// 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;
}
示例#2
0
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);
    }
}
示例#3
0
/*_________________________________________________________________________________________________
|
|  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);
}
示例#5
0
	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]);
			}
		}
	}
示例#6
0
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)
}
示例#7
0
文件: Main_debug.C 项目: Sealos/AI
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) );
    }
}
示例#8
0
文件: Main.C 项目: pmatos/maxsatzilla
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) );
    }
}
示例#9
0
	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");
	}
示例#10
0
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)
}
示例#11
0
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
}
示例#12
0
	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;
			}
		}
	}
示例#13
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();
}
示例#15
0
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
}
示例#16
0
/**
@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) );
    }
}
示例#17
0
/**
@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) );
    }
}
示例#18
0
	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;
	}
示例#19
0
	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();

	}
示例#20
0
				void clear()
				{
					Gaussian::clear();
					x_ct.clear();
					P_ct.clear();
				}
示例#21
0
				Perturbation(const Gaussian & p) :
					Gaussian(p), x_ct(p.size()), P_ct(p.size()) {
					x_ct.clear();
					P_ct.clear();
				}
示例#22
0
				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();
				}
示例#23
0
				Perturbation(const size_t _size) :
					Gaussian(_size), x_ct(_size), P_ct(_size) {
					x_ct.clear();
					P_ct.clear();
				}
示例#24
0
// 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_);
}
示例#25
0
 // Duplicatation (preferred instead):
 void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (&copy[i]) T(data[i]); }
示例#26
0
文件: filestore.C 项目: Amit-DU/dht
 void clear(void) {
   hs.clear();
 }
示例#27
0
 void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
示例#28
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
    }
}
示例#29
0
	void clearPropState() {
		in_queue = false;
		new_fixed.clear();
	}
示例#30
0
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);
}