减少参数(以及什么是程序修复点)

时间:2017-12-14 15:20:21

标签: coq termination totality

考虑以下修复点:

Require Import Coq.Lists.List.
Import ListNotations.

Inductive my_type: Type:=
| Left: my_type
| Right: my_type
.

Fixpoint decrease (which: my_type) (left right: list my_type) : list my_type :=
match which with
| Left =>
  match left with
  | [] => []
  | a::tl => decrease a tl right
  end
| Right =>
  match right with
  | [] => []
  | a::tl => decrease a left tl
  end
end.

Coq拒绝以下修复点,因为它无法猜测减少的修复点(有时left列表会失去它的头部,有时它是right列表。

answer表示可以使用Program Fixpoint并指定{measure ((length left)+(length right))}来解决此问题。

我的问题是:

  • 常规FixpointProgram Fixpoint之间有什么区别?
  • 是否可以在常规Fixpoint中明确减少参数?
  • Next Obligation目标是什么?

1 个答案:

答案 0 :(得分:5)

  • Coq中的Fixpoint命令使用Coq的原语fix构造递归函数,该函数检查结构递归以确保终止。这是Coq中唯一的递归,所有其他技术最终都是某种fix

    Program FixpointProgram的一个特性,它允许以稍微扩展的语言编写定义,然后将其编译为Coq定义。 Program Fixpoint接受任何递归函数,生成一个适当的证明义务,显示函数终止(通过减少每个递归子查询的一些参数),然后将定义和终止证明打包成一个结构上减少的Coq定义一个论点。如果这听起来很神奇,那么CPDT可以很好地解释如何进行这种编码。

  • 是的,您可以添加{struct arg}注释以明确指定哪个参数在结构上正在减少Fixpoint decrease (which: my_type) (left right: list my_type) {struct right} : list my_type。这对你的例子没有帮助,因为你的函数通常不会在结构上减少任何一个参数。所有原始fix构造都有struct注释,但Coq通常可以在您编写Fixpoint时自动推断它。例如,这里是Nat.add

    Nat.add = 
      fix add (n m : nat) {struct n} : nat :=
      match n with
      | 0 => m
      | S p => S (add p m)
      end : nat -> nat -> nat
    
  • Next Obligation Program Fixpoint获得两种类型的目标:首先,每个子查询的参数较小(使用measure,"较小的"是使用< on nats定义,第二,"较小"关系是有根据的;也就是说,它没有无限下降的越来越小的对象序列。我不确定Program Fixpoint为什么Nat.lt不会自动为Program执行此操作,因为它应该知道相关定理。请注意,PUB/SUB具有的功能不仅仅是更一般的递归,因此它可以生成与这些功能相关的其他目标,具体取决于您编写的定义。