I kept a few core methods (e.g., exact_core and apply_core). Reason:
if we use default parameters
meta constant exact (e : expr) (md := semireducible) : tactic unit
then, we will not be able to write
to_expr p >>= exact
The workaround is
do t <- to_expr p, exact t
or
to_expr p >>= (fun x, exact x)
One alternative is to change how we handle default parameters, and
eta-expand applications that involve default parameters.
We may also have an attribute [eta_expand]. Then
attribute [eta_expand] foo
instructs the elaborator to automatically eta-expand foo-applications.
The attribute would give users more control, and avoid potential
performance problems. Without the attribute, then for every function
application the elaborator has to check the type and decide whether it
must be eta-expanded or not.
@gebner @kha What do you think?
44 lines
1.5 KiB
Text
44 lines
1.5 KiB
Text
/-
|
||
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import init.meta.tactic init.function
|
||
|
||
namespace tactic
|
||
open expr
|
||
|
||
private meta def relation_tactic (md : transparency) (op_for : environment → name → option name) (tac_name : string) : tactic unit :=
|
||
do tgt ← target,
|
||
env ← get_env,
|
||
r ← return $ get_app_fn tgt,
|
||
match (op_for env (const_name r)) with
|
||
| (some refl) := do r ← mk_const refl, apply_core r {md := md} >> return ()
|
||
| none := fail $ tac_name ++ " tactic failed, target is not a relation application with the expected property."
|
||
end
|
||
|
||
meta def reflexivity (md := semireducible) : tactic unit :=
|
||
relation_tactic md environment.refl_for "reflexivity"
|
||
|
||
meta def symmetry (md := semireducible) : tactic unit :=
|
||
relation_tactic md environment.symm_for "symmetry"
|
||
|
||
meta def transitivity (md := semireducible) : tactic unit :=
|
||
relation_tactic md environment.trans_for "transitivity"
|
||
|
||
meta def relation_lhs_rhs : expr → tactic (name × expr × expr) :=
|
||
λ e, do
|
||
(const c _) ← return e^.get_app_fn,
|
||
env ← get_env,
|
||
(some (arity, lhs_pos, rhs_pos)) ← return $ env^.relation_info c,
|
||
args ← return $ get_app_args e,
|
||
guard (args^.length = arity),
|
||
(some lhs) ← return $ args^.nth lhs_pos,
|
||
(some rhs) ← return $ args^.nth rhs_pos,
|
||
return (c, lhs, rhs)
|
||
|
||
meta def target_lhs_rhs : tactic (name × expr × expr) :=
|
||
target >>= relation_lhs_rhs
|
||
|
||
end tactic
|