证明coq函数终止的一些帮助
我知道这是一个常见的问题:)我会继续阅读,但我做了一些搜索,我不完全理解“测量”是如何工作的 我正在学习Benjamin Pierce关于依赖类型认证编程的课堂练习。这是我的密码证明coq函数终止的一些帮助,coq,Coq,我知道这是一个常见的问题:)我会继续阅读,但我做了一些搜索,我不完全理解“测量”是如何工作的 我正在学习Benjamin Pierce关于依赖类型认证编程的课堂练习。这是我的密码 Inductive type : Type := | Nat | Bool | Pair : type -> type -> type. Inductive tbinop : type -> type -> type -> Set := | TPlus : tbinop Nat Nat
Inductive type : Type :=
| Nat
| Bool
| Pair : type -> type -> type.
Inductive tbinop : type -> type -> type -> Set :=
| TPlus : tbinop Nat Nat Nat
| TTimes : tbinop Nat Nat Nat
| TEq : forall t, tbinop t t Bool
| TLt : tbinop Nat Nat Bool
| TPair : forall in1 in2, tbinop in1 in2 (Pair in1 in2).
Inductive texp : type -> Set :=
| TNConst : nat -> texp Nat
| TBConst : bool -> texp Bool
| TBinop : forall t1 t2 t, tbinop t1 t2 t -> texp t1 -> texp t2 -> texp t.
Fixpoint typeDenote (t : type) : Type :=
match t with
| Nat => nat
| Bool => bool
| Pair l r => prod (typeDenote l) (typeDenote r)
end.
Fixpoint typeDepth (t: type): nat :=
match t with
| Nat => 1
| Bool => 1
| Pair A B => 1 + Nat.max (typeDepth A) (typeDepth B)
end.
Program Fixpoint tbinopDepth arg1 arg2 res (b: tbinop arg1 arg2 res)
{measure (Nat.max (typeDepth arg1) (typeDepth arg2))}
: nat :=
match b with
| TPlus => 1
| TTimes => 1
| TEq Nat => 1
| TEq Bool => 1
| TEq (Pair A B) => tbinopDepth (TPair A B)
| TLt => 1
| TPair A B => 1 + Nat.max (typeDepth A) (typeDepth B)
end.
Next Obligation.
simpl.
rewrite Nat.max_idempotent.
omega.
Qed.
Eval compute in tbinopDepth (TEq (Pair Nat Nat)). (* 2 *)
Eval compute in tbinopDepth (TEq Nat). (* 1 *)
Program Fixpoint tbinopDenote arg1 arg2 res (b : tbinop arg1 arg2 res)
{measure (tbinopDepth b)} : typeDenote arg1 -> typeDenote arg2 -> typeDenote res :=
match b with
(*| TPlus => plus*)
| TPlus => fun (a:typeDenote Nat) (b:typeDenote Nat) => plus a b : typeDenote Nat
| TTimes => mult
| TEq Nat => beq_nat
| TEq Bool => eqb
| TEq (Pair A B) => fun (a:typeDenote (Pair A B)) (b:typeDenote (Pair A B)) =>
match a, b with
| (x1, x2), (y1, y2) => eqb (tbinopDenote (TEq A) x1 y1) (tbinopDenote (TEq B) x2 y2)
end : typeDenote Bool
| TLt => leb
| TPair _ _ => fun a b => (a,b)
end.
然而,当我试图编译它时,我得到一个类型错误。注意:如果有办法重新构造它以避免必须证明这一点,那当然是理想的!我欢迎这方面的任何建议。也就是说,我想知道我的测量方法哪里出了问题
我得到一个类似这样的错误:
The term "x1" has type
"(fix typeDenote (t : type) : Type :=
match t with
| Nat => nat
| Bool => bool
| Pair l r => (typeDenote l * typeDenote r)%type
end) A" while it is expected to have type
"tbinopDepth (TEq A) < tbinopDepth b".
术语“x1”的类型为
“(固定类型表示(t:类型):类型:=
匹配
|Nat=>Nat
|Bool=>Bool
|对l r=>(类型表示l*类型表示r)%type
结束)一个“当它预期有类型
“TBINOP深度(TEq A)
这就是为什么我认为很明显我不太理解度量是如何与代码交互的,因为我认为度量将生成一个证明义务,而不是改变我定义的函数的类型
我应该补充一点,我之所以包括这两个评估,是因为如果我能达到一个验证目标,
“tbinoptheep(TEq a)
是正确的,因为我们知道b是TEq(a-b对)
,所以tbinoptheep(TEq a)
和tbinoptheep(TEq b)
很可能比这小。但它不会进行类型检查…您可以通过单独定义相等运算符来解决此问题:
Require Import Coq.Arith.Arith.
Set Implicit Arguments.
Inductive type : Type :=
| Nat
| Bool
| Pair : type -> type -> type.
Inductive tbinop : type -> type -> type -> Set :=
| TPlus : tbinop Nat Nat Nat
| TTimes : tbinop Nat Nat Nat
| TEq : forall t, tbinop t t Bool
| TLt : tbinop Nat Nat Bool
| TPair : forall in1 in2, tbinop in1 in2 (Pair in1 in2).
Inductive texp : type -> Set :=
| TNConst : nat -> texp Nat
| TBConst : bool -> texp Bool
| TBinop : forall t1 t2 t, tbinop t1 t2 t -> texp t1 -> texp t2 -> texp t.
Fixpoint typeDenote (t : type) : Type :=
match t with
| Nat => nat
| Bool => bool
| Pair l r => prod (typeDenote l) (typeDenote r)
end.
Fixpoint typeDepth (t: type): nat :=
match t with
| Nat => 1
| Bool => 1
| Pair A B => 1 + Nat.max (typeDepth A) (typeDepth B)
end.
Fixpoint eqb arg : typeDenote arg -> typeDenote arg -> bool :=
match arg return typeDenote arg -> typeDenote arg -> bool with
| Nat => Nat.eqb
| Bool => Bool.eqb
| Pair A B => fun '(x1, y1) '(x2, y2) => andb (eqb _ x1 x2) (eqb _ y1 y2)
end.
Fixpoint tbinopDenote arg1 arg2 res (b : tbinop arg1 arg2 res) {struct arg1}
: typeDenote arg1 -> typeDenote arg2 -> typeDenote res :=
match b in tbinop arg1 arg2 res return typeDenote arg1 -> typeDenote arg2 -> typeDenote res with
| TPlus => Nat.add
| TTimes => Nat.mul
| TEq arg => eqb arg
| TLt => leb
| TPair _ _ => fun a b => (a,b)
end.