!752 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 L relations; p { load("relations"); } answer { if "* is a *" { saveRel(m.unq(0), m.unq(1), "is a", 1); ret "OK, relation saved."; } if "* is not a *" { saveRel(m.unq(0), m.unq(1), "is a", -1); ret "OK, anti-relation saved."; } if "number of relations" ret str(l(relations)); if "list all relations" ret structure(relations); if "is * a *" { S a = m.unq(0), b = m.unq(1); int score = 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); } } static 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("relations"); } static Source currentSource() { new Source s; s.username = getUserName(); s.slackTS = getSlackTS(); s.time = now(); ret s; } static int relScore(S a, S b, S name) { L l = findRels(a, b, name); ret listScore(l); } static 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; } static 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 }