lean4-htt/src/Lean/Meta/Tactic/Revert.lean
2022-03-09 11:27:58 -08:00

45 lines
1.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Meta.Tactic.Clear
namespace Lean.Meta
def revert (mvarId : MVarId) (fvarIds : Array FVarId) (preserveOrder : Bool := false) : MetaM (Array FVarId × MVarId) := do
if fvarIds.isEmpty then
pure (#[], mvarId)
else withMVarContext mvarId do
checkNotAssigned mvarId `revert
for fvarId in fvarIds do
if (← getLocalDecl fvarId) |>.isAuxDecl then
throwError "failed to revert {mkFVar fvarId}, it is an auxiliary declaration created to represent recursive definitions"
let fvars := fvarIds.map mkFVar
match MetavarContext.MkBinding.collectForwardDeps (← getMCtx) (← getLCtx) fvars preserveOrder with
| Except.error _ => throwError "failed to revert variables {fvars}"
| Except.ok toRevert =>
/- We should clear any `auxDecl` in `toRevert` -/
let mut mvarId := mvarId
let mut toRevertNew := #[]
for x in toRevert do
if (← getLocalDecl x.fvarId!) |>.isAuxDecl then
mvarId ← clear mvarId x.fvarId!
else
toRevertNew := toRevertNew.push x
let tag ← getMVarTag mvarId
-- TODO: the following code can be optimized because `MetavarContext.revert` will compute `collectDeps` again.
-- We should factor out the relevat part
-- Set metavariable kind to natural to make sure `revert` will assign it.
setMVarKind mvarId MetavarKind.natural
let (e, toRevert) ←
try
liftMkBindingM <| MetavarContext.revert toRevertNew mvarId preserveOrder
finally
setMVarKind mvarId MetavarKind.syntheticOpaque
let mvar := e.getAppFn
setMVarTag mvar.mvarId! tag
return (toRevert.map Expr.fvarId!, mvar.mvarId!)
end Lean.Meta