1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package jTrolog.lib;
40
41 import jTrolog.engine.BindingsTable;
42 import jTrolog.engine.Prolog;
43 import jTrolog.errors.InvalidLibraryException;
44 import jTrolog.errors.PrologException;
45 import jTrolog.parser.Parser;
46 import jTrolog.terms.Clause;
47 import jTrolog.terms.Flag;
48 import jTrolog.terms.Int;
49 import jTrolog.terms.Number;
50 import jTrolog.terms.Struct;
51 import jTrolog.terms.StructAtom;
52 import jTrolog.terms.Term;
53 import jTrolog.terms.Var;
54 import jTrolog.terms.WrapStruct;
55
56 import java.io.File;
57 import java.io.FileInputStream;
58 import java.io.FileNotFoundException;
59 import java.io.IOException;
60 import java.util.Iterator;
61 import java.util.LinkedList;
62 import java.util.List;
63
64
65
66
67
68
69
70
71 @SuppressWarnings({ "rawtypes", "unchecked","serial" })
72 public class BuiltIn extends Library {
73
74 private Prolog engine;
75
76 public BuiltIn(Prolog mediator) {
77 engine = mediator;
78 }
79
80
81
82
83
84 public String[] getSynonym(String primitive) {
85 if (primitive.equals("cut"))
86 return new String[] { "!" };
87 if (primitive.equals("unify"))
88 return new String[] { "=" };
89 if (primitive.equals("deunify"))
90 return new String[] { "\\=" };
91 if (primitive.equals("comma"))
92 return new String[] { "," };
93 if (primitive.equals("solve"))
94 return new String[] { "initialization" };
95 if (primitive.equals("assertz"))
96 return new String[] { "assert" };
97 if (primitive.equals("copy"))
98 return new String[] { "copy_term" };
99 return null;
100 }
101
102
103
104
105 public boolean comma_2(BindingsTable bt, Term arg0, Term arg1) {
106 throw new RuntimeException("','/2 method is hardcoded in the Engine, do not use Buitlin.comma_2!");
107 }
108
109 public static boolean cut_0(BindingsTable bt) {
110 throw new RuntimeException("!/0 method is hardcoded in engine, do not use Buitlin.cut_0!");
111 }
112
113 public static boolean fail_0(BindingsTable bt) {
114 return false;
115 }
116
117 public static boolean true_0(BindingsTable bt) {
118 return true;
119 }
120
121 public static boolean call_1(BindingsTable bt, Term arg1) {
122 throw new RuntimeException("call/1 method is hardcoded in engine, do not use Buitlin.call_1!");
123 }
124
125 public static boolean halt_0(BindingsTable bt) throws PrologException {
126 throw new PrologException("halt()");
127 }
128
129 public boolean halt_1(BindingsTable bt, jTrolog.terms.Number arg0) throws PrologException {
130 throw new PrologException("halt(" + arg0.intValue() + ")");
131 }
132
133 public boolean $debug_1(BindingsTable bt, Term arg0) {
134 System.out.println("debug=== " + bt.variant(arg0));
135 return true;
136 }
137
138 public boolean $debug_3(BindingsTable bt, Term arg0, Term arg2, Term arg3) {
139 System.out.println("debug0=== " + bt.variant(arg0));
140 System.out.println("debug1=== " + bt.variant(arg2));
141 System.out.println("debug2=== " + bt.variant(arg3));
142 return true;
143 }
144
145 public boolean asserta_1(BindingsTable bt, Term arg0) throws PrologException {
146 arg0 = bt.variant(arg0);
147 engine.assertA(convertTermToClause(arg0));
148 return true;
149 }
150
151 public boolean assertz_1(BindingsTable bt, Term arg0) throws PrologException {
152 arg0 = bt.variant(arg0);
153 engine.assertZ(convertTermToClause(arg0));
154 return true;
155 }
156
157 public boolean $retract_1(BindingsTable bt, Struct arg0) throws PrologException {
158 arg0 = (Struct) bt.variant(arg0);
159 arg0 = convertTermToClause(arg0).original;
160 Struct sarg0 = (Struct) bt.wrapWithID(arg0);
161 Struct retractedClause = engine.retract(sarg0);
162
163 if (retractedClause != null) {
164 bt.unify(retractedClause, arg0);
165 return true;
166 }
167 return false;
168 }
169
170
171
172
173
174
175
176
177
178 public boolean abolish_1(BindingsTable bt, Struct predicateIndicator) throws PrologException {
179 engine.abolish(isPredicateIndicator(predicateIndicator, bt));
180 return true;
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194 public boolean dynamic_1(BindingsTable bt, Struct predicateIndicator) throws PrologException {
195 engine.setDynamicPredicateIndicator(isPredicateIndicator(predicateIndicator, bt));
196 return true;
197 }
198
199
200
201
202 public boolean load_library_1(BindingsTable bt, Struct arg0) throws InvalidLibraryException {
203 if (!BasicLibrary.atom_1(bt, arg0))
204 return false;
205 engine.loadLibrary(arg0.name);
206 return true;
207 }
208
209
210
211
212 public boolean unload_library_1(BindingsTable bt, Struct arg0) throws InvalidLibraryException {
213 if (!BasicLibrary.atom_1(bt, arg0))
214 return false;
215 engine.unloadLibrary(arg0.name);
216 return true;
217 }
218
219
220
221
222 public boolean flag_list_1(BindingsTable bt, Term arg0) {
223 return bt.unify(arg0, bt.wrapWithID(engine.getPrologFlagList()));
224 }
225
226 public boolean unify_2(BindingsTable bt, Term arg0, Term arg1) {
227 return bt.unify(arg0, arg1);
228 }
229
230
231 public boolean deunify_2(BindingsTable bt, Term arg0, Term arg1) {
232 return !bt.unify(arg0, arg1);
233 }
234
235
236
237 public boolean newlist_2(BindingsTable bt, Int length, Var out) throws PrologException {
238 int lengthInt = length.intValue();
239 if (lengthInt < 0)
240 throw new PrologException("domain_error(not_less_than_zero, " + length + ")");
241 if (lengthInt == 0)
242 return bt.unify(out, Term.emptyList);
243 return bt.unify(out, (WrapStruct) bt.wrapWithID(Parser.createListContainingAnyVars(lengthInt)));
244 }
245
246
247 public boolean copy_2(BindingsTable bt, Term arg0, Term arg1) {
248 return bt.unify(bt.wrapWithID(bt.variant(arg0)), arg1);
249 }
250
251
252
253
254 public boolean $find_2(BindingsTable bt, Struct arg0, Term arg1) throws PrologException, CloneNotSupportedException {
255 String key = arg0.predicateIndicator;
256 if (engine.hasPrimitive(key))
257 throw new PrologException("permission_error(access, static_procedure, " + key + ")");
258 LinkedList res = new LinkedList();
259 List clauses = engine.find(key);
260 if (clauses.isEmpty())
261 return bt.unify(arg1, Term.emptyList);
262 for (Iterator it = clauses.iterator(); it.hasNext();)
263 res.add(((Clause) it.next()).original);
264 res.add(Term.emptyList);
265 return bt.unify(arg1, bt.wrapWithID(Parser.createStructList(res)));
266 }
267
268
269 public boolean set_prolog_flag_2(BindingsTable bt, Term arg0, Term arg1) {
270 if (!BasicLibrary.atom_1(bt, arg0) && !(arg0 instanceof Struct) || !BasicLibrary.ground_1(bt, arg1))
271 return false;
272
273 String name = arg0.toString();
274 Flag flag = engine.getFlag(name);
275 if (flag != null) {
276 try {
277 for (Iterator it2 = bt.structListIterator(flag.getValueList(), true); it2.hasNext();) {
278 Term t = (Term) it2.next();
279 if (Prolog.match(arg1, t)) {
280 flag.setValue(arg1);
281 return true;
282 }
283 }
284 } catch (PrologException e) {
285 throw new RuntimeException("error in iterating a Struct list");
286 }
287 }
288 return false;
289 }
290
291
292 public boolean get_prolog_flag_2(BindingsTable bt, Term arg0, Term arg1) {
293 if (!BasicLibrary.atom_1(bt, arg0) && !(arg0 instanceof Struct))
294 return false;
295
296 String name = arg0.toString();
297 Term value = engine.getFlagValue(name);
298 if (value == null)
299 return false;
300 return bt.unify(value, arg1);
301 }
302
303
304
305
306
307
308
309
310
311 public void op_3(BindingsTable bt, Number arg0, StructAtom arg1, StructAtom arg2) {
312 String st = ((Struct) arg1).name;
313 if (st.matches("[xy]?f[xy]?"))
314 engine.opNew(arg2.toString(), st, arg0.intValue());
315 }
316
317 public void flag_4(BindingsTable bt, Term flagName, Struct flagSet, Term flagDefault, Term flagModifiable) {
318 if (flagModifiable.equals(Term.TRUE) || flagModifiable.equals(Term.FALSE))
319 engine.defineFlag(flagName.toString(), flagSet, flagDefault, flagModifiable.equals(Term.TRUE));
320 }
321
322
323
324
325 public void solve_1(BindingsTable bt, Struct goal) throws Throwable {
326 engine.solve(bt.wrapWithID(bt.variant(goal)).toString());
327 }
328
329 public void load_library_1(BindingsTable bt, Term lib) throws InvalidLibraryException {
330 if (BasicLibrary.atom_1(bt, lib))
331 engine.loadLibrary(((Struct) lib).name);
332 }
333
334 public void consult_1(BindingsTable bt, Term theory) throws FileNotFoundException, PrologException, IOException {
335 FileInputStream is;
336 try {
337 is = new FileInputStream(Parser.removeApices(theory.toString()));
338 } catch (FileNotFoundException e) {
339 File dir = new File(System.getProperty("user.dir"));
340 String filename = dir + File.separator + Parser.removeApices(theory.toString());
341 is = new FileInputStream(filename);
342 }
343 engine.addTheory(IOLibrary.readStream(is));
344 }
345
346 public boolean $instantiation_error_0(BindingsTable bt) throws PrologException {
347 throw new PrologException("instantiation_error");
348 }
349
350 public boolean $type_error_2(BindingsTable bt, Term typeName, Term term) throws PrologException {
351 throw new PrologException("type_error(" + typeName + ", " + term + ")");
352 }
353
354 public boolean $representation_error_1(BindingsTable bt, Term maxArity) throws PrologException {
355 throw new PrologException("representation_error(" + maxArity + ")");
356 }
357
358 public boolean $domain_error_zero_1(BindingsTable bt, Term term) throws Exception {
359 throw new PrologException("domain_error(not_less_than_zero, " + term + ")");
360 }
361
362
363
364
365
366
367
368
369 public static Clause convertTermToClause(Term arg0) throws PrologException {
370 if (arg0 instanceof Var)
371 throw new PrologException("instantiation_error");
372
373 if (arg0 instanceof Number)
374 throw new PrologException("type_error(callable, " + arg0 + ")");
375
376 Term head, body;
377 Struct cl = (Struct) arg0;
378 if (cl.predicateIndicator != Parser.doubleClauseSignature) {
379 head = arg0;
380 body = Term.TRUE;
381 } else {
382 head = cl.getArg(0);
383 body = cl.getArg(1);
384 }
385 if (head instanceof Number)
386 throw new PrologException("type_error(callable, " + head + ")");
387 if (head instanceof Var)
388 throw new PrologException("instantiation_error");
389
390 if (body instanceof Number)
391 throw new PrologException("type_error(callable, " + body + ")");
392 body = convertTermToClauseBody(body);
393 Struct[] body2 = convertTermToClauseBody2(body);
394
395 return new Clause(body2, (Struct) head, new Struct(":-", new Term[] { head, body }));
396 }
397
398
399 public static Struct[] convertTermToClauseBody2(Term body) throws PrologException {
400 LinkedList tmp = new LinkedList();
401 while (body instanceof Struct && ((Struct) body).predicateIndicator == Parser.commaSignature) {
402 tmp.add(convertTermToClauseBody(((Struct) body).getArg(0)));
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 body = ((Struct) body).getArg(1);
419 }
420 tmp.add(convertTermToClauseBody(body));
421 return (Struct[]) tmp.toArray(new Struct[tmp.size()]);
422 }
423
424 public static Struct convertTermToClauseBody(Term body) throws PrologException {
425 if (body instanceof Var)
426 return new Struct("call", new Term[] { body });
427 if (body instanceof Number)
428 throw new PrologException("type_error(callable, " + body + ")");
429 Struct s = (Struct) body;
430 String sPredIndic = s.predicateIndicator;
431 if (sPredIndic == Parser.ifSignature || sPredIndic == Parser.commaSignature || sPredIndic == Parser.semiColonSignature || sPredIndic == Parser.throwSignature
432 || sPredIndic == Parser.catchSignature) {
433 Term[] args = new Term[s.arity];
434 for (int i = 0; i < s.arity; i++)
435 args[i] = convertTermToClauseBody(s.getArg(i));
436 return new Struct(s.name, args, s.getOperatorType());
437 }
438 return s;
439 }
440
441 public static String isPredicateIndicator(Struct predicateIndicator, BindingsTable bt) throws PrologException {
442 if (predicateIndicator.predicateIndicator != "'/'/2")
443 throw new PrologException("type_error(predicate_indicator, " + predicateIndicator + ")");
444 Term name = bt.resolve(predicateIndicator.getArg(0));
445 Term arity = bt.resolve(predicateIndicator.getArg(1));
446 if (name instanceof Var || arity instanceof Var)
447 throw new PrologException("instantiation_error");
448 if (!(arity instanceof Int))
449 throw new PrologException("type_error(integer, " + arity + ")");
450 if (!(name instanceof StructAtom))
451 throw new PrologException("type_error(atom, " + name + ")");
452 Int arityInt = (Int) arity;
453 if (arityInt.intValue() < 0)
454 throw new PrologException("domain_error(not_less_than_zero, " + arityInt + ")");
455 if (arityInt.longValue() > Integer.MAX_VALUE)
456 throw new PrologException("representation_error(max_arity)");
457 return Parser.wrapAtom(name.toString()) + "/" + arity;
458 }
459 }