!752

m {
  // subject, predicate, object
  static class SPO {
    S s, p, o;
    int value; // 1 = asserted as true, -1 = asserted as false
  
    *(S *s, S *p, S *o, int *value) {}
    *(S *s, S *p, S *o) {}
    *() {}
    
    public boolean equals(O _o) {
      if (!(_o instanceof SPO)) ret false;
      SPO x = cast _o;
      ret eq(s, x.s) && eq(p, x.p) && eq(o, x.o);
    }
  }
  
  static new L<SPO> data;
  
  static void store(S s, S p, S o, int value) {
    data.add(new SPO(s, p, o, value));
  }
  
  static int query(S s, S p, S o) {
    int i = data.indexOf(new SPO(s, p, o));
    ret i >= 0 ? data.get(i).value : 0;
  }
  
  static S answer(S s) {
    new Matches m;
    if (match("query * * *", s, m))
      ret string(query(m.unq(0), m.unq(1), m.unq(2)));
    if (match("assert * * *", s, m)) {
      store(m.unq(0), m.unq(1), m.unq(2), 1);
      ret "OK.";
    }
    if (match("assertnot * * *", s, m)) {
      store(m.unq(0), m.unq(1), m.unq(2), -1);
      ret "OK.";
    }
    ret null;
  }
  
  p {
    store("2000", "is a", "year", 1);
    assertEq("2000", 1, query("2000", "is a", "year"));
    assertEq("2004", 0, query("2004", "is a", "year"));
    print("OK!");
  }
}