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 package io.github.prolobjectlink.prolog;
27
28 import java.io.File;
29 import java.util.HashSet;
30 import java.util.Map;
31 import java.util.Set;
32
33
34
35
36
37
38
39 public abstract class AbstractProvider implements PrologProvider {
40
41 protected final PrologConverter<?> converter;
42 private static final Set<PrologIndicator> ISO_IEC_BUILT_INS;
43
44 static {
45
46 ISO_IEC_BUILT_INS = new HashSet<PrologIndicator>();
47
48
49 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("dynamic", 1));
50 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("include", 1));
51 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("multifile", 1));
52 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("set_prolog_flag", 2));
53 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("ensure_loaded", 1));
54 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("discontiguous", 1));
55 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("current_prolog_flag", 2));
56 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("initialization", 1));
57
58
59 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("nil", 0));
60 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("fail", 0));
61 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("true", 0));
62 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("false", 0));
63 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.THROW, 1));
64 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CATCH, 3));
65
66
67 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("=", 2));
68 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("\\=", 2));
69 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("subsume", 2));
70 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.UNIFY_WITH_OCCURS_CHECK, 2));
71
72
73 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.VAR, 1));
74 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOM, 1));
75 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FLOAT, 1));
76 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.NUMBER, 1));
77 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.NONVAR, 1));
78 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.OBJECT, 1));
79 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.GROUND, 1));
80 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOMIC, 1));
81 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.INTEGER, 1));
82 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.COMPOUND, 1));
83 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CALLABLE, 1));
84 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CYCLIC_TERM, 1));
85 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ACYCLIC_TERM, 1));
86
87
88 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("@>", 2));
89 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("@<", 2));
90 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("==", 2));
91 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("@>=", 2));
92 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("@=<", 2));
93 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("\\==", 2));
94 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SORT, 2));
95 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.COMPARE, 3));
96 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.KEYSORT, 2));
97
98
99 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ARG, 3));
100 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FUNCTOR, 3));
101 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.COPY_TERM, 2));
102 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.TERM_VARIABLES, 2));
103
104
105 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("is", 2));
106
107
108 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(">", 2));
109 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("<", 2));
110 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("=<", 2));
111 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(">=", 2));
112 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("=:=", 2));
113 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("=\\=", 2));
114
115
116 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("clause", 2));
117 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("current_predicate", 2));
118
119
120 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("abolish", 1));
121 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("asserta", 1));
122 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("assertz", 1));
123 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("retract", 1));
124
125
126 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("forall", 2));
127 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.BAGOF, 3));
128 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SETOF, 3));
129 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FINDALL, 3));
130
131
132 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.OPEN, 3));
133 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CLOSE, 1));
134 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.OPEN, 4));
135 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CLOSE, 2));
136 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SET_INPUT, 1));
137 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SET_OUTPUT, 1));
138 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CURRENT_INPUT, 1));
139 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CURRENT_OUTPUT, 1));
140
141
142
143
144
145 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.NL, 0));
146 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.READ, 1));
147 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.WRITE, 1));
148
149
150 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("call", 1));
151 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("once", 1));
152 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("repeat", 0));
153
154
155 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SUB_ATOM, 5));
156 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CHAR_CODE, 2));
157 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOM_CHARS, 2));
158 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOM_CODES, 2));
159 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOM_LENGTH, 2));
160 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATOM_CONCAT, 3));
161 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.NUMBER_CHARS, 2));
162 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.NUMBER_CODES, 2));
163
164
165 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.OP, 3));
166 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.HALT, 0));
167 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.HALT, 1));
168 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CURRENT_OP, 3));
169 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CHAR_CONVERSION, 2));
170 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CURRENT_CHAR_CONVERSION, 2));
171
172
173 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ABS, 1));
174 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.EXP, 1));
175 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.LOG, 1));
176 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SQRT, 1));
177 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CBRT, 1));
178 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FLOOR, 1));
179 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ROUND, 1));
180 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.CEILING, 1));
181 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.TRUNCATE, 1));
182 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FLOAT_INTEGER_PART, 1));
183 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.FLOAT_FRACTIONAL_PART, 1));
184
185
186
187
188 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.MAX, 2));
189 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.MIN, 2));
190 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.GCD, 2));
191 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.LCM, 2));
192
193
194 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("\\//", 2));
195 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("><", 2));
196 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("/\\", 2));
197 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("<<", 2));
198 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(">>", 2));
199 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("\\/", 1));
200 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator("//", 2));
201
202
203 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SIN, 1));
204 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.COS, 1));
205 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.TAN, 1));
206 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ASIN, 1));
207 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ACOS, 1));
208 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.ATAN, 1));
209 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.SIGN, 1));
210
211
212 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.E, 0));
213 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.PI, 0));
214 ISO_IEC_BUILT_INS.add(new DefaultPrologIndicator(PrologBuiltin.EPSILON, 0));
215
216 }
217
218 public AbstractProvider(PrologConverter<?> converter) {
219 this.converter = converter;
220 }
221
222 protected final String removeQuoted(String functor) {
223 if (functor != null && functor.startsWith("\'") && functor.endsWith("\'")) {
224 return functor.substring(1, functor.length() - 1);
225 }
226 return functor;
227 }
228
229 public final boolean isCompliant() {
230 PrologEngine engine = newEngine();
231 Set<PrologIndicator> implemented = engine.getBuiltIns();
232 for (PrologIndicator prologIndicator : ISO_IEC_BUILT_INS) {
233 if (implemented.contains(prologIndicator)) {
234 return true;
235 }
236 }
237 return false;
238 }
239
240 public final PrologList parseList(String stringList) {
241 PrologTerm term = parseTerm(stringList);
242 checkListType(term);
243 return (PrologList) term;
244 }
245
246 public final PrologClause parseClause(String stringClause) {
247 PrologEngine engine = newEngine();
248 engine.asserta(stringClause);
249 return engine.iterator().next();
250 }
251
252 public final PrologStructure parseStructure(String stringStructure) {
253 PrologTerm term = parseTerm(stringStructure);
254 checkStructureType(term);
255 return (PrologStructure) term;
256 }
257
258 public final Set<PrologClause> parseProgram(String file) {
259 return newEngine(file).getProgramClauses();
260 }
261
262 public final Set<PrologClause> parseProgram(File in) {
263 return parseProgram(in.getAbsolutePath());
264 }
265
266 public final PrologFloat newFloat() {
267 return newFloat(0F);
268 }
269
270 public final PrologDouble newDouble() {
271 return newDouble(0D);
272 }
273
274 public final PrologInteger newInteger() {
275 return newInteger(0);
276 }
277
278 public final PrologLong newLong() {
279 return newLong(0L);
280 }
281
282 public final PrologList newList(PrologTerm head) {
283 return newList(new PrologTerm[] { head });
284 }
285
286 public final PrologList newList(Object head) {
287 return newList(getJavaConverter().toTerm(head));
288 }
289
290 public final PrologList newList(Object[] arguments) {
291 return newList(getJavaConverter().toTermsArray(arguments));
292 }
293
294 public final PrologList newList(Object head, Object tail) {
295 PrologJavaConverter transformer = getJavaConverter();
296 PrologTerm headTerm = transformer.toTerm(head);
297 PrologTerm tailTerm = transformer.toTerm(tail);
298 return newList(headTerm, tailTerm);
299 }
300
301 public final PrologList newList(Object[] arguments, Object tail) {
302 PrologJavaConverter transformer = getJavaConverter();
303 PrologTerm[] array = transformer.toTermsArray(arguments);
304 PrologTerm tailTerm = transformer.toTerm(tail);
305 return newList(array, tailTerm);
306 }
307
308 public final PrologTerm newStructure(String functor, Object... arguments) {
309 PrologJavaConverter transformer = getJavaConverter();
310 PrologTerm[] parameters = transformer.toTermsArray(arguments);
311 return newStructure(functor, parameters);
312 }
313
314 public final PrologTerm newStructure(Object left, String operator, Object right) {
315 PrologJavaConverter transformer = getJavaConverter();
316 PrologTerm leftTerm = transformer.toTerm(left);
317 PrologTerm rightTerm = transformer.toTerm(right);
318 return newStructure(leftTerm, operator, rightTerm);
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333 protected final <T extends PrologTerm> T cast(PrologTerm term, Class<T> type) {
334 return type.cast(term);
335 }
336
337 public final <T extends PrologTerm> T cast(PrologTerm term) {
338 return (T) term;
339 }
340
341 public final <K extends PrologTerm> K toTerm(Object o, Class<K> from) {
342 return converter.toTerm(o, from);
343 }
344
345 public final <K extends PrologTerm> K[] toTermArray(Object[] os, Class<K[]> from) {
346 return converter.toTermArray(os, from);
347 }
348
349 public final <K extends PrologTerm> K[][] toTermMatrix(Object[][] oss, Class<K[][]> from) {
350 return converter.toTermMatrix(oss, from);
351 }
352
353 public final <K extends PrologTerm, V extends Object> Map<String, PrologTerm> toTermMap(Map<String, V> map,
354 Class<K> from) {
355 return converter.toTermMap(map, from);
356 }
357
358 public final <K extends PrologTerm, V extends Object> Map<String, PrologTerm>[] toTermMapArray(Map<String, V>[] map,
359 Class<K> from) {
360 return converter.toTermMapArray(map, from);
361 }
362
363 public final PrologConverter<?> getConverter() {
364 return converter;
365 }
366
367 public final <K> K fromTerm(PrologTerm term, Class<K> to) {
368 return converter.fromTerm(term, to);
369 }
370
371 public final <K> K[] fromTermArray(PrologTerm[] terms, Class<K[]> to) {
372 return converter.fromTermArray(terms, to);
373 }
374
375 public final <K> K fromTerm(PrologTerm head, PrologTerm[] body, Class<K> to) {
376 return converter.fromTerm(head, body, to);
377 }
378
379 public final PrologParser getParser() {
380 return this;
381 }
382
383 public final String getVersion() {
384 return newEngine().getVersion();
385 }
386
387 public final String getName() {
388 return newEngine().getName();
389 }
390
391 public int hashCode() {
392 final int prime = 31;
393 int result = 1;
394 result = prime * result + ((converter == null) ? 0 : converter.hashCode());
395 return result;
396 }
397
398 public boolean equals(Object object) {
399 if (this == object)
400 return true;
401 if (object == null)
402 return false;
403 if (getClass() != object.getClass())
404 return false;
405 AbstractProvider other = (AbstractProvider) object;
406 if (converter == null) {
407 if (other.converter != null)
408 return false;
409 } else if (!converter.equals(other.converter)) {
410 return false;
411 }
412 return true;
413 }
414
415 public abstract String toString();
416
417 private final void checkListType(PrologTerm term) {
418 if (!term.isList()) {
419 throw new ListExpectedError(term);
420 }
421 }
422
423 private final void checkStructureType(PrologTerm term) {
424 if (!term.isStructure()) {
425 throw new StructureExpectedError(term);
426 }
427 }
428
429 }