static void buildSorter(vec<Formula>& ps, vec<Int>& Cs, vec<Formula>& out_sorter) { vec<int> Cs_copy; for (int i = 0; i < Cs.size(); i++) Cs_copy.push(toint(Cs[i])); buildSorter(ps, Cs_copy, out_sorter); }
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 } }
static void buildSorter(vec<Formula>& ps, vec<Int>& Cs, vec<Formula>& carry , vec<Formula>& out_sorter, PBOptions* options) { vec<int> Cs_copy; for (int i = 0; i < Cs.size(); i++) Cs_copy.push(toint(Cs[i])); buildSorter(ps,Cs_copy, carry , out_sorter, options); }