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.jlog;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Enumeration;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import io.github.prolobjectlink.prolog.AbstractEngine;
32 import io.github.prolobjectlink.prolog.AbstractQuery;
33 import io.github.prolobjectlink.prolog.PrologQuery;
34 import io.github.prolobjectlink.prolog.PrologTerm;
35 import ubc.cs.JLog.Foundation.jKnowledgeBase;
36 import ubc.cs.JLog.Foundation.jPrologAPI;
37 import ubc.cs.JLog.Foundation.jVariableVector;
38 import ubc.cs.JLog.Parser.pOperatorRegistry;
39 import ubc.cs.JLog.Parser.pParseStream;
40 import ubc.cs.JLog.Parser.pPredicateRegistry;
41 import ubc.cs.JLog.Terms.jPredicateTerms;
42 import ubc.cs.JLog.Terms.jVariable;
43
44
45
46
47
48
49 final class JLogQuery extends AbstractQuery implements PrologQuery {
50
51 private Map<?, ?> solution;
52 private jPrologAPI jlogApi;
53 private jVariableVector vector = new jVariableVector();
54
55 private static final String PROLOG_EXCEPTION = "PrologException";
56 private static final String JAVA_EXCEPTION = "JavaException";
57
58 protected JLogQuery(AbstractEngine engine, String str) {
59 super(engine);
60
61
62 str = JLogUtil.rectify(str);
63 JLogEngine pe = (JLogEngine) engine;
64 jKnowledgeBase kb = pe.engine.getKnowledgeBase();
65 pOperatorRegistry or = pe.engine.getOperatorRegistry();
66 pPredicateRegistry pr = pe.engine.getPredicateRegistry();
67 String s = str.charAt(str.length() - 1) == '.' ? str : str + '.';
68 pParseStream parser = new pParseStream(s, kb, pr, or);
69 jPredicateTerms terms = parser.parseQuery();
70 terms.enumerateVariables(vector, true);
71
72
73 String source = JLogUtil.toString(pe.engine);
74 jlogApi = new jPrologAPI(source);
75 try {
76 solution = jlogApi.query(s);
77 } catch (Exception e) {
78 solution = null;
79
80 Map<String, PrologTerm> m = new HashMap<String, PrologTerm>();
81 JLogReference prologexception = new JLogReference(getProvider(), e);
82 m.put("PrologException", prologexception);
83 m.put(JAVA_EXCEPTION, prologexception);
84 solution = m;
85 }
86
87 }
88
89 JLogQuery(AbstractEngine engine, PrologTerm term) {
90 super(engine);
91
92 String str = "" + term + "";
93
94
95 str = JLogUtil.rectify(str);
96 JLogEngine pe = (JLogEngine) engine;
97 jKnowledgeBase kb = pe.engine.getKnowledgeBase();
98 pOperatorRegistry or = pe.engine.getOperatorRegistry();
99 pPredicateRegistry pr = pe.engine.getPredicateRegistry();
100 pParseStream parser = new pParseStream(str + '.', kb, pr, or);
101 jPredicateTerms jpts = parser.parseQuery();
102 jpts.enumerateVariables(vector, true);
103
104
105 String source = JLogUtil.toString(pe.engine);
106 jlogApi = new jPrologAPI(source);
107 try {
108 solution = jlogApi.query(str + '.');
109 } catch (Exception e) {
110 solution = null;
111
112 Map<String, PrologTerm> m = new HashMap<String, PrologTerm>();
113 JLogReference prologexception = new JLogReference(getProvider(), e);
114 m.put(PROLOG_EXCEPTION, prologexception);
115 m.put(JAVA_EXCEPTION, prologexception);
116 solution = m;
117 }
118
119 }
120
121 protected JLogQuery(AbstractEngine engine, PrologTerm[] terms) {
122 super(engine);
123
124 if (terms != null && terms.length > 0) {
125
126 String str = Arrays.toString(terms).substring(1);
127 str = str.substring(0, str.length() - 1) + '.';
128
129
130 str = JLogUtil.rectify(str);
131 JLogEngine pe = (JLogEngine) engine;
132 jKnowledgeBase kb = pe.engine.getKnowledgeBase();
133 pOperatorRegistry or = pe.engine.getOperatorRegistry();
134 pPredicateRegistry pr = pe.engine.getPredicateRegistry();
135 pParseStream parser = new pParseStream(str, kb, pr, or);
136 jPredicateTerms jpts = parser.parseQuery();
137 jpts.enumerateVariables(vector, true);
138
139
140 String source = JLogUtil.toString(pe.engine);
141 jlogApi = new jPrologAPI(source);
142 try {
143 solution = jlogApi.query(str);
144 } catch (Exception e) {
145 solution = null;
146
147 Map<String, PrologTerm> m = new HashMap<String, PrologTerm>();
148 JLogReference prologexception = new JLogReference(getProvider(), e);
149 m.put(PROLOG_EXCEPTION, prologexception);
150 m.put(JAVA_EXCEPTION, prologexception);
151 solution = m;
152 }
153
154 }
155
156 }
157
158 protected JLogQuery(AbstractEngine engine, PrologTerm term, PrologTerm[] terms) {
159 super(engine);
160
161 String str = "" + term + "";
162
163
164 str = JLogUtil.rectify(str);
165 JLogEngine pe = (JLogEngine) engine;
166 jKnowledgeBase kb = pe.engine.getKnowledgeBase();
167 pOperatorRegistry or = pe.engine.getOperatorRegistry();
168 pPredicateRegistry pr = pe.engine.getPredicateRegistry();
169 pParseStream parser = new pParseStream(str + '.', kb, pr, or);
170 jPredicateTerms jpts = parser.parseQuery();
171 jpts.enumerateVariables(vector, true);
172
173 if (terms != null && terms.length > 0) {
174
175 str = str + ", " + Arrays.toString(terms).substring(1);
176 str = str.substring(0, str.length() - 1);
177
178
179 str = JLogUtil.rectify(str);
180 parser = new pParseStream(str + '.', kb, pr, or);
181 jpts = parser.parseQuery();
182 jpts.enumerateVariables(vector, true);
183
184 }
185
186
187 String source = JLogUtil.toString(pe.engine);
188 jlogApi = new jPrologAPI(source);
189 try {
190 solution = jlogApi.query(str + '.');
191 } catch (Exception e) {
192 solution = null;
193
194 Map<String, PrologTerm> m = new HashMap<String, PrologTerm>();
195 JLogReference prologexception = new JLogReference(getProvider(), e);
196 m.put(PROLOG_EXCEPTION, prologexception);
197 m.put(JAVA_EXCEPTION, prologexception);
198 solution = m;
199 }
200 }
201
202 public boolean hasSolution() {
203 return solution != null;
204 }
205
206 public boolean hasMoreSolutions() {
207 return solution != null;
208 }
209
210 public PrologTerm[] oneSolution() {
211 if (hasSolution()) {
212 int index = 0;
213 PrologTerm[] array = new PrologTerm[solution.size()];
214 for (Enumeration<?> e = vector.enumerate(); e.hasMoreElements() && index < solution.size();) {
215 Object object = e.nextElement();
216 if (object instanceof jVariable) {
217 String key = ((jVariable) object).getName();
218 array[index++] = JLogUtil.toTerm(getProvider(), solution.get(key));
219 }
220 }
221 return array;
222 }
223 return new PrologTerm[0];
224 }
225
226 public Map<String, PrologTerm> oneVariablesSolution() {
227 if (hasSolution()) {
228 Map<String, PrologTerm> varMap = new HashMap<String, PrologTerm>(solution.size());
229 for (Enumeration<?> e = vector.enumerate(); e.hasMoreElements();) {
230 Object object = e.nextElement();
231 if (object instanceof jVariable) {
232 String key = ((jVariable) object).getName();
233 varMap.put(key, JLogUtil.toTerm(getProvider(), solution.get(key)));
234 }
235 }
236 return varMap;
237 }
238 return new HashMap<String, PrologTerm>(0);
239 }
240
241 public PrologTerm[] nextSolution() {
242 PrologTerm[] array = oneSolution();
243 solution = jlogApi.retry();
244 return array;
245 }
246
247 public Map<String, PrologTerm> nextVariablesSolution() {
248 Map<String, PrologTerm> varMap = oneVariablesSolution();
249 solution = jlogApi.retry();
250 return varMap;
251 }
252
253 public PrologTerm[][] nSolutions(int n) {
254 if (n > 0) {
255 int m = 0;
256 int index = 0;
257 List<PrologTerm[]> all = new ArrayList<PrologTerm[]>();
258 while (hasMoreSolutions() && index < n) {
259 PrologTerm[] solutions = oneSolution();
260 m = solutions.length > m ? solutions.length : m;
261 all.add(solutions);
262 index++;
263 solution = jlogApi.retry();
264 }
265
266 PrologTerm[][] allSolutions = new PrologTerm[n][m];
267 for (int i = 0; i < n; i++) {
268 PrologTerm[] solutionArray = all.get(i);
269 System.arraycopy(solutionArray, 0, allSolutions[i], 0, m);
270 }
271 return allSolutions;
272 }
273 return new PrologTerm[0][0];
274 }
275
276 @SuppressWarnings("unchecked")
277 public Map<String, PrologTerm>[] nVariablesSolutions(int n) {
278 if (n > 0) {
279 int index = 0;
280 Map<String, PrologTerm>[] solutionMaps = new HashMap[n];
281 while (hasMoreSolutions() && index < n) {
282 Map<String, PrologTerm> solutionMap = oneVariablesSolution();
283 solutionMaps[index++] = solutionMap;
284 solution = jlogApi.retry();
285 }
286 return solutionMaps;
287 }
288 return new HashMap[0];
289 }
290
291 public PrologTerm[][] allSolutions() {
292
293 int n = 0;
294 int m = 0;
295 List<PrologTerm[]> all = new ArrayList<PrologTerm[]>();
296 while (hasMoreSolutions()) {
297 PrologTerm[] solutions = oneSolution();
298 m = solutions.length > m ? solutions.length : m;
299 n++;
300 all.add(solutions);
301 solution = jlogApi.retry();
302 }
303
304 PrologTerm[][] allSolutions = new PrologTerm[n][m];
305 for (int i = 0; i < n; i++) {
306 PrologTerm[] solutionArray = all.get(i);
307 System.arraycopy(solutionArray, 0, allSolutions[i], 0, m);
308 }
309 return allSolutions;
310 }
311
312 @SuppressWarnings("unchecked")
313 public Map<String, PrologTerm>[] allVariablesSolutions() {
314 List<Map<String, PrologTerm>> allVariables = new ArrayList<Map<String, PrologTerm>>();
315 while (hasMoreSolutions()) {
316 Map<String, PrologTerm> variables = oneVariablesSolution();
317 allVariables.add(variables);
318 solution = jlogApi.retry();
319 }
320
321 int lenght = allVariables.size();
322 Map<String, PrologTerm>[] allVariablesSolution = new HashMap[lenght];
323 for (int i = 0; i < lenght; i++) {
324 allVariablesSolution[i] = allVariables.get(i);
325 }
326 return allVariablesSolution;
327 }
328
329 public List<Map<String, PrologTerm>> all() {
330 List<Map<String, PrologTerm>> allVariables = new ArrayList<Map<String, PrologTerm>>();
331 while (hasMoreSolutions()) {
332 Map<String, PrologTerm> variables = oneVariablesSolution();
333 allVariables.add(variables);
334 solution = jlogApi.retry();
335 }
336 return allVariables;
337 }
338
339 @Override
340 public int hashCode() {
341 final int prime = 31;
342 int result = super.hashCode();
343 result = prime * result + ((solution == null) ? 0 : solution.hashCode());
344 return result;
345 }
346
347 @Override
348 public boolean equals(Object obj) {
349 if (this == obj)
350 return true;
351 if (!super.equals(obj))
352 return false;
353 if (getClass() != obj.getClass())
354 return false;
355 JLogQuery other = (JLogQuery) obj;
356 if (solution == null) {
357 if (other.solution != null)
358 return false;
359 } else if (!solution.equals(other.solution)) {
360 return false;
361 }
362 return true;
363 }
364
365 public void dispose() {
366 vector = new jVariableVector();
367 if (solution != null) {
368 solution.clear();
369 }
370 jlogApi.stop();
371 }
372
373 }