!752 static new L statements; p { init(); dialog(); } static Lisp lisplist(O... x) { return lisp("", x); } static Lisp enter(O... x) { return lisp("enter", x); } static Lisp answer(O... x) { return lisp("answer", x); } static Lisp or(O... x) { return lisp("or", x); } static void init() { Lisp statement = lisplist( enter("An image has pixels."), enter("What does an image have?"), answer(or("pixels", "An image has pixels.")) ); statements.add(statement); //print(structure(statement)); print(statement); } static void dialog() { Lisp list = lisplist(); while (true) { System.out.print("LISP> "); S s = readLine(); if (s == null) break; s = s.trim(); if (s.equalsIgnoreCase("bye")) break; if (s.equals("!new")) { list = lisplist(); print("! ok"); continue; } /*if (s.startsWith("?")) { s = s.substring(1).trim(); list.add(ask(s)); print("List now: " + list); } else {*/ list.add(enter(s)); print("List now: " + list); //} S a = chimeIn(list); if (a != null) { list.add(answer(a)); print("! " + a); } } } static class Match { Lisp statement; int i; *(Lisp *statement, int *i) {} } static S chimeIn(Lisp history) { Match match = matchFromBeginning(history); print("Match: " + structure(match)); if (match != null && match.i < match.statement.size()) { Lisp next = match.statement.get(match.i); if (next.is("answer")) if (next.get(0).is("or")) return next.get(0).getString(0); else return next.getString(0); } return null; } static Match matchFromBeginning(Lisp history) { Match best = null; for (Lisp statement : statements) { Match match = getMatch(statement, history); if (best == null || match.i > best.i) best = match; } return best; } static Match getMatch(Lisp statement, Lisp history) { int n = Math.min(statement.size(), history.size()); int i = 0; while (i < n) if (!matchLine(statement.get(i), history.get(i))) break; else ++i; return new Match(statement, i); } static boolean matchLine(Lisp l1, Lisp l2) { if (l1.is("enter")) return l1.head.equals(l2.head) && sentenceEq(l1.getString(0), l2.getString(0)); return l1.equals(l2); }