在Coq.Structures.EqualitiesFacts中,有一种方便的PairUsualDecidableType
模块类型,用于从另外两个笛卡尔积中构建UsualDecidableType
模块。
似乎没有相应的PairUsualDecidableTypeFull
模块类型可用于处理UsualDecidableTypeFull
。
我尝试创建一个,如下所示:
Module PairUsualDecidableTypeFull(D1 D2:UsualDecidableTypeFull) <: UsualDecidableTypeFull.
Definition t := (D1.t * D2.t)%type.
Definition eq := @eq t.
Instance eq_equiv : Equivalence eq := _.
Definition eq_refl : forall x : t, x = x. Admitted.
Definition eq_sym : forall x y : t, x = y -> y = x. Admitted.
Definition eq_trans : forall x y z : t, x = y -> y = z -> x = z. Admitted.
Definition eq_dec : forall x y, { eq x y }+{ ~eq x y }. Admitted.
Definition eqb : t -> t -> bool. Admitted.
Definition eqb_eq : forall x y : t, eqb x y = true <-> x = y. Admitted.
End PairUsualDecidableTypeFull.
但Coq抱怨:
Signature components for label eq_refl do not match: the body of definitions differs.
我不明白“签名组件”的含义。鉴于Print UsualDecidableTypeFull
的输出包括:
Definition eq_refl : forall x : t, @Logic.eq t x x.
eq_refl
的类型至少看起来正确。还有什么可能是错的?
我是一名业余爱好者,对Coq来说是新手,运行版本8.9.0。也许由于某些原因,我试图做的事情没有任何意义。标准库包含PairUsualDecidableType
但不包含PairUsualDecidableTypeFull
的事实使我有些怀疑,因为我错过了一些东西。
任何指导都将受到欢迎,在此先感谢。
答案 0 :(得分:1)
首先,已知标准库不完整。因此,没有提供一个特定的定义/引理/模块这一事实并不意味着它不应该存在。对于模块来说更是如此,因为很少使用Coq的模块系统。
关于您的问题,在Coq中,Module
和Module Type
之间的边界很窄。特别是,您不仅可以在声明中使用Module Type
中的定义(我不确定这些术语“定义”和“声明”是否在此处正确使用,但我希望至少可以理解) 。例如,
Module Type Sig.
Parameter n : nat.
Definition plus x y := x + y.
End Sig.
是一个签名,用于声明类型为n
的字段nat
并将字段plus
定义为自然数的加法。编写必须符合此签名的模块时,只要类型对应,就可以根据需要实现声明,但是对于定义,您必须基本上编写与签名相同的主体。例如,您可以编写:
Module M <: Sig.
Definition n := 3.
Definition plus x y := x + y.
End M.
您可以使用Print
来观察哪些字段是声明,哪些字段是定义:声明显示为Parameter
,定义显示为Definition
(但未打印定义的实际内容,这是令人困惑的)。就您而言,eq
,eq_equiv
,eq_refl
,eq_sym
和eq_trans
都是UsualDecidableTypeFull
中的定义,因此您别无选择实现,必须将eq
定义为Logic.eq
,将eq_equiv
定义为eq_equivalence
(参见Equalities中的定义),等等。使用Admitted
时要实现eq_refl
,您使用的主体与签名中给定的主体不同。这样,您的模块定义将被消息the body of definitions differs
拒绝。
如果我回到最初的写函子PairUsualDecidableTypeFull
的问题上来,通过深入研究Equalities和EqualitiesFacts,我写了这个实现,该实现重用了标准库。
Module DT_to_Full (D:DecidableType') <: DecidableTypeFull.
Include Backport_DT (D).
Include HasEqDec2Bool.
End DT_to_Full.
Module PairUsualDecidableTypeFull (D1 D2:UsualDecidableTypeFull)
<: UsualDecidableTypeFull.
Module M := PairUsualDecidableType D1 D2.
Include DT_to_Full (M).
End PairUsualDecidableTypeFull.
答案 1 :(得分:0)
我通过定义以下内容来简单地“包装” Coq的UsualDecidableTypeFull
来解决此问题:
Module Type UDTFW <: UsualDecidableType.
Parameter t : Type.
Definition eq := @Logic.eq t.
Definition eq_equiv : Equivalence eq := _.
Parameter eq_refl : forall x : t, x = x.
Parameter eq_sym : forall x y : t, x = y -> y = x.
Parameter eq_trans : forall x y z : t, x = y -> y = z -> x = z.
Parameter eq_dec : forall x y, { @Logic.eq t x y }+{ ~@Logic.eq t x y }.
Parameter eqb : t -> t -> bool.
Parameter eqb_eq : forall x y : t, eqb x y = true <-> x = y.
End UDTFW.
与:
Module Make_UDTFW (X : UsualDecidableTypeFull) <: UDTFW.
Definition t := X.t.
Definition eq := X.eq.
Definition eq_equiv := X.eq_equiv.
Definition eq_refl := X.eq_refl.
Definition eq_sym := X.eq_sym.
Definition eq_trans := X.eq_trans.
Definition eq_dec := X.eq_dec.
Definition eqb := X.eqb.
Definition eqb_eq := X.eqb_eq.
End Make_UDTFW.
已经在模块级别引入了这种看起来很奇怪的间接级别,实际上在问题中对PairUsualDecidableTypeFull
的定义是可行的,除了在UDTFW
的各处使用UsualDecidableTypeFull
之外。
对于我来说,这个相当丑陋的解决方法已经足够了,但是我非常有兴趣了解真正的问题所在。