Coq中证明携带相关函数的等价性

时间:2018-01-02 17:07:55

标签: coq

假设我们有:

Require Import ZArith Program Omega.

Open Scope Z_scope.

Definition Z_to_nat (z : Z) (p : 0 <= z) : nat.
Proof.
  dependent destruction z.
    - exact (0%nat).
    - exact (Pos.to_nat p).
    - assert (Z.neg p < 0) by apply Zlt_neg_0.
      contradiction.
Qed.

现在我想制定这样的东西:

Lemma Z_to_nat_pred : forall x y p p', (Z_to_nat x p <= Z_to_nat y p')%nat <-> x <= y.

这对我来说似乎并不合适,因为在x <= y中,我可以有负x, y,然后我就不会有关于他们积极性的证据。总而言之,依赖Z_to_nat似乎非常难以使用。如何制定足以显示x <= y来结束(Z_to_nat x p <= Z_to_nat y p')%nat以及相反的方式?

我已经给了它一个bash来检查我可以制定证据的方式(尽管我很确定它不能用这个公式证明)。 我试过了:

Lemma Z_to_nat_pred : forall x y p p',
  (Z_to_nat x p <= Z_to_nat y p')%nat <-> x <= y.
Proof.
  intros.
  split; intros.
  - dependent destruction x;
    dependent destruction y; try easy; try omega.

这引导我实现以下目标:

p : positive
p0 : 0 <= Z.pos p
p' : 0 <= 0
H : (Z_to_nat (Z.pos p) p0 <= Z_to_nat 0 p')%nat
______________________________________(1/1)
Z.pos p <= 0

我可以在这里,例如,通过从H导出矛盾来解决目标,因为Z.pos p不能是<= 0吗?对于Z_to_nat定义我无能为力。

1 个答案:

答案 0 :(得分:2)

以下是与您的问题相关的几条评论:

  • 在Coq中,当使用策略定义函数时,特别是当我们想要计算时,最好使用Defined.结束相应的校对脚本,而不是Qed.(关键的概念是&# 34;透明定义&#34; vs.&#34;不透明定义&#34;,参见Coq ref man)
  • 因此,如果您将Qed替换为Defined,那么策略simpl in H.将适用于Z_to_nat_pred
  • 的证明
  • 编辑:另一种对您的目标有用的策略是exfalso.
  • 您的函数Z_to_nat部分函数,它将证明作为参数。但在许多实际情况中,避免依赖类型更简单,只使用默认值(因此使函数&#34; total&#34;)
  • 后一种策略已经是标准库中可用的两个函数(您已使用Require Import ZArith导入的)。可以将这两个函数视为以非依赖类型方式定义函数Z_to_nat的两种方法:

    Print Z.abs_nat.
    
    Z.abs_nat = 
    fun z : Z => match z with
                 | 0 => 0%nat
                 | Z.pos p => Pos.to_nat p
                 | Z.neg p => Pos.to_nat p
                 end
         : Z -> nat
    
    Print Z.to_nat.
    
    Z.to_nat = 
    fun z : Z => match z with
                 | 0 => 0%nat
                 | Z.pos p => Pos.to_nat p
                 | Z.neg _ => 0%nat
                 end
         : Z -> nat
    
  • 最后看来,对于这两个函数中的每个函数,ZArith都提供了类似于你的引理:

    SearchAbout Z.abs_nat Z.le iff.
    
    Zabs2Nat.inj_le: forall n m : Z, 0 <= n -> 0 <= m -> n <= m <-> (Z.abs_nat n <= Z.abs_nat m)%nat
    Zabs2Nat.inj_lt: forall n m : Z, 0 <= n -> 0 <= m -> n < m <-> (Z.abs_nat n < Z.abs_nat m)%nat
    
    SearchAbout Z.to_nat Z.le iff.
    
    Z2Nat.inj_iff: forall n m : Z, 0 <= n -> 0 <= m -> Z.to_nat n = Z.to_nat m <-> n = m
    Z2Nat.inj_le: forall n m : Z, 0 <= n -> 0 <= m -> n <= m <-> (Z.to_nat n <= Z.to_nat m)%nat
    Z2Nat.inj_lt: forall n m : Z, 0 <= n -> 0 <= m -> n < m <-> (Z.to_nat n < Z.to_nat m)%nat
    

祝你好运