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.
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.
I state the following goal in HOL4:
set_goal([``A:bool``,``B:bool``], ``B:bool``);
resulting in the proof state
val it =
Proof manager status: 1 proof.
1. Incomplete goalstack:
Initial goal:
B
------------------------------------
0. B
1. A
: proofs
I tried to find a proper tactic for using the assumptions. I came up with ASM_MESON_TAC:
e (mesonLib.ASM_MESON_TAC [])
and it proved the goal:
OK..
Meson search level: ..
val it =
Initial goal proved.
[..] ⊢ B: proof
Is this the standard tactic in such a situation? Or, is there a simpler one?
e (FIRST_ASSUM ACCEPT_TAC)
does it.
FIRST_ASSUM applies the argument theorem tactic on assumptions until success.
ACCEPT_TAC simply proves a goal if we supply the same theorem.
ACCEPT_TAC: thm -> tactic
FIRST_ASSUM: (thm -> tactic) -> tactic
(thanks to somebody on #hol)
I need more primitive mechanism of generalization in sections.
For example,
Section sec.
Context (n:nat).
Definition Q:=bool.
End sec.
Check Q.
I will obtain Q : Set, but I need Q:nat->Set.
I've tried Context, Hypotheses, Variables. It doesn't work.
How to obtain such behavior?
This is not a thing you can do with Definition ... := However, you can use Proof using:
Section sec.
Context (n:nat).
Definition Q : Set.
Proof using n.
exact bool.
Defined.
End sec.
Check Q.
Consider the following code:
Inductive Even : nat -> Prop :=
| EO : Even O
| ESS : forall n, Even n -> Even (S (S n)).
Fixpoint is_even_prop (n : nat) : Prop :=
match n with
| O => True
| S O => False
| S (S n) => is_even_prop n
end.
Theorem is_even_prop_correct : forall n, is_even_prop n -> Even n.
Admitted.
Example Even_5000 : Even 5000.
Proof.
apply is_even_prop_correct.
Time constructor. (* ~0.45 secs *)
Undo.
Time (constructor 1). (* ~0.25 secs *)
Undo.
(* The documentation for constructor says that "constructor 1"
should be the same thing as doing this: *)
Time (apply I). (* ~0 secs *)
Undo.
(* Apparently, if there's only one applicable constructor,
reflexivity falls back on constructor and consequently
takes as much time as that tactic: *)
Time reflexivity. (* Around ~0.45 secs also *)
Undo.
(* If we manually reduce before calling constructor things are
faster, if we use the right reduction strategy: *)
Time (cbv; constructor). (* ~0 secs *)
Undo.
Time (cbn; constructor). (* ~0.5 secs *)
Qed.
Theorem is_even_prop_correct_fast : forall n, is_even_prop n = True -> Even n.
Admitted.
Example Even_5000_fast : Even 5000.
Proof.
apply is_even_prop_correct_fast.
(* Everything here is essentially 0 secs: *)
Time constructor.
Undo.
Time reflexivity.
Undo.
Time (apply eq_refl). Qed.
I just wanted to see if you could do reflection in Prop rather than Set and stumbled upon this. My question is not how to do the reflection properly, I just want to know why constructor is so slow in the first case compared to the second case. (Maybe it has something to do with that constructor can immediately see (without any reductions) that the constructor must be eq_refl in the second case? But it must still reduce afterwards...)
Also, while trying to figure out what constructor is doing I noticed that the documentation does not say which reduction strategy will be used by the tactic. Is this omission intentional, and the idea is that you should explicitly say which reduction strategy you want if you want one in particular (otherwise the implementation is free to pick any)?
Short answer: It spends its time trying to figure out what inductive family your goal is a part of (twice, in the case of constructor), using hnf.
Longer answer: Doing a bit of source-diving, it looks like constructor calls Tactics.any_constructor, while constructor 1 calls Tactics.constructor_tac. Tactics.any_constructor in turn calls Tacmach.New.pf_apply Tacred.reduce_to_quantified_ind to determine the inductive type to count the constructors, and then calls Tactics.constructor_tac on each possible constructor in turn. For True, since there is one constructor, it's suggestive that the time for constructor is about double the time for constructor 1; I'm guessing that the time is therefore spent in reduce_to_quantified_ind. Tacred.reduce_to_quantified_ind, in turn, calls reduce_to_ind_gen, which, in turn calls hnf_constr. And, indeed, it looks like Time hnf and Time constructor 1 are about the same. Furthermore, Time constructor is instant after a manual hnf. I'm not sure what strategy hnf uses internally. The documentation omission is almost certainly not deliberate (at least, whatever the current strategy is should appear in a footnote, I think, so feel free to report a bug), but it's not clear to me that the reduction strategy used by constructor in determining what inductive family your goal is a part of should be part of the specification of constructor.
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.