如何禁止简单策略展开算术表达式?
How to forbid simpl tactic to unfold arithmetic expressions?
simpl
策略将 2 + a
到 "match trees" 这样的表达式展开,这看起来一点也不简单。例如:
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)
.
您可以使用 Transparent
和 Opaque
命令控制定义展开。在您的示例中,您应该可以说
Opaque Z.add.
simpl.
Transparent Z.add.
或者,Arguments
command 可用于指示 simpl
策略以避免在某些上下文中简化术语。例如
Arguments Z.add _ _ : simpl nomatch.
在你的情况下对我有用。这个特殊变体的作用是避免简化一个大的、丑陋的 match
会出现在头部位置的术语(你在你的例子中看到的)。但是,还有其他变体。
最后,为了完整起见,Ssreflect 库提供了很好的基础设施,使某些定义在本地不透明。所以你可以这样说
rewrite (lock Z.add) /= -lock.
意思是"lock Z.add
, so that it won't simplify, then simplify the remaining of the expression (the /=
switch), then unlock the definition again (-lock
)"。
您可以调整简单策略的行为方式,从而减少匹配次数。
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
,例如
simpl
策略将 2 + a
到 "match trees" 这样的表达式展开,这看起来一点也不简单。例如:
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)
.
您可以使用 Transparent
和 Opaque
命令控制定义展开。在您的示例中,您应该可以说
Opaque Z.add.
simpl.
Transparent Z.add.
或者,Arguments
command 可用于指示 simpl
策略以避免在某些上下文中简化术语。例如
Arguments Z.add _ _ : simpl nomatch.
在你的情况下对我有用。这个特殊变体的作用是避免简化一个大的、丑陋的 match
会出现在头部位置的术语(你在你的例子中看到的)。但是,还有其他变体。
最后,为了完整起见,Ssreflect 库提供了很好的基础设施,使某些定义在本地不透明。所以你可以这样说
rewrite (lock Z.add) /= -lock.
意思是"lock Z.add
, so that it won't simplify, then simplify the remaining of the expression (the /=
switch), then unlock the definition again (-lock
)"。
您可以调整简单策略的行为方式,从而减少匹配次数。
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
,例如