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

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.

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.

What is the idiomatic way to get `auto` to perform case analysis?

Inductive Foo : nat -> Type :=
| a : Foo 1.
(* ... *)
Goal forall m, Foo m -> m = 1.
Proof.
auto.
Fail Qed.
Is there a straightforward approach to do this?
You can use Hint Extern together with a tactic script that executes the case analysis. For example, this one will use destruct if the argument is a variable, and use inversion_clear otherwise:
Inductive Foo : nat -> Type :=
| a : Foo 1.
Hint Extern 1 => match goal with
| [ H : Foo ?m |- _ ]
=> first [ is_var m; destruct H | inversion_clear H ]
end.
Goal forall m, Foo m -> m = 1.
Proof.
auto.
Qed.
Via Programming Language Foundations, chapter Theory and Practice of Automation in Coq Proofs:
Note that proof search tactics never perform any rewriting step (tactics rewrite, subst), nor any case analysis on an arbitrary data structure or property (tactics destruct and inversion), nor any proof by induction (tactic induction). So, proof search is really intended to automate the final steps from the various branches of a proof. It is not able to discover the overall structure of a proof.
So there is really no way to do this; this goal should be solved manually, and then added to the hint database (Hint blah.).

Apply partially instantiated lemma

Let us assume that we want to prove the following (totally contrived) lemma.
Lemma lem : (forall n0 : nat, 0 <= n0 -> 0 <= S n0) -> forall n, le 0 n.
We want to apply nat_ind to prove it. Here is a possible proof:
Proof.
intros H n. apply nat_ind. constructor. exact H.
Qed.
But why not directly using H in the apply tactic, using something like apply (nat_ind _ _ H) or eapply (nat_ind _ _ H) ? But the first one fails, and the second one hides the remaining goal in an existential variable.
Is it possible in apply or its derivatives to skip hypotheses in order to specify the other arguments while keeping them as classic goals in the remainder of the proof ?
If you do
intros. refine (nat_ind _ _ H _).
then you only have
0 <= 0
left. Is that useful in your case?
Another approach (more universal than in my other answer) would be using the apply ... with ... construct, like this:
intros H n.
apply nat_ind with (2 := H).
Here, 2 is referring to the inductive step parameter of nat_ind (see the Coq v8.5 reference manual, 8.1.3):
In a bindings list of the form (ref_1 := term_1) ... (ref_n := term_n), ref is either an ident or a num. ... If ref_i is some number n, this number denotes the n-th non dependent premise of the term, as determined by the type of term.
This partial proof
intros H n.
apply nat_ind, H.
will give you 0 <= 0 as the only subgoal left.
This approach uses the apply tactic, but does not answer the question in its generality, since it will work only if you want to instantiate the last parameter (which is the case for the example in the question).
Here is quote from the Coq reference manual:
apply term_1 , ... , term_n
This is a shortcut for apply term_1 ; [ .. | ... ; [ .. | apply term_n ]... ], i.e. for the successive applications of term_(i+1) on the last subgoal generated by apply term_i, starting from the application of term_1.
Also, since it's just syntactic sugar, the solution may be considered cheating (and, I guess, abuse of the original intent of the Coq tactics developers) in the context of the question.

Printing a message only if a tactic succeeds

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.