View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi
4    * %%
5    * Copyright (C) 2019 Prolobjectlink Project
6    * %%
7    * Permission is hereby granted, free of charge, to any person obtaining a copy
8    * of this software and associated documentation files (the "Software"), to deal
9    * in the Software without restriction, including without limitation the rights
10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   * copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   * 
14   * The above copyright notice and this permission notice shall be included in
15   * all copies or substantial portions of the Software.
16   * 
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   * THE SOFTWARE.
24   * #L%
25   */
26  package io.github.prolobjectlink.prolog;
27  
28  import java.io.Reader;
29  import java.io.Writer;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  /**
35   * A PrologEngine instance is used in order to interact with the concrete prolog
36   * engine. Is used for interact with the Prolog database or to invoke a built-in
37   * predicate. It is initialized using a provider instance and calling new engine
38   * {@link PrologProvider#newEngine()}
39   * 
40   * <pre>
41   * PrologProvider provider = Prolog.getProvider(Some_PrologProvider_Impl.class);
42   * PrologEngine engine = provider.newEngine();
43   * </pre>
44   * 
45   * The {@link PrologProvider#newEngine(String)} method is used if the specified
46   * file to consult is provided.
47   * 
48   * The prolog engine have a life cycle on the user application. After create an
49   * instance we can consult any file with prolog programs using
50   * {@link #consult(Reader)} or {@link #consult(String)}. If another prolog file
51   * need to be include in main memory we can use {@link #include(Reader)} or
52   * {@link #include(String)}. We can include so much files as we needed.
53   * 
54   * <pre>
55   * engine.consult("family.pl");
56   * engine.include("company.pl");
57   * engine.include("zoo.pl");
58   * </pre>
59   * 
60   * To check if the given goal have solution using the resolution engine
61   * mechanism we can use {@link #contains(String)} or
62   * {@link #contains(PrologTerm, PrologTerm...)}. Both methods returning true if
63   * the given goal have solution or false in other case.
64   * 
65   * <pre>
66   * boolean b = engine.clause("parent( pam, bob)");
67   * </pre>
68   * 
69   * To check if there are a clause in the prolog engine we can use
70   * {@link #clause(String)} or {@link #clause(PrologTerm, PrologTerm...)}. This
71   * methods is based on the prolog engine built-in clause/2 that check if in the
72   * currents predicates exist a clause definition that match with the given
73   * clause. This methods return true if the given clause is defined in the prolog
74   * engine or false in other case. The following cases return true.
75   * 
76   * <pre>
77   * engine.assertz("parent( pam, bob)");
78   * boolean b = engine.clause("parent( X, Y);
79   * boolean t = engine.clause("parent( pam, bob)")
80   * </pre>
81   * 
82   * Java Prolog Interface have an special interface to query to prolog engine
83   * about some specific clauses an operate over solution set. {@link PrologQuery}
84   * is the mechanism to query the prolog database loaded in prolog engine. The
85   * way to create a new prolog query is invoking
86   * {@link PrologEngine#query(String)},
87   * {@link PrologEngine#query(PrologTerm, PrologTerm...)} or
88   * {@link PrologEngine#query(PrologTerm[])}. This interface have several methods
89   * to obtain one, at least N or all query results.
90   * 
91   * <pre>
92   * PrologEngine engine = provider.newEngine("zoo.pl");
93   * PrologVariable x = provider.newVariable("X", 0);
94   * PrologQuery query = engine.query(provider.newStructure("dark", x));
95   * List&lt;Object&gt; solution = query.oneResult();
96   * for (int i = 0; i &lt; solution.size(); i++) {
97   * 	System.out.println(solution.get(i));
98   * }
99   * </pre>
100  * 
101  * Java Prolog Interface have shortcuts methods to obtain queries result from
102  * the engine. The shortcuts methods to obtain one result are
103  * {@link PrologEngine#queryOne(PrologTerm)},
104  * {@link PrologEngine#queryOne(String)},
105  * {@link PrologEngine#queryOne(PrologTerm, PrologTerm...)}. This methods are
106  * equivalent to call {@code PrologEngine.query(...).oneVariablesResult()}.
107  * 
108  * queryN
109  * 
110  * The shortcuts methods to obtain all results are
111  * {@link PrologEngine#queryAll(PrologTerm)},
112  * {@link PrologEngine#queryAll(String)},
113  * {@link PrologEngine#queryAll(PrologTerm, PrologTerm...)}. This methods are
114  * equivalent to call {@code PrologEngine.query(...).allVariablesResult()}.
115  * 
116  * After create an empty prolog engine and load any prolog program, we can
117  * modify the program/database. For this propose we have the methods
118  * {@link #asserta(String)}, {@link #asserta(PrologTerm,PrologTerm...)} or
119  * {@link #assertz(String)}, {@link #assertz(PrologTerm,PrologTerm...)}. The
120  * asserta methods are used when we need store a prolog clause term on top in
121  * the clause family and assertz by other hand, are when we need store a prolog
122  * clause term on the tail in the clause family.
123  * 
124  * <pre>
125  * engine.asserta("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
126  * engine.asserta("parent( pat, jim)");
127  * </pre>
128  * 
129  * <pre>
130  * engine.assertz("parent( pat, jim)");
131  * engine.assertz("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
132  * </pre>
133  * 
134  * For remove clauses in the main memory program if the clause exist can be used
135  * {@link #retract(String)} or {@link #retract(PrologTerm, PrologTerm...)}. Both
136  * methods after build internal clause representation find the specific clause
137  * and if this exist remove it. By other hand if we need remove all clause
138  * family we can use {@link #abolish(String, int)}. This method remove all
139  * predicates that match with the predicate indicator (PI) formed by the
140  * concatenation of the given string functor and integer arity separated by
141  * slash (functor/arity).
142  * 
143  * <pre>
144  * engine.retract("parent( tom, bob)");
145  * </pre>
146  * 
147  * <pre>
148  * engine.abolish("parent", 2);
149  * </pre>
150  * 
151  * All change that take place in the current engine can save to some specific
152  * file using {@link #persist(String)} or {@link #persist(Writer)}.
153  * 
154  * <pre>
155  * engine.assertz(provider.newStructure("parent", pam, bob));
156  * engine.assertz(provider.newStructure("parent", tom, bob));
157  * engine.assertz(provider.newStructure("parent", tom, liz));
158  * engine.assertz(provider.newStructure("parent", bob, ann));
159  * engine.assertz(provider.newStructure("parent", bob, pat));
160  * engine.assertz(provider.newStructure("parent", pat, jim));
161  * 
162  * engine.persist("family.pl");
163  * </pre>
164  * 
165  * By the last {@link #dispose()} clear program in main memory. Release all
166  * resources used and prepare the current engine for realize some new task.
167  * 
168  * <pre>
169  * engine.dispose();
170  * </pre>
171  * 
172  * An additional capability of the prolog engine is the {@link Iterable}
173  * implementation. This allow to prolog engine iterate over all user defined
174  * clauses using a for-each loop or iterator loop.
175  * 
176  * <pre>
177  * for (PrologClause c : engine) {
178  * 	// do something
179  * }
180  * </pre>
181  * 
182  * <pre>
183  * Iterator&lt;?&gt; i = engine.iterator();
184  * while (i.hasNext()) {
185  * 	// do something
186  * }
187  * </pre>
188  * 
189  * The shortcuts methods to obtain N results are
190  * 
191  * {@code PrologEngine.queryN(Class)}, {@code PrologEngine.queryN(Object)},
192  * {@code PrologEngine.queryN(PrologTerm)}, {@code PrologEngine.queryN(String)},
193  * {@code PrologEngine.queryN(Class, Class...)},
194  * {@code PrologEngine.queryN(Object, Object...)},
195  * {@code PrologEngine.queryN(PrologTerm, PrologTerm...)}.
196  * 
197  * This methods are equivalent to call
198  * {@code PrologEngine.query(...).nVariablesResult()}.
199  *
200  * Java Prolog Interface have shortcuts methods to obtain queries result from
201  * the engine. The shortcuts methods to obtain one result are
202  * {@code PrologEngine.queryOne(Class)}, {@code PrologEngine.queryOne(Object)},
203  * {@code PrologEngine.queryOne(PrologTerm)},
204  * {@code PrologEngine.queryOne(String)},
205  * {@code PrologEngine.queryOne(Class, Class...)},
206  * {@code PrologEngine.queryOne(Object, Object...)},
207  * {@code PrologEngine.queryOne(PrologTerm, PrologTerm...)}. This methods are
208  * equivalent to call {@code PrologEngine.query(...).oneVariablesResult()}.
209  * 
210  * The shortcuts methods to obtain N results are
211  * {@code PrologEngine.queryN(Class)}, {@code PrologEngine.queryN(Object)},
212  * {@code PrologEngine.queryN(PrologTerm)}, {@code PrologEngine.queryN(String)},
213  * {@code PrologEngine.queryN(Class, Class...)},
214  * {@code PrologEngine.queryN(Object, Object...)},
215  * {@code PrologEngine.queryN(PrologTerm, PrologTerm...)}. This methods are
216  * equivalent to call {@code PrologEngine.query(...).nVariablesResult()}.
217  * 
218  * The shortcuts methods to obtain all results are
219  * {@code PrologEngine.queryAll(Class)}, {@code PrologEngine.queryAll(Object)},
220  * {@code PrologEngine.queryAll(PrologTerm)},
221  * {@code PrologEngine.queryAll(String)},
222  * {@code PrologEngine.queryAll(Class, Class...)},
223  * {@code PrologEngine.queryAll(Object, Object...)},
224  * {@code PrologEngine.queryAll(PrologTerm, PrologTerm...)}. This methods are
225  * equivalent to call {@code PrologEngine.query(...).allVariablesResult()}.
226  * 
227  * 
228  * 
229  * 
230  * @author Jose Zalacain
231  * @since 1.0
232  */
233 public interface PrologEngine extends Iterable<PrologClause> {
234 
235 	/**
236 	 * Check if the host operating system name refer to Windows OS.
237 	 * 
238 	 * @return true if the host operating system name refer to Windows OS and false
239 	 *         otherwise.
240 	 * @since 1.0
241 	 */
242 	public boolean runOnWindows();
243 
244 	/**
245 	 * Check if the host operating system name refer to Linux OS.
246 	 * 
247 	 * @return true if the host operating system name refer to Linux OS and false
248 	 *         otherwise.
249 	 * @since 1.0
250 	 */
251 	public boolean runOnLinux();
252 
253 	/**
254 	 * Check if the host operating system name refer to OsX.
255 	 * 
256 	 * @return true if the host operating system name refer to OsX and false
257 	 *         otherwise.
258 	 * @since 1.0
259 	 */
260 	public boolean runOnOSX();
261 
262 	/**
263 	 * Return the host operating system name. Is a shortcut to
264 	 * {@code System.getProperty("os.name");}.
265 	 * 
266 	 * @return the host operating system name.
267 	 * @since 1.0
268 	 */
269 	public String getOSName();
270 
271 	/**
272 	 * Return the host operating system version. Is a shortcut to
273 	 * {@code System.getProperty("os.version");}.
274 	 * 
275 	 * @return the host operating system version.
276 	 * @since 1.1
277 	 */
278 	public String getOSVersion();
279 
280 	/**
281 	 * Return the host operating system architecture. Is a shortcut to
282 	 * {@code System.getProperty("os.arch");}.
283 	 * 
284 	 * @return the host operating system architecture.
285 	 * @since 1.0
286 	 */
287 	public String getOSArch();
288 
289 	/**
290 	 * Test the correct integration between under-laying prolog engine and top level
291 	 * interface. Return a string list with the needed conditions to link the
292 	 * under-laying prolog engine. if the under-laying prolog engine is linked the
293 	 * returned set only contain the "OK" string indicating a correct integration.
294 	 * 
295 	 * @return string list with only "OK" string if the prolog engine integration is
296 	 *         correct or the conditions string list needed to link the prolog
297 	 *         engine.
298 	 * @since 1.0
299 	 */
300 	public List<String> verify();
301 
302 	/**
303 	 * Consult a file specified by the string path loading an parsing the prolog
304 	 * program. If the prolog program contains syntax error a syntax exception
305 	 * should be raised.
306 	 * 
307 	 * @param path location of the file to be consulted
308 	 * @since 1.0
309 	 */
310 	public void consult(String path);
311 
312 	/**
313 	 * Consult a prolog program from specified reader parsing the prolog program and
314 	 * put this program into prolog engine. If the prolog program contains syntax
315 	 * error a syntax exception should be raised.
316 	 * 
317 	 * @param reader The reader to read the prolog program from character streams
318 	 * @since 1.0
319 	 */
320 	public void consult(Reader reader);
321 
322 	/**
323 	 * Consult a file specified by the string path loading an parsing the prolog
324 	 * program and include the loaded program into current engine. If the prolog
325 	 * program contains syntax error a syntax exception should be raised.
326 	 * 
327 	 * @param path location of the file to be included
328 	 * @since 1.0
329 	 */
330 	public void include(String path);
331 
332 	/**
333 	 * Consult a prolog program from specified reader parsing the prolog program and
334 	 * include this program into current prolog engine. If the prolog program
335 	 * contains syntax error a syntax exception should be raised.
336 	 * 
337 	 * @param reader The reader to read the prolog program from character streams
338 	 * @since 1.0
339 	 */
340 	public void include(Reader reader);
341 
342 	/**
343 	 * Save the prolog program present in the current engine to some specific file
344 	 * specified by string path.
345 	 * 
346 	 * @param path location of the file.
347 	 * @since 1.0
348 	 */
349 	public void persist(String path);
350 
351 	/**
352 	 * Write the prolog clauses in program present in the current engine using the
353 	 * given driver.
354 	 * 
355 	 * @param writer writer for write prolog clauses in the program.
356 	 * @since 1.0
357 	 */
358 	public void persist(Writer writer);
359 
360 	/**
361 	 * Remove all predicates that match with the predicate indicator (PI) formed by
362 	 * the concatenation of the given string functor and integer arity separated by
363 	 * slash (functor/arity).
364 	 * 
365 	 * <pre>
366 	 * engine.abolish(&quot;parent&quot;, 2); // remove all parent/2 predicates
367 	 * </pre>
368 	 * 
369 	 * @param functor string functor that identify the predicate family to be
370 	 *                remove.
371 	 * @param arity   argument number that identify the predicate family to be
372 	 *                remove.
373 	 * @since 1.0
374 	 */
375 	public void abolish(String functor, int arity);
376 
377 	/**
378 	 * Parse the string creating internal prolog clause and add the clause in the
379 	 * main memory program if the clause non exist. If the clause exist, will not
380 	 * overwritten and the clause will not added. The string have prolog fact or
381 	 * rule syntax. The added clause will be the first clause for a clause lot with
382 	 * the same predicate indicator (PI).
383 	 * 
384 	 * <pre>
385 	 * engine.asserta(&quot;grandparent(X,Z):-parent(X,Y),parent(Y,Z)&quot;);
386 	 * engine.asserta(&quot;parent( pat, jim)&quot;);
387 	 * engine.asserta(&quot;parent( bob, pat)&quot;);
388 	 * engine.asserta(&quot;parent( bob, ann)&quot;);
389 	 * engine.asserta(&quot;parent( tom, liz)&quot;);
390 	 * engine.asserta(&quot;parent( tom, bob)&quot;);
391 	 * engine.asserta(&quot;parent( pam, bob)&quot;);
392 	 * </pre>
393 	 * 
394 	 * @param stringClause - string for create internal prolog clause
395 	 * @since 1.0
396 	 */
397 	public void asserta(String stringClause);
398 
399 	/**
400 	 * Create internal prolog clause and add the clause in the main memory program
401 	 * if the clause non exist. If the clause exist, will not overwritten and the
402 	 * clause will not added. The added clause will be the first clause for a clause
403 	 * lot with the same predicate indicator (PI).
404 	 * 
405 	 * @param term term to be added
406 	 * @since 1.1
407 	 */
408 	public void asserta(PrologTerm term);
409 
410 	/**
411 	 * Add a rule specified by the rule head and rule body if the specified rule
412 	 * clause non exist. If the rule clause exist, will not overwritten and the
413 	 * clause will not added. The head term is the first argument and the body is
414 	 * constituted by the terms array followed of the rule head. If the body array
415 	 * is empty the clause will be considered like fact specified by head only. The
416 	 * added clause will be the first clause for a clause lot with the same
417 	 * predicate indicator (PI). The shared variables in the clause are declared
418 	 * once and use for build the terms that conform the clause to be added
419 	 * 
420 	 * <pre>
421 	 * String parent = &quot;parent&quot;;
422 	 * String grandparent = &quot;grandparent&quot;;
423 	 * 
424 	 * PrologAtom pam = provider.newAtom(&quot;pam&quot;);
425 	 * PrologAtom bob = provider.newAtom(&quot;bob&quot;);
426 	 * PrologAtom ann = provider.newAtom(&quot;ann&quot;);
427 	 * PrologAtom pat = provider.newAtom(&quot;pat&quot;);
428 	 * 
429 	 * PrologVariable x = provider.newVariable(&quot;X&quot;);
430 	 * PrologVariable y = provider.newVariable(&quot;Y&quot;);
431 	 * PrologVariable z = provider.newVariable(&quot;Z&quot;);
432 	 * 
433 	 * engine.asserta(provider.newStructure(grandparent, x, z), provider.newStructure(parent, x, y),
434 	 * 		provider.newStructure(parent, y, z));
435 	 * engine.asserta(provider.newStructure(parent, pat, jim));
436 	 * engine.asserta(provider.newStructure(parent, bob, pat));
437 	 * engine.asserta(provider.newStructure(parent, bob, ann));
438 	 * engine.asserta(provider.newStructure(parent, tom, liz));
439 	 * engine.asserta(provider.newStructure(parent, tom, bob));
440 	 * engine.asserta(provider.newStructure(parent, pam, bob));
441 	 * </pre>
442 	 * 
443 	 * @param head head of rule
444 	 * @param body array of terms that compound the body of the rule
445 	 * @since 1.0
446 	 */
447 	public void asserta(PrologTerm head, PrologTerm... body);
448 
449 	/**
450 	 * Parse the string creating internal prolog clause and add the clause in the
451 	 * main memory program if the clause non exist. If the clause exist, will not
452 	 * overwritten and the clause will not added. The string have prolog fact or
453 	 * rule syntax. The added clause will be the last clause for a clause lot with
454 	 * the same predicate indicator (PI).
455 	 * 
456 	 * <pre>
457 	 * engine.assertz(&quot;parent( pam, bob)&quot;);
458 	 * engine.assertz(&quot;parent( tom, bob)&quot;);
459 	 * engine.assertz(&quot;parent( tom, liz)&quot;);
460 	 * engine.assertz(&quot;parent( bob, ann)&quot;);
461 	 * engine.assertz(&quot;parent( bob, pat)&quot;);
462 	 * engine.assertz(&quot;parent( pat, jim)&quot;);
463 	 * engine.assertz(&quot;grandparent(X,Z):-parent(X,Y),parent(Y,Z)&quot;);
464 	 * </pre>
465 	 * 
466 	 * @param stringClause string clause to be added
467 	 * @since 1.0
468 	 */
469 	public void assertz(String stringClause);
470 
471 	/**
472 	 * Create internal prolog clause and add the clause in the main memory program
473 	 * if the clause non exist. If the clause exist, will not overwritten and the
474 	 * clause will not added. The added clause will be the last clause for a clause
475 	 * lot with the same predicate indicator (PI).
476 	 * 
477 	 * @param term term to be added
478 	 * @since 1.1
479 	 */
480 	public void assertz(PrologTerm term);
481 
482 	/**
483 	 * <p>
484 	 * Add a rule specified by the rule head and rule body if the specified rule
485 	 * clause non exist. If the rule clause exist, will not overwritten and the
486 	 * clause will not added. The head term is the first argument and the body is
487 	 * constituted by the terms array followed of the rule head. If the body array
488 	 * is empty the clause will be considered like fact specified by head only. The
489 	 * added clause will be the last clause for a clause lot with the same predicate
490 	 * indicator (PI). The shared variables in the clause are declared once and use
491 	 * for build the terms that conform the clause to be added
492 	 * </p>
493 	 * 
494 	 * <pre>
495 	 * String parent = &quot;parent&quot;;
496 	 * String grandparent = &quot;grandparent&quot;;
497 	 * PrologAtom pam = provider.newAtom(&quot;pam&quot;);
498 	 * PrologAtom bob = provider.newAtom(&quot;bob&quot;);
499 	 * PrologAtom ann = provider.newAtom(&quot;ann&quot;);
500 	 * PrologAtom pat = provider.newAtom(&quot;pat&quot;);
501 	 * PrologVariable x = provider.newVariable(&quot;X&quot;);
502 	 * PrologVariable y = provider.newVariable(&quot;Y&quot;);
503 	 * PrologVariable z = provider.newVariable(&quot;Z&quot;);
504 	 * engine.assertz(provider.newStructure(parent, pam, bob));
505 	 * engine.assertz(provider.newStructure(parent, tom, bob));
506 	 * engine.assertz(provider.newStructure(parent, tom, liz));
507 	 * engine.assertz(provider.newStructure(parent, bob, ann));
508 	 * engine.assertz(provider.newStructure(parent, bob, pat));
509 	 * engine.assertz(provider.newStructure(parent, pat, jim));
510 	 * engine.assertz(provider.newStructure(grandparent, x, z), provider.newStructure(parent, x, y),
511 	 * 		provider.newStructure(parent, y, z));
512 	 * </pre>
513 	 * 
514 	 * @param head head of rule
515 	 * @param body array of terms that compound the body of the rule
516 	 * @since 1.0
517 	 */
518 	public void assertz(PrologTerm head, PrologTerm... body);
519 
520 	/**
521 	 * Parse the string creating internal prolog clause and returning true if the
522 	 * clause in the main memory program unify with the given clause. If the clause
523 	 * not exist in main memory program or exist but not unify with the given clause
524 	 * false value is returned. The string have prolog fact or rule syntax.
525 	 * 
526 	 * <pre>
527 	 * boolean b = engine.clause(&quot;parent( pam, bob)&quot;);
528 	 * </pre>
529 	 * 
530 	 * <pre>
531 	 * boolean b = engine.clause(&quot;grandparent(X,Z):-parent(X,Y),parent(Y,Z)&quot;);
532 	 * </pre>
533 	 * 
534 	 * @param stringClause string clause to be match
535 	 * @return true if the clause in the main memory program unify with the given
536 	 *         clause, false otherwise
537 	 * @since 1.0
538 	 */
539 	public boolean clause(String stringClause);
540 
541 	/**
542 	 * Find a rule specified by the rule head and rule body in main memory program
543 	 * that unify with the given clause returning true in this case.If the clause
544 	 * not exist in main memory program or exist but not unify with the given clause
545 	 * false value is returned. The shared variables in the clause are declared once
546 	 * and use for build the terms that conform the clause to be found.
547 	 * 
548 	 * @param term term to be match with some clause in main memory program
549 	 * @return true if the clause in the main memory program unify with the clause
550 	 *         equivalent to the given term, false otherwise
551 	 * @since 1.1
552 	 */
553 	public boolean clause(PrologTerm term);
554 
555 	/**
556 	 * Find a rule specified by the rule head and rule body in main memory program
557 	 * that unify with the given clause returning true in this case.If the clause
558 	 * not exist in main memory program or exist but not unify with the given clause
559 	 * false value is returned. The head term is the first argument and the body is
560 	 * constituted by the terms array followed of the rule head. If the body array
561 	 * is empty the clause will be considered like fact specified by head only. The
562 	 * shared variables in the clause are declared once and use for build the terms
563 	 * that conform the clause to be found.
564 	 * 
565 	 * <pre>
566 	 * String parent = &quot;parent&quot;;
567 	 * PrologAtom pam = provider.newAtom(&quot;pam&quot;);
568 	 * PrologAtom bob = provider.newAtom(&quot;bob&quot;);
569 	 * boolean b = engine.clause(provider.newStructure(parent, pam, bob));
570 	 * </pre>
571 	 * 
572 	 * <pre>
573 	 * String grandparent = &quot;grandparent&quot;;
574 	 * PrologVariable x = provider.newVariable(&quot;X&quot;);
575 	 * PrologVariable y = provider.newVariable(&quot;Y&quot;);
576 	 * PrologVariable z = provider.newVariable(&quot;Z&quot;);
577 	 * boolean b = engine.clause(provider.newStructure(grandparent, x, z), provider.newStructure(parent, x, y),
578 	 * 		provider.newStructure(parent, y, z));
579 	 * </pre>
580 	 * 
581 	 * @param head head of rule
582 	 * @param body array of terms that compound the body of the rule
583 	 * @return true if the clause in the main memory program unify with the given
584 	 *         clause, false otherwise
585 	 * @since 1.0
586 	 */
587 	public boolean clause(PrologTerm head, PrologTerm... body);
588 
589 	/**
590 	 * Parse the string creating internal prolog clause and remove the clause in the
591 	 * main memory program if the clause exist. The string have prolog fact or rule
592 	 * syntax.
593 	 * 
594 	 * <pre>
595 	 * engine.retract(&quot;parent( pam, bob).&quot;);
596 	 * engine.retract(&quot;parent( tom, bob).&quot;);
597 	 * engine.retract(&quot;parent( tom, liz).&quot;);
598 	 * engine.retract(&quot;parent( bob, ann).&quot;);
599 	 * engine.retract(&quot;parent( bob, pat).&quot;);
600 	 * engine.retract(&quot;parent( pat, jim).&quot;);
601 	 * engine.retract(&quot;grandparent(X,Z):-parent(X,Y),parent(Y,Z)&quot;);
602 	 * </pre>
603 	 * 
604 	 * @param stringClause string clause to be removed
605 	 * @since 1.0
606 	 */
607 	public void retract(String stringClause);
608 
609 	/**
610 	 * Remove a fact specified by the head if the specified fact clause exist. The
611 	 * shared variables in the clause are declared once and use for build the terms
612 	 * that conform the clause to be removed.
613 	 * 
614 	 * @param term fact to be removed
615 	 * @since 1.1
616 	 */
617 	public void retract(PrologTerm term);
618 
619 	/**
620 	 * Remove a rule specified by the rule head and rule body if the specified rule
621 	 * clause exist. The head term is the first argument and the body is constituted
622 	 * by the terms array followed of the rule head. If the body array is empty the
623 	 * clause will be considered like fact specified by head only. The shared
624 	 * variables in the clause are declared once and use for build the terms that
625 	 * conform the clause to be removed.
626 	 * 
627 	 * <pre>
628 	 * String parent = &quot;parent&quot;;
629 	 * String grandparent = &quot;grandparent&quot;;
630 	 * PrologAtom pam = provider.newAtom(&quot;pam&quot;);
631 	 * PrologAtom bob = provider.newAtom(&quot;bob&quot;);
632 	 * PrologAtom ann = provider.newAtom(&quot;ann&quot;);
633 	 * PrologAtom pat = provider.newAtom(&quot;pat&quot;);
634 	 * PrologVariable x = provider.newVariable(&quot;X&quot;);
635 	 * PrologVariable y = provider.newVariable(&quot;Y&quot;);
636 	 * PrologVariable z = provider.newVariable(&quot;Z&quot;);
637 	 * engine.retract(provider.newStructure(parent, pam, bob));
638 	 * engine.retract(provider.newStructure(parent, tom, bob));
639 	 * engine.retract(provider.newStructure(parent, tom, liz));
640 	 * engine.retract(provider.newStructure(parent, bob, ann));
641 	 * engine.retract(provider.newStructure(parent, bob, pat));
642 	 * engine.retract(provider.newStructure(parent, pat, jim));
643 	 * engine.retract(provider.newStructure(grandparent, x, z), provider.newStructure(parent, x, y),
644 	 * 		provider.newStructure(parent, y, z));
645 	 * </pre>
646 	 * 
647 	 * @param head head of rule
648 	 * @param body array of terms that compound the body of the rule
649 	 * @since 1.0
650 	 */
651 	public void retract(PrologTerm head, PrologTerm... body);
652 
653 	/**
654 	 * Check that two terms (x and y) unify. Prolog unification algorithm is based
655 	 * on three principals rules:
656 	 * <ul>
657 	 * <li>If x and y are atomics constants then x and y unify only if they are same
658 	 * object.</li>
659 	 * <li>If x is a variable and y is anything then they unify and x is
660 	 * instantiated to y. Conversely, if y is a variable then this is instantiated
661 	 * to x.</li>
662 	 * <li>If x and y are structured terms then unify only if they match (equals
663 	 * funtor and arity) and all their correspondents arguments unify.</li>
664 	 * </ul>
665 	 * 
666 	 * 
667 	 * @param t1 the term to unify.
668 	 * @param t2 the term to unify.
669 	 * @return true if the specified term unify whit the current term, false
670 	 *         otherwise.
671 	 * @since 1.0
672 	 */
673 	public boolean unify(PrologTerm t1, PrologTerm t2);
674 
675 	/**
676 	 * Match to other term returning list of substitutions. Used to compute the most
677 	 * general unifier.
678 	 * 
679 	 * @param t1 the term to unify.
680 	 * @param t2 the term to unify.
681 	 * @return true if the specified term unify whit the current term, false
682 	 *         otherwise.
683 	 * @since 1.2
684 	 */
685 	public Map<String, PrologTerm> match(PrologTerm t1, PrologTerm t2);
686 
687 	/**
688 	 * Parse the string creating internal prolog clause and returning true if the
689 	 * given goal have solution using the resolution engine mechanism. If wrapped
690 	 * engine not support a dedicated method then contains can be defined like
691 	 * 
692 	 * {@code query(goal).hasSolution()}
693 	 * 
694 	 * @param goal goal to be queried
695 	 * @return true if the given goal has solution
696 	 * @since 1.0
697 	 */
698 	public boolean contains(String goal);
699 
700 	/**
701 	 * Check if the given goal array have solution using the resolution engine
702 	 * mechanism. If wrapped engine not support a dedicated method then contains can
703 	 * be defined like:
704 	 * 
705 	 * {@code query(goal).hasSolution()}
706 	 * 
707 	 * @param goal goal to be checked
708 	 * @return true if the given goal has solution
709 	 * @since 1.1
710 	 */
711 	public boolean contains(PrologTerm goal);
712 
713 	/**
714 	 * Check if the given goal array have solution using the resolution engine
715 	 * mechanism. If wrapped engine not support a dedicated method then contains can
716 	 * be defined like:
717 	 * 
718 	 * {@code query(goal).hasSolution()}
719 	 * 
720 	 * @param goal  goal to be checked
721 	 * @param goals goals array with the rest of conjunctive goals term (can be
722 	 *              empty)
723 	 * @return true if the given goal has solution
724 	 * @since 1.0
725 	 */
726 	public boolean contains(PrologTerm goal, PrologTerm... goals);
727 
728 	/**
729 	 * Create a new query being the goal the given string with prolog syntax. The
730 	 * query creation process call the wrapped prolog engine and after query
731 	 * creation the query instance is ready to use. This particular query method can
732 	 * raise an syntax exception if the string query have prolog errors.
733 	 * 
734 	 * <pre>
735 	 * PrologQuery query = engine.query(&quot;parent(X, Y)&quot;);
736 	 * </pre>
737 	 * 
738 	 * @param query string goal with prolog syntax.
739 	 * @return a new query instance.
740 	 * @since 1.0
741 	 */
742 	public PrologQuery query(String query);
743 
744 	/**
745 	 * 
746 	 * @param goal
747 	 * @return
748 	 * @since 1.1
749 	 */
750 	public PrologQuery query(PrologTerm goal);
751 
752 	/**
753 	 * Create a new query being the goal the given prolog term array. The given
754 	 * array is treated like a conjunctive goal and after success the first element
755 	 * the next term will be resolved. The query creation process call the wrapped
756 	 * prolog engine and after query creation the query instance is ready to use.
757 	 * 
758 	 * <pre>
759 	 * PrologTerm x = provider.newVariable(&quot;X&quot;, 0);
760 	 * PrologTerm dark = provider.newStructure(&quot;dark&quot;, x);
761 	 * PrologTerm big = provider.newStructure(&quot;big&quot;, x);
762 	 * PrologTerm[] goals = new PrologTerm[] { dark, big };
763 	 * PrologQuery query = engine.query(goals);
764 	 * </pre>
765 	 * 
766 	 * @param terms prolog term array to be query.
767 	 * @return a new query instance.
768 	 * @since 1.0
769 	 */
770 	public PrologQuery query(PrologTerm[] terms);
771 
772 	/**
773 	 * Create a new query with at least one prolog term goal. The rest terms are
774 	 * treated like a conjunctive goal and after success the first element the next
775 	 * term will be resolved. The query creation process call the wrapped prolog
776 	 * engine and after query creation the query instance is ready to use.
777 	 * 
778 	 * <pre>
779 	 * PrologTerm x = provider.newVariable(&quot;X&quot;, 0);
780 	 * PrologTerm dark = provider.newStructure(&quot;dark&quot;, x);
781 	 * PrologTerm big = provider.newStructure(&quot;big&quot;, x);
782 	 * PrologQuery query = engine.query(dark, big);
783 	 * </pre>
784 	 * 
785 	 * @param term  prolog term to be query
786 	 * @param terms prolog term array to be query.
787 	 * @return a new query instance.
788 	 * @since 1.0
789 	 */
790 	public PrologQuery query(PrologTerm term, PrologTerm... terms);
791 
792 	/**
793 	 * Create a new prolog query and return the prolog terms that conform the
794 	 * solution set for the current query. The solution set is a prolog terms map
795 	 * and every map entry is a pair variable name and variable instance value for
796 	 * the variables not anonymous involved in the query.
797 	 * 
798 	 * <pre>
799 	 * List&lt;Map&lt;String, PrologTerm&gt;&gt; m = engine.queryAll("parent(X, Y)");
800 	 * </pre>
801 	 * 
802 	 * @param goal string query with prolog format.
803 	 * @return variable name - variable instance (key - value) map that conform the
804 	 *         solution set for the current query.
805 	 * @since 1.0
806 	 */
807 	public Map<String, PrologTerm> queryOne(String goal);
808 
809 	/**
810 	 * 
811 	 * @param goal
812 	 * @return
813 	 * @since 1.1
814 	 */
815 	public Map<String, PrologTerm> queryOne(PrologTerm goal);
816 
817 	/**
818 	 * Create a new prolog query and return the prolog terms that conform the
819 	 * solution set for the current query. The solution set is a prolog terms map
820 	 * and every map entry is a pair variable name and variable instance value for
821 	 * the variables not anonymous involved in the query.
822 	 * 
823 	 * <pre>
824 	 * PrologVariable x = provider.newVariable("X", 0);
825 	 * PrologVariable y = provider.newVariable("Y", 1);
826 	 * Map&lt;String, PrologTerm&gt; m = engine.queryOne(provider.newStructure("parent", x, y));
827 	 * </pre>
828 	 * 
829 	 * @param term  prolog term to be query
830 	 * @param terms prolog term array to be query.
831 	 * @return variable name - variable instance (key - value) map that conform the
832 	 *         solution set for the current query.
833 	 * @since 1.0
834 	 */
835 	public Map<String, PrologTerm> queryOne(PrologTerm term, PrologTerm... terms);
836 
837 	/**
838 	 * Create a new prolog query and return the list of (N) prolog terms that
839 	 * conform the solution set for the current query. Each list item is a prolog
840 	 * terms map and every map entry is a pair variable name and variable instance
841 	 * value for the variables not anonymous involved in the query.
842 	 * 
843 	 * @param n    query result instance number
844 	 * @param goal string with prolog syntax to be query
845 	 * @return the list of prolog terms that conform the solution set for the
846 	 *         current query.
847 	 * @since 1.0
848 	 */
849 	public List<Map<String, PrologTerm>> queryN(int n, String goal);
850 
851 	/**
852 	 * 
853 	 * @param n
854 	 * @param goal
855 	 * @return
856 	 * @since 1.1
857 	 */
858 	public List<Map<String, PrologTerm>> queryN(int n, PrologTerm goal);
859 
860 	/**
861 	 * Create a new prolog query and return the list of (N) prolog terms that
862 	 * conform the solution set for the current query. Each list item is a prolog
863 	 * terms map and every map entry is a pair variable name and variable instance
864 	 * value for the variables not anonymous involved in the query.
865 	 * 
866 	 * <pre>
867 	 * PrologVariable x = provider.newVariable("X", 0);
868 	 * PrologVariable y = provider.newVariable("Y", 1);
869 	 * List&lt;Map&lt;String, PrologTerm&gt;&gt; m = engine.queryN(5, provider.newStructure("parent", x, y));
870 	 * </pre>
871 	 * 
872 	 * @param n     query result instance number
873 	 * @param term  prolog term to be query
874 	 * @param terms prolog term array to be query.
875 	 * @return the list of prolog terms that conform the solution set for the
876 	 *         current query.
877 	 * @since 1.0
878 	 */
879 	public List<Map<String, PrologTerm>> queryN(int n, PrologTerm term, PrologTerm... terms);
880 
881 	/**
882 	 * Create a new prolog query and return the list of prolog terms that conform
883 	 * the solution set for the current query. Each list item is a prolog terms map
884 	 * and every map entry is a pair variable name and variable instance value for
885 	 * the variables not anonymous involved in the query.
886 	 * 
887 	 * @param goal string with prolog syntax to be query
888 	 * @return the list of prolog terms that conform the solution set for the
889 	 *         current query.
890 	 * @since 1.0
891 	 */
892 	public List<Map<String, PrologTerm>> queryAll(String goal);
893 
894 	/**
895 	 * 
896 	 * @param goal
897 	 * @return
898 	 * @since 1.1
899 	 */
900 	public List<Map<String, PrologTerm>> queryAll(PrologTerm goal);
901 
902 	/**
903 	 * Create a new prolog query and return the list of prolog terms that conform
904 	 * the solution set for the current query. Each list item is a prolog terms map
905 	 * and every map entry is a pair variable name and variable instance value for
906 	 * the variables not anonymous involved in the query.
907 	 * 
908 	 * <pre>
909 	 * PrologVariable x = provider.newVariable("X", 0);
910 	 * PrologVariable y = provider.newVariable("Y", 1);
911 	 * List&lt;Map&lt;String, PrologTerm&gt;&gt; m = engine.queryAll(provider.newStructure("parent", x, y));
912 	 * </pre>
913 	 * 
914 	 * @param term  prolog term to be query
915 	 * @param terms prolog term array to be query.
916 	 * @return the list of prolog terms that conform the solution set for the
917 	 *         current query.
918 	 * @since 1.0
919 	 */
920 	public List<Map<String, PrologTerm>> queryAll(PrologTerm term, PrologTerm... terms);
921 
922 	/**
923 	 * Create a new clause builder instance to build prolog clauses
924 	 * programmatically.
925 	 * 
926 	 * @return a new clause builder instance
927 	 * @since 1.0
928 	 */
929 	public PrologClauseBuilder newClauseBuilder();
930 
931 	/**
932 	 * Create a new query builder instance to build prolog goal programmatically.
933 	 * 
934 	 * @return a new query builder instance
935 	 * @since 1.0
936 	 */
937 	public PrologQueryBuilder newQueryBuilder();
938 
939 	/**
940 	 * Define an operator in the wrapped prolog engine with priority between 0 and
941 	 * 1200 and associativity determined by specifier according to the table below
942 	 * 
943 	 * <table BORDER > <caption>Specification table</caption>
944 	 * <tr>
945 	 * <td ALIGN=CENTER><b>Specifier</b></td>
946 	 * <td ALIGN=CENTER><b>Type</b></td>
947 	 * <td ALIGN=CENTER><b>Associativity</b></td>
948 	 * </tr>
949 	 * <tr>
950 	 * <td>fx</td>
951 	 * <td>prefix</td>
952 	 * <td>no</td>
953 	 * </tr>
954 	 * <tr>
955 	 * <td>fy</td>
956 	 * <td>prefix</td>
957 	 * <td>yes</td>
958 	 * </tr>
959 	 * <tr>
960 	 * <td>xf</td>
961 	 * <td>postfix</td>
962 	 * <td>no</td>
963 	 * </tr>
964 	 * <tr>
965 	 * <td>yf</td>
966 	 * <td>postfix</td>
967 	 * <td>yes</td>
968 	 * </tr>
969 	 * <tr>
970 	 * <td>xfx</td>
971 	 * <td>infix</td>
972 	 * <td>no</td>
973 	 * </tr>
974 	 * <tr>
975 	 * <td>yfx</td>
976 	 * <td>infix</td>
977 	 * <td>left</td>
978 	 * </tr>
979 	 * <tr>
980 	 * <td>xfy</td>
981 	 * <td>infix</td>
982 	 * <td>right</td>
983 	 * </tr>
984 	 * </table>
985 	 * 
986 	 * @since 1.0
987 	 * @param priority  operator priority between 0 and 1200
988 	 * @param specifier associative and position of the operator
989 	 * @param operator  operator to be defined
990 	 */
991 	public void operator(int priority, String specifier, String operator);
992 
993 	/**
994 	 * Check if in the wrapped prolog engine is defined some particular predicate
995 	 * specified by your predicate indicator (PI = functor/arity). If the predicate
996 	 * is defined by prolog engine built-in or by user definition return true and
997 	 * false in other case. If wrapped engine not support a dedicated method the
998 	 * 
999 	 * {@link #currentPredicate(String, int)} will be defined like
1000 	 * 
1001 	 * {@code currentPredicates().contains(new PredicateIndicator(functor, arity));}
1002 	 * 
1003 	 * @since 1.0
1004 	 * @param functor name of the predicate to be check.
1005 	 * @param arity   argument number of the predicate to be check.
1006 	 * @return true in functor/arity predicate is defined and false otherwise.
1007 	 */
1008 	public boolean currentPredicate(String functor, int arity);
1009 
1010 	/**
1011 	 * Check if in the wrapped prolog engine is defined some particular operator
1012 	 * specified by your Priority, Specifier and Operator. If the operator is
1013 	 * defined by prolog engine built-in or by user definition return true or false
1014 	 * in other case. If wrapped engine not support a dedicated method the
1015 	 * 
1016 	 * {@link #currentOperator(int, String, String)}
1017 	 * 
1018 	 * will be defined like
1019 	 * 
1020 	 * {@code currentOperators().contains(new PrologOperator(priority, specifier, operator));}
1021 	 * 
1022 	 * @param priority  operator priority between 0 and 1200
1023 	 * @param specifier associative and position of the operator
1024 	 * @param operator  operator to be checked
1025 	 * @return true if the operator is defined by prolog engine built-in or by user
1026 	 *         definition, false otherwise.
1027 	 * @since 1.0
1028 	 */
1029 	public boolean currentOperator(int priority, String specifier, String operator);
1030 
1031 	/**
1032 	 * Predicate set defined in the wrapped prolog engine. The predicate set will be
1033 	 * constituted by the supported built-ins predicate in the wrapped prolog engine
1034 	 * and user defined predicates present in the prolog program/database. More
1035 	 * formally current predicate set is defined by the union between user defined
1036 	 * predicates and prolog engine built-ins.
1037 	 * 
1038 	 * <pre>
1039 	 * Set&lt;PrologIndicator&gt; cp = new HashSet&lt;PrologIndicator&gt;();
1040 	 * cp.addAll(getPredicates());
1041 	 * cp.addAll(getBuiltIns());
1042 	 * </pre>
1043 	 * 
1044 	 * @return Defined Predicate Set.
1045 	 * @since 1.0
1046 	 */
1047 	public Set<PrologIndicator> currentPredicates();
1048 
1049 	/**
1050 	 * Operator set defined in the wrapped prolog engine. The operator set will be
1051 	 * constituted by the supported built-ins operator in the wrapped prolog engine
1052 	 * and user defined operators present in the prolog program/database.
1053 	 * 
1054 	 * @return defined operator set.
1055 	 * @since 1.0
1056 	 */
1057 	public Set<PrologOperator> currentOperators();
1058 
1059 	/**
1060 	 * Make and return a copy of the clause map present in the current engine. The
1061 	 * map key is a functor/arity string and the value is a prolog clause family
1062 	 * list.
1063 	 * 
1064 	 * @return a clause map present in the current engine.
1065 	 * @since 1.0
1066 	 */
1067 	public Map<String, List<PrologClause>> getProgramMap();
1068 
1069 	/**
1070 	 * Make and return a copy of the clause set present in the current engine.
1071 	 * 
1072 	 * @return a clause set present in the current engine.
1073 	 * @since 1.0
1074 	 */
1075 	public Set<PrologClause> getProgramClauses();
1076 
1077 	/**
1078 	 * Make and return a copy of the program.
1079 	 * 
1080 	 * @return a program in the current engine.
1081 	 * @since 1.1
1082 	 */
1083 	public PrologProgram getProgram();
1084 
1085 	/**
1086 	 * Number of clauses in the current engine.
1087 	 * 
1088 	 * @return number of clauses in the engine.
1089 	 * @since 1.0
1090 	 */
1091 	public int getProgramSize();
1092 
1093 	/**
1094 	 * Check if the program in main memory is empty returning true if the clause
1095 	 * number in the program is 0 and false in otherwise. If wrapped engine not
1096 	 * support a dedicated method {@link #isProgramEmpty()} will be defined like
1097 	 * {@code PrologEngine#getProgramSize()==0;}.
1098 	 * 
1099 	 * @return true if the clause number in the program is 0 and false in otherwise.
1100 	 * @since 1.0
1101 	 */
1102 	public boolean isProgramEmpty();
1103 
1104 	/**
1105 	 * User defined predicate set defined in the wrapped prolog engine. The
1106 	 * predicate set will be constituted by user defined predicates present in the
1107 	 * prolog program/database. The supported built-ins predicate in the wrapped
1108 	 * prolog engine not be include in this set.
1109 	 * 
1110 	 * @return User Defined Predicate Set.
1111 	 * @since 1.0
1112 	 */
1113 	public Set<PrologIndicator> getPredicates();
1114 
1115 	/**
1116 	 * Predicate set defined by the supported built-ins predicate in the wrapped
1117 	 * prolog engine. The user defined predicates in the wrapped prolog engine not
1118 	 * be include in this set.
1119 	 * 
1120 	 * @return built-ins predicates set.
1121 	 * @since 1.0
1122 	 */
1123 	public Set<PrologIndicator> getBuiltIns();
1124 
1125 	/**
1126 	 * Get a Prolog provider instance hold in the current engine.
1127 	 * 
1128 	 * @return a Prolog provider instance.
1129 	 * @since 1.0
1130 	 */
1131 	public PrologProvider getProvider();
1132 
1133 	/**
1134 	 * Get the prolog system logger instance to report any errors or exceptions
1135 	 * 
1136 	 * @return prolog system logger instance
1137 	 * @since 1.0
1138 	 */
1139 	public PrologLogger getLogger();
1140 
1141 	/**
1142 	 * License of the wrapped engine.
1143 	 * 
1144 	 * @return String license of the wrapped engine.
1145 	 * @since 1.0
1146 	 */
1147 	public String getLicense();
1148 
1149 	/**
1150 	 * Version of the wrapped engine.
1151 	 * 
1152 	 * @return String version of the wrapped engine.
1153 	 * @since 1.0
1154 	 */
1155 	public String getVersion();
1156 
1157 	/**
1158 	 * Under-laying engine vendor
1159 	 * 
1160 	 * @return engine vendor
1161 	 * @since 1.1
1162 	 */
1163 	public String getVendor();
1164 
1165 	/**
1166 	 * Name of the wrapped engine.
1167 	 * 
1168 	 * @return String name of the wrapped engine.
1169 	 * @since 1.0
1170 	 */
1171 	public String getName();
1172 
1173 	/**
1174 	 * Clear program in main memory. Release all resources used and prepare the
1175 	 * current engine for realize some new task.
1176 	 * 
1177 	 * @since 1.0
1178 	 */
1179 	public void dispose();
1180 
1181 }