Last active
February 6, 2023 17:35
-
-
Save fpvandoorn/9d21b9530e22bb49ca4adc23484f8402 to your computer and use it in GitHub Desktop.
Errors on commit 4d0921d2 of mathlib4
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
import Mathlib.Init.Data.Nat.Notation | |
import Mathlib.Lean.Message | |
import Mathlib.Lean.Expr.Basic | |
import Mathlib.Data.String.Defs | |
import Mathlib.Tactic.Simps.NotationClass | |
open Lean Elab Parser Command | |
open Meta hiding Config | |
open Elab.Term hiding mkConst | |
def updateName (nm : Name) (s : String) (isPrefix : Bool) : Name := | |
nm.updateLast fun s' ↦ if isPrefix then s ++ "_" ++ s' else s' ++ "_" ++ s | |
namespace Lean.Meta | |
open Tactic Simp | |
def mkSimpContextResult (cfg : Meta.Simp.Config := {}) (simpOnly := false) (kind := SimpKind.simp) | |
(dischargeWrapper := DischargeWrapper.default) (hasStar := false) : | |
MetaM MkSimpContextResult := do | |
match dischargeWrapper with | |
| .default => pure () | |
| _ => | |
if kind == SimpKind.simpAll then | |
throwError "'simp_all' tactic does not support 'discharger' option" | |
if kind == SimpKind.dsimp then | |
throwError "'dsimp' tactic does not support 'discharger' option" | |
let simpTheorems ← if simpOnly then | |
simpOnlyBuiltins.foldlM (·.addConst ·) ({} : SimpTheorems) | |
else | |
getSimpTheorems | |
let congrTheorems ← getSimpCongrTheorems | |
let ctx : Simp.Context := { | |
config := cfg | |
simpTheorems := #[simpTheorems], congrTheorems | |
} | |
if !hasStar then | |
return { ctx, dischargeWrapper } | |
else | |
let mut simpTheorems := ctx.simpTheorems | |
let hs ← getPropHyps | |
for h in hs do | |
unless simpTheorems.isErased (.fvar h) do | |
simpTheorems ← simpTheorems.addTheorem (.fvar h) (← h.getDecl).toExpr | |
let ctx := { ctx with simpTheorems } | |
return { ctx, dischargeWrapper } | |
def mkSimpContext (cfg : Meta.Simp.Config := {}) (simpOnly := false) (kind := SimpKind.simp) | |
(dischargeWrapper := DischargeWrapper.default) (hasStar := false) : | |
MetaM Simp.Context := do | |
let data ← mkSimpContextResult cfg simpOnly kind dischargeWrapper hasStar | |
return data.ctx | |
end Lean.Meta | |
def hasSimpAttribute (env : Environment) (declName : Name) : Bool := | |
simpExtension.getState env |>.lemmaNames.contains <| .decl declName | |
namespace Lean.Parser | |
namespace Attr | |
attribute [notation_class] Add | |
syntax simpsArgsRest := (Tactic.config)? (ppSpace ident)* | |
syntax (name := simps) "simps" "?"? simpsArgsRest : attr | |
macro "simps?" rest:simpsArgsRest : attr => `(attr| simps ? $rest) | |
end Attr | |
namespace Command | |
syntax simpsRule.rename := ident " → " ident | |
syntax simpsRule.erase := "-" ident | |
syntax simpsRule.add := "+" ident | |
syntax simpsRule.prefix := &"as_prefix" ident | |
syntax simpsRule := simpsRule.prefix <|> simpsRule.rename <|> simpsRule.erase <|> simpsRule.add | |
syntax simpsProj := (ppSpace ident (" (" simpsRule,+ ")")?) | |
syntax (name := initialize_simps_projections) | |
"initialize_simps_projections" "?"? simpsProj : command | |
macro "initialize_simps_projections?" rest:simpsProj : command => | |
`(initialize_simps_projections ? $rest) | |
end Command | |
end Lean.Parser | |
initialize registerTraceClass `simps.verbose | |
initialize registerTraceClass `simps.debug | |
namespace Simps | |
structure UnusedStructure where | |
name : Name | |
expr : Expr | |
projNrs : List ℕ | |
isDefault : Bool | |
isPrefix : Bool | |
deriving Inhabited | |
instance : ToMessageData UnusedStructure where toMessageData | |
| ⟨a, b, c, d, e⟩ => .group <| .nest 1 <| | |
"⟨" ++ .joinSep [toMessageData a, toMessageData b, toMessageData c, toMessageData d, | |
toMessageData e] ("," ++ Format.line) ++ "⟩" | |
initialize structureExt : NameMapExtension (List Name × Array UnusedStructure) ← | |
registerNameMapExtension (List Name × Array UnusedStructure) | |
structure ParsedProjectionData where | |
origName : Name × Syntax | |
newName : Name × Syntax | |
isDefault : Bool := true | |
isPrefix : Bool := false | |
expr? : Option Expr := none | |
projNrs : Array Nat := #[] | |
isCustom : Bool := false | |
def ParsedProjectionData.toUnusedStructure (p : ParsedProjectionData) : UnusedStructure := | |
{ p with name := p.newName.1, expr := p.expr?.getD default, projNrs := p.projNrs.toList } | |
instance : ToMessageData ParsedProjectionData where toMessageData | |
| ⟨x₁, x₂, x₃, x₄, x₅, x₆, x₇⟩ => .group <| .nest 1 <| | |
"⟨" ++ .joinSep [toMessageData x₁, toMessageData x₂, toMessageData x₃, toMessageData x₄, | |
toMessageData x₅, toMessageData x₆, toMessageData x₇] | |
("," ++ Format.line) ++ "⟩" | |
inductive ProjectionRule where | |
| rename (oldName : Name) (oldStx : Syntax) (newName : Name) (newStx : Syntax) : | |
ProjectionRule | |
| add : Name → Syntax → ProjectionRule | |
| erase : Name → Syntax → ProjectionRule | |
| prefix : Name → Syntax → ProjectionRule | |
instance : ToMessageData ProjectionRule where toMessageData | |
| .rename x₁ x₂ x₃ x₄ => .group <| .nest 1 <| | |
"rename ⟨" ++ .joinSep [toMessageData x₁, toMessageData x₂, toMessageData x₃, toMessageData x₄] | |
("," ++ Format.line) ++ "⟩" | |
| .add x₁ x₂ => .group <| .nest 1 <| | |
"+⟨" ++ .joinSep [toMessageData x₁, toMessageData x₂] ("," ++ Format.line) ++ "⟩" | |
| .erase x₁ x₂ => .group <| .nest 1 <| | |
"-⟨" ++ .joinSep [toMessageData x₁, toMessageData x₂] ("," ++ Format.line) ++ "⟩" | |
| .prefix x₁ x₂ => .group <| .nest 1 <| | |
"prefix ⟨" ++ .joinSep [toMessageData x₁, toMessageData x₂] ("," ++ Format.line) ++ "⟩" | |
def projectionsInfo (l : List UnusedStructure) (pref : String) (str : Name) : MessageData := | |
let ⟨defaults, nondefaults⟩ := l.partition (·.isDefault) | |
let toPrint : List MessageData := | |
defaults.map fun s ↦ | |
let prefixStr := if s.isPrefix then "(prefix) " else "" | |
m!"Projection {prefixStr}{s.name}: {s.expr}" | |
let print2 : MessageData := | |
String.join <| (nondefaults.map fun nm : UnusedStructure ↦ toString nm.1).intersperse ", " | |
let toPrint := | |
toPrint ++ | |
if nondefaults.isEmpty then [] else | |
[("No lemmas are generated for the projections: " : MessageData) ++ print2 ++ "."] | |
let toPrint := MessageData.joinSep toPrint ("\n" : MessageData) | |
m! "{pref} {str}:\n{toPrint}" | |
def findProjectionIndices (strName projName : Name) : MetaM (List ℕ) := do | |
let env ← getEnv | |
let .some baseStr := findField? env strName projName | | |
throwError "{strName} has no field {projName} in parent structure" | |
let .some fullProjName := getProjFnForField? env baseStr projName | | |
throwError "no such field {projName}" | |
let .some pathToField := getPathToBaseStructure? env baseStr strName | | |
throwError "no such field {projName}" | |
let allProjs := pathToField ++ [fullProjName] | |
return allProjs.map (env.getProjectionFnInfo? · |>.get!.i) | |
partial def getCompositeOfProjectionsAux (stx : Syntax) | |
(proj : String) (e : Expr) (pos : Array ℕ) (args : Array Expr) : MetaM (Expr × Array ℕ) := do | |
dbg_trace s!"1" | |
let env ← getEnv | |
let .const structName _ := (← whnf (←inferType e)).getAppFn | | |
throwError "{e} doesn't have a structure as type" | |
dbg_trace s!"2 {structName}" | |
let projs := getStructureFieldsFlattened env structName | |
dbg_trace s!"3 {projs.size}" | |
let projInfo := projs.toList.map fun p ↦ do | |
(← ("_" ++ p.getString).isPrefixOf? proj, p) | |
dbg_trace s!"4 {projInfo.length} {projInfo}" | |
let some (projRest, projName) := projInfo.reduceOption.getLast? | | |
throwError "Failed to find constructor {proj.drop 1} in structure {structName}." | |
dbg_trace "z" | |
let newE ← mkProjection e projName | |
dbg_trace "4" | |
let newPos := pos ++ (← findProjectionIndices structName projName) | |
if projRest.isEmpty then | |
let newE ← mkLambdaFVars args newE | |
if !stx.isMissing then | |
_ ← TermElabM.run' <| addTermInfo stx newE | |
return (newE, newPos) | |
let type ← inferType newE | |
forallTelescopeReducing type fun typeArgs _tgt ↦ do | |
getCompositeOfProjectionsAux stx projRest (mkAppN newE typeArgs) newPos (args ++ typeArgs) | |
def mkParsedProjectionData (structName : Name) : CoreM (Array ParsedProjectionData) := do | |
let env ← getEnv | |
let projs := getStructureFields env structName | |
if projs.size == 0 then | |
throwError "Declaration {structName} is not a structure." | |
let projData := projs.map fun fieldName ↦ { | |
origName := (fieldName, .missing), newName := (fieldName, .missing), | |
isDefault := isSubobjectField? env structName fieldName |>.isNone } | |
let parentProjs := getStructureFieldsFlattened env structName false | |
let parentProjs := parentProjs.filter (!projs.contains ·) | |
let parentProjData := parentProjs.map fun nm ↦ | |
{origName := (nm, .missing), newName := (nm, .missing)} | |
return projData ++ parentProjData | |
set_option linter.missingDocs false | |
/-! the crash seems to only appear -/ | |
/-! if there are exactly two such documentation sections -/ | |
/-- Execute the projection renamings (and turning off projections) as specified by `rules`. -/ | |
def applyProjectionRules (projs : Array ParsedProjectionData) (rules : Array ProjectionRule) : | |
CoreM (Array ParsedProjectionData) := do | |
let projs : Array ParsedProjectionData := rules.foldl (init := projs) fun projs rule ↦ | |
match rule with | |
| .rename oldName oldStx newName newStx => | |
dbg_trace s!"{oldName} {oldStx} {newName} {newStx}" | |
if (projs.map (·.newName.1)).contains oldName then | |
projs.map fun proj ↦ if proj.newName.1 == oldName then | |
{ proj with | |
newName := (newName, newStx), | |
origName.2 := if proj.origName.2.isMissing then oldStx else proj.origName.2 } | |
else | |
proj | |
else | |
projs.push {origName := (oldName, oldStx), newName := (newName, newStx)} | |
| _ => projs | |
pure projs | |
#eval liftCoreM <| do | |
_ ← applyProjectionRules #[{origName := (`val, .missing), newName := (`val, .missing)}] | |
#[.rename `val .missing `coe .missing] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment