| import Lean | |
| open Lean | |
| structure S1 where | |
| (x y : Nat) | |
| structure S2 extends S1 where | |
| (z : Nat) | |
| structure S3 where | |
| (w : Nat) | |
| structure S4 extends S2, S3 where | |
| (s : Nat) | |
| def check (b : Bool) : CoreM Unit := | |
| unless b do throwError "check failed" | |
| class S5 where | |
| (x y : Nat) | |
| inductive D | |
| | mk (x y z : Nat) : D | |
| /-- | |
| info: #[constants, quotInit, diagnostics, const2ModIdx, extensions, irBaseExts, header] | |
| #[toS2, toS1, x, y, z, toS3, w, s] | |
| (some [S4.toS2, S2.toS1]) | |
| #[S2, S3] | |
| #[S2, S3, S1] | |
| -/ | |
| #guard_msgs in | |
| #eval show CoreM Unit from do | |
| let env ← getEnv | |
| IO.println (getStructureFields env ``Kernel.Environment) | |
| check $ getStructureFields env `S4 == #[`toS2, `toS3, `s] | |
| check $ getStructureFields env `S1 == #[`x, `y] | |
| check $ isSubobjectField? env `S4 `toS2 == some `S2 | |
| check $ getStructureSubobjects env `S4 == #[`S2, `S3] | |
| check $ findField? env `S4 `x == some `S1 | |
| check $ findField? env `S4 `x1 == none | |
| check $ isStructure env `S1 | |
| check $ isStructure env `S2 | |
| check $ isStructure env `S3 | |
| check $ isStructure env `S4 | |
| check $ isStructure env `S5 | |
| check $ !isStructure env `Nat | |
| check $ !isStructure env `D | |
| check $ getPathToBaseStructure? env `S1 `S4 == some [`S4.toS2, `S2.toS1] | |
| IO.println (getStructureFieldsFlattened env `S4) | |
| IO.println (getPathToBaseStructure? env `S1 `S4) | |
| IO.println (getStructureSubobjects env `S4) | |
| IO.println (← getAllParentStructures `S4) | |
| pure () | |
| def dumpStructInfo (structName : Name) : CoreM Unit := do | |
| let env ← getEnv | |
| let some info := getStructureInfo? env structName | |
| | throwError "no such structure {structName}" | |
| IO.println s!"\ | |
| struct: {info.structName}\n\ | |
| fields: {info.fieldNames}\n\ | |
| field infos: {info.fieldInfo.map fun info => s!"({info.fieldName}, {info.subobject?}, {info.projFn})"}\n\ | |
| parent infos: {info.parentInfo.map fun info => (info.structName, info.subobject, info.projFn)}" | |
| /-- | |
| info: struct: S1 | |
| fields: #[x, y] | |
| field infos: #[(y, none, S1.y), (x, none, S1.x)] | |
| parent infos: #[] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `S1 | |
| /-- | |
| info: struct: S2 | |
| fields: #[toS1, z] | |
| field infos: #[(z, none, S2.z), (toS1, (some S1), S2.toS1)] | |
| parent infos: #[(S1, (true, S2.toS1))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `S2 | |
| /-- | |
| info: struct: S3 | |
| fields: #[w] | |
| field infos: #[(w, none, S3.w)] | |
| parent infos: #[] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `S3 | |
| /-- | |
| info: struct: S4 | |
| fields: #[toS2, toS3, s] | |
| field infos: #[(s, none, S4.s), (toS2, (some S2), S4.toS2), (toS3, (some S3), S4.toS3)] | |
| parent infos: #[(S2, (true, S4.toS2)), (S3, (true, S4.toS3))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `S4 | |
| /-! | |
| Basic diamond | |
| -/ | |
| structure A1 where | |
| x : Nat | |
| structure A2 extends A1 where | |
| y : Nat | |
| structure A3 extends A1 where | |
| z : Nat | |
| structure A4 extends A2, A3 where | |
| w : Nat | |
| /-- | |
| info: struct: A1 | |
| fields: #[x] | |
| field infos: #[(x, none, A1.x)] | |
| parent infos: #[] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `A1 | |
| /-- | |
| info: struct: A2 | |
| fields: #[toA1, y] | |
| field infos: #[(y, none, A2.y), (toA1, (some A1), A2.toA1)] | |
| parent infos: #[(A1, (true, A2.toA1))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `A2 | |
| /-- | |
| info: struct: A3 | |
| fields: #[toA1, z] | |
| field infos: #[(z, none, A3.z), (toA1, (some A1), A3.toA1)] | |
| parent infos: #[(A1, (true, A3.toA1))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `A3 | |
| /-- | |
| info: struct: A4 | |
| fields: #[toA2, z, w] | |
| field infos: #[(z, none, A4.z), (w, none, A4.w), (toA2, (some A2), A4.toA2)] | |
| parent infos: #[(A2, (true, A4.toA2)), (A3, (false, A4.toA3))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `A4 | |
| /-! | |
| Abbreviation in parent | |
| -/ | |
| abbrev AA1 := A1 | |
| structure A5 extends AA1 where | |
| a : Nat | |
| /-- | |
| info: struct: A5 | |
| fields: #[toA1, a] | |
| field infos: #[(a, none, A5.a), (toA1, (some A1), A5.toA1)] | |
| parent infos: #[(A1, (true, A5.toA1))] | |
| -/ | |
| #guard_msgs in #eval dumpStructInfo `A5 | |
| /-! | |
| Regression test: make sure mathlib `Type*` still elaborates with levels in correct order. | |
| During development, this came out as `AddEquiv.{u_10, u_9}`. | |
| -/ | |
| section | |
| elab "Type*" : term => do | |
| let u ← Lean.Meta.mkFreshLevelMVar | |
| Lean.Elab.Term.levelMVarToParam (.sort (.succ u)) | |
| variable {F α β M N P G H : Type*} | |
| structure AddEquiv (A B : Type*) : Type | |
| /-- info: AddEquiv.{u_9, u_10} (A : Type u_9) (B : Type u_10) : Type -/ | |
| #guard_msgs in #check AddEquiv | |
| end |