Library CoqLecDemo
This HTML was automatically generated. To play
with these definitions in Coq, dowload the source from
http://www.cs.cornell.edu/~aa755/CS6110/CoqLecDemo.v
Require Export Omega.
Section nat_defn.
Inductive nat : Type :=
| O
| S (n : nat).
Fixpoint plus (n m : nat) : nat :=
match n with
| O ⇒ m
| S n' ⇒ S (plus n' m)
end.
Eval compute in O.
Eval compute in (S O).
Eval compute in (plus (S O) (S (S O))).
End nat_defn.
Coq already provides basic data structures like nat in its
standard library. We will now use that version instead.
Require Export Datatypes.
Check (S (S O)).
Definition Var : Type := nat.
Definition vx : Var := 0.
Definition vy : Var := 1.
Definition vz : Var := 2.
Inductive Term : Type :=
| var (v : Var)
| ap (f : Term) (arg : Term)
| lam (v : Var) (b: Term).
Check (lam vx (var vx)).
Require Export Coq.Lists.List.
Check (nil).
Check (cons 1 nil).
Check (cons 2 (cons 1 nil)).
Print list.
Notation "x :: y" := (cons x y)
(at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x , .. , y ]"
:= (cons x .. (cons y []) ..).
Notation "x ++ y" := (app x y)
(at level 60, right associativity).
SearchPattern (list ?T → list ?T → list ?T).
Locate "++".
Notation "l -- y" := (remove eq_nat_dec y l)
(at level 100).
Fixpoint freeVars (t:Term) : list Var :=
match t with
| var v ⇒ [v]
| ap f a ⇒ (freeVars f) ++ (freeVars a)
| lam v b ⇒ (freeVars b) -- v
end.
Fixpoint boundVars (t:Term) : list Var :=
match t with
| var v ⇒ []
| ap f a ⇒ (boundVars f) ++ (boundVars a)
| lam v b ⇒ v::(boundVars b)
end.
Notation "a ∈ l" := ((In a l)) (at level 100).
Notation "a ∉ l" := (¬ (In a l)) (at level 100).
Locate "~".
Require Export Coq.Unicode.Utf8.
Locate "∀".
SearchPattern (list ?T → ?T → Prop).
SearchPattern (?T → list ?T → Prop).
Lemma freeVarsNotBound:
∀ (v: Var) (t: Term),
(v ∈ (freeVars t))
→ (v ∉ (boundVars t)).
Proof.
induction t.
- simpl. tauto.
- simpl. intros Hc.
SearchAbout In app.
SearchAbout In app iff.
apply in_app_or in Hc.
rewrite in_app_iff.
Check (S (S O)).
Definition Var : Type := nat.
Definition vx : Var := 0.
Definition vy : Var := 1.
Definition vz : Var := 2.
Inductive Term : Type :=
| var (v : Var)
| ap (f : Term) (arg : Term)
| lam (v : Var) (b: Term).
Check (lam vx (var vx)).
Require Export Coq.Lists.List.
Check (nil).
Check (cons 1 nil).
Check (cons 2 (cons 1 nil)).
Print list.
Notation "x :: y" := (cons x y)
(at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x , .. , y ]"
:= (cons x .. (cons y []) ..).
Notation "x ++ y" := (app x y)
(at level 60, right associativity).
SearchPattern (list ?T → list ?T → list ?T).
Locate "++".
Notation "l -- y" := (remove eq_nat_dec y l)
(at level 100).
Fixpoint freeVars (t:Term) : list Var :=
match t with
| var v ⇒ [v]
| ap f a ⇒ (freeVars f) ++ (freeVars a)
| lam v b ⇒ (freeVars b) -- v
end.
Fixpoint boundVars (t:Term) : list Var :=
match t with
| var v ⇒ []
| ap f a ⇒ (boundVars f) ++ (boundVars a)
| lam v b ⇒ v::(boundVars b)
end.
Notation "a ∈ l" := ((In a l)) (at level 100).
Notation "a ∉ l" := (¬ (In a l)) (at level 100).
Locate "~".
Require Export Coq.Unicode.Utf8.
Locate "∀".
SearchPattern (list ?T → ?T → Prop).
SearchPattern (?T → list ?T → Prop).
Lemma freeVarsNotBound:
∀ (v: Var) (t: Term),
(v ∈ (freeVars t))
→ (v ∉ (boundVars t)).
Proof.
induction t.
- simpl. tauto.
- simpl. intros Hc.
SearchAbout In app.
SearchAbout In app iff.
apply in_app_or in Hc.
rewrite in_app_iff.
one can rewrite with an iff
Abort.
SearchAbout nat sumbool.
Check eq_nat_dec.
Notation "n =?= m" := (eq_nat_dec n m) (at level 60).
SearchAbout nat sumbool.
Check eq_nat_dec.
Notation "n =?= m" := (eq_nat_dec n m) (at level 60).
What is the difference between
"n =?= m" and "n = m" ?
The latter is a logical formula asserting n=m.
You cannot do
case analysis (e.g. in the if-then-else below) on the it.
The former is similar to a boolean value
which is "true" iff n=m.
By the end of this course, you will know much
more about the difference
This substitution function only works if the free variables of
a are disjoint from the bound variables of t
Fixpoint substAux (t:Term)
(v: Var) (a : Term) : Term :=
match t with
| var v' ⇒ if ( v =?= v') then a else var v'
| ap f arg ⇒ ap (substAux f v a) (substAux arg v a)
| lam v' b ⇒ lam v'
(if (v =?= v')
then b
else (substAux b v a))
end.
Notation "t [[ a // v ]]" :=
(substAux t v a) (at level 100).
If this seems obvious,
note that it is not true for safe substitution
Lemma substAuxSame : ∀ (t:Term) (v: Var),
t [[ (var v) // v ]] = t.
Proof.
induction t.
- intros v'. simpl.
case (eq_nat_dec v' v).
+ congruence.
+ congruence.
- intros. simpl. congruence.
- intros v'. simpl. case (eq_nat_dec v' v).
+ congruence.
+ intros H. rewrite IHt. reflexivity.
Qed.
Now we need to define safe substiution.
For that we need an ability
to generate fresh variables.
Feel free to skip the next 3
definitions and directly look at
freshVar
Fixpoint fresh_var_aux (v : nat) (vars : list Var)
: nat :=
match vars with
| nil ⇒ v
| x::xs ⇒
if lt_dec v x then v
else if eq_nat_dec v x
then fresh_var_aux (S v) xs
else fresh_var_aux v xs
end.
Locate "::".
Fixpoint insert (v : nat) (vars : list Var)
: list Var :=
match vars with
| nil ⇒ [v]
| x::xs ⇒
if lt_dec x v then x::(insert v xs)
else if eq_nat_dec x v then vars
else v::vars
end.
Fixpoint sort (vars : list Var) : list Var :=
match vars with
| nil ⇒ []
| x :: xs ⇒ insert x (sort xs)
end.
Definition freshVar (v:Var) (vars : list Var) : Var :=
(fresh_var_aux v (sort vars)).
using the Admitted keyword,
One can start using a lemma
even before proving it.
This is often useful for
to-down proof development.
Lemma fresh_var_not_in :
∀ (v:Var) (vars : list Var),
((freshVar v vars) ∉ vars).
Admitted.
Lemma fresh_var_nil : ∀ (v:Var),
freshVar v nil = v.
Proof.
intros. unfold freshVar. simpl.
reflexivity.
Qed.
Notation "n ∈? m" := (in_dec eq_nat_dec n m) (at level 100).
SearchAbout sumbool In.
∀ (v:Var) (vars : list Var),
((freshVar v vars) ∉ vars).
Admitted.
Lemma fresh_var_nil : ∀ (v:Var),
freshVar v nil = v.
Proof.
intros. unfold freshVar. simpl.
reflexivity.
Qed.
Notation "n ∈? m" := (in_dec eq_nat_dec n m) (at level 100).
SearchAbout sumbool In.
Definition from lecture notes
Section 2.2 of
http://www.cs.cornell.edu/courses/CS6110/2010sp/lectures/lec02.pdf
It is not "structurally recursive".
Uncomment the definition of
safeSubst below and see Coq's error message
Fixpoint safeSubst (t:Term)
(x: Var) (e : Term) : Term :=
match t with
| var v ⇒ if (x =?= v) then e else var v
| ap f arg ⇒ ap (safeSubst f x e) (safeSubst arg x e)
| lam y eo ⇒
if (x =?= y)
then
lam y eo
else
if (y ∈? (freeVars e))
then
let z := freshVar
y ([x]++(freeVars e)++ (freeVars eo)) in
lam z (safeSubst (safeSubst eo y (var z)) x e)
else
lam y (safeSubst eo x e)
end.
There are many ways to get around the
above problem. Thos who have
not yet submitted their solution
to Problem 3 of PS1 can define
safe substitution in the following way:
First define the folowing structurally recursive
function:
Fixpoint renameBoundVars
(t:Term) (vAvoid : list Var)
: Term :=
Uncomment the above and fill in the body.
renameBoundVars t vAvoid is supposed
to be a term which is alpha equal to t
and whose bound variables are disjoint
from vAvoid. Hint : You can use substAux
One can now compose renameBoundVars
and substAux to define safe substitution.
Fixpoint safeSubst (t:Term)
(x: Var) (e : Term) : Term :=
match t with
| var v ⇒ if (x =?= v) then e else var v
| ap f arg ⇒ ap (safeSubst f x e) (safeSubst arg x e)
| lam y eo ⇒
if (x =?= y)
then
lam y eo
else
if (y ∈? (freeVars e))
then
let z := freshVar
y ([x]++(freeVars e)++ (freeVars eo)) in
lam z (safeSubst (safeSubst eo y (var z)) x e)
else
lam y (safeSubst eo x e)
end.
Fixpoint renameBoundVars
(t:Term) (vAvoid : list Var)
: Term :=