1 | sclass RuleEngine { |
2 | new LL<S> facts; // stores code token parses |
3 | Map<S, O> phrasesWordTree = wordTree(); |
4 | Clusters<S> clusters = ciClusters(); |
5 | new Prolog prolog; |
6 | |
7 | *(S program) { |
8 | this("", program); |
9 | } |
10 | |
11 | *(S program, bool showStuff) { |
12 | if (showStuff) showStuff(); |
13 | runProgram(program); |
14 | } |
15 | |
16 | *(S inspiration, S program) { |
17 | runProgram(inspiration, program); |
18 | } |
19 | |
20 | void runProgram(S program) { |
21 | runProgram("", program); |
22 | } |
23 | |
24 | void runProgram(S inspiration, S program) { |
25 | for (S s : tlftj(inspiration)) |
26 | addFact("inspired " + quote(s)); |
27 | |
28 | L<S> programLines = tlftj(program); |
29 | //pnl(program); |
30 | //print(); |
31 | |
32 | for (S s : programLines) { |
33 | Pair<S, L<S>> p = parseFunctionCall(s); |
34 | if (p != null) { |
35 | //print("Function call: " + sfu(p)); |
36 | S f = p.a; |
37 | L<S> args = p.b; |
38 | if (eqic(f, "assert")) |
39 | assertFact(getSingleton(p.b)); |
40 | else if (swic(f, "assert_")) { |
41 | if (eqic(f, "assert_answer")) |
42 | assertAnswer(unquote(first(args)), unquote(second(args))); |
43 | else if (eqic(f, "assert_parse")) |
44 | assertParse(args); |
45 | else |
46 | fail("Unknown assertion function: " + f); |
47 | } else if (eqic(f, "fact_question_answer_upperCaseVars")) |
48 | prolog.code( |
49 | dontPrint("if [" + toProlog(unquote(first(args))) + "] and [" |
50 | + toProlog(unquote(second(args))) + "] then [answer is [" |
51 | + toProlog(unquote(third(args))) + "]]")); |
52 | continue; |
53 | } |
54 | |
55 | L<S> tok = javaTok(s); |
56 | if (eqic(second(tok), "assert")) { |
57 | assertFact(join(dropFirst(3, tok))); |
58 | continue; |
59 | } |
60 | |
61 | int i = indexOfSubListLL(tok, "-", "", ">"); |
62 | if (i >= 0) { |
63 | L<S> left = subList(tok, 1, i-1); |
64 | int j = indexOf(left, "+"); |
65 | if (j >= 0) { |
66 | prolog.code( |
67 | print("if [" + toProlog(joinSubList(left, 0, j-1)) |
68 | + "] and [" + toProlog(joinSubList(left, j+2)) + "] then [" |
69 | + toProlog(joinSubList(tok, i+4)) + "]")); |
70 | continue; |
71 | } |
72 | } |
73 | |
74 | tok = codeTokens(tok); |
75 | |
76 | if (eqic(getSingletonOpt(tok), "rewrite")) |
77 | continue with addFactsFromProlog(prolog.rewriteAndSave()); |
78 | |
79 | if (l(tok) == 2 && isIdentifier(first(tok)) && isQuoted(second(tok))) |
80 | if (eq(first(tok), "phrase")) { |
81 | addPhrase(unquote(second(tok))); |
82 | continue; |
83 | } |
84 | |
85 | if (l(tok) == 3 && eq(second(tok), "=")) { |
86 | ciClusters_add(clusters, |
87 | addPhrase(unquote(first(tok))), |
88 | addPhrase(unquote(third(tok)))); |
89 | continue; |
90 | } |
91 | |
92 | addFact(s); |
93 | } |
94 | } |
95 | |
96 | void printStuff { |
97 | printAsciiHeading("Facts"); |
98 | pnlStruct(facts); |
99 | print(); |
100 | |
101 | print("Clusters: " + sfu(clusters)); |
102 | print("Phrases: " + sfu(phrasesWordTree)); |
103 | } |
104 | |
105 | L<S> parseFact(S s) { |
106 | L<S> tok = map toLowerIfIdentifier(javaTokWithAngleBracketsC(/*dropPunctuation*/(s))); |
107 | ret nempties(translateUsingWordTreeC(tok, phrasesWordTree)); |
108 | } |
109 | |
110 | void assertFact(S fact) { |
111 | if (contains(facts, parseFact(fact))) |
112 | print("OK fact: " + fact); |
113 | else |
114 | print("FAILED fact assert: " + fact); |
115 | } |
116 | |
117 | void assertAnswer(S q, S a) { |
118 | Prolog p = new(prolog); |
119 | //p.showStuff = true; |
120 | p.code(dontPrint("to prolog: ", squareBracket(toProlog(q)))); |
121 | L<Lisp> out = p.rewrite(); |
122 | //print("Got " + l(out) + " statement(s)"); |
123 | L<S> lines = map nlUnparse(out); |
124 | L<S> answers = startingWithEndingWith_drop(lines, "answer is [", "]"); |
125 | if (l(answers) == 1 && eqic(first(answers), a)) |
126 | print("OK answer: " + q + " -> " + a); |
127 | else { |
128 | pnl(map nlUnparse(out)); |
129 | print("FAIL answer: " + q + " -> " + first(answers) + " - expected: " + a); |
130 | } |
131 | } |
132 | |
133 | S addPhrase(S s) { |
134 | wordTreeAdd(phrasesWordTree, javaTokC(s), s); |
135 | ret s; |
136 | } |
137 | |
138 | void addFact(S s) { |
139 | L<S> tok = parseFact(s); |
140 | facts.add(tok); |
141 | prolog.code(dontPrint("to prolog: ", squareBracket(factToProlog(tok)))); |
142 | } |
143 | |
144 | void assertParse(L<S> args) { |
145 | args = unquoteAll(args); |
146 | S s = first(args); |
147 | L<S> parsed = parseFact(s); |
148 | L<S> expected = dropFirst(args); |
149 | if (eq(parsed, expected)) |
150 | print("OK parse: " + s + " -> " + sfu(parsed)); |
151 | else |
152 | print("FAILED parse: " + s + " -> " + sfu(parsed) + " - expected: " + sfu(expected)); |
153 | } |
154 | |
155 | S toProlog(S s) { |
156 | L<S> tok = parseFact(upperCaseVarsToDollarVars(s)); |
157 | ret factToProlog(tok); |
158 | } |
159 | |
160 | S factToProlog(L<S> tok) { |
161 | ret joinWithSpace(map ruleEngine_tokenToProlog(tok)); |
162 | } |
163 | |
164 | void addFactsFromProlog(L<Lisp> l) { |
165 | addFacts(printAll(map nlUnparse(l))); |
166 | } |
167 | |
168 | void addFacts(L<S> l) { |
169 | for (S s : unnull(l)) addFact(s); |
170 | } |
171 | |
172 | RuleEngine showStuff() { |
173 | prolog.showStuff = true; |
174 | this; |
175 | } |
176 | } |
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1014771 |
Snippet name: | Rule Engine [Include] |
Eternal ID of this version: | #1014771/13 |
Text MD5: | 950578db2ebe0cbc4096479bdb940fc9 |
Author: | stefan |
Category: | javax / a.i. |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-05-02 09:58:03 |
Source code size: | 5016 bytes / 176 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 364 / 942 |
Version history: | 12 change(s) |
Referenced in: | [show references] |