例如,我有这个样本记录:
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:如何证明这个引理?
答案 0 :(得分:4)
问题1
Coq打印SA
,因为您将其声明为强制。您可以通过在文件中添加选项Set Printing Coercions.
来防止这种情况。据我所知,没有办法只让Coq只打印 SA
,而不能打印其他SB
这样的强制性代码。但是,您可以将:>
替换为:
,以防止将SA
声明为强制。
问题2
如果不假设Coq理论有额外的公理,就无法证明您的引理。问题是您需要证明Z.abs_nat SB <> SA
的两个证明是相等的,才能证明两个Sample
类型的记录是相等的,而Coq的理论中没有什么可以帮助您。您有两种选择:
使用证明无关紧要的公理,即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
的调用:使用e1
和e2
重写时,需要使用它们来防止相关类型错误。)
用不依赖证明有效且无额外公理的命题代替不等式。典型的解决方案是使用命题的布尔版本。 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.