我很好奇。我一直在OCaml中处理此数据类型:
type 'a exptree =
| Epsilon
| Delta of 'a exptree * 'a exptree
| Omicron of 'a
| Iota of 'a exptree exptree
可以使用显式类型的递归函数(最近添加的功能)进行操作。例:
let rec map : 'a 'b. ('a -> 'b) -> 'a exptree -> 'b exptree =
fun f ->
begin function
| Epsilon -> Epsilon
| Delta (t1, t2) -> Delta (map f t1, map f t2)
| Omicron t -> Omicron (f t)
| Iota tt -> Iota (map (map f) tt)
end
但是我从来没有能够在Coq中定义它:
Inductive exptree a :=
| epsilon : exptree a
| delta : exptree a -> exptree a -> exptree a
| omicron : a -> exptree a
| iota : exptree (exptree a) -> exptree a
.
Coq在抱怨。它不喜欢最后一个构造函数,并说了一些我不完全理解或不同意的内容:
Error: Non strictly positive occurrence of "exptree" in "exptree (exptree a) -> exptree a".
我能理解的是,在其定义之内使用否定的归纳类型type 'a term = Constructor ('a term -> …)
会被拒绝,因为它们会导致丑陋的,毫无根据的野兽,例如(无类型的)λ项。但是,这种特殊的exptree
数据类型似乎足够无害:从其OCaml定义来看,其参数'a
从未在负数位置使用。
似乎Coq在这里太谨慎了。那么,这种特殊的归纳数据类型真的存在问题吗?还是Coq在这里可以放宽一点?
另外,其他证明助手又如何应对这种归纳定义(自然)呢?