Printing a message only if a tactic succeeds - coq

Is there a way to print (using idtac?) a message in Ltac only after a command succeeds? Something like
first [ a; idtac "a did it!" | b; idtac "b did!" | idtac "nope"; fail ]
This almost works, except that multiple subgoals cause multiple messages to be printed:
Goal True /\ True.
split; idtac "Split did it!".
Filtering on just the first goal seems to work...
Goal True /\ True.
split; [ idtac "Split did it!" | .. ].
...except when it doesn't:
Goal True /\ True.
tauto; [ idtac "Tauto did it!" | .. ].
I could probably combine both patterns into one, but I'm not too too keen on the 100% penalty hit. And that would still not solve the case of the tactic discharging the goal entirely.
(I'm mostly interested in answers for Coq before 8.5, since in 8.5 Info and the like offer nice facilities for this. Still even in 8.5 it would be interesting to be able to print debug messages only at certain points)

Just using idtac works in Coq >= 8.5.
This almost works, except that multiple subgoals cause multiple messages to be printed:
Goal True /\ True.
split; idtac "Split did it!".
This is not true; if it were, let n := numgoals in idtac n would print multiple times as well. Here is the output I see:
$ ~/.local64/coq/coq-8.5pl3/bin/coqtop
Welcome to Coq 8.5pl3 (November 2016)
Coq < Goal True /\ True.
1 subgoal
============================
True /\ True
Unnamed_thm < split; idtac "Split did it!".
Split did it!
2 subgoals
============================
True
subgoal 2 is:
True
Unnamed_thm <
In Coq <= 8.4, you cannot do this, because Ltac evaluation has a different model. Instead, if you're willing to slightly complicate the proof term, and you have access to the beginning of the tactic sequence, you can do this:
Ltac duplicate_goal :=
lazymatch goal with
| [ |- ?G ] => cut G
end.
Goal True /\ True.
duplicate_goal; [ | split ]; [ idtac "Split did it!"; exact (fun x => x) | .. ].
The idea is that, by duplicating the goal, you can first run your tactic in one copy of the goal, then, assuming that succeeds, you can idtac in the other copy of the goal (which exists as a single goal whether or not your first tactic created multiple subgoals or solved the goal or whatever), and finally solve the duplicate goal with the identity function.

Related

Avoid duplicating code for applying tactics in both hypothesis and goal

I find my self (sort of) duplicating code because I want to the same tactics in the goal and in a hypothesis when they match. For example:
match goal with
| H : PATTERN |- _ => simpl in H; rewrite X in H; ... ; other_tactic in H
| |- PATTERN => simpl ; rewrite ; ... ; other_tactic
end.
If the tactics in the match cases becomes long, I essentially duplicate it, with some in clauses added, and this seem very unsatisfactory, in particular if I have many match clauses, so that I duplicate a lot of code.
Sometimes it is not because that I am matching, but simply that I have defined a custom tactic, but depending on the context I would like to apply it either to the goal or to a named hypothesis. For example:
Ltac my_tac H := simpl in H; rewrite X in H; ... ; other_tactic in H.
Ltac my_tac_goal := simpl ; rewrite X ; ... ; other_tactic.
Then I am again "duplicating" code.
Are there any ways of avoiding this kind of duplication?
At some point I wondered of the goal had a name, say GOAL, like hypothesis, so that simpl in GOAL was equivalent to simpl, but I suspect this is not the case. In that case I could drop the definition of my_tac_goal and then just call my_tac GOAL instead.
Any suggestions on how to avoid this kind of duplication would be appreciated.
PS I had a hard time coming up with a good title, so if somebody thinks of one that fits well, do not hesitate to change it.
The "name" of the goal in an in clause is |- *, but somehow I can't find a reference in the manual for this. E.g. the following works:
Goal 2+2=4 -> 2+2=4 -> 2+2=4.
intros H1 H2.
simpl in H1 |- *.
This applies simpl in H1 and the goal, but not in H2.
Indeed, the DRY principle is often a useful pattern, including for Coq developments!
Regarding the particular use case you describe, it seems you could benefit from the SSReflect tactical in?
Proof-of-concept:
Require Import ssreflect.
Section SomeTest.
Variables (T : Type) (a b : T).
Hypothesis L : a = b.
Ltac my_tac := simpl; rewrite L.
Lemma test (c : T) (H : let _t := tt in (* dummy let-in to exemplify [simpl] *)
(a, c) = (c, b)) :
let _t := tt in (b, c) = (c, a).
do [ my_tac ] in H.
my_tac.
exact: H.
Qed.
End SomeTest.
Obviously, the do [ … ] in H form won't be applicable for any tactic (e.g., an apply/view. tactic should be manually ported to some move/view. tactic), but nothing prevents you from extending the my_tac tactic (e.g., with some if-then-else…), so that relevant parts are adapted manually (or removed) to address both kinds of contexts.

What does Proof. simpl. reflexivity. Qed. mean in Coq?

I'm reading the book Software Foundations and got stuck at the very beginning.
The author defined a boolean type and common operations:
Inductive bool: Type :=
| true
| false.
Definition orb (b1: bool) (b2: bool) : bool :=
match b1 with
| true => true
| false => b2
end.
So let's say we want to prove the correctness of the or function.
The author wrote a test followed by a proof:
Example test_orb1: (orb true false) = true.
Proof. simpl. reflexivity. Qed.
Could someone explain to me what simpl. reflexivity mean? Is there any other way we can prove this simple test?
simpl is a tactic evaluating the goal. In your case, after executing it, the goal will be left to true = true.
reflexivity is a tactic discharging goals of the shape x = x (in its simplest incarnation). What it does under the hood is to provide the proof term eq_refl : x = x as a solution to the current proof obligation.
Now, there are many ways to achieve this thing that ultimately will produce the same (rather trivial) proof eq_refl (try doing Print test_orb1.). First, the simpl operation is not needed because Coq will do some computations when applying a term (in particular when calling reflexivity). Second, you could obtain the same effect as reflexivity by calling constructor, apply eq_refl or refine eq_refl. These are tactics with different goals but that happen to coincide here.

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

what's the correct usage for Coq "local application of tactics"?

I'm reading Coq reference manual (8.5p1) about
Local application of tactics
Different tactics can be applied to the different goals using the
following form:
[ > expr1 | ::: | exprn ]
The expressions expri are evaluated to vi, for i = 0; ...; n and all
have to be tactics. The vi is applied to the i-th goal, for = 1; ...;
n. It fails if the number of focused goals is not exactly n.
So I did a little test with two goals trying to apply two trivial idtac tactics to each, as follows:
Goal forall P Q: Prop, P \/ Q -> Q \/ P.
intros. destruct H. [ > idtac | idtac ].
However, I got an error telling me that only one tactic is expected:
Error: Incorrect number of goals (expected 1 tactic).
I'm confused. Can some one explain what I did wrong, and what's the correct usage?
The key part here is
It fails if the number of focused goals is not exactly n.
You need 2 focused goals.
The number of focused goals can be checked like this:
Ltac print_numgoals := let n := numgoals in idtac "# of goals:" n.
Goal forall P Q: Prop, P \/ Q -> Q \/ P.
intros. destruct H.
print_numgoals. (* prints 1 *)
There is a number of ways of getting several focused goals:
(1) Using sequencing: destruct H; [> idtac | idtac].
(2) Or slightly shorter: destruct H; [> idtac ..].
(3) Using the all selector (see the manual, §8.1):
destruct H. all: [ > id_tac | id_tac ].
In this last case, destruct H. all: print_numgoals. prints 2.
In conclusion, the following should be mentioned -- it seems that local application of tactics in that exact form ([ > ...]) is not very useful, because it is never used in the standard library (and several other libraries) and there are no mentions of it in the manual, except for the section devoted to this feature. Its version of the form expr; [ expr_1 | ... | expr_n] seems to be the most useful.

Why does use of Coq's setoid_replace "by" clause need an extra idtac?

I encountered a strange situation using setoid_replace where a proof step of the form:
setoid_replace (a - c + d) with b by my_tactic
fails with Error: No matching clauses for match goal, but after appending an extra idtac to the tactic:
setoid_replace (a - c + d) with b by (my_tactic; idtac)
the proof succeeds. My understanding of idtac was that it was essentially a no-op. Why does the presence of idtac make a difference here?
Here's the full code. I'm using Coq 8.4pl6 through Proof General.
Require Import QArith.
Open Scope Q.
Lemma rearrange_eq_r a b c d :
a == b -> b + d == a + c -> c == d.
Proof.
intro a_eq_b; rewrite a_eq_b; symmetry; now apply Qplus_inj_l with (z := b).
Qed.
Ltac rearrange :=
match goal with
| [ H : _ == _ |- _ == _ ] => apply rearrange_eq_r with (1 := H); ring
end.
Lemma test_rearrange a b c d e (H0 : e < b) (H1 : b + c == a + d) : e < a - c + d.
Proof.
(* Why is the extra 'idtac' required in the line below? *)
setoid_replace (a - c + d) with b by (rearrange; idtac).
assumption.
Qed.
Note: as Matt observes, idtac doesn't seem to be special here: it seems that any tactic (including fail!) can be used in place of idtac to make the proof succeed.
Thanks to Jason Gross on the Coq bug tracker for explaining this. This has to do with order of evaluation in the Ltac tactic language. In the failing case, the match in rearrange is being applied to the inequality in the immediate goal rather than to the equality generated by setoid_replace. Here's Jason's response on the bug report:
This is because the [match] is evaluated before the [setoid_replace]
is run. It is one of the unfortunate trip-ups of Ltac that things
like [match] and [let ... in ...] are evaluated eagerly until a
statement with semicolons, or other non-match non-let-in statement is
reached. If you add [idtac; ] before the [match] in [rearrange], your
problem will go away.