import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
class main {
static class Example extends Concept {
String sentence, subject;
}
public static void main(final String[] args) throws Exception {
loadConceptsFrom("#1008540");
ScoreBoard sb = new ScoreBoard();
testFunction(sb, "firstWord");
sb.print();
}
static void testFunction(ScoreBoard sb, Object f) {
int fullScore = 0, score = 0;
for (Example e : list(Example.class)) {
String in = trim(e.sentence), out = trim(e.subject);
if (empty(out)) continue;
++fullScore;
String o = (String) pcallF(f, in);
if (eqic(trim(o), out))
++score;
}
sb.fullScore = fullScore;
sb.scores.put(f, (double) score);
}
static String trim(String s) { return s == null ? null : s.trim(); }
static String trim(StringBuilder buf) { return buf.toString().trim(); }
static String trim(StringBuffer buf) { return buf.toString().trim(); }
static String firstWord(String s) {
return firstJavaToken(s);
}
static Object pcallF(Object f, Object... args) {
return pcallFunction(f, args);
}
static B pcallF(F1 f, A a) { try {
return f == null ? null : f.get(a);
} catch (Throwable __e) { return null; } }
static Map _registerThread_threads = Collections.synchronizedMap(new WeakHashMap());
static Thread _registerThread(Thread t) {
_registerThread_threads.put(t, true);
return t;
}
static void _registerThread() { _registerThread(Thread.currentThread()); }
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(String s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(String msg) { throw new RuntimeException(unnull(msg)); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static String getType(Object o) {
return getClassName(o);
}
static Object pcallFunction(Object f, Object... args) {
try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace2(__e); }
return null;
}
static String firstJavaToken(String s) {
return s == null ? null : first(javaTokC(s));
}
static List javaTokC(String s) {
int l = s.length();
ArrayList tok = new ArrayList();
int i = 0;
while (i < l) {
int j = i;
char c, d;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
d = j+1 >= l ? '\0' : s.charAt(j+1);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (c == '/' && d == '*') {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (c == '/' && d == '/') {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
i = j;
if (i >= l) break;
c = s.charAt(i);
d = i+1 >= l ? '\0' : s.charAt(i+1);
// scan for non-whitespace
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (c == '[' && d == '[') {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
tok.add(quickSubstring(s, i, j));
i = j;
}
return tok;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static List unnull(List l) {
return l == null ? emptyList() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static Object[] unnull(Object[] a) {
return a == null ? new Object[0] : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Object callFunction(Object f, Object... args) {
return callF(f, args);
}
static RuntimeException asRuntimeException(Throwable t) {
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static Throwable printStackTrace2(Throwable e) {
// we go to system.out now - system.err is nonsense
print(getStackTrace2(e));
return e;
}
static void printStackTrace2() {
printStackTrace2(new Throwable());
}
static void printStackTrace2(String msg) {
printStackTrace2(new Throwable(msg));
}
/*static void printStackTrace2(S indent, Throwable e) {
if (endsWithLetter(indent)) indent += " ";
printIndent(indent, getStackTrace2(e));
}*/
static String getClassName(Object o) {
return o == null ? "null" : o.getClass().getName();
}
static Object first(Object list) {
return empty((List) list) ? null : ((List) list).get(0);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static WeakHashMap> callF_cache = new WeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static Object callF(Object f, Object... args) { try {
if (f instanceof String)
return callMC((String) f, args);
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) throw fail("No get method in " + getClassName(c));
if (n == 1) return methods.get(0).invoke(f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return m.invoke(f, args);
}
throw fail("No matching get method in " + getClassName(c));
} catch (Exception __e) { throw rethrow(__e); } }
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
m.setAccessible(true);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
static List emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static List emptyList(int capacity) {
return new ArrayList(capacity);
}
// Try to match capacity
static List emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
//static int print_maxLineLength = 0; // 0 = unset
static boolean print_silent; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal> print_byThread; // special handling by thread
static void print() {
print("");
}
// slightly overblown signature to return original object...
static A print(A o) {
ping();
if (print_silent) return o;
String s = String.valueOf(o) + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
if (print_byThread != null) {
F1 f = print_byThread.get();
if (f != null)
if (isFalse(f.get(s))) return;
}
print_raw(s);
}
static void print_raw(String s) {
s = fixNewLines(s);
// TODO if (print_maxLineLength != 0)
StringBuffer loc = local_log;
StringBuffer buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
}
static void print(long l) {
print(String.valueOf(l));
}
static void print(char c) {
print(String.valueOf(c));
}
static void print_append(StringBuffer buf, String s, int max) {
synchronized(buf) {
buf.append(s);
max /= 2;
if (buf.length() > max) try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
}
}
static String quickSubstring(String s, int i, int j) {
if (i == j) return "";
return s.substring(i, j);
}
static String getStackTrace2(Throwable throwable) {
return getStackTrace(throwable) + replacePrefix("java.lang.RuntimeException: ", "FAIL: ",
str(getInnerException(throwable))) + "\n";
}
static String fixNewLines(String s) {
return s.replace("\r\n", "\n").replace("\r", "\n");
}
static volatile boolean ping_pauseAll;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions;
static Map ping_actions = synchroMap(new WeakHashMap());
// always returns true
static boolean ping() {
if (ping_pauseAll || ping_anyActions) ping_impl();
return true;
}
// returns true when it slept
static boolean ping_impl() { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) {
Object action;
synchronized(ping_actions) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
static final HashMap> callMC_cache = new HashMap();
static String callMC_key;
static Method callMC_value;
// varargs assignment fixer for a single string array argument
static Object callMC(String method, String[] arg) {
return callMC(method, new Object[] {arg});
}
static Object callMC(String method, Object... args) { try {
Method me;
synchronized(callMC_cache) {
me = method == callMC_key ? callMC_value : null;
}
if (me != null) return callMC_value.invoke(null, args);
List m;
synchronized(callMC_cache) {
m = callMC_cache.get(method);
}
if (m == null) {
if (callMC_cache.isEmpty()) {
callMC_makeCache();
m = callMC_cache.get(method);
}
if (m == null) throw fail("Method named " + method + " not found in main");
}
int n = m.size();
if (n == 1) {
me = m.get(0);
synchronized(callMC_cache) {
callMC_key = method;
callMC_value = me;
}
return me.invoke(null, args);
}
for (int i = 0; i < n; i++) {
me = m.get(i);
if (call_checkArgs(me, args, false))
return me.invoke(null, args);
}
throw fail("No method called " + method + " with matching arguments found in main");
} catch (Exception __e) { throw rethrow(__e); } }
static void callMC_makeCache() {
synchronized(callMC_cache) {
callMC_cache.clear();
Class _c = (Class) mc(), c = _c;
while (c != null) {
for (Method m : c.getDeclaredMethods())
if ((m.getModifiers() & Modifier.STATIC) != 0) {
m.setAccessible(true);
multiMapPut(callMC_cache, m.getName(), m);
}
c = c.getSuperclass();
}
}
}
static String getStackTrace(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
static RuntimeException rethrow(Throwable e) {
throw asRuntimeException(e);
}
static boolean isFalse(Object o) {
return eq(false, o);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); } static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
return o instanceof String ? l((String) o)
: o instanceof Map ? l((Map) o)
: l((Collection) o); // incomplete
}
static String replacePrefix(String prefix, String replacement, String s) {
if (!startsWith(s, prefix)) return s;
return replacement + substring(s, l(prefix));
}
static Throwable getInnerException(Throwable e) {
while (e.getCause() != null)
e = e.getCause();
return e;
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static Object call(Object o) {
return callFunction(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
try {
if (o instanceof Class) {
Method m = call_findStaticMethod((Class) o, method, args, false);
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = call_findMethod(o, method, args, false);
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
}
static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
}
static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && call_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
}
private static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
static String substring(String s, int x) {
return substring(s, x, l(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
if (x > s.length()) return "";
if (y < x) y = x;
if (y > s.length()) y = s.length();
return s.substring(x, y);
}
static Class mc() {
return main.class;
}
static void multiMapPut(Map> map, A a, B b) {
List l = map.get(a);
if (l == null)
map.put(a, l = new ArrayList());
l.add(b);
}
// TODO: test if android complains about this
static boolean isAWTThread() {
if (isAndroid()) return false;
if (isHeadless()) return false;
return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
return SwingUtilities.isEventDispatchThread();
}
// extended over Class.isInstance() to handle primitive types
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static Thread currentThread() {
return Thread.currentThread();
}
static boolean eq(Object a, Object b) {
return a == null ? b == null : a == b || a.equals(b);
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(b);
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
m.m = new String[] {substring(a, l(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || l(b) > l(a)) return false;
for (int i = 0; i < l(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
SwingUtilities.isEventDispatchThread();
return isHeadless_cache = false;
} catch (Throwable e) { return isHeadless_cache = true; }
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static Map synchroHashMap() {
return Collections.synchronizedMap(new HashMap());
}
static int isAndroid_flag;
static boolean isAndroid() {
if (isAndroid_flag == 0)
isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1;
return isAndroid_flag > 0;
}
static class ScoreBoard {
double fullScore;
Map scores = new HashMap();
void print() {
printAsciiHeading("Score board");
List l = new ArrayList();
for (A key : keys(sortByValueDesc(scores))) {
double score = scores.get(key);
l.add(key + " = " + score + " (" + ratioToIntPercent_floor(score, fullScore) + "%)");
}
pnl(l);
}
}
static abstract class F0 {
abstract A get();
}
static abstract class F1 {
abstract B get(A a);
}
// A concept should be an object, not just a string.
// Functions that should always be there for child processes:
static int concepts_internStringsLongerThan = 10;
static ThreadLocal concepts_unlisted = new ThreadLocal();
static interface Derefable {
Concept get();
}
static interface IConceptIndex {
void update(Concept c); // also for adding
void remove(Concept c);
}
static interface IFieldIndex {
List getAll(Val val);
}
static class Concepts {
Map concepts = synchroTreeMap();
HashMap perClassData = new HashMap();
String programID; // set to "-" for non-persistent (possibly not implemented)
long idCounter;
volatile long changes = 1, changesWritten;
volatile java.util.Timer autoSaver;
volatile boolean savingConcepts, dontSave;
int autoSaveInterval = -1000; // 1 second + wait logic
boolean useGZIP = true, quietSave;
ReentrantLock lock = new ReentrantLock(true);
ReentrantLock saverLock = new ReentrantLock(true);
long lastSaveTook, lastSaveWas;
float maxAutoSavePercentage = 10;
List conceptIndices;
Map, Map> fieldIndices;
Concepts() {}
Concepts(String programID) {
this.programID = programID;}
synchronized long internalID() {
do {
++idCounter;
} while (hasConcept(idCounter));
return idCounter;
}
void initProgramID() {
if (programID == null)
programID = getDBProgramID();
}
// Now tries to load from bot first, then go to disk.
Concepts load() {
return load(false);
}
Concepts safeLoad() {
return load(true);
}
Concepts load(boolean allDynamic) {
initProgramID();
if (tryToGrab(allDynamic)) return this;
return loadFromDisk(allDynamic);
}
Concepts loadFromDisk() { return loadFromDisk(false); }
Concepts loadFromDisk(boolean allDynamic) {
clearConcepts();
DynamicObject_loading.set(true);
try {
long time = now();
Map _concepts = concepts; // empty map
readLocally2_allDynamic.set(allDynamic);
readLocally2(this, programID, "concepts");
Map __concepts = concepts;
concepts = _concepts;
concepts.putAll(__concepts);
int l = readLocally_stringLength;
int tokrefs = unstructure_tokrefs;
assignConceptsToUs();
done("Loaded " + n(l(concepts), "concepts"), time);
if (fileSize(getProgramFile(programID, "idCounter.structure")) != 0)
readLocally2(this, programID, "idCounter");
else
calcIdCounter();
} finally {
DynamicObject_loading.set(null);
}
allChanged();
return this;
}
Concepts loadConcepts() { return load(); }
boolean tryToGrab(boolean allDynamic) {
if (sameSnippetID(programID, getDBProgramID())) return false;
RemoteDB db = connectToDBOpt(programID);
try {
if (db != null) {
loadGrab(db.fullgrab(), allDynamic);
return true;
}
} finally {
if (db != null) db.close();
}
return false;
}
Concepts load(String grab) {
return loadGrab(grab, false);
}
Concepts safeLoad(String grab) {
return loadGrab(grab, true);
}
Concepts loadGrab(String grab, boolean allDynamic) {
clearConcepts();
DynamicObject_loading.set(true);
try {
Map map = (Map)
(allDynamic ? safeUnstructure(grab) : unstructure(grab));
concepts.putAll(map);
assignConceptsToUs();
for (long l : map.keySet())
idCounter = max(idCounter, l);
} finally {
DynamicObject_loading.set(null);
}
allChanged();
return this;
}
void assignConceptsToUs() {
for (Concept c : values(concepts)) {
c._concepts = this;
callOpt_noArgs(c, "_doneLoading2");
}
}
String progID() {
return programID == null ? getDBProgramID() : programID;
}
Concept getConcept(String id) {
return empty(id) ? null : getConcept(parseLong(id));
}
Concept getConcept(long id) {
return (Concept) concepts.get((long) id);
}
Concept getConcept(RC ref) {
return ref == null ? null : getConcept(ref.longID());
}
boolean hasConcept(long id) {
return concepts.containsKey((long) id);
}
void deleteConcept(long id) {
Concept c = getConcept(id);
if (c == null)
print("Concept " + id + " not found");
else
c.delete();
}
void calcIdCounter() {
long id_ = 0;
for (long id : keys(concepts))
id_ = max(id_, id);
idCounter = id_+1;
saveLocally2(this, programID, "idCounter");
}
void saveConceptsIfDirty() { saveConcepts(); }
void save() { saveConcepts(); }
void saveConcepts() {
if (dontSave) return;
initProgramID();
saverLock.lock();
savingConcepts = true;
long start = now(), time;
try {
String s = null;
//synchronized(main.class) {
long _changes = changes;
if (_changes == changesWritten) return;
File f = getProgramFile(programID, useGZIP ? "concepts.structure.gz" : "concepts.structure");
lock.lock();
long fullTime = now();
try {
saveLocally2(this, programID, "idCounter");
if (useGZIP) {
saveGZStructureToFile(f, cloneMap(concepts));
getProgramFile(programID, "concepts.structure").delete();
} else
s = structure(cloneMap(concepts));
} finally {
lock.unlock();
}
changesWritten = _changes; // only update when structure didn't fail
if (!useGZIP) {
time = now()-start;
if (!quietSave)
print("Saving " + toM(l(s)) + "M chars (" /*+ changesWritten + ", "*/ + time + " ms)");
start = now();
saveTextFile(f, javaTokWordWrap(s));
getProgramFile(programID, "concepts.structure.gz").delete();
}
copyFile(f, getProgramFile(programID, "concepts.structure" + (useGZIP ? ".gz" : "") + ".backup" + ymd() + "-" + formatInt(hours(), 2)));
time = now()-start;
if (!quietSave)
print(programID + ": Saved " + toK(f.length()) + " K, " + n(concepts, "concepts") + " (" + time + " ms)");
lastSaveWas = fullTime;
lastSaveTook = now()-fullTime;
} finally {
savingConcepts = false;
saverLock.unlock();
}
}
void _autoSaveConcepts() {
if (autoSaveInterval < 0 && maxAutoSavePercentage != 0) {
long pivotTime = Math.round(lastSaveWas+lastSaveTook*100.0/maxAutoSavePercentage);
if (now() < pivotTime) {
//print("Skipping auto-save (last save took " + lastSaveTook + ")");
return;
}
}
saveConcepts();
}
void clearConcepts() {
concepts.clear();
allChanged();
}
synchronized void allChanged() {
++changes;
}
// auto-save every second if dirty
synchronized void autoSaveConcepts() {
if (autoSaver == null) {
if (isTransient()) throw fail("Can't persist transient database");
autoSaver = doEvery_daemon(abs(autoSaveInterval), new Runnable() { public void run() { try { _autoSaveConcepts() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "_autoSaveConcepts()"; }});
// print("Installed auto-saver (" + autoSaveInterval + " ms, " + progID() + ")");
}
}
void cleanMeUp() {
if (autoSaver != null) {
autoSaver.cancel();
autoSaver = null;
}
while (savingConcepts) sleepInCleanUp(10);
saveConceptsIfDirty();
}
Map getIDsAndNames() {
Map map = new HashMap();
Map cloned = cloneMap(concepts);
for (long id : keys(cloned))
map.put(id, cloned.get(id).className);
return map;
}
void deleteConcepts(List l) {
for (Object o : l)
if (o instanceof Long)
concepts.remove((Long) o);
else if (o instanceof Concept)
((Concept) o).delete();
else
warn("Can't delete " + getClassName(o));
}
A conceptOfType(Class type) {
return firstOfType(allConcepts(), type);
}
List conceptsOfType(Class type) {
return filterByType(allConcepts(), type);
}
List listConcepts(Class type) {
return conceptsOfType(type);
}
List list(Class type) {
return conceptsOfType(type);
}
List list(String type) {
return conceptsOfType(type);
}
List conceptsOfType(String type) {
return filterByDynamicType(allConcepts(), "main$" + type);
}
boolean hasConceptOfType(Class extends Concept> type) {
return hasType(allConcepts(), type);
}
void persistConcepts() {
loadConcepts();
autoSaveConcepts();
}
// We love synonyms
void conceptPersistence() {
persistConcepts();
}
Concepts persist() { persistConcepts(); return this; }
void persist(int interval) { autoSaveInterval = interval; persist(); }
// Runs r if there is no concept of that type
A ensureHas(Class c, Runnable r) {
A a = conceptOfType(c);
if (a == null) {
r.run();
a = conceptOfType(c);
if (a == null)
throw fail("Concept not made by " + r + ": " + shortClassName(c));
}
return a;
}
// Ensures that every concept of type c1 is ref'd by a concept of
// type c2.
// Type of func: voidfunc(concept)
void ensureHas(Class extends Concept> c1, Class extends Concept> c2, Object func) {
for (Concept a : conceptsOfType(c1)) {
Concept b = findBackRef(a, c2);
if (b == null) {
callF(func, a);
b = findBackRef(a, c2);
if (b == null)
throw fail("Concept not made by " + func + ": " + shortClassName(c2));
}
}
}
// Type of func: voidfunc(concept)
void forEvery(Class extends Concept> type, Object func) {
for (Concept c : conceptsOfType(type))
callF(func, c);
}
int deleteAll(Class extends Concept> type) {
List l = (List) conceptsOfType(type);
for (Concept c : l) c.delete();
return l(l);
}
Collection allConcepts() {
synchronized(concepts) {
return new ArrayList(values(concepts));
}
}
int countConcepts(Class c, Object... params) {
int n = 0;
for (A x : list(c)) if (checkConceptFields(x, params)) ++n;
return n;
}
int countConcepts(String c, Object... params) {
int n = 0;
for (Concept x : list(c)) if (checkConceptFields(x, params)) ++n;
return n;
}
int countConcepts() {
return l(concepts);
}
synchronized void addConceptIndex(IConceptIndex index) {
if (conceptIndices == null)
conceptIndices = new ArrayList();
conceptIndices.add(index);
}
synchronized void addFieldIndex(Class extends Concept> c, String field, IFieldIndex index) {
if (fieldIndices == null)
fieldIndices = new HashMap();
Map map = fieldIndices.get(c);
if (map == null)
fieldIndices.put(c, map = new HashMap());
map.put(field, index);
}
synchronized IFieldIndex getFieldIndex(Class extends Concept> c, String field) {
if (fieldIndices == null) return null;
Map map = fieldIndices.get(c);
return map == null ? null : map.get(field);
}
// inter-process methods
RC xnew(String name, Object... values) {
return new RC(cnew(name, values));
}
void xset(long id, String field, Object value) {
xset(new RC(id), field, value);
}
void xset(RC c, String field, Object value) {
if (value instanceof RC)
value = getConcept((RC) value);
cset(getConcept(c), field, value);
}
Object xget(long id, String field) {
return xget(new RC(id), field);
}
Object xget(RC c, String field) {
return xgetPost(cget(getConcept(c), field));
}
Object xgetPost(Object o) {
o = deref(o);
if (o instanceof Concept)
return new RC((Concept) o);
return o;
}
void xdelete(long id) {
xdelete(new RC(id));
}
void xdelete(RC c) {
getConcept(c).delete();
}
void xdelete(List l) {
for (RC c : l)
xdelete(c);
}
List xlist() {
return map("toPassRef", allConcepts());
}
List xlist(String className) {
return map("toPassRef", conceptsOfType(className));
}
boolean isTransient() { return eq(programID, "-"); }
String xfullgrab() {
lock.lock();
try {
if (changes == changesWritten && !isTransient())
return loadConceptsStructure(programID);
return structure(cloneMap(concepts));
} finally {
lock.unlock();
}
}
void xshutdown() {
// Killing whole VM if someone wants this DB to shut down
cleanKillVM();
}
long xchangeCount() { return changes; }
int xcount() { return countConcepts(); }
void register(Concept c) {
if (c._concepts == this) return;
if (c._concepts != null) throw fail("Can't re-register");
c._concepts = this;
c.id = internalID();
c.created = now();
concepts.put((long) c.id, c);
c.change();
}
} // class Concepts
static volatile Concepts mainConcepts = new Concepts(); // Where we create new concepts
static class Concept extends DynamicObject {
transient Concepts _concepts; // Where we belong
long id;
//O madeBy;
//double energy;
//bool defunct;
long created;
// used only internally (cnew)
Concept(String className) {
super(className);
_created();
}
Concept() {
if (!_loading()) {
//className = shortClassName(this); // XXX - necessary?
//print("New concept of type " + className);
_created();
}
}
List[ refs;
List][ backRefs;
static boolean loading() { return _loading(); }
static boolean _loading() { return isTrue(DynamicObject_loading.get()); }
void _created() {
if (!isTrue(concepts_unlisted.get()))
mainConcepts.register(this);
}
/*void put(S field, O value) {
fieldValues.put(field, value);
change();
}
O get(S field) {
ret fieldValues.get(field);
}*/
class Ref {
A value;
Ref() {
if (!isTrue(DynamicObject_loading.get())) refs = addDyn(refs, this);
}
Ref(A value) {
this.value = value;
refs = addDyn(refs, this);
index();
}
// get owning concept (source)
Concept concept() {
return Concept.this;
}
// get target
A get() { return value; }
boolean has() { return value != null; }
void set(A a) {
if (a == value) return;
unindex();
value = a;
index();
}
void set(Ref ref) { set(ref.get()); }
void clear() { set((A) null); }
void index() {
if (value != null)
value.backRefs = addDyn(value.backRefs, this);
change();
}
void unindex() {
if (value != null)
value.backRefs = removeDyn(value.backRefs, this);
}
void change() {
Concept.this.change();
}
}
class RefL extends AbstractList {
List < Ref < A > > l = new ArrayList();
public A set(int i, A o) {
A prev = l.get(i).get();
l.get(i).set(o);
return prev;
}
public void add(int i, A o) {
l.add(i, new Ref(o));
}
public A get(int i) {
return l.get(i).get();
}
public A remove(int i) {
return l.remove(i).get();
}
public int size() {
return l.size();
}
public boolean contains(Object o) {
if (o instanceof Concept)
for (Ref r : l) if (eq(r.get(), o)) return true;
return super.contains(o);
}
}
void delete() {
//name = "[defunct " + name + "]";
//defunct = true;
//energy = 0;
for (Ref r : unnull(refs))
r.unindex();
refs = null;
for (Ref r : cloneList(backRefs))
r.set((Concept) null);
backRefs = null;
if (_concepts != null) {
_concepts.concepts.remove((long) id);
_concepts.allChanged();
if (_concepts.conceptIndices != null)
for (IConceptIndex index : _concepts.conceptIndices)
index.remove(this);
_concepts = null;
}
id = 0;
}
BaseXRef export() {
return new BaseXRef(_concepts.progID(), id);
}
// notice system of a change in this object
void change() {
if (_concepts != null) {
_concepts.allChanged();
if (_concepts.conceptIndices != null)
for (IConceptIndex index : _concepts.conceptIndices)
index.update(this);
}
}
String _programID() {
return _concepts == null ? getDBProgramID() : _concepts.progID();
}
} // class Concept
// remote reference (for inter-process communication or
// external databases). Formerly "PassRef".
// prepared for string ids if we do them later
static class RC {
transient Object owner;
String id;
RC() {} // make serialisation happy
RC(long id) { this.id = str(id); }
RC(Object owner, long id) { this.id = str(id); this.owner = owner; }
RC(Concept c) { this(c.id); }
long longID() { return parseLong(id); }
public String toString() {
return id;
}
transient RemoteDB db;
String getString(String field) { return db.xS(this, field); }
Object get(String field) { return db.xget(this, field); }
void set(String field, Object value) { db.xset(this, field, value); }
}
// Reference to a concept in another program
static class BaseXRef {
String programID;
long id;
BaseXRef() {}
BaseXRef(String programID, long id) {
this.id = id;
this.programID = programID;}
public boolean equals(Object o) {
if (!(o instanceof BaseXRef)) return false;
BaseXRef r = (BaseXRef) ( o);
return eq(programID, r.programID) && eq(id, r.id);
}
public int hashCode() {
return programID.hashCode() + (int) id;
}
}
// BaseXRef as a concept
static class XRef extends Concept {
BaseXRef ref;
XRef() {}
XRef(BaseXRef ref) {
this.ref = ref; _doneLoading2(); }
// after we have been added to concepts
void _doneLoading2() {
getIndex().put(ref, this);
}
HashMap getIndex() {
return getXRefIndex(_concepts);
}
}
static synchronized HashMap getXRefIndex(Concepts concepts) {
HashMap cache = (HashMap) concepts.perClassData.get(XRef.class);
if (cache == null)
concepts.perClassData.put(XRef.class, cache = new HashMap());
return cache;
}
// uses mainConcepts
static XRef lookupOrCreateXRef(BaseXRef ref) {
XRef xref = getXRefIndex(mainConcepts).get(ref);
if (xref == null)
xref = new XRef(ref);
return xref;
}
// define standard concept functions to use main concepts
static List list(Class type) {
return mainConcepts.list(type);
}
static List list(Concepts concepts, Class type) {
return concepts.list(type);
}
static List list(String type) {
return mainConcepts.list(type);
}
static List list(Concepts concepts, String type) {
return concepts.list(type);
}
static int csetAll(Concept c, Object... values) {
return cset(c, values);
}
static void cleanMeUp_concepts() {
mainConcepts.cleanMeUp();
}
static void loadAndAutoSaveConcepts() {
mainConcepts.persist();
}
static void loadAndAutoSaveConcepts(int interval) {
mainConcepts.persist(interval);
}
static void loadConceptsFrom(String progID) {
mainConcepts.programID = progID;
mainConcepts.load();
}
static List conceptsOfType(String type) {
return mainConcepts.conceptsOfType(type);
}
static long changeCount() {
return mainConcepts.changes;
}
static List exposedDBMethods = ll("xlist", "xnew", "xset", "xdelete", "xget", "xclass", "xfullgrab", "xshutdown", "xchangeCount", "xcount");
static RC toPassRef(Concept c) {
return new RC(c);
}
// so we can instantiate the program to run as a bare DB bot
static void printAsciiHeading(String text) {
print(asciiHeading2(text));
}
static Map sortByValueDesc(Map map) {
return orderMapByDescendingValue(map);
}
static int ratioToIntPercent_floor(double x, double y) {
return ifloor(x*100/y);
}
static ArrayList list(A[] a) {
return asList(a);
}
static ArrayList list(int[] a) {
return asList(a);
}
static ArrayList list(Set s) {
return asList(s);
}
static void pnl(Collection l) {
printNumberedLines(l);
}
static void pnl(Map map) {
printNumberedLines(map);
}
static Set keys(Map map) {
return map.keySet();
}
static Set keys(Object map) {
return keys((Map) map);
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
f.setAccessible(true);
return f.get(o);
}
if (o instanceof DynamicObject)
return ((DynamicObject) o).fieldValues.get(field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(Object o, String field) {
try {
Field f = get_findField(o.getClass(), field);
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static ArrayList asList(A[] a) {
return new ArrayList(Arrays.asList(a));
}
static ArrayList asList(int[] a) {
ArrayList l = new ArrayList();
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static String asciiHeading2(String title) {
return asciiHeading(title) + "\n";
}
static int ifloor(double d) {
return (int) Math.floor(d);
}
static List printNumberedLines(List l) {
printNumberedLines((Collection) l);
return l;
}
static void printNumberedLines(Map map) {
printNumberedLines(mapToLines(map));
}
static Collection printNumberedLines(Collection l) {
int i = 0;
if (l != null) for (A a : l) print((++i) + ". " + str(a));
return l;
}
static void printNumberedLines(Object[] l) {
printNumberedLines(asList(l));
}
static void printNumberedLines(Object o) {
printNumberedLines(lines(str(o)));
}
// return a fancy litorderedmap
static Map orderMapByDescendingValue(final Map map) {
List l = new ArrayList(map.keySet());
sort(l, mapComparatorDesc(map));
Map map2 = litorderedmap();
for (A a : l)
map2.put(a, map.get(a));
return map2;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static LinkedHashMap litorderedmap(Object... x) {
LinkedHashMap map = new LinkedHashMap();
litmap_impl(map, x);
return map;
}
static String asciiHeading(String title) {
return "\n" + title + "\n" + rep(l(title), '-');
}
static void sort(T[] a, Comparator super T> c) {
Arrays.sort(a, c);
}
static void sort(T[] a) {
Arrays.sort(a);
}
static void sort(List a, Comparator super T> c) {
Collections.sort(a, c);
}
static void sort(List a) {
Collections.sort(a);
}
static List mapToLines(Map map) {
List l = new ArrayList();
for (Object key : keys(map))
l.add(str(key) + " = " + str(map.get(key)));
return l;
}
static String lines(Collection lines) { return fromLines(lines); }
static List lines(String s) { return toLines(s); }
static Comparator mapComparatorDesc(final Map map) {
return new Comparator() {
public int compare(A a, A b) {
return cmp(map.get(b), map.get(a));
}
};
}
static String rep(int n, char c) {
return repeat(c, n);
}
static String rep(char c, int n) {
return repeat(c, n);
}
static List rep(A a, int n) {
return repeat(a, n);
}
static List rep(int n, A a) {
return repeat(n, a);
}
static int cmp(Number a, Number b) {
return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue());
}
static int cmp(double a, double b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(String a, String b) {
return a == null ? b == null ? 0 : -1 : a.compareTo(b);
}
static int cmp(Object a, Object b) {
if (a == null) return b == null ? 0 : -1;
if (b == null) return 1;
return ((Comparable) a).compareTo(b);
}
// usually L]
static String fromLines(Collection lines) {
StringBuilder buf = new StringBuilder();
if (lines != null)
for (Object line : lines)
buf.append(str(line)).append('\n');
return buf.toString();
}
static String fromLines(String... lines) {
return fromLines(asList(lines));
}
static List toLines(File f) {
return toLines(loadTextFile(f));
}
public static List toLines(String s) {
List lines = new ArrayList();
if (s == null) return lines;
int start = 0;
while (true) {
int i = toLines_nextLineBreak(s, start);
if (i < 0) {
if (s.length() > start) lines.add(s.substring(start));
break;
}
lines.add(s.substring(start, i));
if (s.charAt(i) == '\r' && i+1 < s.length() && s.charAt(i+1) == '\n')
i += 2;
else
++i;
start = i;
}
return lines;
}
private static int toLines_nextLineBreak(String s, int start) {
for (int i = start; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '\r' || c == '\n')
return i;
}
return -1;
}
static Map litmap(Object... x) {
TreeMap map = new TreeMap();
litmap_impl(map, x);
return map;
}
static void litmap_impl(Map map, Object... x) {
for (int i = 0; i < x.length-1; i += 2)
if (x[i+1] != null)
map.put(x[i], x[i+1]);
}
static String repeat(char c, int n) {
n = Math.max(n, 0);
char[] chars = new char[n];
for (int i = 0; i < n; i++)
chars[i] = c;
return new String(chars);
}
static List repeat(A a, int n) {
List l = new ArrayList(n);
for (int i = 0; i < n; i++)
l.add(a);
return l;
}
static List repeat(int n, A a) {
return repeat(a, n);
}
public static String loadTextFile(String fileName) {
return loadTextFile(fileName, null);
}
public static String loadTextFile(File fileName, String defaultContents) {
try {
if (fileName == null || !fileName.exists())
return defaultContents;
FileInputStream fileInputStream = new FileInputStream(fileName);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
return loadTextFile(inputStreamReader);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String loadTextFile(File fileName) {
return loadTextFile(fileName, null);
}
public static String loadTextFile(String fileName, String defaultContents) {
return fileName == null ? defaultContents : loadTextFile(newFile(fileName), defaultContents);
}
public static String loadTextFile(Reader reader) throws IOException {
StringBuilder builder = new StringBuilder();
try {
char[] buffer = new char[1024];
int n;
while (-1 != (n = reader.read(buffer)))
builder.append(buffer, 0, n);
} finally {
reader.close();
}
return builder.toString();
}
static File newFile(File base, String... names) {
for (String name : names) base = new File(base, name);
return base;
}
static File newFile(String name) {
return name == null ? null : new File(name);
}
static class RemoteDB {
DialogIO db;
String name;
// s = bot name or snippet ID
RemoteDB(String s) {
this(s, false);
}
RemoteDB(String s, boolean autoStart) {
name = s;
if (isSnippetID(s)) name = dbBotName(s);
db = findBot(name);
if (db == null)
if (autoStart) {
nohupJavax(fsI(s));
waitForBotStartUp(name);
assertNotNull("Weird problem", db = findBot(s));
} else
throw fail("DB " + s + " not running");
}
boolean functional() { return db != null; } // now always true
List list() { return adopt((List) rpc(db, "xlist")); }
List list(String className) { return adopt((List) rpc(db, "xlist", className)); }
List xlist() { return list(); }
List xlist(String className) { return list(className); }
// adopt is an internal method
List adopt(List l) {
if (l != null) for (RC rc : l) adopt(rc);
return l;
}
RC adopt(RC rc) { if (rc != null) rc.db = this; return rc; }
Object adopt(Object o) {
if (o instanceof RC) return adopt((RC) o);
return o;
}
String xclass(RC o) {
return (String) rpc(db, "xclass", o);
}
Object xget(RC o, String field) {
return adopt(rpc(db, "xget", o, field));
}
String xS(RC o, String field) {
return (String) xget(o, field);
}
RC xgetref(RC o, String field) {
return adopt((RC) xget(o, field));
}
void xset(RC o, String field, Object value) {
rpc(db, "xset", o, field, value);
}
RC uniq(String className) {
RC ref = first(list(className));
if (ref == null)
ref = xnew(className);
return ref;
}
RC xuniq(String className) { return uniq(className); }
RC xnew(String className, Object... values) {
return adopt((RC) rpc(db, "xnew", className, values));
}
void xdelete(RC o) {
rpc(db, "xdelete", o);
}
void xdelete(List l) {
rpc(db, "xdelete", l);
}
void close() {
if (db != null)
db.close();
}
String fullgrab() { return (String) rpc(db, "xfullgrab"); }
String xfullgrab() { return fullgrab(); }
void xshutdown() { rpc(db, "xshutdown"); }
long xchangeCount() { return (long) rpc(db, "xchangeCount"); }
int xcount() { return (int) rpc(db, "xcount"); }
void reconnect() {
close();
db = findBot(name);
}
RC rc(long id) { return new RC(this, id); }
}
static ThreadLocal DynamicObject_loading = new ThreadLocal();
static class DynamicObject {
String className; // just the name, without the "main$"
LinkedHashMap fieldValues = new LinkedHashMap();
DynamicObject() {}
// className = just the name, without the "main$"
DynamicObject(String className) {
this.className = className;}
}
static RemoteDB connectToDBOpt(String dbNameOrID) { try {
return new RemoteDB(dbNameOrID);
} catch (Throwable __e) { return null; } }
static A findBackRef(Concept c, Class type) {
for (Concept.Ref r : c.backRefs)
if (instanceOf(r.concept(), type))
return (A) r.concept();
return null;
}
static A findBackRef(Class type, Concept c) {
return findBackRef(c, type);
}
static A assertNotNull(A a) {
assertTrue(a != null);
return a;
}
static A assertNotNull(String msg, A a) {
assertTrue(msg, a != null);
return a;
}
static String fsI(String id) {
return formatSnippetID(id);
}
static String fsI(long id) {
return formatSnippetID(id);
}
static void sleepInCleanUp(long ms) { try {
if (ms < 0) return;
Thread.sleep(ms);
} catch (Exception __e) { throw rethrow(__e); } }
static List filterByDynamicType(Collection c, String type) {
List l = new ArrayList();
for (A x : c)
if (eq(dynamicClassName(x), type))
l.add(x);
return l;
}
static List cloneList(Collection l) {
if (l == null) return new ArrayList();
// assume collection's mutex is equal to collection, which will be true unless you explicitly pass a mutex to synchronizedList() which no one ever does.
synchronized(l) {
return new ArrayList(l);
}
}
static Object safeUnstructure(String s) {
return unstructure(s, true);
}
static List addDyn(List l, A a) {
if (l == null) l = new ArrayList();
l.add(a);
return l;
}
static long toK(long l) {
return (l+1023)/1024;
}
// returns number of changes
static int cset(Concept c, Object... values) { try {
int changes = 0;
values = expandParams(c.getClass(), values);
warnIfOddCount(values);
for (int i = 0; i+1 < l(values); i += 2) {
String field = (String) values[i];
Object value = values[i+1];
Field f = setOpt_findField(c.getClass(), field);
//print("cset: " + c.id + " " + field + " " + struct(value) + " " + f);
if (value instanceof RC) value = c._concepts.getConcept((RC) value);
value = deref(value);
if (value instanceof String && l((String) value) >= concepts_internStringsLongerThan) value = ((String) value).intern();
if (f == null) {
// TODO: keep ref if it exists
mapPut2(c.fieldValues, field, value instanceof Concept ? c.new Ref((Concept) value) : value);
c.change();
} else if (isSubtypeOf(f.getType(), Concept.Ref.class)) {
((Concept.Ref) f.get(c)).set((Concept) derefRef(value));
c.change(); ++changes;
} else {
Object old = f.get(c);
if (neq(value, old)) {
f.set(c, value);
c.change(); ++changes;
}
}
}
return changes;
} catch (Exception __e) { throw rethrow(__e); } }
static boolean contains(Collection c, Object o) {
return c != null && c.contains(o);
}
static boolean contains(Object[] x, Object o) {
if (x != null)
for (Object a : x)
if (eq(a, o))
return true;
return false;
}
static boolean contains(String s, char c) {
return s != null && s.indexOf(c) >= 0;
}
static boolean contains(String s, String b) {
return s != null && s.indexOf(b) >= 0;
}
static long toM(long l) {
return (l+1024*1024-1)/(1024*1024);
}
static String toM(long l, int digits) {
return formatDouble(toM_double(l), digits);
}
static long waitForBotStartUp_timeoutSeconds = 60;
// returns address or fails
static String waitForBotStartUp(String botName) {
for (int i = 0; i < waitForBotStartUp_timeoutSeconds; i++) {
sleepSeconds(i == 0 ? 0 : 1);
String addr = getBotAddress(botName);
if (addr != null)
return addr;
}
throw fail("Bot not found: " + quote(botName));
}
static List removeDyn(List l, A a) {
if (l == null) return null;
l.remove(a);
return empty(l) ? null : l;
}
static Object cget(Object c, String field) {
Object o = getOpt(c, field);
if (o instanceof Concept.Ref) return ((Concept.Ref) o).get();
return o;
}
public static void copyFile(File src, File dest) { try {
mkdirsForFile(dest);
FileInputStream inputStream = new FileInputStream(src.getPath());
FileOutputStream outputStream = newFileOutputStream(dest.getPath());
try {
copyStream(inputStream, outputStream);
inputStream.close();
} finally {
outputStream.close();
}
} catch (Exception __e) { throw rethrow(__e); } }
static void clearConcepts() {
mainConcepts.clearConcepts();
}
static void clearConcepts(Concepts concepts) {
concepts.clearConcepts();
}
static A firstOfType(Collection c, Class type) {
for (Object x : c)
if (isInstanceX(type, x))
return (A) x;
return null;
}
static Object unstructure(String text) {
return unstructure(text, false);
}
static Object unstructure(String text, final boolean allDynamic) {
return unstructure(text, allDynamic, null);
}
static int structure_internStringsLongerThan = 50;
static int unstructure_tokrefs; // stats
abstract static class unstructure_Receiver {
abstract void set(Object o);
}
// classFinder: func(name) -> class (optional)
static Object unstructure(String text, boolean allDynamic,
Object classFinder) {
if (text == null) return null;
return unstructure_tok(javaTokC_noMLS_iterator(text), allDynamic, classFinder);
}
static Object unstructure_reader(BufferedReader reader) {
return unstructure_tok(javaTokC_noMLS_onReader(reader), false, null);
}
static Object unstructure_tok(final Producer tok, final boolean allDynamic, final Object classFinder) {
final boolean debug = unstructure_debug;
final class X {
int i = -1;
HashMap refs = new HashMap();
HashMap tokrefs = new HashMap();
HashSet concepts = new HashSet();
HashMap classesMap = new HashMap();
List stack = new ArrayList();
String curT;
// look at current token
String t() {
return curT;
}
// get current token, move to next
String tpp() {
String t = curT;
consume();
return t;
}
void parse(final unstructure_Receiver out) {
String t = t();
int refID = 0;
if (structure_isMarker(t, 0, l(t))) {
refID = parseInt(t.substring(1));
consume();
}
final int _refID = refID;
// if (debug) print("parse: " + quote(t));
final int tokIndex = i;
parse_inner(refID, tokIndex, new unstructure_Receiver() {
void set(Object o) {
if (_refID != 0)
refs.put(_refID, o);
if (o != null)
tokrefs.put(tokIndex, o);
out.set(o);
}
});
}
void parse_inner(int refID, int tokIndex, final unstructure_Receiver out) {
String t = t();
// if (debug) print("parse_inner: " + quote(t));
Class c = classesMap.get(t);
if (c == null) {
if (t.startsWith("\"")) {
String s = internIfLongerThan(unquote(tpp()), structure_internStringsLongerThan);
out.set(s); return;
}
if (t.startsWith("'")) {
out.set(unquoteCharacter(tpp())); return;
}
if (t.equals("bigint")) {
out.set(parseBigInt()); return;
}
if (t.equals("d")) {
out.set(parseDouble()); return;
}
if (t.equals("fl")) {
out.set(parseFloat()); return;
}
if (t.equals("false") || t.equals("f")) {
consume(); out.set(false); return;
}
if (t.equals("true") || t.equals("t")) {
consume(); out.set(true); return;
}
if (t.equals("-")) {
consume();
t = tpp();
out.set(isLongConstant(t) ? (Object) (-parseLong(t)) : (Object) (-parseInt(t))); return;
}
if (isInteger(t) || isLongConstant(t)) {
consume();
//if (debug) print("isLongConstant " + quote(t) + " => " + isLongConstant(t));
if (isLongConstant(t)) {
out.set(parseLong(t)); return;
}
long l = parseLong(t);
boolean isInt = l == (int) l;
if (debug)
print("l=" + l + ", isInt: " + isInt);
out.set(isInt ? (Object) new Integer((int) l) : (Object) new Long(l)); return;
}
if (t.equals("File")) {
consume();
File f = new File(unquote(tpp()));
out.set(f); return;
}
if (t.startsWith("r") && isInteger(t.substring(1))) {
consume();
int ref = Integer.parseInt(t.substring(1));
Object o = refs.get(ref);
if (o == null)
print("Warning: unsatisfied back reference " + ref);
out.set(o); return;
}
if (t.startsWith("t") && isInteger(t.substring(1))) {
consume();
int ref = Integer.parseInt(t.substring(1));
Object o = tokrefs.get(ref);
if (o == null)
print("Warning: unsatisfied token reference " + ref);
out.set(o); return;
}
if (t.equals("hashset")) {
parseHashSet(out); return;
}
if (t.equals("treeset")) {
parseTreeSet(out); return;
}
if (eqOneOf(t, "hashmap", "hm")) {
consume();
parseMap(new HashMap(), out);
return;
}
if (t.equals("lhm")) {
consume();
parseMap(new LinkedHashMap(), out);
return;
}
if (t.equals("{")) {
parseMap(out); return;
}
if (t.equals("[")) {
parseList(out); return;
}
if (t.equals("bitset")) {
parseBitSet(out); return;
}
if (t.equals("array") || t.equals("intarray")) {
parseArray(out); return;
}
if (t.equals("ba")) {
consume();
String hex = unquote(tpp());
out.set(hexToBytes(hex)); return;
}
if (t.equals("boolarray")) {
consume();
int n = parseInt(tpp());
String hex = unquote(tpp());
out.set(boolArrayFromBytes(hexToBytes(hex), n)); return;
}
if (t.equals("class")) {
out.set(parseClass()); return;
}
if (t.equals("l")) {
parseLisp(out); return;
}
if (t.equals("null")) {
consume(); out.set(null); return;
}
if (eq(t, "c")) {
consume("c");
t = t();
assertTrue(isJavaIdentifier(t));
concepts.add(t);
}
}
if (eq(t, "j")) {
consume("j");
out.set(parseJava()); return;
}
if (c == null && !isJavaIdentifier(t))
throw new RuntimeException("Unknown token " + (i+1) + ": " + t);
// any other class name
if (c == null) {
// First, find class
if (allDynamic) c = null;
else c = classFinder != null ? (Class) callF(classFinder, t) : findClass(t);
if (c != null)
classesMap.put(t, c);
}
// Check if it has an outer reference
consume();
boolean hasBracket = eq(t(), "(");
if (hasBracket) consume();
boolean hasOuter = hasBracket && eq(t(), "this$1");
DynamicObject dO = null;
Object o = null;
if (c != null) {
o = hasOuter ? nuStubInnerObject(c) : nuEmptyObject(c);
if (o instanceof DynamicObject) dO = (DynamicObject) o;
} else {
if (concepts.contains(t) && (c = findClass("Concept")) != null)
o = dO = (DynamicObject) nuEmptyObject(c);
else
dO = new DynamicObject();
dO.className = t;
if (debug) print("Made dynamic object " + t + " " + shortClassName(dO));
}
// Save in references list early because contents of object
// might link back to main object
if (refID != 0)
refs.put(refID, o != null ? o : dO);
tokrefs.put(tokIndex, o != null ? o : dO);
// NOW parse the fields!
final LinkedHashMap fields = new LinkedHashMap(); // preserve order
final Object _o = o;
final DynamicObject _dO = dO;
if (hasBracket) {
stack.add(new Runnable() { public void run() { try {
if (eq(t(), ")")) {
consume(")");
objRead(_o, _dO, fields);
out.set(_o != null ? _o : _dO);
} else {
final String key = unquote(tpp());
consume("=");
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object value) {
fields.put(key, value);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \")\")) {\r\n consume(\")\");\r\n objRead(_o, _dO, fie..."; }});
} else {
objRead(o, dO, fields);
out.set(o != null ? o : dO);
}
}
void objRead(Object o, DynamicObject dO, Map fields) {
if (o != null)
if (dO != null) {
if (debug)
printStructure("setOptAllDyn", fields);
setOptAllDyn(dO, fields);
} else {
setOptAll(o, fields);
}
else for (String field : keys(fields))
dO.fieldValues.put(field.intern(), fields.get(field));
if (o != null)
pcallOpt_noArgs(o, "_doneLoading");
}
void parseSet(final Set set, final unstructure_Receiver out) {
parseList(new unstructure_Receiver() {
void set(Object o) {
set.addAll((List) o);
out.set(set);
}
});
}
void parseLisp(final unstructure_Receiver out) {
consume("l");
consume("(");
final ArrayList list = new ArrayList();
stack.add(new Runnable() { public void run() { try {
if (eq(t(), ")")) {
consume(")");
out.set(newObject("main$Lisp", (String) list.get(0), subList(list, 1)));
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
list.add(o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \")\")) {\r\n consume(\")\");\r\n out.set(newObject(\"main$..."; }});
}
void parseBitSet(final unstructure_Receiver out) {
consume("bitset");
consume("{");
final BitSet bs = new BitSet();
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "}")) {
consume("}");
out.set(bs);
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
bs.set((Integer) o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(bs);\r\n } ..."; }});
}
void parseList(final unstructure_Receiver out) {
consume("[");
final ArrayList list = new ArrayList();
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "]")) {
consume("]");
out.set(list);
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
//if (debug) print("List element type: " + getClassName(o));
list.add(o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"]\")) {\r\n consume(\"]\");\r\n out.set(list);\r\n ..."; }});
}
void parseArray(final unstructure_Receiver out) {
final String type = tpp();
consume("{");
final List list = new ArrayList();
stack.add(new Runnable() { public void run() { try {
if (eq(t(), "}")) {
consume("}");
out.set(type.equals("intarray") ? toIntArray(list) : list.toArray());
} else {
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
list.add(o);
if (eq(t(), ",")) consume();
}
});
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (eq(t(), \"}\")) {\r\n consume(\"}\");\r\n out.set(type.equals(\"int..."; }});
}
Object parseClass() {
consume("class");
consume("(");
String name = unquote(tpp());
consume(")");
name = dropPrefix("main$", name);
Class c = allDynamic ? null : classFinder != null ? (Class) callF(classFinder, name) : findClass(name);
if (c != null) return c;
DynamicObject dO = new DynamicObject();
dO.className = "java.lang.Class";
dO.fieldValues.put("name", name);
return dO;
}
Object parseBigInt() {
consume("bigint");
consume("(");
String val = tpp();
if (eq(val, "-"))
val = "-" + tpp();
consume(")");
return new BigInteger(val);
}
Object parseDouble() {
consume("d");
consume("(");
String val = unquote(tpp());
consume(")");
return Double.parseDouble(val);
}
Object parseFloat() {
consume("fl");
String val;
if (eq(t(), "(")) {
consume("(");
val = unquote(tpp());
consume(")");
} else {
val = unquote(tpp());
}
return Float.parseFloat(val);
}
void parseHashSet(unstructure_Receiver out) {
consume("hashset");
parseSet(new HashSet(), out);
}
void parseTreeSet(unstructure_Receiver out) {
consume("treeset");
parseSet(new TreeSet(), out);
}
void parseMap(unstructure_Receiver out) {
parseMap(new TreeMap(), out);
}
Object parseJava() {
String j = unquote(tpp());
Matches m = new Matches();
if (jmatch("java.awt.Color[r=*,g=*,b=*]", j, m))
return nuObject("java.awt.Color", parseInt(m.unq(0)), parseInt(m.unq(1)), parseInt(m.unq(2)));
else {
warn("Unknown Java object: " + j);
return null;
}
}
void parseMap(final Map map, final unstructure_Receiver out) {
consume("{");
stack.add(new Runnable() {
boolean v;
Object key;
public void run() {
if (v) {
v = false;
stack.add(this);
consume("=");
parse(new unstructure_Receiver() {
void set(Object value) {
map.put(key, value);
if (debug)
print("parseMap: Got value " + getClassName(value) + ", next token: " + quote(t()));
if (eq(t(), ",")) consume();
}
});
} else {
if (eq(t(), "}")) {
consume("}");
out.set(map);
} else {
v = true;
stack.add(this);
parse(new unstructure_Receiver() {
void set(Object o) {
key = o;
}
});
}
} // if v else
} // run()
});
}
/*void parseSub(unstructure_Receiver out) {
int n = l(stack);
parse(out);
while (l(stack) > n)
stack
}*/
void consume() { curT = tok.next(); ++i; }
void consume(String s) {
if (!eq(t(), s)) {
/*S prevToken = i-1 >= 0 ? tok.get(i-1) : "";
S nextTokens = join(tok.subList(i, Math.min(i+2, tok.size())));
fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");*/
throw fail(quote(s) + " expected, got " + quote(t()));
}
consume();
}
void parse_x(unstructure_Receiver out) {
consume(); // get first token
parse(out);
while (nempty(stack))
popLast(stack).run();
}
}
final Var v = new Var();
X x = new X();
x.parse_x(new unstructure_Receiver() {
void set(Object o) { v.set(o); }
});
unstructure_tokrefs = x.tokrefs.size();
return v.get();
}
static boolean unstructure_debug;
static SortedMap synchroTreeMap() {
return Collections.synchronizedSortedMap(new TreeMap());
}
public static boolean isSnippetID(String s) {
try {
parseSnippetID(s);
return true;
} catch (RuntimeException e) {
return false;
}
}
static Concept getConcept(long id) {
return mainConcepts.getConcept(id);
}
static A getConcept(Class cc, long id) {
return getConcept(mainConcepts, cc, id);
}
static A getConcept(Concepts concepts, Class cc, long id) {
Concept c = concepts.getConcept(id);
if (c == null) return null;
if (!isInstance(cc, c))
throw fail("Can't convert concept: " + getClassName(c) + " -> " + getClassName(cc) + " (" + id + ")");
return (A) c;
}
static Collection allConcepts() {
return mainConcepts.allConcepts();
}
static Collection allConcepts(Concepts concepts) {
return concepts.allConcepts();
}
static void nohupJavax(final String javaxargs) {
{ Thread _t_0 = new Thread() {
public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs); } catch (Throwable __e) { printStackTrace2(__e); } }
};
startThread(_t_0); }
}
static void nohupJavax(final String javaxargs, final String vmArgs) {
{ Thread _t_1 = new Thread() {
public void run() { try { call(hotwireOnce("#1008562"), "nohupJavax", javaxargs, vmArgs); } catch (Throwable __e) { printStackTrace2(__e); } }
};
startThread(_t_1); }
}
static List map(Iterable l, Object f) {
return map(f, l);
}
static List map(Object f, Iterable l) {
List x = emptyList(l);
for (Object o : unnull(l))
x.add(callF(f, o));
return x;
}
static List map(Object f, Object[] l) { return map(f, asList(l)); }
static List map(Object[] l, Object f) { return map(f, l); }
static List map(Object f, Map map) {
return map(map, f);
}
static List map(Map map, Object f) {
List x = new ArrayList();
for (Object _e : map.entrySet()) {
Map.Entry e = (Map.Entry) _e;
x.add(callF(f, e.getKey(), e.getValue()));
}
return x;
}
static Map cloneMap(Map map) {
if (map == null) return litmap();
// assume mutex is equal to collection
synchronized(map) {
return map instanceof TreeMap ? new TreeMap(map)
: map instanceof LinkedHashMap ? new LinkedHashMap(map)
: new HashMap(map);
}
}
static void set(Object o, String field, Object value) {
if (o instanceof Class) set((Class) o, field, value);
else try {
Field f = set_findField(o.getClass(), field);
smartSet(f, o, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static void set(Class c, String field, Object value) {
try {
Field f = set_findStaticField(c, field);
smartSet(f, null, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field set_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field set_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static String getDBProgramID_id;
static String getDBProgramID() {
return nempty(getDBProgramID_id) ? getDBProgramID_id : programID();
}
static int max(int a, int b) { return Math.max(a, b); }
static int max(int a, int b, int c) { return max(max(a, b), c); }
static long max(int a, long b) { return Math.max((long) a, b); }
static long max(long a, long b) { return Math.max(a, b); }
static double max(int a, double b) { return Math.max((double) a, b); }
static float max(float a, float b) { return Math.max(a, b); }
static double max(double a, double b) { return Math.max(a, b); }
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static short max(short[] c) {
short x = -0x8000;
for (short d : c) if (d > x) x = d;
return x;
}
static void change() {
//mainConcepts.allChanged();
// safe version for now cause function is sometimes included unnecessarily (e.g. by EGDiff)
callOpt(getOptMC("mainConcepts"), "allChanged");
}
// firstDelay = delay
static java.util.Timer doEvery_daemon(int delay, final Object r) {
return doEvery_daemon(delay, delay, r);
}
static java.util.Timer doEvery_daemon(int delay, int firstDelay, final Object r) {
final java.util.Timer timer = new java.util.Timer(true);
timer.scheduleAtFixedRate(smartTimerTask(r, timer, delay), firstDelay, delay);
return timer;
}
static Map findBot_cache = synchroHashMap();
static int findBot_timeout = 5000;
static DialogIO findBot(String searchPattern) {
// first split off sub-bot suffix
String subBot = null;
int i = searchPattern.indexOf('/');
if (i >= 0 && (isJavaIdentifier(searchPattern.substring(0, i)) || isInteger(searchPattern.substring(0, i)))) {
subBot = searchPattern.substring(i+1);
searchPattern = searchPattern.substring(0, i);
if (!isInteger(searchPattern))
searchPattern = "Multi-Port at " + searchPattern + ".";
}
// assume it's a port if it's an integer
if (isInteger(searchPattern))
return talkToSubBot(subBot, talkTo(parseInt(searchPattern)));
if (eq(searchPattern, "remote"))
return talkToSubBot(subBot, talkTo("second.tinybrain.de", 4999));
Integer port = findBot_cache.get(searchPattern);
if (port != null) try {
DialogIO io = talkTo("localhost", port);
io.waitForLine(/*findBot_timeout*/); // TODO: implement
String line = io.readLineNoBlock();
if (indexOfIgnoreCase(line, searchPattern) == 0) {
call(io, "pushback", line); // put hello string back in
return talkToSubBot(subBot, io);
}
} catch (Exception e) {
e.printStackTrace();
}
List bots = quickBotScan();
// find top-level bots
for (ProgramScan.Program p : bots) {
if (indexOfIgnoreCase(p.helloString, searchPattern) == 0) { // strict matching - start of hello string only, but case-insensitive
findBot_cache.put(searchPattern, p.port);
return talkToSubBot(subBot, talkTo("localhost", p.port));
}
}
// find sub-bots
for (ProgramScan.Program p : bots) {
String botName = firstPartOfHelloString(p.helloString);
boolean isVM = startsWithIgnoreCase(p.helloString, "This is a JavaX VM.");
boolean shouldRecurse = startsWithIgnoreCase(botName, "Multi-Port") || isVM;
if (shouldRecurse) try {
Map subBots = (Map) unstructure(sendToLocalBotQuietly(p.port, "list bots"));
for (Number vport : subBots.keySet()) {
String name = subBots.get(vport);
if (startsWithIgnoreCase(name, searchPattern))
return talkToSubBot(vport.longValue(), talkTo("localhost", p.port));
}
} catch (Throwable __e) { print(exceptionToStringShort(__e)); }
}
return null;
}
static String n(long l, String name) {
return l + " " + trim(l == 1 ? singular(name) : getPlural(name));
}
static String n(Collection l, String name) {
return n(l(l), name);
}
static String n(Map m, String name) {
return n(l(m), name);
}
static String n(Object[] a, String name) {
return n(l(a), name);
}
static boolean sameSnippetID(String a, String b) {
return a != null && b != null && parseSnippetID(a) == parseSnippetID(b);
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
throw fail(getClassName(o));
}
static float abs(float f) { return Math.abs(f); }
static int abs(int i) { return Math.abs(i); }
static double abs(double d) { return Math.abs(d); }
static Concept cnew(String name, Object... values) {
Class extends Concept> cc = findClass(name);
Concept c = cc != null ? nuObject(cc) : new Concept(name);
csetAll(c, values);
return c;
}
static Concept cnew(Concepts concepts, String name, Object... values) {
Class extends Concept> cc = findClass(name);
concepts_unlisted.set(true);
Concept c;
try {
c = cc != null ? nuObject(cc) : new Concept(name);
} finally {
concepts_unlisted.set(null);
}
concepts.register(c);
csetAll(c, values);
return c;
}
static A cnew(Class cc, Object... values) {
A c = nuObject(cc);
csetAll(c, values);
return c;
}
static A cnew(Concepts concepts, Class cc, Object... values) {
concepts_unlisted.set(true);
A c;
try {
c = nuObject(cc);
} finally {
concepts_unlisted.set(null);
}
concepts.register(c);
csetAll(c, values);
return c;
}
static String loadConceptsStructure(String progID) {
return loadTextFilePossiblyGZipped(getProgramFile(progID, "concepts.structure"));
}
static String loadConceptsStructure() {
return loadConceptsStructure(dbProgramID());
}
static long parseLong(String s) {
if (s == null) return 0;
return Long.parseLong(dropSuffix("L", s));
}
static long parseLong(Object s) {
return Long.parseLong((String) s);
}
static boolean equals(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
static boolean hasType(Collection c, Class type) {
for (Object x : c)
if (isInstanceX(type, x))
return true;
return false;
}
static List ll(A... a) {
return litlist(a);
}
static String formatInt(int i, int digits) {
return padLeft(str(i), '0', digits);
}
static boolean bareDBMode_on;
static void bareDBMode() {
bareDBMode(null); // default autoSaveInterval
}
static void bareDBMode(Integer autoSaveInterval) {
bareDBMode_on = true;
conceptsAndBot(autoSaveInterval);
}
static WeakHashMap> callOpt_noArgs_cache = new WeakHashMap();
static Object callOpt_noArgs(Object o, String method) { try {
if (o == null) return null;
if (o instanceof Class)
return callOpt(o, method); // not optimized
Class c = o.getClass();
HashMap map;
synchronized(callOpt_noArgs_cache) {
map = callOpt_noArgs_cache.get(c);
if (map == null)
map = callOpt_noArgs_makeCache(c);
}
Method m = map.get(method);
return m != null ? m.invoke(o) : null;
} catch (Exception __e) { throw rethrow(__e); } }
// used internally - we are in synchronized block
static HashMap callOpt_noArgs_makeCache(Class c) {
HashMap map = new HashMap();
Class _c = c;
do {
for (Method m : c.getDeclaredMethods())
if (m.getParameterTypes().length == 0) {
m.setAccessible(true);
String name = m.getName();
if (!map.containsKey(name))
map.put(name, m);
}
_c = _c.getSuperclass();
} while (_c != null);
callOpt_noArgs_cache.put(c, map);
return map;
}
static void cleanKillVM() {
ping();
cleanKillVM_noSleep();
sleep();
}
static void cleanKillVM_noSleep() {
call(getJavaX(), "cleanKill");
}
static List filterByType(Collection c, Class type) {
List l = new ArrayList();
for (Object x : c)
if (isInstanceX(type, x))
l.add((A) x);
return l;
}
static List filterByType(Object[] c, Class type) {
return filterByType(asList(c), type);
}
static int done_minPrint = 10;
static long done(long startTime, String desc) {
long time = now()-startTime;
if (time >= done_minPrint)
print(desc + " [" + time + " ms]");
return time;
}
static long done(String desc, long startTime) {
return done(startTime, desc);
}
static long done(long startTime) {
return done(startTime, "");
}
static String dbBotName(String progID) {
return fsI(progID) + " Concepts";
}
static boolean warn_on = true;
static void warn(String s) {
if (warn_on)
print("Warning: " + s);
}
static void warn(String s, List warnings) {
warn(s);
if (warnings != null)
warnings.add(s);
}
static long fileSize(String path) { return getFileSize(path); }
static long fileSize(File f) { return getFileSize(f); }
/** writes safely (to temp file, then rename) */
static File saveTextFile(String fileName, String contents) throws IOException {
CriticalAction action = beginCriticalAction("Saving file " + fileName + " (" + l(contents) + " chars)");
try {
File file = new File(fileName);
File parentFile = file.getParentFile();
if (parentFile != null)
parentFile.mkdirs();
String tempFileName = fileName + "_temp";
File tempFile = new File(tempFileName);
if (contents != null) {
if (tempFile.exists()) try {
String saveName = tempFileName + ".saved." + now();
copyFile(tempFile, new File(saveName));
} catch (Throwable e) { printStackTrace(e); }
FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath());
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
printWriter.print(contents);
printWriter.close();
}
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + fileName);
if (contents != null)
if (!tempFile.renameTo(file))
throw new IOException("Can't rename " + tempFile + " to " + file);
return file;
} finally {
action.done();
}
}
static File saveTextFile(File fileName, String contents) { try {
saveTextFile(fileName.getPath(), contents);
return fileName;
} catch (Exception __e) { throw rethrow(__e); } }
static A uniq(Class c, Object... params) {
return uniqueConcept(c, params);
}
static A uniq(Concepts cc, Class c, Object... params) {
return uniqueConcept(cc, c, params);
}
static void readLocally(String progID, String varNames) {
readLocally2(mc(), progID, varNames);
}
static void readLocally(String varNames) {
readLocally2(mc(), programID(), varNames);
}
static void readLocally2(Object obj, String varNames) {
readLocally2(obj, programID(), varNames);
}
static int readLocally_stringLength;
static ThreadLocal readLocally2_allDynamic = new ThreadLocal();
// read a string variable from standard storage
// does not overwrite variable contents if there is no file
static void readLocally2(Object obj, String progID, String varNames) { try {
boolean allDynamic = isTrue(getAndClearThreadLocal(readLocally2_allDynamic));
for (String variableName : javaTokC(varNames)) {
File textFile = new File(programDir(progID), variableName + ".text");
String value = loadTextFile(textFile);
if (value != null)
set(main.class, variableName, value);
else {
File structureFile = new File(programDir(progID), variableName + ".structure");
value = loadTextFile(structureFile);
if (value == null) {
File structureGZFile = new File(programDir(progID), variableName + ".structure.gz");
if (!structureGZFile.isFile()) return;
//value = loadGZTextFile(structureGZFile);
InputStream fis = new FileInputStream(structureGZFile);
try {
GZIPInputStream gis = new GZIPInputStream(fis);
InputStreamReader reader = new InputStreamReader(gis, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(reader);
//O o = unstructure_reader(bufferedReader);
Object o = unstructure_tok(javaTokC_noMLS_onReader(bufferedReader), allDynamic, null);
readLocally_set(obj, variableName, o);
} finally {
fis.close();
}
return;
}
readLocally_stringLength = l(value);
if (nempty(value))
readLocally_set(obj, variableName, allDynamic ? safeUnstructure(value) : unstructure(value));
}
}
} catch (Exception __e) { throw rethrow(__e); } }
static void readLocally_set(Object c, String varName, Object value) {
Object oldValue = get(c, varName);
if (oldValue instanceof List && !(oldValue instanceof ArrayList) && value != null) {
// Assume it's a synchroList.
value = synchroList((List) value);
}
set(c, varName, value);
}
static boolean hasConcept(Class extends Concept> c, Object... params) {
return findConceptWhere(c, params) != null;
}
static String javaTokWordWrap(String s) {
int cols = 120, col = 0;
List tok = javaTok(s);
for (int i = 0; i < l(tok); i++) {
String t = tok.get(i);
if (odd(i) && col >= cols && !containsNewLine(t))
tok.set(i, t += "\n");
int idx = t.lastIndexOf('\n');
if (idx >= 0) col = l(t)-(idx+1);
else col += l(t);
}
return join(tok);
}
static Object deref(Object o) {
if (o instanceof Derefable) o = ((Derefable) o).get();
return o;
}
static void saveGZStructureToFile(File file, Object o) { try {
File parentFile = file.getParentFile();
if (parentFile != null)
parentFile.mkdirs();
File tempFile = tempFileFor(file);
if (tempFile.exists()) try {
String saveName = tempFile.getPath() + ".saved." + now();
copyFile(tempFile, new File(saveName));
} catch (Throwable e) { printStackTrace(e); }
FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath());
GZIPOutputStream gos = new GZIPOutputStream(fileOutputStream);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(gos, "UTF-8");
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
structureToPrintWriter(o, printWriter);
printWriter.close();
gos.close();
fileOutputStream.close();
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + file.getPath());
if (!tempFile.renameTo(file))
throw new IOException("Can't rename " + tempFile + " to " + file);
} catch (Exception __e) { throw rethrow(__e); } }
static Collection values(Map map) {
return map == null ? emptyList() : map.values();
}
static Str concept(String name) {
for (Str s : list(Str.class))
if (eqic(s.name, name) || containsIgnoreCase(s.otherNames, name))
return s;
return new Str(name);
}
static void remove(List l, int i) {
if (l != null && i >= 0 && i < l(l))
l.remove(i);
}
static void remove(Collection l, A a) {
if (l != null) l.remove(a);
}
static String ymd() {
return year() + formatInt(month(), 2) + formatInt(dayOfMonth(), 2);
}
static Object load(String varName) {
readLocally(varName);
return get(mc(), varName);
}
static Object load(String progID, String varName) {
readLocally(progID, varName);
return get(mc(), varName);
}
static long now_virtualTime;
static long now() {
return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis();
}
static int countConcepts(Class c, Object... params) {
return mainConcepts.countConcepts(c, params);
}
static int countConcepts() {
return mainConcepts.countConcepts();
}
static int countConcepts(String className) {
return mainConcepts.countConcepts(className);
}
static int countConcepts(Concepts concepts, String className) {
return concepts.countConcepts(className);
}
static String shortClassName(Object o) {
if (o == null) return null;
Class c = o instanceof Class ? (Class) o : o.getClass();
String name = c.getName();
return shortenClassName(name);
}
static boolean checkConceptFields(Concept x, Object... data) {
for (int i = 0; i < l(data); i += 2)
if (neq(cget(x, (String) data[i]), deref(data[i+1])))
return false;
return true;
}
static File getProgramFile(String progID, String fileName) {
if (new File(fileName).isAbsolute())
return new File(fileName);
return new File(getProgramDir(progID), fileName);
}
static File getProgramFile(String fileName) {
return getProgramFile(getProgramID(), fileName);
}
static void saveLocally(String variableName) {
saveLocally(programID(), variableName);
}
static void saveLocally(String progID, String variableName) {
saveLocally2(mc(), progID, variableName);
}
static void saveLocally2(Object obj, String variableName) {
saveLocally2(obj, programID(), variableName);
}
static void saveLocally2(Object obj, String progID, String variableName) {
Lock _lock_1288 = saveLock(); lock(_lock_1288); try {
File textFile = new File(programDir(progID), variableName + ".text");
File structureFile = new File(programDir(progID), variableName + ".structure");
Object x = get(obj, variableName);
if (x == null) {
textFile.delete();
structureFile.delete();
} else if (x instanceof String) {
saveTextFile(textFile, (String) x);
structureFile.delete();
} else {
saveTextFile(structureFile, javaTokWordWrap(structure(x)));
textFile.delete();
}
} finally { _lock_1288.unlock(); } }
static int hours() {
return hours(Calendar.getInstance());
}
static int hours(Calendar c) {
return c.get(Calendar.HOUR_OF_DAY);
}
static Lock dbLock() {
return mainConcepts.lock;
}
static Object rpc(String botName, String method, Object... args) {
return unstructure_debug(matchOK2OrFail(
sendToLocalBot(botName, rpc_makeCall(method, args))));
}
static Object rpc(DialogIO bot, String method, Object... args) {
return unstructure_debug(matchOK2OrFail(
bot.ask(rpc_makeCall(method, args))));
}
static String rpc_makeCall(String method, Object... args) {
if (empty(args))
return "call " + method;
return format("call *", concatLists((List) ll(method), asList(args)));
}
static boolean structure_showTiming, structure_checkTokenCount;
static String structure(Object o) {
return structure(o, new structure_Data());
}
static String structure(Object o, structure_Data d) {
StringWriter sw = new StringWriter();
d.out = new PrintWriter(sw);
structure_go(o, d);
String s = str(sw);
if (structure_checkTokenCount) {
print("token count=" + d.n);
assertEquals("token count", l(javaTokC(s)), d.n);
}
return s;
}
static void structure_go(Object o, structure_Data d) {
structure_1(o, d);
while (nempty(d.stack))
popLast(d.stack).run();
}
static void structureToPrintWriter(Object o, PrintWriter out) {
structure_Data d = new structure_Data();
d.out = out;
structure_go(o, d);
}
// leave to false, unless unstructure() breaks
static boolean structure_allowShortening = false;
static class structure_Data {
PrintWriter out;
int stringSizeLimit;
int shareStringsLongerThan = 20;
boolean noStringSharing;
IdentityHashMap