2015-11-10 19:44:18 +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
|
|
|
|
*/
|
|
|
|
#include "library/blast/blast.h"
|
|
|
|
#include "library/blast/options.h"
|
|
|
|
#include "library/blast/choice_point.h"
|
2015-11-11 08:02:47 +00:00
|
|
|
#include "library/blast/simple_actions.h"
|
2015-11-13 23:21:26 +00:00
|
|
|
#include "library/blast/proof_expr.h"
|
2015-11-10 19:44:18 +00:00
|
|
|
#include "library/blast/intros.h"
|
2015-11-13 23:21:26 +00:00
|
|
|
#include "library/blast/subst.h"
|
2015-11-11 00:57:57 +00:00
|
|
|
#include "library/blast/backward.h"
|
2015-11-10 19:44:18 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
namespace blast {
|
|
|
|
/** \brief Implement a simple proof strategy for blast.
|
|
|
|
We use it mainly for testing new actions and the whole blast infra-structure. */
|
|
|
|
class simple_strategy {
|
2015-11-13 21:05:20 +00:00
|
|
|
config m_config;
|
2015-11-10 19:44:18 +00:00
|
|
|
|
|
|
|
enum status { NoAction, ClosedBranch, Continue };
|
|
|
|
|
2015-11-13 21:05:20 +00:00
|
|
|
void display_msg(char const * msg) {
|
|
|
|
ios().get_diagnostic_channel() << msg << "\n\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void display_action(char const * name) {
|
|
|
|
if (m_config.m_trace) {
|
|
|
|
ios().get_diagnostic_channel() << "== action: " << name << " ==>\n\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void display() {
|
|
|
|
if (m_config.m_trace) {
|
|
|
|
auto out = diagnostic(env(), ios());
|
|
|
|
out << "state [" << curr_state().get_proof_depth() << "], #choice: " << get_num_choice_points() << "\n";
|
|
|
|
display_curr_state();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void display_if(action_result r) {
|
|
|
|
if (m_config.m_trace && !failed(r))
|
|
|
|
display();
|
|
|
|
}
|
|
|
|
|
2015-11-11 08:02:47 +00:00
|
|
|
optional<hypothesis_idx> activate_hypothesis() {
|
2015-11-10 19:44:18 +00:00
|
|
|
return curr_state().activate_hypothesis();
|
|
|
|
}
|
|
|
|
|
2015-11-11 00:57:57 +00:00
|
|
|
action_result next_action() {
|
2015-11-13 21:05:20 +00:00
|
|
|
if (intros_action()) {
|
|
|
|
display_action("intros");
|
2015-11-11 00:57:57 +00:00
|
|
|
return action_result::new_branch();
|
2015-11-13 21:05:20 +00:00
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
|
2015-11-11 08:02:47 +00:00
|
|
|
if (auto hidx = activate_hypothesis()) {
|
2015-11-13 21:05:20 +00:00
|
|
|
display_action("activate");
|
|
|
|
if (auto pr = assumption_contradiction_actions(*hidx)) {
|
|
|
|
display_action("assumption-contradiction");
|
2015-11-11 08:02:47 +00:00
|
|
|
return action_result::solved(*pr);
|
2015-11-13 21:05:20 +00:00
|
|
|
}
|
2015-11-13 23:21:26 +00:00
|
|
|
if (subst_action(*hidx)) {
|
|
|
|
display_action("subst");
|
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
return action_result::new_branch();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto pr = assumption_action()) {
|
2015-11-11 08:02:47 +00:00
|
|
|
// Remark: this action is only relevant
|
|
|
|
// when the target has been modified.
|
2015-11-13 21:05:20 +00:00
|
|
|
display_action("assumption");
|
2015-11-11 00:57:57 +00:00
|
|
|
return action_result::solved(*pr);
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
|
|
|
|
action_result r = constructor_action();
|
2015-11-13 21:05:20 +00:00
|
|
|
if (!failed(r)) {
|
|
|
|
display_action("constructor");
|
|
|
|
return r;
|
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
|
|
|
|
// TODO(Leo): add more actions...
|
2015-11-13 21:05:20 +00:00
|
|
|
|
|
|
|
display_msg(">>> FAILED <<<");
|
2015-11-11 00:57:57 +00:00
|
|
|
return action_result::failed();
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-11 00:57:57 +00:00
|
|
|
action_result next_branch(expr pr) {
|
2015-11-10 19:44:18 +00:00
|
|
|
while (curr_state().has_proof_steps()) {
|
2015-11-11 00:57:57 +00:00
|
|
|
proof_step s = curr_state().top_proof_step();
|
2015-11-13 23:21:26 +00:00
|
|
|
action_result r = s.resolve(unfold_hypotheses_ge(curr_state(), pr));
|
2015-11-11 00:57:57 +00:00
|
|
|
switch (r.get_kind()) {
|
|
|
|
case action_result::Failed:
|
2015-11-13 21:05:20 +00:00
|
|
|
display_msg(">>> next-branch FAILED <<<");
|
2015-11-11 00:57:57 +00:00
|
|
|
return r;
|
|
|
|
case action_result::Solved:
|
|
|
|
pr = r.get_proof();
|
2015-11-10 19:44:18 +00:00
|
|
|
curr_state().pop_proof_step();
|
2015-11-11 00:57:57 +00:00
|
|
|
break;
|
|
|
|
case action_result::NewBranch:
|
|
|
|
return action_result::new_branch();
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
return action_result::solved(pr);
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
optional<expr> search_upto(unsigned depth) {
|
2015-11-13 21:05:20 +00:00
|
|
|
if (m_config.m_trace) {
|
|
|
|
ios().get_diagnostic_channel() << "* Search upto depth " << depth << "\n\n";
|
|
|
|
}
|
|
|
|
display();
|
2015-11-11 00:57:57 +00:00
|
|
|
action_result r = next_action();
|
2015-11-13 21:05:20 +00:00
|
|
|
display_if(r);
|
2015-11-10 19:44:18 +00:00
|
|
|
while (true) {
|
2015-11-13 18:38:25 +00:00
|
|
|
lean_assert(curr_state().check_invariant());
|
2015-11-13 21:05:20 +00:00
|
|
|
if (curr_state().get_proof_depth() > depth) {
|
|
|
|
display_msg(">>> maximum search depth reached <<<");
|
2015-11-11 00:57:57 +00:00
|
|
|
r = action_result::failed();
|
2015-11-13 21:05:20 +00:00
|
|
|
}
|
2015-11-11 00:57:57 +00:00
|
|
|
switch (r.get_kind()) {
|
|
|
|
case action_result::Failed:
|
|
|
|
r = next_choice_point();
|
|
|
|
if (failed(r)) {
|
|
|
|
// all choice points failed...
|
2015-11-13 21:05:20 +00:00
|
|
|
display_msg(">>> proof not found, no choice points left <<<");
|
2015-11-10 19:44:18 +00:00
|
|
|
return none_expr();
|
|
|
|
}
|
2015-11-13 21:05:20 +00:00
|
|
|
display_msg("* next choice point");
|
2015-11-10 19:44:18 +00:00
|
|
|
break;
|
2015-11-11 00:57:57 +00:00
|
|
|
case action_result::Solved:
|
|
|
|
r = next_branch(r.get_proof());
|
|
|
|
if (r.get_kind() == action_result::Solved) {
|
|
|
|
// all branches have been solved
|
2015-11-13 21:05:20 +00:00
|
|
|
display_msg("* found proof");
|
2015-11-11 00:57:57 +00:00
|
|
|
return some_expr(r.get_proof());
|
|
|
|
}
|
2015-11-13 21:05:20 +00:00
|
|
|
display_msg("* next branch");
|
2015-11-10 19:44:18 +00:00
|
|
|
break;
|
2015-11-11 00:57:57 +00:00
|
|
|
case action_result::NewBranch:
|
|
|
|
r = next_action();
|
2015-11-10 19:44:18 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-11-13 21:05:20 +00:00
|
|
|
display_if(r);
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
optional<expr> search() {
|
|
|
|
state s = curr_state();
|
2015-11-13 21:05:20 +00:00
|
|
|
unsigned d = m_config.m_init_depth;
|
2015-11-11 00:57:57 +00:00
|
|
|
while (true) {
|
2015-11-10 19:44:18 +00:00
|
|
|
if (auto r = search_upto(d))
|
|
|
|
return r;
|
2015-11-13 21:05:20 +00:00
|
|
|
d += m_config.m_inc_depth;
|
|
|
|
if (d > m_config.m_max_depth) {
|
2015-11-11 00:57:57 +00:00
|
|
|
display_curr_state();
|
|
|
|
return none_expr();
|
|
|
|
}
|
2015-11-10 19:44:18 +00:00
|
|
|
curr_state() = s;
|
|
|
|
clear_choice_points();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2015-11-13 21:05:20 +00:00
|
|
|
simple_strategy():
|
|
|
|
m_config(ios().get_options()) {
|
2015-11-10 19:44:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
optional<expr> operator()() {
|
|
|
|
return search();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
optional<expr> apply_simple_strategy() {
|
|
|
|
return simple_strategy()();
|
|
|
|
}
|
|
|
|
}}
|