Require Import List.
Require Import String.
Open Scope string_scope.
Definition var := string.
Inductive Expr : Set :=
| Var : var -> Expr
| App : Expr -> Expr -> Expr
| Lam : var -> Expr -> Expr.
Notation "'V' x" := (Var x) (at level 48).
Notation "e1 @ e2" := (App e1 e2) (at level 49).
Notation "\ x , t" := (Lam x t) (at level 50).
Check (\"x", \"y", V"x").
Check (\"x", \"y", V"y").
Check ((\"x", V"x" @ V"x") @ (\"x", V"x" @ V"x")).
Inductive Subst : Expr -> Expr -> var ->
Expr -> Prop :=
| SubstVar_same : forall e x,
Subst (V x) e x e
| SubstVar_diff : forall e x1 x2,
x1 <> x2 ->
Subst (V x1) e x2 (V x1)
| SubstApp : forall eA eB e x eA' eB',
Subst eA e x eA' ->
Subst eB e x eB' ->
Subst (eA @ eB) e x (eA' @ eB')
| SubstLam_same : forall eA e x,
Subst (\x, eA) e x (\x, eA)
| SubstLam_diff : forall eA e x1 x2 eA',
x1 <> x2 ->
Subst eA e x2 eA' ->
Subst (\x1, eA) e x2 (\x1, eA').
Lemma subst_test_1:
Subst (\"x", V"y") (V"z") "y" (\"x", V"z").
Proof.
constructor.
{ discriminate. }
{ constructor. }
Qed.
Lemma subst_test_2:
Subst (\"x", V"x") (V"z") "x"
(\"x", V"x").
Proof.
constructor.
Qed.
Require Import String.
Open Scope string_scope.
Definition var := string.
Inductive Expr : Set :=
| Var : var -> Expr
| App : Expr -> Expr -> Expr
| Lam : var -> Expr -> Expr.
Notation "'V' x" := (Var x) (at level 48).
Notation "e1 @ e2" := (App e1 e2) (at level 49).
Notation "\ x , t" := (Lam x t) (at level 50).
Check (\"x", \"y", V"x").
Check (\"x", \"y", V"y").
Check ((\"x", V"x" @ V"x") @ (\"x", V"x" @ V"x")).
Inductive Subst : Expr -> Expr -> var ->
Expr -> Prop :=
| SubstVar_same : forall e x,
Subst (V x) e x e
| SubstVar_diff : forall e x1 x2,
x1 <> x2 ->
Subst (V x1) e x2 (V x1)
| SubstApp : forall eA eB e x eA' eB',
Subst eA e x eA' ->
Subst eB e x eB' ->
Subst (eA @ eB) e x (eA' @ eB')
| SubstLam_same : forall eA e x,
Subst (\x, eA) e x (\x, eA)
| SubstLam_diff : forall eA e x1 x2 eA',
x1 <> x2 ->
Subst eA e x2 eA' ->
Subst (\x1, eA) e x2 (\x1, eA').
Lemma subst_test_1:
Subst (\"x", V"y") (V"z") "y" (\"x", V"z").
Proof.
constructor.
{ discriminate. }
{ constructor. }
Qed.
Lemma subst_test_2:
Subst (\"x", V"x") (V"z") "x"
(\"x", V"x").
Proof.
constructor.
Qed.
Small Step:
e1 --> e1' --------------------- e1 e2 --> e1' e2 ----------------------------- (\x. e1) e2 --> e1[e2/x]
Inductive SStep : Expr -> Expr -> Prop :=
| Scrunch : forall e1 e1' e2,
SStep e1 e1' ->
SStep (e1 @ e2) (e1' @ e2)
| Ssubst : forall x e1 e2 e1',
Subst e1 e2 x e1' ->
SStep ((\x, e1) @ e2) e1'.
Notation "e1 --> e2" := (SStep e1 e2) (at level 51).
Lemma sstep_test_1:
(\"x", V"x") @ V"z" --> V"z".
Proof.
apply Ssubst.
apply SubstVar_same.
Qed.
Lemma Lam_nostep:
forall x e1 e2,
~ (\x, e1 --> e2).
Proof.
intros. intro. inversion H.
Qed.
Lemma Subst_det:
forall e1 e2 x e3,
Subst e1 e2 x e3 ->
forall e3',
Subst e1 e2 x e3' ->
e3 = e3'.
Proof.
induction 1; intros.
{ inversion H; subst; auto.
congruence.
}
{ inversion H0; subst; auto.
congruence.
}
{ inversion H1; subst; auto.
f_equal; auto.
}
{ inversion H; subst; auto.
congruence.
}
{ inversion H1; subst; auto.
{ congruence. }
{ f_equal; auto. }
}
Qed.
Lemma SStep_det:
forall e e1,
e --> e1 ->
forall e2,
e --> e2 ->
e1 = e2.
Proof.
intro. intro. intro. induction H.
{ intros. inversion H0.
{ subst. f_equal. auto. }
{ subst. apply Lam_nostep in H. contradiction. }
}
{ intros. inversion H0.
{ subst. apply Lam_nostep in H4. contradiction. }
{ subst. eapply Subst_det in H5.
{ eassumption. }
{ assumption. }
}
}
Qed.
Big Step:
--------------------- \x. e ==> \x. e e1 ==> \x.e1' e1'[e2/x] ==> v ------------------------------------ e1 e2 ==> v
Inductive BStep : Expr -> Expr -> Prop :=
| BSval : forall x e,
BStep (\x, e) (\x, e)
| BSsubst : forall e1 e2 x e1' e2' v,
BStep e1 (\x, e1') ->
Subst e1' e2 x e2' ->
BStep e2' v ->
BStep (e1 @ e2) v.
Notation "e1 ==> e2" := (BStep e1 e2) (at level 51).
Lemma bstep_test_1:
(\"x", V"x") @ (\"y", V"y") ==> (\"y", V"y").
Proof.
econstructor.
{ left. }
{ constructor. }
{ left. }
Qed.
Lemma bstep_test_2:
forall e,
~ (V"x" ==> e).
Proof.
intro. intro. inversion H.
Qed.
Lemma bstep_lam_inv:
forall x1 e1 x2 e2,
\x1, e1 ==> \x2, e2 ->
x1 = x2 /\ e1 = e2.
Proof.
intros. inversion H. auto.
Qed.
Lemma bstep_test_3:
forall e1,
e1 = (\"x", V"x" @ V"x") @ (\"x", V"x" @ V"x") ->
forall e2,
~ (e1 ==> e2).
Proof.
intros. intro. induction H0.
{ discriminate. }
{ inversion H. subst. inversion H0_. subst. inversion H0. subst. inversion H3.
{ subst. inversion H7.
{ subst. auto. }
{ auto. }
}
{ auto. }
}
Qed.
Lemma bstep_det:
forall e e1,
e ==> e1 ->
forall e2,
e ==> e2 ->
e1 = e2.
Proof.
intro. intro. intro. induction H.
{ intros. inversion H. reflexivity. }
{ intros. inversion H2. subst.
apply IHBStep1 in H5. inversion H5. subst.
replace e2'0 with e2' in *.
{ auto. }
{ eapply Subst_det.
{ eassumption. }
{ assumption. }
}
}
Qed.
Inductive SSstar : Expr -> Expr -> Prop :=
| SSrefl : forall e,
SSstar e e
| SSstep : forall e e' e'',
SStep e e' ->
SSstar e' e'' ->
SSstar e e''.
Notation "e1 -->* e2" := (SSstar e1 e2) (at level 51).
Lemma SStar_trans:
forall e1 e2 e3,
e1 -->* e2 ->
e2 -->* e3 ->
e1 -->* e3.
Proof.
intros. induction H.
{ assumption. }
{ econstructor.
{ eassumption. }
{ auto. }
}
Qed.
Lemma SStar_crunch_left:
forall e1 e1',
e1 -->* e1' ->
forall e2,
e1 @ e2 -->* e1' @ e2.
Proof.
intro. intro. intro. induction H.
{ left. }
{ intro. econstructor.
{ left. eassumption. }
{ auto. }
}
Qed.
Lemma BStep_SSstar:
forall e1 e2,
e1 ==> e2 ->
e1 -->* e2.
Proof.
intros. induction H.
{ left. }
{ eapply SStar_trans with (e2 := (\x, e1') @ e2).
{ apply SStar_crunch_left. assumption. }
{ econstructor.
{ right. eassumption. }
{ assumption. }
}
}
Qed.
This page has been generated by coqdoc