package externaltools;
import java.io.*;
import java.security.SecureRandom;
public class PrologSolver extends ExternalSolver {
private String pathToProlog;
public PrologSolver() throws FileNotFoundException {
this(null);
}
public PrologSolver(String program) throws FileNotFoundException {
this.program = program;
pathToProlog = searchForExe();
if (pathToProlog == null) {
throw new FileNotFoundException("Swi-prolog not found. "
+ "You should have swipl or swipl.exe available "
+ "from your path or current folder.");
}
}
public boolean isSatisfiable() {
String output = run(true);
return output.equals("yes");
}
//TODO: Implement ignore warnings properly
public String run(boolean ignoreWarnings) {
// Create a temporary file: FileWriter fw = new
// FileWriter(file.getAbsoluteFile());
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File tempFile = generateFile("prolog_q",
Long.toString(System.currentTimeMillis()), tempDir);
// write the program to the temporary file:
FileWriter fw = null;
try {
fw = new FileWriter(tempFile.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(program);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
String options = " -s " + tempFile.getAbsolutePath()
+ " -t " + " main " + " -q ";
OsUtils.runCommand(pathToProlog, options,null);
if (OsUtils.errors.length()>0) {
throw new IllegalArgumentException(
"prolog program constructed from a rule for warnings "
+ "checking contains errors: " + OsUtils.errors.toString());
}
return OsUtils.result.toString().trim();
}
private static String searchForExe() {
String[] candidates = { "swipl.exe", "swipl" };
for (String candidate : candidates) {
boolean found = true;
try {
Process p = Runtime.getRuntime().exec(candidate);
p.destroy();
} catch (IOException ex) {
found = false;
}
if (found)
return candidate;
}
return null;
}
private static final SecureRandom random = new SecureRandom();
static File generateFile(String prefix, String suffix, File dir) {
long n = random.nextLong();
if (n == Long.MIN_VALUE) {
n = 0; // corner case
} else {
n = Math.abs(n);
}
return new File(dir, prefix +"_"+ Long.toString(n) + "_"+suffix);
}
}