!752 static class Line { S text; Source source; *(S *text, Source *source) {} *() {} } static class Theory { S name; new L relations; new L allLines; *(S *name) {} *() {} int relScore(S a, S b, S name) { L l = findRels(a, b, name); ret listScore(l); } L findRels(S a, S b, S name) { new L l; for (Rel r : relations) if (eq(r.a, a) && eq(r.b, b) && eq(r.name, name)) l.add(r); ret l; } int listScore(L l) { int min = 1, max = -1; for (Rel r : l) { min = min(min, r.score); max = max(max, r.score); } ret min != max ? 0 : min; // default to unknown } void saveRel(S a, S b, S name, int score) { new Rel r; r.source = currentSource(); r.a = a; r.b = b; r.name = name; r.score = score; relations.add(r); save("theories"); } void saveLine(S text, Source source) { allLines.add(new Line(text, source)); save("theories"); } } static class Source { S username, slackTS; long time; } static class Rel { Source source; S a, b; // the things to relate S name; // e.g. "is a" int score; // -1 (no), 0 (unknown), 1 (yes) } static new Map theories; p { load("theories"); } static S answer(S s) { new Matches m; if "number of theories" ret str(l(theories)); if "list all theories" ret structure(keys(theories)); if (!matchStart("theory *:", s, m)) ret null; S theoryName = m.unq(0); Theory theory = theories.get(theoryName); if (theory == null) { theories.put(theoryName, theory = new Theory(theoryName)); save("theories"); } s = m.rest().trim(); // has theory now theory.saveLine(s, currentSource()); if "* is a *" { theory.saveRel(m.unq(0), m.unq(1), "is a", 1); ret "OK, relation saved."; } if "* is not a *" { theory.saveRel(m.unq(0), m.unq(1), "is a", -1); ret "OK, anti-relation saved."; } if "a * is a *" { theory.saveRel(m.unq(0), m.unq(1), "a X is a Y", 1); ret "OK, relation saved."; } if "a * is not a *" { theory.saveRel(m.unq(0), m.unq(1), "a X is a Y", -1); ret "OK, anti-relation saved."; } if "number of relations" ret str(l(theory.relations)); if "list all relations" ret structure(theory.relations); if "all lines" ret structure(theory.allLines); if "is * a *" { S a = m.unq(0), b = m.unq(1); int score = theory.relScore(a, b, "is a"); S answer = score < 0 ? "No, * is not a *" : score > 0 ? "Yes, * is a *" : "I'm not sure if * is a *."; ret format(answer, a, b); } ret "Unknown theory command, saved literally: " + m.rest(); } static Source currentSource() { new Source s; s.username = getUserName(); s.slackTS = getSlackTS(); s.time = now(); ret s; }