results relating to derivation trees (derrec, dersrec) as data structures,
like Isabelle dertrees, rather than purely as properties of conclusions,
including use of derrec_fc ie without the conclusion as part of the type
Require Export List.
Set Implicit Arguments.
Export ListNotations.
Require Import Coq.Program.Equality. (* for dependent induction/destruction *)
Require Import genT gen ddT existsT.
Require Import PeanoNat.
Require Import Lia.
(* tried to do an inductive property where property Q also involved the
proof tree (as well as the endsequent): this created a problem that
the list of proof trees which are part of the dersrec object are not
all of the same type - so one cannot go from
ds : dersrec rules prems concls to ForallT (dersrec rules prems ??) ds'
instead need to define allPder and do the following *)
Inductive allPder X (rules : rlsT X) (prems : X -> Type) P :
forall concls : list X, dersrec rules prems concls -> Type :=
| allPder_Nil : @allPder X rules prems P [] (dlNil rules prems)
| allPder_Cons : forall seq seqs d, P seq d -> forall ds,
@allPder X rules prems P seqs ds ->
@allPder X rules prems P (seq :: seqs) (dlCons d ds)
.
Lemma allPderD : forall X rules prems Q ps (dpss : dersrec rules prems ps) p,
allPder Q dpss -> InT (p : X) ps -> {d : derrec rules prems p & Q p d}.
Proof. induction ps.
intros. inversion X1.
intros dpss p adp inp. inversion adp. subst.
inversion inp ; subst.
exists d. assumption.
clear X0 inp adp. exact (IHps ds p X1 X2). Qed.
(* destruct for allPder dlCons *)
Lemma allPder_dlConsD: forall X rules prems Q seq seqs d ds,
@allPder X rules prems Q (seq :: seqs) (dlCons d ds) ->
Q seq d * allPder Q ds.
Proof.
intros. (* inversion X0 produces existT equalities *)
(* induction X0 produces trivial subgoal 2, unsolvable subgoal 1 *)
(* dependent induction X0. OK, but irrelevant IHX0, trivial subgoal *)
dependent destruction X0.
split ; assumption. Qed.
Definition derrec_rect_mut_all X (rules : rlsT X) prems Q cl1 cl2 :=
derrec_rect_mut Q (@allPder X rules prems Q) cl1 cl2
(allPder_Nil Q) (@allPder_Cons X rules prems Q).
(*
Check derrec_rect_mut_all.
*)
Inductive in_dersrec X (rules : rlsT X) prems concl
(d : derrec rules prems concl) :
forall concls, dersrec rules prems concls -> Type :=
| in_dersrec_hd : forall concls ds, in_dersrec d
(@dlCons X rules prems concl concls d ds)
| in_dersrec_tl : forall concl' d' concls ds, in_dersrec d ds ->
in_dersrec d (@dlCons X rules prems concl' concls d' ds)
.
Inductive is_nextup X (rules : rlsT X) prems (concl : X) (concls : list X)
(ds : dersrec rules prems concls) : derrec rules prems concl -> Type :=
| is_nextupI : forall rps, is_nextup ds (derI concl rps ds)
(* can't make this next line work
| is_nextup_nil : is_nextup (dlNil rules prems) (dpI _ _ _ _)
*)
.
Inductive in_nextup X (rules : rlsT X) prems (concln concl : X)
(dn : derrec rules prems concln) (d : derrec rules prems concl) : Type :=
| in_nextupI : forall concls (ds : dersrec rules prems concls),
is_nextup ds d -> in_dersrec dn ds -> in_nextup dn d
.
Lemma in_drs_concl_in W rules ps (cn : W) (drs : dersrec rules emptyT ps)
(dtn : derrec rules emptyT cn) : in_dersrec dtn drs -> InT cn ps.
Proof. intro ind. induction ind. apply InT_eq.
apply InT_cons. assumption. Qed.
Lemma in_nextup_concl_in W rules ps (concl cn : W) rpc
(drs : dersrec rules emptyT ps) (dtn : derrec rules emptyT cn) :
in_nextup dtn (derI concl rpc drs) -> InT cn ps.
Proof. intro ind. inversion ind. inversion X. subst.
dependent destruction H2. clear H1 rps0 ind X.
exact (in_drs_concl_in X0). Qed.
Lemma all_in_d_allP: forall X rules prems Q ps (dpss : dersrec rules prems ps),
(forall (p : X) (d : derrec rules prems p), in_dersrec d dpss -> Q p d) ->
allPder Q dpss.
Proof. induction dpss. intros. apply allPder_Nil.
intros. apply allPder_Cons. apply X0. apply in_dersrec_hd.
apply IHdpss. intros. apply X0. apply in_dersrec_tl. assumption. Qed.
(* alternative proof, longer, shows need to use dependent inversion
Proof. induction ps. intros. dependent inversion dpss. apply allPder_Nil.
intro. dependent inversion dpss. subst.
intros. apply allPder_Cons. apply X0. apply in_dersrec_hd.
apply IHps. intros. apply X0. apply in_dersrec_tl. assumption. Qed.
*)
Lemma allP_all_in_d: forall X rules prems Q ps (dpss : dersrec rules prems ps),
allPder Q dpss ->
forall (p : X) (d : derrec rules prems p), in_dersrec d dpss -> Q p d.
Proof. induction ps. intro. dependent inversion dpss.
intros. inversion X1.
intro. dependent inversion dpss. subst.
intro. (* inversion X0 gives existT equalities *)
dependent destruction X0.
intros. (* inversion X1 gives existT equalities *)
dependent destruction X1. assumption.
eapply IHps. eassumption. assumption. Qed.
Lemma allPderD_in :
forall X rules prems Q ps (dpss : dersrec rules prems ps) p,
allPder Q dpss -> InT (p : X) ps ->
{d : derrec rules prems p & in_dersrec d dpss & Q p d}.
Proof. induction ps.
intros. inversion X1.
intros dpss p adp inp. dependent destruction adp.
inversion inp ; subst.
exists d. apply in_dersrec_hd. assumption.
pose (IHps ds p adp X0). destruct s. (* cD doesn't work here - why?? *)
exists x. apply in_dersrec_tl. assumption. assumption. Qed.
(*
Check allPderD_in.
*)
Fixpoint derrec_height X rules prems concl
(der : @derrec X rules prems concl) :=
match der with
| dpI _ _ _ _ => 0
| derI _ _ ds => S (dersrec_height ds)
end
with dersrec_height X rules prems concls
(ders : @dersrec X rules prems concls) :=
match ders with
| dlNil _ _ => 0
| dlCons d ds => max (derrec_height d) (dersrec_height ds)
end.
Fixpoint derrec_size X rules prems concl
(der : @derrec X rules prems concl) :=
match der with
| dpI _ _ _ _ => 0
| derI _ _ ds => S (dersrec_size ds)
end
with dersrec_size X rules prems concls
(ders : @dersrec X rules prems concls) :=
match ders with
| dlNil _ _ => 0
| dlCons d ds => (derrec_size d) + (dersrec_size ds)
end.
Definition derrec_concl X rules prems concl
(der : @derrec X rules prems concl) :=
match der with
| dpI _ _ c _ => c
| derI c _ _ => c
end.
Fixpoint dersrec_concls X rules prems concls
(ders : @dersrec X rules prems concls) :=
match ders with
| dlNil _ _ => []
| dlCons d ds => derrec_concl d :: dersrec_concls ds
end.
Definition der_botr_ps X rules prems concl
(der : @derrec X rules prems concl) :=
match der with
| dpI _ _ _ _ => []
| @derI _ _ _ ps _ _ _ => ps
end.
Definition dersrec_hd X rules prems c cs
(ders : @dersrec X rules prems (c :: cs)) : derrec rules prems c :=
match
ders in (dersrec _ _ l) return match l with
| [] => IDProp
| c1 :: _ => derrec rules prems c1
end
with
| dlNil _ _ => idProp
| dlCons d _ => d
end.
Definition dersrec_tl X rules prems c cs
(ders : @dersrec X rules prems (c :: cs)) :=
match
ders as ders0 in (dersrec _ _ l)
return
(match l as x return (dersrec rules prems x -> Type) with
| [] => fun _ : dersrec rules prems [] => IDProp
| c1 :: c0 => fun _ : dersrec rules prems (c1 :: c0) => dersrec rules prems c0
end ders0)
with
| dlNil _ _ => idProp
| dlCons _ ds => ds
end.
Definition dersrec_singleD' X rules prems c
(ders : @dersrec X rules prems [c]) := dersrec_hd ders.
Definition dersrec_singleI' X rules prems c
(d : @derrec X rules prems c) := dlCons d (@dlNil X rules prems).
Definition dersrec_single' X rules prems c :=
(@dersrec_singleD' X rules prems c, @dersrec_singleI' X rules prems c).
(*
Lemma in_dersrec_single X rs ps c (ds : @dersrec X rs ps c) :
in_dersrec (dersrec_singleD ds) ds.
Proof. dependent destruction ds. (* dependent induction ds. also seems OK *)
HOW TO CONTINUE PROOF ?? NB works better for dersrec_singleD'
*)
Lemma botr_ps_der W rules prems c (d : derrec rules prems c) :
@dersrec W rules prems (der_botr_ps d).
Proof. destruct d ; simpl. apply dlNil. apply d. Qed.
Lemma in_dersrec_single' X rs ps c (ds : @dersrec X rs ps [c]) :
in_dersrec (dersrec_singleD' ds) ds.
Proof. dependent destruction ds. (* dependent induction ds. also seems OK,
but dependent inversion gives a type error *)
unfold dersrec_singleD'. simpl. apply in_dersrec_hd. Qed.
(* can't do this, gives The term "ds" has type "dersrec rules prems l"
while it is expected to have type "dersrec rules prems ".
Fixpoint derrec_nextup X rules prems concl
(der : @derrec X rules prems concl) :=
match der with
| dpI _ _ _ _ => dlNil rules prems
| derI _ _ ds => ds
end.
*)
Lemma dersrec_hd_eq X rs ps c cs
(d : @derrec X rs ps c) (ds : @dersrec X rs ps cs) :
dersrec_hd (dlCons d ds) = d.
Proof. simpl. reflexivity. Qed.
Lemma dersrec_tl_eq X rs ps c cs
(d : @derrec X rs ps c) (ds : @dersrec X rs ps cs) :
dersrec_tl (dlCons d ds) = ds.
Proof. simpl. reflexivity. Qed.
Lemma in_drs_drs_hd X rs ps c cs (ds : @dersrec X rs ps (c :: cs)) :
in_dersrec (dersrec_hd ds) ds.
Proof. dependent destruction ds. (* dependent induction ds. also seems OK *)
simpl. apply in_dersrec_hd. Qed.
Lemma dersrec_height_nil : forall X rules prems ps (ds : @dersrec X rules prems ps),
ps = [] -> dersrec_height ds = 0.
Proof.
induction ds.
- simpl. reflexivity.
- intro. inversion H.
Qed.
Lemma dersrec_height_le: forall X rules prems n ps
(ds : dersrec rules prems ps),
(forall (p : X) (d : derrec rules prems p),
in_dersrec d ds -> derrec_height d <= n) -> dersrec_height ds <= n.
Proof. (* induction ps.
intros. inversion ds. this step seems to do nothing *)
induction ds.
intros. simpl. apply le_0_n.
intros. simpl. apply Nat.max_lub.
apply H. apply in_dersrec_hd.
apply IHds. intros. apply H. apply in_dersrec_tl. assumption. Qed.
Lemma le_dersrec_height: forall X rules prems n ps
(ds : dersrec rules prems ps),
forall (p : X) (d : derrec rules prems p),
in_dersrec d ds -> n <= derrec_height d -> n <= dersrec_height ds.
Proof. (* induction ps.
intros. inversion ds. this step seems to do nothing *)
(* this doesn't work - why ??
induction ds ; intros ; inversion X0 ; subst ; simpl ; rewrite Nat.max_le_iff.
left. assumption.
right. eapply IHds. 2: eassumption.
WHAT NOW ???
*)
intros. induction X0 ; simpl ; rewrite Nat.max_le_iff ; tauto. Qed.
(*
Fixpoint aderrec_height X
(rules : list X -> X -> Prop) (prems : X -> Prop) concl
(der : @aderrec X rules prems concl) :=
match der with
| adpI _ _ _ _ => 0
| aderI _ _ _ => 0
end.
*)
Fixpoint derl_height X
(rules : list X -> X -> Prop) (prems : list X) (concl : X)
(der : @derl X rules prems concl) :=
match der with
| asmI _ _ => 0
| dtderI _ _ ds => S (dersl_height ds)
end
with dersl_height X (rules : list X -> X -> Prop) (prems concls : list X)
(ders : @dersl X rules prems concls) :=
match ders with
| dtNil _ => 0
| dtCons d ds => max (derl_height d) (dersl_height ds)
end.
Lemma der_concl_eq: forall X (rules : rlsT X) prems concl
(d : derrec rules prems concl), derrec_concl d = concl.
Proof. dependent inversion d ; simpl ; reflexivity. Qed.
Lemma ders_concls_eq: forall X (rules : rlsT X) prems concls
(ds : dersrec rules prems concls), dersrec_concls ds = concls.
Proof. induction ds ; simpl. reflexivity.
rewrite -> (der_concl_eq d). rewrite IHds. reflexivity. Qed.
der(s)rec_fc(s) - trees without conclusion as part of the type
Inductive derrec_fc X rules (prems : X -> Type) : Type :=
| fcI : forall concl, derrec rules prems concl -> derrec_fc rules prems.
Inductive dersrec_fcs X rules (prems : X -> Type) : Type :=
| fcsI : forall concls, dersrec rules prems concls -> dersrec_fcs rules prems.
Inductive in_nextup_fc X (rules : rlsT X) prems :
relationT (derrec_fc rules prems) :=
| in_nextup_fcI : forall concln concl
(dn : derrec rules prems concln) (d : derrec rules prems concl),
in_nextup dn d -> in_nextup_fc (fcI dn) (fcI d)
.
Lemma AccT_in_nextup_fc X rules prems dt: AccT (@in_nextup_fc X rules prems) dt.
Proof. destruct dt. revert d. revert concl.
eapply derrec_rect_mut_all.
- intros. apply AccT_intro. intros y iny.
dependent destruction iny. inversion i. inversion X0.
- intros * apd. apply AccT_intro. intros y iny.
dependent destruction iny. inversion i. dependent destruction X0.
exact (allP_all_in_d apd X1). Qed.
Fixpoint dersrec_trees X rules prems concls
(ders : @dersrec X rules prems concls) :=
match ders with
| dlNil _ _ => []
| dlCons d ds => fcI d :: dersrec_trees ds
end.
Definition nextup W rules prems (dt : @derrec_fc W rules prems) :=
match dt with
| fcI (dpI _ _ _ _) => []
| fcI (derI _ _ ds) => dersrec_trees ds
end.
Definition derrec_fc_concl X rules prems
(der : @derrec_fc X rules prems) :=
match der with
| fcI d => derrec_concl d
end.
Definition dersrec_fc_concls X rules prems
(ders : @dersrec_fcs X rules prems) :=
match ders with
| fcsI ds => dersrec_concls ds
end.
(* note, this includes case where the tree is simply a premise *)
Inductive botRule_fc X rules prems (der : @derrec_fc X rules prems) : rlsT X :=
| botRule_fcI : botRule_fc der
(map (@derrec_fc_concl _ _ _) (nextup der)) (derrec_fc_concl der).
(* this fails, d has type "derrec rules prems x", but x not in scope
Fixpoint derrec_of_fc X rules prems
(der : @derrec_fc X rules prems) :=
match der with
| fcI d => d
end.
*)
(* while we can't get something of type derrec rules prems _
from something of type derrec_fc ..., we can get it and then
apply any function to it whose result type doesn't involve the conclusion *)
Definition derrec_fc_size X rules prems
(der : @derrec_fc X rules prems) :=
match der with
| fcI d => derrec_size d
end.
Definition dersrec_fc_size X rules prems
(ders : @dersrec_fcs X rules prems) :=
match ders with
| fcsI ds => dersrec_size ds
end.
Definition derrec_fc_height X rules prems
(der : @derrec_fc X rules prems) :=
match der with
| fcI d => derrec_height d
end.
Definition dersrec_fc_height X rules prems
(ders : @dersrec_fcs X rules prems) :=
match ders with
| fcsI ds => dersrec_height ds
end.
Lemma der_fc_concl_eq: forall X (rules : rlsT X) prems concl
(d : derrec rules prems concl), derrec_fc_concl (fcI d) = concl.
Proof. simpl. apply der_concl_eq. Qed.
Lemma dersrec_trees_concls_eq X rules prems ps (ds : dersrec rules prems ps) :
map (@derrec_fc_concl X rules prems) (dersrec_trees ds) = ps.
Proof. induction ds. simpl. reflexivity.
simpl. rewrite (der_concl_eq d). rewrite IHds. reflexivity. Qed.
Lemma der_botr_ps_eq X rules prems c (dt : derrec rules prems c) :
map (@derrec_fc_concl X rules prems) (nextup (fcI dt)) = der_botr_ps dt.
Proof. destruct dt ; simpl. reflexivity. apply dersrec_trees_concls_eq. Qed.
Lemma der_der_fc X rules prems (der : @derrec_fc X rules prems) :
derrec rules prems (derrec_fc_concl der).
Proof. destruct der. simpl. rewrite der_concl_eq. exact d. Qed.
Lemma ders_ders_fcs X rules prems (ders : @dersrec_fcs X rules prems) :
dersrec rules prems (dersrec_fc_concls ders).
Proof. destruct ders. simpl. rewrite ders_concls_eq. exact d. Qed.
Lemma in_drs_trees: forall X rules prems cs ds c (d : derrec rules prems c),
in_dersrec d ds -> InT (fcI d) (@dersrec_trees X rules prems cs ds).
Proof. intros. induction X0 ; simpl.
apply InT_eq. apply InT_cons. assumption. Qed.
Lemma in_trees_drs: forall X rules prems cs ds c (d : derrec rules prems c),
InT (fcI d) (@dersrec_trees X rules prems cs ds) -> in_dersrec d ds.
Proof. induction cs ; intro ; dependent inversion ds ; simpl ; intros.
inversion X0.
(* inversion X0. injection H2. gives existT equality *)
subst. dependent destruction X0. apply in_dersrec_hd.
apply in_dersrec_tl. apply IHcs. assumption. Qed.
Lemma der_botRule W rules (dt : derrec_fc rules emptyT) :
{ps : list W & {c : W & rules ps c & botRule_fc dt ps c}}.
Proof. destruct dt. destruct d. destruct e.
exists ps. exists concl. exact r.
pose botRule_fcI.
specialize (b W rules emptyT (fcI (derI concl r d))).
simpl in b. rewrite dersrec_trees_concls_eq in b. exact b. Qed.
Lemma botRule_fc_concl W rules prems ps (c : W) (dt : derrec_fc rules prems) :
botRule_fc dt ps c -> derrec_fc_concl dt = c.
Proof. intro br. destruct br. reflexivity. Qed.
Lemma botRule_fc_rules W rules ps (c : W) (dt : derrec_fc rules emptyT) :
botRule_fc dt ps c -> rules ps c.
Proof. intro br. destruct br. destruct dt.
rewrite (der_fc_concl_eq d).
destruct d. destruct e. simpl.
rewrite (dersrec_trees_concls_eq d). exact r. Qed.
Lemma botRule_fc_drs W rules prems ps (c : W) (dt : derrec_fc rules prems) :
botRule_fc dt ps c -> dersrec rules prems ps.
Proof. intro br. destruct br. destruct dt.
destruct d. simpl. apply dlNil.
simpl. rewrite (dersrec_trees_concls_eq d). exact d. Qed.
Lemma botRule_fc_ps W rules prems ps (c : W) (dt : derrec_fc rules prems) :
botRule_fc dt ps c -> map (@derrec_fc_concl W rules prems) (nextup dt) = ps.
Proof. intro br. destruct br. destruct dt. reflexivity. Qed.
Lemma get_botrule W rules prems (c : W) (dt : derrec rules prems c) :
botRule_fc (fcI dt) (der_botr_ps dt) c.
Proof. rewrite <- der_botr_ps_eq.
eapply eq_rect. apply botRule_fcI. apply der_fc_concl_eq. Qed.
Definition bot_is_rule W rules (c : W) (dt : derrec rules emptyT c) :=
botRule_fc_rules (get_botrule dt).
Lemma botRule_fc_prems W rules prems (c : W) (dt : derrec rules prems c) ps c' :
botRule_fc (fcI dt) ps c' -> (c = c') * (der_botr_ps dt = ps).
Proof. intro br. rewrite <- der_botr_ps_eq. rewrite (botRule_fc_ps br).
split. destruct br. rewrite der_fc_concl_eq. reflexivity. reflexivity. Qed.
Lemma in_nextup_eqv W rules prems (concln concl : W)
(dtn : derrec rules prems concln) (dt : derrec rules prems concl) :
iffT (in_nextup dtn dt) (InT (fcI dtn) (nextup (fcI dt))).
Proof. apply pair ; intros.
- destruct X. destruct i. simpl. exact (in_drs_trees i0).
- simpl in X. destruct dt. inversion X.
apply in_trees_drs in X.
eapply in_nextupI. apply is_nextupI. exact X. Qed.
Definition in_nextup_nu W rules prems concln concl dtn dt :=
iffT_D1 (@in_nextup_eqv W rules prems concln concl dtn dt).
Definition nextup_in_nu W rules prems concln concl dtn dt :=
iffT_D2 (@in_nextup_eqv W rules prems concln concl dtn dt).
Lemma in_nextup_fc_eqv W rules prems (dtn dt : @derrec_fc W rules prems) :
iffT (in_nextup_fc dtn dt) (InT dtn (nextup dt)).
Proof. apply pair ; intros.
- destruct X. exact (in_nextup_nu i).
- destruct dtn. destruct dt. apply in_nextup_fcI. exact (nextup_in_nu _ X).
Qed.
Definition in_nextup_fc_nu W rules prems dtn dt :=
iffT_D1 (@in_nextup_fc_eqv W rules prems dtn dt).
Definition nextup_in_nu_fc W rules prems dtn dt :=
iffT_D2 (@in_nextup_fc_eqv W rules prems dtn dt).
(* converse to this requires is_nextup (dlNil rules prems) (dpI _ _ _ _) *)
Lemma is_nextup_ndt W rules prems concls (concl : W)
(dts : dersrec rules prems concls)
(dt : derrec rules prems concl) :
is_nextup dts dt -> nextup (fcI dt) = dersrec_trees dts.
Proof. unfold nextup. intros. destruct X. reflexivity. Qed.
Lemma drs_trees_height W rules prems ps (ds : @dersrec W rules prems ps) dn:
InT dn (dersrec_trees ds) -> derrec_fc_height dn <= dersrec_height ds.
Proof. induction ds ; simpl ; intro inn ; inversion inn.
subst. simpl. apply PeanoNat.Nat.le_max_l.
apply (Nat.le_trans _ _ _ (IHds X)). apply PeanoNat.Nat.le_max_r. Qed.
Lemma nextup_height W rules prems dt dn: InT dn (nextup dt) ->
(@derrec_fc_height W rules prems dn) < derrec_fc_height dt.
Proof. intro inn. destruct dt. destruct d ; simpl in inn. inversion inn.
simpl. apply Nat.lt_succ_r, drs_trees_height, inn. Qed.
Lemma fcI_inj: forall X rules prems concl (d1 : @derrec X rules prems concl) d2,
fcI d1 = fcI d2 -> d1 = d2.
Proof. intros. (* injection H gives existT equality *)
dependent destruction H. reflexivity. Qed.
(* this doesn't work - type of Q
Goal forall X rules prems Q cs (ds : @dersrec X rules prems cs),
allPder Q ds -> Forall2T Q cs (dersrec_trees ds).
*)
Open Scope type_scope.
Lemma dersrecD_forall_in_dersrec : forall (X : Type) (rs : list X -> X -> Type) (ps : X -> Type) (cs : list X) (ds : dersrec rs ps cs) (c : X),
InT c cs -> (existsT2 d : derrec rs ps c, in_dersrec d ds).
Proof.
induction ds; intros c Hin.
inversion Hin.
inversion Hin.
+ subst. exists d. constructor.
+ subst. eapply IHds in X0. destruct X0 as [d2 Hin2].
exists d2. constructor 2. eapply Hin2.
Qed.
Lemma dersrec_double_verb: forall X rules prems c1 c2 (d : (dersrec rules prems [c1;c2])),
existsT2 (d1 : (derrec rules prems (c1 : X))) (d2 : (derrec rules prems (c2 : X))),
(in_dersrec d1 d) * (in_dersrec d2 d).
Proof.
intros.
assert (InT c1 [c1;c2]) as Hin1. constructor. reflexivity.
assert (InT c2 [c1;c2]) as Hin2. constructor 2. constructor. reflexivity.
eapply dersrecD_forall_in_dersrec in Hin1.
destruct Hin1 as [d1 Hin1]. exists d1.
eapply dersrecD_forall_in_dersrec in Hin2.
destruct Hin2 as [d2 Hin2]. exists d2.
split. apply Hin1. apply Hin2.
Qed.
Definition dp {X : Type} {rules : list X -> X -> Type} {prems : X -> Type}
{concl : X} (der : derrec rules prems concl) := @derrec_height X rules prems concl der.
Lemma dersrec_derrec_height : forall n {X : Type} {rules prems G}
(D2 : dersrec rules prems [G]),
dersrec_height D2 = n ->
existsT2 (D1 : derrec rules prems G),
@derrec_height X _ _ _ D1 = n.
Proof.
intros *.
intros Ht.
remember D2 as D2'.
remember [G] as GG.
destruct D2. discriminate.
subst. simpl.
inversion HeqGG. subst.
exists d.
remember [] as l.
destruct D2. simpl.
rewrite PeanoNat.Nat.max_0_r. reflexivity.
discriminate.
Qed.
Lemma dersrec_derrec2_height : forall n {X : Type} {rules prems G1 G2}
(D2 : dersrec rules prems [G1;G2]),
dersrec_height D2 = n ->
existsT2 (D1a : derrec rules prems G1) (D1b : derrec rules prems G2),
n = max (@derrec_height X _ _ _ D1a) (@derrec_height X _ _ _ D1b).
Proof.
intros *.
intros Ht.
remember D2 as D2'.
remember [G1;G2] as GG.
destruct D2. discriminate.
destruct seqs. discriminate.
destruct seqs. 2 : discriminate.
edestruct (@dersrec_derrec_height (@dersrec_height _ _ _ _ D2)_ _ _ _ D2).
reflexivity.
subst. simpl.
inversion HeqGG. subst.
exists d. exists x0.
rewrite e. reflexivity.
Qed.
Lemma dersrec_derrec_dp : forall n {X : Type} {rules prems G}
(D2 : dersrec rules prems [G]),
dersrec_height D2 = n ->
existsT2 (D1 : derrec rules prems G),
@dp X _ _ _ D1 = n.
Proof. eapply dersrec_derrec_height. Qed.
Lemma dersrec_derrec2_dp : forall n {X : Type} {rules prems G1 G2}
(D2 : dersrec rules prems [G1;G2]),
dersrec_height D2 = n ->
existsT2 (D1a : derrec rules prems G1) (D1b : derrec rules prems G2),
n = max (@dp X _ _ _ D1a) (@dp X _ _ _ D1b).
Proof. eapply dersrec_derrec2_height. Qed.
Lemma dersrec_derrec_height_le : forall {T : Type} rules prems ps p
(ds : dersrec rules prems ps)
(d : derrec rules prems p),
in_dersrec d ds ->
derrec_height d <= @dersrec_height T _ _ _ ds.
Proof.
intros T rules prems ps p ds d Hin.
eapply le_dersrec_height.
2 : eapply le_n.
assumption.
Qed.
Lemma dp_same : forall {T : Type} {rules prems} (l1 l2 : list T)
(D1 : derrec rules prems l1)
(Heq : l1 = l2),
dp (eq_rect _ (fun l => derrec rules prems l) D1 l2 Heq) = dp D1.
Proof. induction D1; intros Heq; subst; reflexivity. Qed.
Lemma dp_same_fun : forall {T T2 : Type} {rules prems} (l1 l2 : list T) (f : list T -> T2)
(D1 : derrec rules prems (f l1))
(Heq : l1 = l2),
dp (eq_rect _ (fun l => derrec rules prems (f l)) D1 l2 Heq) = dp D1.
Proof. intros; inversion D1; subst; reflexivity. Qed.
Lemma derrec_dp_same :
forall {X : Type} rules (prems : X -> Type) G H (D1 : derrec rules prems G),
G = H ->
existsT2 (D2 : derrec rules prems H), dp D1 = dp D2.
Proof. intros. subst. exists D1. reflexivity. Qed.
Lemma derrec_dp_same2 :
forall {X : Type} rules (prems : X -> Type) G (D1 : derrec rules prems G) H,
G = H ->
existsT2 (D2 : derrec rules prems H), dp D1 = dp D2.
Proof. intros. subst. exists D1. reflexivity. Qed.
Definition get_D {X} rules prems G H D pf :=
(let (D', HD') := (fun (X : Type) (rules : list X -> X -> Type) (prems : X -> Type)
(G H : X) (D1 : derrec rules prems G) (H0 : G = H) =>
eq_rect_r
(fun G0 : X =>
forall D2 : derrec rules prems G0,
existsT2 D3 : derrec rules prems H, dp D2 = dp D3)
(fun D2 : derrec rules prems H =>
existT (fun D3 : derrec rules prems H => dp D2 = dp D3) D2 eq_refl) H0 D1)
X rules prems
G H D pf in D').
(*
Parameter (X : Type) (rules : list X -> X -> Type) (prems : X -> Type)
(G H : X) (D : derrec rules prems G) (pf : G = H).
Compute (get_D rules prems G H D pf).
*)
Lemma dp_get_D : forall (X : Type) (rules : list X -> X -> Type) (prems : X -> Type)
(G H : X) (D : derrec rules prems G) (pf : G = H),
dp D = dp (get_D D pf).
Proof. intros. subst. reflexivity. Qed.
Definition get_dpD {X : Type} (rules : list X -> X -> Type) (prems : X -> Type) (G H : X)
(D : derrec rules prems G) (pf : G = H) :=
EqdepFacts.internal_eq_rew_r_dep
(fun (G0 : X) (pf0 : G0 = H) =>
forall D0 : derrec rules prems G0, dp D0 = dp (get_D D0 pf0))
(fun D0 : derrec rules prems H => eq_refl) pf D.
Ltac tfm_dersrec_derrec_dp D2s D2 Hdp HdpD2 Hdp'' Hdp' :=
destruct (dersrec_derrec_dp D2s eq_refl) as [D2 HdpD2];
match goal with
| [ H : dp ?D1 + S (dersrec_height D2s) <= ?m |- _ ] =>
assert (dp D1 + (S (dp D2)) <= m) as Hdp'';
[rewrite HdpD2; assumption | ];
assert (dp D1 + dp D2 <= m - 1) as Hdp';
[lia | ]; clear HdpD2 D2s Hdp
end.
Ltac tfm_dersrec_derrec2_dp D2s D2 Hdp HdpD2 Hdpa'' Hdpb'' Hdpa' Hdpb' HeqD2s Hmax1 Hmax2 :=
assert (dersrec_height D2s = dersrec_height D2s) as HeqD2s;
[reflexivity |];
destruct (dersrec_derrec2_dp D2s HeqD2s) as [D2a [D2b HdpD2]];
clear HeqD2s;
epose proof (Nat.le_max_r _ _) as Hmax1;
epose proof (Nat.le_max_r _ _) as Hmax2;
rewrite <- HdpD2 in Hmax1;
rewrite <- HdpD2 in Hmax2;
match goal with
| [ H : dp ?D1 + S (dersrec_height D2s) <= ?m |- _ ] =>
assert (dp D1 + (S (dp D2a)) <= m) as Hdpa'';
[lia | ];
assert (dp D1 + (S (dp D2b)) <= m) as Hdpb'';
[lia | ];
assert (dp D1 + (dp D2a) <= m - 1) as Hdpa';
[lia | ];
assert (dp D1 + (dp D2b) <= m - 1) as Hdpb';
[lia | ];
clear HdpD2 D2s Hdp Hmax1 Hmax2
end.