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
 | Om
 | 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 ?Tlist ?Tlist ?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 bv::(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 → ?TProp).
SearchPattern (?Tlist ?TProp).

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).

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 argap (substAux f v a) (substAux arg v a)
| lam v' blam 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
    | nilv
    | 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 :: xsinsert 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.

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 vif (x =?= v) then e else var v
| ap f argap (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.