How to forbid simpl tactic to unfold arithmetic expressions?

江枫思渺然 提交于 2019-12-30 08:39:06

问题


The simpl tactic unfolds expressions like 2 + a to "match trees" which doesn't seem simple at all. For example:

Goal forall i:Z, ((fun x => x + i) 3 = i + 3).
simpl.

Leads to:

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

How to avoid such complications with simpl tactic?

This particular goal can be solved with omega, but if it is a bit more sophisticated, omega fails, and i have to resort to something like: replace (2 + a) with (a + 2); simpl; replace (a + 2) with (2 + a).


回答1:


You can control definition unfolding with the Transparent and Opaque commands. In your example, you should be able to say something like

Opaque Z.add.
simpl.
Transparent Z.add.

Alternatively, the Arguments command can be used to instruct the simpl tactic to avoid simplifying terms in certain contexts. E.g.

Arguments Z.add _ _ : simpl nomatch.

does the trick for me in your case. What this particular variant does is to avoid simplifying a term when a big, ugly match would appear in head position after doing so (what you saw in your example). There are other variants too, however.

Finally, just for completeness, the Ssreflect library provides nice infrastructure for making certain definitions opaque locally. So you could say something like

rewrite (lock Z.add) /= -lock.

meaning "lock Z.add, so that it won't simplify, then simplify the remaining of the expression (the /= switch), then unlock the definition again (-lock)".




回答2:


You can tweak how the simpl tactic behaves so you get less matches.

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.

Read more about it here.

Otherwise you can use other tactics that allow you to choose how to reduce. cbn beta, for example.



来源:https://stackoverflow.com/questions/28432187/how-to-forbid-simpl-tactic-to-unfold-arithmetic-expressions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!