//package bots.prologbot.prologsystem;
//
//import gnu.prolog.database.Pair;
//import gnu.prolog.database.PrologTextLoaderError;
//import gnu.prolog.demo.mentalarithmetic.NoAnswerException;
//import gnu.prolog.io.TermWriter;
//import gnu.prolog.term.AtomTerm;
//import gnu.prolog.term.CompoundTerm;
//import gnu.prolog.term.IntegerTerm;
//import gnu.prolog.term.Term;
//import gnu.prolog.term.VariableTerm;
//import gnu.prolog.vm.Environment;
//import gnu.prolog.vm.Interpreter;
//import gnu.prolog.vm.PrologCode;
//import gnu.prolog.vm.PrologException;
//import gnu.prolog.vm.TermConstants;
//
//import java.io.File;
//import java.util.List;
//
//import bots.prologbot.PrologBot;
//
//public class GnuPrologSystem {
//
// private final static String n = System.getProperty("line.separator");
//
// private final PrologBot bot;
//
// /**
// * Whether we have done {@link #setup()} or not.
// */
// private static boolean issetup = false;
//
// /**
// * The {@link Environment} we are using.
// *
// * @see #setup() for creation
// * @see #generateQuestion(int,int) for usage
// */
// private static Environment env;
// /**
// * The {@link Interpreter} we are using.
// *
// * @see #setup() for creation
// * @see #generateQuestion(int,int) for usage
// */
// private static Interpreter interpreter;
//
// public GnuPrologSystem(PrologBot bot) {
// this.bot = bot;
// }
//
// public static Pair<String, Integer> generateQuestion(int limit, int length) throws PrologException, NoAnswerException {
// setup();
//
// // // Construct the question.
// // Create variable terms so that we can pull the answers out later
// VariableTerm listTerm = new VariableTerm("List");
// VariableTerm answerTerm = new VariableTerm("Answer");
// // Create the arguments to the compound term which is the question
// Term[] args = { new IntegerTerm(limit), new IntegerTerm(length), listTerm, answerTerm };
// // Construct the question
// CompoundTerm goalTerm = new CompoundTerm(AtomTerm.get("arithmetic"), args);
//
// synchronized (interpreter)// so that this class is thread safe.
// {
// // Print out any errors
// debug();
//
// // Execute the goal and return the return code.
// RC rc = interpreter.runOnce(goalTerm);
//
// // If it succeeded.
// if (rc == PrologCode.RC.SUCCESS || rc == PrologCode.RC.SUCCESS_LAST) {
// // Create the answer
// Pair<String, Integer> answer = new Pair<String, Integer>(null, 0);
//
// // Get hold of the actual Terms which the variable terms point to
// Term list = listTerm.dereference();
// Term value = answerTerm.dereference();
// // Check it is valid
// if (list != null) {
// if (list instanceof CompoundTerm) {
// CompoundTerm cList = (CompoundTerm) list;
// if (cList.tag == TermConstants.listTag)// it is a list
// {// Turn it into a string to use.
// answer.left = TermWriter.toString(list);
// } else {
// throw new NoAnswerException("List is not a list but is a CompoundTerm: " + list);
// }
// } else {
// throw new NoAnswerException("List is not a list: " + list);
// }
// } else {
// throw new NoAnswerException("List null when it should not be null");
// }
// if (value != null) {
// if (value instanceof IntegerTerm) {
// answer.right = ((IntegerTerm) value).value;
// } else {
// throw new NoAnswerException("Answer is not an integer: (" + value + ") but List is:" + list);
// }
// } else {
// throw new NoAnswerException("Answer null when it should not be null");
// }
//
// return answer;
// } else {
// throw new NoAnswerException("Goal failed");
// }
// }
// }
//
// /**
// * Ensure that we have an environment and have loaded the prolog code and have
// * an interpreter to use.
// */
// private synchronized static void setup() {
// if (issetup) {
// return;// don't setup more than once
// }
//
// // Construct the environment
// env = new Environment();
//
// // get the filename relative to the class file
// env.ensureLoaded(AtomTerm.get(name));
//
// // Get the interpreter.
// interpreter = env.createInterpreter();
// // Run the initialization
// env.runInitialization(interpreter);
//
// // So that we don't repeat ourselves
// issetup = true;
// }
//
// public synchronized void updateBotProlog(String prolog) {
// // File file = new File(directory, bot.getName() + ".pl");
// // StringWriter out = new StringWriter();
// // out.write("% Generated by server" + n);
// // out.write(":- include(bk)." + n);
// // out.write(":- include(state)." + n);
// // out.write("" + n);
// // out.write("% Generated by client" + n);
// // out.write(prolog);
// // writeToFile(file, out.toString());
// }
//
// private void writeToFile(File file, String prolog) {
// // try {
// // FileWriter out2 = new FileWriter(file);
// // BufferedWriter out = new BufferedWriter(out2);
// // out.write(prolog);
// // out.close();
// // out2.close();
// // } catch (IOException e) {
// // e.printStackTrace();
// // System.err.println("Could not write prolog code.");
// // System.exit(-1);
// // }
// }
//
// public synchronized void updateState(String state) {
// // writeToFile(new File(directory, "state.pl"), state);
// }
//
// public synchronized String executeQuery() {
// // try {
// // ProcessBuilder pb = new ProcessBuilder("yap", "-l", bot.getName() + ".pl", "-g", "evaluate", "-q");
// // pb.directory(directory);
// // Process p = pb.start();
// // int exitValue = p.waitFor();
// // if (exitValue != 0) {
// // throw new IllegalStateException();
// // }
// // InputStreamReader in = new InputStreamReader(p.getInputStream());
// // BufferedReader result = new BufferedReader(in);
// // String output = result.readLine();
// // result.close();
// // in.close();
// // return output;
// // } catch (IOException e) {
// // e.printStackTrace();
// // System.err.println("Could not query Prolog.");
// // System.exit(-1);
// // } catch (InterruptedException e) {
// // e.printStackTrace();
// // System.err.println("Could not query Prolog.");
// // System.exit(-1);
// // }
// // return null;
// }
//
// /**
// * Collect debugging information if something has gone wrong in particular get
// * any {@link PrologTextLoaderError PrologTextLoaderErrors} which were created
// * during loading.
// */
// private static void debug() {
// List<PrologTextLoaderError> errors = env.getLoadingErrors();
// for (PrologTextLoaderError error : errors) {
// error.printStackTrace();
// }
//
// /*
// * Map<AtomTerm, Term> atom2flag = env.getPrologFlags(); Set<AtomTerm> atoms
// * = atom2flag.keySet(); for (AtomTerm a : atoms) {
// * System.out.println(a.toString() + " => " + atom2flag.get(a)); }
// */
// }
//
//}