This PR adds a case to `Level.geq` that is present in the kernel's level `is_geq` procedure, making them consistent with one another. This came up during testing of `lean4lean`. Currently `Level.geq` differs from `level::is_geq` in the case of `max u v >= imax u v`. The elaborator function is overly pessimistic and yields `false` on this while the kernel function yields true. This comes up concretely in the `Trans` class: ```lean class Trans (r : α → β → Sort u) (s : β → γ → Sort v) (t : outParam (α → γ → Sort w)) where trans : r a b → s b c → t a c ``` The type of this class is `Sort (max (max (max (max (max (max 1 u) u_1) u_2) u_3) v) w)` (where `u_1 u_2 u_3` are the levels of `α β γ`), but if you try writing that type explicitly then the `class` command fails. Omitting the type leaves the `class` to infer the universe level (the command assumes the level is correct, and the kernel agrees it is), but including the type then the elaborator checks the level inequality with `Level.geq` and fails. --------- Co-authored-by: Kyle Miller <kmill31415@gmail.com>
9 lines
359 B
Text
9 lines
359 B
Text
import Lean.Level
|
|
|
|
open Lean
|
|
|
|
#guard levelZero == levelZero
|
|
#guard levelZero != mkLevelSucc levelZero
|
|
#guard mkLevelMax (mkLevelSucc levelZero) levelZero != mkLevelSucc levelZero
|
|
#guard mkLevelMax (mkLevelSucc levelZero) levelZero == mkLevelMax (mkLevelSucc levelZero) levelZero
|
|
#guard Level.geq (.max (.param `u) (.param `v)) (.imax (.param `u) (.param `v))
|