Download Jar. Uses 3874K of libraries. Click here for Pure Java version (10167L/74K).
!7 static Map<S, Set<S>> theSet; static new LinkedHashSet<Updatable> allObjects; static long changes; static new MultiMap<S, Pair<S>> groupingsByA; static new MultiMap<S> subClasses; static S groupings = [[ <preposition> + <noun> = <adverbial_phrase> <determiner> + <noun> = <noun> <adverb> + <verb_phrase> = <verb_phrase> <verb> = <verb_phrase> <verb> + <noun> = <verb_phrase> <noun> + <verb_phrase> = <sentence> <adverbial_phrase> + <sentence> = <sentence> ]]; sclass Updatable { void update {} void setField(S field, O value) { if (eq(get(this, field), value)) ret; set(this, field, value); change(); } } sclass Expectation { S ifClass; Runnable action; *() {} *(S *ifClass, Runnable *action) {} } sclass Word extends Updatable { S text; // or null if unknown new LinkedHashSet<Word> prev; new LinkedHashSet<Word> next; L<Word> constituents; // if group new L<Expectation> expectations; new L<Expectation> fulfilledExpectations; new TreeSet<S> classes; int classesConvertedToTraits; new LinkedHashSet<Word> groups; // I am part of new L<Trait> traits; void update { // Add direct word classes if (text != null) for (S c : reverseLookupInMapToSets(theSet, text)) addClass(c); // Make text for group if (isGroup() && text == null) { L<S> l = collect(constituents, 'text); if (!anyNull(l)) setField(text := joinWithSpace(l)); } // Process expectations for (Expectation e : cloneList(expectations)) { //print("Checking expected class " + e.ifClass); if (classes.contains(e.ifClass)) { moveElementFromCollectionToCollection(e, expectations, fulfilledExpectations); change(); callF(e.action); } } if (l(classes) > classesConvertedToTraits) { for (fS c : dropFirst(classesConvertedToTraits, classes)) addTraitsForClass(c); classesConvertedToTraits = l(classes); } for (Trait t : iterateListConcurrently(traits)) t.update(); } bool isGroup() { ret constituents != null; } bool addClass(S c) { if (!classes.add(c)) false; change(); long n; do { n = changes; // optimizable for (S d : iterateListConcurrently(asList(classes))) for (S e : subClasses.get(d)) if (classes.add(e)) change(); } while (changes != n); true; } void addExpectation(Expectation e) { //print("addExpectation " + e); expectations.add(e); change(); } void addTraitsForClass(S c) { for (PairS p : groupingsByA.get(c)) addTrait(LinkWithTo(p.a, p.b)); } void addTrait(Trait t) { set(t, w := this); traits.add(t); } } static Word makeGroup(Word a, Word b, S newClass) { //print("makeGroup " + a.text + " / " + b.text); L<Word> list = ll(a, b); // look for existing group for (Word g : a.groups) if (eq(g.constituents, list)) { if (g.addClass(newClass)) print("Added class " + newClass + " to existing group: " + a.text + " + " + b.text); ret g; } // new group print("Making group " + newClass + " " + a.text + " + " + b.text); print(" prev=" + sfu(collect(a.prev, 'text))); print(" next=" + sfu(collect(b.next, 'text))); new Word g; allObjects.add(g); g.addClass(newClass); g.constituents = list; for (Word w : list) w.groups.add(g); g.prev.addAll(a.prev); g.next.addAll(b.next); for (Word prev : a.prev) prev.next.add(g); for (Word next : b.next) next.prev.add(g); ret g; } sclass Trait extends Updatable { Word w; } sclass LinkWithTo extends Trait { S linkWith, linkTo; // classes int expectationsSentToNext; *() {} *(S *linkWith, S *linkTo) {} void update { if (l(w.next) > expectationsSentToNext) { for (final Word next : dropFirst(expectationsSentToNext, w.next)) next.addExpectation(Expectation(linkWith, r { makeGroup(w, next, linkTo) })); expectationsSentToNext = l(w.next); } } } p-exp { fS sentence = "In the movies Dracula always wears a cape"; L<S> rawWords = printStruct(words(sentence)); theSet = ai_englishWordCategoriesWithElements(); parseGroupings(); new L<Word> words; for (S w : rawWords) words.add(nu(Word, text := w)); for (int i = 0; i < l(words)-1; i++) linkWords(words.get(i), words.get(i+1)); //printStruct(first(words)); addAll(allObjects, words); long lastChanges; do { lastChanges = changes; print(n2(changes, "change")); for (Updatable w : cloneList(allObjects)) w.update(); } while (lastChanges != changes); //for (Word w : words) printStruct(cloneForPrinting(w)); for (Word w : words) print(" " + textAndClasses(w)); print(); L<Word> groups = [Word w : instancesOf(Word, allObjects) | w.constituents != null]; print(); print(n2(groups, "group")); for (Word g : groups) { print("Group: " + textAndClasses(g)); print(" " + grouped(g)); } assertNempty([Word g : groups | eq(g.text, sentence) && g.classes.contains("<sentence>")]); print("OK"); } sS textAndClasses(Word w) { ret w.text + " (" + joinWithComma(w.classes) + ")"; } svoid linkWords(Word a, Word b) { a.next.add(b); b.prev.add(a); } static O cloneForPrinting(Word w) { ret cloneWithoutFields(w, 'prev, 'next, 'constituents); } svoid change() { ++changes; } svoid parseGroupings() { for (S s : tlft(groupings)) { L<S> tok = javaTokWithAngleBracketsC(s); if (l(tok) == 5) groupingsByA.put(tok.get(0), pair(tok.get(2), tok.get(4))); else if (l(tok) == 3) subClasses.put(tok.get(0), tok.get(2)); } } sS grouped(Word g) { if (g.constituents == null) ret g.text; new L<S> l; for (Word w : g.constituents) l.add(curlyBraceIfMultipleTokens(grouped(w))); ret joinWithSpace(l); }
Began life as a copy of #1017342
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1017348 |
Snippet name: | Intelligent Words v2 [OK] |
Eternal ID of this version: | #1017348/31 |
Text MD5: | 20445a528c7a8441f8ccf94577551323 |
Transpilation MD5: | 86ab5c8f51f0b96387f956ce84d3daa1 |
Author: | stefan |
Category: | javax / a.i. |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-07-17 23:16:03 |
Source code size: | 6119 bytes / 235 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 430 / 1205 |
Version history: | 30 change(s) |
Referenced in: | #1017351 - AI_BottomUpParser1 #1017353 - Test AI_BottomUpParser1 (OK) |