lean2/src/library/blast/choice_point.h
2015-11-15 13:12:21 -08:00

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); }
};
}}