2015-11-15 21:12:21 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
2015-12-05 02:44:04 +00:00
|
|
|
#include "util/interrupt.h"
|
2015-12-09 03:37:06 +00:00
|
|
|
#include "library/trace.h"
|
2015-11-15 21:12:21 +00:00
|
|
|
#include "library/blast/strategy.h"
|
|
|
|
#include "library/blast/choice_point.h"
|
|
|
|
#include "library/blast/blast.h"
|
|
|
|
#include "library/blast/proof_expr.h"
|
2015-11-18 20:59:53 +00:00
|
|
|
#include "library/blast/trace.h"
|
2015-11-15 21:12:21 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
namespace blast {
|
2015-12-05 21:25:20 +00:00
|
|
|
strategy_fn::strategy_fn() {}
|
2015-11-15 21:12:21 +00:00
|
|
|
|
2015-12-06 00:55:04 +00:00
|
|
|
action_result strategy_fn::activate_hypothesis() {
|
2015-11-23 02:22:26 +00:00
|
|
|
auto hidx = curr_state().select_hypothesis_to_activate();
|
|
|
|
if (!hidx) return action_result::failed();
|
|
|
|
auto r = hypothesis_pre_activation(*hidx);
|
2015-12-09 20:17:51 +00:00
|
|
|
// The pre-activation may delete the hypothesis (e.g., subsumption)
|
|
|
|
if (!solved(r) && !failed(r) && !curr_state().get_hypothesis_decl(*hidx).is_dead()) {
|
2015-11-23 02:22:26 +00:00
|
|
|
curr_state().activate_hypothesis(*hidx);
|
|
|
|
return hypothesis_post_activation(*hidx);
|
|
|
|
} else {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-05 21:25:20 +00:00
|
|
|
action_result strategy_fn::next_branch(expr pr) {
|
2015-12-06 00:55:04 +00:00
|
|
|
while (m_ps_check_point.has_new_proof_steps(curr_state())) {
|
2015-11-15 21:12:21 +00:00
|
|
|
proof_step s = curr_state().top_proof_step();
|
|
|
|
action_result r = s.resolve(unfold_hypotheses_ge(curr_state(), pr));
|
|
|
|
switch (r.get_kind()) {
|
|
|
|
case action_result::Failed:
|
2015-12-09 03:37:06 +00:00
|
|
|
trace_search(">>> next-branch FAILED <<<");
|
2015-11-15 21:12:21 +00:00
|
|
|
return r;
|
|
|
|
case action_result::Solved:
|
|
|
|
pr = r.get_proof();
|
|
|
|
curr_state().pop_proof_step();
|
|
|
|
break;
|
|
|
|
case action_result::NewBranch:
|
|
|
|
return action_result::new_branch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return action_result::solved(pr);
|
|
|
|
}
|
|
|
|
|
2015-12-08 03:31:34 +00:00
|
|
|
bool strategy_fn::show_failure() const {
|
|
|
|
return get_config().m_show_failure;
|
|
|
|
}
|
|
|
|
|
2015-12-06 00:55:04 +00:00
|
|
|
optional<expr> strategy_fn::search() {
|
|
|
|
scope_choice_points scope1;
|
|
|
|
m_ps_check_point = curr_state().mk_proof_steps_check_point();
|
|
|
|
m_init_num_choices = get_num_choice_points();
|
|
|
|
unsigned init_proof_depth = curr_state().get_proof_depth();
|
|
|
|
unsigned max_depth = get_config().m_max_depth;
|
2015-12-10 01:13:28 +00:00
|
|
|
lean_trace_search(tout() << "begin '" << get_name() << "' strategy (max-depth: " << max_depth << ")\n";);
|
2015-11-19 03:12:29 +00:00
|
|
|
trace_curr_state();
|
2015-12-09 15:34:15 +00:00
|
|
|
trace_target();
|
2015-11-15 21:12:21 +00:00
|
|
|
action_result r = next_action();
|
2015-11-19 03:12:29 +00:00
|
|
|
trace_curr_state_if(r);
|
2015-11-15 21:12:21 +00:00
|
|
|
while (true) {
|
2015-12-05 02:44:04 +00:00
|
|
|
check_system("blast");
|
2015-11-15 21:12:21 +00:00
|
|
|
lean_assert(curr_state().check_invariant());
|
2015-12-06 00:55:04 +00:00
|
|
|
if (curr_state().get_proof_depth() > max_depth) {
|
2015-12-09 03:37:06 +00:00
|
|
|
trace_search(">>> maximum search depth reached <<<");
|
2015-11-15 21:12:21 +00:00
|
|
|
r = action_result::failed();
|
|
|
|
}
|
|
|
|
switch (r.get_kind()) {
|
|
|
|
case action_result::Failed:
|
2015-12-10 01:45:36 +00:00
|
|
|
lean_trace_deadend(tout() << "strategy '" << get_name() << "'\n"; curr_state().display(tout()););
|
2015-11-15 21:12:21 +00:00
|
|
|
r = next_choice_point(m_init_num_choices);
|
|
|
|
if (failed(r)) {
|
|
|
|
// all choice points failed...
|
2015-12-10 01:13:28 +00:00
|
|
|
lean_trace_search(tout() << "strategy '" << get_name() << "' failed, no proof found\n";);
|
2015-12-30 01:08:33 +00:00
|
|
|
if (show_failure()) {
|
|
|
|
display_at_buffer(sstream() << "strategy '" << get_name() << "' failed, no proof found, final state:\n");
|
|
|
|
display_curr_state_at_buffer();
|
|
|
|
}
|
2015-11-15 21:12:21 +00:00
|
|
|
return none_expr();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case action_result::Solved:
|
|
|
|
r = next_branch(r.get_proof());
|
|
|
|
if (r.get_kind() == action_result::Solved) {
|
|
|
|
// all branches have been solved
|
2015-12-10 01:13:28 +00:00
|
|
|
lean_trace_search(tout() << "strategy '" << get_name() << "' succeeded, proof found\n";);
|
2015-12-06 00:55:04 +00:00
|
|
|
return some_expr(unfold_hypotheses_ge(curr_state(), r.get_proof(), init_proof_depth));
|
2015-11-15 21:12:21 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case action_result::NewBranch:
|
|
|
|
r = next_action();
|
|
|
|
break;
|
|
|
|
}
|
2015-12-09 16:04:02 +00:00
|
|
|
trace_depth_nchoices();
|
2015-11-19 03:12:29 +00:00
|
|
|
trace_curr_state_if(r);
|
2015-12-09 15:34:15 +00:00
|
|
|
trace_target();
|
2015-11-15 21:12:21 +00:00
|
|
|
}
|
|
|
|
}
|
2015-12-06 22:12:44 +00:00
|
|
|
|
2015-12-06 22:33:21 +00:00
|
|
|
strategy operator||(strategy const & s1, strategy const & s2) {
|
|
|
|
return [=]() { // NOLINT
|
2015-12-06 22:12:44 +00:00
|
|
|
if (auto r = s1())
|
|
|
|
return r;
|
|
|
|
else
|
|
|
|
return s2();
|
2015-12-06 22:33:21 +00:00
|
|
|
};
|
2015-12-06 22:12:44 +00:00
|
|
|
}
|
2015-11-15 21:12:21 +00:00
|
|
|
}}
|