按属性定义的coq

时间:2015-05-11 15:42:20

标签: coq

我无法正式化以下形式的定义:定义一个整数,使某些属性成立。

我们说我正式确定了该属性的定义:

Definition IsGood (x : Z) : Prop := ...

现在我需要一个表格的定义:

Definition Good : Z := ...

假设我证明了具有该属性的整数并且是唯一的:

Lemma Lemma_GoodExistsUnique : exists! (x : Z), IsGood x.

是否可以使用GoodIsGood轻松定义Lemma_GoodExistsUnique

因为属性是在整数上定义的,所以似乎不需要额外的公理。无论如何,我不知道如何添加像选择公理这样的东西可以帮助定义。

另外,我无法正式确定以下表格的定义(我怀疑这与我上面描述的问题有关,但请注明是否不是这种情况):对于每个x,都存在y,这些y对于不同的x是不同的。例如,如何使用N定义IsGood个不同的良好整数:

Definition ThereAreNGoodIntegers (N : Z) (IsGood : Z -> Prop) := ...?

在现实世界的数学中,像这样的定义时不时出现,所以如果Coq适合于实用数学,这应该不难形式化。

1 个答案:

答案 0 :(得分:7)

对你的第一个问题的简短回答是:一般来说,这是不可能的,但在你的特定情况下,是的。

在Coq的理论中,命题(即Prop s)及其证明具有非常特殊的地位。特别是,通常不可能编写提取存在证据的证人的选择运算符。这样做是为了使理论与某些公理和原则相容,例如证明不相关,即证明给定命题的所有证明彼此相等。如果您希望能够这样做,您需要将此选择运算符添加为理论的附加公理,如standard library

然而,在某些特定情况下, 可以从抽象存在证据中提取证人,而不会再出现任何其他公理。特别是,当有问题的属性是可判定的时,可以对可数类型(例如Z)执行此操作。例如,您可以使用Ssreflect库中的choiceType接口来准确获取所需内容(查找xchoose函数)。

话虽这么说,我通常建议反对以这种方式做事,因为这会导致不必要的复杂性。直接定义Good可能更容易,而不需要求助于存在证明,然后单独证明Good具有所寻求的属性。

Definition Good : Z := (* ... *)
Definition IsGood (z : Z) : Prop := (* ... *)

Lemma GoodIsGood : IsGood Good.
Proof. (* ... *) Qed.

Lemma GoodUnique : forall z : Z, IsGood z -> z = Good.

如果您绝对想要使用存在证明来定义Good,您还可以更改Lemma_GoodExistsUnique的证据,以便在Type而不是Prop中使用连词,因为它允许您使用proj1_sig函数直接提取见证:

Lemma Lemma_GoodExistsUnique : {z : Z | Good z /\ forall z', Good z' -> z' = z}.
Proof. (* ... *) Qed.

至于你的第二个问题,是的,它与第一点有点相关。我再次建议您写下一个y_from_x函数Z -> Z,它将计算给定y x,然后单独证明此函数与输入和输出相关以某种特定的方式。然后,您可以通过证明y是单射的来说,x对于不同的y_from_x是不同的。

另一方面,我不确定你的最后一个例子与第二个问题的关系。如果我理解你想要正确做什么,你可以写一些类似

的东西
Definition ThereAreNGoodIntegers (N : Z) (IsGood : Z -> Prop) :=
  exists zs : list Z,
    Z.of_nat (length zs) = N
    /\ NoDup zs
    /\ Forall IsGood zs.

这里,Z.of_nat : nat -> Z是从自然到整数的规范注入,NoDup是一个断言,断言列表不包含重复元素,而Forall是更高的 - order谓词断言给定谓词(在这种情况下,IsGood)包含列表中所有元素。

作为最后一点,我建议不要使用Z来处理只能涉及自然数的事物。在您的示例中,您使用整数来讨论集合的基数,并且此数字始终是自然数。