Skip to content

Commit 1138062

Browse files
fix: normalize imax 1 u to u (#7631)
This PR fixes `Lean.Level.mkIMaxAux` (`mk_imax` in the kernel) such that `imax 1 u` reduces to `u`. Closes #7096
1 parent ebf455a commit 1138062

File tree

5 files changed

+24
-14
lines changed

5 files changed

+24
-14
lines changed

src/Lean/Level.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,10 @@ private def isAlreadyNormalizedCheap : Level → Bool
295295

296296
/- Auxiliary function used at `normalize` -/
297297
private def mkIMaxAux : Level → Level → Level
298-
| _, zero => zero
299-
| zero, u => u
300-
| u₁, u₂ => if u₁ == u₂ then u₁ else mkLevelIMax u₁ u₂
298+
| _, zero => zero
299+
| zero, u => u
300+
| succ zero, u => u
301+
| u₁, u₂ => if u₁ == u₂ then u₁ else mkLevelIMax u₁ u₂
301302

302303
/- Auxiliary function used at `normalize` -/
303304
@[specialize] private partial def getMaxArgsAux (normalize : Level → Level) : Level → Bool → Array Level → Array Level

src/kernel/level.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,25 @@ level mk_max(level const & l1, level const & l2) {
9393
}
9494
}
9595

96+
static level * g_level_zero = nullptr;
97+
static level * g_level_one = nullptr;
98+
level const & mk_level_zero() { return *g_level_zero; }
99+
level const & mk_level_one() { return *g_level_one; }
100+
bool is_one(level const & l) { return l == mk_level_one(); }
101+
96102
level mk_imax(level const & l1, level const & l2) {
97103
if (is_not_zero(l2))
98104
return mk_max(l1, l2);
99105
else if (is_zero(l2))
100106
return l2; // imax u 0 = 0 for any u
101-
else if (is_zero(l1))
102-
return l2; // imax 0 u = u for any u
107+
else if (is_zero(l1) || is_one(l1))
108+
return l2; // imax 0 u = imax 1 u = u for any u
103109
else if (l1 == l2)
104110
return l1; // imax u u = u
105111
else
106112
return mk_imax_core(l1, l2);
107113
}
108114

109-
static level * g_level_zero = nullptr;
110-
static level * g_level_one = nullptr;
111-
level const & mk_level_zero() { return *g_level_zero; }
112-
level const & mk_level_one() { return *g_level_one; }
113-
bool is_one(level const & l) { return l == mk_level_one(); }
114-
115115
bool operator==(level const & l1, level const & l2) {
116116
if (kind(l1) != kind(l2)) return false;
117117
if (hash(l1) != hash(l2)) return false;

tests/lean/binrelTypeMismatch.lean.expected.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ has type
1010
Prop : Type
1111
but is expected to have type
1212
Bool : Type
13-
Prop → sorry : Sort (imax 1 u_1)
13+
Prop → sorry : Sort u_1
1414
binrelTypeMismatch.lean:20:27-20:28: error: type mismatch
1515
p
1616
has type
1717
Prop : Type
1818
but is expected to have type
1919
Bool : Type
20-
Prop → sorry : Sort (imax 1 u_1)
20+
Prop → sorry : Sort u_1

tests/lean/run/7096.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/-!
2+
# Normalization of imax 1 u
3+
4+
https://github.com/leanprover/lean4/issues/7096
5+
6+
Universe levels of the form `imax 1 u` should normalize to `u`.
7+
-/
8+
9+
example (α : Sort u) : Sort u := Unit → α

tests/lean/run/issue4726.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
-- A refexive type, with multiple parameters to make sure
33
-- we get the order right
44

5-
inductive N where
5+
inductive N : Type where
66
| cons : (Nat -> Bool → N) -> N
77

88

0 commit comments

Comments
 (0)