Library LambdaTamer.Binding
Require
Import
Bool List TheoryList Eqdep Omega.
Require
Import
LambdaTamer.ListUtil.
Require
Import
LambdaTamer.ListT.
Set Implicit
Arguments.
Section
Subst.
Variable
dom : Set.
Inductive
Var : list dom -> dom -> Set :=
| First : forall G t, Var (t :: G) t
| Next : forall G t t', Var G t -> Var (t' :: G) t.
Definition
VarNil : forall ls (t : dom), Var ls t -> Var (ls ++ nil) t.
Definition
liftVar' : forall (G : list dom) t G', Var (G ++ G') t
-> forall t', Var (G ++ t' :: G') t.
Definition
liftVar (G : list dom) (t : dom) (v : Var G t) (t' : dom) : Var (t' :: G) t :=
liftVar' nil G v t'.
Fixpoint
liftVarEnd (G : list dom) (t : dom) (G' : list dom) (v : Var G t) {struct G'}
: Var (G ++ G') t :=
match G' return (Var (G ++ G') t) with
| nil => VarNil v
| _ :: _ => liftVar' _ _ (liftVarEnd _ v) _
end.
Fixpoint
grabVar (G : list dom) (t : dom) (G' : list dom) {struct G} : Var (G ++ t :: G') t :=
match G return (Var (G ++ t :: G') t) with
| nil => First _ _
| _ :: _ => Next _ (grabVar _ _ _)
end.
Definition
lastVar G t : Var (G ++ t :: nil) t :=
grabVar _ _ _.
Definition
lastVar' G1 G2 t : Var (G1 ++ (G2 ++ t :: nil)) t.
Variable
denote : dom -> Type.
Inductive
Subst : list dom -> Type :=
| SNil : Subst nil
| SCons : forall t G, denote t -> Subst G -> Subst (t :: G).
Fixpoint
appSubst (ts1 : list dom) (s1 : Subst ts1) (ts2 : list dom) (s2 : Subst ts2) {struct s1}
: Subst (ts1 ++ ts2) :=
match s1 in (Subst ts1) return (Subst (ts1 ++ ts2)) with
| SNil => s2
| SCons _ _ x s1' => SCons x (appSubst s1' s2)
end.
Definition
head : forall t G, Subst (t :: G) -> denote t.
Definition
tail : forall t G, Subst (t :: G) -> Subst G.
Fixpoint
revAppN_Subst G1 (s1 : Subst G1) (pos : nat) G2 (s2 : Subst G2) {struct s1}
: Subst (revAppN G1 pos G2) :=
match s1 in (Subst G1) return (Subst (revAppN G1 pos G2)) with
| SNil => s2
| SCons t G v s1' =>
match pos return (Subst (revAppN (t :: G) pos G2)) with
| O => s2
| S pos' => revAppN_Subst s1' pos' (SCons v s2)
end
end.
Fixpoint
Subst_drop (G : list dom) (s : Subst G) (n : nat) {struct s}
: Subst (drop G n) :=
match s in (Subst G) return (Subst (drop G n)) with
| SNil => SNil
| SCons t G' v s' =>
match n return (Subst (drop (t :: G') n)) with
| O => SCons v s'
| S n' => Subst_drop s' n'
end
end.
Lemma
Subst_revAppN_split' : forall ts1 (s1 : Subst ts1)
pos1 pos2 ts2 (s2 : Subst ts2)
(Heq : revAppN ts1 (pos1 + pos2) ts2
= revAppN (drop ts1 pos1) pos2 (revAppN ts1 pos1 ts2)),
revAppN_Subst s1 (pos1 + pos2) s2
= eq_rect _ Subst
(revAppN_Subst (Subst_drop s1 pos1) pos2 (revAppN_Subst s1 pos1 s2))
_ (sym_eq Heq).
Lemma
Subst_revAppN_split : forall ts1 (s1 : Subst ts1)
pos1 pos2 ts2 (s2 : Subst ts2),
revAppN_Subst s1 (pos1 + pos2) s2
= eq_rect _ Subst
(revAppN_Subst (Subst_drop s1 pos1) pos2 (revAppN_Subst s1 pos1 s2))
_ (sym_eq (revAppN_split _ _ _ _)).
Fixpoint
VarDenote (G : list dom) (t : dom) (v : Var G t) {struct v}
: Subst G -> denote t :=
match v in (Var G t) return (Subst G -> denote t) with
| First _ _ => fun s => head s
| Next _ _ _ v => fun s => VarDenote v (tail s)
end.
Lemma
Subst_invert_nil'
: forall P : Subst nil -> Type,
P SNil ->
forall G s, match G return (Subst G -> _) with
| nil => P
| _ => fun _ => True
end s.
Theorem
Subst_invert_nil
: forall P : Subst nil -> Type,
P SNil ->
forall s, P s.
Lemma
Subst_invert_cons'
: forall P : forall t G, Subst (t :: G) -> Type,
(forall (t : dom) (G : list dom) (d : denote t) (s : Subst G),
P t G (SCons d s))
-> forall G s, match G return (Subst G -> Type) with
| nil => fun _ => True
| _ => P _ _
end s.
Theorem
Subst_invert_cons
: forall P : forall t G, Subst (t :: G) -> Type,
(forall (t : dom) (G : list dom) (d : denote t) (s : Subst G),
P t G (SCons d s))
-> forall t G (s : Subst (t :: G)), P _ _ s.
Theorem
inversion_Subst_nil : forall (s : Subst nil),
s = SNil.
Theorem
inversion_Subst_cons : forall t G (s : Subst (t :: G)),
exists v, exists s', s = SCons v s'.
End
Subst.
Ltac
inversion_Subst_nil ls :=
let His := fresh "His" in
(generalize (inversion_Subst_nil ls); intro His;
subst; simpl in *; unfold eq_rect_r in *; simpl in *).
Ltac
inversion_Subst_cons ls :=
let His := fresh "His"
with h := fresh "h"
with t := fresh "t" in
(destruct (inversion_Subst_cons ls) as [h [t His]];
subst; simpl in *;
repeat rewrite eq_rect_r_ident; repeat rewrite eq_rect_ident).
Ltac
inversion_Subst s := inversion_Subst_nil s || inversion_Subst_cons s.
Ltac
inversion_Subst_any :=
match goal with
| [ ls : Subst _ nil |- _ ] => inversion_Subst_nil ls
| [ ls : Subst _ (_ :: _) |- _ ] => inversion_Subst_cons ls
end.
Section
Var_invert.
Variable
dom : Set.
Lemma
Var_invert'
: forall P : forall (t' : dom) l t, Var (t' :: l) t -> Prop,
(forall G t, P t G t (First G t)) ->
(forall G t t' v,
P t' G t (Next t' v)) ->
forall l t v,
match l return (Var l t -> Prop) with
| nil => fun _ => True
| _ => fun v => P _ _ _ v
end v.
Theorem
Var_invert
: forall P : forall (t' : dom) l t, Var (t' :: l) t -> Prop,
(forall G t, P t G t (First G t)) ->
(forall G t t' v,
P t' G t (Next t' v)) ->
forall t' l t v, P t' l t v.
Definition
permuteVar : forall (G1 : list dom) t1 t2 G2 t, Var (G1 ++ t1 :: t2 :: G2) t
-> Var (G1 ++ t2 :: t1 :: G2) t.
Definition
frontVar' : forall G1 (t : dom) G2 t',
Var (G1 +++ t :: G2) t'
-> Var (t :: G1 +++ G2) t'.
Definition
frontVar : forall G1 (t : dom) G2 t',
Var (G1 ++ t :: G2) t'
-> Var (t :: G1 ++ G2) t'.
Section
substVar.
Variable
dom2 : Set.
Variable
term : list dom -> dom2 -> Set.
Variable
inj : dom -> dom2.
Variable
var : forall G t, Var G t -> term G (inj t).
Variable
lift : forall a G t, term G t -> term (a :: G) t.
Definition
substVar' : forall (G : list dom) t' G' t, Var (G ++ t' :: G') t
-> term G' (inj t') -> term (G ++ G') (inj t).
Definition
substVar : forall t' (G : list dom) t, Var (t' :: G) t
-> term G (inj t') -> term G (inj t).
End
substVar.
Definition
retype_Var : forall t t', t = t'
-> forall G, Var (dom:= dom) G t
-> Var G t'.
Theorem
retype_Var_ident : forall G t (H : t = t) (k : Var G t),
retype_Var H k = k.
Lemma
Var_split : forall t G t' (v : Var (t :: G) t'),
(t = t' /\ forall Heq : t = t', v = retype_Var Heq (First _ _))
\/ exists v', v = Next _ v'.
End
Var_invert.
Ltac
inversion_Var elm :=
let Heq := fresh "Heq"
with His := fresh "His"
with v' := fresh "v'" in
(destruct (Var_split elm) as [[Heq His] | [v' His]];
[subst; generalize (His (refl_equal _)); clear His; intro His;
repeat rewrite retype_Var_ident in His
| idtac];
subst; simpl in *;
repeat rewrite eq_rect_r_ident; repeat rewrite eq_rect_ident);
repeat rewrite eq_rect_ident.
Ltac
inversion_Var_any :=
match goal with
| [ v : Var _ _ |- _ ] => inversion v; fail
| [ v : Var _ _ |- _ ] => inversion_Var v
end.
Ltac
simpl_Binding := repeat progress
(repeat inversion_Subst_any;
repeat inversion_Var_any;
simpl in *; intuition).
Section
VarConvert.
Variables
dom1 dom2 : Set.
Variable
convert : dom1 -> dom2.
Fixpoint
VarConvert (G : list dom1) (t : dom1) (v : Var G t) {struct v}
: Var (map convert G) (convert t) :=
match v in (Var G t) return (Var (map convert G) (convert t)) with
| First _ _ => First _ _
| Next _ _ _ v' => Next _ (VarConvert v')
end.
End
VarConvert.
Section
Subst_lr.
Variables
dom1 dom2 : Set.
Variable
denote1 : dom1 -> Type.
Variable
denote2 : dom2 -> Type.
Variable
compile : dom1 -> dom2.
Variable
val_lr : forall (t : dom1), denote1 t -> denote2 (compile t) -> Prop.
Inductive
Subst_lr : forall G, Subst denote1 G -> Subst denote2 (map compile G) -> Prop :=
| Slr_Nil : Subst_lr (SNil _) (SNil _)
| Slr_Cons : forall t G (v : denote1 t) (s : Subst _ G) cv cs,
val_lr v cv
-> Subst_lr s cs
-> Subst_lr (SCons _ v s) (SCons _ cv cs).
Lemma
Subst_lr_Var : forall G t (v : Var G t) s s',
Subst_lr s s'
-> val_lr (VarDenote v s) (VarDenote (VarConvert compile v) s').
Definition
liftSubst' : forall G G', Subst denote1 (G ++ G')
-> forall t, denote1 t -> Subst denote1 (G ++ t :: G').
Theorem
liftSubst'_sound : forall G G' (s : Subst denote1 (G ++ G'))
t' (v0 : denote1 t')
t (v : Var (G ++ G') t),
VarDenote (liftVar' G G' v t') (liftSubst' _ _ s v0) =
VarDenote v s.
Lemma
VarNil_sound : forall G t (v : Var G t) (s' : Subst denote1 _),
VarDenote (VarNil v)
(appSubst s' (SNil _))
= VarDenote v s'.
Theorem
grabVar_sound : forall G t G' s x s',
VarDenote (grabVar G t G') (appSubst (denote:= denote1) s (SCons _ x s')) = x.
Theorem
lastVar_sound : forall G1 G2 t s1 s2 x,
VarDenote (lastVar (G1 ++ G2) t)
(appSubst (appSubst s1 s2) (SCons t x (SNil denote1))) = x.
Lemma
appSubst_liftSubst' : forall G (s : Subst denote1 G)
a h G' (s' : Subst denote1 G'),
appSubst s (SCons a h s')
= liftSubst' _ _ (appSubst s s') h.
Theorem
permuteVar_sound : forall (G1 : list dom1) t1 t2 G2 t
(v : Var (G1 ++ t1 :: t2 :: G2) t) (s1 : Subst denote1 _) x1 x2 s2,
VarDenote (permuteVar _ _ _ _ v) (appSubst s1 (SCons _ x1 (SCons _ x2 s2)))
= VarDenote v (appSubst s1 (SCons _ x2 (SCons _ x1 s2))).
End
Subst_lr.
Section
SubstU_lr.
Variables
dom : Set.
Variables
denote1 denote2 : dom -> Type.
Variable
val_lr : forall (t : dom), denote1 t -> denote2 t -> Prop.
Inductive
SubstU_lr : forall G, Subst denote1 G -> Subst denote2 G -> Prop :=
| SlrU_Nil : SubstU_lr (SNil _) (SNil _)
| SlrU_Cons : forall t G (v : denote1 t) (s : Subst _ G) cv cs,
val_lr v cv
-> SubstU_lr s cs
-> SubstU_lr (SCons _ v s) (SCons _ cv cs).
Lemma
SubstU_lr_Var : forall G t (v : Var G t) s s',
SubstU_lr s s'
-> val_lr (VarDenote v s) (VarDenote v s').
End
SubstU_lr.
Section
multiOp.
Variables
dty rty : Set.
Variable
term : list dty -> rty -> Set.
Variable
dtyDenote : dty -> Type.
Variable
rtyDenote : rty -> Type.
Variable
termDenote : forall G t, term G t -> Subst dtyDenote G -> rtyDenote t.
Lemma
Subst_decomp : forall t G (s1 s2 : Subst dtyDenote (t :: G)),
head s1 = head s2
-> tail s1 = tail s2
-> s1 = s2.
Lemma
cast_SCons_head : forall t x G (s : Subst dtyDenote G)
G' (Heq : t :: G = t :: G'),
head (t:= t) (G:= G') (eq_rect _ (Subst dtyDenote) (SCons t x s) _ Heq)
= x.
Lemma
cast_SCons_tail : forall t x G (s : Subst dtyDenote G)
G' (Heq : t :: G = t :: G') Heq',
tail (t:= t) (G:= G') (eq_rect _ (Subst dtyDenote) (SCons t x s) _ Heq)
= eq_rect _ (Subst dtyDenote) s _ Heq'.
Lemma
appSubst_decomp : forall G1 G2 (s1 : Subst dtyDenote G1) (s2 : Subst dtyDenote G2)
G2' (Heq : G1 ++ G2 = G1 ++ G2') Heq',
eq_rect _ (Subst dtyDenote) (appSubst s1 s2) _ Heq
= appSubst s1 (eq_rect _ (Subst dtyDenote) s2 _ Heq').
Lemma
appSubst_nil : forall G (s : Subst dtyDenote G) Heq,
s = eq_rect _ (Subst _) (appSubst s (SNil _)) _ Heq.
Lemma
appSubst_nil' : forall G (s : Subst dtyDenote G) Heq,
appSubst s (SNil _) = eq_rect _ (Subst dtyDenote) s _ Heq.
Theorem
appSubst_assoc : forall G1 (s1 : Subst dtyDenote G1)
G2 (s2 : Subst dtyDenote G2)
G3 (s3 : Subst dtyDenote G3)
Heq,
appSubst s1 (appSubst s2 s3)
= eq_rect _ (Subst dtyDenote) (appSubst (appSubst s1 s2) s3) _ Heq.
Theorem
appSubst_assoc' : forall G1 (s1 : Subst dtyDenote G1)
G2 (s2 : Subst dtyDenote G2)
G3 (s3 : Subst dtyDenote G3)
Heq,
appSubst (appSubst s1 s2) s3
= eq_rect _ (Subst dtyDenote) (appSubst s1 (appSubst s2 s3)) _ Heq.
Lemma
revAppN_Subst_app : forall G1 (s1 : Subst dtyDenote G1) pos,
exists G1', exists s1', forall G2,
exists Heq : revAppN G1 pos G2 = G1' ++ G2,
forall (s2 : Subst dtyDenote G2),
revAppN_Subst s1 pos s2
= eq_rect _ (Subst dtyDenote)
(appSubst s1' s2)
_ (sym_eq Heq).
Lemma
termDenote_ass : forall G1 G2 G3 t (op : term ((G1 ++ G2) ++ G3) t) s1 s2 s3 Heq,
termDenote op (appSubst (appSubst s1 s2) s3)
= termDenote (eq_rect _ (fun G => term G _) op _ Heq) (appSubst s1 (appSubst s2 s3)).
Hint
Resolve app_middle.
Lemma
termDenote_cons_ass : forall t' G1 G2 G3 t (op : term (G1 ++ t' :: G2 ++ G3) t) s1 x s2 s3 Heq,
termDenote op (appSubst s1 (SCons _ x (appSubst s2 s3)))
= termDenote (eq_rect _ (fun G => term G _) op _ Heq) (appSubst (appSubst s1 (SCons _ x (SNil _))) (appSubst s2 s3)).
Definition
termNil : forall G t,
term (G ++ nil) t
-> term G t.
Implicit
Arguments termNil [G t].
Theorem
lastVar'_sound : forall G1 G2 t (s1 : Subst dtyDenote G1) s2 x,
VarDenote
(lastVar' G1 G2 t)
(appSubst s1 (appSubst s2 (SCons _ x (SNil _))))
= x.
Section
lift.
Variable
lift' : forall G G' t, term (G ++ G') t
-> forall t', term (G ++ t' :: G') t.
Definition
liftEnd G' G t (op : term G t) : term (G ++ G') t.
Definition
liftEnd' G'' G G' t (op : term (G ++ G') t) : term (G ++ G' ++ G'') t.
Definition
liftMiddle G'' G G' t (op : term (G ++ G') t) : term (G ++ G'' ++ G') t.
Hypothesis
lift'_sound : forall G G' t (e : term (G ++ G') t)
t' s v,
termDenote (lift' _ _ e t') (liftSubst' _ _ s _ v)
= termDenote e s.
Theorem
liftEnd_sound : forall G' G t
(op : term G t) s1 s2,
termDenote (liftEnd G' op) (appSubst s1 s2)
= termDenote op s1.
Implicit
Arguments liftEnd' [G G' t].
Theorem
liftEnd'_sound : forall G'' G G' t (op : term (G ++ G') t) s1 s2 s3,
termDenote (liftEnd' G'' op) (appSubst s1 (appSubst s2 s3))
= termDenote op (appSubst s1 s2).
Implicit
Arguments liftMiddle [G G' t].
Theorem
liftMiddle_sound : forall G'' G G' t (op : term (G ++ G') t)
s1 s2 s3,
termDenote (liftMiddle G'' op) (appSubst s1 (appSubst s2 s3))
= termDenote op (appSubst s1 s3).
Theorem
liftMiddle_cons_sound : forall G'' t' G G' t (op : term (t' :: G ++ G') t)
x1 s1 s2 s3,
termDenote (liftMiddle (G:= t' :: G) G'' op) (SCons _ x1 (appSubst s1 (appSubst s2 s3)))
= termDenote op (SCons _ x1 (appSubst s1 s3)).
End
lift.
Section
permute.
Variable
permute : forall G1 t1 t2 G2 t, term (G1 ++ t1 :: t2 :: G2) t
-> term (G1 ++ t2 :: t1 :: G2) t.
Definition
front' : forall t' t G2 G1 G3 (lin : term (G1 ++ G2 ++ t' :: G3) t),
term (G1 ++ t' :: G2 ++ G3) t.
Definition
front t' t G1 G2 (lin : term (G1 ++ t' :: G2) t)
: term (t' :: G1 ++ G2) t :=
front' t' G1 nil G2 lin.
Definition
embed' : forall t' t G2 G1 G3 (lin : term (G1 ++ t' :: G2 ++ G3) t),
term (G1 ++ G2 ++ t' :: G3) t.
Definition
embed t' t G1 G2 (lin : term (t' :: G1 ++ G2) t)
: term (G1 ++ t' :: G2) t :=
embed' t' G1 nil G2 lin.
Implicit
Arguments embed [t' t G1 G2].
Definition
multiSwap G2 G1 G3 t (lin : term (G1 ++ G2 ++ G3) t)
: term (G2 ++ G1 ++ G3) t.
Implicit
Arguments multiSwap [G2 G1 G3 t].
Hypothesis
permute_sound : forall G1 t1 t2 G2 t (e : term (G1 ++ t1 :: t2 :: G2) t)
s1 x1 x2 s2,
termDenote (permute _ _ _ _ e) (appSubst s1 (SCons _ x1 (SCons _ x2 s2)))
= termDenote e (appSubst s1 (SCons _ x2 (SCons _ x1 s2))).
Theorem
front'_sound : forall t' t G2 G1 G3 (lin : term (G1 ++ G2 ++ t' :: G3) t)
s1 x s2 s3,
termDenote (front' _ _ _ _ lin) (appSubst s1 (SCons _ x (appSubst s2 s3)))
= termDenote lin (appSubst s1 (appSubst s2 (SCons _ x s3))).
Implicit
Arguments front [t' t G1 G2].
Theorem
front_sound : forall t' t G1 G2 (lin : term (G1 ++ t' :: G2) t)
x s1 s2,
termDenote (front lin) (SCons _ x (appSubst s1 s2))
= termDenote lin (appSubst s1 (SCons _ x s2)).
Theorem
embed'_sound : forall t' t G2 G1 G3 (lin : term (G1 ++ t' :: G2 ++ G3) t)
s1 x s2 s3,
termDenote (embed' _ _ _ _ lin) (appSubst s1 (appSubst s2 (SCons _ x s3)))
= termDenote lin (appSubst s1 (SCons _ x (appSubst s2 s3))).
Theorem
embed_sound : forall t' t G1 G2 (lin : term (t' :: G1 ++ G2) t)
x s1 s2,
termDenote (embed lin) (appSubst s1 (SCons _ x s2))
= termDenote lin (SCons _ x (appSubst s1 s2)).
Definition
eq_cons : forall ls1 ls2 (a : dty), ls1 = ls2 -> a :: ls1 = a :: ls2.
Theorem
cast_cons : forall (P : list dty -> Type) (a : dty) ls1 ls2 (v : P (a :: ls1)) (Heq : ls1 = ls2),
eq_rect _ (fun ls => P (a :: ls)) v _ Heq
= eq_rect _ P v _ (eq_cons _ Heq).
Theorem
multiSwap_sound : forall G2 G1 G3 t (lin : term (G1 ++ G2 ++ G3) t)
s1 s2 s3,
termDenote (multiSwap lin) (appSubst s2 (appSubst s1 s3))
= termDenote lin (appSubst s1 (appSubst s2 s3)).
Definition
eq_app : forall ls1 ls2 (G : list dty), ls1 = ls2 -> G ++ ls1 = G ++ ls2.
Theorem
cast_app : forall (P : list dty -> Type) (G : list dty) ls1 ls2 (v : P (G ++ ls1)) (Heq : ls1 = ls2),
eq_rect _ (fun ls => P (G ++ ls)) v _ Heq
= eq_rect _ P v _ (eq_app _ Heq).
End
permute.
End
multiOp.
Implicit
Arguments termNil [dty rty G t].
Implicit
Arguments front [dty rty term t' t G1 G2].
Implicit
Arguments embed [dty rty term t' t G1 G2].
Implicit
Arguments multiSwap [dty rty term G2 G1 G3 t].
Implicit
Arguments liftEnd [dty rty term G t].
Implicit
Arguments liftEnd' [dty rty term G t].
Implicit
Arguments liftMiddle [dty rty term G G' t].
Implicit
Arguments front_sound [dty rty term dtyDenote rtyDenote termDenote permute t' t G1 G2].
Implicit
Arguments embed_sound [dty rty term dtyDenote rtyDenote termDenote permute t' t G1 G2].
Implicit
Arguments liftEnd_sound [dty rty term dtyDenote rtyDenote termDenote lift'].
Implicit
Arguments liftEnd'_sound [dty rty term dtyDenote rtyDenote termDenote lift'].
Implicit
Arguments liftMiddle_sound [dty rty term dtyDenote rtyDenote termDenote lift'].
Implicit
Arguments liftMiddle_cons_sound [dty rty term dtyDenote rtyDenote termDenote lift'].
Implicit
Arguments multiSwap_sound [dty rty term dtyDenote rtyDenote termDenote permute].
Section
strengthen.
Variable
dom : Set.
Fixpoint
varInfo (G : list dom) : Set :=
match G with
| nil => unit
| _ :: G' => (bool * varInfo G')%type
end.
Fixpoint
varInfo_incl (G : list dom) : varInfo G -> varInfo G -> Prop :=
match G return (varInfo G -> varInfo G -> Prop) with
| nil => fun _ _ => True
| _ :: _ => fun vi1 vi2 => implb (fst vi1) (fst vi2) = true /\ varInfo_incl _ (snd vi1) (snd vi2)
end.
Implicit
Arguments varInfo_incl [G].
Fixpoint
varInfo_none (G : list dom) : varInfo G :=
match G return (varInfo G) with
| nil => tt
| _ :: G' => (false, varInfo_none G')
end.
Fixpoint
varInfo_all (G : list dom) : varInfo G :=
match G return (varInfo G) with
| nil => tt
| _ :: G' => (true, varInfo_all G')
end.
Fixpoint
varInfo_pad (G1 : list dom) : forall G2, varInfo G2 -> varInfo (G1 ++ G2) :=
match G1 return (forall G2, varInfo G2 -> varInfo (G1 ++ G2)) with
| nil => fun _ vi => vi
| _ :: G1' => fun _ vi => (true, varInfo_pad G1' _ vi)
end.
Fixpoint
varInfo_drop (G2 G1 : list dom) {struct G1} : varInfo (G1 ++ G2) -> varInfo G2 :=
match G1 return (varInfo (G1 ++ G2) -> varInfo G2) with
| nil => fun vi => vi
| _ :: _ => fun vi => varInfo_drop _ _ (snd vi)
end.
Fixpoint
varInfo_keep (G2 G1 : list dom) {struct G1} : varInfo (G1 ++ G2) -> varInfo (G1 ++ G2) :=
match G1 return (varInfo (G1 ++ G2) -> varInfo (G1 ++ G2)) with
| nil => fun _ => varInfo_all _
| _ :: _ => fun vi => (fst vi, varInfo_keep _ _ (snd vi))
end.
Fixpoint
varInfo_take (G1 G2 : list dom) {struct G1} : varInfo (G1 ++ G2) -> varInfo G1 :=
match G1 return (varInfo (G1 ++ G2) -> varInfo G1) with
| nil => fun _ => tt
| _ :: _ => fun vi => (fst vi, varInfo_take _ _ (snd vi))
end.
Fixpoint
varInfo_app (G1 G2 : list dom) {struct G1} : varInfo G1 -> varInfo G2 -> varInfo (G1 ++ G2) :=
match G1 return (varInfo G1 -> varInfo G2 -> varInfo (G1 ++ G2)) with
| nil => fun _ vi2 => vi2
| _ :: _ => fun vi1 vi2 => (fst vi1, varInfo_app _ _ (snd vi1) vi2)
end.
Fixpoint
Var_freeVars (G : list dom) (t : dom) (v : Var G t) {struct v}
: varInfo G :=
match v in (Var G t) return (varInfo G) with
| First _ _ => (true, varInfo_none _)
| Next _ _ _ v' => (false, Var_freeVars v')
end.
Fixpoint
varInfo_apply (G : list dom) : varInfo G -> list dom :=
match G return (varInfo G -> list dom) with
| nil => fun _ => nil
| t :: G' => fun vi =>
if fst vi
then t :: varInfo_apply G' (snd vi)
else varInfo_apply G' (snd vi)
end.
Theorem
varInfo_apply_pad : forall G1 G2 (vi : varInfo G2),
varInfo_apply _ (varInfo_pad G1 _ vi)
= G1 ++ varInfo_apply _ vi.
Theorem
varInfo_all_incl : forall G (vi : varInfo G),
varInfo_incl vi (varInfo_all _).
Hint
Resolve varInfo_all_incl.
Theorem
varInfo_keep_incl : forall G1 G2 (vi : varInfo (G1 ++ G2)),
varInfo_incl vi (varInfo_keep _ _ vi).
Theorem
varInfo_incl_take G1 G2 (vi : varInfo (G1 ++ G2))
: varInfo_incl vi (varInfo_app _ _ (varInfo_take _ _ vi) (varInfo_all G2)).
Theorem
varInfo_incl_split : forall G1 G2 (vi1 vi2 : varInfo (G1 ++ G2)),
varInfo_incl (varInfo_take _ _ vi1) (varInfo_take _ _ vi2)
-> varInfo_incl (varInfo_drop _ _ vi1) (varInfo_drop _ _ vi2)
-> varInfo_incl vi1 vi2.
Theorem
varInfo_take_app : forall G1 G2 (vi1 : varInfo G1) (vi2 : varInfo G2),
varInfo_take _ _ (varInfo_app _ _ vi1 vi2) = vi1.
Theorem
varInfo_drop_app : forall G1 G2 (vi1 : varInfo G1) (vi2 : varInfo G2),
varInfo_drop _ _ (varInfo_app _ _ vi1 vi2) = vi2.
Theorem
varInfo_incl_take_drop G1 G2 G3 (vi : varInfo (G1 ++ G2 ++ G3))
: varInfo_incl vi
(varInfo_app _ _
(varInfo_all G1)
(varInfo_app _ _
(varInfo_take _ _ (varInfo_drop _ _ vi))
(varInfo_all G3))).
Theorem
varInfo_apply_all : forall G (vi : varInfo G),
G = varInfo_apply _ (varInfo_all G).
Hint
Resolve varInfo_apply_all.
Theorem
varInfo_apply_take G1 G2 (vi : varInfo (G1 ++ G2))
: varInfo_apply G1 (varInfo_take _ _ vi) ++ G2
= varInfo_apply (G1 ++ G2)
(varInfo_app _ _
(varInfo_take _ _ vi)
(varInfo_all G2)).
Theorem
varInfo_apply_drop G1 G2 (vi : varInfo G2)
: varInfo_apply (G1 ++ G2)
(varInfo_app _ _
(varInfo_all G1) vi)
= G1 ++ varInfo_apply G2 vi.
Theorem
varInfo_apply_take_drop G1 G2 G3 (vi : varInfo (G1 ++ G2 ++ G3))
: G1 ++ varInfo_apply G2 (varInfo_take _ _ (varInfo_drop _ _ vi)) ++ G3
= varInfo_apply (G1 ++ G2 ++ G3)
(varInfo_app _ _
(varInfo_all G1)
(varInfo_app _ _
(varInfo_take _ _ (varInfo_drop _ _ vi))
(varInfo_all G3))).
Lemma
strengthen_First : forall G t vi,
varInfo_incl (Var_freeVars (First G t)) vi
-> Var (t :: varInfo_apply G (snd vi)) t
-> Var (varInfo_apply (t :: G) vi) t.
Lemma
strengthen_Next_true : forall G t t' vi,
fst vi = true
-> Var (t' :: varInfo_apply G (snd vi)) t
-> Var (varInfo_apply (t' :: G) vi) t.
Implicit
Arguments strengthen_Next_true [G t t' vi].
Lemma
strengthen_Next_false : forall G t t' vi,
fst vi = false
-> Var (varInfo_apply G (snd vi)) t
-> Var (varInfo_apply (t' :: G) vi) t.
Implicit
Arguments strengthen_Next_false [G t t' vi].
Fixpoint
Var_strengthen (G : list dom) (t : dom) (v : Var G t) {struct v}
: forall (vi : varInfo G), varInfo_incl (Var_freeVars v) vi -> Var (varInfo_apply G vi) t :=
match v in (Var G t) return (forall (vi : varInfo G), varInfo_incl (Var_freeVars v) vi -> Var (varInfo_apply G vi) t) with
| First _ _ => fun vi Hscoped => strengthen_First Hscoped (First _ _)
| Next _ _ _ v' => fun vi Hscoped =>
match fst vi as b return (fst vi = b -> _) with
| true => fun Heq => strengthen_Next_true Heq (Next _ (Var_strengthen v' _ (proj2 Hscoped)))
| false => fun Heq => strengthen_Next_false Heq (Var_strengthen v' _ (proj2 Hscoped))
end (refl_equal _)
end.
Fixpoint
varInfo_join (G : list dom) : varInfo G -> varInfo G -> varInfo G :=
match G return (varInfo G -> varInfo G -> varInfo G) with
| nil => fun _ _ => tt
| _ :: G' => fun vi1 vi2 => (orb (fst vi1) (fst vi2), varInfo_join _ (snd vi1) (snd vi2))
end.
Implicit
Arguments varInfo_join [G].
Theorem
varInfo_join_incl : forall G (vi : varInfo G)
vi1, varInfo_incl vi vi1
-> forall vi2, varInfo_incl vi vi2
-> varInfo_incl vi (varInfo_join vi1 vi2).
Hint
Resolve varInfo_join_incl.
Theorem
varInfo_join_incl1 : forall G (vi1 vi2 : varInfo G),
varInfo_incl vi1 (varInfo_join vi1 vi2).
Hint
Resolve varInfo_join_incl1.
Theorem
varInfo_join_incl2 : forall G (vi1 vi2 : varInfo G),
varInfo_incl vi1 (varInfo_join vi2 vi1).
Hint
Resolve varInfo_join_incl2.
Theorem
varInfo_double_join_incl : forall G (vi1 vi2 vi : varInfo G),
varInfo_incl vi1 vi2
-> varInfo_incl (varInfo_join vi1 vi) (varInfo_join vi2 vi).
Hint
Resolve varInfo_double_join_incl.
Theorem
varInfo_fold_incl_acc' : forall G (ls : list (varInfo G)) (vi1 vi2 : varInfo G),
varInfo_incl vi1 vi2
-> varInfo_incl
(fold_left (varInfo_join (G:= _)) ls vi1)
(fold_left (varInfo_join (G:= _)) ls vi2).
Hint
Resolve varInfo_fold_incl_acc'.
Theorem
varInfo_incl_trans : forall G (v1 v2 v3 : varInfo G),
varInfo_incl v1 v2
-> varInfo_incl v2 v3
-> varInfo_incl v1 v3.
Hint
Resolve varInfo_incl_trans.
Theorem
varInfo_fold_incl_acc : forall G (vi2 : varInfo G) (ls : list (varInfo G)) (vi1 : varInfo G),
varInfo_incl (fold_left (varInfo_join (G:= _)) ls vi1) vi2
-> varInfo_incl vi1 vi2.
Hint
Resolve varInfo_fold_incl_acc.
Theorem
varInfo_incl_refl : forall G (vi : varInfo G),
varInfo_incl vi vi.
Hint
Resolve varInfo_incl_refl.
Theorem
varInfo_fold_incl_acc'' : forall G (vi2 : varInfo G) (ls : list (varInfo G)) (vi : varInfo G),
varInfo_incl vi (fold_left (varInfo_join (G:= _)) ls vi).
Hint
Resolve varInfo_fold_incl_acc''.
Theorem
varInfo_fold_incl_ls : forall G (vi2 : varInfo G) (ls : list (varInfo G)) (vi1 : varInfo G),
varInfo_incl (fold_left (varInfo_join (G:= _)) ls vi1) vi2
-> forall vi, In vi ls
-> varInfo_incl vi vi2.
Theorem
varInfo_incl_drop : forall G1 G2 (vi1 : varInfo (G1 ++ G2)) vi2,
varInfo_incl (varInfo_drop _ _ vi1) vi2
-> varInfo_incl vi1 (varInfo_pad _ _ vi2).
Variable
denote : dom -> Type.
Lemma
strengthen_SCons_true : forall G t' vi,
fst vi = true
-> Subst denote (t' :: varInfo_apply G (snd vi))
-> Subst denote (varInfo_apply (t' :: G) vi).
Implicit
Arguments strengthen_SCons_true [G t' vi].
Lemma
strengthen_SCons_false : forall G t' vi,
fst vi = false
-> Subst denote (varInfo_apply G (snd vi))
-> Subst denote (varInfo_apply (t' :: G) vi).
Implicit
Arguments strengthen_SCons_false [G t' vi].
Fixpoint
Subst_strengthen (G : list dom) (s : Subst denote G) {struct s}
: forall (vi : varInfo G), Subst denote (varInfo_apply G vi) :=
match s in (Subst _ G) return (forall (vi : varInfo G), Subst denote (varInfo_apply G vi)) with
| SNil => fun _ => SNil _
| SCons _ _ x s' => fun vi =>
match fst vi as b return (fst vi = b -> _) with
| true => fun Heq => strengthen_SCons_true Heq (SCons _ x (Subst_strengthen s' (snd vi)))
| false => fun Heq => strengthen_SCons_false Heq (Subst_strengthen s' (snd vi))
end (refl_equal _)
end.
Theorem
Subst_strengthen_all : forall (G : list dom) s Heq,
eq_rect _ (Subst denote) (Subst_strengthen s (varInfo_all G)) _ Heq = s.
Theorem
Var_strengthen_sound : forall G t (v : Var G t) vi
(Hscoped : varInfo_incl (Var_freeVars v) vi) s,
VarDenote (Var_strengthen v vi Hscoped) (Subst_strengthen s vi)
= VarDenote v s.
End
strengthen.
Implicit
Arguments frontVar [dom G1 t G2 t'].
Implicit
Arguments varInfo_join [dom G].
Implicit
Arguments varInfo_pad [dom G2].
Implicit
Arguments varInfo_drop [dom G1 G2].
Implicit
Arguments varInfo_keep [dom G1 G2].
Implicit
Arguments varInfo_take [dom G1 G2].
Implicit
Arguments varInfo_incl [dom G].
Implicit
Arguments varInfo_app [dom G1 G2].
Index
This page has been generated by coqdoc