package warnings;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashSet;
import externaltools.PrologSolver;
public class Solve {
public static boolean run(ArrayList<PrimitiveFormula> conj)
throws FileNotFoundException {
// check for immediate false conjunct:
if (conj == null) {
return false;
}
for (PrimitiveFormula F : conj) {
if (F.primitiveType == PrimitiveFormulaType.unsat) {
return false;
}
}
HashSet<String> arithmeticVariables = VariablesUtils
.fetchArithmeticVariables(conj);
StringBuilder pProlog = new StringBuilder();
pProlog.append(":- use_module(library(clpfd)).");
pProlog.append(System.getProperty("line.separator"));
pProlog.append(":- style_check(-singleton).");
pProlog.append(System.getProperty("line.separator"));
PrologRule rule = new PrologRule();
int setId = 0;
int gId = 0;
for (PrimitiveFormula F : conj) {
if (F.primitiveType == PrimitiveFormulaType.sat) {
continue;
}
Term term1 = (Term) F.operands[0];
if (F.primitiveType == PrimitiveFormulaType.relation) {
Term term2 = (Term) F.operands[1];
if (F.negated) {
F.rel = Relation.getOppositeRelation(F.rel);
}
if (term1.isPrimitiveArithmetic(arithmeticVariables)
&& ((Term) F.operands[1])
.isPrimitiveArithmetic(arithmeticVariables)) {
// for each primitive arithmetic of the form t1 rel t2 do
// add relation to the body
rule.addRelAtom(term1, term2, F.rel, true);
} else {
rule.addRelAtom(term1, term2, F.rel, false);
}
} else if (F.primitiveType == PrimitiveFormulaType.membership) {
Term term = (Term) F.operands[0];
GroundSet set = (GroundSet) F.operands[1];
if (set.type == GroundSetType.NumericRange) {
// for each g_i of the form t \in n1..n2
// pArithm := pArithm union t in n1..n2 2.
NumericRangeGroundSet numericRange = (NumericRangeGroundSet) set;
if (!F.negated) {
if (term.isVariable()) {
rule.addRangeAtom(term, numericRange.lowest,
numericRange.highest);
} else {
rule.addRelAtom(term1,
new Term(numericRange.lowest),
Relation.greatereq, true);
rule.addRelAtom(term1, new Term(
numericRange.highest), Relation.lesseq,
true);
}
} else {
++gId;
pProlog.append("g_" + gId + "(" + term.toString() + ")"
+ ":-" + term.toString() + " #> "
+ numericRange.highest + ".");
pProlog.append("g_" + gId + "(" + term.toString() + ")"
+ ":-" + term.toString() + " #< "
+ numericRange.lowest + ".");
rule.addNonRelAtom("g_" + gId, term, false);
}
}
else {
if (term1.isPrimitiveArithmetic(arithmeticVariables)) {
++setId;
for (String element : set.getElements()) {
if (isNumber(element)) {
pProlog.append("set_" + setId + "(" + element
+ ").");
pProlog.append(System
.getProperty("line.separator"));
}
}
rule.addNonRelAtom("set_" + setId, term1, F.negated);
} else {
++setId;
for (String element : set.getElements()) {
pProlog.append("set_" + setId + "(" + element
+ ").");
pProlog.append(System.getProperty("line.separator"));
}
rule.addNonRelAtom("set_" + setId, term1, F.negated);
}
}
}
}
rule.reorderBodyAtoms();
HashSet<String> newVariables=rule.fetchArithmeticsIntoIsAtoms();
arithmeticVariables.addAll(newVariables);
rule.addVarRangeAtom(arithmeticVariables);
rule.addLabelingAtom(arithmeticVariables);
pProlog.append(rule.toString());
pProlog.append(System.getProperty("line.separator"));
pProlog.append("main :-(p -> writeln(yes) ; writeln(no)).");
pProlog.append(System.getProperty("line.separator"));
boolean result = true;
try {
PrologSolver prologProgram = new PrologSolver(pProlog.toString());
result = prologProgram.isSatisfiable();
} catch (FileNotFoundException ex) {
System.err.println("WARNING:" + ex.getMessage());
System.err.println("Warnings will not be displayed");
}
return result;
}
private static boolean isNumber(String s) {
for (Character c : s.toCharArray()) {
if (!Character.isDigit(c))
return false;
}
return true;
}
}