如果我写一个非平凡的递归函数(即使用function
而不是fun
),那么代码生成器拒绝执行我的函数,除非我提供终止证明 - 即使是{{ 1}} - 证明就足够了。这是我的最小工作示例(不要担心sorry
函数的内容,它只是一个带有非平凡终止证明的随机函数):
foo
目前theory Misc imports
Main
"~~/src/HOL/Library/Code_Target_Numeral"
begin
function foo :: "nat list ⇒ nat list list"
where
"foo G = (
if G = [] then
map concat [[G]]
else
concat (map foo (map (λx. [Suc x]) (tl G)))
)"
by auto
termination sorry
value "foo [1,2,3]"
end
命令返回正确的结果value
。但是,如果删除行"[]"
,则termination sorry
命令将返回value
。
有没有办法让代码生成器执行"foo [1, 2, 3]"
,而不必用可怕的foo
来破坏我的理论文件?我不想实际做终止证明,因为这是一个非常难以证明的证据。
答案 0 :(得分:2)
克里斯的评论回答了你的问题,但我想我只是举个例子。
非终止函数具有引入不健全的能力,这就是需要终止证明的原因(或者至少是sorry
)。
例如,使用以下函数定义:
function f :: "nat ⇒ nat" where "f n = f n + 1"
by auto
termination
sorry
然后我们可以继续证明False
:
lemma "False"
by (metis a.f.elims add_eq_self_zero if_1_0_0)
不健全来自于函数的非终止。
在您的具体示例中,终止证明并不太难:您可以看到列表G
的长度始终在减少。然后我们可以使用一个度量函数并显示它会减少,如下所示:
termination
(* Give Isabelle a termination relation. We say that the length
* of the parameter is strictly decreasing to 0. *)
apply (relation "measure length", simp)
(* simplify *)
apply clarsimp
(* Sledgehammer can now solve this goal, but by hand is a bit neater. *)
apply (drule length_pos_if_in_set, clarsimp)
done