View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jpl7
4    * %%
5    * Copyright (C) 2019 Prolobjectlink Project
6    * %%
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions are met:
9    * 
10   * 1. Redistributions of source code must retain the above copyright notice,
11   *    this list of conditions and the following disclaimer.
12   * 2. Redistributions in binary form must reproduce the above copyright notice,
13   *    this list of conditions and the following disclaimer in the documentation
14   *    and/or other materials provided with the distribution.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   * #L%
28   */
29  package io.github.prolobjectlink.prolog.jpl7;
30  
31  import static io.github.prolobjectlink.prolog.PrologTermType.CUT_TYPE;
32  import static io.github.prolobjectlink.prolog.PrologTermType.DOUBLE_TYPE;
33  import static io.github.prolobjectlink.prolog.PrologTermType.FLOAT_TYPE;
34  import static io.github.prolobjectlink.prolog.PrologTermType.INTEGER_TYPE;
35  import static io.github.prolobjectlink.prolog.PrologTermType.LONG_TYPE;
36  
37  import org.jpl7.Atom;
38  import org.jpl7.Query;
39  import org.jpl7.Term;
40  import org.jpl7.fli.Prolog;
41  
42  import io.github.prolobjectlink.prolog.AbstractTerm;
43  import io.github.prolobjectlink.prolog.PrologProvider;
44  import io.github.prolobjectlink.prolog.PrologTerm;
45  
46  /**
47   * 
48   * @author Jose Zalacain
49   * @since 1.0
50   */
51  abstract class JplTerm extends AbstractTerm implements PrologTerm {
52  
53  	protected Term value;
54  
55  	public static final Term JPL_TRUE = new Atom("true");
56  
57  	protected JplTerm(int type, PrologProvider provider) {
58  		super(type, provider);
59  	}
60  
61  	protected JplTerm(int type, PrologProvider provider, Term value) {
62  		super(type, provider);
63  		this.value = value;
64  	}
65  
66  	public final boolean isAtom() {
67  		return value.isAtom();
68  	}
69  
70  	public final boolean isNumber() {
71  		return isFloat() || isDouble() || isInteger() || isLong();
72  	}
73  
74  	public final boolean isFloat() {
75  		return type == FLOAT_TYPE && value.isFloat();
76  	}
77  
78  	public final boolean isDouble() {
79  		return type == DOUBLE_TYPE;
80  	}
81  
82  	public final boolean isInteger() {
83  		return type == INTEGER_TYPE && value.isInteger();
84  	}
85  
86  	public final boolean isLong() {
87  		return type == LONG_TYPE;
88  	}
89  
90  	public final boolean isVariable() {
91  		return value.isVariable();
92  	}
93  
94  	public final boolean isList() {
95  		return value.isListNil() || value.isListPair();
96  	}
97  
98  	public final boolean isStructure() {
99  		return isCompound() && !isList();
100 	}
101 
102 	public final boolean isNil() {
103 		if (!isVariable() && !isNumber()) {
104 			return value.hasFunctor("nil", 0);
105 		}
106 		return false;
107 	}
108 
109 	public final boolean isEmptyList() {
110 		return value.isListNil();
111 	}
112 
113 	public final boolean isEvaluable() {
114 		if (!isVariable() && !isList() && !isNumber() && getArity() == 2) {
115 			String key = "LIST";
116 			String opQuery = "findall(OP,current_op(_,_,OP)," + key + ")";
117 			Query query = new Query(opQuery);
118 			if (query.hasSolution()) {
119 				Term term = query.oneSolution().get(key);
120 				Term[] termArray = term.toTermArray();
121 				for (Term termArray1 : termArray) {
122 					if (termArray1.name().equals(getFunctor())) {
123 						return true;
124 					}
125 				}
126 			}
127 			query.close();
128 		}
129 		return false;
130 	}
131 
132 	public final boolean isAtomic() {
133 		return !isCompound() && !isList();
134 	}
135 
136 	public final boolean isCompound() {
137 		return value.isCompound();
138 	}
139 
140 	public final boolean isTrueType() {
141 		return value.isJTrue();
142 	}
143 
144 	public final boolean isFalseType() {
145 		return value.isJFalse();
146 	}
147 
148 	public final boolean isNullType() {
149 		return value.isJNull();
150 	}
151 
152 	public final boolean isVoidType() {
153 		return value.isJVoid();
154 	}
155 
156 	public final boolean isObjectType() {
157 		return value.type() == Prolog.JREF;
158 	}
159 
160 	public final boolean isReference() {
161 		return value.isJRef();
162 	}
163 
164 	public final PrologTerm getTerm() {
165 		return this;
166 	}
167 
168 	public boolean unify(PrologTerm o) {
169 		return unify(fromTerm(o, Term.class));
170 	}
171 
172 	private final boolean unify(Term o) {
173 		String q = "unify_with_occurs_check(" + value + "," + o + ")";
174 		Query query = new Query(q);
175 		boolean result = query.hasSolution();
176 		query.close();
177 		return result;
178 	}
179 
180 	public int compareTo(PrologTerm o) {
181 
182 		String key = "Order";
183 		Term term = fromTerm(o, Term.class);
184 		String arguments = key + "," + value + "," + term;
185 		Query query = new Query("compare(" + arguments + ")");
186 
187 		query.open();
188 		Term order = query.getSolution().get(key);
189 		query.close();
190 
191 		if (order.hasFunctor("<", 0)) {
192 			return -1;
193 		} else if (order.hasFunctor(">", 0)) {
194 			return 1;
195 		}
196 
197 		return 0;
198 
199 	}
200 
201 	@Override
202 	public int hashCode() {
203 		final int prime = 31;
204 		int result = 1;
205 		result = prime * result + type;
206 		// Term not implement hashCode()
207 		result = prime * result + ((value == null) ? 0 : value.toString().hashCode());
208 		return result;
209 	}
210 
211 	@Override
212 	public boolean equals(Object obj) {
213 		if (this == obj)
214 			return true;
215 		if (obj == null)
216 			return false;
217 		JplTerm other = (JplTerm) obj;
218 		if (value == null) {
219 			if (other.value != null)
220 				return false;
221 		} else if (!unify(other.value)) {
222 			return false;
223 		}
224 		return true;
225 	}
226 
227 	@Override
228 	public String toString() {
229 		if (type == CUT_TYPE) {
230 			return getFunctor();
231 		}
232 		return "" + value + "";
233 	}
234 
235 }