Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
From mathcomp Require Import all_ssreflect. (* Lambda calculator *) Module Lambda. Inductive expr : Set := | Var of nat | Abs of expr | App of expr & expr. Fixpoint shift k (e : expr) := match e with | Var n => if k <= n then Var n.+1 else Var n | Abs e1 => Abs (shift k.+1 e1) | App e1 e2 => App (shift k e1) (shift k e2) end. Fixpoint open_rec k u (e : expr) := match e with | Var n => if k == n then u else if leq k n then Var n.-1 else e | Abs e1 => Abs (open_rec k.+1 (shift 0 u) e1) | App e1 e2 => App (open_rec k u e1) (open_rec k u e2) end. Fixpoint reduce (e : expr) : option expr := match e with | App (Abs e1) e2 => Some (open_rec 0 e2 e1) | App e1 e2 => match reduce e1, reduce e2 with | Some e1', _ => Some (App e1' e2) | None, Some e2' => Some (App e1 e2') | None, None => None end | Abs e1 => if reduce e1 is Some e1' then Some (Abs e1') else None | _ => None end. Fixpoint eval (n : nat) e := if n is k.+1 then if reduce e is Some e' then eval k e' else e else e. Coercion Var : nat >-> expr. (* 自然数を変数として直接に使える *) Definition one := Abs (Abs (App 1 0)). (* λf.λx.(f x) *) Definition church (n : nat) := Abs (Abs (iter n (App 1) 0)). Eval compute in church 3. Definition chadd := Abs (Abs (Abs (Abs (App (App 3 1) (App (App 2 1) 0))))). (* λm.λn.λf.λx.(m f (n f x)) *) Eval compute in eval 6 (App (App chadd (church 3)) (church 2)). Inductive reduces : expr -> expr -> Prop := | Rbeta : forall e1 e2, reduces (App (Abs e1) e2) (open_rec 0 e2 e1) | Rapp1 : forall e1 e2 e1', reduces e1 e1' -> reduces (App e1 e2) (App e1' e2) | Rapp2 : forall e1 e2 e2', reduces e2 e2' -> reduces (App e1 e2) (App e1 e2') | Rabs : forall e1 e1', reduces e1 e1' -> reduces (Abs e1) (Abs e1'). (* 反射推移閉包 *) Inductive RT_closure {A} (R : A -> A -> Prop) : A -> A -> Prop := | RTbase : forall a, RT_closure R a a | RTnext : forall a b c, R a b -> RT_closure R b c -> RT_closure R a c. Hint Constructors reduces RT_closure : core. Lemma reduce_ok e e' : reduce e = Some e' -> reduces e e'. Proof. move: e'; induction e => //= e'. case He: (reduce e) => [e1|] // [] <-. admit. destruct e1 => //. - admit. - case => <-. by constructor. - case He1: (reduce (App _ _)) => [e1'|]. case => <-. Admitted. Theorem eval_ok n e e' : eval n e = e' -> RT_closure reduces e e'. Admitted. Fixpoint closed_expr n e := match e with | Var k => k < n | App e1 e2 => closed_expr n e1 && closed_expr n e2 | Abs e1 => closed_expr n.+1 e1 end. Lemma shift_closed n e : closed_expr n e -> shift n e = e. Admitted. Lemma open_rec_closed n u e : closed_expr n e -> open_rec n u e = e. Proof. move: n u. induction e => //= k u Hc. - case: ifP => Hk1. by rewrite (eqP Hk1) ltnn in Hc. by rewrite leqNgt Hc. Admitted. Lemma closed_iter_app n k e1 e2 : closed_expr k e1 -> closed_expr k e2 -> closed_expr k (iter n (App e1) e2). Admitted. Lemma closed_church n : closed_expr 0 (church n). Admitted. Lemma closed_expr_S n e : closed_expr n e -> closed_expr n.+1 e. Admitted. Hint Resolve closed_iter_app closed_church closed_expr_S. Lemma open_iter_app k n u e1 e2 : open_rec k u (iter n (App e1) e2) = iter n (App (open_rec k u e1)) (open_rec k u e2). Admitted. Lemma reduces_iter n e1 e2 e2' : reduces e2 e2' -> reduces (iter n (App e1) e2) (iter n (App e1) e2'). Admitted. Theorem chadd_ok' m n : RT_closure reduces (App (App chadd (church m)) (church n)) (church (m+n)). Proof. eapply RTnext; repeat constructor. rewrite /=. rewrite !shift_closed; auto. eapply RTnext; repeat constructor. rewrite /=. rewrite !(shift_closed,open_rec_closed); auto. Admitted. Lemma reduce_iter_app n (k : nat) x : reduce (iter n (App k) x) = if reduce x is Some x' then Some (iter n (App k) x') else None. Admitted. Lemma eval_add m n e : eval (m+n) e = eval m (eval n e). Admitted. Theorem chadd_ok m n : exists h, exists h', eval h (App (App chadd (church m)) (church n)) = eval h' (church (m+n)). Proof. elim: m n => [|m IHm] n. rewrite add0n. exists 6; exists 0 => /=. rewrite !(shift_closed,open_iter_app); auto. case: {IHm}(IHm n.+1) => h [h' IHm]. exists (6+h); exists (6+h'). rewrite (addSnnS m) -(addn1 m). move: (f_equal (eval 6) IHm). rewrite -!eval_add => <- /=. rewrite !(shift_closed,open_iter_app) /=; auto. do! rewrite !reduce_iter_app /=. by rewrite iter_add. Qed. End Lambda.