!7 static L sentences = toLinesFullTrim([[ "0" is a digit. "1" is a digit. "2" is a digit. "3" is a digit. "4" is a digit. "5" is a digit. "6" is a digit. "7" is a digit. "8" is a digit. "9" is a digit. These are all the digits that exist. A number is a concatenation of digits. ]]); static L questions = toLinesFullTrim([[ Is "5" a digit? Is "your mama" a digit? ]]); static class Concept { S name; new L stringExamples; new L descriptions; boolean closed; *(S *name) {} *() {} void addStringExample(S s) { if (!stringExamples.contains(s)) // yes it's inefficient... who cares right now :)))))) stringExamples.add(s); } void addDescription(S s) { if (!descriptions.contains(s)) descriptions.add(s); } } static class Concepts { new Map map; Concept get(S s) { Concept c = map.get(s); if (c == null) map.put(s, c = new Concept(s)); return c; } } static new Concepts concepts; p { for (S s : concatLists(sentences, questions)) { print("> " + s); print("< " + answer(s)); } print("Number of concepts: " + concepts.map.size() + " (" + structure(concepts.map.keySet()) + ")"); makeAndroid("Digit Understander Bot."); } static synchronized S answer(S s) { L tok = javaTok(s); S[] bla = match("* is a *.", tok); if (bla != null && bla[0].startsWith("\"")) { print(bla[0] + " is a " + bla[1] + "!"); concepts.get(bla[1]).addStringExample(unquote(bla[0])); return "ok"; } bla = match("These are all the * that exist.", tok); if (bla != null) { S c = bla[0].replaceAll("s$", ""); concepts.get(c).closed = true; return "ok, closed concept " + c + "."; } bla = match("A * is ... .", tok); if (bla != null) { S desc = joinRest(bla, 1); concepts.get(bla[0]).addDescription(desc); print(bla[0] + ": " + desc); return "ok"; } // process questions on knowledge base bla = match("Is * a *?", tok); if (bla != null) { S answer = null /*"Dunno."*/; Concept c = concepts.get(bla[1]); if (bla[0].startsWith("\"") && c.closed) { answer = c.stringExamples.contains(unquote(bla[0])) ? "Yes." : "No."; } return answer; } bla = match("what is a *?", tok); if (bla != null) { S answer = null /*"Dunno."*/; Concept c = concepts.get(unquote(bla[0])); if (!c.descriptions.isEmpty()) answer = "A " + c.name + " is " + c.descriptions.get(0) + "."; else if (c.closed) answer = "A " + c.name + " is one of " + c.stringExamples.size() + " globally defined strings."; return answer; } return null; } static S[] match(S pat, L tok) { new Matches m; return match3(pat, join(tok), m) ? m.m : null; }