/- Copyright (c) 2016 Gabriel Ebner. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Gabriel Ebner -/ import .utils open monad expr tactic namespace super -- TODO(gabriel): rewrite using conversions meta def trim : expr → tactic expr | (app (lam n m d b) arg) := if ¬b^.has_var then trim b else lift₂ app (trim (lam n m d b)) (trim arg) | (app a b) := lift₂ app (trim a) (trim b) | (lam n m d b) := do x ← mk_local' `x m d, b' ← trim (instantiate_var b x), return $ lam n m d (abstract_local b' x^.local_uniq_name) | (elet n t v b) := if has_var b then do x ← mk_local_def `x t, b' ← trim (instantiate_var b x), return $ elet n t v (abstract_local b' x^.local_uniq_name) else trim b | e := return e -- iterate trim until convergence meta def trim' : expr → tactic expr | e := do e' ← trim e, if e =ₐ e' then return e else trim' e' open tactic meta def with_trim {α} (tac : tactic α) : tactic α := do gs ← get_goals, match gs with | (g::gs) := do g' ← infer_type g >>= mk_meta_var, set_goals [g'], r ← tac, now, set_goals (g::gs), instantiate_mvars g' >>= trim' >>= exact, return r | [] := fail "no goal" end end super