我正在测试Coq重写策略模数关联性和交换性(aac_tactics
)。以下示例适用于整数(Z
),但在使用有理数(Q
)替换整数时会生成错误。
Require Import ZArith.
Import Instances.Z.
Goal (forall x:Z, x + (-x) = 0)
-> forall a b c:Z, a + b + c + (-(c+a)) = b.
intros H ? ? ?.
aac_rewrite H.
将Require Import ZArith.
替换为Require Import QArith.
等时,会出现错误:
错误:战术失败:找不到匹配的发生模数。
在aac_rewrite H.
Z
和Q
之间存在类似的不一致问题,结果与Z
/ Q
范围是否公开有关。
但我不明白为什么aac重写在这里不起作用。导致不一致的原因是什么,以及如何使Z
和Q
的行为相同?
答案 0 :(得分:2)
AAC_tactics库需要表达相关性,交换性等的定理。让我们用Qplus_assoc
表示有理数的相关性定律。
Qplus_assoc
: forall x y z : Q, x + (y + z) == x + y + z
正如您所看到的Qplus_assoc
没有使用=
,它使用==
来表示左侧和右侧之间的连接。 Rational在标准库中定义为整数和正数对:
Record Q : Set := Qmake {Qnum : Z; Qden : positive}.
因为,例如1/2 = 2/4,我们需要一些其他方法来比较相等的有理数(除=
之外的eq
除外)。因此,stdlib定义了Qeq
:
Definition Qeq (p q : Q) := (Qnum p * QDen q)%Z = (Qnum q * QDen p)%Z.
带符号
Infix "==" := Qeq (at level 70, no associativity) : Q_scope.
因此,在有理数的情况下,您可能希望将您的示例重写为以下内容:
Require Import Coq.QArith.QArith.
Require Import AAC_tactics.AAC.
Require AAC_tactics.Instances.
Import AAC_tactics.Instances.Q.
Open Scope Q_scope.
Goal (forall x, x + (-x) == 0) ->
forall a b c, a + b + c + (-(c+a)) == b.
intros H ? ? ?.
aac_rewrite H.
Search (0 + ?x == ?x).
apply Qplus_0_l.
Qed.