10 #include "ThreadPool/ThreadPool.h" 12 #include "dreal/contractor/contractor.h" 13 #include "dreal/contractor/contractor_cell.h" 14 #include "dreal/contractor/counterexample_refiner.h" 15 #include "dreal/contractor/generic_contractor_generator.h" 16 #include "dreal/util/assert.h" 17 #include "dreal/util/box.h" 18 #include "dreal/util/exception.h" 19 #include "dreal/util/interrupt.h" 20 #include "dreal/util/logging.h" 21 #include "dreal/util/nnfizer.h" 22 #include "dreal/util/optional.h" 28 const Variables& quantified_variables, Box b,
53 template <
typename ContextType>
54 class ContractorForall :
public ContractorCell {
63 DynamicBitset(box.
size()), config},
65 quantified_variables_{get_quantified_variables(f_)},
69 context_for_counterexample_{
config} {
70 DREAL_ASSERT(epsilon > 0.0);
71 DREAL_ASSERT(inner_delta > 0.0);
73 DREAL_ASSERT(epsilon > inner_delta);
74 DREAL_ASSERT(!is_false(strengthend_negated_nested_f_));
80 context_for_counterexample_.mutable_config().mutable_precision() =
82 context_for_counterexample_.mutable_config().mutable_use_polytope() =
85 get_quantified_formula(f_), ExtendBox(box, quantified_variables_),
86 context_for_counterexample_.config());
88 for (
const Variable& exist_var : box.variables()) {
89 context_for_counterexample_.DeclareVariable(exist_var);
91 for (
const Variable& forall_var : get_quantified_variables(f_)) {
92 context_for_counterexample_.DeclareVariable(forall_var);
95 if (is_conjunction(strengthend_negated_nested_f_)) {
98 get_operands(strengthend_negated_nested_f_)) {
99 context_for_counterexample_.Assert(formula);
102 context_for_counterexample_.Assert(strengthend_negated_nested_f_);
108 input.set(box.index(v));
111 refiner_ = std::make_unique<CounterexampleRefiner>(
112 strengthend_negated_nested_f_, quantified_variables_,
113 context_for_counterexample_.config());
130 const Box& counterexample)
const {
135 contractor_status.
mutable_box()[exist_var] = (*current_box)[exist_var];
140 for (
const Variable& forall_var : get_quantified_variables(f_)) {
142 counterexample[forall_var].mid();
144 contractor_.
Prune(&contractor_status);
145 if (contractor_status.
box().
empty()) {
153 bool changed =
false;
154 for (
int i = 0; i < cs->
box().
size(); ++i) {
155 if (cs->
box()[i] != contractor_status.
box()[i]) {
157 (*current_box)[i] = contractor_status.
box()[i];
174 Config& config_for_counterexample{
175 context_for_counterexample_.mutable_config()};
179 #ifdef DREAL_CHECK_INTERRUPT 181 DREAL_LOG_DEBUG(
"KeyboardInterrupt(SIGINT) Detected.");
182 throw std::runtime_error(
"KeyboardInterrupt(SIGINT) Detected.");
188 context_for_counterexample_.SetInterval(exist_var,
189 current_box[exist_var].lb(),
190 current_box[exist_var].ub());
193 config_for_counterexample.mutable_stack_left_box_first() =
194 !config_for_counterexample.stack_left_box_first();
195 optional<Box> counterexample_opt = context_for_counterexample_.CheckSat();
196 if (counterexample_opt) {
197 Box& counterexample{*counterexample_opt};
199 DREAL_LOG_DEBUG(
"ContractorForall::Prune: Counterexample found:\n{}",
202 if (
config().use_local_optimization()) {
203 counterexample = refiner_->Refine(counterexample);
205 bool need_to_break_the_loop =
206 PruneWithCounterexample(cs, ¤t_box, counterexample);
207 if (need_to_break_the_loop) {
212 DREAL_LOG_DEBUG(
"ContractorForall::Prune: No counterexample found.");
219 std::ostream&
display(std::ostream& os)
const override {
220 return os <<
"ContractorForall(" << f_ <<
")";
233 const Formula strengthend_negated_nested_f_;
237 mutable ContextType context_for_counterexample_;
238 const bool use_local_optimization_{
false};
240 std::unique_ptr<CounterexampleRefiner> refiner_;
243 template <
typename ContextType>
253 DynamicBitset(box.
size()), config},
256 inner_delta_{inner_delta},
258 ctcs_(ctc_ready_.size()) {
282 return ctc->Prune(cs);
285 std::ostream&
display(std::ostream& os)
const override {
286 return os <<
"ContractorForall(" << f_ <<
")";
291 thread_local
const int kThreadId{ThreadPool::get_thread_id()};
292 DREAL_ASSERT(kThreadId == ThreadPool::get_thread_id());
293 DREAL_ASSERT(0 <= kThreadId &&
294 kThreadId <= static_cast<int>(ctc_ready_.size()));
295 if (ctc_ready_[kThreadId]) {
296 return ctcs_[kThreadId].get();
300 auto ctc_unique_ptr = std::make_unique<ContractorForall<ContextType>>(
301 f_, box, epsilon_, inner_delta_, inner_config);
304 ctcs_[kThreadId] = std::move(ctc_unique_ptr);
305 ctc_ready_[kThreadId] = 1;
310 const double epsilon_{};
311 const double inner_delta_{};
313 mutable std::vector<int> ctc_ready_;
314 mutable std::vector<std::unique_ptr<ContractorForall<ContextType>>> ctcs_;
317 template <
typename ContextType>
321 return Contractor{std::make_shared<ContractorForallMt<ContextType>>(
322 std::move(f), box, epsilon, inner_delta,
config)};
324 return Contractor{std::make_shared<ContractorForall<ContextType>>(
325 std::move(f), box, epsilon, inner_delta,
config)};
330 template <
typename ContextType>
331 std::shared_ptr<ContractorForall<ContextType>>
to_forall(
std::ostream & display(std::ostream &os) const override
Outputs this contractor to os.
Definition: contractor_forall.h:285
Formula Convert(const Formula &f, bool push_negation_into_relationals=false) const
Converts f into an equivalent formula f' in NNF.
Definition: nnfizer.cc:9
const Config & config() const
Returns config.
Definition: contractor_cell.cc:33
Box & mutable_box()
Returns a mutable reference of the embedded box.
Definition: contractor_status.cc:65
Contractor Generate(const Formula &f, const Box &box, const Config &config) const
Generates f into a contractor using box.
Definition: generic_contractor_generator.cc:15
OptionValue< int > & mutable_number_of_jobs()
Returns a mutable OptionValue for 'number_of_jobs'.
Definition: config.cc:51
Abstract base class of contractors.
Definition: contractor_cell.h:29
Contractor make_contractor_forall(Formula f, const Box &box, double epsilon, double inner_delta, const Config &config)
Returns a forall contractor.
Definition: contractor_forall.h:318
ContractorForall & operator=(const ContractorForall &)=delete
Deleted copy assign operator.
Sum type of symbolic::Expression and symbolic::Formula.
Definition: api.cc:9
void AddUsedConstraint(const Formula &f)
Add a formula f into the used constraints.
Definition: contractor_status.cc:75
bool use_polytope_in_forall() const
Returns whether it uses polytope contractors inside forall contractors.
Definition: config.cc:29
bool use_local_optimization() const
Returns whether it uses local optimization algorithm in exist-forall problems.
Definition: config.cc:43
ContractorForallMt(Formula f, const Box &box, double epsilon, double inner_delta, const Config &config)
Constructs ForallMt contractor using f and box.
Definition: contractor_forall.h:250
int number_of_jobs() const
Returns the number of parallel jobs.
Definition: config.cc:50
Contractor for forall constraints.
Definition: contractor.h:24
std::shared_ptr< ContractorForall< ContextType > > to_forall(const Contractor &contractor)
Converts contractor to ContractorForall.
Definition: contractor_forall.h:331
Represents a symbolic variable.
Definition: symbolic_variable.h:16
DynamicBitset & mutable_output()
Returns a mutable reference of the output field.
Definition: contractor_status.cc:73
Box RefineCounterexample(const Formula &query, const Variables &quantified_variables, Box b, double precision)
Add Doc.
const DynamicBitset & input() const
Returns its input.
Definition: contractor_cell.cc:29
volatile std::atomic_bool g_interrupted
Flag to indicate an interrupt (SIGINT) is received.
Definition: interrupt.cc:4
void Prune(ContractorStatus *cs) const
Prunes cs.
Definition: contractor.cc:88
void set_include_forall()
Sets include_forall true.
Definition: contractor_cell.cc:37
bool empty() const
Checks if this box is empty.
Definition: box.cc:100
std::ostream & display(std::ostream &os) const override
Outputs this contractor to os.
Definition: contractor_forall.h:219
Definition: contractor_forall.h:244
double precision() const
Returns the precision option.
Definition: config.cc:20
void set_empty()
Make this box empty.
Definition: box.cc:102
void Add(const Variable &v)
Adds v to the box.
Definition: box.cc:51
Represents a n-dimensional interval vector.
Definition: box.h:17
int size() const
Returns the size of the box.
Definition: box.cc:104
const Box & box() const
Returns a const reference of the embedded box.
Definition: contractor_status.cc:63
A class implementing NNF (Negation Normal Form) conversion.
Definition: nnfizer.h:12
Formula DeltaStrengthen(const Formula &f, const double delta)
Strengthen the input formula $p f by delta.
Definition: symbolic.cc:504
Converts an arbitrary formula into a contractor.
Definition: generic_contractor_generator.h:11
void Prune(ContractorStatus *cs) const override
Performs pruning on cs.
Definition: contractor_forall.h:279
bool is_forall(const Contractor &contractor)
Returns true if contractor is forall contractor.
Definition: contractor.cc:221
Represents a set of variables.
Definition: symbolic_variables.h:25
Contractor status.
Definition: contractor_status.h:13
Definition: contractor.h:30
DynamicBitset & mutable_input()
Returns its input.
Definition: contractor_cell.cc:31
const std::vector< Variable > & variables() const
Returns the variables in the box.
Definition: box.cc:121
~ContractorForall() override=default
Default destructor.
void Prune(ContractorStatus *cs) const override
Performs pruning on cs.
Definition: contractor_forall.h:172
ContractorForall(Formula f, const Box &box, double epsilon, double inner_delta, const Config &config)
Constructs Forall contractor using f and box.
Definition: contractor_forall.h:60