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?
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.