View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jtrolog
4    * %%
5    * Copyright (C) 2012 - 2018 WorkLogic Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  /*
23   * tuProlog - Copyright (C) 2001-2007 aliCE team at deis.unibo.it
24   *
25   * This library is free software; you can redistribute it and/or
26   * modify it under the terms of the GNU Lesser General Public
27   * License as published by the Free Software Foundation; either
28   * version 2.1 of the License, or (at your option) any later version.
29   *
30   * This library is distributed in the hope that it will be useful,
31   * but WITHOUT ANY WARRANTY; without even the implied warranty of
32   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
33   * Lesser General Public License for more details.
34   *
35   * You should have received a copy of the GNU Lesser General Public
36   * License along with this library; if not, write to the Free Software
37   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
38   */
39  package jTrolog.lib;
40  
41  import jTrolog.engine.BindingsTable;
42  import jTrolog.errors.InvalidLibraryException;
43  import jTrolog.errors.PrologException;
44  import jTrolog.parser.Parser;
45  import jTrolog.terms.EvaluableTerm;
46  import jTrolog.terms.Float;
47  import jTrolog.terms.Int;
48  import jTrolog.terms.IteratorAsTerm;
49  import jTrolog.terms.Long;
50  import jTrolog.terms.Number;
51  import jTrolog.terms.Struct;
52  import jTrolog.terms.StructAtom;
53  import jTrolog.terms.Term;
54  import jTrolog.terms.Var;
55  import jTrolog.terms.WrapStruct;
56  import jTrolog.terms.WrapVar;
57  
58  import java.util.Arrays;
59  import java.util.HashMap;
60  import java.util.Iterator;
61  import java.util.LinkedList;
62  
63  /**
64   * This class defines a set of basic built-in predicates for the tuProlog engine
65   * 
66   * Library/Theory dependency: none
67   * 
68   * 
69   * 
70   */
71  @SuppressWarnings({ "rawtypes", "unchecked","serial" })
72  public class BasicLibrary extends Library {
73  
74  	//
75  	// meta-predicates
76  	//
77  
78  	/**
79  	 * sets a new theory provided as a text
80  	 */
81  	public boolean set_theory_1(BindingsTable bt, Term th) {
82  		if (!atom_1(bt, th))
83  			return false;
84  		try {
85  			engine.clearTheory();
86  			engine.addTheory(((Struct) th).name);
87  			return true;
88  		} catch (PrologException e) {
89  			System.err.println("invalid theory:" + e.getMessage());
90  			return false;
91  		}
92  	}
93  
94  	/**
95  	 * adds a new theory provided as a text
96  	 */
97  	public boolean add_theory_1(BindingsTable bt, Term th) throws PrologException {
98  		if (!atom_1(bt, th))
99  			return false;
100 		((Library) this).engine.addTheory(((Struct) th).name);
101 		return true;
102 	}
103 
104 	/** gets current theory text */
105 	public boolean get_theory_1(BindingsTable bt, Term arg) {
106 		return bt.unify(arg, new StructAtom(engine.getTheory()));
107 	}
108 
109 	public boolean load_library_2(BindingsTable bt, Struct className, Term libName) throws InvalidLibraryException {
110 		Library lib = engine.loadLibrary(Parser.removeApices(className.name));
111 		return bt.unify(libName, new StructAtom(lib.getName()));
112 	}
113 
114 	public boolean get_operators_list_1(BindingsTable bt, Struct argument) {
115 		LinkedList result = new LinkedList();
116 		for (Iterator it = engine.getCurrentOperators(); it.hasNext();)
117 			result.add((it.next()));
118 		if (result.isEmpty())
119 			return bt.unify(argument, Term.emptyList);
120 		result.add(Term.emptyList);
121 		return bt.unify(argument, bt.createStructList(result));
122 	}
123 
124 	public boolean warning_0(BindingsTable bt) {
125 		engine.resetWarningList();
126 		return true;
127 	}
128 
129 	public boolean nowarning_0(BindingsTable bt) {
130 		engine.resetWarningList();
131 		return true;
132 	}
133 
134 	//
135 	// term type inspection
136 	//
137 
138 	public static boolean constant_1(BindingsTable bt, Term t) {
139 		return atomic_1(bt, t);
140 	}
141 
142 	public static boolean number_1(BindingsTable bt, Term t) {
143 		return t instanceof Number;
144 	}
145 
146 	public static boolean integer_1(BindingsTable bt, Term t) {
147 		return t instanceof Int;
148 	}
149 
150 	public static boolean float_1(BindingsTable bt, Term t) {
151 		return t instanceof Float;
152 	}
153 
154 	public static boolean atom_1(BindingsTable bt, Term t) {
155 		return t instanceof StructAtom;
156 	}
157 
158 	public static boolean compound_1(BindingsTable bt, Term t) {
159 		return t instanceof Struct && !(t instanceof StructAtom);
160 	}
161 
162 	public static boolean list_1(BindingsTable bt, Term t) throws PrologException {
163 		if (t instanceof Var)
164 			throw new PrologException("instantiation_error");
165 		if (t.equals(Term.emptyList))
166 			return true;
167 		if (!(t instanceof Struct))
168 			return false;
169 		final Struct s = (Struct) t;
170 		if (s.predicateIndicator != Parser.listSignature)
171 			return false;
172 		// iterate the list to find the last element and run isList on that last
173 		// element
174 		Term last = null;
175 		for (Iterator it = Struct.iterator(s); it.hasNext(); last = (Term) it.next())
176 			;
177 		return list_1(bt, bt.resolve(last));
178 	}
179 
180 	public boolean var_1(BindingsTable bt, Term t) {
181 		return t instanceof Var;
182 	}
183 
184 	public boolean nonvar_1(BindingsTable bt, Term t) {
185 		return !(t instanceof Var);
186 	}
187 
188 	public static boolean atomic_1(BindingsTable bt, Term t) {
189 		return t instanceof Number || t instanceof StructAtom;
190 	}
191 
192 	public static boolean ground_1(BindingsTable bt, Term t) {
193 		if (t instanceof Var)
194 			return false;
195 		if (t instanceof Number || t instanceof StructAtom)
196 			return true;
197 		// compound and thus wrapped struct
198 		WrapStruct wrapStruct = ((WrapStruct) t);
199 		Var[] childVars = wrapStruct.getVarList();
200 		if (childVars == null)
201 			return false; // todo no WrapStruct should have null as childVars.
202 							// Should find out when and why null is returned
203 							// here..
204 		int ctx = wrapStruct.getContext();
205 		for (int i = 0; i < childVars.length; i++) {
206 			if (!ground_1(bt, bt.resolve(new WrapVar(childVars[i], ctx))))
207 				return false;
208 		}
209 		return true;
210 	}
211 
212 	public boolean $arg_3(BindingsTable bt, Int n, Struct term, Term arg) throws PrologException {
213 		if (!BasicLibrary.compound_1(bt, term))
214 			throw new PrologException("type_error(compound, " + term + ")");
215 		if (n.intValue() < 0)
216 			throw new PrologException("domain_error(not_less_than_zero, " + n + ")");
217 
218 		if (n.intValue() == 0 || n.intValue() > term.arity)
219 			return false;
220 
221 		Term nthArg = term.getArg(n.intValue() - 1);
222 		return bt.unify(arg, nthArg);
223 	}
224 
225 	public boolean $functor_3(BindingsTable bt, Term term, Term name, Term arity) throws PrologException {
226 		Int maxArity = (Int) engine.getFlagValue("max_arity");
227 
228 		if (term instanceof Var) {
229 			if (name instanceof Var || arity instanceof Var)
230 				throw new PrologException("instantiation_error");
231 
232 			if (!BasicLibrary.atomic_1(bt, name))
233 				throw new PrologException("type_error(atomic, " + name + ")");
234 
235 			if (!(arity instanceof Int))
236 				throw new PrologException("type_error(integer, " + arity + ")");
237 
238 			if (((Int) arity).longValue() > maxArity.intValue())
239 				throw new PrologException("representation_error(max_arity)");
240 
241 			if (((Int) arity).intValue() < 0)
242 				throw new PrologException("domain_error(not_less_than_zero, " + arity + ")");
243 
244 			if (!BasicLibrary.atom_1(bt, name) && ((Int) arity).intValue() > 0)
245 				throw new PrologException("type_error(atom, " + name + ")");
246 
247 			if (BasicLibrary.atomic_1(bt, name) && ((Int) arity).intValue() == 0)
248 				return bt.unify(term, name);
249 
250 			Struct newList = (WrapStruct) bt.wrapWithID(Parser.createListContainingAnyVars(((Int) arity).intValue() + 1));
251 			bt.unify(newList.getArg(0), name);
252 			return $tofromlist_2(bt, term, newList);
253 		}
254 
255 		if (BasicLibrary.atomic_1(bt, term))
256 			return bt.unify(term, name) && bt.unify(arity, new Int(0));
257 
258 		if (BasicLibrary.compound_1(bt, term)) {
259 			StructAtom a = new StructAtom(((Struct) term).name);
260 			return bt.unify(name, a) && bt.unify(arity, new Int(((Struct) term).arity));
261 		}
262 		return false;
263 	}
264 
265 	public boolean $tofromlist_2(BindingsTable bt, Term structIn, Term listIn) throws PrologException {
266 		if (structIn instanceof Number || structIn instanceof StructAtom) {
267 			Struct newList = (WrapStruct) bt.wrapWithID(Parser.createListContainingAnyVars(1));
268 			bt.unify(newList.getArg(0), structIn);
269 			return bt.unify(newList, listIn);
270 		}
271 		if (structIn instanceof Struct) {
272 			Struct struct = (Struct) structIn;
273 			WrapStruct medium = (WrapStruct) bt.wrapWithID(Parser.createListContainingAnyVars(struct.arity + 1));
274 			Iterator it = bt.structListIterator(medium, false);
275 			// unify the name of the struct with the first in the medium list
276 			bt.unify((Term) it.next(), new StructAtom(struct.name));
277 			// unify the children of the Struct with the rest of the medium list
278 			for (int i = 0; i < struct.arity; i++)
279 				bt.unify((Var) it.next(), struct.getArg(i));
280 			// try to unify the medium list generated from the struct with
281 			// listIn
282 			return bt.unify(medium, listIn);
283 		}
284 		if (structIn instanceof Var) {
285 			if (listIn instanceof Var)
286 				throw new PrologException("instantiation_error");
287 			if (!list_1(bt, listIn))
288 				throw new PrologException("type_error(list, " + listIn + ")");
289 			if (listIn.equals(Term.emptyList))
290 				throw new PrologException("domain_error(non_empty_list, " + listIn + ")");
291 			Struct list = (Struct) listIn;
292 
293 			Term head = bt.resolve(list.getArg(0));
294 			if (head instanceof Var)
295 				throw new PrologException("instantiation_error");
296 			if (!BasicLibrary.atom_1(bt, head))
297 				throw new PrologException("type_error(atom, " + head + ")");
298 
299 			Term tail = bt.resolve(list.getArg(1));
300 			if (tail instanceof Struct) {
301 				LinkedList terms = new LinkedList();
302 				for (Iterator it = bt.structListIterator((Struct) tail, true); it.hasNext();)
303 					terms.add(it.next());
304 				if (terms.isEmpty())
305 					return bt.unify(structIn, head);
306 				if (terms.size() > ((Int) engine.getFlagValue("max_arity")).intValue())
307 					throw new PrologException("representation_error(max_arity)");
308 
309 				Term[] argValuesToBeLinked = (Term[]) terms.toArray(new Term[0]);
310 				Term[] variableArgs = new Term[argValuesToBeLinked.length];
311 				for (int i = 0; i < argValuesToBeLinked.length; i++)
312 					variableArgs[i] = new Var("_", i + 1);
313 				WrapStruct wrapStructRes = (WrapStruct) bt.wrapWithID(new Struct(head.toString(), variableArgs));
314 				for (int i = 0; i < argValuesToBeLinked.length; i++)
315 					bt.unify(wrapStructRes.getArg(i), argValuesToBeLinked[i]);
316 				return bt.unify(structIn, wrapStructRes);
317 			} else {
318 				Struct newStruct = new Struct(head.toString(), new Term[] { new Var("_", 1) });
319 				WrapStruct wrapStructRes = (WrapStruct) bt.wrapWithID(newStruct);
320 				bt.unify(wrapStructRes.getArg(0), tail);
321 				return bt.unify(structIn, wrapStructRes);
322 			}
323 		}
324 		return false;
325 	}
326 
327 	public boolean current_time_1(BindingsTable bt, Term time) throws Throwable {
328 		return bt.unify(time, new Long(System.currentTimeMillis()));
329 	}
330 
331 	//
332 	// term/espression comparison
333 	//
334 
335 	public Term eval_1(BindingsTable bt, EvaluableTerm structIn) throws Throwable {
336 		return bt.evalExpression(engine, structIn);
337 	}
338 
339 	public boolean is_2(BindingsTable bt, Term structIn, EvaluableTerm listIn) throws Throwable {
340 		return bt.unify(structIn, bt.evalExpression(engine, listIn));
341 	}
342 
343 	public boolean expression_equality_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
344 		Number val1 = bt.evalExpression(engine, structIn);
345 		Number val2 = bt.evalExpression(engine, listIn);
346 		if (val1 instanceof Float || val2 instanceof Float)
347 			return Number.compareDoubleValues(val1, val2) == 0;
348 		return val1.equals(val2);
349 	}
350 
351 	public boolean expression_greater_than_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
352 		Number num0 = bt.evalExpression(engine, structIn);
353 		Number num1 = bt.evalExpression(engine, listIn);
354 		if (num0 instanceof Float || num1 instanceof jTrolog.terms.Float)
355 			return Number.compareDoubleValues(num0, num1) > 0;
356 		return num0.intValue() > num1.intValue();
357 	}
358 
359 	public boolean expression_less_or_equal_than_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
360 		return !expression_greater_than_2(bt, structIn, listIn);
361 	}
362 
363 	public boolean expression_less_than_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
364 		return !expression_greater_or_equal_than_2(bt, structIn, listIn);
365 	}
366 
367 	public boolean expression_greater_or_equal_than_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
368 		return expression_greater_than_2(bt, structIn, listIn) || expression_equality_2(bt, structIn, listIn);
369 	}
370 
371 	public static boolean term_equality_2(BindingsTable bt, Term structIn, Term listIn) {
372 		if (structIn instanceof Var) {
373 			if (!(listIn instanceof Var))
374 				return false;
375 			Var v = (Var) listIn;
376 			if (((Var) structIn).isAnonymous() && v.isAnonymous())
377 				return false;
378 			return v.equals(structIn);
379 		}
380 		if (structIn instanceof Number) {
381 			if (!(listIn instanceof Number))
382 				return false;
383 			return number_equality_2((Number) structIn, (Number) listIn);
384 		}
385 
386 		if (structIn instanceof Struct) {
387 			if (!(listIn instanceof Struct))
388 				return false;
389 
390 			Struct ts = (Struct) listIn;
391 			if (((Struct) structIn).arity != ts.arity || !((Struct) structIn).name.equals(ts.name))
392 				return false;
393 
394 			for (int i = 0; i < ((Struct) structIn).arity; i++) {
395 				if (!term_equality_2(null, ((Struct) structIn).getArg(i), ts.getArg(i)))
396 					return false;
397 			}
398 			return true;
399 		}
400 		return false;
401 	}
402 
403 	public static boolean number_equality_2(Number listIn, Number structIn) {
404 		if (listIn instanceof Int && structIn instanceof Int)
405 			return structIn.longValue() == listIn.longValue();
406 		else if (listIn instanceof Float && structIn instanceof Float)
407 			return Number.compareDoubleValues(structIn, listIn) == 0;
408 		return false;
409 	}
410 
411 	public static boolean term_greater_than_2(BindingsTable bt, Term structIn, Term listIn) {
412 		if (structIn instanceof Var) {
413 			if (!(listIn instanceof Var))
414 				return false;
415 			return structIn.toString().hashCode() > listIn.toString().hashCode();
416 		}
417 
418 		if (structIn instanceof Struct) {
419 			if (listIn instanceof Struct) {
420 				Struct ts = (Struct) listIn;
421 				int tarity = ts.arity;
422 				if (((Struct) structIn).arity < tarity)
423 					return false;
424 				if (((Struct) structIn).arity == tarity) {
425 					if (((Struct) structIn).name.equals(ts.name)) {
426 						for (int i = 0; i < ((Struct) structIn).arity; i++) {
427 							if (term_greater_than_2(null, ((Struct) structIn).getArg(i), ts.getArg(i)))
428 								return true;
429 							if (!term_equality_2(null, ((Struct) structIn).getArg(i), ts.getArg(i)))
430 								return false;
431 						}
432 					}
433 					if (((Struct) structIn).name.compareTo(ts.name) <= 0)
434 						return false;
435 				}
436 			}
437 			return true;
438 		}
439 		if (structIn instanceof Number) {
440 			if (listIn instanceof Var)
441 				return true;
442 			if (listIn instanceof Struct)
443 				return false;
444 			if (!(listIn instanceof Number))
445 				return false;
446 
447 			Number n2 = ((Number) listIn);
448 			Number n1 = ((Number) structIn);
449 			if (n1 instanceof Float || n2 instanceof Float)
450 				return Number.compareDoubleValues(n1, n2) > 0;
451 			return n1.longValue() > n2.longValue();
452 		}
453 		return false; // such as implementation specific NullTerm etc.
454 	}
455 
456 	public static boolean term_less_than_2(BindingsTable bt, Term structIn, Term listIn) {
457 		return !term_greater_than_2(null, structIn, listIn) && !term_equality_2(null, structIn, listIn);
458 	}
459 
460 	public Term expression_plus_1(BindingsTable bt, EvaluableTerm structIn) throws Throwable {
461 		return bt.evalExpression(engine, structIn);
462 	}
463 
464 	public Term expression_minus_1(BindingsTable bt, EvaluableTerm listIn) throws Throwable {
465 		Number val0 = bt.evalExpression(engine, listIn);
466 		if (val0 instanceof jTrolog.terms.Long)
467 			return new jTrolog.terms.Long(val0.longValue() * -1);
468 		if (val0 instanceof Int)
469 			return new Int(val0.intValue() * -1);
470 		if (val0 instanceof jTrolog.terms.Double)
471 			return new jTrolog.terms.Double(val0.doubleValue() * -1);
472 		if (val0 instanceof jTrolog.terms.Float)
473 			return new jTrolog.terms.Float(val0.floatValue() * -1);
474 		return null;
475 	}
476 
477 	public Term expression_bitwise_not_1(BindingsTable bt, EvaluableTerm structIn) throws Throwable {
478 		Number val = bt.evalExpression(engine, structIn);
479 		if (!(val instanceof Int))
480 			throw new PrologException("type_error(integer, " + val + ")");
481 		return new Int(~val.intValue());
482 	}
483 
484 	public Term expression_plus_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
485 		Number val0 = bt.evalExpression(engine, structIn);
486 		Number val1 = bt.evalExpression(engine, listIn);
487 		if (val0 instanceof Float || val1 instanceof Float)
488 			return new jTrolog.terms.Double(val0.doubleValue() + val1.doubleValue());
489 		return Number.getIntegerNumber(val0.longValue() + val1.longValue());
490 	}
491 
492 	public Term expression_minus_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
493 		Number val0 = bt.evalExpression(engine, structIn);
494 		Number val1 = bt.evalExpression(engine, listIn);
495 		if (val0 instanceof Float || val1 instanceof Float)
496 			return new jTrolog.terms.Double(val0.doubleValue() - val1.doubleValue());
497 		return Number.getIntegerNumber(val0.longValue() - val1.longValue());
498 	}
499 
500 	public Term expression_multiply_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
501 		Number val0 = bt.evalExpression(engine, structIn);
502 		Number val1 = bt.evalExpression(engine, listIn);
503 		if (val0 instanceof Float || val1 instanceof Float)
504 			return new jTrolog.terms.Double(val0.doubleValue() * val1.doubleValue());
505 		return Number.getIntegerNumber(val0.longValue() * val1.longValue());
506 	}
507 
508 	public Term expression_div_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
509 		Number val0 = bt.evalExpression(engine, structIn);
510 		Number val1 = bt.evalExpression(engine, listIn);
511 		if (val0 instanceof Float || val1 instanceof Float)
512 			return new jTrolog.terms.Double(val0.doubleValue() / val1.doubleValue());
513 		return Number.getIntegerNumber((long) (val0.doubleValue() / val1.doubleValue()));
514 	}
515 
516 	public Term expression_integer_div_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
517 		return Number.getIntegerNumber(bt.evalExpression(engine, structIn).longValue() / bt.evalExpression(engine, listIn).longValue());
518 	}
519 
520 	public Term expression_pow_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
521 		double val = Math.pow(bt.evalExpression(engine, structIn).doubleValue(), bt.evalExpression(engine, listIn).doubleValue());
522 		return new jTrolog.terms.Double(val);
523 	}
524 
525 	public Term expression_bitwise_shift_right_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
526 		return new Int(bt.evalExpression(engine, structIn).intValue() >> bt.evalExpression(engine, listIn).intValue());
527 	}
528 
529 	public Term expression_bitwise_shift_left_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
530 		return new Int(bt.evalExpression(engine, structIn).intValue() << bt.evalExpression(engine, listIn).intValue());
531 	}
532 
533 	public Term expression_bitwise_and_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
534 		return new Int(bt.evalExpression(engine, structIn).intValue() & bt.evalExpression(engine, listIn).intValue());
535 	}
536 
537 	public Term expression_bitwise_or_2(BindingsTable bt, EvaluableTerm structIn, EvaluableTerm listIn) throws Throwable {
538 		return new Int(bt.evalExpression(engine, structIn).intValue() | bt.evalExpression(engine, listIn).intValue());
539 	}
540 
541 	//
542 	// text/atom manipulation predicates
543 	//
544 
545 	/**
546 	 * bidirectional text/term conversion.
547 	 */
548 	public boolean text_term_2(BindingsTable bt, Term structIn, Term listIn) {
549 		if (!ground_1(bt, structIn))
550 			return bt.unify(structIn, new StructAtom(listIn.toString()));
551 		Term result = new Parser(Parser.removeApices(structIn.toString()), engine).nextTerm(false);
552 		return bt.unify(listIn, result);
553 	}
554 
555 	public boolean text_concat_3(BindingsTable bt, Term source1, Term source2, Term dest) {
556 		if (!atom_1(bt, source1) || !atom_1(bt, source2))
557 			return false;
558 		return bt.unify(dest, new StructAtom(((Struct) source1).name + ((Struct) source2).name));
559 	}
560 
561 	public boolean num_atom_2(BindingsTable bt, Term structIn, Term listIn) {
562 		if (listIn instanceof Var) {
563 			if (structIn instanceof Number)
564 				return bt.unify(listIn, new StructAtom(structIn.toString()));
565 			return false;
566 		}
567 		if (!atom_1(bt, listIn))
568 			return false;
569 		Number num = Parser.parseNumber(Parser.removeApices(((Struct) listIn).name).trim());
570 		return bt.unify(structIn, num);
571 	}
572 
573 	public String getTheory() {
574 		return
575 		//
576 		// operators defined by the BasicLibrary theory
577 		//
578 		"':-'(op( 1200, fx,   ':-')). \n"
579 				+ ":- op( 1200, xfx,  ':-'). \n"
580 				+ ":- op( 1200, fx,   '?-'). \n"
581 				+ ":- op( 1100, xfy,  ';'). \n"
582 				+ ":- op( 1050, xfy,  '->'). \n"
583 				+ ":- op( 1000, xfy,  ','). \n"
584 				+ ":- op(  900, fy,   '\\+'). \n"
585 				+ ":- op(  900, fy,   'not'). \n"
586 				+
587 				//
588 				":- op(  700, xfx,  '='). \n"
589 				+ ":- op(  700, xfx,  '\\='). \n"
590 				+ ":- op(  700, xfx,  '=='). \n"
591 				+ ":- op(  700, xfx,  '\\=='). \n"
592 				+
593 				//
594 				":- op(  700, xfx,  '@>'). \n"
595 				+ ":- op(  700, xfx,  '@<'). \n"
596 				+ ":- op(  700, xfx,  '@=<'). \n"
597 				+ ":- op(  700, xfx,  '@>='). \n"
598 				+ ":- op(  700, xfx,  '=:='). \n"
599 				+ ":- op(  700, xfx,  '=\\='). \n"
600 				+ ":- op(  700, xfx,  '>'). \n"
601 				+ ":- op(  700, xfx,  '<'). \n"
602 				+ ":- op(  700, xfx,  '=<'). \n"
603 				+ ":- op(  700, xfx,  '>='). \n"
604 				+
605 				//
606 				":- op(  700, xfx,  'is'). \n"
607 				+ ":- op(  700, xfx,  '=..'). \n"
608 				+ ":- op(  500, yfx,  '+'). \n"
609 				+ ":- op(  500, yfx,  '-'). \n"
610 				+ ":- op(  500, yfx,  '/\\'). \n"
611 				+ ":- op(  500, yfx,  '\\/'). \n"
612 				+ ":- op(  400, yfx,  '*'). \n"
613 				+ ":- op(  400, yfx,  '/'). \n"
614 				+ ":- op(  400, yfx,  '//'). \n"
615 				+ ":- op(  400, yfx,  '>>'). \n"
616 				+ ":- op(  400, yfx,  '<<'). \n"
617 				+ ":- op(  400, yfx,  'rem'). \n"
618 				+ ":- op(  400, yfx,  'mod'). \n"
619 				+ ":- op(  200, xfx,  '**'). \n"
620 				+ ":- op(  200, xfy,  '^'). \n"
621 				+ ":- op(  200, fy,   '\\'). \n"
622 				+ ":- op(  200, fy,   '-'). \n"
623 				+
624 				//
625 				// flag management
626 				//
627 				"current_prolog_flag(Name,Value) :- get_prolog_flag(Name,Value),!.\n"
628 				+ "current_prolog_flag(Name,Value) :- flag_list(L), member(flag(Name,Value),L).\n"
629 				+
630 				//
631 				// expression/term comparison
632 				//
633 				"'=\\='(X,Y):- not expression_equality(X,Y). \n"
634 				+ "'\\=='(X,Y):- not term_equality(X,Y).\n"
635 				+ "'@>='(X,Y):- not term_less_than(X,Y).\n"
636 				+ "'@=<'(X,Y):- not term_greater_than(X,Y).\n"
637 				+
638 				//
639 				// meta-predicates
640 				//
641 				"clause(H,B) :- var(H),!, '$instantiation_error'. "
642 				+ "clause(H,B) :- number(H),!, '$type_error'(callable, H). "
643 				+ "clause(H,B) :- number(B),!, '$type_error'(callable, B). "
644 				+ "clause(H,B) :- '$find'(H,L), member((':-'(H,B)),L). "
645 				+
646 
647 				"current_predicate(PI) :- PI = Name/Arity, "
648 				+ "'$all_dynamic_predicate_indicators'(Iterator), "
649 				+ "has_next(Iterator), "
650 				+ "'$current_pred_impl'(Name, Arity, Iterator). "
651 				+
652 
653 				"has_next(Iterator) :- not('$has_next'(Iterator)), !, fail. "
654 				+ "has_next(Iterator) :- true. "
655 				+ "has_next(Iterator) :- has_next(Iterator). "
656 				+
657 				//
658 				"C -> T ; B :- C, !, T. \n"
659 				+ "C -> T ; B :- !, B. \n"
660 				+ "C -> T :- C, !, T. \n"
661 				+ "A ; B :- A. \n                                                                                          "
662 				+ "A ; B :- B. \n                                                                                          "
663 				+ "unify_with_occurs_check(X,Y) :- X=Y.\n                                                                     "
664 				+ // todo, every check now has with_occurs_check, and
665 					// with_occurs must be shut down manually..
666 				"current_op(Pri,Type,Name):-get_operators_list(L),member(op(Pri,Type,Name),L).\n                          "
667 				+ "once(X) :- X.                                                                                  "
668 				+ "repeat. \n                                                                                              "
669 				+ "repeat        :- repeat. \n                                                                             "
670 				+ "'\\+'(P):- not(P). \n                                                                                             "
671 				+ "not(G) :- call(G),!,fail. \n                                                                     "
672 				+ "not(_). \n                                                                                              "
673 				+
674 				//
675 				// All solutions predicates
676 				//
677 				"findall(Template, Goal, Instances) :- \n"
678 				+ "new_record_key(Key), \n"
679 				+ "findall_impl(Template, Goal, Key, L), \n"
680 				+ "Instances = L. \n"
681 				+ "findall_impl(Template, Goal, Key, _) :- \n"
682 				+ "call(Goal), \n"
683 				+ "copy(Template, CL), \n"
684 				+ "record(Key, CL), \n"
685 				+ "fail. \n"
686 				+ "findall_impl(_, _, Key, Instances) :- "
687 				+ "recorded(Key, Instances), "
688 				+ "erase(Key). \n"
689 				+
690 
691 				"bagof(Template, Goal, Instances) :- \n"
692 				+ "free_variables_set(Goal, Template, Set), \n"
693 				+ "Witness =.. [witness | Set], \n"
694 				+ "iterated_goal_term(Goal, G), \n"
695 				+ "findall(Witness + Template, G, S), \n"
696 				+ "'$bagof_impl_a'(Witness, S, Instances). \n"
697 				+
698 
699 				"'$bagof_impl_a'(_, [], _) :- !, fail. \n"
700 				+ "'$bagof_impl_a'(WitnessIn, BigSet, Instances) :- "
701 				+ "'$stripBagList'(WitnessIn, BigSet, Matches, RemainderSet, Variant), "
702 				+ "'$bagof_impl_b'(WitnessIn, Instances, RemainderSet, Variant, Matches). "
703 				+
704 
705 				"'$bagof_impl_b'(WitnessIn, Instances, _, Variant, Matches) :- WitnessIn = Variant, Instances = Matches. \n"
706 				+ // first success?
707 				"'$bagof_impl_b'(WitnessIn, Instances, RemainderSet, _, _) :- '$bagof_impl_a'(WitnessIn, RemainderSet, Instances). \n"
708 				+ // get the next from remainding bag
709 					//
710 					//
711 					//
712 					// "bagof(Template, Goal, Instances) :- " +
713 					// "free_variables_set(Goal, Template, Set), " +
714 					// "Witness =.. [witness | Set], " +
715 					// "iterated_goal_term(Goal, G), " +
716 					// "findall(Witness + Template, G, S), " +
717 					// "new_record_key(SetKey), " +
718 					// "record(SetKey, S), " +
719 					// "bagof_impl_x(Witness, SetKey, Instances). " +
720 					//
721 					// "bagof_impl_x(_, SetKey, _) :- " +
722 					// "recorded(SetKey, []), " +
723 					// "!, " +
724 					// "fail. \n" +
725 					// "bagof_impl_x(Witness, SetKey, Instances) :- " +
726 					// "recorded(SetKey, List), " +
727 					// "split_list(Witness, List, Instances, Rest), " +
728 					// "erase(SetKey), " +
729 					// "record(SetKey, Rest). \n" +
730 					// "bagof_impl_x(Witness, SetKey, Instances) :- bagof_impl_x(Witness, SetKey, Instances). "
731 					// +
732 					//
733 					// "split_list(Witness, [WW + TT | List], [TT | Instances], Rest) :- variant2(Witness, WW), !, split_list(Witness, List, Instances, Rest). "
734 					// +
735 					// "split_list(Witness, [H | List], Instances, [H | Rest]) :- split_list(Witness, List, Instances, Rest). "
736 					// +
737 					// "split_list(_, [], [], []). " +
738 					//
739 				"setof(Template, Goal, Instances) :- \n"
740 				+ "bagof(Template, Goal, List), \n"
741 				+ "quicksort(List, '@<', OrderedList), \n"
742 				+ "no_duplicates(OrderedList, Instances). \n"
743 				+
744 
745 				// "free_variables_set(T, V, FV) :- \n" +
746 				// "variable_set(T, VST), \n" +
747 				// "existential_variables(T, EVST), \n" +
748 				// "variable_set(V, VSV), \n" +
749 				// "list_remove(VST, EVST, V1), " +
750 				// "list_remove(V1, VSV, V2), " +
751 				// "FV = V2. \n" +
752 				//
753 				// "list_remove([],L2,[]). \n                                                                                    "
754 				// +
755 				// "list_remove([E|T1], L2, L3):- member(E, L2), !, list_remove(T1,L2,L3). \n                                                         "
756 				// +
757 				// "list_remove([E|T1], L2, [E|T3]):- list_remove(T1,L2,T3). \n                                                         "
758 				// +
759 				//
760 				"free_variables_set(Term, WithRespectTo, Set) :- \n"
761 				+ "variable_set(Term, VS), \n"
762 				+ "variable_set(WithRespectTo, VS1), \n"
763 				+ "existential_variables(Term, EVS1), \n"
764 				+ "'$list_diff'(VS, VS1, T), \n"
765 				+ "'$list_diff'(T, EVS1, T2), \n"
766 				+ "Set =T2. \n"
767 				+
768 
769 				"existential_variables(Term, []) :- var(Term), !. \n"
770 				+ "existential_variables(Term, []) :- atomic(Term), !. \n"
771 				+ "existential_variables(V ^ G, EVS) :- variable_set(V, VS), \n"
772 				+ "existential_variables(G, ExistentialVars), \n"
773 				+ "append(VS, ExistentialVars, EVS). \n"
774 				+ "existential_variables(_, []). \n"
775 				+
776 
777 				"iterated_goal_term(_ ^ SubGoal, Goal) :- iterated_goal_term(SubGoal, Goal). \n"
778 				+ "iterated_goal_term(G, G). \n"
779 				+
780 
781 				// intersect not tested
782 				"intersect([H|A],B,[H|C]) :- member(H,B), !, intersect(A,B,C). "
783 				+ "intersect([H|T],B,C) :- intersect(T,B,C). "
784 				+ "intersect([],[],[]). "
785 				+
786 
787 				"diff(A,B,C) :- diff_impl(A,B,A2,C). "
788 				+ "diff_impl([H|A],B,A2,C) :- member(H,B), !, diff_impl(A,B,A2,C). "
789 				+ "diff_impl([H|A],B,A2,[H|C]) :- diff_impl(A,B,A2,C). "
790 				+ "diff_impl([],[H|B],A2,C) :- member(H,A2), !, diff_impl([],B,A2,C). "
791 				+ "diff_impl([],[H|B],A2,[H|C]) :- diff_impl([],B,A2,C). "
792 				+ "diff_impl([],[],[],[]). "
793 				+
794 
795 				"no_duplicates([], []). \n"
796 				+ "no_duplicates([H | T], L) :- member(H, T), !, no_duplicates(T, L). \n"
797 				+ "no_duplicates([H | T], [H | L]) :- no_duplicates(T, L). \n"
798 				+
799 				//
800 				// theory management predicates
801 				//
802 				"retract(Rule) :- Rule = ':-'(Head, Body), !, clause(Head, Body), '$retract'(Rule). \n"
803 				+ "retract(Fact) :- clause(Fact, true), '$retract'(Fact). \n"
804 				+
805 
806 				"retractall(Head) :- findall(Head, clause(Head, _), L), '$retract_clause_list'(L), !. \n"
807 				+ "'$retract_clause_list'([]). \n"
808 				+ "'$retract_clause_list'([E | T]) :- !, '$retract'(E), '$retract_clause_list'(T). \n"
809 				+
810 				//
811 				// auxiliary predicates
812 				//
813 				"member(E,[E|_]). \n                                                                                     "
814 				+ "member(E,[_|L]):- member(E,L). \n                                                                       " + "length(L, S) :- number(S), S >= 0, !, lengthN(L, S), !. \n"
815 				+ "length(L, S) :- var(S), lengthX(L, S). \n" + "lengthN([],0). \n" + "lengthN(_, N) :- nonvar(N), N < 0, !, fail. \n" + "lengthN([_|L], N) :- lengthN(L,M), N is M + 1. \n"
816 				+ "lengthX([],0). \n" + "lengthX([_|L], N) :- lengthX(L,M), N is M + 1. \n"
817 				+ "append([],L2,L2). \n                                                                                    "
818 				+ "append([E|T1],L2,[E|T2]):- append(T1,L2,T2). \n                                                         "
819 				+ "reverse(L1,L2):- reverse0(L1,[],L2). \n                                                                 "
820 				+ "reverse0([],Acc,Acc). \n                                                                                "
821 				+ "reverse0([H|T],Acc,Y):- reverse0(T,[H|Acc],Y). \n                                                       "
822 				+ "delete(E,[],[]). \n                                                                                     "
823 				+ "delete2(E,[E|T],L):- !,delete(E,T,L). \n                                                                 "
824 				+ "delete(E,[H|T],[H|L]):- delete2(E,T,L). \n                                                               "
825 				+ "element(1,[E|L],E):- !. \n                                                                              "
826 				+ "element(N,_,_):- N < 0, !, fail. \n                                                                     "
827 				+ "element(N,[_|L],E):- M is N - 1,element(M,L,E). \n                                                      " +
828 
829 				"quicksort([],Pred,[]).                             \n" + "quicksort([X|Tail],Pred,Sorted):-                  \n" + "   split(X,Tail,Pred,Small,Big),                   \n"
830 				+ "   quicksort(Small,Pred,SortedSmall),              \n" + "   quicksort(Big,Pred,SortedBig),                  \n" + "   append(SortedSmall,[X|SortedBig],Sorted).       \n"
831 				+ "split(_,[],_,[],[]).                               \n" + "split(X,[Y|Tail],Pred,Small,[Y|Big]):-             \n" + "   Predicate =..[Pred,X,Y],                        \n"
832 				+ "   call(Predicate),!,                              \n" + "   split(X,Tail,Pred,Small,Big).                   \n" + "split(X,[Y|Tail],Pred,[Y|Small],Big):-             \n"
833 				+ "   split(X,Tail,Pred,Small,Big).                   \n";
834 	}
835 
836 	// Internal Java predicates which are part of the bagof/3 and setof/3
837 	// algorithm
838 
839 	public boolean $has_next_1(BindingsTable bt, IteratorAsTerm iterator) {
840 		return iterator.hasNext();
841 	}
842 
843 	public boolean $all_dynamic_predicate_indicators_1(BindingsTable bt, Term iterator) throws PrologException {
844 		if (iterator instanceof Var) {
845 			Term iteratorTerm = new IteratorAsTerm(engine.dynamicPredicateIndicators());
846 			return bt.unify(iterator, iteratorTerm);
847 		}
848 		if (iterator instanceof IteratorAsTerm)
849 			return ((IteratorAsTerm) iterator).hasNext();
850 		throw new PrologException("$all_dynamic_predicate_indicators has a bug. contact ivar.");
851 	}
852 
853 	public boolean $current_pred_impl_3(BindingsTable bt, Term name, Term arity, IteratorAsTerm allDynamicPIs) {
854 		String nextDynamicPI = (String) allDynamicPIs.next();
855 		String[] pred = nextDynamicPI.split("/");
856 		if (!bt.unify(name, new StructAtom(pred[0])))
857 			return false;
858 		return bt.unify(arity, new Int(pred[1]));
859 	}
860 
861 	// "variable_set(T, [T]) :- var(T), !. \n" +
862 	// "variable_set(T, []) :- atomic(T), !. \n" +
863 	// "variable_set(T, List) :- T =.. [_|Args], variable_set_arguments(Args, List). \n"
864 	// +
865 	//
866 	// "variable_set_arguments([], []). \n" +
867 	// "variable_set_arguments([H|T], List) :- " +
868 	// "variable_set(H, SubList1), " +
869 	// "variable_set_arguments(T, SubList2), " +
870 	// "append(SubList1, SubList2, List). \n" +
871 	public boolean variable_set_2(BindingsTable bt, Term withVars, Term varList) {
872 		if (withVars instanceof Number || withVars instanceof StructAtom)
873 			return bt.unify(Term.emptyList, varList);
874 		LinkedList l = new LinkedList();
875 		if (withVars instanceof Var)
876 			l.add(withVars);
877 		else
878 			l.addAll(Arrays.asList(((Struct) withVars).getVarList()));
879 		l.add(Term.emptyList);
880 		return bt.unify(bt.createStructList(l), varList);
881 	}
882 
883 	// internal variable / data base map
884 	private HashMap map = new HashMap();
885 
886 	public boolean new_record_key_1(BindingsTable bt, Var key) {
887 		Long newKey = new Long(key.hashCode());
888 		return bt.unify(key, newKey);
889 	}
890 
891 	public boolean record_2(BindingsTable bt, Number key, Term unit) {
892 		LinkedList appendStorage = (LinkedList) map.get(key.toString());
893 		if (appendStorage == null)
894 			appendStorage = new LinkedList();
895 		appendStorage.add(BindingsTable.unWrap(unit));
896 		map.put(key.toString(), appendStorage);
897 		return true;
898 	}
899 
900 	public boolean erase_2(BindingsTable bt, Number key, Term list) {
901 		LinkedList appendStorage = (LinkedList) map.remove(key.toString());
902 		if (appendStorage == null)
903 			return bt.unify(list, Term.emptyList);
904 		appendStorage.add(Term.emptyList);
905 		return bt.unify(list, bt.createStructList(appendStorage));
906 	}
907 
908 	public boolean recorded_2(BindingsTable bt, Number key, Term list) {
909 		LinkedList appendStorage = (LinkedList) map.get(key.toString());
910 		if (appendStorage == null)
911 			return bt.unify(list, Term.emptyList);
912 		appendStorage.add(Term.emptyList);
913 		return bt.unify(list, bt.createStructList(appendStorage));
914 	}
915 
916 	public boolean erase_1(BindingsTable bt, Number key) {
917 		map.remove(key.toString());
918 		return true;
919 	}
920 
921 	// internal variable / data base map
922 
923 	public boolean $stripBagList_5(BindingsTable bt, Struct witnessIn, Struct a_and_bSet, Term aSet, Term bSet, Term variant) throws PrologException {
924 		LinkedList results = new LinkedList();
925 		LinkedList remains = new LinkedList();
926 
927 		int wrapID = witnessIn instanceof WrapStruct ? ((WrapStruct) witnessIn).context : bt.getUniqueExecutionCtxID();
928 		witnessIn = (Struct) BindingsTable.wrapWithID(bt.variant(witnessIn), wrapID);
929 
930 		// 1a. get a variant of the first witness+template from the inputList
931 		Iterator it = bt.structListIterator(a_and_bSet, true);
932 		Struct w_t = (Struct) it.next();
933 
934 		// 1b. the witness branch of the first result will be used to match
935 		// other results with identical witnesses
936 		Struct witness1 = (Struct) variant(witnessIn, w_t.getArg(0));
937 		bt.unify(w_t.getArg(0), witness1);
938 
939 		// 1c. unify first witness with Variant output and add to result
940 		bt.unify(variant, witness1);
941 		results.add(BindingsTable.unWrap(w_t.getArg(1)));
942 
943 		// 2. iterate the rest of the input list and
944 		// put all matching witnesses from bigset into result and the rest in
945 		// remainder
946 		while (it.hasNext()) {
947 			w_t = (Struct) it.next();
948 			Struct witness2 = (Struct) variant(witness1, w_t.getArg(0));
949 			if (term_equality_2(null, witness1, witness2)) {
950 				bt.unify(w_t.getArg(0), witness1);
951 				results.add(BindingsTable.unWrap(w_t.getArg(1)));
952 			} else {
953 				remains.add(BindingsTable.unWrap(w_t));
954 			}
955 		}
956 
957 		// 3. unify the results lists and remains list with aSet and bSet
958 		if (remains.isEmpty()) {
959 			bt.unify(bSet, Term.emptyList);
960 		} else {
961 			remains.add(Term.emptyList);
962 			bt.unify(bSet, BindingsTable.wrapWithID(Parser.createStructList(remains), wrapID));
963 		}
964 		results.add(Term.emptyList);
965 		return bt.unify(aSet, BindingsTable.wrapWithID(Parser.createStructList(results), wrapID));
966 	}
967 
968 	// todo not finished.. Just a hack to see if things roughly work
969 	// todo bug in the bag_of predicate..
970 	// todo I think the fault lies with variant..
971 	// todo I think variant constructs a Struct with Variables from various
972 	// contexts..
973 	private static Term variant(Term former, Term latter) {
974 		if (BasicLibrary.atomic_1(null, latter))
975 			return latter;
976 		if (latter instanceof Var) {
977 			if (former instanceof Var)
978 				return former;
979 			throw new RuntimeException("h�");
980 		}
981 		if (latter instanceof Struct) {
982 			if (former instanceof Var)
983 				return latter;
984 			if (!(former instanceof Struct))
985 				throw new RuntimeException("h�2");
986 			final Struct sFormer = (Struct) former;
987 			final Struct sLatter = (Struct) latter;
988 			if (sFormer.predicateIndicator != sLatter.predicateIndicator)
989 				throw new RuntimeException("h�3");
990 			Term[] newChildren = new Term[sLatter.arity];
991 			for (int i = 0; i < sFormer.arity; i++)
992 				newChildren[i] = variant(BindingsTable.unWrap(sFormer.getArg(i)), BindingsTable.unWrap(sLatter.getArg(i))); // todo
993 																															// this
994 																															// is
995 																															// just
996 																															// a
997 																															// hack.
998 																															// I
999 																															// don't
1000 																															// think
1001 																															// it
1002 																															// works
1003 																															// at
1004 																															// all,
1005 																															// this
1006 																															// needs
1007 																															// to
1008 																															// be
1009 																															// fixed
1010 			return BindingsTable.wrapWithID(new Struct(sLatter.name, newChildren), ((WrapStruct) former).context); // todo
1011 																													// bug
1012 																													// in
1013 																													// context
1014 																													// setting
1015 																													// here..
1016 		}
1017 		throw new RuntimeException("h�4");
1018 	}
1019 
1020 	public boolean $list_diff_3(BindingsTable bt, Struct main, Struct retract, Var diff) throws PrologException {
1021 		if (retract.equals(Term.emptyList))
1022 			return bt.unify(diff, main);
1023 		LinkedList resultList = new LinkedList();
1024 		outer: for (Iterator it = bt.structListIterator(main, true); it.hasNext();) {
1025 			Term child = (Term) it.next();
1026 			for (Iterator it2 = bt.structListIterator(retract, true); it2.hasNext();) {
1027 				Term child2 = (Term) it2.next();
1028 				if (BasicLibrary.term_equality_2(null, child, child2))
1029 					continue outer;
1030 			}
1031 			resultList.add(child);
1032 		}
1033 		if (resultList.isEmpty())
1034 			return bt.unify(diff, Term.emptyList);
1035 		resultList.add(Term.emptyList);
1036 		return bt.unify(diff, bt.createStructList(resultList));
1037 	}
1038 
1039 	/**
1040 	 * Defines a map for synonyms for primitives. String primitive name =
1041 	 * String[]{synonym name, another synonym name, ..}.
1042 	 */
1043 	public String[] getSynonym(String primitive) {
1044 		if (primitive.equals("expression_plus"))
1045 			return new String[] { "+" };
1046 		if (primitive.equals("expression_minus"))
1047 			return new String[] { "-" };
1048 		if (primitive.equals("expression_multiply"))
1049 			return new String[] { "*" };
1050 		if (primitive.equals("expression_div"))
1051 			return new String[] { "/" };
1052 		if (primitive.equals("expression_pow"))
1053 			return new String[] { "**" };
1054 		if (primitive.equals("expression_bitwise_shift_right"))
1055 			return new String[] { ">>" };
1056 		if (primitive.equals("expression_bitwise_shift_left"))
1057 			return new String[] { "<<" };
1058 		if (primitive.equals("expression_bitwise_and"))
1059 			return new String[] { "/\\" };
1060 		if (primitive.equals("expression_bitwise_or"))
1061 			return new String[] { "\\/" };
1062 		if (primitive.equals("expression_integer_div"))
1063 			return new String[] { "//" };
1064 		if (primitive.equals("expression_bitwise_not"))
1065 			return new String[] { "\\" };
1066 		if (primitive.equals("$functor"))
1067 			return new String[] { "functor" };
1068 		if (primitive.equals("$arg"))
1069 			return new String[] { "arg" };
1070 		if (primitive.equals("$tofromlist"))
1071 			return new String[] { "=.." };
1072 		if (primitive.equals("expression_equality"))
1073 			return new String[] { "=:=" };
1074 		if (primitive.equals("expression_greater_than"))
1075 			return new String[] { ">" };
1076 		if (primitive.equals("expression_less_than"))
1077 			return new String[] { "<" };
1078 		if (primitive.equals("expression_greater_or_equal_than"))
1079 			return new String[] { ">=" };
1080 		if (primitive.equals("expression_less_or_equal_than"))
1081 			return new String[] { "=<" };
1082 		if (primitive.equals("term_equality"))
1083 			return new String[] { "==" };
1084 		if (primitive.equals("term_greater_than"))
1085 			return new String[] { "@>" };
1086 		if (primitive.equals("term_less_than"))
1087 			return new String[] { "@<" };
1088 		return null;
1089 	}
1090 
1091 }