parent
412f03b08b
commit
5d95cb0979
4 changed files with 57 additions and 1 deletions
|
@ -5,14 +5,25 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "kernel/type_checker.h"
|
||||
#include "kernel/for_each_fn.h"
|
||||
#include "kernel/error_msgs.h"
|
||||
#include "library/util.h"
|
||||
#include "library/constants.h"
|
||||
#include "library/reducible.h"
|
||||
#include "library/tactic/tactic.h"
|
||||
#include "library/tactic/elaborate.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
|
||||
namespace lean {
|
||||
// Return true iff \c e is of the form (?m l_1 ... l_n), where ?m is a metavariable and l_i's local constants
|
||||
bool is_meta_placeholder(expr const & e) {
|
||||
if (!is_meta(e))
|
||||
return false;
|
||||
buffer<expr> args;
|
||||
get_app_args(e, args);
|
||||
return std::all_of(args.begin(), args.end(), is_local);
|
||||
}
|
||||
|
||||
tactic exact_tactic(elaborate_fn const & elab, expr const & e, bool enforce_type_during_elaboration, bool allow_metavars) {
|
||||
return tactic01([=](environment const & env, io_state const & ios, proof_state const & s) {
|
||||
proof_state new_s = s;
|
||||
|
@ -39,7 +50,24 @@ tactic exact_tactic(elaborate_fn const & elab, expr const & e, bool enforce_type
|
|||
}
|
||||
substitution subst = new_s.get_subst();
|
||||
assign(subst, g, *new_e);
|
||||
return some(proof_state(new_s, tail(gs), subst));
|
||||
if (allow_metavars) {
|
||||
buffer<goal> new_goals;
|
||||
name_generator ngen = new_s.get_ngen();
|
||||
auto tc = mk_type_checker(env, ngen.mk_child(), new_s.relax_main_opaque());
|
||||
for_each(*new_e, [&](expr const & m, unsigned) {
|
||||
if (!has_expr_metavar(m))
|
||||
return false;
|
||||
if (is_meta_placeholder(m)) {
|
||||
new_goals.push_back(goal(m, tc->infer(m).first));
|
||||
return false;
|
||||
}
|
||||
return !is_metavar(m) && !is_local(m);
|
||||
});
|
||||
goals new_gs = to_list(new_goals.begin(), new_goals.end(), tail(gs));
|
||||
return some(proof_state(new_s, new_gs, subst, ngen));
|
||||
} else {
|
||||
return some(proof_state(new_s, tail(gs), subst));
|
||||
}
|
||||
} else {
|
||||
return some_proof_state(new_s);
|
||||
}
|
||||
|
|
6
tests/lean/run/refine1.lean
Normal file
6
tests/lean/run/refine1.lean
Normal file
|
@ -0,0 +1,6 @@
|
|||
example (a b : Prop) : a → b → a ∧ b :=
|
||||
begin
|
||||
intros [Ha, Hb],
|
||||
refine (and.intro _ Hb),
|
||||
exact Ha
|
||||
end
|
8
tests/lean/run/refine2.lean
Normal file
8
tests/lean/run/refine2.lean
Normal file
|
@ -0,0 +1,8 @@
|
|||
import logic
|
||||
|
||||
example {A : Type} (f : A → A) (a b : A) : f a = b → f (f a) = f b :=
|
||||
begin
|
||||
intro fa_eq_b,
|
||||
refine (congr_arg f _),
|
||||
exact fa_eq_b
|
||||
end
|
14
tests/lean/run/refine3.lean
Normal file
14
tests/lean/run/refine3.lean
Normal file
|
@ -0,0 +1,14 @@
|
|||
import data.nat.basic
|
||||
open nat
|
||||
|
||||
theorem zero_left (n : ℕ) : 0 + n = n :=
|
||||
nat.induction_on n
|
||||
!add_zero
|
||||
(take m IH,
|
||||
begin
|
||||
refine
|
||||
(calc
|
||||
0 + succ m = succ (0 + m) : _
|
||||
... = succ m : IH),
|
||||
esimp
|
||||
end)
|
Loading…
Reference in a new issue