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<Object> solution = query.oneResult();
96 * for (int i = 0; i < 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<?> 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("parent", 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("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
386 * engine.asserta("parent( pat, jim)");
387 * engine.asserta("parent( bob, pat)");
388 * engine.asserta("parent( bob, ann)");
389 * engine.asserta("parent( tom, liz)");
390 * engine.asserta("parent( tom, bob)");
391 * engine.asserta("parent( pam, bob)");
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 = "parent";
422 * String grandparent = "grandparent";
423 *
424 * PrologAtom pam = provider.newAtom("pam");
425 * PrologAtom bob = provider.newAtom("bob");
426 * PrologAtom ann = provider.newAtom("ann");
427 * PrologAtom pat = provider.newAtom("pat");
428 *
429 * PrologVariable x = provider.newVariable("X");
430 * PrologVariable y = provider.newVariable("Y");
431 * PrologVariable z = provider.newVariable("Z");
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("parent( pam, bob)");
458 * engine.assertz("parent( tom, bob)");
459 * engine.assertz("parent( tom, liz)");
460 * engine.assertz("parent( bob, ann)");
461 * engine.assertz("parent( bob, pat)");
462 * engine.assertz("parent( pat, jim)");
463 * engine.assertz("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
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 = "parent";
496 * String grandparent = "grandparent";
497 * PrologAtom pam = provider.newAtom("pam");
498 * PrologAtom bob = provider.newAtom("bob");
499 * PrologAtom ann = provider.newAtom("ann");
500 * PrologAtom pat = provider.newAtom("pat");
501 * PrologVariable x = provider.newVariable("X");
502 * PrologVariable y = provider.newVariable("Y");
503 * PrologVariable z = provider.newVariable("Z");
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("parent( pam, bob)");
528 * </pre>
529 *
530 * <pre>
531 * boolean b = engine.clause("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
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 = "parent";
567 * PrologAtom pam = provider.newAtom("pam");
568 * PrologAtom bob = provider.newAtom("bob");
569 * boolean b = engine.clause(provider.newStructure(parent, pam, bob));
570 * </pre>
571 *
572 * <pre>
573 * String grandparent = "grandparent";
574 * PrologVariable x = provider.newVariable("X");
575 * PrologVariable y = provider.newVariable("Y");
576 * PrologVariable z = provider.newVariable("Z");
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("parent( pam, bob).");
596 * engine.retract("parent( tom, bob).");
597 * engine.retract("parent( tom, liz).");
598 * engine.retract("parent( bob, ann).");
599 * engine.retract("parent( bob, pat).");
600 * engine.retract("parent( pat, jim).");
601 * engine.retract("grandparent(X,Z):-parent(X,Y),parent(Y,Z)");
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 = "parent";
629 * String grandparent = "grandparent";
630 * PrologAtom pam = provider.newAtom("pam");
631 * PrologAtom bob = provider.newAtom("bob");
632 * PrologAtom ann = provider.newAtom("ann");
633 * PrologAtom pat = provider.newAtom("pat");
634 * PrologVariable x = provider.newVariable("X");
635 * PrologVariable y = provider.newVariable("Y");
636 * PrologVariable z = provider.newVariable("Z");
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("parent(X, Y)");
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("X", 0);
760 * PrologTerm dark = provider.newStructure("dark", x);
761 * PrologTerm big = provider.newStructure("big", 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("X", 0);
780 * PrologTerm dark = provider.newStructure("dark", x);
781 * PrologTerm big = provider.newStructure("big", 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<Map<String, PrologTerm>> 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<String, PrologTerm> 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<Map<String, PrologTerm>> 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<Map<String, PrologTerm>> 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<PrologIndicator> cp = new HashSet<PrologIndicator>();
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 }