box icp_loop_with_nc_bt(box b, contractor const & ctc, SMTConfig & config) { static unsigned prune_count = 0; stack<box> box_stack; stack<int> bisect_var_stack; box_stack.push(b); bisect_var_stack.push(-1); // Dummy var do { // Loop Invariant assert(box_stack.size() == bisect_var_stack.size()); DREAL_LOG_INFO << "new_icp_loop()" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.top(); try { b = ctc.prune(b, config); } catch (contractor_exception & e) { // Do nothing } prune_count++; box_stack.pop(); bisect_var_stack.pop(); if (!b.is_empty()) { // SAT if (b.max_diam() > config.nra_precision) { tuple<int, box, box> splits = b.bisect(); unsigned const index = get<0>(splits); box const & first = get<1>(splits); box const & second = get<2>(splits); if (second.is_bisectable()) { box_stack.push(second); box_stack.push(first); } else { box_stack.push(first); box_stack.push(second); } bisect_var_stack.push(index); bisect_var_stack.push(index); } else { break; } } else { // UNSAT while (box_stack.size() > 0) { assert(box_stack.size() == bisect_var_stack.size()); int bisect_var = bisect_var_stack.top(); ibex::BitSet const & input = ctc.input(); DREAL_LOG_DEBUG << ctc; if (!input[bisect_var]) { box_stack.pop(); bisect_var_stack.pop(); } else { break; } } } } while (box_stack.size() > 0); DREAL_LOG_DEBUG << "prune count = " << prune_count; return b; }
void prune(box & b, contractor & ctc, SMTConfig & config, unordered_set<shared_ptr<constraint>> & used_constraints) { try { ctc.prune(b, config); auto this_used_constraints = ctc.used_constraints(); used_constraints.insert(this_used_constraints.begin(), this_used_constraints.end()); if (config.nra_use_stat) { config.nra_stat.increase_prune(); } } catch (contractor_exception & e) { // Do nothing } }
// Prune a given box b using ctc, but keep the old state of ctc void test_prune(box & b, contractor & ctc, SMTConfig & config) { try { auto const old_output = ctc.output(); auto const old_used_constraints = ctc.used_constraints(); ctc.prune(b, config); ctc.set_output(old_output); ctc.set_used_constraints(old_used_constraints); } catch (contractor_exception & e) { // Do nothing } }
box naive_icp::solve(box b, contractor & ctc, scoped_vec<shared_ptr<constraint>> const & ctrs, SMTConfig & config, BranchHeuristic& brancher) { thread_local static unordered_set<shared_ptr<constraint>> used_constraints; used_constraints.clear(); thread_local static vector<box> solns; thread_local static vector<box> box_stack; solns.clear(); box_stack.clear(); box_stack.push_back(b); do { DREAL_LOG_INFO << "naive_icp::solve - loop" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); box_stack.pop_back(); prune(b, ctc, config, used_constraints); if (!b.is_empty()) { if (config.nra_use_stat) { config.nra_stat.increase_branch(); } vector<int> sorted_dims = brancher.sort_branches(b, ctrs, config); if (sorted_dims.size() > 0) { int const i = sorted_dims[0]; tuple<int, box, box> splits = b.bisect_at(sorted_dims[0]); box const & first = get<1>(splits); box const & second = get<2>(splits); assert(first.get_idx_last_branched() == i); assert(second.get_idx_last_branched() == i); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(i) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } if (config.nra_found_soln >= config.nra_multiple_soln) { break; } solns.push_back(b); } } } while (box_stack.size() > 0); ctc.set_used_constraints(used_constraints); if (config.nra_multiple_soln > 1 && solns.size() > 0) { return solns.back(); } else { assert(!b.is_empty() || box_stack.size() == 0); return b; } }
box naive_icp::solve(box b, contractor const & ctc, SMTConfig & config) { vector<box> solns; vector<box> box_stack; box_stack.push_back(b); do { DREAL_LOG_INFO << "icp_loop()" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); box_stack.pop_back(); try { b = ctc.prune(b, config); if (config.nra_use_stat) { config.nra_stat.increase_prune(); } } catch (contractor_exception & e) { // Do nothing } if (!b.is_empty()) { tuple<int, box, box> splits = b.bisect(config.nra_precision); if (config.nra_use_stat) { config.nra_stat.increase_branch(); } int const i = get<0>(splits); if (i >= 0) { box const & first = get<1>(splits); box const & second = get<2>(splits); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(i) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_found_soln >= config.nra_multiple_soln) { break; } if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } solns.push_back(b); } } } while (box_stack.size() > 0); if (config.nra_multiple_soln > 1 && solns.size() > 0) { return solns.back(); } else { assert(!b.is_empty() || box_stack.size() == 0); // cerr << "BEFORE ADJUST_BOUND\n==================\n" << b << "=========================\n\n\n"; b.adjust_bound(box_stack); // cerr << "AFTER ADJUST_BOUND\n==================\n" << b << "=========================\n\n\n"; return b; } }
box icp_loop(box b, contractor const & ctc, SMTConfig & config) { vector<box> solns; stack<box> box_stack; box_stack.push(b); do { DREAL_LOG_INFO << "icp_loop()" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.top(); box_stack.pop(); try { b = ctc.prune(b, config); } catch (contractor_exception & e) { // Do nothing } if (!b.is_empty()) { if (b.max_diam() > config.nra_precision) { tuple<int, box, box> splits = b.bisect(); unsigned const i = get<0>(splits); box const & first = get<1>(splits); box const & second = get<2>(splits); if (second.is_bisectable()) { box_stack.push(second); box_stack.push(first); } else { box_stack.push(first); box_stack.push(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(i) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_multiple_soln > 1) { cerr << "Find " << config.nra_found_soln << "-th solution:" << endl; cerr << b << endl; } solns.push_back(b); if (config.nra_found_soln >= config.nra_multiple_soln) { break; } } } } while (box_stack.size() > 0); if (solns.size() > 0) { return solns.back(); } else { return b; } }
void parallel_helper_fn(unsigned const id, contractor & c, box & b, SMTConfig & config, pruning_thread_status & s, mutex & m, condition_variable & cv, int & index, atomic_int & tasks_to_run) { s = pruning_thread_status::RUNNING; PARALLEL_LOG << "parallel_helper: thread " << id << " is running. " << tasks_to_run << "tasks to run"; // PARALLEL_LOG << "parallel_helper: thread " << id << " ctc = " << c; try { c.prune(b, config); if (b.is_empty()) { // do something for UNSAT s = pruning_thread_status::UNSAT; PARALLEL_LOG << "parallel_helper: thread " << id << " is UNSAT."; } else { s = pruning_thread_status::SAT; PARALLEL_LOG << "parallel_helper: thread " << id << " is SAT."; // do something for SAT } } catch (contractor_exception & e) { // handle for exception s = pruning_thread_status::EXCEPTION; PARALLEL_LOG << "parallel_helper: thread " << id << " throws an contractor_exception: " << e.what(); } catch (thread_interrupted & e) { // just killed s = pruning_thread_status::KILLED; tasks_to_run--; PARALLEL_LOG << "parallel_helper: thread " << id << " is KILLED."; return; } catch (exception & e) { tasks_to_run--; PARALLEL_LOG << "parallel_helper: thread " << id << " throws an unexpected exception: " << e.what(); return; } PARALLEL_LOG << "parallel_helper: thread " << id << " is waiting for a mutex lock"; unique_lock<mutex> lk(m); PARALLEL_LOG << "parallel_helper: thread " << id << " get a lock"; index = id; tasks_to_run--; PARALLEL_LOG << "parallel_helper: thread " << id << " unlocks"; lk.unlock(); cv.notify_one(); PARALLEL_LOG << "parallel_helper: thread " << id << " notifies CV"; return; }
box ncbt_icp::solve(box b, contractor & ctc, SMTConfig & config) { thread_local static unordered_set<shared_ptr<constraint>> used_constraints; used_constraints.clear(); static unsigned prune_count = 0; thread_local static vector<box> box_stack; box_stack.clear(); box_stack.push_back(b); do { // Loop Invariant DREAL_LOG_INFO << "ncbt_icp::solve - loop" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); try { ctc.prune(b, config); auto const this_used_constraints = ctc.used_constraints(); used_constraints.insert(this_used_constraints.begin(), this_used_constraints.end()); if (config.nra_use_stat) { config.nra_stat.increase_prune(); } } catch (contractor_exception & e) { // Do nothing } prune_count++; box_stack.pop_back(); if (!b.is_empty()) { // SAT tuple<int, box, box> splits = b.bisect(config.nra_precision); if (config.nra_use_stat) { config.nra_stat.increase_branch(); } int const index = get<0>(splits); if (index >= 0) { box const & first = get<1>(splits); box const & second = get<2>(splits); assert(first.get_idx_last_branched() == index); assert(second.get_idx_last_branched() == index); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } } else { break; } } else { // UNSAT (b is emptified by pruning operators) // If this bisect_var is not used in all used // constraints, this box is safe to be popped. thread_local static unordered_set<Enode *> used_vars; used_vars.clear(); for (auto used_ctr : used_constraints) { auto this_used_vars = used_ctr->get_vars(); used_vars.insert(this_used_vars.begin(), this_used_vars.end()); } while (box_stack.size() > 0) { int const bisect_var = box_stack.back().get_idx_last_branched(); assert(bisect_var >= 0); // If this bisect_var is not used in all used // constraints, this box is safe to be popped. if (used_vars.find(b.get_vars()[bisect_var]) != used_vars.end()) { // DREAL_LOG_FATAL << b.get_vars()[bisect_var] << " is used in " // << *used_ctr << " and it's not safe to skip"; break; } // DREAL_LOG_FATAL << b.get_vars()[bisect_var] << " is not used and it's safe to skip this box" // << " (" << box_stack.size() << ")"; box_stack.pop_back(); } } } while (box_stack.size() > 0); DREAL_LOG_DEBUG << "prune count = " << prune_count; ctc.set_used_constraints(used_constraints); return b; }
box multiheuristic_icp::solve(box bx, contractor & ctc, scoped_vec<shared_ptr<constraint>> const & ctrs, SMTConfig & config, vector<reference_wrapper<BranchHeuristic>> heuristics) { // don't use yet, since contractor is not yet threadsafe static vector<box> solns; solns.clear(); mutex mu; box hull = bx; // hull is a shared box, that's used by all dothreads, // contains the intersection of the unions of the possible regions for each heuristic. // Therefore, any solution must be in hull. atomic_bool solved; unordered_set<shared_ptr<constraint>> all_used_constraints; prune(hull, ctc, config, all_used_constraints); vector<thread> threads; auto dothread = [&](BranchHeuristic & heuristic) { #define PRUNEBOX(x) prune((x), ctc, config, used_constraints) thread_local static unordered_set<shared_ptr<constraint>> used_constraints; thread_local static vector<box> box_stack; thread_local static vector<box> hull_stack; // nth box in hull_stack contains hull of first n boxes in box_stack box_stack.clear(); hull_stack.clear(); used_constraints.clear(); auto pushbox = [&](box b) { box_stack.push_back(b); // copies hull into vector if (hull_stack.size() > 0) { b.hull(hull_stack.back()); } // maintain hull_stack invariant hull_stack.push_back(b); }; auto popbox = [&] { box b = box_stack.back(); box_stack.pop_back(); hull_stack.pop_back(); return b; }; mu.lock(); box b = hull; mu.unlock(); pushbox(b); do { b = popbox(); mu.lock(); b.intersect(hull); // TODO(clhuang): is contractor threadsafe??? PRUNEBOX(b); mu.unlock(); if (!b.is_empty()) { vector<int> sorted_dims = heuristic.sort_branches(b, ctrs, config); if (config.nra_use_stat) { config.nra_stat.increase_branch(); } if (sorted_dims.size() > 0) { int bisectdim = sorted_dims[0]; auto splits = b.bisect_at(bisectdim); box first = get<1>(splits); box second = get<2>(splits); assert(bisectdim != -1); assert(first.get_idx_last_branched() == bisectdim); assert(second.get_idx_last_branched() == bisectdim); if (second.is_bisectable()) { pushbox(second); pushbox(first); } else { pushbox(first); pushbox(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(bisectdim) << "]" << endl; } } else { mu.lock(); config.nra_found_soln++; solns.push_back(b); if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } if (config.nra_found_soln >= config.nra_multiple_soln) { solved = true; mu.unlock(); break; } mu.unlock(); } } // hull_stack, hopefully shrunk if (!hull_stack.empty()) { mu.lock(); hull.intersect(hull_stack.back()); mu.unlock(); } } while (box_stack.size() > 0 && !solved); mu.lock(); if (config.nra_found_soln == 0) { solved = true; // needed if unsat solns.push_back(b); // would be empty } // update all_used_constraints for (auto x : used_constraints) { all_used_constraints.insert(x); } mu.unlock(); #undef PRUNEBOX }; for (auto& heuristic : heuristics) { threads.push_back(thread(dothread, heuristic)); } for (auto& t : threads) { t.join(); } ctc.set_used_constraints(all_used_constraints); return solns.back(); }
box multiprune_icp::solve(box b, contractor & ctc, scoped_vec<shared_ptr<constraint>> const & ctrs, SMTConfig & config, BranchHeuristic& brancher, unsigned num_try) { #define PRUNEBOX(x) prune((x), ctc, config, used_constraints) thread_local static unordered_set<shared_ptr<constraint>> used_constraints; used_constraints.clear(); thread_local static vector<box> solns; thread_local static vector<box> box_stack; solns.clear(); box_stack.clear(); PRUNEBOX(b); box_stack.push_back(b); do { DREAL_LOG_INFO << "multiprune_icp::solve - loop" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); box_stack.pop_back(); if (!b.is_empty()) { vector<int> sorted_dims = brancher.sort_branches(b, ctrs, config); if (sorted_dims.size() > num_try) { sorted_dims = vector<int>(sorted_dims.begin(), sorted_dims.begin()+num_try); } if (config.nra_use_stat) { config.nra_stat.increase_branch(); } if (sorted_dims.size() > 0) { int bisectdim = -1; box first = b; box second = b; double score = -INFINITY; for (int dim : sorted_dims) { tuple<int, box, box> splits = b.bisect_at(dim); box a1 = get<1>(splits); box a2 = get<2>(splits); PRUNEBOX(a1); PRUNEBOX(a2); double cscore = -a1.volume() * a2.volume(); if (cscore > score || bisectdim == -1) { first.hull(second); a1.intersect(first); a2.intersect(first); first = a1; second = a2; bisectdim = dim; score = cscore; } else { a1.hull(a2); first.intersect(a1); second.intersect(a1); } } assert(bisectdim != -1); assert(first.get_idx_last_branched() == bisectdim); assert(second.get_idx_last_branched() == bisectdim); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(bisectdim) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } if (config.nra_found_soln >= config.nra_multiple_soln) { break; } solns.push_back(b); } } } while (box_stack.size() > 0); ctc.set_used_constraints(used_constraints); if (config.nra_multiple_soln > 1 && solns.size() > 0) { return solns.back(); } else { assert(!b.is_empty() || box_stack.size() == 0); return b; } #undef PRUNEBOX }
opensmt_expr vars_t[2] = {x_t, p_t}; opensmt_expr vars_0[2] = {x_0, p_0}; opensmt_expr assert5 = opensmt_mk_integral(ctx, vars_t, zero, time_0, vars_0, 2, "flow_1"); integral_constraint ic(static_cast<Enode*>(assert5), 1, static_cast<Enode*>(zero), static_cast<Enode*>(time_0), {static_cast<Enode*>(x_0), static_cast<Enode*>(p_0)}, {}, {static_cast<Enode*>(x_t), static_cast<Enode*>(p_t)}, {}, {}, {make_pair(static_cast<Enode*>(vars[0]), static_cast<Enode*>(rhs_x)), make_pair(static_cast<Enode*>(vars[1]), static_cast<Enode*>(rhs_p))}); auto oc = make_shared<ode_constraint>(ic); contractor c = mk_contractor_capd_full(b, oc, ode_direction::FWD); cerr << *oc << endl; cerr << b << endl; auto input_before = c.input(); auto output_before = c.output(); cerr << "Input (BEFORE) : "; input_before.display(cerr) << endl; cerr << "Output (BEFORE) : "; output_before.display(cerr) << endl; c.prune(b, opensmt_ctx->getConfig()); cerr << b << endl; auto input_after = c.input(); auto output_after = c.output(); cerr << "Input (AFTER) : "; input_after.display(cerr) << endl; cerr << "Output (AFTER) : "; output_after.display(cerr) << endl; for (auto ctc : c.used_constraints()) { cerr << "Used constraint : " << *ctc << endl;
box ncbt_icp::solve(box b, contractor const & ctc, SMTConfig & config) { static unsigned prune_count = 0; vector<box> box_stack; vector<int> bisect_var_stack; box_stack.push_back(b); bisect_var_stack.push_back(-1); // Dummy var do { // Loop Invariant assert(box_stack.size() == bisect_var_stack.size()); DREAL_LOG_INFO << "new_icp_loop()" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); try { b = ctc.prune(b, config); if (config.nra_use_stat) { config.nra_stat.increase_prune(); } } catch (contractor_exception & e) { // Do nothing } prune_count++; box_stack.pop_back(); bisect_var_stack.pop_back(); if (!b.is_empty()) { // SAT tuple<int, box, box> splits = b.bisect(config.nra_precision); if (config.nra_use_stat) { config.nra_stat.increase_branch(); } int const index = get<0>(splits); if (index >= 0) { box const & first = get<1>(splits); box const & second = get<2>(splits); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } bisect_var_stack.push_back(index); bisect_var_stack.push_back(index); } else { break; } } else { // UNSAT while (box_stack.size() > 0) { assert(box_stack.size() == bisect_var_stack.size()); int bisect_var = bisect_var_stack.back(); ibex::BitSet const & input = ctc.input(); DREAL_LOG_DEBUG << ctc; if (!input[bisect_var]) { box_stack.pop_back(); bisect_var_stack.pop_back(); } else { break; } } } } while (box_stack.size() > 0); DREAL_LOG_DEBUG << "prune count = " << prune_count; b.adjust_bound(box_stack); return b; }
box naive_icp::solve(box b, contractor & ctc, SMTConfig & config) { thread_local static std::unordered_set<std::shared_ptr<constraint>> used_constraints; used_constraints.clear(); thread_local static vector<box> solns; thread_local static vector<box> box_stack; solns.clear(); box_stack.clear(); box_stack.push_back(b); do { DREAL_LOG_INFO << "naive_icp::solve - loop" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); box_stack.pop_back(); try { ctc.prune(b, config); auto this_used_constraints = ctc.used_constraints(); used_constraints.insert(this_used_constraints.begin(), this_used_constraints.end()); if (config.nra_use_stat) { config.nra_stat.increase_prune(); } } catch (contractor_exception & e) { // Do nothing } if (!b.is_empty()) { tuple<int, box, box> splits = b.bisect(config.nra_precision); if (config.nra_use_stat) { config.nra_stat.increase_branch(); } int const i = get<0>(splits); if (i >= 0) { box const & first = get<1>(splits); box const & second = get<2>(splits); assert(first.get_idx_last_branched() == i); assert(second.get_idx_last_branched() == i); if (second.is_bisectable()) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(i) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } if (config.nra_found_soln >= config.nra_multiple_soln) { break; } solns.push_back(b); } } } while (box_stack.size() > 0); ctc.set_used_constraints(used_constraints); if (config.nra_multiple_soln > 1 && solns.size() > 0) { return solns.back(); } else { assert(!b.is_empty() || box_stack.size() == 0); return b; } }
box sample_icp::solve(box init_b, contractor const & ctc, SMTConfig & config ) { vector<box> solns; vector<box> box_stack; box b = init_b; box_stack.push_back(b); std::map<unsigned int, unsigned int> nempty; // Number of empty boxes at particular depth int nconflicts = 0; // Random Restarts // I need a container for my stack that will allow me to add elements to the end, // i.e lower depth means its at the end and pop from either end // std::set<box, BoxComparator> box_stack; do { DREAL_LOG_INFO << "icp_loop()" << "\t" << "box stack Size = " << box_stack.size(); b = box_stack.back(); box_stack.pop_back(); // std::cout << "Depth: " << b.depth << std::endl; try { b = ctc.prune(b, config); } catch (contractor_exception & e) { // Do nothing } if (!b.is_empty()) { tuple<int, box, box> splits = b.bisect(config.nra_precision); int const i = get<0>(splits); // std::cout << "i is" << i << std::endl; if (i >= 0) { box & first = get<1>(splits); box & second = get<2>(splits); first.depth = b.depth + 1; second.depth = b.depth + 1; bool leftright = random_icp::random_bool(); // std::cout << "left or right? " << leftright << std::endl; if (leftright) { box_stack.push_back(second); box_stack.push_back(first); } else { box_stack.push_back(first); box_stack.push_back(second); } if (config.nra_proof) { config.nra_proof_out << "[branched on " << b.get_name(i) << "]" << endl; } } else { config.nra_found_soln++; if (config.nra_found_soln >= config.nra_multiple_soln) { break; } if (config.nra_multiple_soln > 1) { // If --multiple_soln is used output_solution(b, config, config.nra_found_soln); } solns.push_back(b); } } else { // std::cout << "Backtracking at Depth: " << b.depth << std::endl; nempty[b.depth] += 1; nconflicts += 1; int nconflicts_before_restart = 200; if (nconflicts > nconflicts_before_restart) { std::cout << "Restarting" << std::endl; box_stack.empty(); box_stack.push_back(init_b); nempty.empty(); nconflicts = 0; continue; } } } while (box_stack.size() > 0); if (config.nra_multiple_soln > 1 && solns.size() > 0) { return solns.back(); } else { assert(!b.is_empty() || box_stack.size() == 0); // cerr << "BEFORE ADJUST_BOUND\n==================\n" << b << "=========================\n\n\n"; b.adjust_bound(box_stack); // cerr << "AFTER ADJUST_BOUND\n==================\n" << b << "=========================\n\n\n"; double q = proposal_prob(b.depth, nempty); b.logprob = q; return b; } }