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

196
LINES

< > BotCompany Repo | #1005173 // Rule Matching Test [dev.]

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

Libraryless. Click here for Pure Java version (2068L/14K/46K).

1  
!752
2  
3  
static L<S> data = toLinesFullTrim([[
4  
  If A likes B then A will greet B.
5  
  If X then Y.
6  
  If U then V. && U. => V.
7  
  John likes Paul.
8  
]]);
9  
10  
static L<L<S>> log;
11  
12  
static S toCheck = "John will greet Paul.";
13  
14  
sclass Flow {
15  
  new StringBuilder desc;
16  
  new L<Flow> subs;
17  
  
18  
  Flow sub(S desc) {
19  
    new Flow flow;
20  
    flow.append(desc);
21  
    subs.add(flow);
22  
    ret flow;
23  
  }
24  
  
25  
  void append(O o) {
26  
    desc.append(o).append("\n");
27  
  }
28  
  
29  
  void x(O o) { append(o); }
30  
  
31  
  public S toString() {
32  
    ret str(desc) + indentx(allToStringWithLineBreaks(subs));
33  
  }
34  
}
35  
36  
p-typewriter {
37  
  // Parse data
38  
  log = map("tok", data);
39  
  
40  
  new TreeSet<S> newData;
41  
  
42  
  // Go through all rules
43  
  new Flow flow;
44  
  for (L<S> tok : log) {
45  
    SS m = matchSingle("I => O", tok);
46  
    if (m == null) continue;
47  
    S i = m.get("I"), o = m.get("O");
48  
    // Parse left-hand
49  
    L<S> tokI = tok(i);
50  
    L<L<S>> is = splitAtAmpersands(tokI);
51  
    flow.x("Processing LHS: " + struct(is));
52  
    // Apply rule to input
53  
    for (SS m2 : gSatAnd(is, flow))
54  
      newData.add(join(" ", replaceVars(tok(o), m2)));
55  
  }
56  
  
57  
  print("Lines made (\*l(newData)*/):");
58  
  psl(asList(newData));
59  
  printWithAsciiHeading("FLOW", flow);
60  
}
61  
62  
// null = no satisfaction
63  
// otherwise return var map
64  
static Iterable<SS> gSatAnd(L<L<S>> statements, Flow flow) {
65  
  flow = flow.sub("gSatAnd" + struct(statements));
66  
  assertTrue(l(statements) >= 1);
67  
  
68  
  if (l(statements) == 1)
69  
    ret gSat(first(statements), flow);
70  
  
71  
  new L<SS> l;
72  
  for (SS map : gSat(first(statements), flow)) {
73  
    flow.x("First clause satisfied. " + struct(map));
74  
    L<L<S>> s2 = mapReplaceVars(dropFirst(statements), map);
75  
    flow.x("Now looking for: " + struct(s2));
76  
    for (SS map2 : gSatAnd(s2, flow)) {
77  
      flow.x("Sub gSatAnd returned: " + struct(map2));
78  
      addIfNotEmpty(l, mergeMappings(map, map2));
79  
    }
80  
  }
81  
  ret l;
82  
}
83  
84  
static IterableIterator<SS> gSat(L<S> pat, Flow flow) {
85  
  flow = flow.sub("gSat" + struct(pat));
86  
  ret gMatch(pat, flow);
87  
}
88  
89  
static IterableIterator<SS> gMatch(final L<S> pat, final Flow flow) {
90  
  ret new IterableIterator<SS>() {
91  
    int i = l(log);
92  
    Iterator<SS> m;
93  
    
94  
    public bool hasNext() {
95  
      if (m != null && m.hasNext()) true;
96  
      m = null;
97  
      while (--i >= 0) {
98  
        L<SS> l = match(pat, get(log, i));
99  
        if (nempty(l)) {
100  
          flow.x("gMatch found: " + struct(l));
101  
          m = l.iterator();
102  
          true;
103  
        }
104  
      }
105  
      false;
106  
    }
107  
    
108  
    public SS next() { ret m.next(); }
109  
  };
110  
}
111  
112  
static L<L<S>> splitAtAmpersands(L<S> tok) {
113  
  new L<L<S>> l;
114  
  int iAmp;
115  
  while ((iAmp = indexOfSubList(tok, ll("&", "&"))) >= 0) {
116  
    //print("&& found at " + iAmp);
117  
    l.add(subList(tok, 0, iAmp));
118  
    tok = subList(tok, iAmp+2);
119  
  }
120  
  l.add(tok);
121  
  ret l;
122  
}
123  
124  
static SS matchSingle(S pat, L<S> input) {
125  
  ret getSingletonOpt(match(tok(pat), input));
126  
}
127  
128  
static SS matchSingle(S pat, S input) {
129  
  ret getSingletonOpt(match(pat, input));
130  
}
131  
132  
static L<S> tok(S s) {
133  
  ret s == null ? null : codeTokens(nlTok(s));
134  
}
135  
136  
static L<SS> match(S pat, S input) {
137  
  ret match(tok(pat), tok(input));
138  
}
139  
140  
static L<SS> match(L<S> pat, L<S> input) {
141  
  Map<Int, S> vars = singleCharacterVars(pat);
142  
  new L<SS> matches;
143  
  matchImpl(pat, vars, 0, input, 0, new HashMap, matches);
144  
  ret matches;
145  
}
146  
147  
static void matchImpl(L<S> pat, Map<Int, S> vars,
148  
  int iPat, L<S> input, int iInput, SS values,
149  
  L<SS> matches) {
150  
  if (iPat >= l(pat)) {
151  
    if (iInput < l(input)) ret; // fail, too much input
152  
    //print("Match! " + struct(values));
153  
    matches.add(cloneMap(values));
154  
    ret;
155  
  }
156  
  if (iInput >= l(input)) ret; // out of input
157  
  S t = pat.get(iPat);
158  
  S var = vars.get(iPat);
159  
  if (var != null) {
160  
    // it's a variable, try different lengths of input as match
161  
    for (int jInput = iInput+1; jInput <= l(input); jInput++) {
162  
      S value = join(" ", subList(input, iInput, jInput));
163  
      S oldValue = values.get(var);
164  
      if (oldValue != null && !eqic(value, oldValue)) ret; // fail, bad multi-assignment
165  
      if (oldValue == null)
166  
        values.put(var, value);
167  
      // proceed
168  
      matchImpl(pat, vars, iPat+1, input, jInput, values, matches);
169  
      // delete assignment
170  
      if (oldValue == null) values.remove(var); else values.put(var, oldValue);
171  
    }
172  
  } else {
173  
    // it's a literal
174  
    if (!eqic(t, input.get(iInput))) ret; // fail
175  
    // match, proceed
176  
    matchImpl(pat, vars, iPat+1, input, iInput+1, values, matches);
177  
  }
178  
}
179  
180  
static Map<Int, S> singleCharacterVars(L<S> tok) {
181  
  new Map<Int, S> vars;
182  
  for i over tok: {
183  
    S t = tok.get(i);
184  
    if (l(t) == 1 && isUpperCaseLetter(t.charAt(0)))
185  
      vars.put(i, t);
186  
  }
187  
  ret vars;
188  
}
189  
190  
static L<L<S>> mapReplaceVars(L<L<S>> patterns, final SS map) {
191  
  ret map(func(L<S> pat) { replaceVars(pat, map) }, patterns);
192  
}
193  
194  
static L<S> replaceVars(L<S> tok, final Map<S, S> map) {
195  
  ret flattenList(map(tok, func(S t) { or((O) tok(map.get(t)), t) }));
196  
}

Author comment

Began life as a copy of #1005169

download  show line numbers  debug dex  old transpilations   

Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1005173
Snippet name: Rule Matching Test [dev.]
Eternal ID of this version: #1005173/1
Text MD5: f9b0375363a7b51dfc00af59a4429c45
Transpilation MD5: 4c5d2caab5b5bb4337a2cc3d9c6b8742
Author: stefan
Category: javax / a.i.
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-11-20 17:23:37
Source code size: 5090 bytes / 196 lines
Pitched / IR pitched: No / No
Views / Downloads: 690 / 711
Referenced in: [show references]