12#ifndef MCRL2_DATA_DETAIL_BDD_PROVER_H
13#define MCRL2_DATA_DETAIL_BDD_PROVER_H
15#include "mcrl2/data/detail/prover/bdd_path_eliminator.h"
16#include "mcrl2/data/detail/prover/induction.h"
17#include "mcrl2/data/find.h"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
149 f_deadline = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch() + std::chrono::milliseconds(
int(f_time_limit * 1000)));
154 mCRL2log(log::debug) <<
"Formula: " << f_formula << std::endl;
158 intermediate_bdd = m_rewriter->rewrite(intermediate_bdd,bdd_sigma);
159 intermediate_bdd = f_manipulator.orient(intermediate_bdd);
161 mCRL2log(log::trace) <<
"Formula rewritten and oriented: " << intermediate_bdd << std::endl;
163 while (v_previous_1 != intermediate_bdd && v_previous_2 != intermediate_bdd)
165 v_previous_2
= v_previous_1;
166 v_previous_1
= intermediate_bdd;
168 mCRL2log(log::trace) <<
"End of iteration." << std::endl;
169 mCRL2log(log::trace) <<
"Intermediate BDD: " << intermediate_bdd << std::endl;
173 mCRL2log(log::debug) <<
"Resulting BDD: " << f_bdd << std::endl;
180 return std::string(n,
' ');
187 if (f_time_limit != 0 && (f_deadline <= std::chrono::system_clock::now().time_since_epoch()))
189 mCRL2log(log::debug) <<
"The time limit has passed." << std::endl;
204 const abstraction& a = atermpp::down_cast<abstraction>(formula);
208 const std::unordered_map < data_expression, data_expression >::const_iterator i = f_formula_to_bdd.find(formula);
209 if (i!=f_formula_to_bdd.end())
222 mCRL2log(log::trace) << indent(a_indent) <<
"Smallest guard: " << v_guard << std::endl;
225 const size_t extra_indent = a_indent + 2;
228 v_term1 = m_rewriter->rewrite(v_term1,bdd_sigma);
229 v_term1 = f_manipulator.orient(v_term1);
230 mCRL2log(log::trace) << indent(extra_indent) <<
"True-branch after rewriting and orienting: " << v_term1 << std::endl;
232 mCRL2log(log::trace) << indent(extra_indent) <<
"BDD of the true-branch: " << v_term1 << std::endl;
235 v_term2 = m_rewriter->rewrite(v_term2,bdd_sigma);
236 v_term2 = f_manipulator.orient(v_term2);
237 mCRL2log(log::trace) << indent(extra_indent) <<
"False-branch after rewriting and orienting: " << v_term2 << std::endl;
239 mCRL2log(log::trace) << indent(extra_indent) <<
"BDD of the false-branch: " << v_term2 << std::endl;
242 f_formula_to_bdd[formula]=v_bdd;
250 time_t v_new_time_limit;
252 v_new_time_limit = (f_deadline
253 - std::chrono::duration_cast<std::chrono::milliseconds>(
254 std::chrono::system_clock::now().time_since_epoch()))
258 mCRL2log(log::debug) <<
"Simplifying the BDD:" << std::endl;
259 f_bdd_simplifier->set_time_limit((std::max)(v_new_time_limit, time(
nullptr)));
260 f_bdd = f_bdd_simplifier->simplify(f_bdd);
261 mCRL2log(log::debug) <<
"Resulting BDD: " << f_bdd << std::endl;
276 f_induction.initialize(v_original_formula);
277 while (f_induction.can_apply_induction() && !BDD_Info::is_true(f_bdd))
279 mCRL2log(log::debug) <<
"Applying induction." << std::endl;
280 f_formula = f_induction.apply_induction();
293 f_induction.initialize(v_original_formula);
294 while (f_induction.can_apply_induction() && !BDD_Info::is_true(f_bdd))
296 mCRL2log(log::debug) <<
"Applying induction on the negated formula." << std::endl;
297 f_formula = f_induction.apply_induction();
377 const std::unordered_map < data_expression, data_expression >::const_iterator i = f_smallest.find(formula);
378 if (i!=f_smallest.end())
384 bool result_is_defined=
false;
386 for (
const data_expression& arg: atermpp::down_cast<application>(formula))
388 bool success = smallest(arg,v_small);
391 if (result_is_defined)
396 if (f_info.compare_guard(v_small, result, f_variables) == compare_result_smaller)
404 result_is_defined=
true;
413 if (result_is_defined)
415 f_smallest[formula]=result;
472 mcrl2::data::rewriter::strategy a_rewrite_strategy = mcrl2::
data::jitty,
473 double a_time_limit = 0,
474 bool a_path_eliminator =
false,
475 smt_solver_type a_solver_type = solver_type_cvc,
476 bool a_apply_induction =
false)
484 switch (a_rewrite_strategy)
487#ifdef MCRL2_ENABLE_JITTYC
488 case(jitty_compiling):
495#ifdef MCRL2_ENABLE_JITTYC
496 case(jitty_compiling_prover):
499 throw mcrl2::runtime_error(
"The proving rewriters are not supported by the prover (only jitty and jittyc are supported).");
503 throw mcrl2::runtime_error(
"Unknown type of rewriter.");
508 mCRL2log(log::debug) <<
"Flags:" << std::endl
509 <<
" Reverse: " << std::boolalpha << f_reverse <<
"," << std::endl
510 <<
" Full: " << f_full <<
"," << std::endl;
561 mCRL2log(log::debug) <<
"The formula is a contradiction." << std::endl;
566 mCRL2log(log::debug) <<
"The formula is a tautology." << std::endl;
571 mCRL2log(log::debug) <<
"The formula is satisfiable, but not a tautology." << std::endl;
575 {
throw mcrl2::runtime_error(
576 "Cannot provide witness. This is probably caused by an abrupt stop of the\n"
577 "conversion from expression to EQ-BDD. This typically occurs when a time limit is set.");
589 mCRL2log(log::debug) <<
"The formula is a contradiction." << std::endl;
594 mCRL2log(log::debug) <<
"The formula is a tautology." << std::endl;
599 mCRL2log(log::debug) <<
"The formula is satisfiable, but not a tautology." << std::endl;
603 {
throw mcrl2::runtime_error(
604 "Cannot provide counter example. This is probably caused by an abrupt stop of the\n"
605 "conversion from expression to EQ-BDD. This typically occurs when a time limit is set.");
620 return m_rewriter->getStrategy();
629 f_variables = find_free_variables_in_order(f_formula);
630 mCRL2log(log::debug) <<
"The formula has been set." << std::endl;
A unordered_map class in which aterms can be stored.
An abstraction expression.
const variable_list & variables() const
abstraction(const binder_type &binding_operator, const variable_list &variables, const data_expression &body)
Constructor.
const data_expression & body() const
const binder_type & binding_operator() const
const data_expression & lhs() const
const variable_list & variables() const
data_expression & operator=(const data_expression &) noexcept=default
data_expression & operator=(data_expression &&) noexcept=default
sort_expression sort() const
Returns the sort of the data expression.
The class BDD_Info provides information about the structure of binary decision diagrams.
static const mcrl2::data::data_expression & get_true_branch(const mcrl2::data::data_expression &a_bdd)
Method that returns the true-branch of a BDD.
static bool is_if_then_else(const data_expression &a_bdd)
Method that indicates wether or not the root of a BDD is a guard node.
static bool is_false(const data_expression &a_bdd)
Method that indicates whether or not a BDD equals false.
static const mcrl2::data::data_expression & get_guard(const mcrl2::data::data_expression &a_bdd)
Method that returns the guard of a BDD.
static const mcrl2::data::data_expression & get_false_branch(const mcrl2::data::data_expression &a_bdd)
Method that returns the false-branch of a BDD.
static bool is_true(const data_expression &a_bdd)
Method that indicates whether or not a BDD equals true.
bool get_branch(const data_expression &a_bdd, const bool a_polarity, data_expression &result)
Returns branch of the BDD a_bdd, depending on the polarity a_polarity.
Induction f_induction
Class that creates all statements needed to prove a given property using induction.
strategy rewriter_strategy() const
Returns the strategy of the rewriter used inside this proving rewriter.
std::vector< variable > f_variables
The variables in the expression in order.
std::shared_ptr< BDD_Simplifier > f_bdd_simplifier
Class that simplifies a BDD.
static constexpr bool f_reverse
Flag indicating whether or not the result of the comparison between the first two arguments.
void set_substitution(substitution_type &sigma)
Set the substitution to be used to construct the BDD.
void set_formula(const data_expression &formula)
Sets Prover::f_formula to formula. precondition: the argument passed as parameter formula is an expre...
std::string indent(size_t n)
bool smallest(const data_expression &formula, data_expression &result)
Returns the smallest guard in the formula formula.
data_expression f_bdd
A binary decision diagram in the internal representation of mCRL2.
const Info f_info
A class that provides information about expressions.
data_expression bdd_down(const data_expression &formula, const size_t a_indent=0)
Creates the EQ-BDD corresponding to the formula formula.
static constexpr bool f_full
Flag indicating whether or not the arguments of equality functions are taken into account.
void eliminate_paths()
Removes all inconsistent paths from the BDD BDD_Prover::f_bdd.
BDD_Prover(const rewriter &r, double time_limit=0, bool apply_induction=false)
data_expression get_counter_example()
Returns all the guards on a path in the BDD that leads to a leaf labelled "false",...
substitution_type bdd_sigma
A binary decision diagram in the internal representation of the rewriter.
Answer f_tautology
A flag that indicates whether or not the formala Prover::f_formula is a tautology.
Answer is_contradiction()
Indicates whether or not the formula Prover::f_formula is a contradiction.
data_expression f_formula
An expression of sort Bool.
std::chrono::milliseconds f_deadline
A timestamp representing the moment when the maximal amount of milliseconds has been spent on process...
bool f_processed
A flag that indicates whether or not the formala Prover::f_formula has been processed.
void update_answers()
Updates the values of Prover::f_tautology and Prover::f_contradiction.
std::shared_ptr< detail::Rewriter > get_rewriter()
Returns the rewriter used by this prover (i.e. it returns Prover::f_rewriter).
const double f_time_limit
An integer representing the maximal amount of seconds to be spent on processing a formula.
Manipulator f_manipulator
A class that can be used to manipulate expressions.
bool f_apply_induction
A flag indicating whether or not induction on lists is applied.
void build_bdd()
Constructs the EQ-BDD corresponding to the formula Prover::f_formula.
std::unordered_map< data_expression, data_expression > f_smallest
A hashtable that maps formulas to the smallest guard occuring in those formulas.
Answer f_contradiction
A flag that indicates whether or not the formala Prover::f_formula is a contradiction.
std::unordered_map< data_expression, data_expression > f_formula_to_bdd
A hashtable that maps formulas to BDDs.
data_expression get_bdd()
Returns the BDD BDD_Prover::f_bdd.
data_expression get_witness()
Returns all the guards on a path in the BDD that leads to a leaf labelled "true", if such a leaf exis...
void set_substitution_internal(substitution_type &sigma)
Set the substitution in internal format to be used to construct the BDD.
BDD_Prover(const data_specification &data_spec, const used_data_equation_selector &equations_selector, mcrl2::data::rewriter::strategy a_rewrite_strategy=mcrl2::data::jitty, double a_time_limit=0, bool a_path_eliminator=false, smt_solver_type a_solver_type=solver_type_cvc, bool a_apply_induction=false)
Answer is_tautology()
Indicates whether or not the formula Prover::f_formula is a tautology.
A base class for simplifying binary decision diagrams.
The class Induction generates statements corresponding to.
Base class for classes that provide information about the structure of.
constexpr Info(bool a_full, bool a_reverse)
Constructor that initializes the rewriter.
Base class for classes that provide functionality to modify or create terms.
static data_expression make_reduced_if_then_else(const data_expression &a_expr, const data_expression &a_high, const data_expression &a_low)
Returns an expression in the internal format of the rewriter with the jitty strategy.
RewriterProver(const data_specification &data_spec, mcrl2::data::rewriter::strategy strat, const used_data_equation_selector &equations_selector)
RewriterProver(const RewriterProver &other)=delete
data_expression rewrite(const data_expression &t, substitution_type &sigma) override
Rewrite an mCRL2 data term.
rewrite_strategy getStrategy() override
Get rewriter strategy that is used.
void rewrite(data_expression &result, const data_expression &t, substitution_type &sigma) override
Rewrite an mCRL2 data term.
~RewriterProver() override=default
RewriterProver(const RewriterProver &rewr, BDD_Prover prover_obj_)
void thread_initialise() override
std::shared_ptr< Rewriter > clone() override
Clone a rewriter.
Rewriter interface class.
void rewrite_where(data_expression &result, const where_clause &term, substitution_type &sigma)
virtual void thread_initialise()
Rewriter(const data_specification &data_spec, const used_data_equation_selector &eq_selector)
Constructor. Do not use directly; use createRewriter() function instead.
A strategy is a list of rules and the number of variables that occur in it.
An enumerator algorithm that generates solutions of a condition.
The default element for the todo list of the enumerator.
Rewriter that operates on data expressions.
void thread_initialise()
Initialises this rewriter with thread dependent information.
rewriter clone()
Create a clone of the rewriter in which the underlying rewriter is copied, and not passed as a shared...
rewriter(const rewriter &r)=default
Constructor.
Component for selecting a subset of equations that are actually used in an encompassing specification...
variable(const variable &) noexcept=default
Move semantics.
\brief A where expression
const assignment_list & assignments() const
const data_expression & body() const
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
void CheckRewriteRule(const data_equation &data_eqn)
Check that an mCRL2 data equation is a valid rewrite rule. If not, an runtime_error is thrown indicat...
static void checkPattern(const data_expression &p)
static void check_vars(application::const_iterator begin, const application::const_iterator &end, const std::set< variable > &vars, std::set< variable > &used_vars)
void set_enumerator_iteration_limit(std::size_t size)
bool isValidRewriteRule(const data_equation &data_eqn)
Check whether or not an mCRL2 data equation is a valid rewrite rule.
static bool occur_check(const variable &v, const atermpp::aterm &e)
static void checkPattern(application::const_iterator begin, const application::const_iterator &end)
Answer
A prover that uses EQ-BDDs.
static void check_vars(const data_expression &expr, const std::set< variable > &vars, std::set< variable > &used_vars)
A collection of utilities for lazy expression construction.
data_expression and_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p or q.
Namespace for system defined sort bool_.
const basic_sort & bool_()
Constructor for sort expression Bool.
application not_(const data_expression &arg0)
Application of function symbol !.
const function_symbol & false_()
Constructor for function symbol false.
const function_symbol & true_()
Constructor for function symbol true.
bool is_application(const data_expression &t)
Returns true if the term t is an application.
bool is_abstraction(const atermpp::aterm &x)
Returns true if the term t is an abstraction.
bool is_forall(const atermpp::aterm &x)
Returns true if the term t is a universal quantification.
bool is_function_symbol(const atermpp::aterm &x)
Returns true if the term t is a function symbol.
bool is_exists(const atermpp::aterm &x)
Returns true if the term t is an existential quantification.
bool is_machine_number(const atermpp::aterm &x)
Returns true if the term t is a machine_number.
bool is_lambda(const atermpp::aterm &x)
Returns true if the term t is a lambda abstraction.
bool is_variable(const atermpp::aterm &x)
Returns true if the term t is a variable.
static std::size_t max_enumerator_iterations
bool operator()(const atermpp::aterm &t) const
rewriter_wrapper(Rewriter *r)