1

I am trying to understand how combined ssreflect tactics should be "decomposed" (or how they are composed in the first place). One of the problems I have is to understand the order and associativity of the taticals.

Sometimes, I feel that the order is from right to left. For example

apply : AiB.

seems equivalent to

move : AiB; apply. 

Ignoring the no-op move, it's as if we are applying functions to AiB in order, and apply : AiB. can be viewed as apply (: AiB). . That is, we first move AiB into the goal and then call apply on the goal with AiB in it.

However, I am confused in other occasions:

case: (EM (P y)) => // notPy.

According to the tutorial, this one does a case analysis on (EM (P y)), and then // tries to solve trivial sub-goals. Then?? move => introduce the remaining ones into the context? What's the order of operations here?

Let EM_ be (EM (P y)), is it (move=> notPy (// ( case (:EM_) ) ) ) ?? Am I reading this right, what is the "correct order" of tactic application?

The order is kind of twisted near notPy and inconsistent in general. Is there a way to write the above from right to left in legitimate ssreflect?

thor
  • 21,418
  • 31
  • 87
  • 173

1 Answers1

2

I advice you read the manual to get more details. https://hal.inria.fr/inria-00258384

In your example, recall that move is always a no-op, so it "fuses". Thus with colon, it fuses on the left.

move: H; case <=> case: H

and with => it fuses on the right:

case: H; move => U <=> case: H => U.

Thus for your particular example,

case: (EM (P y)) => // notPy.

could be seen as

move: (EM (P y)); case; move=> // notPy.

Regards!

ejgallego
  • 6,709
  • 1
  • 14
  • 29