Coq 如何为构造函数设置隐式参数

Coq 如何为构造函数设置隐式参数,coq,logical-foundations,Coq,Logical Foundations,在玩诺斯托特练习时,我发现了另一种奇怪的行为。代码如下: Inductive nostutter {X:Type} : list X -> Prop := | ns_nil : nostutter [] | ns_one : forall (x : X), nostutter [x] | ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::

在玩诺斯托特练习时,我发现了另一种奇怪的行为。代码如下:

Inductive nostutter {X:Type} : list X -> Prop :=
| ns_nil : nostutter []
| ns_one : forall (x : X), nostutter [x]
| ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::h::t).

Example test_nostutter_manual: not (nostutter [3;1;1;4]).
Proof.
  intro.
  inversion_clear H.
  inversion_clear H0.
  unfold not in H2.
  (* We are here *)
  specialize (H2 eq_refl).
  apply H2.
Qed.
当我将代码移动到另一个文件“nostutter.v”中时,同样的代码会给出一个预期错误:

术语“eq_refl”的类型为“RelationClasses.reflective Logic.eq”,而 预计其类型为“1=1”

nostutter.v的标题:

Set Warnings "-notation-overridden,-parsing".
Require Import List.
Import ListNotations.
Require Import PeanoNat.
Import Nat.
Local Open Scope nat_scope.
我必须向
eq\u refl
显式添加一个参数:
specialize(H2(eq\u refl 1))。


我认为这与专业化没有特别关系。这是怎么一回事?如何修复?

问题是导入
PeanoNat.Nat

导入
PeanoNat
时,模块类型
Nat
进入范围,因此导入
Nat
将引入
PeanoNat.Nat
。如果要导入
Coq.Init.Nat
,则必须在导入
peanat
之前导入它,或者使用
import Init.Nat.
导入它

在这种情况下,为什么导入
PeanoNat.Nat
会导致问题? ()包含模块1
Nat
。在那个模块里,我们发现了一条不寻常的线条

Include NBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
按照这种定义方式,
eq\u refl
(无任何参数)具有类型
自反式eq
,其中
自反式
是类

Class Reflexive (R : relation A) :=
  reflexivity : forall x : A, R x x.
(在Classes/RelationClasses.v中找到)

这意味着我们总是需要提供一个额外的参数来获得
x=x
类型的东西。这里没有定义隐式参数

为什么导入PeanoNat.Nat之类的模块通常是个坏主意? 如果上面的“雁行图”还不够令人信服,那么我只想说,像这样扩展和导入其他模块和模块类型的模块,通常不打算被导入。它们通常有较短的名称(如
N
Z
Nat
),因此,不必键入长名称,就可以很容易地使用它们中的任何定理。它们通常有很长的进口链,因此包含大量的商品。如果您导入它们,那么现在大量的项正在污染您的全局命名空间。正如您在
eq\u refl
中所看到的,这可能会导致您认为熟悉的常数出现意外行为


  • 在这次冒险中遇到的大多数模块都是“模块类型/函子”类型。可以说,它们很难完全理解,但是可以找到一个简短的指南

  • 我的调查是通过在CoqIDE中打开文件并在可能从其他地方导入的任何内容之后运行命令
    Locate eq\u refl.
    (或者更好的方法是ctrl+shift+L)<代码>定位还可以告诉您常量从何处导入。我希望有一种更简单的方法来查看模块类型中导入的路径,但我不这么认为。您可能会猜到,根据被覆盖的
    eq\u refl
    的类型,我们最终会进入Coq.Classes.RelationClasses,但这并不精确

  • Include NBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
    
    Module BackportEq (E:Eq)(F:IsEq E) <: IsEqOrig E.
     Definition eq_refl := @Equivalence_Reflexive _ _ F.eq_equiv.
     Definition eq_sym := @Equivalence_Symmetric _ _ F.eq_equiv.
     Definition eq_trans := @Equivalence_Transitive _ _ F.eq_equiv.
    End BackportEq.
    
    Class Reflexive (R : relation A) :=
      reflexivity : forall x : A, R x x.