在coq中记录相等性

时间:2018-06-19 08:43:22

标签: coq

例如,我有这个样本记录:

Record Sample := {
  SA :> nat ; 
  SB :> Z ; 
  SCond : Z.abs_nat SB <> SA
}.

当我想证明这个引理时:

Lemma Sample_eq : forall a b : Sample , a = b <-> SA a = SA b /\ SB a = SB b.

我明白这一点:

1 subgoal
______________________________________(1/1)
forall a b : Sample, a = b <-> a = b /\ a = b

问题1:如何强制Coq显示SA a而不是?

问题2:如何证明这个引理?

1 个答案:

答案 0 :(得分:4)

问题1

Coq打印SA,因为您将其声明为强制。您可以通过在文件中添加选项Set Printing Coercions.来防止这种情况。据我所知,没有办法只让Coq只打印 SA,而不能打印其他SB这样的强制性代码。但是,您可以将:>替换为:,以防止将SA声明为强制。

问题2

如果不假设Coq理论有额外的公理,就无法证明您的引理。问题是您需要证明Z.abs_nat SB <> SA的两个证明是相等的,才能证明两个Sample类型的记录是相等的,而Coq的理论中没有什么可以帮助您。您有两种选择:

  1. 使用证明无关紧要的公理,即forall (P : Prop) (p1 p2 : P), p1 = p2。例如:

    Require Import Coq.ZArith.ZArith.
    Require Import Coq.Logic.ProofIrrelevance.
    
    Record Sample := {
      SA : nat;
      SB : Z;
      SCond : Z.abs_nat SB <> SA
    }.
    
    Lemma Sample_eq a b : SA a = SA b -> SB a = SB b -> a = b.
    Proof.
      destruct a as [x1 y1 p1], b as [x2 y2 p2].
      simpl.
      intros e1 e2.
      revert p1 p2.
      rewrite <- e1, <- e2.
      intros p1 p2.
      now rewrite (proof_irrelevance _ p1 p2).
    Qed.
    

    (请注意对revert的调用:使用e1e2重写时,需要使用它们来防止相关类型错误。)

  2. 用不依赖证明有效且无额外公理的命题代替不等式。典型的解决方案是使用命题的布尔版本。 DecidableEqDepSet模块显示,具有可确定相等性的类型(例如布尔值)的相等性证明满足证明不相关的要求。

    Require Import Coq.ZArith.ZArith.
    Require Import Coq.Logic.ProofIrrelevance.
    Require Import Coq.Logic.Eqdep_dec.
    
    Module BoolDecidableSet <: DecidableSet.
    
    Definition U := bool.
    Definition eq_dec := Bool.bool_dec.
    
    End BoolDecidableSet.
    
    Module BoolDecidableEqDepSet := DecidableEqDepSet BoolDecidableSet.
    
    Record Sample := {
      SA : nat;
      SB : Z;
      SCond : Nat.eqb (Z.abs_nat SB) SA = false
    }.
    
    Lemma Sample_eq a b : SA a = SA b -> SB a = SB b -> a = b.
    Proof.
      destruct a as [x1 y1 p1], b as [x2 y2 p2].
      simpl.
      intros e1 e2.
      revert p1 p2.
      rewrite <- e1, <- e2.
      intros p1 p2.
      now rewrite (BoolDecidableEqDepSet.UIP _ _ p1 p2).
    Qed.