|
| 1 | +import Lean |
| 2 | + |
1 | 3 | /-! |
2 | | -Test that `for` loops with `mut` variables of sort-polymorphic type (e.g. `PProd`) work correctly. |
3 | | -`PProd Nat True : Sort (max 1 0)` has a `Prop` component, so `getDecLevel` must see the fully |
4 | | -instantiated and normalized level `1` rather than `max ?u ?v` with unresolved metavariables. |
| 4 | +Test that `getLevel` instantiates and normalizes level metavariables. |
| 5 | +
|
| 6 | +Without this, `getDecLevel` fails on sort-polymorphic types with `Prop` components: |
| 7 | +`PProd.{?u, ?v} Nat True` has sort `max ?u ?v`. After `?u := 1`, `?v := 0`, this should |
| 8 | +normalize to `1` (decrementable to `0`), but without instantiation `decLevel` sees |
| 9 | +`max ?u ?v`, tries to decrement each arm independently inside the `max`, follows |
| 10 | +`?v → 0`, and fails because `dec 0 = none`. |
5 | 11 | -/ |
6 | 12 |
|
| 13 | +-- Direct reproducer: getDecLevel on PProd with assigned-but-uninstantiated level mvars |
| 14 | +open Lean Meta in |
| 15 | +#eval show MetaM _ from do |
| 16 | + let u ← mkFreshLevelMVar |
| 17 | + let v ← mkFreshLevelMVar |
| 18 | + let ty := mkApp2 (mkConst ``PProd [u, v]) (mkConst ``Nat) (mkConst ``True) |
| 19 | + assignLevelMVar u.mvarId! (.succ .zero) |
| 20 | + assignLevelMVar v.mvarId! .zero |
| 21 | + let lvl ← getDecLevel ty |
| 22 | + assert! lvl == .zero |
| 23 | + |
| 24 | +-- End-to-end: for loop with sort-polymorphic mut var |
7 | 25 | def foo : Unit := Id.run do |
8 | 26 | let mut x : PProd Nat True := ⟨0, trivial⟩ |
9 | 27 | for _ in [true] do |
|
0 commit comments