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 ````
``` denotes the unique name of a hypothesis h.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.
-
Instances for tactic.interactive.case_tag
- tactic.interactive.case_tag.has_sizeof_inst
- tactic.interactive.case_tag.has_to_format
- tactic.interactive.case_tag.has_repr
- tactic.interactive.case_tag.has_to_string
- 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.
Instances for tactic.interactive.case_tag.match_result
- tactic.interactive.case_tag.match_result.has_sizeof_inst
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