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.util.Map;
29  
30  /**
31   * <p>
32   * Ancestor prolog data type. All Prolog data types {@link PrologAtom},
33   * {@link PrologNumber}, {@link PrologList}, {@link PrologStructure} and
34   * {@link PrologVariable} are derived from this class. All before mentioned
35   * classes extends from this class the commons responsibilities. Extends from
36   * {@link Comparable} to compare the current term with another term based on
37   * Standard Order.
38   * </p>
39   * 
40   * <p>
41   * The Prolog Provider is the mechanism to create a new Prolog terms invoking
42   * the correspondent methods. {@link PrologProvider#newAtom(String)} for atoms,
43   * {@link PrologProvider#newStructure(String, PrologTerm...)} for structures,
44   * {@link PrologProvider#newVariable(String, int)} for variables and so on.
45   * </p>
46   * 
47   * <p>
48   * With {@link #getType()} the term type can be retrieve. Every term have a type
49   * defined in {@link PrologTermType}. The prolog type have by definition one
50   * order (Standard Order) where Variables &lt; Atoms &lt; Numbers &lt;
51   * Compounds. This order is usable to compare two terms.
52   * </p>
53   * 
54   * <p>
55   * Prolog terms have two specials properties, the functor and the arity. Functor
56   * is the compound term or atom name and arity is the number of arguments
57   * present in the compound terms. Variable and Number don't have this
58   * properties. This properties are accessible from {@link #getArity()} and
59   * {@link #getFunctor()} methods. Variable and Number raise an
60   * {@link ArityError} and {@link FunctorError} respectively. Based on functor
61   * and arity atoms and compound terms have a predicate indicator that is the
62   * signature for the term. The term indicator is an string formed by the
63   * concatenation of {@link #getFunctor()} and {@link #getArity()} separated by
64   * slash.
65   * </p>
66   * 
67   * <p>
68   * The methods {@link #getArguments()} and {@link #getArgument(int)} allow
69   * retrieve the arguments and the some specific arguments for compounds terms
70   * respectively. For atomics terms {@link #getArguments()} return an empty term
71   * array and {@link #getArgument(int)} raise a
72   * {@link ArrayIndexOutOfBoundsException} because don't have arguments. For this
73   * cases is a good practice check compound terms before invoke this methods.
74   * </p>
75   * 
76   * <pre>
77   * if (t.isCompound()) {
78   * 	PrologTerm x = t.getArgument(i);
79   * 	System.out.println(x);
80   * }
81   * </pre>
82   * 
83   * Prolog unification is the process that involves one or more variables such
84   * that they are instantiated with the necessary terms in order to make two
85   * terms are identical. The prolog term interface provide
86   * {@link #unify(PrologTerm)} method to check that the current term unify with
87   * the given term. Prolog unification algorithm is based on three principals
88   * rules:
89   * <ul>
90   * <li>If x and y are atomics constants then x and y unify only if they are same
91   * object.</li>
92   * <li>If x is a variable and y is anything then they unify and x is
93   * instantiated to y. Conversely, if y is a variable then this is instantiated
94   * to x.</li>
95   * <li>If x and y are structured terms then unify only if they match (equals
96   * funtor and arity) and all their correspondents arguments unify.</li>
97   * </ul>
98   * 
99   * <pre>
100  * PrologAtom atom = provider.newAtom("smith");
101  * PrologAtom atom1 = provider.newAtom("doe");
102  * // true because the atoms are equals
103  * assertTrue(atom.unify(atom));
104  * // false because the atoms are different
105  * assertFalse(atom.unify(atom1));
106  * PrologVariable variable = provider.newVariable("X", 0);
107  * // true because atom and variable unify
108  * assertTrue(atom.unify(variable));
109  * </pre>
110  * 
111  * @author Jose Zalacain
112  * @since 1.0
113  */
114 public interface PrologTerm extends Comparable<PrologTerm>, PrologElement {
115 
116 	/**
117 	 * Gets the term indicator represented by one string with the format
118 	 * functor/arity. More formally the indicator string is formed by the
119 	 * concatenation of {@link #getFunctor()} and {@link #getArity()} separated by
120 	 * slash.
121 	 * 
122 	 * @return term indicator
123 	 * @since 1.0
124 	 */
125 	public String getIndicator();
126 
127 	/**
128 	 * True if term has an indicator with the format functor/arity that match with
129 	 * the given functor and arity.
130 	 * 
131 	 * @param functor term functor
132 	 * @param arity   term arity
133 	 * @return True if term has an indicator functor/arity.
134 	 * @since 1.0
135 	 */
136 	public boolean hasIndicator(String functor, int arity);
137 
138 	/**
139 	 * Get the term type.
140 	 * 
141 	 * @return term type.
142 	 * @since 1.0
143 	 */
144 	public int getType();
145 
146 	/**
147 	 * True if this term is an atom
148 	 * 
149 	 * @return whether this Term represents an atom, false in other case
150 	 * @since 1.0
151 	 */
152 	public boolean isAtom();
153 
154 	/**
155 	 * True if this term is an number
156 	 * 
157 	 * @return whether this Term represents an number, false in other case
158 	 * @since 1.0
159 	 */
160 	public boolean isNumber();
161 
162 	/**
163 	 * True if this Term is a single precision floating point number, false in other
164 	 * case
165 	 * 
166 	 * @return whether this Term represents a single precision floating point
167 	 *         number, false in other case
168 	 * @since 1.0
169 	 */
170 	public boolean isFloat();
171 
172 	/**
173 	 * True if this Term is an integer number, false in other case
174 	 * 
175 	 * @return whether this Term represents an integer number
176 	 * @since 1.0
177 	 */
178 	public boolean isInteger();
179 
180 	/**
181 	 * True if this Term is a double precision floating point number, false in other
182 	 * case
183 	 * 
184 	 * @return whether this Term represents a double precision floating point
185 	 *         number, false in other case
186 	 * @since 1.0
187 	 */
188 	public boolean isDouble();
189 
190 	/**
191 	 * True if this Term is a large integer number, false in other case
192 	 * 
193 	 * @return whether this Term represents a large integer number, false in other
194 	 *         case
195 	 * @since 1.0
196 	 */
197 	public boolean isLong();
198 
199 	/**
200 	 * True if this Term is a variable, false in other case
201 	 * 
202 	 * @return whether this Term is a variable
203 	 * @since 1.0
204 	 */
205 	public boolean isVariable();
206 
207 	/**
208 	 * True if this Term is a instanced variable, false in other case
209 	 * 
210 	 * @return whether this Term is a instanced variable
211 	 * @since 1.1
212 	 */
213 	public boolean isVariableBound();
214 
215 	/**
216 	 * True if this Term is a not instanced variable, false in other case
217 	 * 
218 	 * @return whether this Term is a not instanced variable
219 	 * @since 1.1
220 	 */
221 	public boolean isVariableNotBound();
222 
223 	/**
224 	 * True if this Term is a list, false in other case
225 	 * 
226 	 * @return whether this Term is a list
227 	 * @since 1.0
228 	 */
229 	public boolean isList();
230 
231 	/**
232 	 * True if this Term is a structured term, false in other case
233 	 * 
234 	 * @return whether this Term is a structured term
235 	 * @since 1.0
236 	 */
237 	public boolean isStructure();
238 
239 	/**
240 	 * True if this Term is a nil term (null term for prolog), false in other case
241 	 * 
242 	 * @return whether this Term is a nil term
243 	 * @since 1.0
244 	 */
245 	public boolean isNil();
246 
247 	/**
248 	 * True if this Term is a empty list term ([]), false in other case
249 	 * 
250 	 * @return whether this Term is a empty list term
251 	 * @since 1.0
252 	 */
253 	public boolean isEmptyList();
254 
255 	/**
256 	 * True if this Term is a atomic term, false in other case
257 	 * 
258 	 * @return whether this Term is a atomic term
259 	 * @since 1.0
260 	 */
261 	public boolean isAtomic();
262 
263 	/**
264 	 * True if this Term is a compound term, false in other case
265 	 * 
266 	 * @return whether this Term is a compound term
267 	 * @since 1.0
268 	 */
269 	public boolean isCompound();
270 
271 	/**
272 	 * Check if the current term is a compound term and have like functor an
273 	 * operator.
274 	 * 
275 	 * @return true if current term have like functor an operator.
276 	 * @since 1.0
277 	 */
278 	public boolean isEvaluable();
279 
280 	/**
281 	 * Check if the current term is a reference term and the referenced object is an
282 	 * instance of java true value. Most formally check if the reference term
283 	 * is @(true) structure.
284 	 * 
285 	 * @return true if current term have like referenced object an instance of java
286 	 *         true value.
287 	 * @since 1.0
288 	 */
289 	public boolean isTrueType();
290 
291 	/**
292 	 * Check if the current term is a reference term and the referenced object is an
293 	 * instance of java false value. Most formally check if the reference term
294 	 * is @(false) structure.
295 	 * 
296 	 * @return true if current term have like referenced object an instance of java
297 	 *         false value.
298 	 * @since 1.0
299 	 */
300 	public boolean isFalseType();
301 
302 	/**
303 	 * Check if the current term is a reference term and the referenced object is a
304 	 * java null value. Most formally check if the reference term is @(null)
305 	 * structure.
306 	 * 
307 	 * @return true if current term have like referenced object a java null value.
308 	 * @since 1.0
309 	 */
310 	public boolean isNullType();
311 
312 	/**
313 	 * Check if the current term is a reference term for java void type. Most
314 	 * formally check if the reference term is @(void) structure.
315 	 * 
316 	 * @return true if current term is a referenced to java void type.
317 	 * @since 1.0
318 	 */
319 	public boolean isVoidType();
320 
321 	/**
322 	 * Check if the current term is a reference term for some java object instance.
323 	 * Most formally check if the reference term is an structure
324 	 * like @(J#00000000000000000425).
325 	 * 
326 	 * 
327 	 * 
328 	 * @return true if current term is a referenced for some java object instance.
329 	 * @since 1.0
330 	 */
331 	public boolean isObjectType();
332 
333 	/**
334 	 * Check if the current term is a reference term for some java object instance
335 	 * or is a reference term and the referenced object is a java null value.
336 	 * 
337 	 * @return true if current term is a reference term for object instance or java
338 	 *         null value.
339 	 * @since 1.0
340 	 */
341 	public boolean isReference();
342 
343 	/**
344 	 * True if this Term is a Entry, false in other case
345 	 * 
346 	 * @return whether this Term is a entry
347 	 * @since 1.1
348 	 */
349 	public boolean isEntry();
350 
351 	/**
352 	 * True if this Term is a Map, false in other case
353 	 * 
354 	 * @return whether this Term is a map
355 	 * @since 1.1
356 	 */
357 	public boolean isMap();
358 
359 	/**
360 	 * True if this Term is a Field, false in other case
361 	 * 
362 	 * @return whether this Term is a field
363 	 * @since 1.1
364 	 */
365 	@Deprecated
366 	public boolean isField();
367 
368 	/**
369 	 * True if this Term is a Result, false in other case
370 	 * 
371 	 * @return whether this Term is a result
372 	 * @since 1.1
373 	 */
374 	@Deprecated
375 	public boolean isResult();
376 
377 	/**
378 	 * True if this Term is a Parameter, false in other case
379 	 * 
380 	 * @return whether this Term is a parameter
381 	 * @since 1.1
382 	 */
383 	@Deprecated
384 	public boolean isParameter();
385 
386 	/**
387 	 * True if this Term is a Mixin, false in other case
388 	 * 
389 	 * @return whether this Term is a mixin
390 	 * @since 1.1
391 	 */
392 	@Deprecated
393 	public boolean isMixin();
394 
395 	/**
396 	 * True if this Term is a Class, false in other case
397 	 * 
398 	 * @return whether this Term is a class
399 	 * @since 1.1
400 	 */
401 	@Deprecated
402 	public boolean isClass();
403 
404 	/**
405 	 * For references terms return the referenced object.
406 	 * 
407 	 * @return the referenced object if the current term is a reference prolog term
408 	 * @since 1.0
409 	 */
410 	public Object getObject();
411 
412 	/**
413 	 * Return current term instance if current term is not a variable or is a free
414 	 * variable term. If current term is a variable bound term then return the
415 	 * linked term hold by this variable after dereferencing.
416 	 * 
417 	 * @return return a dereferencing term if current term is bound variable,
418 	 *         current term in otherwise
419 	 * @since 1.0
420 	 */
421 	public PrologTerm getTerm();
422 
423 	/**
424 	 * Term arity. The arity of a term is a argument number for compound terms. If a
425 	 * the current term is not a compound term, then an exception is raised
426 	 * indicating a violation.
427 	 * 
428 	 * @return term arity for compound terms or an exception is raised if the term
429 	 *         is not a compound term.
430 	 * @since 1.0
431 	 */
432 	public int getArity();
433 
434 	/**
435 	 * Term functor.The functor of a term is a name for compound terms. If a the
436 	 * current term is not a compound term, then an exception is raised indicating a
437 	 * violation.
438 	 * 
439 	 * @return term functor for compound terms or an exception is raised if the term
440 	 *         is not a compound term.
441 	 * @since 1.0
442 	 */
443 	public String getFunctor();
444 
445 	/**
446 	 * Term arguments if the current term is a compound term. Compound terms are
447 	 * Structures and List data types. They are compoused by a PrologTerm[] array.
448 	 * Atoms, Variables and Numbers return an empty term array.
449 	 * 
450 	 * @return Term arguments if the current term is a compound term.
451 	 * @since 1.0
452 	 */
453 	public PrologTerm[] getArguments();
454 
455 	/**
456 	 * Term located at some given index position in the current term arguments if
457 	 * current term is a compound term. If the current term is not compound term an
458 	 * {@link ArrayIndexOutOfBoundsException} exception is raised.
459 	 * 
460 	 * @param index position to retrieve the correspondent term.
461 	 * @return Term located at some given index position.
462 	 * @throws ArrayIndexOutOfBoundsException if the index value is out of term
463 	 *                                        array bound.
464 	 * @since 1.0
465 	 */
466 	public PrologTerm getArgument(int index);
467 
468 	/**
469 	 * Check that the current term unify with the given term. Prolog unification
470 	 * algorithm is based on three principals rules:
471 	 * <ul>
472 	 * <li>If x and y are atomics constants then x and y unify only if they are same
473 	 * object.</li>
474 	 * <li>If x is a variable and y is anything then they unify and x is
475 	 * instantiated to y. Conversely, if y is a variable then this is instantiated
476 	 * to x.</li>
477 	 * <li>If x and y are structured terms then unify only if they match (equals
478 	 * funtor and arity) and all their correspondents arguments unify.</li>
479 	 * </ul>
480 	 * 
481 	 * 
482 	 * @param term the term to unify with the current term
483 	 * @return true if the specified term unify whit the current term, false if not
484 	 * @since 1.0
485 	 */
486 	public boolean unify(PrologTerm term);
487 
488 	/**
489 	 * Match to other term returning list of substitutions.
490 	 * 
491 	 * @param term - term to match check
492 	 * @return list of substitutions.
493 	 * @since 1.1
494 	 */
495 	public Map<String, PrologTerm> match(PrologTerm term);
496 
497 	/**
498 	 * Prolog provider associated to the current term.
499 	 * 
500 	 * @return Prolog provider associated to the current term.
501 	 * @since 1.0
502 	 */
503 	public PrologProvider getProvider();
504 
505 	/**
506 	 * Casts the current PrologTerm to the class or interface represented by this
507 	 * {@code Class} object.
508 	 *
509 	 * @return the PrologTerm after casting, or null if term is null
510 	 *
511 	 * @throws ClassCastException if the object is not null and is not assignable to
512 	 *                            the type T.
513 	 * @since 1.1
514 	 */
515 	public <T extends PrologTerm> T cast();
516 
517 }