1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
49
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
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 }