我和Coq鬼混.具体来说,我试图实现mergesort,然后证明它的工作原理.
我尝试实施的是:
Fixpoint sort ls :=
match ls with
| nil => nil
| cons x nil => cons x nil
| xs =>
let (left, right) := split xs nil nil
in merge (sort left) (sort right)
end.
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
Error:
Recursive definition of sort is ill-formed.
In environment
sort : list nat -> list nat
ls : list nat
x : nat
l : list nat
y : nat
l0 : list nat
left : list nat
right : list nat
Recursive call to sort has principal argument equal to "left" instead of
one of the following variables: "l" "l0".
Recursive definition is:
"fun ls : list nat =>
match ls with
| nil => nil
| x :: nil => x :: nil
| x :: _ :: _ =>
let (left, right) := split ls nil nil in merge (sort left) (sort right)
end".
Run Code Online (Sandbox Code Playgroud)
我对这些错误的解释是l和l0是没有头的x,没有x的ls和没有x的ls和x之后的元素(我猜它决定调用y?).很遗憾,我没有在其中一个列表上递归,而是在本地定义的列表上递归.
我是否只允许对直接来自模式匹配的事情进行处理?如果是,这似乎是一个严重的限制.周围有办法吗?我猜测Coq无法判断该函数是否会终止.有没有办法证明左右小于xs?
Pti*_*val 10
事实证明,CPDT关于一般递归的章节只解决了这一特定问题:
http://adam.chlipala.net/cpdt/html/GeneralRec.html
阅读名为Well-established recursion的部分,它使用有根据的递归实现合并排序,以帮助Coq的终止检查器感到高兴.
可能有其他的方式来解决使用,要么问题Function还是Program Fixpoint,但我认为阅读有根有据递归不会受到伤害.