I used to use info_auto to display the steps actually performed under the hood by an auto tactic. However, this no longer seems to work with Coq 8.5 (beta3).
The following example used to work for Coq 8.4:
Example auto_example_5: 2 = 2.
Proof.
info_auto.
Qed.
and give me the necessary steps such as apply #eq_refl..
With Coq8.5, I get a warning:
The "info_auto" tactic does not print traces anymore. Use "Info 1 auto", instead.
(* info auto : *)
Using Info 1 auto. as hinted, I got:
<unknown>
in the message view. In other occasions, I sometimes get things like
<unknown>; refine H
But neither is helpful/informational because I can't apply these to finish the proof manually.
What is the proper way to replicate the old info_auto function in Coq 8.5?
This issue seems to have been fixed in Coq 8.6.
Related
Let's suppose that I have the following proof state:
1 subgoal
P, Q : Prop
H : P -> Q
-------------------(1/1)
Q
and I know a way to prove P, how may I add an "inline proof" of it so that I can have it in my list of assumptions?
Another thing you can use is the pose proof tactic. This lets you actually supply the proof term and name it (pose proof (foo bar baz) as qux basically translates into let qux := foo bar baz in ... in the generated proof).
This can be neat for things like specialized versions of a lemma that you're going to use in multiple branches.
The tactic assert does exactly that.
Using assert (<proposition>) breaks your objective into two subgoals, in the first you have to prove "<proposition>" with your current assumptions, and the second has your original goal as the objective, but with "<proposition>" added to the list of assumptions.
You may also specify its name with assert (<proposition>) as <name> or assert (<name>: <proposition>).
Another option is to use cut (<proposition>).
It also creates two objectives, one of the form <proposition> -> <your objective> (then you can get your hypothesis by using intros, or intros <name> if you want to specify its name), and another one in which you have to prove "<prososition>" with your current assumptions.
If you use the SSRreflect proof language, you can use the have proof_of_P: P. <write your proof here> construct.
Diving deep into test_nostutter_1 excersize I found a way to solve it without repeat:
Example test_nostutter_1: nostutter [3;1;4;1;5;6].
Proof.
constructor 3.
(* This will apply the tactics to the 2-nd subgoal *)
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 3.
2: {apply eqb_neq. auto. }
constructor 2.
Qed.
I decided to play more with it and in coq reference manual I found that there is do tactical that can loop a tactic several times.
do num expr
expr is evaluated to v which must be a tactic value. This tactic value v is applied num times. Supposing num > 1, after the first
application of v, v is applied, at least once, to the generated
subgoals and so on. It fails if the application of v fails before the
num applications have been completed.
So I tried this:
do 4 constructor 3; 2: {apply eqb_neq. auto. }
But unfortunately it fails. Only this works:
do 1 constructor 3.
Is it possible to make it work using do?
Answer
There are several issues in the line
do 4 constructor 3; 2: {apply eqb_neq. auto. }
First of all, you can't use the 2: or {} after the chain operator ;. The closest thing you can use is sequence with local application tac; [tac1 | tac2]. Since we want to do something on just the second branch, we can omit tac1 here.
Also, you can't use periods inside a tactical. A period marks the end of a statement, but the whole do expression is a single statement. You should always use sequence operator ; to chain several tactics.
Finally, do n tac; tac works like (do n tac); tac. You can wrap a tactic expression with parentheses, e.g. do n (tac; tac) to change the behavior.
So this one should work:
do 4 (constructor 3; [ | apply eqb_neq; auto ]).
Digression
We can simplify the line in several ways.
auto can be given extra theorems to automate with. Any goal solvable with apply eqb_neq; auto is also solvable with auto using eqb_neq.
do 4 (constructor 3; [ | auto using eqb_neq ]).
The auto tactic never fails, so it can be safely used on both branches.
do 4 (constructor 3; auto using eqb_neq).
repeat repeats until something fails or there are no more subgoals. The following will repeat until the 3rd constructor is no longer applicable.
repeat (constructor 3; auto using eqb_neq).
We can let Coq choose which constructor to apply. This can finish (or almost finish) the proof.
repeat (constructor; auto using eqb_neq).
We can also make constructors of nostutter automated by auto using Hint Constructors command. Now we can auto the whole thing. (You can place the hint command right after your definition of nostutter, then you can auto it everywhere.)
Hint Constructors nostutter.
auto using eqb_neq.
(* if the above fails, the following increases the search depth so it should succeed. *)
auto 6 using eqb_neq.
Actually, the theorem eqb_neq is already registered for auto. So we can just:
auto 6.
When implementing a complex tactic in Ltac, there are some Ltac commands or tactic invocation that I expect to fail and where that is expected (e.g. to terminate a repeat, or to cause backtracking). These failures are usually raised at failure level 0.
Failures raised at higher level “escape” the surrounding try or repeat block, and are useful to signal unexpected failures.
What I am missing is a way to run a tactic tac and treat its failure, even at level 0, to be at a higher level, while retaining the message of the failure. This would let me make sure that repeat does not terminate due to a Ltac programming error on my side.
Can I implement such a failure-raising-level higher-order tactic in Ltac?
You can write a tactic to achieve that in Ocaml. I put that on GitHub here.
For example the following should raise an error instead of silently succeeding:
repeat (match goal with
| [ |- _ ] =>
raise_error_level (assert (3 = 3) by idtac)
end).
I do not know if it is possible to get exactly what you want, but I sometimes use the following idiom:
tactic_expression_that_may_fail_with_level_0
|| fail 1000 "There was some problem here"
If the first tactic fails with level 0, the || will try to run the second one, which will fail with a very high level and report it to you.
It would help if you could provide a concrete use case to see if some other technique would be better suited.
I wonder if there is a way to obtain the proof term (serialized via Print or not) at some level beyond the current context (or just down to primitives). For example, executing the following
From mathcomp Require Import odd_order.PFsection14.
Print Feit_Thompson.
results in
Feit_Thompson =
fun (gT : fingroup.FinGroup.type)
(G : fingroup.group_of (gT:=gT)
(ssreflect.Phant
(fingroup.FinGroup.arg_sort
(fingroup.FinGroup.base gT)))) =>
BGsection7.minSimpleOdd_ind no_minSimple_odd_group (gT:=gT)
(G:=G)
: forall (gT : fingroup.FinGroup.type)
(G : fingroup.group_of (gT:=gT)
(ssreflect.Phant
(fingroup.FinGroup.arg_sort
(fingroup.FinGroup.base gT)))),
is_true
(ssrnat.odd
(fintype.CardDef.card
(T:=fingroup.FinGroup.arg_finType
(fingroup.FinGroup.base gT))
(ssrbool.mem
(finset.SetDef.pred_of_set
(fingroup.gval G))))) ->
is_true (nilpotent.solvable (fingroup.gval G))
but i would like to unfold the identifiers (theorems and definitions) used in the proof term such as no_minSimple_odd_group to their proof terms. I suspect that the opacity of theorems and lemmas might pose an obstacle to this purpose.
The naive solution i can think of is to recursively query each identifier via Print. Or a less naive (and less ideal due to the change in the language representing the proof term) solution, via program extraction.
I am not sure if there is a direct way of doing that, but it wouldn't be too hard to implement, at this level opacity is just a flag and can be bypassed.
However, I wonder about what do you want to achieve?
Note that most proof terms obtained that way are going to be just unmanageable, specially unfolding will quickly lead to a worse than exponential size blowup.
Why doesn't Coq accept this lemma as a hint?
Lemma contr : forall p1 : Prop, False -> p1.
Proof. tauto. Qed.
Hint Resolve contr : Hints.
Or other lemmas that end with a Prop variable?
Looking at the documentation for Hint Resolve ( http://coq.inria.fr/distrib/V8.4/refman/Reference-Manual011.html##command232 ):
term cannot be used as a hint
The type of term contains products over variables which do not appear in the conclusion. A typical example is a transitivity axiom. In that case the apply tactic fails, and thus is useless.
However, it does not seem (to me) to be the case here, as the only product is over p1 which does appear in the conclusion.
The problem here seems to be that your conclusion have absolutely no shape at all. auto seems to work by matching the shape of your goal with the shape of the return type of the hint database. Here, it might be upset by the fact that your goal is just a quantified variable. I am not sure whether this is a reasonable thing to trip over, but this particular instance might be the only case where you might have such a shapeless return type (with obviously the same case for Set and Type), so it's not a big deal.
So, you probably don't need this as a hint?... just use tactics such as tauto, intuition or perform any kind of elimination/destruction/inversion on the value of type False in your environment... not very satisfactory but eh :\