package alice.tuprolog.ui; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Iterator; import alice.tuprolog.InvalidTheoryException; import alice.tuprolog.MalformedGoalException; import alice.tuprolog.NoSolutionException; import alice.tuprolog.Prolog; import alice.tuprolog.SolveInfo; import alice.tuprolog.Theory; import alice.tuprolog.Var; import alice.tuprolog.event.OutputEvent; import alice.tuprolog.event.OutputListener; import alice.tuprolog.event.SpyEvent; import alice.tuprolog.event.SpyListener; import alice.tuprolog.event.WarningEvent; import alice.tuprolog.event.WarningListener; public class Console extends Automaton implements OutputListener, SpyListener, WarningListener { BufferedReader stdin; Prolog engine; SolveInfo info; static final String incipit = "tuProlog " + Prolog.getVersion() + " - DEIS, Università di Bologna a Cesena\n"+ new java.util.Date(); public Console(String[] args) { if (args.length>1) { System.err.println("args: { theory file }"); System.exit(-1); } engine = new Prolog(); stdin = new BufferedReader(new InputStreamReader(System.in)); engine.addWarningListener(this); engine.addOutputListener(this); engine.addSpyListener(this); if (args.length > 0) try { engine.setTheory(new Theory(new FileInputStream(args[0]))); } catch (InvalidTheoryException ex) { System.err.println("invalid theory - line: "+ex.line); System.exit(-1); } catch (Exception ex){ System.err.println("invalid theory."); System.exit(-1); } } @Override public void boot() { System.out.println(incipit); become("goalRequest"); } public void goalRequest() { String goal = ""; while (goal.equals("")) { System.out.print("\n?- "); try { goal = stdin.readLine(); } catch (IOException e) { e.printStackTrace(); } } solveGoal(goal); } void solveGoal(String goal) { try { info = engine.solve(goal); if (engine.isHalted()) System.exit(0); if (!info.isSuccess()) { System.out.println("no."); become("goalRequest"); } else if (!engine.hasOpenAlternatives()) { String binds = info.toString(); if (binds.equals("")) System.out.println("yes."); else System.out.println(solveInfoToString(info) + "\nyes."); become("goalRequest"); } else { String bindings = solveInfoToString(info); System.out.print((bindings == "" ? "true" : bindings) + " ? "); become("getChoice"); } } catch (MalformedGoalException ex) { System.out.println("syntax error in goal:\n" + goal); become("goalRequest"); } } private String solveInfoToString(SolveInfo result) { String s = ""; try { for (Iterator<Var> i = result.getBindingVars().iterator(); i.hasNext();) { Var v = (Var) i.next(); if (v != null && !v.isAnonymous() && v.isBound() && (!(v.getTerm() instanceof Var) || (!((Var) (v.getTerm())).getName().startsWith("_")))) { s += v.getName() + " / " + v.getTerm(); if (i.hasNext()) s += "\n"; } } } catch (NoSolutionException e) {} return s; } public void getChoice() { String choice = ""; try { while (true) { choice = stdin.readLine(); if (!choice.equals(";") && !choice.equals("")) System.out.println("\nAction ( ';' for more choices, otherwise <return> )"); else break; } } catch (IOException ex) {} if (!choice.equals(";")) { System.out.println("yes."); engine.solveEnd(); become("goalRequest"); } else try { System.out.println(); info = engine.solveNext(); if (!info.isSuccess()) { System.out.println("no."); become("goalRequest"); } else { String bindings = solveInfoToString(info); System.out.print((bindings == "" ? "true" : bindings) + " ? "); become("getChoice"); } } catch (Exception ex){ System.out.println("no."); become("goalRequest"); } } @Override public void onOutput(OutputEvent e) { System.out.print(e.getMsg()); } @Override public void onSpy(SpyEvent e) { System.out.println(e.getMsg()); } @Override public void onWarning(WarningEvent e) { System.out.println(e.getMsg()); } public static void main(String[] args) { new Thread(new Console(args)).start(); } }