use of org.logicng.collections.LNGVector in project LogicNG by logic-ng.
the class PBConstraint method normalize.
/**
* Normalizes this constraint s.t. it can be converted to CNF.
* @return the normalized constraint
*/
public Formula normalize() {
final LNGVector<Literal> normPs = new LNGVector<>(this.literals.length);
final LNGIntVector normCs = new LNGIntVector(this.literals.length);
int normRhs;
switch(this.comparator) {
case EQ:
for (int i = 0; i < this.literals.length; i++) {
normPs.push(this.literals[i]);
normCs.push(this.coefficients[i]);
}
normRhs = this.rhs;
final Formula f1 = this.normalize(normPs, normCs, normRhs);
normPs.clear();
normCs.clear();
for (int i = 0; i < this.literals.length; i++) {
normPs.push(this.literals[i]);
normCs.push(-this.coefficients[i]);
}
normRhs = -this.rhs;
final Formula f2 = this.normalize(normPs, normCs, normRhs);
return this.f.and(f1, f2);
case LT:
case LE:
for (int i = 0; i < this.literals.length; i++) {
normPs.push(this.literals[i]);
normCs.push(this.coefficients[i]);
}
normRhs = this.comparator == CType.LE ? this.rhs : this.rhs - 1;
return this.normalize(normPs, normCs, normRhs);
case GT:
case GE:
for (int i = 0; i < this.literals.length; i++) {
normPs.push(this.literals[i]);
normCs.push(-this.coefficients[i]);
}
normRhs = this.comparator == CType.GE ? -this.rhs : -this.rhs - 1;
return this.normalize(normPs, normCs, normRhs);
default:
throw new IllegalStateException("Unknown pseudo-Boolean comparator: " + this.comparator);
}
}
use of org.logicng.collections.LNGVector in project LogicNG by logic-ng.
the class CCAMONested method encodeIntern.
/**
* Internal recursive encoding.
* @param vars the variables of the constraint
*/
private void encodeIntern(final LNGVector<Literal> vars) {
if (vars.size() <= this.groupSize) {
for (int i = 0; i + 1 < vars.size(); i++) {
for (int j = i + 1; j < vars.size(); j++) {
this.result.addClause(vars.get(i).negate(), vars.get(j).negate());
}
}
} else {
final LNGVector<Literal> l1 = new LNGVector<>(vars.size() / 2);
final LNGVector<Literal> l2 = new LNGVector<>(vars.size() / 2);
int i = 0;
for (; i < vars.size() / 2; i++) {
l1.push(vars.get(i));
}
for (; i < vars.size(); i++) {
l2.push(vars.get(i));
}
final Variable newVariable = this.result.newVariable();
l1.push(newVariable);
l2.push(newVariable.negate());
this.encodeIntern(l1);
this.encodeIntern(l2);
}
}
use of org.logicng.collections.LNGVector in project LogicNG by logic-ng.
the class PBBinaryMerge method binary_merge.
private void binary_merge(final LNGVector<Literal> literals, final LNGIntVector coefficients, final int leq, final int maxWeight, final int n, final List<Formula> formula, final Literal gac_lit) {
final int less_then = leq + 1;
final int p = (int) Math.floor(Math.log(maxWeight) / Math.log(2));
final int m = (int) Math.ceil(less_then / Math.pow(2, p));
final int new_less_then = (int) (m * Math.pow(2, p));
final int T = (int) ((m * Math.pow(2, p)) - less_then);
final Literal true_lit = this.f.newPBVariable();
formula.add(true_lit);
final LNGVector<LNGVector<Literal>> buckets = new LNGVector<>();
int bit = 1;
for (int i = 0; i <= p; i++) {
buckets.push(new LNGVector<>());
if ((T & bit) != 0) {
buckets.get(i).push(true_lit);
}
for (int j = 0; j < n; j++) {
if ((coefficients.get(j) & bit) != 0) {
if (gac_lit != null && coefficients.get(j) >= less_then) {
formula.add(this.f.clause(gac_lit, literals.get(j).negate()));
} else {
buckets.get(i).push(literals.get(j));
}
}
}
bit = bit << 1;
}
final LNGVector<LNGVector<Literal>> bucket_card = new LNGVector<>(p + 1);
final LNGVector<LNGVector<Literal>> bucket_merge = new LNGVector<>(p + 1);
for (int i = 0; i < p + 1; i++) {
bucket_card.push(new LNGVector<>());
bucket_merge.push(new LNGVector<>());
}
assert bucket_card.size() == buckets.size();
final LNGVector<Literal> carries = new LNGVector<>();
final EncodingResult tempResul = EncodingResult.resultForFormula(this.f);
for (int i = 0; i < buckets.size(); i++) {
final int k = (int) Math.ceil(new_less_then / Math.pow(2, i));
if (this.config.binaryMergeUseWatchDog) {
totalizer(buckets.get(i), bucket_card.get(i), formula);
} else {
this.sorting.sort(k, buckets.get(i), tempResul, bucket_card.get(i), INPUT_TO_OUTPUT);
formula.addAll(tempResul.result());
}
if (k <= buckets.get(i).size()) {
assert k == bucket_card.get(i).size() || this.config.binaryMergeUseWatchDog;
if (gac_lit != null) {
formula.add(this.f.clause(gac_lit, bucket_card.get(i).get(k - 1).negate()));
} else {
formula.add(this.f.clause(bucket_card.get(i).get(k - 1).negate()));
}
}
if (i > 0) {
if (carries.size() > 0) {
if (bucket_card.get(i).size() == 0) {
bucket_merge.set(i, carries);
} else {
if (this.config.binaryMergeUseWatchDog) {
unary_adder(bucket_card.get(i), carries, bucket_merge.get(i), formula);
} else {
this.sorting.merge(k, bucket_card.get(i), carries, tempResul, bucket_merge.get(i), INPUT_TO_OUTPUT);
formula.addAll(tempResul.result());
}
if (k == bucket_merge.get(i).size() || (this.config.binaryMergeUseWatchDog && k <= bucket_merge.get(i).size())) {
if (gac_lit != null) {
formula.add(this.f.clause(gac_lit, bucket_merge.get(i).get(k - 1).negate()));
} else {
formula.add(this.f.clause(bucket_merge.get(i).get(k - 1).negate()));
}
}
}
} else {
bucket_merge.get(i).replaceInplace(bucket_card.get(i));
}
}
carries.clear();
if (i == 0) {
for (int j = 1; j < bucket_card.get(0).size(); j = j + 2) {
carries.push(bucket_card.get(0).get(j));
}
} else {
for (int j = 1; j < bucket_merge.get(i).size(); j = j + 2) {
carries.push(bucket_merge.get(i).get(j));
}
}
}
}
use of org.logicng.collections.LNGVector in project LogicNG by logic-ng.
the class PBBinaryMerge method encode.
@Override
public List<Formula> encode(final LNGVector<Literal> lts, final LNGIntVector cffs, final int rhs, final List<Formula> formula) {
final LNGVector<Literal> lits = new LNGVector<>(lts.size());
for (final Literal lit : lts) {
lits.push(lit);
}
final LNGIntVector coeffs = new LNGIntVector(cffs);
final int maxWeight = maxWeight(coeffs);
if (!this.config.binaryMergeUseGAC) {
binary_merge(lts, new LNGIntVector(cffs), rhs, maxWeight, lits.size(), formula, null);
} else {
Literal x;
boolean encode_complete_constraint = false;
for (int i = 0; i < lits.size(); i++) {
if (this.config.binaryMergeNoSupportForSingleBit && Double.compare(Math.floor(Math.log(coeffs.get(i)) / Math.log(2)), Math.log(coeffs.get(i)) / Math.log(2)) == 0) {
encode_complete_constraint = true;
continue;
}
final Literal tmpLit = lits.get(i);
final int tmpCoeff = coeffs.get(i);
lits.set(i, lits.back());
coeffs.set(i, coeffs.back());
lits.pop();
coeffs.pop();
x = tmpLit;
if (maxWeight == tmpCoeff) {
int mw = 0;
for (int j = 0; j < coeffs.size(); j++) {
mw = Math.max(mw, coeffs.get(j));
}
if (rhs - tmpCoeff <= 0) {
for (int j = 0; j < lits.size(); j++) {
formula.add(this.f.clause(x.negate(), lits.get(j).negate()));
}
} else {
binary_merge(lits, coeffs, rhs - tmpCoeff, mw, lits.size(), formula, x.negate());
}
} else {
if (rhs - tmpCoeff <= 0) {
for (int j = 0; j < lits.size(); j++) {
formula.add(this.f.clause(x.negate(), lits.get(j).negate()));
}
}
binary_merge(lits, coeffs, rhs - tmpCoeff, maxWeight, lits.size(), formula, x.negate());
}
if (i < lits.size()) {
lits.push(lits.get(i));
lits.set(i, tmpLit);
coeffs.push(coeffs.get(i));
coeffs.set(i, tmpCoeff);
}
}
if (this.config.binaryMergeNoSupportForSingleBit && encode_complete_constraint) {
binary_merge(lts, new LNGIntVector(cffs), rhs, maxWeight, lits.size(), formula, null);
}
}
return formula;
}
use of org.logicng.collections.LNGVector in project LogicNG by logic-ng.
the class UnsatCoreFunction method apply.
@Override
public UNSATCore<Proposition> apply(final MiniSat solver, final Consumer<Tristate> resultSetter) {
if (!solver.getConfig().proofGeneration()) {
throw new IllegalStateException("Cannot generate an unsat core if proof generation is not turned on");
}
if (solver.getResult() == TRUE) {
throw new IllegalStateException("An unsat core can only be generated if the formula is solved and is UNSAT");
}
if (solver.getResult() == Tristate.UNDEF) {
throw new IllegalStateException("Cannot generate an unsat core before the formula was solved.");
}
if (solver.underlyingSolver() instanceof MiniCard) {
throw new IllegalStateException("Cannot compute an unsat core with MiniCard.");
}
if (solver.underlyingSolver() instanceof GlucoseSyrup && solver.getConfig().incremental()) {
throw new IllegalStateException("Cannot compute an unsat core with Glucose in incremental mode.");
}
if (solver.isLastComputationWithAssumptions()) {
throw new IllegalStateException("Cannot compute an unsat core for a computation with assumptions.");
}
final DRUPTrim trimmer = new DRUPTrim();
final Map<Formula, Proposition> clause2proposition = new HashMap<>();
final LNGVector<LNGIntVector> clauses = new LNGVector<>(solver.underlyingSolver().pgOriginalClauses().size());
for (final MiniSatStyleSolver.ProofInformation pi : solver.underlyingSolver().pgOriginalClauses()) {
clauses.push(pi.clause());
final Formula clause = getFormulaForVector(solver, pi.clause());
Proposition proposition = pi.proposition();
if (proposition == null) {
proposition = new StandardProposition(clause);
}
clause2proposition.put(clause, proposition);
}
if (containsEmptyClause(clauses)) {
final Proposition emptyClause = clause2proposition.get(solver.factory().falsum());
return new UNSATCore<>(Collections.singletonList(emptyClause), true);
}
final DRUPTrim.DRUPResult result = trimmer.compute(clauses, solver.underlyingSolver().pgProof());
if (result.trivialUnsat()) {
return handleTrivialCase(solver);
}
final LinkedHashSet<Proposition> propositions = new LinkedHashSet<>();
for (final LNGIntVector vector : result.unsatCore()) {
propositions.add(clause2proposition.get(getFormulaForVector(solver, vector)));
}
return new UNSATCore<>(new ArrayList<>(propositions), false);
}
Aggregations