今日のCoq: eval
よく分からないこと
最初、termを与えると値になるまで評価するevalを書いてみました。
.... Function eval (t :term) {measure term_length t} : term := match t with Var _ | Bool _ | Lambda _ _ _ => t | Apply (Lambda x _ body as t1) t2 => if is_value t2 then eval (subst body x t2) else eval (Apply t1 (eval t2)) | Apply t1 t2 => eval (Apply (eval t1) t2) end.
そしたら、evalがないよ、と言われてしまった。
coqc lambda.v File "./lambda.v", line 66, characters 0-319: Error: No such section variable or assumption: eval.
いろいろ書き換えて試したところ
eval (Apply (eval t1) t2)
みたいな、evalを二回呼び出しているところがダメらしい。
回避方法
どっちにしろ、上記のようなevalだと停止しないことがありそうだったので、1ステップだけ簡約するstepという関数を定義しました。
... Fixpoint step (t : term) := match t with Var _ | Bool _ | Lambda _ _ _ => t | Apply (Lambda x _ body as t1) t2 => if is_value t2 then subst body x t2 else Apply t1 (step t2) | Apply t1 t2 => Apply (step t1) t2 end.
ソースコード
(* simple typed lambda calculus *) Require Import Arith.EqNat. (* simple type *) Inductive type : Set := BoolT : type | FunT : type -> type -> type. Inductive term : Set := Var : nat -> term | Bool : bool -> term | Lambda : nat -> type -> term -> term | Apply : term -> term -> term. (* Eval *) Fixpoint subst (t : term) (old : nat) (new : term) := match t with | Bool _ => t | Var x => if beq_nat x old then new else t | Lambda x type body => if beq_nat x old then t else Lambda x type (subst body old new) | Apply t1 t2 => Apply (subst t1 old new) (subst t2 old new) end. Definition is_value (t : term) := match t with Var _ | Bool _ | Lambda _ _ _ => true | Apply _ _ => false end. Fixpoint step (t : term) := match t with Var _ | Bool _ | Lambda _ _ _ => t | Apply (Lambda x _ body as t1) t2 => if is_value t2 then subst body x t2 else Apply t1 (step t2) | Apply t1 t2 => Apply (step t1) t2 end. (* Function eval (t :term) {measure term_length t} : term := match t with Var _ | Bool _ | Lambda _ _ _ => t | Apply (Lambda x _ body as t1) t2 => if is_value t2 then eval (subst body x t2) else eval (Apply t1 (eval t2)) | Apply t1 t2 => eval (Apply (eval t1) t2) end.*)