// Returns FALSE if clause is always satisfied ('out_clause' should not be used). bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause) { merges++; out_clause.clear(); bool ps_smallest = _ps.size() < _qs.size(); const Clause& ps = ps_smallest ? _qs : _ps; const Clause& qs = ps_smallest ? _ps : _qs; for (int i = 0; i < qs.size(); i++){ if (var(qs[i]) != v){ for (int j = 0; j < ps.size(); j++) if (var(ps[j]) == var(qs[i])) { if (ps[j] == ~qs[i]) return false; else goto next; } out_clause.push(qs[i]); } next:; } for (int i = 0; i < ps.size(); i++) if (var(ps[i]) != v) out_clause.push(ps[i]); return true; }
void getFac(int n , vec &p, vec &a){ p.clear(); a.clear(); while(n > 1){ int small = n ; for(int i = 0 ; i < psiz && prime[i] * prime[i] <= n ; ++ i) if(n % prime[i] == 0){ small = prime[i]; break;} int cnt = 0; while(n % small == 0){ cnt ++ ; n /= small; } p.push_back(small); a.push_back(cnt); } }
/*_________________________________________________________________________________________________ | | analyzeFinal : (p : Lit) -> [void] | | Description: | Specialized analysis procedure to express the final conflict in terms of assumptions. | Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and | stores the result in 'out_conflict'. |________________________________________________________________________________________________@*/ void MiniSATP::analyzeFinal(Lit p, vec<Lit>& out_conflict) { out_conflict.clear(); out_conflict.push(p); if (decisionLevel() == 0) return; seen[var(p)] = 1; for (int i = trail.size()-1; i >= trail_lim[0]; i--){ Var x = var(trail[i]); if (seen[x]){ if (reason[x] == NULL){ assert(level[x] > 0); out_conflict.push(~trail[i]); }else{ Clause& c = *reason[x]; for (int j = 1; j < c.size(); j++) if (level[var(c[j])] > 0) seen[var(c[j])] = 1; } seen[x] = 0; } } seen[var(p)] = 0; }
static void buildSorter(vec<Formula>& ps, vec<int>& Cs, vec<Formula>& carry , vec<Formula>& out_sorter, PBOptions* options) { out_sorter.clear(); vec<Formula> Xs; for (int i = 0; i < ps.size(); i++) for (int j = 0; j < Cs[i]; j++) Xs.push(ps[i]); unarySortAdd(Xs, carry, out_sorter,options->opt_use_shortCuts); }
static void getStaticEdges(WellFounded* wf, int v, vec<int>& edges) { edges.clear(); for (int i = 0; i < wf->head_occ_rules[v].size(); i++) { ConjRule& r = *wf->head_occ_rules[v][i]; for (int j = 0; j < r.sz; j++) { edges.push(r.body[j]); } } }
static void buildSorter(vec<Formula>& ps, vec<int>& Cs, vec<Formula>& out_sorter) { out_sorter.clear(); for (int i = 0; i < ps.size(); i++) for (int j = 0; j < Cs[i]; j++) out_sorter.push(ps[i]); oddEvenSort(out_sorter); // (overwrites inputs) }
static void readClause(char*& in, VSolver& S, vec<Lit>& lits) { int parsed_lit, var; lits.clear(); for (;;){ parsed_lit = parseInt(in); if (parsed_lit == 0) break; var = abs(parsed_lit)-1; lits.push( (parsed_lit > 0) ? Lit(var) : ~Lit(var) ); } }
static void readClause(B& in, Solver& S, vec<Lit>& lits) { int parsed_lit, var; lits.clear(); for (;;){ parsed_lit = parseInt(in); if (parsed_lit == 0) break; var = abs(parsed_lit)-1; while (var >= S.nVars()) S.newVar(); lits.push( (parsed_lit > 0) ? Lit(var) : ~Lit(var) ); } }
static void getDynamicEdges(WellFounded* wf, int v, vec<int>& edges) { edges.clear(); for (int i = 0; i < wf->head_occ_rules[v].size(); i++) { ConjRule& r = *wf->head_occ_rules[v][i]; if (r.isFalse()) continue; edges.push(r.body[r.w]); } // fprintf(stderr, "%d: ", v); // for (int i = 0; i < edges.size(); i++) fprintf(stderr, "%d ", edges[i]); // fprintf(stderr, "\n"); }
static void buildSorter(vec<Formula>& ps, vec<int>& Cs, vec<Formula>& out_sorter, PBOptions* options) { out_sorter.clear(); for (int i = 0; i < ps.size(); i++) for (int j = 0; j < Cs[i]; j++) out_sorter.push(ps[i]); if (options->opt_sorting_network_encoding==pairwiseSortEncoding) pw_sort(out_sorter); else oddEvenSort(out_sorter); // (overwrites inputs) }
void XorSubsumer::addFromSolver(vec<XorClause*>& cs) { clauseID = 0; clauses.clear(); XorClause **i = cs.getData(); for (XorClause **end = i + cs.size(); i != end; i++) { if (i+1 != end) __builtin_prefetch(*(i+1)); linkInClause(**i); } cs.clear(); cs.push(NULL); //HACK --to force xor-propagation }
void clearPropState() { in_queue = false; dead_rules.clear(); if (sat.confl) { for (int i = 0; i < no_support.size(); i++) { for ( ; pufhead[i] < no_support[i].size(); pufhead[i]++) { no_support_bool[no_support[i][pufhead[i]]] = false; } no_support[i].clear(); ushead[i] = 0; pufhead[i] = 0; } } }
static Int readClauseCnf(B& in, mS& S, vec<Lit>& lits,bool wcnf) { int parsed_lit, var; Int weight=1; if(wcnf) weight = parseIntCnf(in); lits.clear(); for (;;){ parsed_lit = toint(parseIntCnf(in)); if (parsed_lit == 0) break; var = abs(parsed_lit)-1; while (var >= S.nVars()) S.newVar(); lits.push( (parsed_lit > 0) ? Lit(var) : ~Lit(var) ); } return weight; }
void rippleAdder(const vec<Formula>& xs, const vec<Formula>& ys, vec<Formula>& out) { Formula c = _0_; out.clear(); for (int i = 0; i < max(xs.size(),ys.size()); i++){ Formula x = i < xs.size() ? xs[i] : _0_; Formula y = i < ys.size() ? ys[i] : _0_; out.push(FAs(x,y,c)); c = FAc(x,y,c); } out.push(c); while (out.last() == _0_) out.pop(); }
void XorSubsumer::addFromSolver(vec<XorClause*>& cs) { clauseID = 0; clauses.clear(); XorClause **i = cs.getData(); for (XorClause **end = i + cs.size(); i != end; i++) { if (i+1 != end) __builtin_prefetch(*(i+1), 1, 1); linkInClause(**i); if ((*i)->getVarChanged() || (*i)->getStrenghtened()) (*i)->calcXorAbstraction(); } cs.clear(); cs.push(NULL); //HACK --to force xor-propagation }
/** @brief Reads in a clause and puts it in lit @p[out] lits */ void DimacsParser::readClause(StreamBuffer& in, vec<Lit>& lits) { int32_t parsed_lit; Var var; uint32_t len; lits.clear(); for (;;) { parsed_lit = parseInt(in, len); if (parsed_lit == 0) break; var = abs(parsed_lit)-1; if (!debugNewVar) { if (var >= ((uint32_t)1)<<25) { std::cout << "ERROR! Variable requested is far too large: " << var << std::endl; exit(-1); } while (var >= solver->nVars()) solver->newVar(); } lits.push( (parsed_lit > 0) ? Lit(var, false) : Lit(var, true) ); } }
/** @brief Reads in a clause and puts it in lit @p[out] lits */ void DimacsParser::readClause(StreamBuffer& in, vec<Lit>& lits) throw (DimacsParseError) { int32_t parsed_lit; Var var; uint32_t len; lits.clear(); for (;;) { parsed_lit = parseInt(in, len); if (parsed_lit == 0) break; var = abs(parsed_lit)-1; if (!debugNewVar) { if (var >= ((uint32_t)1)<<25) { std::ostringstream ostr; ostr << "Variable requested is far too large: " << var; throw DimacsParseError(ostr.str()); } while (var >= solver->nVars()) solver->newVar(); } lits.push( (parsed_lit > 0) ? Lit(var, false) : Lit(var, true) ); } }
bool propagate() { // find all unsupported if (DEBUG) printf("propagating\n"); for (int i = 0; i < dead_rules.size(); i++) killSupport(rules[dead_rules[i]]); for (int i = 0; i < no_support.size(); i++) { while (ushead[i] < no_support[i].size()) { int x = no_support[i][ushead[i]++]; for (int j = 0; j < body_occ_rules[x].size(); j++) { killSupport(body_occ_rules[x][j]); } } } if (DEBUG) printf("Decision level: %d\n", engine.decisionLevel()); if (DEBUG) printf("No support: "); if (DEBUG) for (int i = 0; i < no_support.size(); i++) { for (int j = 0; j < no_support[i].size(); j++) { printf("%d, ", no_support[i][j]); } } if (DEBUG) printf("\n"); int start = -1; // pick one to start building unfounded set for (int i = 0; i < no_support.size(); i++) { for ( ; pufhead[i] < no_support[i].size(); pufhead[i]++) { int x = no_support[i][pufhead[i]]; if (no_support_bool[x] && !BoolView(lits[x]).isFalse()) { start = x; break; } } if (start != -1) break; } // if all processed, we're done if (start == -1) { if (DEBUG) printf("all done\n"); for (int i = 0; i < no_support.size(); i++) { no_support[i].clear(); ushead[i] = 0; pufhead[i] = 0; } return true; } // start building unfounded set ufset.clear(); ufset.push(start); ufset_bool[start] = true; if (DEBUG) printf("starting with %d\n", start); nfset.clear(); int nfshead = 0; for (int uf = 0; uf < ufset.size(); uf++) { int h = ufset[uf]; if (!no_support_bool[h]) { fprintf(stderr, "not no_support %d!\n", h); for (int k = 0; k < ufset.size(); k++) fprintf(stderr, "%d ", ufset[k]); fprintf(stderr, "- %d %d\n", uf, h); } assert(no_support_bool[h]); // add rules with h as head for (int i = 0; i < head_occ_rules[h].size(); i++) { if (DEBUG) printf("checking %dth rule for %d\n", i, h); ConjRule *r = head_occ_rules[h][i]; if (r->isFalse()) continue; r->w = r->sz-1; if (DEBUG) printf("proping rule\n"); if (propRule(*r)) break; } // propagate nfset while (nfshead < nfset.size()) { int x = nfset[nfshead++]; for (int i = 0; i < watches[x].size(); i++) { ConjRule *r = watches[x][i]; // if head already founded by another rule, ignore if (!no_support_bool[r->head]) continue; if (r->isFalse()) continue; r->w--; propRule(*r); } watches[x].clear(); } } // we have now found an unfounded set! i.e., everything in ufset which is still not justified // if empty, should jump straight back up! // calc dynamic SCC // fprintf(stderr, "calc Dyn SCC\n"); index = 0; assert(S.size() == 0); for (int i = 0; i < indices.size(); i++) { indices[i] = -1; lowlink[i] = -1; } sccs.clear(); for (int i = 0; i < ufset.size(); i++) { int h = ufset[i]; if (!no_support_bool[h]) continue; if (indices[h] != -1) continue; // fprintf(stderr, "root %d ", h); strongconnect(h, &getDynamicEdges); } assert(S.size() == 0); // if (sccs.size() > 0) fprintf(stderr, "d %d ", sccs.size()); // create an explanation vec<Lit> ps(1); for (int i = 0; i < ufset.size(); i++) { ufset_bool[ufset[i]] = false; watches[ufset[i]].clear(); int h = ufset[i]; if (!no_support_bool[h]) continue; for (int i = 0; i < head_occ_rules[h].size(); i++) { ConjRule *r = head_occ_rules[h][i]; if (r->isFalse()) { ps.push(r->body_lit); } } } Clause *expl = Reason_new(ps.size()); for (int i = 1; i < ps.size(); i++) (*expl)[i] = ps[i]; for (int i = 0; i < ufset.size(); i++) { int h = ufset[i]; if (!no_support_bool[h]) continue; if (DEBUG) printf("making %d false\n", h); if (ADD_CLAUSES) { ps[0] = ~lits[h]; sat.addClause(*Clause_new(ps, false), false); } assert(!BoolView(lits[h]).isFalse()); if (!BoolView(lits[h]).setVal(0, expl)) return false; no_support_bool[h] = false; } if (DEBUG) printf("reawaken\n"); // reawaken, this is not quite correct engine.p_queue[priority].push(this); return true; }
void init() { if (PREPROCESS) preprocess(); else { for (int i = 0; i < raw_heads.size(); i++) getId(raw_heads[i]); } in_S.growTo(lits.size(), false); scc_ids.growTo(lits.size(), -1); indices.growTo(lits.size(), -1); lowlink.growTo(lits.size(), -1); head_occ_rules.growTo(lits.size()); body_occ_rules.growTo(lits.size()); watches.growTo(lits.size()); support.growTo(lits.size(), NULL); no_support_bool.growTo(lits.size(), false); ufset_bool.growTo(lits.size(), false); // form rules for (int i = 0; i < raw_heads.size(); i++) { if (raw_heads[i] == bv_false) continue; if (raw_bl[i] == bv_false) raw_bl[i] = newBoolVar(); if (FLIP_NEG) { vec<BoolView> b; for (int j = 0; j < raw_posb[i].size(); j++) b.push(raw_posb[i][j]); for (int j = 0; j < raw_negb[i].size(); j++) b.push(raw_negb[i][j]); array_bool_and(b, raw_bl[i]); } else { array_bool_and(raw_posb[i], raw_negb[i], raw_bl[i]); } if (so.well_founded) raw_bl[i].attach(this, rules.size(), EVENT_U); vec<int> b; for (int j = 0; j < raw_posb[i].size(); j++) { map<int,int>::iterator it = lit_to_index.find(toInt((Lit) raw_posb[i][j])); if (it == lit_to_index.end()) continue; b.push(it->second); } ConjRule *r = ConjRule_new(getId(raw_heads[i]), b, raw_bl[i]); rules.push(r); } for (int i = 0; i < rules.size(); i++) { ConjRule& r = *rules[i]; for (int j = 0; j < r.sz; j++) { body_occ_rules[r.body[j]].push(&r); } head_occ_rules[r.head].push(&r); } // post array_bool_or's for (int i = 0; i < lits.size(); i++) { vec<BoolView> b; for (int j = 0; j < head_occ_rules[i].size(); j++) { b.push(BoolView(head_occ_rules[i][j]->body_lit)); if (!COMPLETE) bool_rel(~BoolView(head_occ_rules[i][j]->body_lit), BRT_OR, BoolView(lits[i])); } if (COMPLETE) array_bool_or(b, BoolView(lits[i])); } // calc SCC's if (CALC_SCC) { index = 0; assert(S.size() == 0); for (int i = 0; i < indices.size(); i++) { indices[i] = -1; lowlink[i] = -1; } sccs.clear(); for (int i = 0; i < lits.size(); i++) { if (indices[i] == -1) { // printf("SCC root: %d\n", i); strongconnect(i, &getStaticEdges); // printf("num scc's: %d\n", scc_id); } } assert(S.size() == 0); for (int i = 0; i < sccs.size(); i++) { for (int j = 0; j < sccs[i].size(); j++) { scc_ids[sccs[i][j]] = i; } } } else { sccs.push(); for (int i = 0; i < lits.size(); i++) { scc_ids[i] = 0; } } no_support.growTo(sccs.size()); ushead.growTo(sccs.size(), 0); pufhead.growTo(sccs.size(), 0); for (int i = 0; i < lits.size(); i++) { if (BoolView(lits[i]).isFalse()) continue; assert(scc_ids[i] >= 0); assert(scc_ids[i] < no_support.size()); // fprintf(stderr, "%d ", scc_ids[i]); no_support[scc_ids[i]].push(i); no_support_bool[i] = true; } // if (DEBUG) { printf("Lits: %d\n", lits.size()); printf("Rules: %d\n", rules.size()); printf("SCCs: %d\n", sccs.size()); // } if (DEBUG) for (int i = 0; i < rules.size(); i++) { ConjRule& r = *rules[i]; printf("Rule %d: ", i); printf("%d <- ", r.head); for (int j = 0; j < r.sz; j++) printf("%d ", r.body[j]); printf("\n"); } if (so.well_founded) pushInQueue(); }
void clear() { Gaussian::clear(); x_ct.clear(); P_ct.clear(); }
Perturbation(const Gaussian & p) : Gaussian(p), x_ct(p.size()), P_ct(p.size()) { x_ct.clear(); P_ct.clear(); }
Perturbation(const vec & p, const sym_mat & P) : Gaussian(p, P), x_ct(p.size()), P_ct(p.size()) { x_ct.clear(); P_ct.clear(); }
Perturbation(const size_t _size) : Gaussian(_size), x_ct(_size), P_ct(_size) { x_ct.clear(); P_ct.clear(); }
// Write 'd' in binary, then substitute 0 with '_0_', 1 with 'f'. This is the resulting 'out' vector. // static inline void bitAdder(Int d, Formula f, vec<Formula>& out) { out.clear(); for (; d != 0; d >>= 1) out.push(((d & 1) != 0) ? f : _0_); }
// Duplicatation (preferred instead): void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (©[i]) T(data[i]); }
void clear(void) { hs.clear(); }
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
static void buildConstraint(vec<Formula>& ps, vec<Int>& Cs, vec<Formula>& carry, vec<int>& base, int digit_no, vec<vec<Formula> >& out_digits, int max_cost) { assert(ps.size() == Cs.size()); if (FEnv::topSize() > max_cost) throw Exception_TooBig(); /** pf("buildConstraint("); for (int i = 0; i < ps.size(); i++) pf("%d*%s ", Cs[i], (*debug_names)[index(ps[i])]); pf("+ %d carry)\n", carry.size()); **/ if (digit_no == base.size()){ // Final digit, build sorter for rest: // -- add carry bits: for (int i = 0; i < carry.size(); i++) ps.push(carry[i]), Cs.push(1); out_digits.push(); buildSorter(ps, Cs, out_digits.last()); }else{ vec<Formula> ps_rem; vec<int> Cs_rem; vec<Formula> ps_div; vec<Int> Cs_div; // Split sum according to base: int B = base[digit_no]; for (int i = 0; i < Cs.size(); i++){ Int div = Cs[i] / Int(B); int rem = toint(Cs[i] % Int(B)); if (div > 0){ ps_div.push(ps[i]); Cs_div.push(div); } if (rem > 0){ ps_rem.push(ps[i]); Cs_rem.push(rem); } } // Add carry bits: for (int i = 0; i < carry.size(); i++) ps_rem.push(carry[i]), Cs_rem.push(1); // Build sorting network: vec<Formula> result; buildSorter(ps_rem, Cs_rem, result); // Get carry bits: carry.clear(); for (int i = B-1; i < result.size(); i += B) carry.push(result[i]); out_digits.push(); for (int i = 0; i < B-1; i++){ Formula out = _0_; for (int j = 0; j < result.size(); j += B){ int n = j+B-1; if (j + i < result.size()) out |= result[j + i] & ((n >= result.size()) ? _1_ : ~result[n]); } out_digits.last().push(out); } buildConstraint(ps_div, Cs_div, carry, base, digit_no+1, out_digits, max_cost); // <<== change to normal loop } }
void clearPropState() { in_queue = false; new_fixed.clear(); }
static void optimizeBase(vec<Int>& seq, int carry_ins, vec<Int>& rhs, int cost, vec<int>& base, int& cost_bestfound, vec<int>& base_bestfound) { if (cost >= cost_bestfound) return; // "Base case" -- don't split further, build sorting network for current sequence: int final_cost = 0; for (int i = 0; i < seq.size(); i++){ if (seq[i] > INT_MAX) goto TooBig; #ifdef ExpensiveBigConstants final_cost += toint(seq[i]); #else int c; for (c = 1; c*c < seq[i]; c++); final_cost += c; #endif if (final_cost < 0) goto TooBig; } if (cost + final_cost < cost_bestfound){ base.copyTo(base_bestfound); cost_bestfound = cost + final_cost; } TooBig:; /**/static int depth = 0; // <<== could count 1:s here for efficiency vec<Int> new_seq; vec<Int> new_rhs; #ifdef PickSmallest int p = -1; for (int i = 0; i < seq.size(); i++) if (seq[i] > 1){ p = seq[i]; break; } if (p != -1){ #else //int upper_lim = (seq.size() == 0) ? 1 : seq.last(); // <<== Check that sqRoot is an 'int' (no truncation of 'Int') //for (int i = 0; i < (int)elemsof(primes) && primes[i] <= upper_lim; i++){ for (int i = 0; i < (int)elemsof(primes); i++){ int p = primes[i]; #endif int rest = carry_ins; // Sum of all the remainders. Int div, rem; /**/for (int n = depth; n != 0; n--) pf(" "); pf("prime=%d carry_ins=%d\n", p, carry_ins); /**/for (int n = depth; n != 0; n--) pf(" "); pf("New seq:"); for (int j = 0; j < seq.size(); j++){ rest += toint(seq[j] % Int(p)); div = seq[j] / Int(p); if (div > 0) //**/pf(" %d", div), new_seq.push(div); } /**/pf("\n"); /**/for (int n = depth; n != 0; n--) pf(" "); pf("rest=%d\n", rest); /**/for (int n = depth; n != 0; n--) pf(" "); pf("New rhs:"); #ifdef AllDigitsImportant bool digit_important = true; #else bool digit_important = false; #endif for (int j = 0; j < rhs.size(); j++){ div = rhs[j] / p; if (new_rhs.size() == 0 || div > new_rhs.last()){ rem = rhs[j] % p; /**/pf(" %d:%d", div, rem), new_rhs.push(div); if (!(rem == 0 && rest < p) && !(rem > rest)) digit_important = true; } /* <<== om 'rhs' slutar på 0:a och 'rest' inte kan overflowa, då behövs inte det sorterande nätverket för 'rest' ("always TRUE") samma sak om 'rhs' sista siffra är strikt större än 'rest' ("never TRUE") */ } /**/pf("\n\n"); base.push(p); /**/depth++; optimizeBase(new_seq, rest/p, new_rhs, cost+(digit_important ? rest : 0), base, cost_bestfound, base_bestfound); /**/depth--; base.pop(); new_seq.clear(); new_rhs.clear(); } } static void optimizeBase(vec<Int>& seq, vec<Int>& rhs, int& cost_bestfound, vec<int>& base_bestfound) { vec<int> base; cost_bestfound = INT_MAX; base_bestfound.clear(); optimizeBase(seq, 0, rhs, 0, base, cost_bestfound, base_bestfound); }