为什么Coq反对以下PairUsualDecidableTypeFull模块类型?

时间:2019-04-09 19:07:06

标签: coq

在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的事实使我有些怀疑,因为我错过了一些东西。

任何指导都将受到欢迎,在此先感谢。

2 个答案:

答案 0 :(得分:1)

首先,已知标准库不完整。因此,没有提供一个特定的定义/引理/模块这一事实并不意味着它不应该存在。对于模块来说更是如此,因为很少使用Coq的模块系统。

关于您的问题,在Coq中,ModuleModule 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(但未打印定义的实际内容,这是令人困惑的)。就您而言,eqeq_equiveq_refleq_symeq_trans都是UsualDecidableTypeFull中的定义,因此您别无选择实现,必须将eq定义为Logic.eq,将eq_equiv定义为eq_equivalence(参见Equalities中的定义),等等。使用Admitted时要实现eq_refl,您使用的主体与签名中给定的主体不同。这样,您的模块定义将被消息the body of definitions differs拒绝。

如果我回到最初的写函子PairUsualDecidableTypeFull的问题上来,通过深入研究EqualitiesEqualitiesFacts,我写了这个实现,该实现重用了标准库。

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之外。

对于我来说,这个相当丑陋的解决方法已经足够了,但是我非常有兴趣了解真正的问题所在。