// extensive version (better results) with full search static class LCombineTwoFunctions2 extends LearnerImpl { static boolean debug; static long instances; Stepper stepper; new List examples; *() { ++instances; if (debug) debug("Instances: " + instances); } public void finalize() {--instances; } public void processInOut(O in, O out) { examples.add(new O[] {in, out}); if (stepper == null) stepper = new Stepper(allFunctions()); while (!stepper.ended()) { long time = System.currentTimeMillis(); boolean b = check(stepper.current()); time = System.currentTimeMillis()-time; if (debug) debug("check time: " + time); if (b) ret; // ok, keep else stepper.step(); } fail(); } boolean check(Function[] fg) { if (debug) { debug("Examples: " + examples.size() + ", stepper size: " + stepper.functions.size()); debug("Checking " + structure(fg)); } for (O[] e : examples) { O o = tryProcess(fg[0], e[0]); if (o != null) { O x = tryProcess(fg[1], o); if (e[1].equals(x)) continue; // example ok } ret false; } ret true; // all examples ok } public O processIn(O in) { Function[] fg = stepper.current(); ret fg[1].process(fg[0].process(in)); } static O tryProcess(Function f, O in) null on exception { ret f.process(in); } static class Stepper { List functions; int i1, i2; *(List *functions) {} boolean ended() { ret i1 >= functions.size(); } Function[] current() { ret new Function[] {functions.get(i1), functions.get(i2)}; } void step() { if (i2 < functions.size()-1) ++i2; else { ++i1; i2 = 0; } } } }