!759

p {
  L<S> log = scanEventLogForText("#1004032", "wallpaper");
  psl(log);
  genLog_set(log);
  
  for (Matches m : gJMatch("if * and * then *")) {
    //print("if then: " + struct(m));
    Iterator<SS> sat = satisfyStatements(ll(m.unq(0), m.unq(1)));
    while (sat.hasNext())
      print("Inferred statement: " + replaceVars(m.unq(2), sat.next()));
  }
}

// null = no satisfaction
// otherwise return var map
static Iterator<SS> satisfyStatements(L<S> statements) {
  if (l(statements) == 1)
    ret satisfyStatement(first(statements));
  
  if (l(statements) == 2) {
    new L<SS> l;
    for (SS map : satisfyStatement(first(statements)))
      for (SS map2 : satisfyStatement(get(statements, 1)))
        addIfNotEmpty(l, mergeMappings(map, map2));
    ret l.iterator();
  }
      
  fail("too complicated for now :)");
}

static IterableIterator<SS> satisfyStatement(S statement) {
  final new L<S> vars;
  S pat = upperCaseVarsToStars(statement, vars);
  ret mapI(func(Matches m) {
    new SS map;
    for (int i = 0; i < l(m.m); i++)
      map.put(vars.get(i), m.unq(i));
    ret map;
  }, gJMatch(pat));
}