v3.4.0
Features
-
Implement RFC #1820
-
Add
string.iteratorabstraction for traversing strings.
The VM contains an efficient implementation of this type. -
Add support for non-ASCII char literals. Example:
'α'. -
Unicode escape characters in string and char literals. For example,
'\u03B1'is equivalent to'α'. -
Predictable runtime cost model for recursive functions. The equation compiler uses
different techniques for converting recursive equations into recursors and/or
well-founded fixed points. The new approach used in the code generator ignores
these encoding tricks when producing byte code. So, the runtime cost model
is identical to the one in regular strict functional languages. -
Add
d_array n α(array type where value type may depend on index),
where (α : fin n → Type u). -
Add instance for
decidable_eq (d_array n α)anddecidable_eq (array n α).
The new instance is more efficient than the one in mathlib because it doesn't
convert the array into a list. -
Add aliasing pattern syntax
id@pat, which introduces the nameidfor the value matched by
the patternpat. -
Add alternative syntax
{..., ..s}for the structure update{s with ...}.
Multiple fallback sources can be given:{..., ..s, ..t}will fall back to
searching a field ins, then int. The last component can also be..,
which will replace any missing fields with a placeholder.
The old notation will be removed in the future. -
Add support for structure instance notation
{...}in patterns. Use..to ignore
unmatched fields. -
Type class
has_equivfor≈notation. -
Add
funext ids*tactic for applying the funext lemma. -
Add
iterate n { t }for applying tactictntimes.
Remark:iterate { t }appliestuntil it fails. -
Add
with_cases { t }. This tactic appliestto the main goal,
and reverts any new hypothesis in the resulting subgoals.with_casesalso enable "goal tagging".
Remark:inductionandcasestag goals using constructor names.applyandconstructortag goals
using parameter names. Thecasetactic can select goals using tags. -
Add
cases_matching ptactic for applying thecasestactic to a hypothesish : ts.t.
tmatches the patternp. Alternative versions:cases_matching* pandcases_matching [p_1, ..., p_n].
Example:cases_matching* [_ ∨ _, _ ∧ _]destructs all conjunctions and disjunctions in the main goal. -
Add
cases_type Itactic for applying thecasestactic to a hypothesish : I ....
cases_type! Ionly succeeds when the number of resulting goals is <= 1.
Alternative versions:cases_type I_1 ... I_n,cases_type* I,cases_type!* I.
Example:cases_type* and ordestructs all conjunctions and disjunctions in the main goal. -
Add
constructor_matching ptactic. It is syntax sugar formatch_target p; constructor.
The variantconstructor_matching* pis more efficient thanfocus1 { repeat { match_target p; constructor } }
because the patterns are compiled only once. -
injection hnow supports nested and mutually recursive datatypes. -
Display number of goals in the
*Lean Goal*buffer (if number of goals > 1). -
hide id*command for hiding aliases.
The following command hides the aliasis_truefordecidable.is_true.hide is_true -
Add
abbreviationdeclaration command.abbreviation d : t := vis equivalent to
@[reducible, inline] def d : t := vand a kernel reducibility hint.
Before this command, we had to use meta programming for setting the kernel reducibility hint.
This was problematic because we could only define abbreviations after the meta programming
framework was defined. -
Add "smart unfolding". The idea is to prevent internal compilation details
used by the equation compiler to "leak" during unification, tactic execution and
reduction. With "smart unfolding", the termnat.add a (nat.succ b)reduces
tonat.succ (nat.add a b)instead ofnat.succ (... incomprehensible mess ...).
This feature addresses a problem reported by many users.
See issue #1794.
The commandset_option type_context.smart_unfolding falsedisables this feature. -
Add support for "auto params" at
simptactic. Example: given@[simp] lemma fprop1 (x : nat) (h : x > 0 . tactic.assumption) : f x = x := ...The simplifier will try to use tactic
assumptionto synthesize parameterh. -
Add interactive
sorrytactic (alias foradmit). -
simpnow reduces equalitiesc_1 ... = c_2 ...tofalseifc_1andc_2are distinct
constructors. This feature can be disabled usingsimp {constructor_eq := ff}. -
simpnow reduces equalitiesc a_1 ... a_n = c b_1 ... b_ntoa_1 = b_1 /\ ... /\ a_n = b_nifcis a constructor.
This feature can be disabled usingsimp {constructor_eq := ff}. -
substandsubst_varsnow support heterogeneous equalities that are actually homogeneous
(i.e.,@heq α a β bwhereαandβare definitionally equal). -
Add interactive
subst_varstactic. -
Add
leanpkg add foo/baras a shorthand forleanpkg add https://github.com/foo/bar. -
Add
leanpkg help <command>. -
Add
[norm]simp set. It contains all lemmas tagged with[simp]plus any
lemma tagged with[norm].
These rules are used to produce normal forms and/or reduce the
number of constants used in a goal. For example, we plan to
add the lemmaf <$> x = x >>= pure ∘ fto[norm]. -
Add
iota_eqn : boolfield tosimp_config.simp {iota_eqn := tt}uses
all non trivial equation lemmas generated by equation/pattern-matching compiler.
A lemma is considered non trivial if it is not of the formforall x_1 ... x_n, f x_1 ... x_n = tand
a proof by reflexivity.simp!is a shorthand forsimp {iota_eqn := tt}.
For example, given the goal... |- [1,2].map nat.succ = t,simp!reduces the left-hand-side
of the equation to[nat.succ 1, nat.succ 2]. In this example,simp!is equivalent to
simp [list.map]. -
Allow the Script, Double-struck, and Fractur symbols from
Mathematical Alphanumeric Symbols: https://unicode.org/charts/PDF/U1D400.pdf
to be used as variables Example:variables 𝓞 : Prop. -
Structure instance notation now allows explicitly setting implicit structure fields
-
Structure instance notation now falls back to type inference for inferring the
value of a superclass. This change eliminates the need for most..source specifiers
in instance declarations. -
The
--profileflag will now print cumulative profiling times at the end of execution -
do notation now uses the top-level, overloadable
bindfunction instead ofhas_bind.bind,
allowing binds with different type signatures -
Structures fields can now be defined with an implicitness infer annotation and parameters.
class has_pure (f : Type u → Type v) := -- make f implicit (pure {} {α : Type u} : α → f α) -
Add
except_tandreader_tmonad transformers -
Add
monad_{except,reader,state}classes for accessing effects anywhere in a monad stack
without the need for explicit lifting. Add analogousmonad_{except,reader,state}_adapter
classes for translating a monad stack into another one with the same shape but different
parameter types.
Changes
-
Command
variable [io.interface]is not needed anymore to use theiomonad.
It is also easier to add new io primitives. -
Replace
inoutmodifier in type class declarations without_parammodifier.
Reason: counterintuitive behavior in the type class resolution procedure.
The result could depend on partial information available in theinout
parameter. Now a parameter(R : inout α → β → Prop)should be written
as(R : out_param (α → β → Prop))or(R : out_param $ α → β → Prop).
Remark: users may define their own notation for declaringout_params.
Example:notation `out`:1024 a:0 := out_param aWe did not include this notation in core lib because
outis frequently used to
name parameters, local variables, etc. -
casetactic now supports thewith_cases { t }tactic. See entry above aboutwith_cases.
The tag and new hypotheses are now separated with:. Example:case pos { t }: execute tactictto goal taggedposcase pos neg { t }: execute tactictto goal taggedpos negcase : x y { t }: execute tactictto main goal after renaming the first two hypotheses produced by precedingwith_case { t' }.case pos neg : x y { t }: execute tactictto goal taggedpos negafter renaming the first two hypotheses produced by precedingwith_case { t' }.
-
cases hnow also tries to clearhwhen performing dependent elimination. -
repeat { t }behavior changed. Now, it appliestto each goal. If the application succeeds,
the tactic is applied recursively to all the generated subgoals until it eventually fails.
The recursion stops in a subgoal when the tactic has failed to make progress.
The previousrepeattactic was renamed toiterate. -
The automatically generated recursor
C.recfor an inductive datatype
now usesihto name induction hypotheses instead ofih_1if there is only one.
If there is more than one induction hypotheses, the name is generated by concatenatingih_
before the constructor field name. For example, for the constructor| node (left right : tree) (val : A) : treeThe induction hypotheses are now named:
ih_leftandih_right.
This change only affects tactical proofs where explicit names are not provided
toinductionandcasestactics. -
induction handcases htactic use a new approach for naming new hypotheses.
If names are not provided by the user, these tactics will create a "base" name
by concatenating the input hypothesis name with the constructor field name.
If there is only one field, the tactic simply reuses the hypothesis name.
The final name is generated by making sure the "base" name is unique.
Remarks:- If
his not a hypothesis, then no concatenation is performed. - The old behavior can be obtained by using the following command
set_option tactic.induction.concat_names falseThis change was suggested by Tahina Ramananandro. The idea is to have more
robust tactic scripts when helper tactics that destruct many hypotheses automatically
are used.
Remark: The newguard_names { t }tactical can be used to generate
robust tactic scripts that are not sensitive to naming generation strategies used byt. - If
-
Remove
[simp]attribute from lemmasor.assoc,or.comm,or.left_comm,and.assoc,and.comm,and.left_comm,add_assoc,add_comm,add_left_com,mul_assoc,mul_commandmul_left_comm.
These lemmas were being used to "sort" arguments of AC operators: and, or, (+) and (*).
This was producing unstable proofs. The old behavior can be retrieved by using the commandslocal attribute [simp] ...orattribute [simp] ...in the affected files. -
stringis now a list of unicode scalar values. Moreover, in the VM,
strings are implemented as an UTF-8 encoded array of bytes. -
array α nis now writtenarray n α. Motivation: consistencyd_array n α. -
Move
rb_mapandrb_treeto thenativenamespace. We will later add
pure Lean implementations. Useopen nativeto port files. -
apply tbehavior changed when type oftis of the formforall (a_1 : A_1) ... (a_n : A_n), ?m ..., where?mis an unassigned metavariable.
In this case,apply tbehaves asapply t _ ... _wheren_have been added, independently of the goal target type.
The new behavior is useful when usingapplywith eliminator-like definitions. -
ginduction t with h h1 h2is nowinduction h : t with h1 h2. -
apply_corenow also returns the parameter name associated with new metavariables. -
applynow also returns the new metavariables (and the parameter name associated with them). Even the assigned metavariables are returned. -
by_cases p with h==>by_cases h : p -
leanpkg now always stores .lean package files in a separate
srcdirectory. -
Structure constructor parameters representing superclasses are now marked as instance implicit.
Note: Instances using the {...} structure notation should not be affected by this change. -
The monad laws have been separated into new type classes
is_lawful_{functor,applicative,monad}. -
unitis now an abbreviation ofpunit.{0}
API name changes
monad.has_monad_lift(_t)~>has_monad_lift(_t)monad.map_comp~>comp_mapstate(_t).{read,write}~>{get,put}(general operations defined on anymonad_state)- deleted
monad.monad_transformer - deleted
monad.lift{n}. Usef <$> a1 <*> ... <*> aninstead ofmonad.lift{n} f a1 ... an. - merged
has_mapintofunctor unit_eq(_unit)~>punit_eq(_punit)