Libraryless. Click here for Pure Java version (4502L/30K/94K).
1 | !752 |
2 | |
3 | !include #1002752 // newest LThread |
4 | |
5 | static interface TheoryHolder { |
6 | public Lisp getTheory(S name); |
7 | } |
8 | |
9 | static class Rewriter { |
10 | new L<S> log; |
11 | new L<Lisp> statements; |
12 | TheoryHolder holder; |
13 | int safety, exceptions; |
14 | int safetyMax = 10000, statementsMax = 100; |
15 | boolean nativeOn; // use all the native functions defined in bots |
16 | |
17 | *(TheoryHolder *holder, L<S> theoryNames) { |
18 | for (S name : theoryNames) { |
19 | if (eq(name, "native")) |
20 | nativeOn = true; |
21 | else { |
22 | Lisp t = null; |
23 | pcall { |
24 | t = holder.getTheory(name); |
25 | } |
26 | if (t == null) |
27 | log.add(format("Warning: Theory * not found", name)); |
28 | else |
29 | addTheory(t); |
30 | } |
31 | } |
32 | } |
33 | |
34 | void addTheory(Lisp tree) { |
35 | if (isJuxta(tree)) |
36 | for (Lisp part : tree) |
37 | addTheory(part); |
38 | else |
39 | statements.add(tree); |
40 | } |
41 | |
42 | IEngine makeEngine() { |
43 | IEngine engine = null; |
44 | if (nativeOn) { |
45 | final L<Method> nativeBots = findNativeMethods(); |
46 | engine = new IEngine() { |
47 | public boolean yo(Native n) { |
48 | n.printExceptions = true; |
49 | |
50 | for (Method method : nativeBots) |
51 | if (n.callExternal(method)) |
52 | ret true; |
53 | ret false; |
54 | } |
55 | |
56 | public void memorize(Lisp statement) {} |
57 | public void forget(Lisp statement) {} |
58 | }; |
59 | } |
60 | ret engine; |
61 | } |
62 | |
63 | LThread newLThread(Lisp rule, IEngine engine) { |
64 | LThread thread = new LThread(rule); |
65 | thread.engine = engine; |
66 | //thread.log = log; |
67 | thread.statements.addAll(statements); |
68 | ret thread; |
69 | } |
70 | |
71 | // do the rewrites! |
72 | void go() { |
73 | IEngine engine = makeEngine(); |
74 | boolean anyChange; |
75 | safety = 0; |
76 | do { |
77 | anyChange = false; |
78 | |
79 | // run rules |
80 | |
81 | for (Lisp rule : cloneList(statements)) |
82 | if (rule.head.startsWith("if ")) try { |
83 | LThread thread = newLThread(rule, engine); |
84 | boolean success = thread.run(); |
85 | if (success) { |
86 | for (Lisp s : thread.output) |
87 | if (!statements.contains(s)) { |
88 | statements.add(s); |
89 | anyChange = true; |
90 | } |
91 | } |
92 | } catch (Exception e) { |
93 | exceptions++; |
94 | } |
95 | } while (anyChange && ++safety < safetyMax && l(statements) < statementsMax); |
96 | } |
97 | |
98 | boolean query(Lisp q, SNLMatches m) { |
99 | IEngine engine = makeEngine(); |
100 | LThread thread = newLThread(lisp("if *", q), engine); |
101 | if (!thread.run()) ret false; |
102 | m.addAll(thread.m); |
103 | ret true; |
104 | } |
105 | } |
106 | |
107 | static Rewriter newRewriter(S description) { |
108 | ret new Rewriter(new TheoryHolder() { |
109 | public Lisp getTheory(S name) { |
110 | ret getTheoryFromBot(name); |
111 | } |
112 | }, unquoteAll(codeTokensOnly(javaTok(description)))); |
113 | } |
114 | |
115 | static S doQuery(S query, Rewriter r) { |
116 | new SNLMatches matches; |
117 | if (!r.query(snlToTree(query), matches) |
118 | && !r.query(snlToTree("X = " + query), matches)) // automagic |
119 | ret "false\n"; |
120 | |
121 | r.go(); |
122 | L<S> l = cloneList(r.log); |
123 | for (S var : matches.keySet()) |
124 | l.add(var + " = " + snlFromTree(matches.get(var))); |
125 | ret "TRUE\n" + slackSnippetOpt(fromLines(l)); |
126 | } |
127 | |
128 | answer { |
129 | if (!attn()) ret null; |
130 | |
131 | if (matchStart("rewrite", s, m)) exceptionToUser { |
132 | Rewriter r = newRewriter(m.rest()); |
133 | int n = l(r.statements); |
134 | r.go(); |
135 | L<S> l = cloneList(r.log); |
136 | L<Lisp> newStatements = subList(r.statements, n); |
137 | if (empty(newStatements)) |
138 | l.add("<no results>"); |
139 | else |
140 | for (Lisp tree : newStatements) |
141 | l.add(snlFromTree(tree)); |
142 | ret slackSnippet(fromLines(l)); |
143 | } |
144 | |
145 | if (matchStart("query *", s, m)) exceptionToUser { |
146 | ret doQuery(m.unq(0), newRewriter(m.rest())); |
147 | } |
148 | |
149 | if (s.startsWith("nat ") || s.startsWith("native ")) exceptionToUser { |
150 | s = dropUntilSpace(s); |
151 | ret doQuery(s, newRewriter("native")); |
152 | } |
153 | |
154 | if "list native bots" |
155 | ret structure(findNativeBots()); |
156 | } |
157 | |
158 | static Lisp getTheoryFromBot(S name) { |
159 | ret (Lisp) quickImport(callOpt(getBot("#1002762"), "getParsedTheory", name)); |
160 | } |
161 | |
162 | static L<Method> findNativeMethods() { |
163 | new L l; |
164 | for (S id : getSubBotIDs()) { |
165 | O bot = getBot(id); |
166 | //Method m = findMethod(bot, "yo", n); // doesn't work b/c of realms |
167 | Method m = findMethodNamed(bot, "safe"); |
168 | if (isNativeMethod(m)) { |
169 | l.add(m); |
170 | Class c = m.getDeclaringClass(); |
171 | print("Declaring class: " + ihc(c) + ", bot: " + ihc(bot)); |
172 | } |
173 | } |
174 | print("Native methods found: " + l(l)); |
175 | ret l; |
176 | } |
177 | |
178 | static L<S> findNativeBots() { |
179 | new L l; |
180 | for (S id : getSubBotIDs()) { |
181 | O bot = getBot(id); |
182 | Method m = findMethodNamed(bot, "safesafe"); |
183 | if (isNativeMethod(m)) |
184 | l.add(id); |
185 | } |
186 | ret l; |
187 | } |
188 | |
189 | static boolean isNativeMethod(Method m) { |
190 | if (m == null) ret false; |
191 | Class[] p = m.getParameterTypes(); |
192 | if (p.length != 1) ret false; |
193 | S name = p[0].getName(); |
194 | //print("Parameter type: " + name); |
195 | ret eq("main$Native", name); |
196 | } |
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1002781 |
Snippet name: | Rewriting Bot (LIVE) |
Eternal ID of this version: | #1002781/1 |
Text MD5: | d91bc425bc82e061950c83ea7883e744 |
Transpilation MD5: | 1df8b5887f552f60cc705b5efc13ad58 |
Author: | stefan |
Category: | eleu / nl |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-02-27 00:49:03 |
Source code size: | 5099 bytes / 196 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 793 / 775 |
Referenced in: | [show references] |