我制作了以下归纳数据类型和递归函数。
Require Coq.Lists.List.
Inductive PairTree : Type :=
| PTLeaf : PairTree
| PTBranch : (nat*nat) -> PairTree -> PairTree -> PairTree.
Fixpoint smush (r m : list nat) : list nat :=
match m with
| nil => r
| h :: t => smush (h :: r) t
end.
我使用这些函数定义了以下函数,并使用辅助“gas”参数,以便轻松满足Coq的终止规则。
Fixpoint fueled_prefix_part (gas : nat) (r m : list nat) : PairTree :=
match gas with
| 0 => PTLeaf
| S gas' =>
match r with
| nil => PTLeaf
| f :: fs =>
match fs with
| nil => PTLeaf
| f' :: fs' =>
PTBranch (f, f')
(fueled_prefix_part gas' (smush fs' m) nil)
(fueled_prefix_part gas' (f :: fs') (f' :: m))
end
end
end.
但是,我想从中提取实际代码并运行它。因此,代替对气体的结构递归,我可以获得更好的提取代码,而不是我可以使用以下代码,因为那时我可以使用其他类似nat的数据类型< (例如Haskell Integers)。
Require Import Recdef.
Require Export Coq.omega.Omega.
Require Export Coq.Lists.List.
(* Insert definitions of PairTree and smush here. *)
Function fpp' (gas: nat) (r m: list nat) {measure (fun x => x) gas}: PairTree :=
match 0 <? gas with
| false => PTLeaf
| true =>
match r with
| nil => PTLeaf
| f :: fs =>
match fs with
| nil => PTLeaf
| f' :: fs' =>
let gas' := gas - 1 in
PTBranch (f, f')
(fpp' gas' (smush fs' m) nil)
(fpp' gas' (f :: fs') (f' :: m))
end
end
end.
当然,我们不能在那里结束;我们必须证明这种情况终止了。以下似乎证明终止......
Proof.
intro gas. destruct gas; intros _ _ teq _ _ _ _ _ _.
inversion teq.
omega.
intro gas. destruct gas; intros _ _ teq _ _ _ _ _ _.
inversion teq.
omega.
此时 ProofGeneral 我在目标屏幕上看不到目标,在响应屏幕中,我看到了消息
No more subgoals.
(dependent evars:)
所以我输入
Defined.
并收到错误消息
Toplevel input, characters 0-8:
Error: Attempt to save a proof with shelved goals (in proof fpp'_terminate)
到底是怎么回事?如果我输入
Unshelve.
Defined.
我得到了同样的错误。