()
| 474 | /// The innermost domain `bvar0` refers to a variable of type Prop, not a Sort. |
| 475 | #[test] |
| 476 | fn bad_forall_sort_bad() { |
| 477 | let mut env = KEnv::<Meta>::new(); |
| 478 | // id : {α : Sort u} → α → α, simplified as Type → Type → Type... no. |
| 479 | // id.{2} : Sort 2 → Sort 2 := fun x => x |
| 480 | // id.{2} (Sort 1) (Sort 0) = Sort 0 = Prop |
| 481 | // Let's use: id_univ2 : Sort 2 → Sort 2 := fun x => x |
| 482 | let (id2_id, id2_c) = mk_defn( |
| 483 | "id2", |
| 484 | 0, |
| 485 | vec![], |
| 486 | pi(sort(usucc(usucc(uzero()))), sort(usucc(usucc(uzero())))), // Sort 2 → Sort 2 |
| 487 | nlam("x", sort(usucc(usucc(uzero()))), var(0)), |
| 488 | ReducibilityHints::Abbrev, |
| 489 | ); |
| 490 | env.insert(id2_id, id2_c); |
| 491 | |
| 492 | // forallSortBad : Prop := ∀ (_ : id2 (Sort 1) applied to Sort 0... ) |
| 493 | // Actually simpler: the domain is (id2 Prop) which reduces to Prop. |
| 494 | // Then the next domain is bvar(0) which is a Prop value, NOT a Sort. |
| 495 | // |
| 496 | // value = ∀ (_ : id2 Prop), ∀ (_ : bvar0), bvar1 |
| 497 | // After WHNF of `id2 Prop` → Prop. Then domain 2 is bvar0 : Prop (not a Sort). |
| 498 | // Wait, id2 : Sort 2 → Sort 2. Prop = Sort 0 : Sort 1, not Sort 2. |
| 499 | // So id2 Prop would fail (Prop : Sort 1, not Sort 2). |
| 500 | // |
| 501 | // Let's use a simpler approach: id at level 1. |
| 502 | // id1 : Sort 1 → Sort 1 := fun x => x |
| 503 | // id1 Prop = Prop (since Prop : Sort 1) |
| 504 | let (id1_id, id1_c) = mk_defn( |
| 505 | "id1", |
| 506 | 0, |
| 507 | vec![], |
| 508 | pi(sort(usucc(uzero())), sort(usucc(uzero()))), // Sort 1 → Sort 1 |
| 509 | nlam("x", sort(usucc(uzero())), var(0)), |
| 510 | ReducibilityHints::Abbrev, |
| 511 | ); |
| 512 | env.insert(id1_id, id1_c); |
| 513 | |
| 514 | // value = ∀ (_ : id1 Prop), ∀ (_ : bvar0), bvar1 |
| 515 | // id1 Prop reduces to Prop (a Sort). First forall OK. |
| 516 | // Second forall: domain = bvar0 (the variable of type Prop). Not a Sort! |
| 517 | let id1_prop = app(cnst("id1", &[]), sort0()); |
| 518 | // ∀ (_ : id1 Prop), ∀ (_ : bvar0), ∀ (_ : bvar0), bvar1 |
| 519 | // depth 1: _1 : Prop (from id1 Prop) |
| 520 | // depth 2: _2 : _1 (var(0) at depth 1 = _1, a Prop variable). _2 has type _1 : Prop. |
| 521 | // depth 3: domain = bvar0 = _2 (var(0) at depth 2). _2 has type _1 (Prop value). |
| 522 | // infer(_2) = _1. ensure_sort(_1) must fail: _1 is a Prop variable, not a Sort. |
| 523 | let value = npi( |
| 524 | "_", |
| 525 | id1_prop, // ∀ _1 : id1 Prop, ... |
| 526 | npi( |
| 527 | "_", |
| 528 | var(0), // ∀ _2 : _1, ... (_1 : Prop, so _2 has a Prop-typed type) |
| 529 | npi( |
| 530 | "_", |
| 531 | var(0), // ∀ _3 : _2, ... — _2's type is _1 (a Prop var, NOT Sort) |
| 532 | var(1), |
| 533 | ), |
nothing calls this directly
no test coverage detected