1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package io.github.prolobjectlink.prolog.jpl;
23
24 import static io.github.prolobjectlink.prolog.PrologTermType.CUT_TYPE;
25 import static io.github.prolobjectlink.prolog.PrologTermType.DOUBLE_TYPE;
26 import static io.github.prolobjectlink.prolog.PrologTermType.FLOAT_TYPE;
27 import static io.github.prolobjectlink.prolog.PrologTermType.INTEGER_TYPE;
28 import static io.github.prolobjectlink.prolog.PrologTermType.LONG_TYPE;
29
30 import java.util.Map;
31
32 import io.github.prolobjectlink.prolog.AbstractTerm;
33 import io.github.prolobjectlink.prolog.PrologList;
34 import io.github.prolobjectlink.prolog.PrologProvider;
35 import io.github.prolobjectlink.prolog.PrologQuery;
36 import io.github.prolobjectlink.prolog.PrologTerm;
37 import jpl.Atom;
38 import jpl.Query;
39 import jpl.Term;
40
41
42
43
44
45
46 abstract class JplTerm extends AbstractTerm implements PrologTerm {
47
48 protected Term value;
49
50 static final Term JPL_TRUE = new Atom("true");
51
52 protected JplTerm(int type, PrologProvider provider) {
53 super(type, provider);
54 }
55
56 protected JplTerm(int type, PrologProvider provider, Term value) {
57 super(type, provider);
58 this.value = value;
59 }
60
61 public final boolean isAtom() {
62 return value.isAtom();
63 }
64
65 public final boolean isNumber() {
66 return isFloat() || isDouble() || isInteger() || isLong();
67 }
68
69 public final boolean isFloat() {
70 return type == FLOAT_TYPE && value.isFloat();
71 }
72
73 public final boolean isDouble() {
74 return type == DOUBLE_TYPE;
75 }
76
77 public final boolean isInteger() {
78 return type == INTEGER_TYPE && value.isInteger();
79 }
80
81 public final boolean isLong() {
82 return type == LONG_TYPE;
83 }
84
85 public final boolean isVariable() {
86 return value.isVariable();
87 }
88
89 public final boolean isList() {
90 if (!isVariable()) {
91 return value.equals(JplList.EMPTY) || value.hasFunctor(".", 2);
92 }
93 return false;
94 }
95
96 public final boolean isStructure() {
97 return isCompound() && !isList();
98 }
99
100 public final boolean isNil() {
101 if (!isVariable() && !isNumber()) {
102 return value.hasFunctor("nil", 0);
103 }
104 return false;
105 }
106
107 public final boolean isEmptyList() {
108 return value.equals(JplList.EMPTY);
109 }
110
111 public final boolean isEvaluable() {
112 if (!isVariable() && !isList() && !isNumber() && getArity() == 2) {
113 String key = "LIST";
114 String stringQuery = "findall(OP,current_op(_,_,OP)," + key + ")";
115 JplEngine engine = (JplEngine) provider.newEngine();
116 PrologQuery query = new JplQuery(engine, engine.getCache(), stringQuery);
117 Map<String, PrologTerm>[] solution = query.allVariablesSolutions();
118 for (Map<String, PrologTerm> map : solution) {
119 for (PrologTerm operatorList : map.values()) {
120 if (!operatorList.isVariable() && operatorList.isList()) {
121 PrologList l = (PrologList) operatorList;
122 for (PrologTerm operator : l) {
123 if (operator.getFunctor().equals(getFunctor())) {
124 return true;
125 }
126 }
127 }
128 }
129 }
130 }
131 return false;
132 }
133
134 public final boolean isAtomic() {
135 return !isCompound() && !isList();
136 }
137
138 public final boolean isCompound() {
139 return value.isCompound() && !isAtom();
140 }
141
142 public final boolean isTrueType() {
143 return value.isJTrue();
144 }
145
146 public final boolean isFalseType() {
147 return value.isJFalse();
148 }
149
150 public final boolean isNullType() {
151 return value.isJNull();
152 }
153
154 public final boolean isVoidType() {
155 return value.isJVoid();
156 }
157
158 public final boolean isObjectType() {
159 return value.isJObject();
160 }
161
162 public final boolean isReference() {
163 return value.isJRef();
164 }
165
166 public final PrologTerm getTerm() {
167 return this;
168 }
169
170 public final boolean unify(PrologTerm o) {
171 return unify(fromTerm(o, Term.class));
172 }
173
174 private final boolean unify(Term o) {
175 String q = "unify_with_occurs_check(" + value + "," + o + ")";
176 Query query = new Query(q);
177 boolean result = query.hasSolution();
178 query.close();
179 return result;
180 }
181
182 public final int compareTo(PrologTerm o) {
183
184 String key = "Order";
185 Term term = fromTerm(o, Term.class);
186 String arguments = key + "," + value + "," + term;
187 Query query = new Query("compare(" + arguments + ")");
188
189 query.open();
190 Term order = (Term) query.getSolution().get(key);
191 query.close();
192
193 if (order.hasFunctor("<", 0)) {
194 return -1;
195 } else if (order.hasFunctor(">", 0)) {
196 return 1;
197 }
198
199 return 0;
200
201 }
202
203 public int hashCode() {
204 final int prime = 31;
205 int result = 1;
206 result = prime * result + type;
207
208 result = prime * result + ((value == null) ? 0 : value.toString().hashCode());
209 return result;
210 }
211
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 public String toString() {
228 if (type == CUT_TYPE) {
229 return getFunctor();
230 }
231 return "" + value + "";
232 }
233
234 }