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: | 1193 / 1177 |
| Referenced in: | [show references] |