use of org.logicng.formulas.FType 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.FType in project LogicNG by logic-ng.
the class FactorOutSimplifier method factorOut.
private static Formula factorOut(final NAryOperator formula) {
final Formula factorOutFormula = computeMaxOccurringSubformula(formula);
if (factorOutFormula == null) {
return null;
}
final FormulaFactory f = formula.factory();
final FType type = formula.type();
final List<Formula> formulasWithRemoved = new ArrayList<>();
final List<Formula> unchangedFormulas = new ArrayList<>();
for (final Formula operand : formula) {
if (operand.type() == FType.LITERAL) {
if (operand.equals(factorOutFormula)) {
formulasWithRemoved.add(f.constant(type == FType.OR));
} else {
unchangedFormulas.add(operand);
}
} else if (operand.type() == FType.AND || operand.type() == FType.OR) {
boolean removed = false;
final List<Formula> newOps = new ArrayList<>();
for (final Formula op : operand) {
if (!op.equals(factorOutFormula)) {
newOps.add(op);
} else {
removed = true;
}
}
(removed ? formulasWithRemoved : unchangedFormulas).add(f.naryOperator(operand.type(), newOps));
} else {
unchangedFormulas.add(operand);
}
}
return f.naryOperator(type, f.naryOperator(type, unchangedFormulas), f.naryOperator(dual(type), factorOutFormula, f.naryOperator(type, formulasWithRemoved)));
}
use of org.logicng.formulas.FType in project LogicNG by logic-ng.
the class DistributiveSimplifier method distributeNAry.
private Formula distributeNAry(final Formula formula, final boolean cache, final FormulaFactory f) {
final Formula result;
final FType outerType = formula.type();
final FType innerType = dual(outerType);
final Set<Formula> operands = new LinkedHashSet<>();
for (final Formula op : formula) {
operands.add(this.apply(op, cache));
}
final Map<Formula, Set<Formula>> part2Operands = new LinkedHashMap<>();
Formula mostCommon = null;
int mostCommonAmount = 0;
for (final Formula op : operands) {
if (op.type() == innerType) {
for (final Formula part : op) {
final Set<Formula> partOperands = part2Operands.computeIfAbsent(part, k -> new LinkedHashSet<>());
partOperands.add(op);
if (partOperands.size() > mostCommonAmount) {
mostCommon = part;
mostCommonAmount = partOperands.size();
}
}
}
}
if (mostCommon == null || mostCommonAmount == 1) {
result = f.naryOperator(outerType, operands);
return result;
}
operands.removeAll(part2Operands.get(mostCommon));
final Set<Formula> relevantFormulas = new LinkedHashSet<>();
for (final Formula preRelevantFormula : part2Operands.get(mostCommon)) {
final Set<Formula> relevantParts = new LinkedHashSet<>();
for (final Formula part : preRelevantFormula) {
if (!part.equals(mostCommon)) {
relevantParts.add(part);
}
}
relevantFormulas.add(f.naryOperator(innerType, relevantParts));
}
operands.add(f.naryOperator(innerType, mostCommon, f.naryOperator(outerType, relevantFormulas)));
result = f.naryOperator(outerType, operands);
return result;
}
Aggregations