!7 sS text = [[ One node "A". One node "B". B to the right of A. ]]; static new TreeSet nodes; static new LinkedHashSet relations; static new LinkedHashSet maybes; static new TreeMap coordinates; static Canvas canvas; static JCheckBox cbMaybe; p-subst { doIt(); } svoid doIt { clearAll(nodes, relations, maybes, coordinates); for (S s : sentences(text)) { new Matches m; if "One node *" nodes.add($1); else if "* to the right of *" relations.add(new Relation("to the right of", $1, $2)); } print("Got nodes: " + sfu(nodes)); print("Got relations: " + sfu(relations)); makeCoordinates(); print("Got coordinates: " + sfu(coordinates)); canvas = showCAL(makeCAL(), canvas); swing { addToFrame(canvas, jcenteredline( cbMaybe = onChange(jcheckbox(cbMaybe, "Alternate interpretation"), f doIt), jbutton("Again", f doIt))); } } svoid makeCoordinates { for (S node : nodes) coordinates.put(node, pt(random(100), random(100))); processRules(); if (isChecked(cbMaybe)) { migrateList(maybes, relations); processRules(); } } svoid processRules { for (Relation r : cloneList(relations)) { if (r.is("to the right of")) { maybes.add(Relation("on the same height as", r.a(), r.b())); Pt pa = coordinates.get(r.a()), pb = coordinates.get(r.b()); if (pa != null && pb != null) pa.x = max(pa.x, pb.x+10); } if (r.is("on the same height as")) { Pt pa = coordinates.get(r.a()), pb = coordinates.get(r.b()); if (pa != null && pb != null) pa.y = pb.y; } } } static CirclesAndLines makeCAL() { Rect r = mergeRects(map(f ptToRect, values(coordinates))); BufferedImage img = newBufferedImage(20, 20, Color.white); new CirclesAndLines cal; for (S node : keys(coordinates)) { Pt p = coordinates.get(node); double x = ((p.x-r.x)/(double) r.w)*0.8+0.1; double y = ((p.y-r.y)/(double) r.h)*0.7+0.1; cal.circle(img, x, y, node); } ret cal; }