Coercions and lifts #
The elaborator tries to insert coercions automatically.
Only instances of has_coe
type class are considered in the process.
Lean also provides a "lifting" operator: ↑a
.
It uses all instances of has_lift
type class.
Every has_coe
instance is also a has_lift
instance.
We recommend users only use has_coe
for coercions that do not produce a lot
of ambiguity.
All coercions and lifts can be identified with the constant coe
.
We use the has_coe_to_fun
type class for encoding coercions from
a type to a function space.
We use the has_coe_to_sort
type class for encoding coercions from
a type to a sort.
- lift : a → b
Can perform a lifting operation ↑a
.
We specify the universes in has_coe
, has_coe_to_fun
, and has_coe_to_sort
explicitly in order to match exactly what appears in Lean4.
- coe : a → b
Instances
- coe_bool_to_Prop
- coe_subtype
- string_to_name
- nat_to_format
- string_to_format
- expr.has_coe
- tactic.opt_to_tac
- tactic.ex_to_tac
- lean.parser.has_coe
- smt_tactic.has_coe
- list.bin_tree_to_list
- int.has_coe
- native.float.of_nat_coe
- native.float.of_int_coe
- json.string_coe
- json.int_coe
- json.float_coe
- json.bool_coe
- json.array_coe
- widget.component.has_coe
- widget.html.list_coe
- units.has_coe
- add_units.has_coe
- monoid_hom.has_coe_to_one_hom
- add_monoid_hom.has_coe_to_zero_hom
- monoid_hom.has_coe_to_mul_hom
- add_monoid_hom.has_coe_to_add_hom
- monoid_with_zero_hom.has_coe_to_monoid_hom
- monoid_with_zero_hom.has_coe_to_zero_hom
- equiv.coe_embedding
- equiv.perm.coe_embedding
- ring_hom.has_coe_monoid_hom
- rel_embedding.rel_hom.has_coe
- rel_iso.rel_embedding.has_coe
- multiset.has_coe
- fin.fin_to_nat
- sym.has_coe
- coe_pnat_nat
- ring_equiv.has_coe_to_ring_hom
- distrib_mul_action_hom.has_coe
- distrib_mul_action_hom.has_coe'
- mul_semiring_action_hom.has_coe
- mul_semiring_action_hom.has_coe'
- tactic.ring.expr.has_coe
- linarith.preprocessor_to_gb_preprocessor
- linarith.global_preprocessor_to_gb_preprocessor
- distrib_mul_action_hom.linear_map.has_coe
- linear_equiv.linear_map.has_coe
- con.to_submonoid
- add_con.to_add_submonoid
- part.has_coe
- omega_complete_partial_order.order_hom.has_coe
- tactic.abel.expr.has_coe
- alg_hom.coe_ring_hom
- alg_hom.coe_monoid_hom
- alg_hom.coe_add_monoid_hom
- alg_equiv.has_coe_to_ring_equiv
- alg_equiv.has_coe_to_alg_hom
- linear_map.coe_is_scalar_tower
- nat.primes.coe_nat
- non_unital_alg_hom.distrib_mul_action_hom.has_coe
- non_unital_alg_hom.mul_hom.has_coe
- alg_hom.non_unital_alg_hom.has_coe
- initial_seg.rel_embedding.has_coe
- principal_seg.rel_embedding.has_coe
- principal_seg.has_coe_initial_seg
- tactic.norm_fin.eval_fin_m.has_coe
- alternating_map.multilinear_map.has_coe
- pfun.has_coe
- topological_space.opens.set.has_coe
- fractional_ideal.submodule.has_coe
- continuous_linear_map.linear_map.has_coe
- continuous_linear_equiv.continuous_linear_map.has_coe
- has_coe'
- mv_polynomial.coe_to_mv_power_series
- polynomial.coe_to_power_series
- laurent_series.has_coe
- ratfunc.coe_to_laurent_series
- free_ring.free_comm_ring.has_coe
- nnreal.real.has_coe
- ennreal.has_coe
- complex.has_coe
- gaussian_int.complex.has_coe
- efmt.has_coe
- efmt.coe_format
- json.has_coe
- coe : a → b
Auxiliary class that contains the transitive closure of has_coe
.
Instances
- con.quotient.has_coe_t
- add_con.quotient.has_coe_t
- coe_trans
- nat.cast_coe
- int.cast_coe
- rat.cast_coe
- pos_num_coe
- num_nat_coe
- znum_coe
- zmod.has_coe_t
- coe_base
- coe_option
- widget.html.to_string_coe
- one_hom.has_coe_t
- zero_hom.has_coe_t
- mul_hom.has_coe_t
- add_hom.has_coe_t
- monoid_hom.has_coe_t
- add_monoid_hom.has_coe_t
- monoid_with_zero_hom.has_coe_t
- equiv.has_coe_t
- mul_equiv.has_coe_t
- add_equiv.has_coe_t
- with_bot.has_coe_t
- with_top.has_coe_t
- ring_hom.has_coe_t
- with_one.has_coe_t
- with_zero.has_coe_t
- order_iso.has_coe_t
- order_hom_class.order_hom.has_coe_t
- finset.set.has_coe_t
- set_like.set.has_coe_t
- ring_equiv.has_coe_t
- quotient_group.has_quotient.quotient.has_coe_t
- quotient_add_group.has_quotient.quotient.has_coe_t
- valuation.has_coe_t
- top_hom.has_coe_t
- bot_hom.has_coe_t
- bounded_order_hom.has_coe_t
- sup_hom.has_coe_t
- inf_hom.has_coe_t
- sup_bot_hom.has_coe_t
- inf_top_hom.has_coe_t
- lattice_hom.has_coe_t
- bounded_lattice_hom.has_coe_t
- Sup_hom.has_coe_t
- Inf_hom.has_coe_t
- frame_hom.has_coe_t
- complete_lattice_hom.has_coe_t
- ultrafilter.filter.has_coe_t
- connected_components.has_coe_t
- continuous_map.has_coe_t
- fractional_ideal.coe_to_fractional_ideal
- open_subgroup.has_coe_set
- open_add_subgroup.has_coe_set
- open_subgroup.has_coe_subgroup
- open_add_subgroup.has_coe_add_subgroup
- open_subgroup.has_coe_opens
- open_add_subgroup.has_coe_opens
- uniform_space.completion.has_coe_t
- adjoin_root.adjoin_root.has_coe_t
- intermediate_field.adjoin.field_coe
- intermediate_field.adjoin.set_coe
- coe : Π (x : a), F x
Instances
- coe_fn_trans
- fun_like.has_coe_to_fun
- expr.has_coe_to_fun
- widget.component.has_coe_to_fun
- widget.tc.has_coe_to_fun
- applicative_transformation.has_coe_to_fun
- one_hom.has_coe_to_fun
- zero_hom.has_coe_to_fun
- mul_hom.has_coe_to_fun
- add_hom.has_coe_to_fun
- monoid_hom.has_coe_to_fun
- add_monoid_hom.has_coe_to_fun
- monoid_with_zero_hom.has_coe_to_fun
- monoid.End.has_coe_to_fun
- add_monoid.End.has_coe_to_fun
- equiv.has_coe_to_fun
- additive.has_coe_to_fun
- multiplicative.has_coe_to_fun
- mul_equiv.has_coe_to_fun
- add_equiv.has_coe_to_fun
- function.embedding.has_coe_to_fun
- ring_hom.has_coe_to_fun
- rel_hom.has_coe_to_fun
- rel_embedding.has_coe_to_fun
- rel_iso.has_coe_to_fun
- order_hom.has_coe_to_fun
- ring_equiv.has_coe_to_fun
- mul_action_hom.has_coe_to_fun
- distrib_mul_action_hom.has_coe_to_fun
- mul_semiring_action_hom.has_coe_to_fun
- finsupp.has_coe_to_fun
- tactic.ring.horner_expr.has_coe_to_fun
- linear_map.has_coe_to_fun
- linear_equiv.has_coe_to_fun
- con.has_coe_to_fun
- add_con.has_coe_to_fun
- dfinsupp.has_coe_to_fun
- linear_map.general_linear_group.has_coe_to_fun
- omega_complete_partial_order.chain.has_coe_to_fun
- omega_complete_partial_order.continuous_hom.has_coe_to_fun
- tactic.abel.normal_expr.has_coe_to_fun
- absolute_value.has_coe_to_fun
- alg_hom.has_coe_to_fun
- alg_equiv.has_coe_to_fun
- linear_pmap.has_coe_to_fun
- basis.has_coe_to_fun
- non_unital_alg_hom.has_coe_to_fun
- monoid_algebra.has_coe_to_fun
- add_monoid_algebra.has_coe_to_fun
- valuation.has_coe_to_fun
- add_valuation.has_coe_to_fun
- initial_seg.has_coe_to_fun
- principal_seg.has_coe_to_fun
- pequiv.has_coe_to_fun
- multilinear_map.has_coe_to_fun
- alternating_map.has_coe_to_fun
- top_hom.has_coe_to_fun
- bot_hom.has_coe_to_fun
- bounded_order_hom.has_coe_to_fun
- sup_hom.has_coe_to_fun
- inf_hom.has_coe_to_fun
- sup_bot_hom.has_coe_to_fun
- inf_top_hom.has_coe_to_fun
- lattice_hom.has_coe_to_fun
- bounded_lattice_hom.has_coe_to_fun
- Sup_hom.has_coe_to_fun
- Inf_hom.has_coe_to_fun
- frame_hom.has_coe_to_fun
- complete_lattice_hom.has_coe_to_fun
- compact_exhaustion.has_coe_to_fun
- homeomorph.has_coe_to_fun
- continuous_map.has_coe_to_fun
- continuous_linear_map.to_fun
- continuous_linear_equiv.has_coe_to_fun
- cau_seq.has_coe_to_fun
- hahn_series.summable_family.has_coe_to_fun
- module.dual.has_coe_to_fun
- bilin_form.has_coe_to_fun
- direct_sum.has_coe_to_fun
- coe : a → S
Instances
- set_like.has_coe_to_sort
- coe_sort_trans
- coe_sort_bool
- set.has_coe_to_sort
- finset.has_coe_to_sort
- category_theory.induced_category.has_coe_to_sort
- category_theory.bundled.has_coe_to_sort
- Mon.has_coe_to_sort
- AddMon.has_coe_to_sort
- CommMon.has_coe_to_sort
- AddCommMon.has_coe_to_sort
- Group.has_coe_to_sort
- AddGroup.has_coe_to_sort
- CommGroup.has_coe_to_sort
- AddCommGroup.has_coe_to_sort
- SemiRing.has_coe_to_sort
- Ring.has_coe_to_sort
- CommSemiRing.has_coe_to_sort
- CommRing.has_coe_to_sort
Equations
Equations
User level coercion operators #
Equations
Equations
Notation #
Transitive closure for has_lift
, has_coe
, has_coe_to_fun
#
We add this instance directly into has_coe_t
to avoid non-termination.
Suppose coe_option had type (has_coe a (option a))
.
Then, we can loop when searching a coercion from α
to β
(has_coe_t α β)
1- coe_trans at (has_coe_t α β)
(has_coe α ?b₁) and (has_coe_t ?b₁ c)
2- coe_option at (has_coe α ?b₁)
?b₁ := option α
3- coe_trans at (has_coe_t (option α) β)
(has_coe (option α) ?b₂) and (has_coe_t ?b₂ β)
4- coe_option at (has_coe (option α) ?b₂)
?b₂ := option (option α))
...
Equations
- coe_option = {coe := λ (x : a), some x}
- coe : a → b
Auxiliary transitive closure for has_coe
which does not contain
instances such as coe_option
.
They would produce non-termination when combined with coe_fn_trans
and coe_sort_trans
.
Instances
Equations
- coe_trans_aux = {coe := λ (x : a), has_coe_t_aux.coe (coe_b x)}
Equations
- coe_base_aux = {coe := coe_b _inst_1}
Equations
- coe_fn_trans = {coe := λ (x : a), ⇑(has_coe_t_aux.coe x)}
Equations
- coe_sort_trans = {coe := λ (x : a), ↥(has_coe_t_aux.coe x)}
Every coercion is also a lift
Equations
- coe_to_lift = {lift := coe_t _inst_1}
Basic coercions #
Tactics such as the simplifier only unfold reducible constants when checking whether two terms are definitionally
equal or a term is a proposition. The motivation is performance.
In particular, when simplifying p -> q
, the tactic simp
only visits p
if it can establish that it is a proposition.
Thus, we mark the following instance as @[reducible]
, otherwise simp
will not visit ↑p
when simplifying ↑p -> q
.
Equations
- coe_decidable_eq x = show decidable (x = tt), from bool.decidable_eq x tt
Equations
- coe_subtype = {coe := subtype.val (λ (x : a), p x)}
Basic lifts #
Remark: we can't use [has_lift_t a₂ a₁]
since it will produce non-termination whenever a type class resolution
problem does not have a solution.
Equations
- lift_fn_range = {lift := λ (f : a → b₁) (x : a), ↑(f x)}
A dependent version of lift_fn_range
.
Equations
- lift_pi_range = {lift := λ (f : Π (i : α), A i) (i : α), ↑(f i)}
Equations
- lift_fn_dom = {lift := λ (f : a₁ → b) (x : a₂), f ↑x}