coqltac

Pattern-matching a hypothesis obtained from a pattern-match on goal


Consider the following development:

Definition done {T : Type} (x : T) := True.

Goal Test.
  pose 1 as n.
  assert (done n) by constructor.
  Fail ltac:(
    match goal with 
    | [ H : done _ |- _ ] => fail
    | [ H : _ |- _ ] =>
      match goal with
      | [ _: done H |- _ ] => idtac "H == n"
      | [ _: done n |- _ ] => idtac "H != n"; fail 2
      end
    end
  ).
Abort.

This prints H != n. I'm finding this very surprising, since the only hypothesis in scope are n and done n - and done n was already dispatched by the first branch of the top-level match.

How can I match done n without explicitly referring to n, as in the first branch of the second match?


Solution

  • I think you are confused by the way match works. The first branch of the matching is matched against every hypothesis, and if it always fails, the second branch is tested, and so on. In your example, the first branch matches hypothesis H, but the execution of the corresponding tactic (fail) fails, thus the second branch is tried that also matches hypothesis H.

    Actually, the first branch of the outer match seems to do what you want (i.e. matches on a hypothesis of the form done _) so I don't really get the point of your inner match.

    For instance,

    match goal with 
    | [ H' : done _ |- _ ] => idtac H'
    end.
    

    prints H, showing that the right hypothesis is matched.

    Note that you don't need the ltac:() expression to use Fail on a tactic. For example, Fail fail. works.