| import Lean.Elab |
| import Lean.Meta |
|
|
| open Lean |
|
|
| namespace Pantograph.Tactic |
|
|
| / |
| def assign (goal: MVarId) (expr: Expr) (nextGoals: List MVarId): MetaM (List MVarId) := do |
| goal.checkNotAssigned `Pantograph.Tactic.assign |
|
|
| |
| let exprType β Meta.inferType expr |
| let goalType β goal.getType |
| unless β Meta.isDefEq goalType exprType do |
| throwError s!"{β Meta.ppExpr expr} : {β Meta.ppExpr exprType} β {β Meta.ppExpr goalType}" |
| goal.assign expr |
| nextGoals.filterM (not <$> Β·.isAssigned) |
|
|
| def evalAssign : Elab.Tactic.Tactic := fun stx => Elab.Tactic.withMainContext do |
| let target β Elab.Tactic.getMainTarget |
| let goal β Elab.Tactic.getMainGoal |
| goal.checkNotAssigned `Pantograph.Tactic.evalAssign |
| let (expr, nextGoals) β Elab.Tactic.elabTermWithHoles stx |
| (expectedType? := .some target) |
| (tagSuffix := .anonymous ) |
| (allowNaturalHoles := true) |
| goal.assign expr |
| Elab.Tactic.replaceMainGoal nextGoals |
|
|
| / |
| types of the sorrys. -/ |
| def sorryToHole (src : Expr) (post : Expr β MetaM Expr := pure) |
| : StateRefT (List MVarId) MetaM Expr := |
| Meta.transform src Ξ» expr => |
| if expr.isSorry then do |
| let type β instantiateMVars (expr.getArg! 0 |>.bindingBody!) |
| if type.hasSorry then |
| throwError s!"Coupling is not allowed in draft tactic: {β Meta.ppExpr type}" |
| let type β post type |
| let mvar β Meta.mkFreshExprSyntheticOpaqueMVar type |
| modify (mvar.mvarId! :: .) |
| return .done mvar |
| else |
| return .continue |
|
|
| |
| def draft (goal : MVarId) (expr : Expr) : MetaM (List MVarId) := do |
| goal.checkNotAssigned `Pantograph.Tactic.draft |
| let exprType β Meta.inferType expr |
| let goalType β goal.getType |
| unless β Meta.isDefEq goalType exprType do |
| throwError s!"{β Meta.ppExpr expr} : {β Meta.ppExpr exprType} β {β Meta.ppExpr goalType}" |
|
|
| let (expr', holes) β sorryToHole expr |>.run [] |
| goal.assign expr' |
| return holes.reverse |
|
|
| def evalDraft : Elab.Tactic.Tactic := fun stx β¦ Elab.Tactic.withMainContext do |
| let target β Elab.Tactic.getMainTarget |
| let goal β Elab.Tactic.getMainGoal |
| let (expr, holeGoals) β Elab.Tactic.elabTermWithHoles stx |
| (expectedType? := .some target) |
| (tagSuffix := .anonymous) |
| (allowNaturalHoles := true) |
| let draftGoals β draft goal expr |
| Elab.Tactic.replaceMainGoal $ holeGoals ++ draftGoals |
|
|
|
|
| end Pantograph.Tactic |
|
|