use of org.logicng.formulas.Formula in project LogicNG by logic-ng.
the class Anonymizer method apply.
@Override
public Formula apply(final Formula formula, final boolean cache) {
if (formula.variables().isEmpty()) {
return formula;
}
final Formula cached = formula.transformationCacheEntry(ANONYMIZATION);
if (cache && cached != null) {
return cached;
}
for (final Variable variable : formula.variables()) {
if (this.substitution.getSubstitution(variable) == null) {
this.substitution.addMapping(variable, formula.factory().variable(this.prefix + this.counter++));
}
}
final Formula transformed = formula.substitute(this.substitution);
if (cache) {
formula.setTransformationCacheEntry(ANONYMIZATION, transformed);
}
return transformed;
}
use of org.logicng.formulas.Formula in project LogicNG by logic-ng.
the class NNFTransformation method applyRec.
private Formula applyRec(final Formula formula, final boolean polarity) {
final FormulaFactory f = formula.factory();
Formula nnf;
if (polarity) {
nnf = formula.transformationCacheEntry(NNF);
if (nnf != null) {
return nnf;
}
}
final FType type = formula.type();
switch(type) {
case TRUE:
case FALSE:
case LITERAL:
nnf = polarity ? formula : formula.negate();
break;
case NOT:
nnf = applyRec(((Not) formula).operand(), !polarity);
break;
case OR:
case AND:
nnf = applyRec(formula.iterator(), formula.type(), polarity, f);
break;
case EQUIV:
final Equivalence equiv = (Equivalence) formula;
if (polarity) {
nnf = f.and(f.or(applyRec(equiv.left(), false), applyRec(equiv.right(), true)), f.or(applyRec(equiv.left(), true), applyRec(equiv.right(), false)));
} else {
nnf = f.and(f.or(applyRec(equiv.left(), false), applyRec(equiv.right(), false)), f.or(applyRec(equiv.left(), true), applyRec(equiv.right(), true)));
}
break;
case IMPL:
final Implication impl = (Implication) formula;
if (polarity) {
nnf = f.or(applyRec(impl.left(), false), applyRec(impl.right(), true));
} else {
nnf = f.and(applyRec(impl.left(), true), applyRec(impl.right(), false));
}
break;
case PBC:
final PBConstraint pbc = (PBConstraint) formula;
if (polarity) {
final List<Formula> encoding = pbc.getEncoding();
nnf = applyRec(encoding.iterator(), FType.AND, true, f);
} else {
nnf = applyRec(pbc.negate(), true);
}
break;
default:
throw new IllegalStateException("Unknown formula type = " + type);
}
if (polarity) {
formula.setTransformationCacheEntry(NNF, nnf);
}
return nnf;
}
use of org.logicng.formulas.Formula in project LogicNG by logic-ng.
the class PureExpansionTransformation method apply.
@Override
public Formula apply(final Formula formula, final boolean cache) {
final FormulaFactory f = formula.factory();
switch(formula.type()) {
case FALSE:
case TRUE:
case LITERAL:
return formula;
case NOT:
final Not not = (Not) formula;
return f.not(apply(not.operand(), cache));
case OR:
case AND:
final NAryOperator nary = (NAryOperator) formula;
final List<Formula> newOps = new ArrayList<>(nary.numberOfOperands());
for (final Formula op : nary) {
newOps.add(apply(op, cache));
}
return f.naryOperator(formula.type(), newOps);
case IMPL:
case EQUIV:
final BinaryOperator binary = (BinaryOperator) formula;
final Formula newLeft = apply(binary.left(), cache);
final Formula newRight = apply(binary.right(), cache);
return f.binaryOperator(formula.type(), newLeft, newRight);
case PBC:
final PBConstraint pbc = (PBConstraint) formula;
if (pbc.isAmo() || pbc.isExo()) {
final EncodingResult encodingResult = EncodingResult.resultForFormula(f);
final Variable[] vars = literalsAsVariables(pbc.operands());
this.amoEncoder.build(encodingResult, vars);
final List<Formula> encoding = encodingResult.result();
if (pbc.isExo()) {
encoding.add(f.or(vars));
}
return f.and(encoding);
} else {
throw new UnsupportedOperationException("Pure encoding for a PBC of type other than AMO or EXO is currently not supported.");
}
default:
throw new IllegalStateException("Unknown formula type: " + formula.type());
}
}
use of org.logicng.formulas.Formula in project LogicNG by logic-ng.
the class Subsumption method generateSubsumedUBTree.
/**
* Generates a UBTree from the formulas operands (clauses in CNF, minterms in DNF)
* where all subsumed operands are already deleted.
* @param formula the formula (must be an n-ary operator and CNF or DNF)
* @return the UBTree with the operands and deleted subsumed operands
*/
protected static UBTree<Literal> generateSubsumedUBTree(final Formula formula) {
final SortedMap<Integer, List<SortedSet<Literal>>> mapping = new TreeMap<>();
for (final Formula term : formula) {
mapping.computeIfAbsent(term.literals().size(), k -> new ArrayList<>()).add(term.literals());
}
final UBTree<Literal> ubTree = new UBTree<>();
for (final Map.Entry<Integer, List<SortedSet<Literal>>> entry : mapping.entrySet()) {
for (final SortedSet<Literal> set : entry.getValue()) {
if (ubTree.firstSubset(set) == null) {
ubTree.addSet(set);
}
}
}
return ubTree;
}
use of org.logicng.formulas.Formula 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