!752 static int maxObjects = 1000; concepts. concept Obj { O o; *() {} *(O *o) { change(); } } concept Function { S name; bool nonDet; *() {} *(S *name) { change(); } } concept Result { new Ref f; new Ref argument; new Ref result; PersistableThrowable error; long when, time; } Result > Application {} Result > PreviousResult {} static L f_listFiles(File dir) { ret asList(listFiles(dir)); } static long f_fileSize(File f) { ret f.length(); } static L safeFunctionsToTry = ll("f_listFiles", "f_fileSize"); static new LinkedHashSet roots; p { concepts(); addStuff(javaxDataDir()); addStuff(userHome()); for (S name : safeFunctionsToTry) uniq(Function, +name); int lastN = -1; while licensed { int n = countConcepts(Obj); if (n == lastN) { print("No new objects (have " + n + "), ending"); break; } lastN = n; if (n >= maxObjects) { print("Got more than " + maxObjects + " objects (" + n + "), stopping"); break; } tryStuffOnStuff(true); } } svoid tryStuffOnStuff(bool reapply) { for (Obj o) unpackStuff(o.o); for (Function f) { Method m = findMethodNamed(mc(), f.name); Class[] types = m.getParameterTypes(); if (l(types) == 1) { for (Obj argument : list(Obj)) { Application app = findConcept(Application, +f, +argument); if (!reapply && app != null) continue; O o = argument.o; if (isInstanceX(types[0], o)) { print("Calling " + f.name + " on object " + argument.id); long time = now(); O out = null; Throwable error = null; try { out = m.invoke(null, o); } catch e { error = e; } time = now()-time; Obj result = findConcept(Obj, o := out); bool seen = result != null; if (result == null) result = cnew(Obj, o := out); // have previous result? bool prevResult = app != null; if (prevResult) { if (neq(app.result!, result)) { print(" differs"); // Save previous result cnew(PreviousResult, +f, +argument, result := app.result, error := app.error, when := app.when, time := app.time); // Mark function non-deterministic cset(f, nonDet := true); } } else app = cnew(Application, +f, +argument); cset(app, +result, when := now(), +time, error := persistableThrowable(error)); if (!prevResult) print(error != null ? " error" : seen ? " seen" : " new"); } } } } } svoid addStuff(O o) { if (o == null) ret; if (!hasConcept(Obj, +o)) { cnew(Obj, +o); print("Got: " + struct(o)); } } svoid unpackStuff(O o) { if (o instanceof ArrayList) for (O x : (Collection) o) addStuff(x); }