我有两个不同的模块签名到两个不同的文件。它们具有相同的字段名称但行为不同。
里面的functor定义了另一个函子。
PI.v
Module Type TPI.
Parameter sig : Signature.
Parameter trsInt: forall f, pi f.
End TPI.
Module P (Export T: TPI).
Lemma A...
Module Export Mono <: MonoType.
End P.
和
MI.v
Module Type TMI.
Parameter sig : Signature.
Parameter trsInt : forall f, mi f.
End TMI.
Module M (Export TM: TMI).
Lemma B ...
Module Export Mono <: MonoType.
End M.
其他文件中的MonoType
位置,例如Mono.v
这是我的情况。
我在该文件中有另一个名为B.v
的文件,我需要在文件PI.v
和MI.v
中使用定义和引理。
一个定义我需要使用它们两个例如。
Definition redPair R is :=
match is with
| Type_PI => pi_int R is
| Type_MI => mi_int R is
end.
我在R
遇到问题,因为pi_int R
和mi_int R
有sig
(签名)不同,其中pi_int
使用了trsInt
模块签名TPI
和mint_int
在模块签名trsInt
中使用了TMI
。
这是我定义它的方式:
Module PI (Import P : TPI).
Definition pi_int R is := P.trsInt ...
(* inside PI I define another functor for MI *)
Module MI (Import M : TMI).
Definition mi_int R is := M.trsInt ...
Definition redPair R is :=
match is with
| Type_PI => pi_int R is
| Type_MI => mi_int R is (* error here saying that it used the sig of
P.sig but in this case mi_int used the sig of M.sig *)
end.
End MI.
End PI.
我的问题是,有没有一种方法可以让我拥有一个良好的模块结构,我可以在定义redPair
处拥有相同的签名?谢谢您的帮助。
答案 0 :(得分:3)
实际上,在redPair
的定义中,您无法保证P.sig
和M.sig
具有相同的类型,这就是您收到此错误消息的原因。
解决此类问题的方法是通过“共享约束”强制实现类型相等。以下是与您类似的代码,演示了我如何强制P.sig
和M.sig
等于nat
:
Module Type TPI.
Parameter sig : Type.
Parameter x : sig.
End TPI.
Module Type TMI.
Parameter sig : Type.
Parameter x : sig.
End TMI.
Module PI (Import P : TPI with Definition sig := nat).
Definition pi_int := x.
Module MI (Import M : TMI with Definition sig := nat).
Definition mi_int := x.
Definition f (x : bool) :=
if x
then pi_int
else mi_int.
End MI.
End PI.
您也可以选择保留P.sig
不受约束,但强制执行M.sig
是相同的:
Module PI (Import P : TPI).
Definition pi_int := x.
Module MI (Import M : TMI with Definition sig := P.sig).
Definition mi_int := x.
Definition f (x : bool) :=
if x
then pi_int
else mi_int.
End MI.
End PI.
既然已经提到了解决问题的方法,我建议您在Coq中使用模块和仿函数时要小心。通常情况下,您实际上只需要依赖记录。模块和仿函数对每个人来说都很复杂,你必须关心抽象,共享约束等等。
现状似乎是你应该避免使用它们,除非你实际上需要它们提供的依赖记录:抽象和/或子类型。
事实上,我现在对你的定义感到有些不安。例如,在MI
内定义PI
是否有意义?没有更多背景,这似乎是武断的也许它确实如此,我只是说你在使用模块时应该小心,并确保你很好地掌握你正在做的事情,否则它可能适得其反! :)
但如果您只是在尝试,请尝试一下。了解各种可能性以及各自的利弊是很好的。