简体   繁体   中英

How to apply do tactic to a sequence

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] tac; [tac1 | tac2] 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 do n tac; tac works like (do n tac); tac (do n tac); tac . You can wrap a tactic expression with parentheses, eg 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 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM