我正在用codatatype
进行我的第一次实验,但我很早就被卡住了。我开始使用这个分支的定义,可能是无限的树:
codatatype (lset: 'a) ltree = Node (lnext : "'a ⇒ 'a ltree option")
并且一些定义可以正常工作:
primcorec lempty :: "'a ltree"
where "lnext lempty = (λ _ . None)"
primcorec single :: "'a ⇒ 'a ltree"
where "lnext (single x) = (λ _ . None)(x := Some lempty)"
但这不起作用:
primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = (λ _ . None)(x := Some (many x))"
我收到错误消息
primcorec error:
Invalid map function in "[x ↦ many x]"
我可以通过编写
来解决这个问题primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = (λ x'. if x' = x then Some (many x) else None)"
这使得primcorec
需要“了解”函数更新运算符,类似于fun
需要fundef_cong
lemmas和inductive
需要{{1} lemmas。但具体到底是什么?
答案 0 :(得分:2)
如果codatatype通过其他类型构造函数进行递归,则primcorec
期望递归调用正确嵌套在这些类型构造函数的map函数中。在该示例中,递归遍历函数类型和选项类型,其映射函数为op o
和map_option
。因此,对many
的递归调用应采用op o (map_option many)
形式。因此,以下定义有效:
primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = map_option many ∘ [x ↦ x]"
为方便起见,primcorec
支持更多语法输入格式。特别是,函数类型的map函数也可以使用lambda抽象编写。此外,它支持大小写区分和if
。这就是您的第二个版本被接受的原因。但是,当您查看生成的定义many_def
时,您会发现它比使用显式地图函数更复杂。
primcorec
不支持任意函数的注册,因此您无法在原始格式中使用fun_upd
。原始的corecursion是句法的。也许在将来会有function
的核心对应物。
地图功能在tutorial on datatypes和this paper中解释。