Libraryless. Click here for Pure Java version (1147L/8K/27K).
1 | !752 |
2 | |
3 | // TermCons -> Lisp |
4 | |
5 | static int varCount; |
6 | |
7 | static class Var extends Lisp { |
8 | Lisp instance; |
9 | |
10 | *() { |
11 | this("V" + (++varCount)); |
12 | } |
13 | |
14 | *(S name) { |
15 | super(name); |
16 | instance = this; |
17 | } |
18 | |
19 | void reset() { instance = this; } |
20 | |
21 | public String toString() { |
22 | if (instance == this) ret getName(); |
23 | ret instance.toString(); |
24 | } |
25 | |
26 | S getName() { |
27 | ret head; |
28 | } |
29 | } |
30 | |
31 | static class Clause { |
32 | Lisp head; |
33 | Goal body; |
34 | |
35 | *(Lisp *head, Goal *body) {} |
36 | *(Lisp *head) {} |
37 | |
38 | Clause copy() { |
39 | return new Clause(copy2(head), body == null ? null : body.copy()); |
40 | } |
41 | |
42 | public String toString() { |
43 | ret head + " :- " + (body == null ? "true" : body); |
44 | } |
45 | }; |
46 | |
47 | static class Program { |
48 | Clause pcar; |
49 | Program pcdr; |
50 | |
51 | *(Clause *pcar, Program *pcdr) {} |
52 | *(L<Clause> clauses) { |
53 | this(clauses, 0); |
54 | } |
55 | |
56 | *(L<Clause> clauses, int i) { |
57 | pcar = clauses.get(i); |
58 | if (i+1 < l(clauses)) |
59 | pcdr = new Program(clauses, i+1); |
60 | } |
61 | |
62 | *(Clause... clauses) { |
63 | this(asList(clauses)); |
64 | } |
65 | } |
66 | |
67 | static class Trail { |
68 | Var tcar; |
69 | Trail tcdr; |
70 | |
71 | *(Var *tcar, Trail *tcdr) {} |
72 | |
73 | }; |
74 | |
75 | static Trail sofar = null; |
76 | |
77 | static Trail Trail_Note() { return sofar; } |
78 | static void Trail_Push(Var x) { sofar = new Trail(x, sofar); } |
79 | static void Trail_Undo(Trail whereto) { |
80 | for (; sofar != whereto; sofar = sofar.tcdr) |
81 | sofar.tcar.reset(); |
82 | } |
83 | |
84 | static class TermVarMapping { |
85 | new L<Var> vars; |
86 | |
87 | *(L<Var> *vars) {} |
88 | *(Var... vars) { this.vars.addAll(asList(vars)); } |
89 | |
90 | void showanswer() { |
91 | print("TRUE."); |
92 | for (Var v : vars) |
93 | print(" " + v.getName() + " = " + v); |
94 | } |
95 | } |
96 | |
97 | static class Goal { |
98 | Lisp car; |
99 | Goal cdr; |
100 | |
101 | *(Lisp *car, Goal *cdr) {} |
102 | *(Lisp *car) {} |
103 | |
104 | public String toString() { |
105 | ret cdr == null ? car.toString() : car + "; " + cdr; |
106 | } |
107 | |
108 | void solve(Program p, int level, TermVarMapping map) { |
109 | print(indent(level) + "solve@" + level + ": " + this); |
110 | for (Program q = p; q != null; q = q.pcdr) { |
111 | Trail t = Trail_Note(); |
112 | Clause c = q.pcar.copy(); |
113 | Trail_Undo(t); |
114 | print(indent(level) + " try:" + c); |
115 | if (unify(car, c.head)) { |
116 | Goal gdash = c.body == null ? cdr : c.body.append(cdr); |
117 | if (gdash == null) |
118 | map.showanswer(); |
119 | else |
120 | gdash.solve(p, level+1, map); |
121 | } else |
122 | print(indent(level) + " nomatch."); |
123 | Trail_Undo(t); |
124 | } |
125 | } |
126 | |
127 | Goal copy() { |
128 | return new Goal(copy2(car), |
129 | cdr == null ? null : cdr.copy()); |
130 | } |
131 | |
132 | Goal append(Goal l) { |
133 | return new Goal(car, cdr == null ? null : cdr.append(l)); |
134 | } |
135 | |
136 | } // class Goal |
137 | |
138 | static boolean unify(Lisp thiz, Lisp t) { |
139 | if (thiz instanceof Var) { |
140 | Var v = cast thiz; |
141 | if (v.instance != v) |
142 | return unify(v.instance, t); |
143 | Trail_Push(v); |
144 | v.instance = t; |
145 | return true; |
146 | } |
147 | |
148 | return unify2(t, thiz); |
149 | } |
150 | |
151 | static boolean unify2(Lisp thiz, Lisp t) { |
152 | if (thiz instanceof Var) |
153 | return unify(thiz, t); |
154 | |
155 | int arity = thiz.size(); |
156 | if (neq(thiz.head, t.head) || arity != t.size()) |
157 | return false; |
158 | for (int i = 0; i < arity; i++) |
159 | if (!unify(thiz.get(i), t.get(i))) |
160 | return false; |
161 | return true; |
162 | } |
163 | |
164 | static Lisp copy(Lisp thiz) { |
165 | if (thiz instanceof Var) { |
166 | Var v = cast thiz; |
167 | if (v.instance == v) { |
168 | Trail_Push(v); |
169 | v.instance = new Var(); |
170 | } |
171 | return v.instance; |
172 | } |
173 | |
174 | ret copy2(thiz); |
175 | } |
176 | |
177 | static Lisp newTermCons(Lisp t) { |
178 | Lisp l = new Lisp(t.head); |
179 | for (Lisp arg : t) |
180 | l.add(copy(arg)); |
181 | ret l; |
182 | } |
183 | |
184 | static Lisp copy2(Lisp thiz) { |
185 | return newTermCons(thiz); |
186 | } |
187 | |
188 | p { |
189 | /* A sample test program: append */ |
190 | |
191 | S at_app = "app"; |
192 | S at_cons = "cons"; |
193 | Lisp f_nil = lisp("nil"); |
194 | Lisp f_1 = lisp("1"); |
195 | Lisp f_2 = lisp("2"); |
196 | Lisp f_3 = lisp("3"); |
197 | |
198 | Lisp v_x = new Var; |
199 | Lisp lhs1 = lisp(at_app, f_nil, v_x, v_x); |
200 | Clause c1 = new Clause(lhs1); |
201 | |
202 | Lisp v_l = new Var(); |
203 | Lisp v_m = new Var(); |
204 | Lisp v_n = new Var(); |
205 | Lisp rhs2 = lisp(at_app, v_l, v_m, v_n); |
206 | Lisp lhs2 = lisp(at_app, lisp(at_cons, v_x, v_l), |
207 | v_m, |
208 | lisp(at_cons, v_x, v_n)); |
209 | |
210 | Clause c2 = new Clause(lhs2, new Goal(rhs2)); |
211 | |
212 | Var v_i = new Var(); |
213 | Var v_j = new Var(); |
214 | Lisp rhs3 = lisp(at_app, v_i, v_j, |
215 | lisp(at_cons, f_1, |
216 | lisp(at_cons, f_2, |
217 | lisp(at_cons, f_3, f_nil)))); |
218 | |
219 | Goal g1 = new Goal(rhs3); |
220 | |
221 | Program test_p = new Program(c1, c2); |
222 | Program test_p2 = new Program(c2, c1); |
223 | |
224 | TermVarMapping var_name_map = new TermVarMapping(v_i, v_j); |
225 | |
226 | print("=======Append with normal clause order:"); |
227 | g1.solve(test_p, 0, var_name_map); |
228 | print(); |
229 | print("=======Append with reversed normal clause order:"); |
230 | g1.solve(test_p2, 0, var_name_map); |
231 | } |
Began life as a copy of #1002818
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: | #1002819 |
Snippet name: | Prolog Interpreter (v1, without class), superseded by #1002820 |
Eternal ID of this version: | #1002819/1 |
Text MD5: | 9036be40e7917a7cf44a100063f7ebef |
Transpilation MD5: | d2dd472f8977826d6e7d9c5d437e4935 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-02-27 04:18:59 |
Source code size: | 5035 bytes / 231 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 683 / 653 |
Referenced in: | [show references] |