3#ifndef TURBO_COMMON_SOLVING_HPP
4#define TURBO_COMMON_SOLVING_HPP
17#include "battery/utility.hpp"
18#include "battery/allocator.hpp"
19#include "battery/vector.hpp"
20#include "battery/shared_ptr.hpp"
22#include "lala/simplifier.hpp"
23#include "lala/vstore.hpp"
24#include "lala/cartesian_product.hpp"
25#include "lala/interval.hpp"
27#include "lala/terms.hpp"
28#include "lala/fixpoint.hpp"
29#include "lala/search_tree.hpp"
30#include "lala/bab.hpp"
31#include "lala/split_strategy.hpp"
32#include "lala/interpretation.hpp"
34#include "lala/flatzinc_parser.hpp"
36#ifdef WITH_XCSP3PARSER
37 #include "lala/XCSP3_parser.hpp"
47static std::atomic<bool> got_signal;
48static void (*prev_sigint)(int);
49static void (*prev_sigterm)(int);
51void signal_handler(
int signum)
53 signal(SIGINT, signal_handler);
54 signal(SIGTERM, signal_handler);
58 if (signum == SIGINT && prev_sigint != SIG_DFL && prev_sigint != SIG_IGN) {
59 (*prev_sigint)(signum);
61 if (signum == SIGTERM && prev_sigterm != SIG_DFL && prev_sigterm != SIG_IGN) {
62 (*prev_sigterm)(signum);
67 prev_sigint = signal(SIGINT, signal_handler);
68 prev_sigterm = signal(SIGTERM, signal_handler);
72 return static_cast<bool>(got_signal);
80 sigaddset(&ctrlc, SIGINT);
81 sigaddset(&ctrlc, SIGTERM);
82 if(sigprocmask(SIG_BLOCK, &ctrlc, NULL) != 0) {
83 printf(
"%% ERROR: Unable to deal with CTRL-C. Therefore, we will not be able to print the latest solution before quitting.\n");
90 sigset_t pending_sigs;
91 sigemptyset(&pending_sigs);
92 sigpending(&pending_sigs);
93 return sigismember(&pending_sigs, SIGINT) == 1 || sigismember(&pending_sigs, SIGTERM) == 1;
100template <
class A,
class Timepo
int>
102 auto now = std::chrono::high_resolution_clock::now();
103 a.stats.duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count();
104 if(a.config.timeout_ms == 0) {
107 if(a.stats.duration >=
static_cast<int64_t
>(a.config.timeout_ms)) {
108 if(a.config.verbose_solving) {
109 printf(
"%% CPU: Timeout reached.\n");
111 a.stats.exhaustive =
false;
118template <
class Alloc,
size_t n>
135template <
class Alloc,
size_t n>
138 return Alloc{}.allocate(bytes);
141 Alloc{}.deallocate(data);
152template <
class Universe,
153 class BasicAllocator,
155 class StoreAllocator>
160 using LIStore = VStore<universe_type, BasicAllocator>;
162 using IStore = VStore<Universe, StoreAllocator>;
163 using IPC = PC<IStore, PropAllocator>;
165 using Split = SplitStrategy<IPC, BasicAllocator>;
166 using IST = SearchTree<IPC, Split, BasicAllocator>;
167 using IBAB = BAB<IST, LIStore>;
184 template <
class U2,
class BasicAlloc2,
class PropAllocator2,
class StoreAllocator2>
208 store = deps.template clone<IStore>(other.
store);
209 ipc = deps.template clone<IPC>(other.
ipc);
210 split = deps.template clone<Split>(other.
split);
213 bab = deps.template clone<IBAB>(other.
bab);
217 template <
class U2,
class BasicAlloc2,
class PropAllocator2,
class StoreAllocator2>
237 template <
class Alloc>
257 size_t num_subproblems = 1;
278 VarEnv<BasicAllocator>
env;
301 printf(
"%% Abstract domain allocated.\n");
322 if(f.sig() == ::lala::IN && f.seq(1).is(F::S) && f.seq(1).s().size() > 1) {
323 f.type_as(
ipc->aty());
326 for(
int i = 0; i < f.seq().size(); ++i) {
331 for(
int i = 0; i < f.eseq().size(); ++i) {
341 template <
class F,
class Env,
class A>
342 CUDA
bool interpret_and_diagnose_and_tell(
const F& f, Env&
env, A& a) {
343 IDiagnostics diagnostics;
344 if(!interpret_and_tell(f,
env, a, diagnostics)) {
345 IDiagnostics diagnostics2;
346 interpret_and_tell<true>(f,
env, a, diagnostics2);
347 diagnostics2.print();
357 printf(
"%% Interpreting the formula...\n");
359 if(!interpret_and_diagnose_and_tell(f,
env, *
bab)) {
364 bool can_interpret =
true;
365 if(
split->num_strategies() == 0) {
366 can_interpret &= interpret_default_strategy<F>();
369 can_interpret &= interpret_default_eps_strategy<F>();
371 return can_interpret;
377 printf(
"%% Simplifying the formula...\n");
379 IDiagnostics diagnostics;
380 typename ISimplifier::template tell_type<basic_allocator_type> tell{
basic_allocator};
381 if(top_level_ginterpret_in<IKind::TELL>(*
simplifier, f,
env, tell, diagnostics)) {
386 printf(
"WARNING: Could not simplify the formula because:\n");
387 IDiagnostics diagnostics2;
388 top_level_ginterpret_in<IKind::TELL, true>(*
simplifier, f,
env, tell, diagnostics2);
389 diagnostics2.print();
397 printf(
"%% Typing the formula...\n");
401 printf(
"%% Typed AST:\n");
410 printf(
"%% Interpreted AST:\n");
411 ipc->deinterpret(
env).print(
true);
415 printf(
"%% Formula has been interpreted.\n");
422 auto start = std::chrono::high_resolution_clock::now();
429#ifdef WITH_XCSP3PARSER
435 std::cerr <<
"Could not parse input file." << std::endl;
440 printf(
"%% Input file parsed\n");
444 printf(
"%% Parsed AST:\n");
451 printf(
"%% Formula syntactically simplified.\n");
457 auto interpretation_time = std::chrono::high_resolution_clock::now();
464 auto start = std::chrono::high_resolution_clock::now();
466 GaussSeidelIteration fp_engine;
467 fp_engine.fixpoint(*
ipc);
475 auto interpretation_time = std::chrono::high_resolution_clock::now();
481 CUDA
bool interpret_default_strategy() {
483 printf(
"%% No split strategy provided, using the default one (first_fail, indomain_min).\n");
486 typename F::Sequence seq;
487 seq.push_back(F::make_nary(
"first_fail", {}));
488 seq.push_back(F::make_nary(
"indomain_min", {}));
489 for(
int i = 0; i <
env.num_vars(); ++i) {
490 seq.push_back(F::make_avar(
env[i].avars[0]));
492 F search_strat = F::make_nary(
"search", std::move(seq));
493 if(!interpret_and_diagnose_and_tell(search_strat,
env, *
bab)) {
500 CUDA
bool interpret_default_eps_strategy() {
501 typename F::Sequence seq;
502 seq.push_back(F::make_nary(
"first_fail", {}));
503 seq.push_back(F::make_nary(
"indomain_min", {}));
504 for(
int i = 0; i <
env.num_vars(); ++i) {
505 seq.push_back(F::make_avar(
env[i].avars[0]));
507 F search_strat = F::make_nary(
"search", std::move(seq));
508 if(!interpret_and_diagnose_and_tell(search_strat,
env, *
eps_split)) {
572 if(!
bab->objective_var().is_untyped() && !
best->is_top()) {
580 template <
class U2,
class BasicAlloc2,
class PropAlloc2,
class StoreAlloc2>
582 if(
bab->is_optimization() && !other.
best->is_top() &&
bab->compare_bound(*other.
best, *
best)) {
589using Itv = Interval<local::ZLB>;
591template <
class Universe,
class Allocator = battery::standard_allocator>
593 battery::statistics_allocator<Allocator>,
594 battery::statistics_allocator<UniqueLightAlloc<Allocator, 0>>,
595 battery::statistics_allocator<UniqueLightAlloc<Allocator, 1>>>;
Interval< local::ZLB > Itv
Definition common_solving.hpp:589
bool must_quit()
Definition common_solving.hpp:89
void block_signal_ctrlc()
Definition common_solving.hpp:77
bool check_timeout(A &a, const Timepoint &start)
Definition common_solving.hpp:101
Definition common_solving.hpp:175
Definition common_solving.hpp:177
Definition common_solving.hpp:156
abstract_ptr< IBAB > bab
Definition common_solving.hpp:275
void type_and_interpret(F &f)
Definition common_solving.hpp:395
SearchTree< IPC, Split, BasicAllocator > IST
Definition common_solving.hpp:166
Configuration< BasicAllocator > config
Definition common_solving.hpp:283
CUDA void typing(F &f) const
Definition common_solving.hpp:319
CUDA bool interpret(const F &f)
Definition common_solving.hpp:355
CUDA void deallocate()
Definition common_solving.hpp:306
VStore< universe_type, BasicAllocator > LIStore
Definition common_solving.hpp:160
CUDA void print_final_solution()
Definition common_solving.hpp:561
StoreAllocator store_allocator
Definition common_solving.hpp:266
CUDA AbstractDomains(const tag_gpu_block_copy &, bool enable_sharing, const AbstractDomains< U2, BasicAlloc2, PropAllocator2, StoreAllocator2 > &other, const BasicAllocator &basic_allocator=BasicAllocator(), const PropAllocator &prop_allocator=PropAllocator(), const StoreAllocator &store_allocator=StoreAllocator())
Definition common_solving.hpp:185
CUDA bool prepare_simplifier(F &f)
Definition common_solving.hpp:375
CUDA void allocate(int num_vars)
Definition common_solving.hpp:286
BasicAllocator basic_allocator
Definition common_solving.hpp:264
BAB< IST, LIStore > IBAB
Definition common_solving.hpp:167
CUDA void meet(AbstractDomains< U2, BasicAlloc2, PropAlloc2, StoreAlloc2 > &other)
Definition common_solving.hpp:581
CUDA bool on_solution_node()
Definition common_solving.hpp:550
CUDA bool on_node()
Definition common_solving.hpp:515
abstract_ptr< LIStore > best
Definition common_solving.hpp:274
battery::shared_ptr< TFormula< basic_allocator_type >, basic_allocator_type > FormulaPtr
Definition common_solving.hpp:419
AbstractDomains(AbstractDomains &&other)=default
abstract_ptr< IStore > store
Definition common_solving.hpp:268
VarEnv< BasicAllocator > env
Definition common_solving.hpp:278
CUDA bool is_printing_intermediate_sol()
Definition common_solving.hpp:525
Simplifier< IPC, BasicAllocator > ISimplifier
Definition common_solving.hpp:164
FormulaPtr prepare_solver()
Definition common_solving.hpp:421
abstract_ptr< IPC > ipc
Definition common_solving.hpp:269
PC< IStore, PropAllocator > IPC
Definition common_solving.hpp:163
CUDA AbstractDomains(const AbstractDomains< U2, BasicAlloc2, PropAllocator2, StoreAllocator2 > &other, const BasicAllocator &basic_allocator=BasicAllocator(), const PropAllocator &prop_allocator=PropAllocator(), const StoreAllocator &store_allocator=StoreAllocator(), const tag_copy_cons &tag=tag_copy_cons{})
Definition common_solving.hpp:218
abstract_ptr< IST > search_tree
Definition common_solving.hpp:273
CUDA void on_failed_node()
Definition common_solving.hpp:557
PropAllocator prop_allocator_type
Definition common_solving.hpp:170
BasicAllocator basic_allocator_type
Definition common_solving.hpp:169
SplitStrategy< IPC, BasicAllocator > Split
Definition common_solving.hpp:165
abstract_ptr< ISimplifier > simplifier
Definition common_solving.hpp:270
abstract_ptr< Split > eps_split
Definition common_solving.hpp:272
void preprocess()
Definition common_solving.hpp:462
abstract_ptr< Split > split
Definition common_solving.hpp:271
Statistics stats
Definition common_solving.hpp:284
SolverOutput< BasicAllocator > solver_output
Definition common_solving.hpp:281
CUDA bool update_solution_stats()
Definition common_solving.hpp:539
PropAllocator prop_allocator
Definition common_solving.hpp:265
typename Universe::local_type universe_type
Definition common_solving.hpp:157
VStore< Universe, StoreAllocator > IStore
Definition common_solving.hpp:162
StoreAllocator store_allocator_type
Definition common_solving.hpp:171
CUDA void print_solution()
Definition common_solving.hpp:529
CUDA void prune()
Definition common_solving.hpp:534
CUDA AbstractDomains(const this_type &other, const BasicAllocator &basic_allocator=BasicAllocator(), const PropAllocator &prop_allocator=PropAllocator(), const StoreAllocator &store_allocator=StoreAllocator())
Definition common_solving.hpp:230
CUDA AbstractDomains(const Configuration< Alloc > &config, const BasicAllocator &basic_allocator=BasicAllocator(), const PropAllocator &prop_allocator=PropAllocator(), const StoreAllocator &store_allocator=StoreAllocator())
Definition common_solving.hpp:238
CUDA void print_mzn_statistics()
Definition common_solving.hpp:568
size_t stop_after_n_nodes
Definition config.hpp:33
battery::string< allocator_type > problem_path
Definition config.hpp:46
CUDA InputFormat input_format() const
Definition config.hpp:194
bool print_intermediate_solutions
Definition config.hpp:31
bool print_ast
Definition config.hpp:37
CUDA void print_mzn_statistics() const
Definition config.hpp:172
bool verbose_solving
Definition config.hpp:36
size_t stop_after_n_solutions
Definition config.hpp:32
bool free_search
Definition config.hpp:34
bool print_statistics
Definition config.hpp:35
size_t subproblems_power
Definition config.hpp:43
Definition statistics.hpp:26
size_t eps_num_subproblems
Definition statistics.hpp:37
size_t fails
Definition statistics.hpp:33
size_t depth_max
Definition statistics.hpp:35
CUDA void print_mzn_statistics() const
Definition statistics.hpp:92
size_t constraints
Definition statistics.hpp:28
CUDA void print_mzn_objective(const auto &obj, bool is_minimization) const
Definition statistics.hpp:118
CUDA void meet(const Statistics &other)
Definition statistics.hpp:62
int64_t interpretation_duration
Definition statistics.hpp:31
CUDA void print_mzn_end_stats() const
Definition statistics.hpp:114
size_t eliminated_variables
Definition statistics.hpp:42
CUDA void print_mzn_final_separator() const
Definition statistics.hpp:133
size_t nodes
Definition statistics.hpp:32
size_t eliminated_formulas
Definition statistics.hpp:43
size_t solutions
Definition statistics.hpp:34
size_t variables
Definition statistics.hpp:27
CUDA void print_mzn_separator() const
Definition statistics.hpp:129
size_t exhaustive
Definition statistics.hpp:36
Definition common_solving.hpp:119
CUDA void deallocate(void *data)
Definition common_solving.hpp:130
UniqueAlloc & operator=(UniqueAlloc &&alloc)=default
UniqueAlloc(const UniqueAlloc &alloc)=default
UniqueAlloc & operator=(const UniqueAlloc &alloc)=default
Alloc allocator
Definition common_solving.hpp:120
CUDA void * allocate(size_t bytes)
Definition common_solving.hpp:127
UniqueAlloc(UniqueAlloc &&alloc)=default
CUDA UniqueAlloc(const Alloc &alloc)
Definition common_solving.hpp:122
Definition common_solving.hpp:136
CUDA void * allocate(size_t bytes)
Definition common_solving.hpp:137
CUDA void deallocate(void *data)
Definition common_solving.hpp:140