GEN_TAC
Often used as the initial step of a proof
Remove the universal quantifier in the goal
Suppose the goal is to prove associativity of "/\"
Initial goal:
!x y z. x /\ y /\ z = (x /\ y) /\ z
Use GEN_TAC
- e(GEN_TAC);
to obtain
1 subgoal:
> val it =
!y z. x /\ y /\ z = (x /\ y) /\ z
: goalstack
with universal quantifier x removed.
Use
e(REPEAT GEN_TAC) to remove them all.
Use
e(GEN_TAC THEN GEN_TAC); to remove two universal quantifiers
Return to index
val it =
(a x ==> b x) /\ ~b x ==> ~a x
: goalstack
- e(DISCH_TAC);
OK..
1 subgoal:
> val it =
~a x
------------------------------------
(a x ==> b x) /\ ~b x
: goalstack
Return to index
Set a goal that is an implication and has a conjuctive conclusion
g(`!(x:num). (a x==> b x) /\ ~b x ==> (~a x /\ ~~~b x)`);
> val it =
Proof manager status:
1. Incomplete:
Initial goal:
!x. (a x ==> b x) /\ ~b x ==> ~a x /\ ~~~b x
: proofs
Now peel off universal quantifier and move antecedent to assumption list
- e(GEN_TAC THEN DISCH_TAC);
OK..
Now you have a conjunctive goal and can prove them separately
1 subgoal:
> val it =
~a x /\ ~~~b x
------------------------------------
(a x ==> b x) /\ ~b x
: goalstack
- e(CONJ_TAC);
OK..
2 subgoals:
> val it =
~~~b x
------------------------------------
(a x ==> b x) /\ ~b x
~a x
------------------------------------
(a x ==> b x) /\ ~b x
: goalstack
This is an example where the "stack" property of the proof environment
can be seen. The original sequent that was on top of the stack
has been replaced by two sequents on the stack
Return to indexSTRIP TAC is a combination of GEN_TAC, CONJ_TAC and DISCH_TAC
1. Incomplete:
Initial goal:
!x. (a x ==> b x) /\ ~b x ==> ~a x /\ ~~~b x
: proofs
- e(REPEAT STRIP_TAC);
OK..
2 subgoals:
> val it =
F
------------------------------------
0. a x ==> b x
1. ~b x
2. ~~b x
F
------------------------------------
0. a x ==> b x
1. ~b x
2. a x
: goalstack
Return to indexUse UNDISCH_TAC to move an assumption from the assumption list to the goal, as the antecedent of an implication.
You must specify which assumption to move, so the "Term" function is used. It is frequent that you need to specify the types of the variables mentioned in the argument of Term.
val it =
F
------------------------------------
0. a x ==> b x
1. ~b x
2. ~~b x
: goalstack
- e(UNDISCH_TAC (Term `~~b (x:num)`));
OK..
1 subgoal:
> val it =
~~b x ==> F
------------------------------------
0. a x ==> b x
1. ~b x
: goalstack
Return to indexUsed to do resolution on the assumption list, adding results to the assumption list.
F
------------------------------------
0. a x ==> b x
1. ~b x
2. a x
: goalstack
- e(RES_TAC);
OK..
1 subgoal:
> val it =
F
------------------------------------
0. a x ==> b x
1. ~b x
2. a x
3. b x
: goalstack
Notice the assumption list now has both b x and ~ b x
as elements. RES_TAC will detect this and since the assumption
list is contradictory, it will declare the sequent true.
False implies everything!!!
- e(RES_TAC);
OK..
Goal proved.
[..] |- F
Goal proved.
[...] |- F
Return to indexUse in cases where you wish to split the proof in two, with some term true in one and false in the other.
val it =
~~b x ==> F
------------------------------------
0. a x ==> b x
1. ~b x
: goalstack
We will split with b x in one part and ~b x in the other.
- e(ASM_CASES_TAC (Term `(b:num->bool) x`));
OK..
2 subgoals:
> val it =
~~b x ==> F
------------------------------------
0. a x ==> b x
1. ~b x
2. ~b x
~~b x ==> F
------------------------------------
0. a x ==> b x
1. ~b x
2. b x
: goalstack
Return to indexRewrite the goal using equations in the assumption list.
Writing is left to right. If the left side of an equation from the assumption list appears in the goal, then the goal is rewritten with that occurence replaced by the right side of the equation. If you want right to left replacement, use GSYM conversion
ASM_REWRITE_TAC takes an argument that is a list of theorems. Often you don't have any theorems to include so an empty list is the argument.
ASM_REWRITE_TAC []
The above can be replaced by AR, which is less typing, if you have opened ante_allTacs.
val it =
~~b x ==> F
------------------------------------
0. a x ==> b x
1. ~b x
: goalstack
- e(ASM_REWRITE_TAC []);
OK..
Goal proved.
[.] |- ~~b x ==> F
Goal proved.
[..] |- F
> val it =
Initial goal proved.
|- !x. (a x ==> b x) /\ ~b x ==> ~a x /\ ~~~b x : goalstack
Return to index
e(LEMMA_TAC (Term `t0 < (SUC t) + t0`)
Presumably, the term is needed on the assumption list.
e(LEMMA_MP_TAC (Term `t0 < (SUC t) + t0`)
Presumably the term is needed as the antecedent of an
implication with the original goal as conclusion.
Return to index
Return to tactics list
1 subgoal:
> val it =
PARITY_Design f out ==> PARITY_Spec f out
: goalstack
- e(REWRITE_TAC [PARITY_Design_def, PARITY_Spec_def]);
OK..
1 subgoal:
> val it =
(?next notgate.
MULTIPLEXER f notgate out next /\ NOT_gate out notgate /\
REG next out) ==>
out 0 /\ !t. out (SUC t) = PARITY (SUC t) f
: goalstack
;
So we see that the definitions of PARITY_Design_def and
PARITY_Spec_def have been used.
Later in the same proof we want to use an assumption for rewriting,
but we want the rewriting to be right to left. Use with_asm to
select the assumption. The "fn th" text captures the assumption
as "th". Then include th in the REWRITE_TAC using GSYM to reverse it.
It would have been a simpler tactic if we had not wanted the reversal.
e(with_asm "out t" (REWRITE_TAC o ulist));
would suffice for rewriting left to right.
> val it =
(if f (SUC t) then ~PARITY (SUC t) f else PARITY (SUC t) f) =
PARITY (SUC (SUC t)) f
------------------------------------
0. !t. next t = (if f t then notgate t else out t)
1. !t. notgate t = ~out t
2. out 0
3. !t. out (SUC t) = next t
4. out (SUC t) = PARITY (SUC t) f
: goalstack
- e(with_asm "out t" (fn th => (REWRITE_TAC [(GSYM th)])));
OK..
1 subgoal:
> val it =
(if f (SUC t) then ~out (SUC t) else out (SUC t)) =
PARITY (SUC (SUC t)) f
------------------------------------
0. !t. next t = (if f t then notgate t else out t)
1. !t. notgate t = ~out t
2. out 0
3. !t. out (SUC t) = next t
4. out (SUC t) = PARITY (SUC t) f
: goalstack
Return to index
Initial goal:
(x * 6) MOD 6 = 0
: proofs
- MOD_EQ_0;
> val it = |- !n. 0 < n ==> !k. (k * n) MOD n = 0 : thm
- e(MATCH_MP_TAC MOD_EQ_0);
OK..
1 subgoal:
> val it =
0 < 6
Return to index Initial goal:
!a b c. (a \/ b) /\ (c \/ ~b) ==> a \/ c
: proofs
- e(TAUT_TAC);
OK..
> val it =
Initial goal proved.
|- !a b c. (a \/ b) /\ (c \/ ~b) ==> a \/ c : goalstack
Return to index1 subgoal:
> val it =
(2 ** n - 1 + 1 = 2 ** n) ==> (2 * 2 ** n - 1 + 1 = 2 * 2 ** n)
: goalstack
- e(ARITH_TAC);
OK..
Goal proved.
|- (2 ** n - 1 + 1 = 2 ** n) ==> (2 * 2 ** n - 1 + 1 = 2 * 2 ** n)
Return to index
(!i. i < 0 ==> ~g i) = (0 = Val 0 g)
: goalstack
- e(RW_TAC arith_ss []);
OK..
1 subgoal:
> val it =
0 = Val 0 g
: goalstack
Return to index
> val it =
!t. out (SUC t) = PARITY (SUC t) f
------------------------------------
0. !t. next t = (if f t then notgate t else out t)
1. !t. notgate t = ~out t
2. out 0
3. !t. out (SUC t) = next t
: goalstack
- e(Induct);
OK..
2 subgoals:
> val it =
out (SUC (SUC t)) = PARITY (SUC (SUC t)) f
------------------------------------
0. !t. next t = (if f t then notgate t else out t)
1. !t. notgate t = ~out t
2. out 0
3. !t. out (SUC t) = next t
4. out (SUC t) = PARITY (SUC t) f
out (SUC 0) = PARITY (SUC 0) f
------------------------------------
0. !t. next t = (if f t then notgate t else out t)
1. !t. notgate t = ~out t
2. out 0
3. !t. out (SUC t) = next t
: goalstack
Return to index
!t. out (SUC t) = (if f t then ~out t else out t)
------------------------------------
0. PARITY_Design f out
1. out 0
: goalstack
- PARITY_Design_Implies;
> val it =
|- !f out.
PARITY_Design f out ==>
!t. out (SUC t) = (if f t then ~out t else out t) : thm
- e(IMP_RES_TAC PARITY_Design_Implies );
OK..
Goal proved.
[.] |- !t. out (SUC t) = (if f t then ~out t else out t)