void contractor_fixpoint::worklist_fixpoint_alg(contractor_status & cs) { thread_local static queue<unsigned> q; q = queue<unsigned>(); // empty queue thread_local static ibex::BitSet ctc_bitset = ibex::BitSet::empty(m_clist.size()); ctc_bitset.clear(); // Add all contractors to the queue. for (int i = m_clist.size() - 1; i >= 0; --i) { contractor & c_i = m_clist[i]; contractor_status_guard csg(cs); c_i.prune(cs); if (cs.m_box.is_empty()) { return; } ibex::BitSet const & output_i = cs.m_output; if (output_i.empty()) { continue; } q.push(i); ctc_bitset.add(i); } if (q.size() == 0) { return; } // Fixed Point Loop thread_local static box old_box(cs.m_box); do { interruption_point(); old_box = cs.m_box; unsigned const idx = q.front(); q.pop(); ctc_bitset.remove(idx); assert(idx < m_clist.size()); contractor & c = m_clist[idx]; contractor_status_guard csg(cs); c.prune(cs); if (cs.m_box.is_empty()) { return; } auto const & c_output = cs.m_output; if (!c_output.empty()) { // j-th dimension is changed as a result of pruning // need to add a contractor which takes j-th dim as an input for (int j = c_output.min(); j <= c_output.max(); ++j) { if (!c_output.contain(j)) { continue; } for (unsigned k = 0; k < m_clist.size(); ++k) { // Only add if it's not in the current queue if (!ctc_bitset.contain(k)) { contractor const & c_k = m_clist[k]; if (c_k.get_input().contain(j)) { q.push(k); ctc_bitset.add(k); } } } } } } while (q.size() > 0 && cs.m_box.max_diam() >= cs.m_config.nra_precision && !m_term_cond(old_box, cs.m_box)); return; }
box contractor_fixpoint::worklist_fixpoint_alg(box old_box, SMTConfig & config) const { box new_box = old_box; m_input = ibex::BitSet::empty(old_box.size()); m_output = ibex::BitSet::empty(old_box.size()); // Add all contractors to the queue. unordered_set<contractor> c_set; queue<contractor> q; for (contractor const & c : m_clist) { if (c_set.find(c) == c_set.end()) { q.push(c); c_set.insert(c); } } unsigned const num_initial_ctcs = c_set.size(); unsigned count = 0; // Fixed Point Loop do { old_box = new_box; contractor const & c = q.front(); new_box = c.prune(new_box, config); count++; m_input.union_with(c.input()); m_output.union_with(c.output()); unordered_set<constraint const *> const & used_constraints = c.used_constraints(); m_used_constraints.insert(used_constraints.begin(), used_constraints.end()); if (new_box.is_empty()) { return new_box; } c_set.erase(c); q.pop(); vector<bool> diff_dims = new_box.diff_dims(old_box); for (unsigned i = 0; i < diff_dims.size(); i++) { if (diff_dims[i]) { for (contractor const & c : m_clist) { if (c.input()[i]) { if (c_set.find(c) == c_set.end()) { q.push(c); c_set.insert(c); } break; } } } } } while (q.size() > 0 && ((count < num_initial_ctcs) || !m_term_cond(old_box, new_box))); return new_box; }
box contractor_fixpoint::naive_fixpoint_alg(box old_box, SMTConfig & config) const { box new_box = old_box; m_input = ibex::BitSet::empty(old_box.size()); m_output = ibex::BitSet::empty(old_box.size()); // Fixed Point Loop do { old_box = new_box; for (contractor const & c : m_clist) { new_box = c.prune(new_box, config); m_input.union_with(c.input()); m_output.union_with(c.output()); unordered_set<constraint const *> const & used_constraints = c.used_constraints(); m_used_constraints.insert(used_constraints.begin(), used_constraints.end()); if (new_box.is_empty()) { return new_box; } } } while (!m_term_cond(old_box, new_box)); return new_box; }
void contractor_fixpoint::naive_fixpoint_alg(contractor_status & cs) { // First Iteration (run always) for (contractor & c : m_clist) { interruption_point(); c.prune(cs); if (cs.m_box.is_empty()) { return; } } box old_box = cs.m_box; unsigned i = 0; // Next Iterations (stop when 1) a box is smaller enough or 2) termination condition holds do { interruption_point(); old_box = cs.m_box; contractor & c = m_clist[i]; c.prune(cs); if (cs.m_box.is_empty()) { return; } i = (i + 1) % m_clist.size(); } while (cs.m_box.max_diam() > cs.m_config.nra_precision && !m_term_cond(old_box, cs.m_box)); return; }
void contractor_fixpoint::worklist_fixpoint_alg(contractor_status & cs) { queue<int> q; ibex::BitSet ctc_bitset(m_clist.size()); // Add all contractors to the queue. for (unsigned i = 0; i < m_clist.size(); ++i) { contractor & c_i = m_clist[i]; contractor_status_guard csg(cs); c_i.prune(cs); if (cs.m_box.is_empty()) { return; } ibex::BitSet const & output_i = cs.m_output; if (!output_i.empty()) { assert(!ctc_bitset.contain(i)); q.push(i); ctc_bitset.add(i); } } if (q.size() == 0) { return; } // Fixed Point Loop do { interruption_point(); unsigned const idx = q.front(); q.pop(); ctc_bitset.remove(idx); assert(!ctc_bitset.contain(idx)); assert(idx < m_clist.size()); contractor & c = m_clist[idx]; m_old_box = cs.m_box; contractor_status_guard csg(cs); c.prune(cs); if (cs.m_box.is_empty()) { return; } auto const & c_output = cs.m_output; if (!c_output.empty()) { // j-th dimension is changed as a result of pruning // need to add a contractor which takes j-th dim as an input int j = c_output.min(); do { if (!c_output.contain(j)) { continue; } for (int const dependent_ctc_id : m_dep_map[j]) { if (!ctc_bitset.contain(dependent_ctc_id)) { q.push(dependent_ctc_id); ctc_bitset.add(dependent_ctc_id); } } j = c_output.next(j); } while (j < c_output.max()); } } while (q.size() > 0 && (m_old_box != cs.m_box) && cs.m_box.is_bisectable(cs.m_config.nra_precision) && !m_term_cond(m_old_box, cs.m_box)); return; }