鉴于任何编程语言,只要存在标准库函数,我们就应该使用它而不是编写自己的代码。人们会认为这个建议同样适用于Coq。但是,我最近强迫自己使用same_relation
模块的Relation
谓词,我感觉情况更糟。所以我必须遗漏一些东西,因此我的问题。为了说明我的意思,让我们考虑可能的关系:
Require Import Relations. (* same_relation *)
Require Import Setoids.Setoid. (* seems to be needed for rewrite *)
Inductive rel1 {A:Type} : A -> A -> Prop :=
| rel1_refl : forall x:A, rel1 x x. (* for example *)
Inductive rel2 {A:Type} : A -> A -> Prop :=
| rel2_refl : forall x:A, rel2 x x. (* for example *)
只要rel1
和rel2
相同,这些关系的具体细节就不重要了。现在,如果我想忽略Coq库,我可以简单地说:
Lemma L1: forall (A:Type)(x y:A), rel1 x y <-> rel2 x y.
Proof.
(* some proof *)
Qed.
如果我想按照我的直觉并使用Coq库:
Lemma L2: forall (A:Type), same_relation A rel1 rel2.
Proof.
(* some proof *)
Qed.
在最简单的情况下,似乎已经证明引理L1
或引理L2
同样有益:
Lemma application1: forall (A:Type) (x y:A),
rel1 x y -> rel2 x y (* for example *)
Proof.
intros A x y H. apply L1 (* or L2 *) . exact H.
Qed.
我是否决定使用apply L1
或apply L2
没有任何区别......
然而在实践中,我们可能面临更复杂的目标:
Lemma application2: forall (A:Type) (x y:A) (p:Prop),
p /\ rel1 x y -> p /\ rel2 x y.
Proof.
intros A x y p H. rewrite <- L1. exact H.
Qed.
我的观点是,rewrite <- L1
替换rewrite <- L2
将会失败。对于前面的示例也是如此,但至少我能够使用apply
而不是rewrite
。在这种情况下我不能使用apply
(除非我经历了分裂目标的麻烦)。因此,如果我只有Lemma rewrite
,我似乎已经失去了使用L2
的便利。
对等效(不仅仅是相等)的结果使用rewrite
非常方便。似乎将等价包装到谓词same_relation
中会带来这种便利。我是否正确地遵循自己的直觉并强迫自己使用same_relation
?更一般地说,如果在标准Coq库中定义了一个构造,我应该使用它,而不是定义我自己的版本吗?
答案 0 :(得分:4)
你提出两个问题,我试着单独回答:
关于你的重写问题,这个问题很自然,因为same_relation
的定义是双重包含。我同意使用iff
的定义可能会更方便。这真的取决于你的目标类型。您的问题的可能解决方案是定义视图:
Lemma L1 {A:Type} {x y:A} : rel1 x y <-> rel2 x y.
Proof.
Admitted.
Lemma L2 {A:Type} : same_relation A rel1 rel2.
Proof.
Admitted.
Lemma U {T} {R1 R2 : relation T} :
same_relation _ R1 R2 -> forall x y, R1 x y <-> R2 x y.
Proof. now destruct 1; intros x y; split; auto. Qed.
Lemma application2 {A:Type} {x y:A} {p:Prop} :
p /\ rel1 x y -> p /\ rel2 x y.
Proof. now rewrite (U L2). Qed.
另请注意,使用<->
关系进行重写并非基于相等,而是基于&#34; setoid重写&#34;。事实上,以下内容并不适用于Coq A <-> B -> A = B
。
关于第二个问题,是否使用Coq标准库是一个非常主观的主题。我个人很少使用它,我更喜欢一个名为math-comp
的不同的库,而是YMMV。关于关系,mathcomp主要是专门用于布尔关系rel x y = x -> y -> bool
,因此,等价被简单地定义为相等,通常,给定r1 r2
你写r1 =2 r2
。
[edit] :请注意,关系库的日期为:
Coq中的朴素集合论。 Coq V6.1。这项工作于1993年7月由F. Prost开始。
事实上,它可能不是建立Coq开发的最佳现代基地。