use of org.logicng.formulas.Literal in project LogicNG by logic-ng.
the class Assignment method blockingClause.
/**
* Creates the blocking clause for this assignment wrt. a given set of literals. If the set is {@code null},
* all literals are considered relevant.
* @param f the formula factory
* @param literals the set of literals
* @return the blocking clause for this assignment
*/
public Formula blockingClause(final FormulaFactory f, final Collection<? extends Literal> literals) {
if (literals == null) {
return blockingClause(f);
}
final List<Literal> ops = new ArrayList<>();
for (final Literal lit : literals) {
final Variable var = lit.variable();
final Literal negatedVar = var.negate();
if (this.pos.contains(var)) {
ops.add(negatedVar);
} else if (this.neg.contains(negatedVar)) {
ops.add(var);
}
}
return f.or(ops);
}
use of org.logicng.formulas.Literal in project LogicNG by logic-ng.
the class DimacsReader method readCNF.
/**
* Reads a given DIMACS CNF file and returns the contained clauses as a list of formulas.
* @param file the file
* @param f the formula factory
* @param prefix the prefix for the variable names
* @return the list of formulas (clauses)
* @throws IOException if there was a problem reading the file
*/
public static List<Formula> readCNF(final File file, final FormulaFactory f, final String prefix) throws IOException {
final List<Formula> result = new ArrayList<>();
try (final BufferedReader br = new BufferedReader(new FileReader(file))) {
while (br.ready()) {
final String line = br.readLine();
if (!line.startsWith("c") && !line.startsWith("p") && !line.trim().isEmpty()) {
final String[] split = line.split("\\s+");
if (!"0".equals(split[split.length - 1].trim())) {
throw new IllegalArgumentException("Line '" + line + "' did not end with 0.");
}
final LinkedHashSet<Literal> vars = new LinkedHashSet<>(split.length - 1);
for (int i = 0; i < split.length - 1; i++) {
final String lit = split[i].trim();
if (!lit.isEmpty()) {
if (lit.startsWith("-")) {
vars.add(f.literal(prefix + split[i].trim().substring(1), false));
} else {
vars.add(f.variable(prefix + split[i].trim()));
}
}
}
result.add(f.or(vars));
}
}
}
return result;
}
use of org.logicng.formulas.Literal in project LogicNG by logic-ng.
the class FormulaDimacsFileWriter method write.
/**
* Writes a given formula's internal data structure as a dimacs file. Must only be called with a formula which is in CNF.
* @param fileName the file name of the dimacs file to write
* @param formula the formula
* @param writeMapping indicates whether an additional file for translating the ids to variable names shall be written
* @throws IOException if there was a problem writing the file
* @throws IllegalArgumentException if the formula was not in CNF
*/
public static void write(final String fileName, final Formula formula, final boolean writeMapping) throws IOException {
final File file = new File(fileName.endsWith(".cnf") ? fileName : fileName + ".cnf");
final SortedMap<Variable, Long> var2id = new TreeMap<>();
long i = 1;
for (final Variable var : new TreeSet<>(formula.variables())) {
var2id.put(var, i++);
}
if (!formula.holds(CNFPredicate.get())) {
throw new IllegalArgumentException("Cannot write a non-CNF formula to dimacs. Convert to CNF first.");
}
final List<Formula> parts = new ArrayList<>();
if (formula.type().equals(FType.LITERAL) || formula.type().equals(FType.OR)) {
parts.add(formula);
} else {
for (final Formula part : formula) {
parts.add(part);
}
}
final StringBuilder sb = new StringBuilder("p cnf ");
final int partsSize = formula.type().equals(FType.FALSE) ? 1 : parts.size();
sb.append(var2id.size()).append(" ").append(partsSize).append(System.lineSeparator());
for (final Formula part : parts) {
for (final Literal lit : part.literals()) {
sb.append(lit.phase() ? "" : "-").append(var2id.get(lit.variable())).append(" ");
}
sb.append(String.format(" 0%n"));
}
if (formula.type().equals(FType.FALSE)) {
sb.append(String.format("0%n"));
}
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
writer.append(sb);
writer.flush();
}
if (writeMapping) {
final String mappingFileName = (fileName.endsWith(".cnf") ? fileName.substring(0, fileName.length() - 4) : fileName) + ".map";
writeMapping(new File(mappingFileName), var2id);
}
}
use of org.logicng.formulas.Literal in project LogicNG by logic-ng.
the class FormulaDotFileWriter method write.
/**
* Writes a given formula's internal data structure as a dot file.
* @param file the file of the dot file to write
* @param formula the formula
* @param alignLiterals indicates whether all literals should be aligned at the same vertical level
* @throws IOException if there was a problem writing the file
*/
public static void write(final File file, final Formula formula, boolean alignLiterals) throws IOException {
final StringBuilder sb = new StringBuilder(String.format("digraph G {%n"));
final Map<Formula, Integer> ids = new HashMap<>();
if (alignLiterals && !formula.literals().isEmpty()) {
sb.append(String.format("{ rank = same;%n"));
}
int id = 0;
for (final Literal lit : formula.literals()) {
ids.put(lit, id);
sb.append(" id").append(id).append(" [shape=box, label=\"").append(lit.phase() ? lit.name() : "¬" + lit.name()).append(String.format("\"];%n"));
id++;
}
if (alignLiterals && !formula.literals().isEmpty()) {
sb.append(String.format("}%n"));
}
generateDotString(formula, sb, ids);
sb.append(String.format("}%n"));
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
writer.append(sb);
writer.flush();
}
}
use of org.logicng.formulas.Literal in project LogicNG by logic-ng.
the class BDDFactory method buildRec.
/**
* Recursive build procedure for the BDD.
* <p>
* If a BDD handler is given and the BDD generation is aborted due to the handler, the method will return
* {@link BDDKernel#BDD_ABORT} as result. If {@code null} is passed as handler, the generation will continue without
* interruption.
* @param formula the formula
* @param kernel the BDD kernel
* @param construction the BDD construction instance
* @param handler the BDD handler
* @return the BDD index or {@link BDDKernel#BDD_ABORT} if the computation was aborted
*/
private static int buildRec(final Formula formula, final BDDKernel kernel, final BDDConstruction construction, final BDDHandler handler) {
switch(formula.type()) {
case FALSE:
return BDDKernel.BDD_FALSE;
case TRUE:
return BDDKernel.BDD_TRUE;
case LITERAL:
final Literal lit = (Literal) formula;
final int idx = kernel.getOrAddVarIndex(lit.variable());
return lit.phase() ? construction.ithVar(idx) : construction.nithVar(idx);
case NOT:
{
final Not not = (Not) formula;
final int operand = buildRec(not.operand(), kernel, construction, handler);
if (operand == BDDKernel.BDD_ABORT) {
return BDDKernel.BDD_ABORT;
}
final int res = kernel.addRef(construction.not(operand), handler);
kernel.delRef(operand);
return res;
}
case IMPL:
case EQUIV:
final BinaryOperator binary = (BinaryOperator) formula;
final int left = buildRec(binary.left(), kernel, construction, handler);
if (left == BDDKernel.BDD_ABORT) {
return BDDKernel.BDD_ABORT;
}
final int right = buildRec(binary.right(), kernel, construction, handler);
if (right == BDDKernel.BDD_ABORT) {
return BDDKernel.BDD_ABORT;
}
int res = kernel.addRef(binary instanceof Implication ? construction.implication(left, right) : construction.equivalence(left, right), handler);
kernel.delRef(left);
kernel.delRef(right);
return res;
case AND:
case OR:
{
final Iterator<Formula> it = formula.iterator();
res = buildRec(it.next(), kernel, construction, handler);
if (res == BDDKernel.BDD_ABORT) {
return BDDKernel.BDD_ABORT;
}
while (it.hasNext()) {
final int operand = buildRec(it.next(), kernel, construction, handler);
if (operand == BDDKernel.BDD_ABORT) {
return BDDKernel.BDD_ABORT;
}
final int previous = res;
res = formula instanceof And ? kernel.addRef(construction.and(res, operand), handler) : kernel.addRef(construction.or(res, operand), handler);
kernel.delRef(previous);
kernel.delRef(operand);
}
return res;
}
case PBC:
return buildRec(formula.nnf(), kernel, construction, handler);
default:
throw new IllegalArgumentException("Unsupported operator for BDD generation: " + formula.type());
}
}
Aggregations