79 lines
2.7 KiB
C++
79 lines
2.7 KiB
C++
/*
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
Author: Leonardo de Moura
|
|
*/
|
|
#pragma once
|
|
#include "library/blast/state.h"
|
|
|
|
namespace lean {
|
|
namespace blast {
|
|
/** \brief Choice points are used different ways to proceed
|
|
For example, given
|
|
|- A \/ B
|
|
we may proceed by trying to prove A or B. Each alternative
|
|
is a different proof state. Actions my create choice points
|
|
and add them to the choice point stack.
|
|
*/
|
|
class choice_point_cell {
|
|
MK_LEAN_RC(); // Declare m_rc counter
|
|
void dealloc() { delete this; }
|
|
public:
|
|
virtual ~choice_point_cell() {}
|
|
/** \brief Update next proof state. This method may
|
|
perform destructive updates, choice points are not shared
|
|
objects.
|
|
|
|
The next method result can be:
|
|
1- Failed: failure
|
|
2- NewBranch: the current state has been updated, and it contains
|
|
a new branch to be solved.
|
|
3- Solved(pr): the current state has been updated, and its current
|
|
branch has been closed by the next choice.
|
|
*/
|
|
virtual action_result next() = 0;
|
|
};
|
|
|
|
/** \brief Smart pointer for choice points */
|
|
class choice_point {
|
|
choice_point_cell * m_ptr;
|
|
public:
|
|
choice_point():m_ptr(nullptr) {}
|
|
choice_point(choice_point_cell * c):m_ptr(c) { m_ptr->inc_ref(); }
|
|
choice_point(choice_point const & s):m_ptr(s.m_ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
|
choice_point(choice_point && s):m_ptr(s.m_ptr) { s.m_ptr = nullptr; }
|
|
~choice_point() { if (m_ptr) m_ptr->dec_ref(); }
|
|
choice_point & operator=(choice_point const & s) { LEAN_COPY_REF(s); }
|
|
choice_point & operator=(choice_point && s) { LEAN_MOVE_REF(s); }
|
|
|
|
action_result next() {
|
|
lean_assert(m_ptr);
|
|
return m_ptr->next();
|
|
}
|
|
};
|
|
|
|
/** \brief Initialize thread local data-structures for storing choice points */
|
|
void init_choice_points();
|
|
/** \brief Add choice point to the top of the stack */
|
|
void push_choice_point(choice_point const & c);
|
|
inline void push_choice_point(choice_point_cell * cell) {
|
|
push_choice_point(choice_point(cell));
|
|
}
|
|
/** \brief Keep executing choice points until one of them doesn't fail. */
|
|
action_result next_choice_point(unsigned base = 0);
|
|
/** \brief Return size of the choice point stack */
|
|
unsigned get_num_choice_points();
|
|
/** \brief Shrink the size of the choice point stack.
|
|
\pre n <= get_num_choice_points */
|
|
void shrink_choice_points(unsigned n);
|
|
/** \brief Clear/remove all choice points */
|
|
void clear_choice_points();
|
|
|
|
class scope_choice_points {
|
|
unsigned m_num_choices;
|
|
public:
|
|
scope_choice_points():m_num_choices(get_num_choice_points()) {}
|
|
~scope_choice_points() { shrink_choice_points(m_num_choices); }
|
|
};
|
|
}}
|