假设我们有目标
a + b + c + d = a + c + b + d
a, b, c, d: nat
和plus_comm
中的引理Arith
:
plus_comm
: forall n m : nat, n + m = m + n
可以做
rewrite plus_comm.
获得d + (a + b + c) = a + c + b + d
和rewrite (plus_comm a b).
获得b + a + c + d = a + c + b + d
。但是执行rewrite (plus_comm b c)
或rewrite (plus_comm c d)
会引发类似于
Found no subterm matching "b + c" in the current goal.
问题。
为什么会这样,我们该怎么做才能在目标中将b + c
重写为c + b
?
编辑。
要将b + c
重写为c + b
,我们可以做
rewrite (plus_assoc_reverse a).
rewrite (plus_comm b c).
rewrite plus_assoc.
使用reflexivity.
证明引理
有没有更优雅的方式?
答案 0 :(得分:4)
Coq中的+
运算符保持关联性,因此a + b + c + d
之类的名词实际上是伪装的((a + b) + c) + d
。这应该可以回答为什么plus_comm
不能达到您的期望。
要解决这些类型的目标,您需要应用发现的一系列引理。这通常很乏味,因此可以使用一些策略来解决这些问题,例如omega
(请参阅this问题)。
答案 1 :(得分:3)
在这种情况下,如果您想避免完全了解所有定理,则可以经常写:
ring
此命令(也称为战术),在加载Arith
库后立即可用。它专门用于证明等式,其中两个项具有相同的模联合性,加法和乘法的可交换性以及乘法加法的分布性。如果您使用的是整数Z
,则还可以包括减法。
另一个答案中建议的策略omega
可以解决问题,但仅适用于包含有限形式的乘法的公式。附带说明一下,omega
将在Coq的未来版本中淘汰,它将由名为lia
(代表线性整数算术)的策略代替。