Tactic index
In this document we illustrate various Rocq tactics that appear in the course. They are not ordered alphabetically but rather follow an order more or less in line with the lecture notes.
intro
Usage: intro h, where h is a new name.
intro h introduces hypothesis h into the context
It works when the goal is equivalent to A -> B or forall (x : A), B, in
which case h is of type A and the goal becomes B (where x is replaced
by h when it appears).
forall (P : nat -> Prop) (x : nat), P x -> P (0 + x)forall (P : nat -> Prop) (x : nat), P x -> P (0 + x)Q: nat -> Propforall x : nat, Q x -> Q (0 + x)Q: nat -> Prop
y: natQ y -> Q (0 + y)Abort.Q: nat -> Prop
y: nat
h: Q yQ (0 + y)
split
Usage: split.
Applies when the goal is morally a conjunction of subgoals and asks the user
to prove those subgoals instead.
This works for conjunction (A /\ B) and nullary-conjunction (True):
True /\ True /\ TrueTrue /\ True /\ TrueTrueTrue /\ Truesplit.TrueTrue /\ TrueTrueTruesplit.Truesplit. Abort.True
More advanced. It in fact applies whenever the goal is an inductive type which has exactly one constructor and requires you to give its arguments one by one.
unit * (0 = 0)unit * (0 = 0)unit0 = 0split.unitsplit. Abort.0 = 0
destruct
Usage: destruct t as p, where t is an expression (often a variable) and
p is an intropattern (explained below).
Performs case analysis on t, generating as many goals as possible ways to
construct t (for instance, for t : bool, there are two such cases), and
replacing t in the goal by the corresponding constructions (so true and
false in the bool case).
As a first approximation, you can see p as the list of cases, separated by
pipes (|), and for each of them you provide the names to be used for the
introduced constants, separated by spaces.
See for instance, case analysis on natural numbers:
forall (P : nat -> Prop) (n : nat), P nforall (P : nat -> Prop) (n : nat), P nP: nat -> Propforall n : nat, P nP: nat -> Prop
n: natP nAbort.P: nat -> PropP 0P: nat -> Prop
m: natP (S m)
The intropattern contains no name for the 0 case, since 0 takes no argument,
and exactly one for the successor case, since S takes one argument.
Variant: destruct t1 as p1, t2 as p2, …, tn as pn.
Lets you run several destruct in parallel.
Gives you all possible combinations as goals.
forall (P : bool -> bool -> nat -> Type) (x y : bool) (n : nat), P x y nforall (P : bool -> bool -> nat -> Type) (x y : bool) (n : nat), P x y nAbort.P: bool -> bool -> nat -> TypeP true true 0P: bool -> bool -> nat -> Type
m: natP true true (S m)P: bool -> bool -> nat -> TypeP true false 0P: bool -> bool -> nat -> Type
m: natP true false (S m)P: bool -> bool -> nat -> TypeP false true 0P: bool -> bool -> nat -> Type
m: natP false true (S m)P: bool -> bool -> nat -> TypeP false false 0P: bool -> bool -> nat -> Type
m: natP false false (S m)
Advanced variant: destruct t as p eqn:e.
This version lets you additionally record an equality e : t = _ where _
stands for the construction in each goal.
forall (P : bool -> Prop) (b : bool), P bforall (P : bool -> Prop) (b : bool), P bp: bool -> Propforall b : bool, p bp: bool -> Prop
b: boolp bAbort.p: bool -> Prop
b: bool
e: b = truep truep: bool -> Prop
b: bool
e: b = falsep false
intros
Usage: intros p1 p2 ... pN, where each pI is an intropattern, the list
can be empty.
At first glance, it behaves like a succession of intro:
indeed, intros a b c. is equivalent to intro a. intro b. intro c.
When no argument is provided, it introduces as much as it can, using
auto-generated names.
intros can in fact do much more, since intropatterns can be used to also
perform case analysis.
forall (P : bool -> nat -> Type) (b : bool) (n : nat), P b nforall (P : bool -> nat -> Type) (b : bool) (n : nat), P b nAbort.P: bool -> nat -> TypeP true 0P: bool -> nat -> TypeP true 1P: bool -> nat -> Type
k: natP true (S (S k))P: bool -> nat -> TypeP false 0P: bool -> nat -> TypeP false 1P: bool -> nat -> Type
k: natP false (S (S k))
apply
Usage: apply t, where t is an expression (often a lemma or an
assumption).
Unifies the type of t with the goal to attempt to conclude using t.
If successful, the resulting goals will correspond to arguments to t that must
be provided to conclude, or none if t is sufficient.
From Stdlib Require Import List.forall (A : Type) (l : list A), l ++ nil = lforall (A : Type) (l : list A), l ++ nil = lapply app_nil_r. Abort.A: Type
l: list Al ++ nil = lforall P Q R : Type, (P -> Q -> R) -> Rforall P Q R : Type, (P -> Q -> R) -> RP, Q, R: Type
h: P -> Q -> RRAbort.P, Q, R: Type
h: P -> Q -> RPP, Q, R: Type
h: P -> Q -> RQ
Variant: apply f in h where h is an hypothesis.
This time it tries to unify the type of h with one of the arguments of f.
forall P Q : nat -> Type, (forall n : nat, P n -> Q 5 -> Q (n + 2)) -> P 10 -> Q 12forall P Q : nat -> Type, (forall n : nat, P n -> Q 5 -> Q (n + 2)) -> P 10 -> Q 12P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: P 10Q 12Abort.P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: Q (10 + 2)Q 12P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: P 10Q 5
Variant: apply f in h as g, lets you additionally give a new name (g) to
the generated hypothesis, while keeping h in scope.
forall P Q : nat -> Type, (forall n : nat, P n -> Q 5 -> Q (n + 2)) -> P 10 -> Q 12forall P Q : nat -> Type, (forall n : nat, P n -> Q 5 -> Q (n + 2)) -> P 10 -> Q 12P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: P 10Q 12Abort.P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: P 10
hQ: Q (10 + 2)Q 12P, Q: nat -> Type
hPQ: forall n : nat, P n -> Q 5 -> Q (n + 2)
hP: P 10Q 5
Variant: apply f,g,h, lets you chain several apply in a row by
separating them with commas.
forall P Q R : Type, (P -> Q) -> (Q -> R) -> P -> Rforall P Q R : Type, (P -> Q) -> (Q -> R) -> P -> Rapply hQR, hPQ, hP. Abort.P, Q, R: Type
hPQ: P -> Q
hQR: Q -> R
hP: PR
Variant: apply f with u.
This variant lets you provide arguments that cannot be inferred from unification
with the goal alone.
In the example below, f takes n as argument, which doesn't appear in its
conclusion so apply f fails, telling you it's missing n.
We can provide it with apply f with 3 or apply f with (n := 2) to be
explicit about the argument being provided.
forall P : nat -> Type, (forall n m : nat, P n -> P m) -> P 10forall P : nat -> Type, (forall n m : nat, P n -> P m) -> P 10P: nat -> Type
f: forall n m : nat, P n -> P mP 10P: nat -> Type
f: forall n m : nat, P n -> P mP 10P: nat -> Type
f: forall n m : nat, P n -> P mP 3Abort.P: nat -> Type
f: forall n m : nat, P n -> P mP 2
assumption
Usage: assumption.
Concludes the goal if one of the assumptions matches it exactly.
forall (P Q : Prop) (R : Type), (P -> Q -> R) -> P /\ Q -> Rforall (P Q : Prop) (R : Type), (P -> Q -> R) -> P /\ Q -> RP, Q: Prop
R: Type
hPQR: P -> Q -> R
hP: P
hQ: QRP, Q: Prop
R: Type
hPQR: P -> Q -> R
hP: P
hQ: QPP, Q: Prop
R: Type
hPQR: P -> Q -> R
hP: P
hQ: QQassumption.P, Q: Prop
R: Type
hPQR: P -> Q -> R
hP: P
hQ: QPassumption. Abort.P, Q: Prop
R: Type
hPQR: P -> Q -> R
hP: P
hQ: QQ
left
Usage: left.
Lets you prove a goal of the form A \/ B by requiring you to prove A
instead.
forall A B : Prop, A \/ Bforall A B : Prop, A \/ BA, B: PropA \/ BAbort.A, B: PropA
right
Usage: right.
Lets you prove a goal of the form A \/ B by requiring you to prove B
instead.
Basically the same as left, but going right instead.
forall A B : Prop, A \/ Bforall A B : Prop, A \/ BA, B: PropA \/ BAbort.A, B: PropB
exfalso
Usage: exfalso.
Replaces the current goal with False, using the ex falso quod libet
principle, also known as principle of explosion: you can deduce anything from
False.
forall (P : Prop) (Q : Type), P -> ~ P -> Qforall (P : Prop) (Q : Type), P -> ~ P -> QP: Prop
Q: Type
hP: P
hnP: ~ PQAbort.P: Prop
Q: Type
hP: P
hnP: ~ PFalse
simpl
Usage: simpl.
Performs computation in the current goal to "simplify" it (in some sense).
forall P : nat -> Type, P 10 -> P (4 + 6)forall P : nat -> Type, P 10 -> P (4 + 6)P: nat -> Type
hP: P 10P (4 + 6)Abort.P: nat -> Type
hP: P 10P 10
Variant: simpl in h, where h is an assumption.
forall P : nat -> Type, P (7 + 3) -> P 10forall P : nat -> Type, P (7 + 3) -> P 10P: nat -> Type
hP: P (7 + 3)P 10Abort.P: nat -> Type
hP: P 10P 10
Variant: simpl in *.
Simplifies all hypotheses and the goal at once.
forall P : nat -> Type, P (2 + 2) -> P (4 + 8) -> P (27 + 5)forall P : nat -> Type, P (2 + 2) -> P (4 + 8) -> P (27 + 5)P: nat -> Type
h4: P (2 + 2)
h12: P (4 + 8)P (27 + 5)Abort.P: nat -> Type
h4: P 4
h12: P 12P 32
Variant: simpl n, where n is a constant name.
Perform computation only for n.
10 + 2 - (3 + 5) = 1910 + 2 - (3 + 5) = 19Abort.12 - 8 = 19
reflexivity
Usage: reflexivity.
Prove goals of the shape t = t, it thus corresponds to reflexivity of
equality.
f_equal
Usage: f_equal.
Turns a goal of the shape f x y … z = f x' y' … z' into x = x', y = y'
and z = z'.
forall (A B C D : Type) (f : A -> B -> C -> D) (x : A) (y : B) (z : C) (x' : A) (y' : B) (z' : C), f x y z = f x' y' z'forall (A B C D : Type) (f : A -> B -> C -> D) (x : A) (y : B) (z : C) (x' : A) (y' : B) (z' : C), f x y z = f x' y' z'A, B, C, D: Type
f: A -> B -> C -> D
x: A
y: B
z: C
x': A
y': B
z': Cf x y z = f x' y' z'Abort.A, B, C, D: Type
f: A -> B -> C -> D
x: A
y: B
z: C
x': A
y': B
z': Cx = x'A, B, C, D: Type
f: A -> B -> C -> D
x: A
y: B
z: C
x': A
y': B
z': Cy = y'A, B, C, D: Type
f: A -> B -> C -> D
x: A
y: B
z: C
x': A
y': B
z': Cz = z'
induction
Usage: induction t as p.
This works a bit like destruct except that it uses the induction principle
corresponding to the type of t and additionally gives induction hypotheses
in the recursive cases.
The intropattern p must also name said induction hypotheses.
forall n : nat, n + 0 = nforall n : nat, n + 0 = nn: natn + 0 = n0 + 0 = 0m: nat
ih: m + 0 = mS m + 0 = S mreflexivity.0 + 0 = 0m: nat
ih: m + 0 = mS m + 0 = S mm: nat
ih: m + 0 = mS (m + 0) = S mapply ih. Abort.m: nat
ih: m + 0 = mm + 0 = m
Variant: induction t as p in x, y, …, z |- *, where x, y, …, z is a
comma-separated sequence of assumptions (in the context) to generalise over.
It works like induction above but produce a stronger induction hypothesis
by generalising over the listed constants.
n, m, k: natk * (n + m) = k * n + k * mn, m, k: natk * (n + m) = k * n + k * mn, m: nat0 * (n + m) = 0 * n + 0 * mn, m, k: nat
ihk: forall n m : nat, k * (n + m) = k * n + k * mS k * (n + m) = S k * n + S k * mn, m: nat0 * (n + m) = 0 * n + 0 * mreflexivity.n, m: nat0 = 0Abort.n, m, k: nat
ihk: forall n m : nat, k * (n + m) = k * n + k * mS k * (n + m) = S k * n + S k * m
Advanced variant: induction t as p using ind.
Performs induction using a custom induction principle provided by ind.
From Stdlib Require Import Lia.forall P : nat -> Prop, P 0 -> P 1 -> (forall n : nat, P n -> P (S n) -> P (S (S n))) -> forall n : nat, P nforall P : nat -> Prop, P 0 -> P 1 -> (forall n : nat, P n -> P (S n) -> P (S (S n))) -> forall n : nat, P nP: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: natP nP: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: natP n /\ P (S n)P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
h: P n /\ P (S n)P nP: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: natP n /\ P (S n)P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))P 0 /\ P 1P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S n) /\ P (S (S n))P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))P 0 /\ P 1all: assumption.P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))P 0P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))P 1P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S n) /\ P (S (S n))P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S n)P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S (S n))assumption.P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S n)P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S (S n))all: assumption.P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P nP: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
ih1: P n
ih2: P (S n)P (S n)apply h. Qed. Fixpoint fib n : nat := match n with | 0 | 1 => 1 | S (S n as m) => fib m + fib n end.P: nat -> Prop
h0: P 0
h1: P 1
hSS: forall n : nat, P n -> P (S n) -> P (S (S n))
n: nat
h: P n /\ P (S n)P nn: natn <= fib nn: natn <= fib n0 <= fib 01 <= fib 1n: nat
hn: n <= fib n
hSn: S n <= fib (S n)S (S n) <= fib (S (S n))0 <= fib 0lia.0 <= 11 <= fib 1lia.1 <= 1n: nat
hn: n <= fib n
hSn: S n <= fib (S n)S (S n) <= fib (S (S n))n: nat
hn: n <= fib n
hSn: S n <= fib (S n)S (S n) <= fib (S n) + fib nhn: 0 <= fib 0
hSn: 1 <= fib 12 <= fib 1 + fib 0n: nat
hn: S n <= fib (S n)
hSn: S (S n) <= fib (S (S n))S (S (S n)) <= fib (S (S n)) + fib (S n)hn: 0 <= fib 0
hSn: 1 <= fib 12 <= fib 1 + fib 0lia.hn: 0 <= fib 0
hSn: 1 <= fib 12 <= 2lia. Qed.n: nat
hn: S n <= fib (S n)
hSn: S (S n) <= fib (S (S n))S (S (S n)) <= fib (S (S n)) + fib (S n)
rewrite
Usage: rewrite t, where t is a term (for instance lemma or assumption).
Assuming t is a (possibly universally quantified) equality lhs = rhs,
replaces occurrences of lhs in the goal by rhs.
forall (A : Type) (P : A -> Type) (a b : A), a = b -> P b -> P aforall (A : Type) (P : A -> Type) (a b : A), a = b -> P b -> P aA: Type
P: A -> Type
a, b: A
e: a = b
h: P bP aAbort.A: Type
P: A -> Type
a, b: A
e: a = b
h: P bP b
Variant: rewrite <- t.
Similar, but replaces rhs by lhs instead.
forall (A : Type) (P : A -> Type) (a b : A), a = b -> P a -> P bforall (A : Type) (P : A -> Type) (a b : A), a = b -> P a -> P bA: Type
P: A -> Type
a, b: A
e: a = b
h: P aP bAbort.A: Type
P: A -> Type
a, b: A
e: a = b
h: P aP a
Variant: rewrite t in h, where h is an assumption.
Similarly, but the replacement is done in h.
forall (A : Type) (P : A -> Type) (a b : A), a = b -> P a -> P bforall (A : Type) (P : A -> Type) (a b : A), a = b -> P a -> P bA: Type
P: A -> Type
a, b: A
e: a = b
h: P aP bAbort.A: Type
P: A -> Type
a, b: A
e: a = b
h: P bP b
Variant: rewrite rs, where rs is a list of rewrites such as t or
<- t.
Performs several rewrites in succession.
X: Type
P: X -> Type
a, b, c: X
e: a = b
e': c = bP aX: Type
P: X -> Type
a, b, c: X
e: a = b
e': c = bP aAbort.X: Type
P: X -> Type
a, b, c: X
e: a = b
e': c = bP c
Variant: rewrite !t.
Rewrites using t several times in a row until it no longer can.
X: Type
a, b, c, d, e, f: list Xa ++ b ++ c ++ d ++ e ++ f = ((((a ++ b) ++ c) ++ d) ++ e) ++ fX: Type
a, b, c, d, e, f: list Xa ++ b ++ c ++ d ++ e ++ f = ((((a ++ b) ++ c) ++ d) ++ e) ++ fX: Type
a, b, c, d, e, f: list X(a ++ b) ++ c ++ d ++ e ++ f = ((((a ++ b) ++ c) ++ d) ++ e) ++ fX: Type
a, b, c, d, e, f: list X(((a ++ b) ++ c) ++ d) ++ e ++ f = ((((a ++ b) ++ c) ++ d) ++ e) ++ freflexivity. Qed.X: Type
a, b, c, d, e, f: list X((((a ++ b) ++ c) ++ d) ++ e) ++ f = ((((a ++ b) ++ c) ++ d) ++ e) ++ f
specialize
Usage: specialize (h u v … w), where h is an assumption, and u, v, … w
are terms.
Replaces hypothesis h with its instantiation with the provided arguments.
X, Y, Z, A: Type
h: X -> Y -> Z -> AX -> (Y -> Z) -> Y -> AX, Y, Z, A: Type
h: X -> Y -> Z -> AX -> (Y -> Z) -> Y -> AX, Y, Z, A: Type
h: X -> Y -> Z -> A
x: X
z: Y -> Z
y: YAX, Y, Z, A: Type
h: Y -> Z -> A
x: X
z: Y -> Z
y: YAX, Y, Z, A: Type
h: Y -> Z -> A
x: X
z: Z
y: YAAbort.X, Y, Z, A: Type
h: A
x: X
z: Z
y: YA
Variant: specialize (h u v … w) as g, where g is a new name.
Produce a new hypothesis g corresponding to the instantiation of h with
the provided arguments. h is left unchanged.
X, Y, Z, A: Type
h: X -> Y -> Z -> AX -> (Y -> Z) -> Y -> AX, Y, Z, A: Type
h: X -> Y -> Z -> AX -> (Y -> Z) -> Y -> AX, Y, Z, A: Type
h: X -> Y -> Z -> A
x: X
z: Y -> Z
y: YAX, Y, Z, A: Type
h: X -> Y -> Z -> A
x: X
z: Y -> Z
y: Y
h': Y -> Z -> AAX, Y, Z, A: Type
h: X -> Y -> Z -> A
x: X
z: Y -> Z
y: Y
h': Y -> Z -> A
z': ZAAbort.X, Y, Z, A: Type
h: X -> Y -> Z -> A
x: X
z: Y -> Z
y: Y
h': A
z': ZA
Variant: specialize (h u v … w) as p, where p is an intropattern.
Behaves like specialize (h u v … w) followed by destruct h as p.
h: nat -> natnath: nat -> natnatAbort.natm: natnat
exists
Usage: exists t, where t is a term.
Applies to goals for the form exists x, P x and replaces it with goal P t.
exists n : nat, n = 0exists n : nat, n = 0Abort.0 = 0
Variant: exists u,v,w taking a list of terms.
Works like a succession of exists: exists u then exists v then
existts w.
exists a b c : nat, a + b = b + cexists a b c : nat, a + b = b + cAbort.1 + 2 = 2 + 3
symmetry
Usage: symmetry.
Applies to a goal of the form u = v and replaces it with goal v = u,
exploiting the fact that equality is symmetric.
forall (A : Type) (u v : A), u = vforall (A : Type) (u v : A), u = vA: Type
u, v: Au = vAbort.A: Type
u, v: Av = u
Variant: symmetry in h, where h is an hypothesis.
Applies symmetry to hypothesis h.
A: Type
u, v: A
e: u = vv = uA: Type
u, v: A
e: u = vv = uAbort.A: Type
u, v: A
e: v = uv = u
assert
Usage: assert (h : P) or equivalently assert (P) as h, where P is a
statement (or type) and h is name of your choice.
When the goal is G, yield two goals: a first one where you have to prove
P in the same context, and one where you prove G but with extra hypothesis
h : P.
P, Q: Prop(P -> ~ P) -> FalseP, Q: Prop(P -> ~ P) -> FalseP, Q: Prop
h: P -> ~ PFalseP, Q: Prop
h: P -> ~ P~ PP, Q: Prop
h: P -> ~ P
nP: ~ PFalseP, Q: Prop
h: P -> ~ P~ PP, Q: Prop
h: P -> ~ P
p: PFalseall: assumption.P, Q: Prop
h: P -> ~ P
p: PPP, Q: Prop
h: P -> ~ P
p: PPAbort.P, Q: Prop
h: P -> ~ P
nP: ~ PFalse
unfold
Usage: unfold d where d is the name of a definition.
Replaces occurrences of d in the goal with its definition.
It works both for global definitions (such as defined with Definition)
and for local definitions (stemming for a let).
Definition test x := x + x.let bar := test 0 + test 1 in bar + test 2 = test 3let bar := test 0 + test 1 in bar + test 2 = test 3bok:= test 0 + test 1: natbok + test 2 = test 3bok:= test 0 + test 1: natbok + (2 + 2) = 3 + 3Abort.bok:= test 0 + test 1: nattest 0 + test 1 + (2 + 2) = 3 + 3
Variant: unfold d in h where h is an hypothesis.
Unfold definition d inside h.
let bar := test 0 + test 1 in bar + test 2 = test 3let bar := test 0 + test 1 in bar + test 2 = test 3bok:= test 0 + test 1: natbok + test 2 = test 3Abort.bok:= 0 + 0 + (1 + 1): natbok + test 2 = test 3
contradiction
Usage: contradiction.
Concludes the goal by finding obviously contradicting hypotheses such as P
and ~ P.
forall P : Prop, P -> ~ P -> boolforall P : Prop, P -> ~ P -> boolcontradiction. Abort.P: Prop
h: P
hn: ~ Pbool
lia
Usage: lia.
Solves a goal that involves linear integer arithmetic (essentially addition and multiplication by a constant, equality and inequality). This is a decidable theory, so its output is predictable and reliable: the best kind of automation.
n, m, k: natn = 2 * k -> m = k + 1 -> m < 2 + nlia. Abort.n, m, k: natn = 2 * k -> m = k + 1 -> m < 2 + n
change
Usage: change t, where t is a term.
Replaces the whole goal with t, provided the goal and t are convertible:
that is, equal up to computation.
true <> falsetrue <> falseh: true = falseFalseAbort.h: true = falseif true then False else True
Variant change t in h, where h is an hypothesis.
Replaces the type of h with t if they are convertible.
forall (P : nat -> Type) (n : nat), P n -> P (0 + n)forall (P : nat -> Type) (n : nat), P n -> P (0 + n)P: nat -> Type
n: nat
h: P nP (0 + n)Abort.P: nat -> Type
n: nat
h: P (0 + n)P (0 + n)
Variant change t with u, where u is a term.
In the goal, replaces occurrences of t with u, assuming they are
convertible.
forall (P : nat -> nat -> nat -> Type) (a b c : nat), P (a + b) (S b) (c * a)forall (P : nat -> nat -> nat -> Type) (a b c : nat), P (a + b) (S b) (c * a)P: nat -> nat -> nat -> Type
a, b, c: natP (a + b) (S b) (c * a)P: nat -> nat -> nat -> Type
a, b, c: nat
f:= fun x : nat => 0 + x: nat -> natP (a + b) (S b) (c * a)Abort.P: nat -> nat -> nat -> Type
a, b, c: nat
f:= fun x : nat => 0 + x: nat -> natP (f a + b) (S b) (c * f a)
discriminate
Usage: discriminate.
Closes a goal that assumes an equality between different constructors of an inductive type.
true <> falsediscriminate. Abort.true <> false
Variant: discriminate h where h is an hypothesis.
Instructs discriminate that the inconsistent equality is h.
A: Type
e: true = falseAdiscriminate e. Abort.A: Type
e: true = falseA
inversion
congruence
constructor
Usage: constructor.
Applies the first constructor that applies to the current goal.
boolconstructor. Defined.bool
Variant: constructor n where n is a numeral (a concrete natural number).
Applies the n-th constructor corresponding to the goal.
boolconstructor 2. Defined.bool