Require Export contexts_defs. Require Export subst0_defs. Require Export drop_defs. (*#* #caption "current axioms for strict substitution in contexts", "substituted tail item: second operand", "substituted tail item: first operand", "substituted tail item: both operands" *) (*#* #cap #cap c, c1, c2 #alpha v in W, u in V, u1 in V1, u2 in V2, k in z, r in q *) Inductive csubst0 : nat -> T -> C -> C -> Prop := | csubst0_snd : (k:?; i:?; v,u1,u2:?) (subst0 (r k i) v u1 u2) -> (c:?) (csubst0 (S i) v (CTail c k u1) (CTail c k u2)) | csubst0_fst : (k:?; i:?; c1,c2:?; v:?) (csubst0 (r k i) v c1 c2) -> (u:?) (csubst0 (S i) v (CTail c1 k u) (CTail c2 k u)) | csubst0_both : (k:?; i:?; v,u1,u2:?) (subst0 (r k i) v u1 u2) -> (c1,c2:?) (csubst0 (r k i) v c1 c2) -> (csubst0 (S i) v (CTail c1 k u1) (CTail c2 k u2)). (*#* #stop file *) Hint csubst0 : ltlc := Constructors csubst0. Section csubst0_gen_base. (***********************************************) Theorem csubst0_gen_tail: (k:?; c1,x:?; u1,v:?; i:?) (csubst0 (S i) v (CTail c1 k u1) x) -> (OR (EX u2 | x = (CTail c1 k u2) & (subst0 (r k i) v u1 u2) ) | (EX c2 | x = (CTail c2 k u1) & (csubst0 (r k i) v c1 c2) ) | (EX u2 c2 | x = (CTail c2 k u2) & (subst0 (r k i) v u1 u2) & (csubst0 (r k i) v c1 c2) )). Intros until 1; InsertEq H '(S i); InsertEq H '(CTail c1 k u1). XCase H; Clear x v y y0; Intros; Inversion H1. (* case 1: csubst0_snd *) Inversion H0; Rewrite H3 in H; Rewrite H5 in H; Rewrite H6 in H; XEAuto. (* case 2: csubst0_fst *) Inversion H0; Rewrite H3 in H; Rewrite H4 in H; Rewrite H5 in H; XEAuto. (* case 2: csubst0_both *) Inversion H2; Rewrite H5 in H; Rewrite H6 in H; Rewrite H7 in H; Rewrite H4 in H0; Rewrite H5 in H0; Rewrite H7 in H0; XEAuto. Qed. End csubst0_gen_base. Tactic Definition CSubst0GenBase := Match Context With | [ H: (csubst0 (S ?1) ?2 (CTail ?3 ?4 ?5) ?6) |- ? ] -> LApply (csubst0_gen_tail ?4 ?3 ?6 ?5 ?2 ?1); [ Clear H; Intros H | XAuto ]; XElim H; Intros H; XElim H; Intros. Section csubst0_drop. (***************************************************) Theorem csubst0_drop_ge : (i,n:?) (le i n) -> (c1,c2:?; v:?) (csubst0 i v c1 c2) -> (e:?) (drop n (0) c1 e) -> (drop n (0) c2 e). XElim i. (* case 1: i = 0 *) Intros; Inversion H0. (* case 2: i > 0 *) Intros i; XElim n. (* case 2.1: n = 0 *) Intros; Inversion H0. (* case 2.2: n > 0 *) Intros until 3; Clear H0; InsertEq H2 '(S i); XElim H0; Intros. DropGenBase. (* case 2.2.1: csubst0_snd *) XAuto. (* case 2.2.2: csubst0_fst *) XReplaceIn H0 i0 i; DropGenBase; NewInduction k; XEAuto. (* case 2.2.3: csubst0_both *) XReplaceIn H0 i0 i; XReplaceIn H2 i0 i. DropGenBase; NewInduction k; XEAuto. Qed. Tactic Definition IH := Match Context With | [ H0: (n:?) (lt n ?1) -> (c1,c2:?; v:?) (csubst0 ?1 v c1 c2) -> (e:C) (drop n (0) c1 e) -> ?; H1: (csubst0 ?1 ?2 ?3 ?4); H2: (drop ?5 (0) ?3 ?6) |- ? ] -> LApply (H0 ?5); [ Clear H0; Intros H0 | XAuto ]; LApply (H0 ?3 ?4 ?2); [ Clear H0 H1; Intros H0 | XAuto ]; LApply (H0 ?6); [ Clear H0 H2; Intros H0 | XAuto ]; XElim H0; Intros H0; [ Idtac | XElim H0 | XElim H0 | XElim H0 ]; Intros | [ H0: (r ? ?1) = (S ?1) -> (e:?) (drop (S ?2) (0) ?3 e) -> ?; H1: (drop (S ?2) (0) ?3 ?4) |- ? ] -> LApply H0; [ Clear H0; Intros H0 | XAuto ]; LApply (H0 ?4); [ Clear H0 H1; Intros H0 | XAuto ]; XElim H0; Intros H0; [ Idtac | XElim H0 | XElim H0 | XElim H0 ]; Intros. Theorem csubst0_drop_lt : (i,n:?) (lt n i) -> (c1,c2:?; v:?) (csubst0 i v c1 c2) -> (e:?) (drop n (0) c1 e) -> (OR (drop n (0) c2 e) | (EX k e0 u w | e = (CTail e0 k u) & (drop n (0) c2 (CTail e0 k w)) & (subst0 (minus (r k i) (S n)) v u w) ) | (EX k e1 e2 u | e = (CTail e1 k u) & (drop n (0) c2 (CTail e2 k u)) & (csubst0 (minus (r k i) (S n)) v e1 e2) ) | (EX k e1 e2 u w | e = (CTail e1 k u) & (drop n (0) c2 (CTail e2 k w)) & (subst0 (minus (r k i) (S n)) v u w) & (csubst0 (minus (r k i) (S n)) v e1 e2) )). XElim i. (* case 1: i = 0 *) Intros; Inversion H. (* case 2: i > 0 *) Intros i; XElim n. (* case 2.1: n = 0 *) Intros H0; Clear H0; Intros until 1; InsertEq H0 '(S i); XElim H0; Clear H c1 c2 v y; Intros; DropGenBase; XRewrite e; Rewrite <- r_arith0 in H; Try Rewrite <- r_arith0 in H0; Replace i with i0; XEAuto. (* case 2.2: n > 0 *) Intros until 3; Clear H0; InsertEq H2 '(S i); XElim H0; Clear c1 c2 v y; Intros; DropGenBase. (* case 2.2.1: csubst0_snd *) XEAuto. (* case 2.2.2: csubst0_fst *) Replace i0 with i; XAuto; XReplaceIn H0 i0 i; XReplaceIn H2 i0 i; Clear H3 i0. Apply (r_dis k); Intros; Rewrite (H3 i) in H0; Rewrite (H3 n) in H4. (* case 2.2.2.1: bind *) IH; XRewrite e; Try Rewrite <- (H3 n) in H; Try Rewrite <- (H3 n) in H0; Try Rewrite <- r_arith1 in H4; Try Rewrite <- r_arith1 in H5; XEAuto. (* case 2.2.2.2: flat *) IH; XRewrite e; Try Rewrite <- (H3 n) in H2; Try Rewrite <- (H3 n) in H4; XEAuto. (* case 2.2.3: csubst0_both *) Replace i0 with i; XAuto; XReplaceIn H0 i0 i; XReplaceIn H2 i0 i; XReplaceIn H3 i0 i; Clear H4 i0. Apply (r_dis k); Intros; Rewrite (H4 i) in H2; Rewrite (H4 n) in H5. (* case 2.2.2.1: bind *) IH; XRewrite e; Try Rewrite <- (H4 n) in H; Try Rewrite <- (H4 n) in H2; Try Rewrite <- r_arith1 in H5; Try Rewrite <- r_arith1 in H6; XEAuto. (* case 2.2.3.2: flat *) IH; XRewrite e; Try Rewrite <- (H4 n) in H3; Try Rewrite <- (H4 n) in H5; XEAuto. Qed. Theorem csubst0_drop_ge_back : (i,n:?) (le i n) -> (c1,c2:?; v:?) (csubst0 i v c1 c2) -> (e:?) (drop n (0) c2 e) -> (drop n (0) c1 e). XElim i. (* case 1 : i = 0 *) Intros; Inversion H0. (* case 2 : i > 0 *) Intros i; XElim n. (* case 2.1 : n = 0 *) Intros; Inversion H0. (* case 2.2 : n > 0 *) Intros until 3; Clear H0; InsertEq H2 '(S i); XElim H0; Intros; DropGenBase. (* case 2.2.1 : csubst0_snd *) XAuto. (* case 2.2.2 : csubst0_fst *) XReplaceIn H0 i0 i; NewInduction k; XEAuto. (* case 2.2.3 : csubst0_both *) XReplaceIn H0 i0 i; XReplaceIn H2 i0 i; NewInduction k; XEAuto. Qed. End csubst0_drop. Tactic Definition CSubst0Drop := Match Context With | [ H1: (lt ?2 ?1); H2: (csubst0 ?1 ?3 ?4 ?5); H3: (drop ?2 (0) ?4 ?6) |- ? ] -> LApply (csubst0_drop_lt ?1 ?2); [ Intros H_x | XAuto ]; LApply (H_x ?4 ?5 ?3); [ Clear H_x; Intros H_x | XAuto ]; LApply (H_x ?6); [ Clear H_x H3; Intros H3 | XAuto ]; XElim H3; [ Intros | Intros H3; XElim H3; Intros | Intros H3; XElim H3; Intros | Intros H3; XElim H3; Intros ] | [ H1: (le ?1 ?2); H2: (csubst0 ?1 ?3 ?4 ?5); H3: (drop ?2 (0) ?4 ?6) |- ? ] -> LApply (csubst0_drop_ge ?1 ?2); [ Intros H_x | XAuto ]; LApply (H_x ?4 ?5 ?3); [ Clear H_x; Intros H_x | XAuto ]; LApply (H_x ?6); [ Clear H_x H3; Intros | XAuto ] | [H2: (csubst0 ?1 ?3 ?4 ?5); H3: (drop ?1 (0) ?4 ?6) |- ? ] -> LApply (csubst0_drop_ge ?1 ?1); [ Intros H_x | XAuto ]; LApply (H_x ?4 ?5 ?3); [ Clear H_x H2; Intros H2 | XAuto ]; LApply (H2 ?6); [ Clear H2 H3; Intros | XAuto ] | [H2: (csubst0 ?1 ?3 ?4 ?5); H3: (drop ?1 (0) ?5 ?6) |- ? ] -> LApply (csubst0_drop_ge_back ?1 ?1); [ Intros H_x | XAuto ]; LApply (H_x ?4 ?5 ?3); [ Clear H_x; Intros H_x | XAuto ]; LApply (H_x ?6); [ Clear H_x H3; Intros | XAuto ] | [H2: (csubst0 ?1 ?3 ?4 ?5); H3: (drop ?2 (0) ?5 ?6) |- ? ] -> LApply (csubst0_drop_ge_back ?1 ?2); [ Intros H_x | XAuto ]; LApply (H_x ?4 ?5 ?3); [ Clear H_x; Intros H_x | XAuto ]; LApply (H_x ?6); [ Clear H_x H3; Intros | XAuto ].