Recursive cases (rcases
) tactic and related tactics #
rcases
is a tactic that will perform cases
recursively, according to a pattern. It is used to
destructure hypotheses or expressions composed of inductive types like h1 : a ∧ b ∧ c ∨ d
or
h2 : ∃ x y, trans_rel R x y
. Usual usage might be rcases h1 with ⟨ha, hb, hc⟩ | hd
or
rcases h2 with ⟨x, y, _ | ⟨z, hxz, hzy⟩⟩
for these examples.
Each element of an rcases
pattern is matched against a particular local hypothesis (most of which
are generated during the execution of rcases
and represent individual elements destructured from
the input expression). An rcases
pattern has the following grammar:
- A name like
x
, which names the active hypothesis asx
. - A blank
_
, which does nothing (letting the automatic naming system used bycases
name the hypothesis). - A hyphen
-
, which clears the active hypothesis and any dependents. - The keyword
rfl
, which expects the hypothesis to beh : a = b
, and callssubst
on the hypothesis (which has the effect of replacingb
witha
everywhere or vice versa). - A type ascription
p : ty
, which sets the type of the hypothesis toty
and then matches it againstp
. (Of course,ty
must unify with the actual type ofh
for this to work.) - A tuple pattern
⟨p1, p2, p3⟩
, which matches a constructor with many arguments, or a series of nested conjunctions or existentials. For example if the active hypothesis isa ∧ b ∧ c
, then the conjunction will be destructured, andp1
will be matched againsta
,p2
againstb
and so on. - An alteration pattern
p1 | p2 | p3
, which matches an inductive type with multiple constructors, or a nested disjunction likea ∨ b ∨ c
.
The patterns are fairly liberal about the exact shape of the constructors, and will insert additional alternation branches and tuple arguments if there are not enough arguments provided, and reuse the tail for further matches if there are too many arguments provided to alternation and tuple patterns.
This file also contains the obtain
and rintro
tactics, which use the same syntax of rcases
patterns but with a slightly different use case:
rintro
(orrintros
) is used likerintro x ⟨y, z⟩
and is the same asintros
followed byrcases
on the newly introduced arguments.obtain
is the same asrcases
but with a syntax styled afterhave
rather thancases
.obtain ⟨hx, hy⟩ | hz := foo
is equivalent torcases foo with ⟨hx, hy⟩ | hz
. Unlikercases
,obtain
also allows one to omit:= foo
, although a type must be provided in this case, as inobtain ⟨hx, hy⟩ | hz : a ∧ b ∨ c
, in which case it produces a subgoal for provinga ∧ b ∨ c
in addition to the subgoalshx : a, hy : b |- goal
andhz : c |- goal
.
Tags #
rcases, rintro, obtain, destructuring, cases, pattern matching, match
These synonyms for list
are used to clarify the meanings of the many
usages of lists in this module.
-
listΣ
is used where a list represents a disjunction, such as the list of possible constructors of an inductive type. -
listΠ
is used where a list represents a conjunction, such as the list of arguments of an individual constructor.
These are merely type synonyms, and so are not checked for consistency by the compiler.
The def
/local notation
combination makes Lean retain these
annotations in reported types.
A list, with a disjunctive meaning (like a list of inductive constructors, or subgoals)
Equations
A list, with a conjunctive meaning (like a list of constructor arguments, or hypotheses)
Equations
Like zip_with
, but if the lists don't match in length, the excess elements will be put at the
end of the result.
Equations
- tactic.merge_list m (a :: l₁) (b :: l₂) = m a b :: tactic.merge_list m l₁ l₂
- tactic.merge_list m (hd :: tl) list.nil = hd :: tl
- tactic.merge_list m list.nil (hd :: tl) = hd :: tl
- tactic.merge_list m list.nil list.nil = list.nil