Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

235
LINES

< > BotCompany Repo | #1017348 // Intelligent Words v2 [OK]

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar

Download Jar. Uses 3874K of libraries. Click here for Pure Java version (10167L/74K).

1  
!7
2  
3  
static Map<S, Set<S>> theSet;
4  
static new LinkedHashSet<Updatable> allObjects;
5  
static long changes;
6  
static new MultiMap<S, Pair<S>> groupingsByA;
7  
static new MultiMap<S> subClasses;
8  
9  
static S groupings = [[
10  
  <preposition> + <noun> = <adverbial_phrase>
11  
  <determiner> + <noun> = <noun>
12  
  <adverb> + <verb_phrase> = <verb_phrase>
13  
  <verb> = <verb_phrase>
14  
  <verb> + <noun> = <verb_phrase>
15  
  <noun> + <verb_phrase> = <sentence>
16  
  <adverbial_phrase> + <sentence> = <sentence>
17  
]];
18  
19  
sclass Updatable {
20  
  void update {}
21  
  
22  
  void setField(S field, O value) {
23  
    if (eq(get(this, field), value)) ret;
24  
    set(this, field, value);
25  
    change();
26  
  }
27  
}
28  
29  
sclass Expectation {
30  
  S ifClass;
31  
  Runnable action;
32  
  
33  
  *() {}
34  
  *(S *ifClass, Runnable *action) {}
35  
}
36  
37  
sclass Word extends Updatable {
38  
  S text; // or null if unknown
39  
  new LinkedHashSet<Word> prev;
40  
  new LinkedHashSet<Word> next;
41  
  L<Word> constituents; // if group
42  
  new L<Expectation> expectations;
43  
  new L<Expectation> fulfilledExpectations;
44  
  new TreeSet<S> classes;
45  
  int classesConvertedToTraits;
46  
  new LinkedHashSet<Word> groups; // I am part of
47  
  new L<Trait> traits;
48  
  
49  
  void update {
50  
    // Add direct word classes
51  
    if (text != null)
52  
      for (S c : reverseLookupInMapToSets(theSet, text))
53  
        addClass(c);
54  
    
55  
    // Make text for group  
56  
    if (isGroup() && text == null) {
57  
      L<S> l = collect(constituents, 'text);
58  
      if (!anyNull(l)) setField(text := joinWithSpace(l));
59  
    }
60  
    
61  
    // Process expectations
62  
    for (Expectation e : cloneList(expectations)) {
63  
      //print("Checking expected class " + e.ifClass);
64  
      if (classes.contains(e.ifClass)) {
65  
        moveElementFromCollectionToCollection(e, expectations, fulfilledExpectations);
66  
        change();
67  
        callF(e.action);
68  
      }
69  
    }
70  
    
71  
    if (l(classes) > classesConvertedToTraits) {
72  
      for (fS c : dropFirst(classesConvertedToTraits, classes))
73  
        addTraitsForClass(c);
74  
      classesConvertedToTraits = l(classes);
75  
    }
76  
    
77  
    for (Trait t : iterateListConcurrently(traits))
78  
      t.update();
79  
  }
80  
  
81  
  bool isGroup() { ret constituents != null; }
82  
  
83  
  bool addClass(S c) {
84  
    if (!classes.add(c)) false;
85  
    change();
86  
    long n;
87  
    do {
88  
      n = changes;
89  
      // optimizable
90  
      for (S d : iterateListConcurrently(asList(classes)))
91  
        for (S e : subClasses.get(d))
92  
          if (classes.add(e)) change();
93  
    } while (changes != n);
94  
    true;
95  
  }
96  
  
97  
  void addExpectation(Expectation e) {
98  
    //print("addExpectation " + e);
99  
    expectations.add(e);
100  
    change();
101  
  }
102  
  
103  
  void addTraitsForClass(S c) {
104  
    for (PairS p : groupingsByA.get(c))
105  
      addTrait(LinkWithTo(p.a, p.b));
106  
  }
107  
  
108  
  void addTrait(Trait t) {
109  
    set(t, w := this);
110  
    traits.add(t);
111  
  }
112  
}
113  
114  
static Word makeGroup(Word a, Word b, S newClass) {
115  
  //print("makeGroup " + a.text + " / " + b.text);
116  
  L<Word> list = ll(a, b);
117  
  
118  
  // look for existing group
119  
  for (Word g : a.groups)
120  
    if (eq(g.constituents, list)) {
121  
      if (g.addClass(newClass))
122  
        print("Added class " + newClass + " to existing group: " + a.text + " + " + b.text);
123  
      ret g;
124  
    }
125  
      
126  
  // new group
127  
  print("Making group " + newClass + " " + a.text + " + " + b.text);
128  
  print("  prev=" + sfu(collect(a.prev, 'text)));
129  
  print("  next=" + sfu(collect(b.next, 'text)));
130  
  new Word g;
131  
  allObjects.add(g);
132  
  g.addClass(newClass);
133  
  g.constituents = list;
134  
  for (Word w : list)
135  
    w.groups.add(g);
136  
  g.prev.addAll(a.prev);
137  
  g.next.addAll(b.next);
138  
  for (Word prev : a.prev) prev.next.add(g);
139  
  for (Word next : b.next) next.prev.add(g);
140  
  ret g;
141  
}
142  
143  
sclass Trait extends Updatable {
144  
  Word w;
145  
}
146  
147  
sclass LinkWithTo extends Trait {
148  
  S linkWith, linkTo; // classes
149  
  int expectationsSentToNext;
150  
  
151  
  *() {}
152  
  *(S *linkWith, S *linkTo) {}
153  
  
154  
  void update {
155  
    if (l(w.next) > expectationsSentToNext) {
156  
      for (final Word next : dropFirst(expectationsSentToNext, w.next))
157  
        next.addExpectation(Expectation(linkWith, r {
158  
          makeGroup(w, next, linkTo)
159  
        }));
160  
      expectationsSentToNext = l(w.next);
161  
    }
162  
  }
163  
}
164  
165  
p-exp {
166  
  fS sentence = "In the movies Dracula always wears a cape";
167  
  L<S> rawWords = printStruct(words(sentence));
168  
  
169  
  theSet = ai_englishWordCategoriesWithElements();
170  
  parseGroupings();
171  
  
172  
  new L<Word> words;
173  
  for (S w : rawWords)
174  
    words.add(nu(Word, text := w));
175  
  for (int i = 0; i < l(words)-1; i++)
176  
    linkWords(words.get(i), words.get(i+1));
177  
  //printStruct(first(words));
178  
  
179  
  addAll(allObjects, words);
180  
  long lastChanges;
181  
  do {
182  
    lastChanges = changes;
183  
    print(n2(changes, "change"));
184  
    for (Updatable w : cloneList(allObjects))
185  
      w.update();
186  
  } while (lastChanges != changes);
187  
  
188  
  //for (Word w : words) printStruct(cloneForPrinting(w));
189  
  for (Word w : words) print("  " + textAndClasses(w));
190  
  print();
191  
    
192  
  L<Word> groups = [Word w : instancesOf(Word, allObjects) | w.constituents != null];
193  
  print();
194  
  print(n2(groups, "group"));
195  
  for (Word g : groups) {
196  
    print("Group: " + textAndClasses(g));
197  
    print("  " + grouped(g));
198  
  }
199  
    
200  
  assertNempty([Word g : groups | eq(g.text, sentence) && g.classes.contains("<sentence>")]);
201  
  print("OK");
202  
}
203  
204  
sS textAndClasses(Word w) {
205  
  ret w.text + " (" + joinWithComma(w.classes) + ")";
206  
}
207  
208  
svoid linkWords(Word a, Word b) {
209  
  a.next.add(b);
210  
  b.prev.add(a);
211  
}
212  
213  
static O cloneForPrinting(Word w) {
214  
  ret cloneWithoutFields(w, 'prev, 'next, 'constituents);
215  
}
216  
217  
svoid change() { ++changes; }
218  
219  
svoid parseGroupings() {
220  
  for (S s : tlft(groupings)) {
221  
    L<S> tok = javaTokWithAngleBracketsC(s);
222  
    if (l(tok) == 5)
223  
      groupingsByA.put(tok.get(0), pair(tok.get(2), tok.get(4)));
224  
    else if (l(tok) == 3)
225  
      subClasses.put(tok.get(0), tok.get(2));
226  
  }
227  
}
228  
229  
sS grouped(Word g) {
230  
  if (g.constituents == null) ret g.text;
231  
  new L<S> l;
232  
  for (Word w : g.constituents)
233  
    l.add(curlyBraceIfMultipleTokens(grouped(w)));
234  
  ret joinWithSpace(l);
235  
}

Author comment

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: 431 / 1208
Version history: 30 change(s)
Referenced in: [show references]