refactor: Split Constructions module (#4656)

for better build paralleization and less rebuilding when editing one of
these files.
This commit is contained in:
Joachim Breitner 2024-07-05 10:25:44 +02:00 committed by GitHub
parent 5ad5c2cf04
commit 5ce886cf96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 153 additions and 132 deletions

View file

@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
-/
prelude
import Lean.Meta.Constructions
import Lean.Meta.Constructions.CasesOn
import Lean.Compiler.ImplementedByAttr
import Lean.Elab.PreDefinition.WF.Eqns

View file

@ -4,135 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.AuxRecursor
import Lean.AddDecl
import Lean.Meta.AppBuilder
import Lean.Meta.CompletionName
import Lean.Meta.Constructions.CasesOn
import Lean.Meta.Constructions.NoConfusion
import Lean.Meta.Constructions.RecOn
import Lean.Meta.Constructions.BRecOn
namespace Lean
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
open Meta
def mkCasesOn (declName : Name) : MetaM Unit := do
let name := mkCasesOnName declName
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => markAuxRecursor env name
modifyEnv fun env => addProtected env name
def mkNoConfusionCore (declName : Name) : MetaM Unit := do
-- Do not do anything unless can_elim_to_type. TODO: Extract to util
let .inductInfo indVal ← getConstInfo declName | return
let recInfo ← getConstInfo (mkRecName declName)
unless recInfo.levelParams.length > indVal.levelParams.length do return
let name := Name.mkStr declName "noConfusionType"
let decl ← ofExceptKernelException (mkNoConfusionTypeCoreImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => addToCompletionBlackList env name
modifyEnv fun env => addProtected env name
let name := Name.mkStr declName "noConfusion"
let decl ← ofExceptKernelException (mkNoConfusionCoreImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => markNoConfusion env name
modifyEnv fun env => addProtected env name
def mkNoConfusionEnum (enumName : Name) : MetaM Unit := do
if (← getEnv).contains ``noConfusionEnum then
mkToCtorIdx
mkNoConfusionType
mkNoConfusion
else
-- `noConfusionEnum` was not defined yet, so we use `mkNoConfusionCore`
mkNoConfusionCore enumName
where
mkToCtorIdx : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let numCtors := info.ctors.length
let declName := Name.mkStr enumName "toCtorIdx"
let enumType := mkConst enumName us
let natType := mkConst ``Nat
let declType ← mkArrow enumType natType
let mut minors := #[]
for i in [:numCtors] do
minors := minors.push <| mkNatLit i
withLocalDeclD `x enumType fun x => do
let motive ← mkLambdaFVars #[x] natType
let declValue ← mkLambdaFVars #[x] <| mkAppN (mkApp2 (mkConst (mkCasesOnName enumName) (levelOne::us)) motive x) minors
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
mkNoConfusionType : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let v ← mkFreshUserName `v
let enumType := mkConst enumName us
let sortV := mkSort (mkLevelParam v)
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
withLocalDeclD `P sortV fun P =>
withLocalDeclD `x enumType fun x =>
withLocalDeclD `y enumType fun y => do
let declType ← mkForallFVars #[P, x, y] sortV
let declValue ← mkLambdaFVars #[P, x, y] (← mkAppM ``noConfusionTypeEnum #[toCtorIdx, P, x, y])
let declName := Name.mkStr enumName "noConfusionType"
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := v :: info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
mkNoConfusion : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let v ← mkFreshUserName `v
let enumType := mkConst enumName us
let sortV := mkSort (mkLevelParam v)
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
let noConfusionType := mkConst (Name.mkStr enumName "noConfusionType") (mkLevelParam v :: us)
withLocalDecl `P BinderInfo.implicit sortV fun P =>
withLocalDecl `x BinderInfo.implicit enumType fun x =>
withLocalDecl `y BinderInfo.implicit enumType fun y => do
withLocalDeclD `h (← mkEq x y) fun h => do
let declType ← mkForallFVars #[P, x, y, h] (mkApp3 noConfusionType P x y)
let declValue ← mkLambdaFVars #[P, x, y, h] (← mkAppOptM ``noConfusionEnum #[none, none, none, toCtorIdx, P, x, y, h])
let declName := Name.mkStr enumName "noConfusion"
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := v :: info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
modifyEnv fun env => markNoConfusion env declName
def mkNoConfusion (declName : Name) : MetaM Unit := do
if (← isEnumType declName) then
mkNoConfusionEnum declName
else
mkNoConfusionCore declName
end Lean

View file

@ -0,0 +1,23 @@
/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.AddDecl
import Lean.Meta.Basic
namespace Lean
@[extern "lean_mk_cases_on"] opaque mkCasesOnImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
open Meta
def mkCasesOn (declName : Name) : MetaM Unit := do
let name := mkCasesOnName declName
let decl ← ofExceptKernelException (mkCasesOnImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => markAuxRecursor env name
end Lean

View file

@ -0,0 +1,126 @@
/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.AddDecl
import Lean.Meta.AppBuilder
import Lean.Meta.CompletionName
namespace Lean
@[extern "lean_mk_no_confusion_type"] opaque mkNoConfusionTypeCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
@[extern "lean_mk_no_confusion"] opaque mkNoConfusionCoreImp (env : Environment) (declName : @& Name) : Except KernelException Declaration
open Meta
def mkNoConfusionCore (declName : Name) : MetaM Unit := do
-- Do not do anything unless can_elim_to_type. TODO: Extract to util
let .inductInfo indVal ← getConstInfo declName | return
let recInfo ← getConstInfo (mkRecName declName)
unless recInfo.levelParams.length > indVal.levelParams.length do return
let name := Name.mkStr declName "noConfusionType"
let decl ← ofExceptKernelException (mkNoConfusionTypeCoreImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => addToCompletionBlackList env name
modifyEnv fun env => addProtected env name
let name := Name.mkStr declName "noConfusion"
let decl ← ofExceptKernelException (mkNoConfusionCoreImp (← getEnv) declName)
addDecl decl
setReducibleAttribute name
modifyEnv fun env => markNoConfusion env name
modifyEnv fun env => addProtected env name
def mkNoConfusionEnum (enumName : Name) : MetaM Unit := do
if (← getEnv).contains ``noConfusionEnum then
mkToCtorIdx
mkNoConfusionType
mkNoConfusion
else
-- `noConfusionEnum` was not defined yet, so we use `mkNoConfusionCore`
mkNoConfusionCore enumName
where
mkToCtorIdx : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let numCtors := info.ctors.length
let declName := Name.mkStr enumName "toCtorIdx"
let enumType := mkConst enumName us
let natType := mkConst ``Nat
let declType ← mkArrow enumType natType
let mut minors := #[]
for i in [:numCtors] do
minors := minors.push <| mkNatLit i
withLocalDeclD `x enumType fun x => do
let motive ← mkLambdaFVars #[x] natType
let declValue ← mkLambdaFVars #[x] <| mkAppN (mkApp2 (mkConst (mkCasesOnName enumName) (levelOne::us)) motive x) minors
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
mkNoConfusionType : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let v ← mkFreshUserName `v
let enumType := mkConst enumName us
let sortV := mkSort (mkLevelParam v)
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
withLocalDeclD `P sortV fun P =>
withLocalDeclD `x enumType fun x =>
withLocalDeclD `y enumType fun y => do
let declType ← mkForallFVars #[P, x, y] sortV
let declValue ← mkLambdaFVars #[P, x, y] (← mkAppM ``noConfusionTypeEnum #[toCtorIdx, P, x, y])
let declName := Name.mkStr enumName "noConfusionType"
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := v :: info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
mkNoConfusion : MetaM Unit := do
let ConstantInfo.inductInfo info ← getConstInfo enumName | unreachable!
let us := info.levelParams.map mkLevelParam
let v ← mkFreshUserName `v
let enumType := mkConst enumName us
let sortV := mkSort (mkLevelParam v)
let toCtorIdx := mkConst (Name.mkStr enumName "toCtorIdx") us
let noConfusionType := mkConst (Name.mkStr enumName "noConfusionType") (mkLevelParam v :: us)
withLocalDecl `P BinderInfo.implicit sortV fun P =>
withLocalDecl `x BinderInfo.implicit enumType fun x =>
withLocalDecl `y BinderInfo.implicit enumType fun y => do
withLocalDeclD `h (← mkEq x y) fun h => do
let declType ← mkForallFVars #[P, x, y, h] (mkApp3 noConfusionType P x y)
let declValue ← mkLambdaFVars #[P, x, y, h] (← mkAppOptM ``noConfusionEnum #[none, none, none, toCtorIdx, P, x, y, h])
let declName := Name.mkStr enumName "noConfusion"
addAndCompile <| Declaration.defnDecl {
name := declName
levelParams := v :: info.levelParams
type := declType
value := declValue
safety := DefinitionSafety.safe
hints := ReducibilityHints.abbrev
}
setReducibleAttribute declName
modifyEnv fun env => markNoConfusion env declName
def mkNoConfusion (declName : Name) : MetaM Unit := do
if (← isEnumType declName) then
mkNoConfusionEnum declName
else
mkNoConfusionCore declName
end Lean

View file

@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Dany Fabian
-/
prelude
import Lean.Meta.Constructions
import Lean.Meta.Constructions.CasesOn
import Lean.Meta.Match.Match
namespace Lean.Meta.IndPredBelow