This is a hard coded extra case. It is not an instance of has_coe. Even if we change has_coe to accomodate this case, it will not be a satisfactory solution because this coercion depends on the element and not the type, and the element usually contains metavariables. We should eventually write a tactic for synthesizing coercions.
62 lines
2.2 KiB
Text
62 lines
2.2 KiB
Text
/-
|
||
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import init.meta.name init.meta.format
|
||
|
||
/- Reflect a C++ level object. The VM replaces it with the C++ implementation. -/
|
||
inductive level
|
||
| zero : level
|
||
| succ : level → level
|
||
| max : level → level → level
|
||
| imax : level → level → level
|
||
| param : name → level
|
||
| mvar : name → level
|
||
|
||
instance : inhabited level :=
|
||
⟨level.zero⟩
|
||
|
||
/- TODO(Leo): provide a definition in Lean. -/
|
||
meta constant level.has_decidable_eq : decidable_eq level
|
||
attribute [instance] level.has_decidable_eq
|
||
meta constant level.lt : level → level → bool
|
||
meta constant level.lex_lt : level → level → bool
|
||
meta constant level.fold {α :Type} : level → α → (level → α → α) → α
|
||
/- Return the given level expression normal form -/
|
||
meta constant level.normalize : level → level
|
||
/- Return tt iff lhs and rhs denote the same level.
|
||
The check is done by normalization. -/
|
||
meta constant level.eqv : level → level → bool
|
||
/- Return tt iff the first level occurs in the second -/
|
||
meta constant level.occurs : level → level → bool
|
||
/- Replace a parameter named n with l in the first level if the list contains the pair (n, l) -/
|
||
meta constant level.instantiate : level → list (name × level) → list level
|
||
meta constant level.to_format : level → options → format
|
||
meta constant level.to_string : level → string
|
||
|
||
meta def level.cmp (a b : level) : ordering :=
|
||
if level.lt a b then ordering.lt
|
||
else if a = b then ordering.eq
|
||
else ordering.gt
|
||
|
||
meta instance : has_to_string level :=
|
||
⟨level.to_string⟩
|
||
|
||
meta instance : has_to_format level :=
|
||
⟨λ l, level.to_format l options.mk⟩
|
||
|
||
meta instance : has_ordering level :=
|
||
⟨level.cmp⟩
|
||
|
||
meta def level.of_nat : nat → level
|
||
| 0 := level.zero
|
||
| (nat.succ n) := level.succ (level.of_nat n)
|
||
|
||
meta def level.has_param : level → name → bool
|
||
| (level.succ l) n := level.has_param l n
|
||
| (level.max l₁ l₂) n := level.has_param l₁ n || level.has_param l₂ n
|
||
| (level.imax l₁ l₂) n := level.has_param l₁ n || level.has_param l₂ n
|
||
| (level.param n₁) n := n₁ = n
|
||
| l n := ff
|