请考虑以下代码:
Require Import FMapAVL.
Require Import Coq.Structures.OrderedTypeEx.
Module NatMap := FMapAVL.Make(Nat_as_OT).
Inductive ttree (K : Type) (V : Type) :=
| tleaf : ttree K V
| tnode : ttree K V -> K -> V -> ttree K V -> nat -> ttree K V.
Inductive test :=
| test1 : test
| test2 : ttree nat test -> test
| test3 : list test -> test
| test4 : NatMap.t test -> test.
在Coq 8.6中,我得到Error: Non strictly positive occurrence of "test" in "NatMap.t test -> test".
没有test4
我就没有错误。
为什么在我的NatMap.t
归纳类型中应用FMapAVL
(nat
和test
键)构造函数会在应用list
构造函数时产生非严格的正面出现甚至ttree
构造函数(就像FMapAVL
的内部结构一样)好吗?
如果我想从我的示例中获取test4
之类的内容,有哪些常见的解决方法,最好是不要求我像ttree
那样制作自己的地图实现?
答案 0 :(得分:1)
问题是Coq无法处理一些高阶归纳类型作为嵌套归纳 - 我不相信我完全理解这些局限性,但我调查了一下。
有助于解释行为的一个重要事实是Coq特别支持将归纳类型传递给类型构造函数。 CPDT's Inductive Types章节在嵌套归纳类型一节中对此进行了解释:Coq创建的list
或ttree
版本专门针对test
并假装您正在定义tree
和这些具有互感的专用电感。这通常可以正常工作(例如您的list
甚至ttree
定义)。它甚至适用于模块,只要它们使用“transparent ascription”(和FMapAVL.Make这样做)。但是,当类型是索引而不是参数时(例如,Type
位于冒号右侧而不是左侧)时,它似乎会崩溃:
Module Type Transformer.
Axiom T:Type -> Type.
End Transformer.
Module IdOpaque : Transformer.
Definition T (t:Type) := t.
End IdOpaque.
Inductive transformer : Type -> Type :=
| MkT : forall t, t -> transformer t .
(* make the argument a parameter *)
Inductive transformer' (t:Type) : Type :=
| MkT' : t -> transformer' t.
Module IdInd <: Transformer.
Definition T : Type -> Type := transformer.
End IdInd.
Module IdTransparent <: Transformer.
Definition T (t:Type) : Type := t.
End IdTransparent.
(* works with a simple definition, even inside a module, as long as its
transparent *)
Inductive test1 :=
| mkTest1 (_:IdTransparent.T test1).
(* not strictly positive (Coq can't see definition) *)
Fail Inductive test2 :=
| mkTest2 (_:IdOpaque.T test2).
(* this is pretty much what happens with FMapAVL.Make *)
Fail Inductive test3 :=
| mkTest3 (_:IdInd.T test3).
(* even this fails *)
Fail Inductive test4 :=
| mkTest4 (_:transformer test4).
(* this finally works *)
Inductive test5 :=
| mkTest5 (_:transformer' test5).