Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Qpf/Macro/Common.lean
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,6 @@ def elabCommandAndTrace (stx : Syntax)
pure idents




open Parser.Command in
instance : Quote Modifiers (k := ``declModifiers) where
quote mod :=
Expand All @@ -235,7 +233,7 @@ instance : Quote Modifiers (k := ``declModifiers) where

let visibility := match mod.visibility with
| .regular => mkNullNode
| .«protected» => mkNode ``«protected» #[mkAtom "protected "]
| .«public» => mkNode ``«public» #[mkAtom "public "]
| .«private» => mkNode ``«private» #[mkAtom "private "]

mkNode ``declModifiers #[
Expand Down
19 changes: 9 additions & 10 deletions Qpf/Macro/Comp.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import Qq
namespace Macro.Comp
open MvQPF
open Lean Elab Term Command Meta
open Mathlib (Vector)

open PrettyPrinter (delab)
open Syntax
Expand Down Expand Up @@ -65,7 +64,7 @@ def synthQPF {n : Nat} (F : Q(TypeFun.{u,u} $n)) : MetaM Q(MvQPF $F) := do
Then, tries to infer an instance of `MvQPF (TypeFun.curried F)`
-/
protected partial def parseApp (isLiveVar : FVarId → Bool) (F : Q(Type u)) :
TermElabM ((n : Nat) × Q(TypeFun.{u,u} $n) × Vector Expr n) :=
TermElabM ((n : Nat) × Q(TypeFun.{u,u} $n) × List.Vector Expr n) :=
if F.isApp then
/-
HACK: Technically `F` is *not* an instance of `CurriedTypeFun 0`.
Expand All @@ -77,9 +76,9 @@ protected partial def parseApp (isLiveVar : FVarId → Bool) (F : Q(Type u)) :
throwError "application expected:\n {F}"

where
parseAppAux : {n : Nat} → Q(CurriedTypeFun.{u,u} $n) → Vector Expr n → Option Exception → _
parseAppAux : {n : Nat} → Q(CurriedTypeFun.{u,u} $n) → List.Vector Expr n → Option Exception → _
| depth', Expr.app F a, args', _ => do
let args := Vector.cons a args'
let args := .cons a args'
let depth : Nat := depth' + 1
let F : Q(CurriedTypeFun.{u,u} $depth) := F

Expand Down Expand Up @@ -169,11 +168,11 @@ structure ElabQpfResult (u : Level) (arity : Nat) where
qpf : Q(@MvQPF _ $F) := by exact q(by infer_instance)
deriving Inhabited

def isLiveVar (varIds : Vector FVarId n) (id : FVarId) := varIds.toList.contains id
def isLiveVar (varIds : List.Vector FVarId n) (id : FVarId) := varIds.toList.contains id

open PrettyPrinter in
mutual
partial def handleLiveFVar (vars : Vector FVarId arity) (target : FVarId) : TermElabM (ElabQpfResult u arity) := do
partial def handleLiveFVar (vars : List.Vector FVarId arity) (target : FVarId) : TermElabM (ElabQpfResult u arity) := do
trace[QPF] f!"target {Expr.fvar target} is a free variable"
let ind ← match List.indexOf' target vars.toList with
| none => throwError "Free variable {Expr.fvar target} is not one of the qpf arguments"
Expand All @@ -192,7 +191,7 @@ partial def handleConst (target : Q(Type u)) : TermElabM (ElabQpfResult u arity
pure { F := const, qpf := q(Const.mvqpf)}


partial def handleApp (vars : Vector FVarId arity) (target : Q(Type u)) : TermElabM (ElabQpfResult u arity) := do
partial def handleApp (vars : List.Vector FVarId arity) (target : Q(Type u)) : TermElabM (ElabQpfResult u arity) := do
let vars' := vars.toList

let ⟨numArgs, F, args⟩ ← (Comp.parseApp (isLiveVar vars) target)
Expand Down Expand Up @@ -231,14 +230,14 @@ partial def handleApp (vars : Vector FVarId arity) (target : Q(Type u)) : TermEl
return { F := comp, qpf }


partial def handleArrow (binderType body : Expr) (vars : Vector FVarId arity) (targetStx : Option Term := none) (normalized := false) : TermElabM (ElabQpfResult u arity) := do
partial def handleArrow (binderType body : Expr) (vars : List.Vector FVarId arity) (targetStx : Option Term := none) (normalized := false) : TermElabM (ElabQpfResult u arity) := do
let newTarget ← mkAppM ``MvQPF.Arrow.Arrow #[binderType, body]
elabQpf vars newTarget targetStx normalized

/--
Elaborate the body of a qpf
-/
partial def elabQpf {arity : Nat} (vars : Vector FVarId arity) (target : Q(Type u)) (targetStx : Option Term := none) (normalized := false) :
partial def elabQpf {arity : Nat} (vars : List.Vector FVarId arity) (target : Q(Type u)) (targetStx : Option Term := none) (normalized := false) :
TermElabM (ElabQpfResult u arity) := do
trace[QPF] "elabQPF :: {(vars.map Expr.fvar).toList} -> {target}"
let isLiveVar := isLiveVar vars
Expand Down Expand Up @@ -301,7 +300,7 @@ def elabQpfCompositionBody (view: QpfCompositionBodyView) :
withoutAutoBoundImplicit <| do
let target_expr ← elabTermEnsuringTypeQ (u:=u.succ.succ) view.target q(Type u)
let arity := vars.toList.length
let vars : Vector _ arity := ⟨vars.toList, rfl⟩
let vars : List.Vector _ arity := ⟨vars.toList, rfl⟩

let some vars := vars.mmap Expr.fvarId? |
throwError "Expected all args to be fvars" -- TODO: throwErrorAt
Expand Down
54 changes: 23 additions & 31 deletions Qpf/Macro/Data.lean
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,8 @@ end
open Elab.Term (TermElabM)

def CtorView.declReplacePrefix (pref new_pref : Name) (ctor: CtorView) : CtorView :=
let declName := ctor.declName.replacePrefix pref new_pref
{
declName,
ref := ctor.ref
modifiers := ctor.modifiers
binders := ctor.binders
type? := ctor.type?
{ ctor with
declName := ctor.declName.replacePrefix pref new_pref
}


Expand All @@ -93,6 +88,16 @@ private def addSuffixToDeclIdent {m} [Monad m] [MonadResolveName m] (declId : Sy
let (_, uncurriedDeclId, _) ← addSuffixToDeclId declId suffix
pure ⟨uncurriedDeclId.raw[0]⟩

open private elabInductiveViews from Lean.Elab.MutualInductive in
open private elabCtors from Lean.Elab.Inductive in
private def elabInductiveView (vars : Array Expr) (view : InductiveView) : TermElabM Unit := do
let view := {
view
elabCtors := fun rs r params => do
let ctors ← elabCtors (rs.map (·.indFVar)) params r
return { ctors }
}
let _ ← elabInductiveViews vars #[view]

open Parser in
/--
Expand All @@ -114,33 +119,23 @@ def mkHeadT (view : InductiveView) : CommandElabM Name := do
-- The head type is the same as the original type, but with all constructor arguments removed
let ctors ← view.ctors.mapM fun ctor => do
let declName := ctor.declName.replacePrefix view.declName declName
pure {
pure { ctor with
modifiers, declName,
ref := ctor.ref
binders := mkNullNode
binders := mkNullNode,
type? := none
: CtorView
}

-- let type ← `(Type $(mkIdent `u))

-- TODO: make `HeadT` universe polymorphic
let view := {
let view := { view with
ctors, declId, declName, shortDeclName, modifiers,
binders := view.binders.setArgs #[]
levelNames := view.levelNames

ref := view.ref
type? := view.type?

derivingClasses := view.derivingClasses
computedFields := #[]
: InductiveView
}

withQPFTraceNode "elabInductiveViews" <|
runTermElabM <| fun vars =>
elabInductiveViews vars #[view]
runTermElabM (elabInductiveView · view)
pure declName

open Parser Parser.Term Parser.Command in
Expand Down Expand Up @@ -267,8 +262,8 @@ def mkQpf (shapeView : InductiveView) (ctorArgs : Array CtorArgs) (headT P : Ide
let (i, j) := (args.per_type.enum.map fun (i, t) =>
-- the order of types is reversed, since `TypeVec`s count right-to-left
let i := arity - 1 - i
((t.indexOf? arg).map fun ⟨j, _⟩ => (i, j)).toList
).toList.join.get! 0
((t.idxOf? arg).map fun j => (i, j)).toList
).toList.flatten[0]!

`($unbox_child $(Fin2.quoteOfNat i) $(PFin2.quoteOfNat j))

Expand Down Expand Up @@ -341,15 +336,13 @@ def mkShape (view : DataView) : TermElabM MkShapeResult := do
let modifiers : Modifiers := {
isUnsafe := view.modifiers.isUnsafe
}
let view : InductiveView := {
let view : InductiveView := { view with
ctors, declId, declName, shortDeclName, modifiers, binders,
levelNames := []

ref := view.ref
type? := view.type?

derivingClasses := view.derivingClasses
computedFields := #[]
isClass := false
allowIndices := false
allowSortPolymorphism := false
: InductiveView
}

Expand All @@ -359,8 +352,7 @@ def mkShape (view : DataView) : TermElabM MkShapeResult := do
return ⟨r, declName, PName, do
withQPFTraceNode "mkShape effects" <| do

runTermElabM <| fun vars =>
elabInductiveViews vars #[view]
runTermElabM (elabInductiveView · view)

let headTName ← mkHeadT view
let childTName ← mkChildT view r headTName
Expand Down
2 changes: 1 addition & 1 deletion Qpf/Macro/Data/Constructors.lean
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def mkConstructorsWithNameAndType
|> RecursionForm.toType retTy

let modifiers : Modifiers := {
isNoncomputable := view.modifiers.isNoncomputable
computeKind := view.modifiers.computeKind
attrs := #[{
name := `matchPattern
}]
Expand Down
5 changes: 2 additions & 3 deletions Qpf/Macro/Data/Count.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ open Lean Meta

open Parser
private partial def countVarOccurencesAux (r : Replace) (acc : Array Nat) : Syntax → Array Nat
| Syntax.node _ ``Term.arrow #[arg, _arrow, tail] =>
| Syntax.node _ ``Term.arrow #[arg, _arrow, tail] =>
-- NOTE: `indexOf` return an index one-past-the-end of `r.vars` if it cant find the index
let i := (r.vars.indexOf? arg.getId).map fun ⟨n, _⟩ => n
let i := i.getD acc.size
let i := (r.vars.idxOf? arg.getId).getD acc.size

-- dbg_trace "{r.expr}.indexOf {arg} == {i}"
-- dbg_trace "pre: {acc}"
Expand Down
6 changes: 3 additions & 3 deletions Qpf/Macro/Data/Replace.lean
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ private def ReplaceM.identFor (stx : Term) : ReplaceM m Ident := do
let args := ctor.args.push argName
-- dbg_trace "\nstx := {stx}\nr.expr := {r.expr}"

let name ← match r.expr.indexOf? stx with
let name ← match r.expr.idxOf? stx with
| some id => do
let per_type := ctor.per_type.set! id $ (ctor.per_type.get! id).push argName
let per_type := ctor.per_type.set! id $ (ctor.per_type[id]!).push argName
let ctor := { args, per_type }
StateT.set { r with ctor }
pure $ r.vars.get! id
pure $ r.vars[id]!
| none => do
let per_type := ctor.per_type.push #[argName]
let name ← mkFreshBinderName
Expand Down
17 changes: 12 additions & 5 deletions Qpf/Macro/Data/View.lean
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ def DataView.asInductive (view : DataView) : InductiveView
derivingClasses := view.derivingClasses
-- TODO: find out what these computed fields are, add support for them in `data`/`codata`
computedFields := #[]
isClass := false
allowIndices := false
allowSortPolymorphism := false
}


Expand Down Expand Up @@ -259,7 +262,7 @@ def DataView.doSanityChecks (view : DataView) : CommandElabM Unit := do


/-
Heavily based on `inductiveSyntaxToView` from Lean.Elab.Declaration
Heavily based on `inductiveSyntaxToView` from Lean.Elab.Inductive
-/
def dataSyntaxToView (modifiers : Modifiers) (decl : Syntax) : CommandElabM DataView :=
withQPFTraceNode "dataSyntaxToView" (tag := "dataSyntaxToView") <| do
Expand All @@ -273,23 +276,27 @@ def dataSyntaxToView (modifiers : Modifiers) (decl : Syntax) : CommandElabM Data
let ⟨name, declName, levelNames⟩ ← expandDeclId (← getCurrNamespace) (← getLevelNames) declId modifiers
-- addDeclarationRanges declName decl
let ctors ← decl[4].getArgs.mapM fun ctor => withRef ctor do
-- def ctor := leading_parser optional docComment >> "\n| " >> declModifiers >> rawIdent >> optDeclSig
/-
```
def ctor := leading_parser optional docComment >> "\n| " >> declModifiers >> rawIdent >> optDeclSig
```
-/
let mut ctorModifiers ← elabModifiers ⟨ctor[2]⟩
if let some leadingDocComment := ctor[0].getOptional? then
if ctorModifiers.docString?.isSome then
logErrorAt leadingDocComment "duplicate doc string"
ctorModifiers := { ctorModifiers with docString? := TSyntax.getDocString ⟨leadingDocComment⟩ }
ctorModifiers := { ctorModifiers with docString? := some ⟨leadingDocComment⟩ }
if ctorModifiers.isPrivate && modifiers.isPrivate then
throwError "invalid 'private' constructor in a 'private' inductive datatype"
if ctorModifiers.isProtected && modifiers.isPrivate then
throwError "invalid 'protected' constructor in a 'private' inductive datatype"
checkValidCtorModifier ctorModifiers
let ctorName := ctor.getIdAt 3
let ctorName := declName ++ ctorName
let ctorName ← withRef ctor[3] $ applyVisibility ctorModifiers.visibility ctorName
let ctorName ← withRef ctor[3] <| applyVisibility ctorModifiers ctorName
let (binders, type?) := expandOptDeclSig ctor[4]
addDocString' ctorName ctorModifiers.docString?
return { ref := ctor, modifiers := ctorModifiers, declName := ctorName, binders := binders, type? := type? : CtorView }
return { ref := ctor, declId := ctor[3], modifiers := ctorModifiers, declName := ctorName, binders := binders, type? := type? : CtorView }
let classes ← liftCoreM <| getOptDerivingClasses decl[5]


Expand Down
1 change: 1 addition & 0 deletions Qpf/MathlibPort/Fin2.lean
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Authors: Mario Carneiro
-/

import Mathlib.Data.Fin.Fin2
import Mathlib.Data.Fintype.OfMap

/-!
# Inductive type variant of `Fin`
Expand Down
2 changes: 1 addition & 1 deletion Test/DeadWrap.lean
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Test
data DeadWrap (α : Type) β
| mk : α → DeadWrap α β

/-- info: 'Test.DeadWrap.Base' depends on axioms: [propext, Quot.sound] -/
/-- info: 'Test.DeadWrap.Base' depends on axioms: [propext] -/
#guard_msgs in
#print axioms DeadWrap.Base

Expand Down
Loading