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
- ring_hom.has_coe_add_monoid_hom
- rel_embedding.rel_hom.has_coe
- rel_iso.rel_embedding.has_coe
- multiset.has_coe
- fin.fin_to_nat
- coe_pnat_nat
- tactic.ring.expr.has_coe
- linarith.preprocessor_to_gb_preprocessor
- linarith.global_preprocessor_to_gb_preprocessor
- ring_equiv.has_coe_to_mul_equiv
- ring_equiv.has_coe_to_add_equiv
- ring_equiv.has_coe_to_ring_hom
- tactic.abel.expr.has_coe
- con.to_submonoid
- add_con.to_add_submonoid
- distrib_mul_action_hom.has_coe
- distrib_mul_action_hom.has_coe'
- mul_semiring_action_hom.has_coe
- mul_semiring_action_hom.has_coe'
- distrib_mul_action_hom.linear_map.has_coe
- linear_equiv.linear_map.has_coe
- part.has_coe
- omega_complete_partial_order.order_hom.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
- nnreal.real.has_coe
- ennreal.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
- coe_base
- coe_option
- widget.html.to_string_coe
- with_bot.has_coe_t
- with_top.has_coe_t
- monoid_hom.has_coe_t
- add_monoid_hom.has_coe_t
- with_one.has_coe_t
- with_zero.has_coe_t
- finset.set.has_coe_t
- set_like.set.has_coe_t
- quiver.weakly_connected_component.has_coe_t
- quotient_group.has_quotient.quotient.has_coe_t
- quotient_add_group.has_quotient.quotient.has_coe_t
- 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
- equiv.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
- function.embedding.has_coe_to_fun
- ring_hom.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
- rel_hom.has_coe_to_fun
- rel_embedding.has_coe_to_fun
- rel_iso.has_coe_to_fun
- order_hom.has_coe_to_fun
- tactic.ring.horner_expr.has_coe_to_fun
- ring_equiv.has_coe_to_fun
- tactic.abel.normal_expr.has_coe_to_fun
- absolute_value.has_coe_to_fun
- cau_seq.has_coe_to_fun
- con.has_coe_to_fun
- add_con.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
- linear_map.has_coe_to_fun
- linear_equiv.has_coe_to_fun
- dfinsupp.has_coe_to_fun
- finsupp.has_coe_to_fun
- omega_complete_partial_order.chain.has_coe_to_fun
- omega_complete_partial_order.continuous_hom.has_coe_to_fun
- linear_map.general_linear_group.has_coe_to_fun
- alg_hom.has_coe_to_fun
- alg_equiv.has_coe_to_fun
- coe : a → S
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}