feat: add applyMatchSplitter
It applies the match splitter without using simplification theorems
This commit is contained in:
parent
c795a75045
commit
2775298fef
1 changed files with 16 additions and 10 deletions
|
|
@ -74,23 +74,22 @@ private def generalizeMatchDiscrs (mvarId : MVarId) (discrs : Array Expr) : Meta
|
|||
let (fvarIds, mvarId) ← generalize mvarId args
|
||||
return (fvarIds[:discrs.size], mvarId)
|
||||
|
||||
def splitMatch (mvarId : MVarId) (e : Expr) : MetaM (List MVarId) := do
|
||||
let some app ← matchMatcherApp? e | throwError "match application expected"
|
||||
let (discrFVarIds, mvarId) ← generalizeMatchDiscrs mvarId app.discrs
|
||||
trace[Meta.debug] "split [1]:\n{MessageData.ofGoal mvarId}"
|
||||
def applyMatchSplitter (mvarId : MVarId) (matcherDeclName : Name) (us : Array Level) (params : Array Expr) (discrs : Array Expr) : MetaM (List MVarId) := do
|
||||
let (discrFVarIds, mvarId) ← generalizeMatchDiscrs mvarId discrs
|
||||
let (reverted, mvarId) ← revert mvarId discrFVarIds (preserveOrder := true)
|
||||
let (discrFVarIds, mvarId) ← introNP mvarId discrFVarIds.size
|
||||
let numExtra := reverted.size - discrFVarIds.size
|
||||
let discrs := discrFVarIds.map mkFVar
|
||||
let matchEqns ← Match.getEquationsFor app.matcherName
|
||||
let some info ← getMatcherInfo? matcherDeclName | throwError "'applyMatchSplitter' failed, '{matcherDeclName}' is not a 'match' auxiliary declaration."
|
||||
let matchEqns ← Match.getEquationsFor matcherDeclName
|
||||
withMVarContext mvarId do
|
||||
let motive ← mkLambdaFVars discrs (← getMVarType mvarId)
|
||||
-- Fix universe
|
||||
let mut us := app.matcherLevels
|
||||
if let some uElimPos := app.uElimPos? then
|
||||
let mut us := us
|
||||
if let some uElimPos := info.uElimPos? then
|
||||
-- Set universe elimination level to zero (Prop).
|
||||
us := us.set! uElimPos levelZero
|
||||
let splitter := mkAppN (mkConst matchEqns.splitterName us.toList) app.params
|
||||
let splitter := mkAppN (mkConst matchEqns.splitterName us.toList) params
|
||||
let splitter := mkAppN (mkApp splitter motive) discrs
|
||||
check splitter -- TODO
|
||||
let mvarIds ← apply mvarId splitter
|
||||
|
|
@ -98,11 +97,18 @@ def splitMatch (mvarId : MVarId) (e : Expr) : MetaM (List MVarId) := do
|
|||
let numParams := matchEqns.splitterAltNumParams[i]
|
||||
let (_, mvarId) ← introN mvarId numParams
|
||||
let (_, mvarId) ← introNP mvarId numExtra
|
||||
trace[Meta.debug] "before simpMatch:\n{MessageData.ofGoal mvarId}"
|
||||
let mvarId ← simpMatchTargetCore mvarId app.matcherName matchEqns.eqnNames[i]
|
||||
return (i+1, mvarId::mvarIds)
|
||||
return mvarIds.reverse
|
||||
|
||||
def splitMatch (mvarId : MVarId) (e : Expr) : MetaM (List MVarId) := do
|
||||
let some app ← matchMatcherApp? e | throwError "match application expected"
|
||||
let matchEqns ← Match.getEquationsFor app.matcherName
|
||||
let mvarIds ← applyMatchSplitter mvarId app.matcherName app.matcherLevels app.params app.discrs
|
||||
let (_, mvarIds) ← mvarIds.foldlM (init := (0, [])) fun (i, mvarIds) mvarId => do
|
||||
let mvarId ← simpMatchTargetCore mvarId app.matcherName matchEqns.eqnNames[i]
|
||||
return (i+1, mvarId::mvarIds)
|
||||
return mvarIds.reverse
|
||||
|
||||
/-- Return an `if-then-else` or `match-expr` to split. -/
|
||||
partial def findSplit? (env : Environment) (e : Expr) : Option Expr :=
|
||||
if let some target := e.find? isCandidate then
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue