-
Notifications
You must be signed in to change notification settings - Fork 450
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add proper erasure of type dependencies in LCNF (#6678)
This PR modifies LCNF.toMonoType to use a more refined type erasure scheme, which distinguishes between irrelevant/erased information (represented by lcErased) and erased type dependencies (represented by lcAny). This corresponds to the irrelevant/object distinction in the old code generator.
- Loading branch information
Showing
6 changed files
with
293 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
import Lean | ||
import Lean.Compiler.LCNF.MonoTypes | ||
import Lean.Compiler.LCNF.Types | ||
|
||
open Lean Meta | ||
open Compiler.LCNF (toLCNFType toMonoType) | ||
|
||
def toMonoLCNFType (type : Expr) : MetaM Expr := do | ||
toMonoType (← toLCNFType type) | ||
|
||
def checkMonoType! (type₁ type₂ : Expr) : MetaM Unit := do | ||
let monoType ← toMonoLCNFType type₁ | ||
if monoType != type₂ then | ||
throwError f!"mono type for {type₁} is {monoType}, expected {type₂}" | ||
let monoMonoType ← toMonoType monoType | ||
if monoMonoType != monoType then | ||
throwError f!"toMonoType is not idempotent: toMonoType of {monoType} is {monoMonoType}" | ||
|
||
-- Nat | ||
|
||
#eval checkMonoType! | ||
(.const ``Nat []) | ||
(.const ``Nat []) | ||
|
||
-- Decidable | ||
|
||
#eval checkMonoType! | ||
(.const ``Decidable []) | ||
(.const ``Bool []) | ||
|
||
-- Prop | ||
|
||
#eval checkMonoType! | ||
(.sort .zero) | ||
(.const ``lcErased []) | ||
|
||
-- Type | ||
|
||
#eval checkMonoType! | ||
(.sort (.succ .zero)) | ||
(.const ``lcErased []) | ||
|
||
-- Sort u | ||
|
||
#eval checkMonoType! | ||
(.sort (.param `u)) | ||
(.const ``lcErased []) | ||
|
||
-- List Nat | ||
|
||
#eval checkMonoType! | ||
(.app (.const ``List [.succ .zero]) (.const ``Nat [])) | ||
(.app (.const ``List []) (.const ``Nat [])) | ||
|
||
-- List Type | ||
|
||
#eval checkMonoType! | ||
(.app (.const ``List [.succ (.succ .zero)]) (.sort (.succ .zero))) | ||
(.app (.const ``List []) (.const ``lcErased [])) | ||
|
||
-- Inductive type with trivial structure | ||
|
||
inductive TrivialInductive : Type where | ||
| constructor (a : Nat) : TrivialInductive | ||
|
||
#eval checkMonoType! | ||
(.const ``TrivialInductive []) | ||
(.const ``Nat []) | ||
|
||
-- Inductive type with trivial structure and irrelevant fields | ||
|
||
inductive TrivialInductivePropFields : Type where | ||
| constructor (p₁ : Prop) (a : Nat) (p₂ : Prop) : TrivialInductivePropFields | ||
|
||
#eval checkMonoType! | ||
(.const ``TrivialInductivePropFields []) | ||
(.const ``Nat []) | ||
|
||
-- Structure type with trivial structure | ||
|
||
structure TrivialStructure : Type where | ||
a : Nat | ||
|
||
#eval checkMonoType! | ||
(.const ``TrivialStructure []) | ||
(.const ``Nat []) | ||
|
||
-- Structure type with trivial structure and irrelevant fields | ||
|
||
structure TrivialStructurePropFields : Type where | ||
p₁ : Prop | ||
a : Nat | ||
p₂ : Prop | ||
|
||
#eval checkMonoType! | ||
(.const ``TrivialStructurePropFields []) | ||
(.const ``Nat []) | ||
|
||
-- Nat → Nat | ||
|
||
#eval checkMonoType! | ||
(.forallE `a (.const ``Nat []) (.const ``Nat []) .default) | ||
(.forallE `a (.const ``Nat []) (.const ``Nat []) .default) | ||
|
||
-- Nat → List Nat | ||
|
||
#eval checkMonoType! | ||
(.forallE `a (.const ``Nat []) (.app (.const ``List [.succ .zero]) (.const ``Nat [])) .default) | ||
(.forallE `a (.const ``Nat []) (.app (.const ``List []) (.const ``Nat [])) .default) | ||
|
||
-- Nat → Prop | ||
|
||
#eval checkMonoType! | ||
(.forallE `a (.const ``Nat []) (.sort .zero) .default) | ||
(.const ``lcErased []) | ||
|
||
-- Nat → Type | ||
|
||
#eval checkMonoType! | ||
(.forallE `a (.const ``Nat []) (.sort (.succ .zero)) .default) | ||
(.const ``lcErased []) | ||
|
||
-- Nat → Bool → Type | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `a (.const ``Bool []) (.sort (.succ .zero)) .default) | ||
.default) | ||
(.const ``lcErased []) | ||
|
||
-- (α : Type) → List α | ||
|
||
#eval checkMonoType! | ||
(.forallE `α (.sort (.succ .zero)) (.app (.const ``List [.succ .zero]) (.bvar 0)) .default) | ||
(.forallE `α (.const ``lcErased []) (.app (.const ``List []) (.const ``lcAny [])) .default) | ||
|
||
-- List Nat → List Bool | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.app (.const ``List [.succ .zero]) (.const ``Nat [])) | ||
(.app (.const ``List [.succ .zero]) (.const ``Bool [])) | ||
.default) | ||
(.forallE `a | ||
(.app (.const ``List []) (.const ``Nat [])) | ||
(.app (.const ``List []) (.const ``Bool [])) | ||
.default) | ||
|
||
-- List Nat → List Prop | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.app (.const ``List [.succ .zero]) (.const ``Nat [])) | ||
(.app (.const ``List [.succ .zero]) (.sort .zero)) | ||
.default) | ||
(.forallE `a | ||
(.app (.const ``List []) (.const ``Nat [])) | ||
(.app (.const ``List []) (.const ``lcErased [])) | ||
.default) | ||
|
||
-- (α : Type) → α → α | ||
|
||
#eval checkMonoType! | ||
(.forallE `α | ||
(.sort (.succ .zero)) | ||
(.forallE `a (.bvar 0) (.bvar 1) .default) | ||
.default) | ||
(.forallE `α | ||
(.const ``lcErased []) | ||
(.forallE `a (.const ``lcAny []) (.const ``lcAny []) .default) | ||
.default) | ||
|
||
-- Nat → (α : Type) → α → Bool | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `α | ||
(.sort (.succ .zero)) | ||
(.forallE `a (.bvar 0) (.const ``Bool []) .default) | ||
.default) | ||
.default) | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `α | ||
(.const ``lcErased []) | ||
(.forallE `a (.const ``lcAny []) (.const ``Bool []) .default) | ||
.default) | ||
.default) | ||
|
||
-- Nat → Bool → Type | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `b (.const ``Bool []) (.sort (.succ .zero)) .default) | ||
.default) | ||
(.const ``lcErased []) | ||
|
||
-- Nat → Bool → (Nat → Type) | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `b (.const ``Bool []) (.sort (.succ .zero)) .default) | ||
.default) | ||
(.const ``lcErased []) | ||
|
||
-- Nat → (Nat → Type) → Bool | ||
|
||
#eval checkMonoType! | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `b | ||
(.forallE `c (.const ``lcErased []) (.sort (.succ .zero)) .default) | ||
(.const ``Bool []) | ||
.default) | ||
.default) | ||
(.forallE `a | ||
(.const ``Nat []) | ||
(.forallE `b | ||
(.const ``lcErased []) | ||
(.const ``Bool []) | ||
.default) | ||
.default) | ||
|
||
-- (α : Sort u) → (β : α → Sort v) → (a : α) → ((x : α) → β x) → β a | ||
|
||
#eval checkMonoType! | ||
(.forallE | ||
`α | ||
(.sort (.param `u)) | ||
(.forallE | ||
`β | ||
(.forallE `f1 (.bvar 0) (.sort (.param `v)) .default) | ||
(.forallE | ||
`a | ||
(.bvar 1) | ||
(.forallE | ||
`f2 | ||
(.forallE `x (.bvar 2) (.app (.bvar 2) (.bvar 0)) .default) | ||
(.app (.bvar 2) (.bvar 1)) | ||
.default) | ||
.default) | ||
.default) | ||
.default) | ||
(.forallE | ||
`α | ||
(.const ``lcErased []) | ||
(.forallE | ||
`β | ||
(.const ``lcErased []) | ||
(.forallE | ||
`a | ||
(.const ``lcAny []) | ||
(.forallE | ||
`f2 | ||
(.forallE `x (.const ``lcAny []) (.const ``lcAny []) .default) | ||
(.const ``lcAny []) | ||
.default) | ||
.default) | ||
.default) | ||
.default) |