Case tags
Case tags are an internal mechanism used by certain tactics to communicate with
each other. They are generated by the tactics cases, induction and
with_cases ('cases-like tactics'), which generate goals corresponding to the
'cases' of an inductive hypothesis. Each of these goals carries a case tag. They
are consumed by the case tactic, which focuses on one of these cases. Their
purpose is twofold:
- Give intuitive names to case goals. For example, when performing induction on
a natural number, two cases are generated: one tagged with 
nat.zeroand one tagged withnat.succ. Users can then focus on e.g. the second goal withcase succ {...}. - Communicate which new hypotheses were introduced by the cases-like tactic
that generated the goal. For example, when performing induction on a
list α, theconscase introduces two hypotheses corresponding to the two arguments of theconsconstructor.caseallows users to name these withcase cons : x xs {...}. To perform this renaming,caseneeds to know which hypotheses to rename; this information is contained in the case tag for theconsgoal. 
Module contents
This module defines
- what a case tag is (see 
case_tag); - how to render a 
case_tagas a list of names (seerender); - how to parse  a 
case_tagfrom a list of names (seeparse); - how to match a 
case_tagwith a sequence of names given by the user (seematch_tag). 
- pi : list name → ℕ → tactic.interactive.case_tag
 - hyps : list name → list name → tactic.interactive.case_tag
 
A case tag carries the following information:
A list of names identifying the case ('case names'). This is usually a list of constructor names, one for each case split that was performed. For example, the sequence of tactics
cases n; cases xs, wherenis a natural number andxsis a list, will generate four cases tagged as follows:Note: In the case tag, the case names are stored in reverse order. Thus, the case names of the first case tag would be
list.nil, nat.zero. This is because when printing a goal tag (as part of a goal state), Lean prints all non-internal names in reverse order.Information about the arguments introduced by the cases-like tactic. Different tactics work slightly different in this regard:
The
with_casestactic generates goals where the target quantifies over any added hypotheses. For example,with_cases { cases xs }, wherexsis alist α, will generate a target of the formα → list α → ...in theconscase, where the two arguments correspond to the two arguments of theconsconstructor. Goals of this form are tagged with apicase tag (since the target is a pi type). In addition to the case names, it contains a natural number,num_arguments, which specifies how many of the arguments that the target quantifies over were introduced bywith_cases.For example, given
n : ℕandxs : list α, the fourth goal generated bywith_cases { cases n; induction xs }has this form:... ⊢ ℕ → α → ∀ (xs' : list α), P xs' → ...The corresponding case tag is
since the first four arguments of the target were introduced by
with_cases {...}.The
casesandinductiontactics do not add arguments to the target, but rather introduce them as hypotheses in the local context. Goals of this form are tagged with ahypscase tag. In addition to the case names, it contains a list of unique names of the hypotheses that were introduced.For example, given
xs : list α, the second goal generated byinduction xshas this form:... x : α xs' : list α ih_xs' : P xs' ⊢ ...The corresponding goal tag is
hyps [`list.cons] [`<x>, `<xs'>, `<ih_xs'>]where `
<h>denotes the unique name of a hypothesish.Note: Many tactics do not preserve the unique names of hypotheses (particularly those tactics that use
revert). Therefore, ahypscase tag is only guaranteed to be valid directly after it was generated.
The constructor names associated with a case tag.
Renders a case tag to a goal tag (i.e. a list of names), according to the following schema:
- A 
pitag with namesN₀ ... Nₙand number of argumentsais rendered aslean [`_case.pi.a, N₀, ..., Nₙ] - A 
hypstag with namesN₀ ... Nₙand argument namesA₀ ... Aₘis rendered aslean [`_case.hyps, A₀._arg, ..., Aₘ._arg, N₀, ..., Nₙ] 
Creates a pi case tag from an input tag in_tag. The names of the resulting
tag are the non-internal names in in_tag (in the order in which they appear in
in_tag). num_arguments is the number of arguments of the resulting tag.
Creates a hyps case tag from an input tag in_tag. The names of the
resulting tag are the non-internal names in in_tag (in the order in which they
appear in in_tag). arguments is the list of unique hypothesis names of the
resulting tag.
Parses a case tag from the list of names produced by render.
- exact_match : tactic.interactive.case_tag.match_result
 - fuzzy_match : tactic.interactive.case_tag.match_result
 - no_match : tactic.interactive.case_tag.match_result
 
Indicates the result of matching a list of names against the names of a case
tag. See match_tag.
The 'minimum' of two match results:
- If any of the arguments is 
no_match, the result isno_match. - Otherwise, if any of the arguments is 
fuzzy_match, the result isfuzzy_match. - Otherwise (iff both arguments are 
exact_match), the result isexact_match. 
Equations
- tactic.interactive.case_tag.match_result.no_match.combine _x = tactic.interactive.case_tag.match_result.no_match
 - tactic.interactive.case_tag.match_result.fuzzy_match.combine tactic.interactive.case_tag.match_result.no_match = tactic.interactive.case_tag.match_result.no_match
 - tactic.interactive.case_tag.match_result.fuzzy_match.combine tactic.interactive.case_tag.match_result.fuzzy_match = tactic.interactive.case_tag.match_result.fuzzy_match
 - tactic.interactive.case_tag.match_result.fuzzy_match.combine tactic.interactive.case_tag.match_result.exact_match = tactic.interactive.case_tag.match_result.fuzzy_match
 - tactic.interactive.case_tag.match_result.exact_match.combine tactic.interactive.case_tag.match_result.no_match = tactic.interactive.case_tag.match_result.no_match
 - tactic.interactive.case_tag.match_result.exact_match.combine tactic.interactive.case_tag.match_result.fuzzy_match = tactic.interactive.case_tag.match_result.fuzzy_match
 - tactic.interactive.case_tag.match_result.exact_match.combine tactic.interactive.case_tag.match_result.exact_match = tactic.interactive.case_tag.match_result.exact_match
 
Match the names of a case tag against a user-supplied list of names ns. For
this purpose, we consider the names in reverse order, i.e. in the order in
which they are displayed to the user. The matching then uses the following
rules:
- If 
nsis exactly the same sequence of names asnames, this is an exact match. - If 
nsis a suffix ofnames, this is a fuzzy match. Additionally, each of the names innsmay be a suffix of the corresponding name innames. - Otherwise, we have no match.
 
Thus, the tag
is matched by any of these tags: