* base relationship * synthesized relationship * relation "names" should be nodes as well * just triples? (x, R, y) TextField = function(contents) { this.contents = contents this.letters = [] } TextField.prototype.width = 30 TextField.prototype.letterAt = function(idx) { return (idx < 0 || idx >= this.contents.size) ? null : this.letters[idx] } Letter = function(tf, idx) { this.tf = tf; this.idx = idx } Letter.prototype.successor = function() { this.succ == undefined ? this.succ = this.tf.letterAt(idx + 1) : this.succ } Letter.prototype.predecessor = function() { this.pred == undefined ? this.pred = this.tf.letterAt(idx - 1) : this.pred } Letter.prototype.toString = function() { return "Letter(..." + this.predecessor().letter + "<" + this.letter() + ">" + this.successor.letter() + "...)" } TextField.prototype.classifyContents = function() { for (var idx = 0; idx < this.contents.length; idx++) this.letters[idx] = new Letter(this, idx) } TextField.prototype.print = function() { for (var idx = 0; idx < this.contents.length; idx++) Transcript.show(this.letterAt(idx)) } tf = new TextField("this is a test") tf.classifyContents() tf.print() Character.newId = (function() { return function() { return id++ } })() Character = function(tf, c) { this.tf = tf; this.theCharacter = c } Character.prototype.width = function() { return 1 } Word = function(tf) { this.tf = tf; this.first = null; this.last = null } Word.prototype.width = function() { var c = this.first, w = 0 while (true) { w = w + 1 if (c == this.last) return w c = this.tf.successor(c) } } TextField.prototype.reclassify = function() { tf }