Built with
doc-gen4, running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+↑Ctrl+↓to navigate,
Ctrl+🖱️to focus.
On Mac, use
Cmdinstead of
Ctrl.
/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Mario Carneiro
-/
import Lean
/-!
A rudimentary export format, adapted from
with support for lean 4 kernel primitives.
-/
open Lean (HashMap HashSet)
namespace Lean
namespace Export
/- References -/
private opaque MethodsRefPointed : NonemptyType.{0}
private def MethodsRef : Type := MethodsRefPointed.type
inductive Entry
| name (n : Name)
| level (n : Level)
| expr (n : Expr)
| defn (n : Name)
deriving Inhabited
instance : Coe Name Entry := ⟨Entry.name⟩
instance : Coe Level Entry := ⟨Entry.level⟩
instance : Coe Expr Entry := ⟨Entry.expr⟩
structure Alloc (α) [BEq α] [Hashable: Sort ?u.890 → Sort (max1?u.890)
Hashable α] where
map : HashMap α Nat
next : Nat
deriving Inhabited
structure State where
names : Alloc Name := ⟨HashMap.empty.insert Name.anonymous 0, 1⟩
levels : Alloc Level := ⟨HashMap.empty.insert levelZero 0, 1⟩
exprs : Alloc Expr
defs : HashSet Name
stk : Array (Bool × Entry)
deriving Inhabited
class OfState (α : Type) [BEq α] [Hashable: Sort ?u.3634 → Sort (max1?u.3634)
Hashable α] where
get : State → Alloc α
modify : (Alloc α → Alloc α) → State → State
instance : OfState Name where
get s := s.names
modify f s := { s with names := f s.names }
instance : OfState Level where
get s := s.levels
modify f s := { s with levels := f s.levels }
instance : OfState Expr where
get s := s.exprs
modify f s := { s with exprs := f s.exprs }
end Export
abbrev ExportM := StateT Export.State CoreM
namespace Export
def alloc {α} [BEq α] [Hashable: Sort ?u.4536 → Sort (max1?u.4536)
Hashable α] [OfState α] (a : α) : ExportM Nat := do
let n := (OfState.get (α := α) (← get)).next
modify $ OfState.modify (α := α) fun s ↦ {map := s.map.insert a n, next := n+1}
pure: {f : Type ?u.4910 → Type ?u.4909} → [self : Pure f] → {α : Type ?u.4910} → α → f α
pure n
def exportName (n : Name) : ExportM Nat := do
match (← get).names.map.find? n with
| some i => pure: {f : Type ?u.5905 → Type ?u.5904} → [self : Pure f] → {α : Type ?u.5905} → α → f α
pure i
| none => match n with
| .anonymous => pure: {f : Type ?u.6019 → Type ?u.6018} → [self : Pure f] → {α : Type ?u.6019} → α → f α
pure 0
| .num p a => let i ← alloc n; IO.println s!"{i} #NI {← exportName p} {a}"; pure: {f : Type ?u.6532 → Type ?u.6531} → [self : Pure f] → {α : Type ?u.6532} → α → f α
pure i
| .str p s => let i ← alloc n; IO.println s!"{i} #NS {← exportName p} {s}"; pure: {f : Type ?u.6937 → Type ?u.6936} → [self : Pure f] → {α : Type ?u.6937} → α → f α
pure i
def exportLevel (L : Level) : ExportM Nat := do
match (← get).levels.map.find? L with
| some i => pure: {f : Type ?u.12166 → Type ?u.12165} → [self : Pure f] → {α : Type ?u.12166} → α → f α
pure i
| none => match L with
| .zero => pure: {f : Type ?u.12280 → Type ?u.12279} → [self : Pure f] → {α : Type ?u.12280} → α → f α
pure 0
| .succ l =>
let i ← alloc L; IO.println s!"{i} #US {← exportLevel l}"; pure: {f : Type ?u.12740 → Type ?u.12739} → [self : Pure f] → {α : Type ?u.12740} → α → f α
pure i
| .max l₁ l₂ =>
let i ← alloc L; IO.println s!"{i} #UM {← exportLevel l₁} {← exportLevel l₂}"; pure: {f : Type ?u.13192 → Type ?u.13191} → [self : Pure f] → {α : Type ?u.13192} → α → f α
pure i
| .imax l₁ l₂ =>
let i ← alloc L; IO.println s!"{i} #UIM {← exportLevel l₁} {← exportLevel l₂}"; pure: {f : Type ?u.13648 → Type ?u.13647} → [self : Pure f] → {α : Type ?u.13648} → α → f α
pure i
| .param n =>
let i ← alloc L; IO.println s!"{i} #UP {← exportName n}"; pure: {f : Type ?u.14004 → Type ?u.14003} → [self : Pure f] → {α : Type ?u.14004} → α → f α
pure i
| .mvar _ => unreachable!
def biStr : BinderInfo → String
| BinderInfo.default => "#BD"
| BinderInfo.implicit => "#BI"
| BinderInfo.strictImplicit => "#BS"
| BinderInfo.instImplicit => "#BC"
open ConstantInfo in
mutual
partial def exportExpr (E : Expr) : ExportM Nat := do
match (← get).exprs.map.find? E with
| some i => pure: {f : Type ?u.24371 → Type ?u.24370} → [self : Pure f] → {α : Type ?u.24371} → α → f α
pure i
| none => match E with
| .bvar n => let i ← alloc E; IO.println s!"{i} #EV {n}"; pure: {f : Type ?u.24856 → Type ?u.24855} → [self : Pure f] → {α : Type ?u.24856} → α → f α
pure i
| .fvar _ => unreachable!
| .mvar _ => unreachable!
| .sort l => let i ← alloc E; IO.println s!"{i} #ES {← exportLevel l}"; pure: {f : Type ?u.25434 → Type ?u.25433} → [self : Pure f] → {α : Type ?u.25434} → α → f α
pure i
| .const n ls =>
exportDef n
let i ← alloc E
let mut s := s!"{i} #EC {← exportName n}"
for l in ls do s := s ++ s!" {← exportLevel l}": ?m.25954
s!s!" {← exportLevel l}": ?m.25954
" {← exportLevels!" {← exportLevel l}": ?m.25954
ls!" {← exportLevel l}": ?m.25954
}"
IO.println s; pure: {f : Type ?u.26255 → Type ?u.26254} → [self : Pure f] → {α : Type ?u.26255} → α → f α
pure i
| .app e₁ e₂ =>
let i ← alloc E; IO.println s!"{i} #EA {← exportExpr e₁} {← exportExpr e₂}"; pure: {f : Type ?u.26721 → Type ?u.26720} → [self : Pure f] → {α : Type ?u.26721} → α → f α
pure i
| .lam _ e₁ e₂ d =>
let i ← alloc E
IO.println s!"{i} #EL {biStr d} {← exportExpr e₁} {← exportExpr e₂}"; pure: {f : Type ?u.27234 → Type ?u.27233} → [self : Pure f] → {α : Type ?u.27234} → α → f α
pure i
| .forallE _ e₁ e₂ d =>
let i ← alloc E
IO.println s!"{i} #EP {biStr d} {← exportExpr e₁} {← exportExpr e₂}"; pure: {f : Type ?u.27747 → Type ?u.27746} → [self : Pure f] → {α : Type ?u.27747} → α → f α
pure i
| .letE _ e₁ e₂ e₃ _ =>
let i ← alloc E
IO.println s!"{i} #EP {← exportExpr e₁} {← exportExpr e₂} {← exportExpr e₃}"; pure: {f : Type ?u.28315 → Type ?u.28314} → [self : Pure f] → {α : Type ?u.28315} → α → f α
pure i
| .lit (.natVal n) => let i ← alloc E; IO.println s!"{i} #EN {n}"; pure: {f : Type ?u.28630 → Type ?u.28629} → [self : Pure f] → {α : Type ?u.28630} → α → f α
pure i
| .lit (.strVal s) => let i ← alloc E; IO.println s!"{i} #ET {s}"; pure: {f : Type ?u.28927 → Type ?u.28926} → [self : Pure f] → {α : Type ?u.28927} → α → f α
pure i
| .mdata _ _ => unreachable!
| .proj n k e =>
let i ← alloc E; IO.println s!"{i} #EJ {← exportName n} {k} {← exportExpr e}"; pure: {f : Type ?u.29533 → Type ?u.29532} → [self : Pure f] → {α : Type ?u.29533} → α → f α
pure i
partial def exportDef (n : Name) : ExportM Unit := do
if (← get).defs.contains n then return: ?m.36730 ?m.36732
return
let ci ← getConstInfo n
for c in ci.value!.getUsedConstants do
unless (← get).defs.contains c do
exportDef c
match ci with
| axiomInfo val => axdef "#AX" val.name val.type val.levelParams
| defnInfo val => defn "#DEF" val.name val.type val.value val.levelParams
| thmInfo val => defn "#THM" val.name val.type val.value val.levelParams
| opaqueInfo val => defn "#CN" val.name val.type val.value val.levelParams
| quotInfo _ =>
IO.println "#QUOT"
for n in [``Quot, ``Quot.mk, ``Quot.lift: {α : Sort u} → {r : α → α → Prop} → {β : Sort v} → (f : α → β) → (∀ (a b : α), r a b → f a = f b) → Quot r → β
Quot.lift, ``Quot.ind] do
insert n
| inductInfo val => ind val.all
| ctorInfo val => ind (← getConstInfoInduct val.induct): ?m.38027
(← getConstInfoInduct(← getConstInfoInduct val.induct): ?m.38027
val(← getConstInfoInduct val.induct): ?m.38027
.induct(← getConstInfoInduct val.induct): ?m.38027
).all
| recInfo val => ind val.all
where
insert (n : Name) : ExportM Unit :=
modify fun s ↦ { s with defs := s.defs.insert n }
defn (ty : String) (n : Name) (t e : Expr) (ls : List Name) : ExportM Unit := do
let mut s := s!"{ty} {← exportName n} {← exportExpr t} {← exportExpr e}"
for l in ls do s := s ++ s!" {← exportName l}": ?m.30834
s!s!" {← exportName l}": ?m.30834
" {← exportNames!" {← exportName l}": ?m.30834
ls!" {← exportName l}": ?m.30834
}"
IO.println s
insert n
axdef (ty : String) (n : Name) (t : Expr) (ls : List Name) : ExportM Unit := do
let mut s := s!"{ty} {← exportName n} {← exportExpr t}"
for l in ls do s := s ++ s!" {← exportName l}": ?m.31717
s!s!" {← exportName l}": ?m.31717
" {← exportNames!" {← exportName l}": ?m.31717
ls!" {← exportName l}": ?m.31717
}"
IO.println s
insert n
ind : List Name → ExportM Unit
| [] => unreachable!
| is@(i::_) => do
let val ← getConstInfoInduct i
let mut s := match is.length with
| 1 => s!"#IND {val.numParams}"
| n => s!"#MUT {val.numParams} {n}"
for j in is do insert j; insert (mkRecName j)
for j in is do
let val ← getConstInfoInduct j
s := s ++ s!" {← exportName val.name} {← exportExpr val.type} {val.ctors.length}"
for c in val.ctors do
insert c
s := s ++ s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
s!s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
" {← exportNames!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
cs!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
} {← exportExprs!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
(← getConstInfoCtor c): ?m.33409
(← getConstInfoCtor(← getConstInfoCtor c): ?m.33409
c(← getConstInfoCtor c): ?m.33409
)s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
.types!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.33825
}"
for j in is do s ← indbody j s
for l in val.levelParams do s := s ++ s!" {← exportName l}": ?m.34715
s!s!" {← exportName l}": ?m.34715
" {← exportNames!" {← exportName l}": ?m.34715
ls!" {← exportName l}": ?m.34715
}"
IO.println s
indbody (ind : Name) (s : String) : ExportM String := do
let val ← getConstInfoInduct ind
let mut s := s ++ s!" {← exportName ind} {← exportExpr val.type} {val.ctors.length}"
for c in val.ctors do
s := s ++ s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
s!s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
" {← exportNames!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
cs!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
} {← exportExprs!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
(← getConstInfoCtor c): ?m.35991
(← getConstInfoCtor(← getConstInfoCtor c): ?m.35991
c(← getConstInfoCtor c): ?m.35991
)s!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
.types!" {← exportName c} {← exportExpr (← getConstInfoCtor c).type}": ?m.36132
}"
pure: {f : Type ?u.36387 → Type ?u.36386} → [self : Pure f] → {α : Type ?u.36387} → α → f α
pure s
end
def runExportM (m : ExportM α) : CoreM α := m.run' default
-- #eval runExportM (exportDef `Lean.Expr)
end Export
end Lean