Isabelle primcofix中的相互递归

Isabelle primcofix中的相互递归,isabelle,coinduction,Isabelle,Coinduction,当我写作时 codatatype inftree = node nat inftree inftree primcorec one :: inftree and two :: inftree where "one = node 1 one two" | "two = node 2 one two" 我明白了 “inftree”既不是与“inftree”相互协同的草书,也不是通过自身嵌套的协同草书 为什么,以及如何避免它?命令primcorec仅支持基本的corecursion,因

当我写作时

codatatype inftree = node nat inftree inftree

primcorec one :: inftree and two :: inftree where
    "one = node 1 one two"
  | "two = node 2 one two"
我明白了

“inftree”既不是与“inftree”相互协同的草书,也不是通过自身嵌套的协同草书


为什么,以及如何避免它?

命令
primcorec
仅支持基本的corecursion,因此相互corecursion仅支持相互CoreCursoritive CodataType。您的两个函数
one
two
不是原始的协同草书,因此不直接受支持。如果更通用的命令
corec
支持相互协作,则它将落入其片段,但尚未为
corec
实现相互协作。因此,您必须找到一个非相互的corecursive定义,然后将
one
two
定义为派生函数。规范的解决方案是使用
bool
作为参数:

 primcorec one_two :: "bool => inftree" where
    "one_two is_one = Node (if is_one then 1 else 2) (one_two True) (one_two False)"

 definition "one = one_two True"
 definition "two = one_two False"

此外,在您可以通过共归纳证明它们之前,您必须首先将关于
one
two
的大多数属性概括为
one\u two

我的猜测是
primcorec
只支持相互协同的数据类型的相互协同的递归函数,也就是说,定义的函数的相互递归必须精确地遵循codatatype的相互递归。我不知道如何去做你想做的事情,但话说回来,我几乎不是一个专家——w.r.t.codatatypes通常会怀疑的人之一可能知道,但我建议尝试使用isabelle用户邮件列表而不是StackOverflow。我正在关注Coq中关于共生产的讨论,并试图指出isabelle,事情很简单,我可以在Coq谈话进行时在Isabelle中实现它……但在上面的一点上我失败了。如果我没记错的话,Coq在其逻辑中有codatatypes和coinduction作为原语,而Isabelle必须在HOL之上构建所有这些东西。当然,这让事情变得更加困难。我能想到的一个解决方案是引入一个人工相互递归的codatatype
inftre1=node nat inftre1 inftre2
等,用
primcorec
在其上定义
One
two
函数,然后使用三种类型之间的明显同构将结果函数转移到
inftree
。或者使用
fn=node n(f1)(f2)
定义一个函数
f::nat->inftree
,并定义
one=f1
two=f2