在Coq中定义参数化不动点

在Coq中定义参数化不动点,coq,Coq,我试图在Coq中定义一个不动点,其中一个函数定义通过一个参数引用另一个函数定义,但我得到了一些令人困惑的错误 我已将此定义最小化: Require Import Coq.Init.Notations. Require Import Coq.Init.Datatypes. Inductive Wrapper (T : Type) := | Wrap : T -> Wrapper T . Inductive Unwrapper := | Empty : Unwrapper |

我试图在Coq中定义一个不动点,其中一个函数定义通过一个参数引用另一个函数定义,但我得到了一些令人困惑的错误

我已将此定义最小化:

Require Import Coq.Init.Notations.
Require Import Coq.Init.Datatypes.

Inductive Wrapper (T : Type) :=
  | Wrap : T -> Wrapper T
  .
Inductive Unwrapper :=
  | Empty : Unwrapper
  | Unwrap : Wrapper Unwrapper -> Unwrapper
  .

Fixpoint Unwrapper_size (u : Unwrapper) {struct u} : nat :=
  match u with
  | Empty => O
  | Unwrap w => Wrapper_size w
  end

with Wrapper_size (w : Wrapper Unwrapper) {struct w} : nat :=
  match w with
  | Wrap _ t => Unwrapper_size t
  end.
导致此错误的原因:

Recursive definition of Wrapper_size is ill-formed.
In environment
Unwrapper_size : Unwrapper -> nat
Wrapper_size : Wrapper Unwrapper -> nat
w : Wrapper Unwrapper
t : Unwrapper
Recursive call to Unwrapper_size has principal argument equal to
"t" instead of a subterm of "w".
Recursive definition is:
"fun w : Wrapper Unwrapper =>
match w with
| Wrap _ t => Unwrapper_size t
end".

这里,
t
显然是
w
的一个子项-
w
是我们匹配得到的
t
,但Coq不接受它。这里的错误是什么,我该如何避免呢?

假设您在其他参数上也使用了
包装器。然后需要打破相互递归,使函数与数据类型“并行”。所以你想写
Wrapper\u size:Wrapper T->(T->nat)->nat

然后您可以在
Unwrapper\u size
中使用
Wrapper\u size Unwrapper\u size
:Coq应该在终止检查中进行足够的内联,以识别这是安全的


在本例中,手动内联也很容易:
Unwrapper\u size
将在
Unwrap(Wrap\t)
上匹配,并在
t
上递归。您的代码非常可疑:唯一的基本情况返回0,并且在nat上没有操作。因此,如果它终止,它只返回0。这可能不是你想要的。是的,我已经最小化了定义,以便更清楚地阅读。我的实际用例不那么空洞,但它只是给问题增加了更多的噪音。(您可以想象实际增加递归调用的结果以生成一个更有用的函数。)正如有人在IRC上所说,“尝试将包装器和展开器定义为相互归纳的”,给出
归纳包装器:=Wrap:unwrapper->wrapper with unwrapper
:Coq的“子项”概念假设递归遵循数据类型的结构。我想这对最初的一个没有帮助,但最好有一个例子,说明这不起作用。我有另一个想法…如果你也包装其他东西,那么你需要打破相互递归,使函数与数据类型“并行”。所以写
Wrapper\u size:Wrapper T->(T->nat)->nat.
然后我会尝试在
Unwrapper\u size
中使用
Wrapper\u size Unwrapper\u size
:Coq可能会在终止检查中进行足够的内联,以识别这是安全的。(在本例中,手动内联也很容易:Unwrapper_size`将在
Unwrap(wrap t)
上匹配,并在
t
上递归)。如果所有其他操作都失败,则总是有充分的归纳,但这很烦人,我会尝试避免它。