simpl
策略展开2 + a
到#34;匹配树和#34;等表达式。这看起来并不简单。例如:
Goal forall i:Z, ((fun x => x + i) 3 = i + 3).
simpl.
导致:
forall i : Z,
match i with
| 0 => 3
| Z.pos y' =>
Z.pos
match y' with
| q~1 =>
match q with
| q0~1 => (Pos.succ q0)~1
| q0~0 => (Pos.succ q0)~0
| 1 => 3
end~0
| q~0 =>
match q with
| q0~1 => (Pos.succ q0)~0
| q0~0 => q0~1
| 1 => 2
end~1
| 1 => 4
end
| Z.neg y' => Z.pos_sub 3 y'
end = i + 3
如何通过simpl
策略避免此类并发症?
这个特定的目标可以通过omega
解决,但如果它更复杂一点,omega就会失败,我不得不求助于:replace (2 + a) with (a + 2); simpl; replace (a + 2) with (2 + a)
。
答案 0 :(得分:8)
您可以使用Transparent
和Opaque
命令控制定义展开。在您的示例中,您应该能够说出类似
Opaque Z.add.
simpl.
Transparent Z.add.
或者,Arguments
command可用于指示simpl
策略,以避免在某些情况下简化术语。 E.g。
Arguments Z.add _ _ : simpl nomatch.
在你的情况下,为我做了诀窍。这个特殊变体的作用是避免在这样做之后(在你的例子中看到的)大的,丑陋的match
出现在头部位置时简化一个术语。但是,还有其他变种。
最后,为了完整起见,Ssreflect库提供了很好的基础设施,可以使某些定义在本地不透明。所以你可以说像
rewrite (lock Z.add) /= -lock.
意为“锁定Z.add
,以便它不会简化,然后简化表达式的剩余部分(/=
开关),然后再次解锁定义(-lock
)”
答案 1 :(得分:4)
您可以调整简化策略的行为方式,以减少匹配。
Require Import Coq.ZArith.ZArith.
Goal forall i:Z, ((fun x => (x + i)%Z) 3%Z = (i + 3)%Z).
Arguments Z.add x y : simpl nomatch.
simpl.
详细了解here。
否则,您可以使用other tactics来选择减少的方法。例如cbn beta
。