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.tuprolog;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import alice.tuprolog.MalformedGoalException;
30 import alice.tuprolog.NoMoreSolutionException;
31 import alice.tuprolog.NoSolutionException;
32 import alice.tuprolog.Prolog;
33 import alice.tuprolog.SolveInfo;
34 import alice.tuprolog.Struct;
35 import alice.tuprolog.Term;
36 import alice.tuprolog.Var;
37 import io.github.prolobjectlink.prolog.AbstractEngine;
38 import io.github.prolobjectlink.prolog.AbstractQuery;
39 import io.github.prolobjectlink.prolog.PrologLogger;
40 import io.github.prolobjectlink.prolog.PrologQuery;
41 import io.github.prolobjectlink.prolog.PrologTerm;
42
43
44
45
46
47
48 final class TuPrologQuery extends AbstractQuery implements PrologQuery {
49
50 private Prolog tuProlog;
51 private SolveInfo solution;
52
53 TuPrologQuery(AbstractEngine engine, String query) {
54 super(engine);
55 tuProlog = ((TuPrologEngine) engine).engine;
56 try {
57 solution = tuProlog.solve("" + query + ".");
58 } catch (MalformedGoalException e) {
59 getLogger().error(getClass(), PrologLogger.SYNTAX_ERROR, e);
60 }
61 }
62
63 TuPrologQuery(AbstractEngine engine, PrologTerm term) {
64 super(engine);
65 Term query = fromTerm(term, Term.class);
66 tuProlog = ((TuPrologEngine) engine).engine;
67 solution = tuProlog.solve(query);
68 }
69
70 TuPrologQuery(AbstractEngine engine, PrologTerm[] terms) {
71 super(engine);
72 if (terms != null && terms.length > 0) {
73 Term term = fromTerm(terms[terms.length - 1], Term.class);
74 for (int i = terms.length; i > 1; i--) {
75 term = new Struct(",", fromTerm(terms[i - 2], Term.class), term);
76 }
77 tuProlog = ((TuPrologEngine) engine).engine;
78 solution = tuProlog.solve(term);
79 }
80 }
81
82 TuPrologQuery(AbstractEngine engine, PrologTerm term, PrologTerm[] terms) {
83 super(engine);
84 Term query = fromTerm(term, Term.class);
85 if (terms != null && terms.length > 0) {
86 query = fromTerm(terms[terms.length - 1], Term.class);
87 for (int i = terms.length; i > 1; i--) {
88 query = new Struct(",", fromTerm(terms[i - 2], Term.class), query);
89 }
90 query = new Struct(",", fromTerm(term, Term.class), query);
91 }
92 tuProlog = ((TuPrologEngine) engine).engine;
93 solution = tuProlog.solve(query);
94 }
95
96 public boolean hasSolution() {
97 return solution != null && solution.isSuccess();
98 }
99
100 public boolean hasMoreSolutions() {
101 return tuProlog != null && tuProlog.hasOpenAlternatives();
102 }
103
104 public PrologTerm[] oneSolution() {
105 if (solution != null && solution.isSuccess()) {
106 try {
107 List<Var> vars = solution.getBindingVars();
108 PrologTerm[] array = new PrologTerm[vars.size()];
109 for (int i = 0; i < array.length; i++) {
110 array[i] = toTerm(vars.get(i).getTerm(), PrologTerm.class);
111 }
112 return array;
113 } catch (NoSolutionException e) {
114
115 }
116 }
117 return new PrologTerm[0];
118 }
119
120 public Map<String, PrologTerm> oneVariablesSolution() {
121 if (solution != null && solution.isSuccess()) {
122 try {
123 List<Var> vars = solution.getBindingVars();
124 Map<String, PrologTerm> map = new HashMap<String, PrologTerm>(vars.size());
125 for (Var var : vars) {
126 map.put(var.getName(), toTerm(var.getTerm(), PrologTerm.class));
127 }
128 return map;
129 } catch (NoSolutionException e) {
130
131 }
132 }
133 return new HashMap<String, PrologTerm>(0);
134 }
135
136 public PrologTerm[] nextSolution() {
137 try {
138 PrologTerm[] array = oneSolution();
139 if (hasMoreSolutions()) {
140 solution = tuProlog.solveNext();
141 }
142 return array;
143 } catch (NoMoreSolutionException e) {
144
145 }
146 return new PrologTerm[0];
147 }
148
149 public Map<String, PrologTerm> nextVariablesSolution() {
150 try {
151 Map<String, PrologTerm> map = oneVariablesSolution();
152 if (hasMoreSolutions()) {
153 solution = tuProlog.solveNext();
154 }
155 return map;
156 } catch (NoMoreSolutionException e) {
157
158 }
159 return new HashMap<String, PrologTerm>(0);
160 }
161
162 public PrologTerm[][] nSolutions(int n) {
163 if (n > 0) {
164
165 int m = 0;
166 int index = 0;
167 List<PrologTerm[]> all = new ArrayList<PrologTerm[]>();
168
169 PrologTerm[] array = oneSolution();
170 m = array.length > m ? array.length : m;
171 all.add(array);
172 index++;
173
174 while (hasMoreSolutions() && index < n) {
175 try {
176 solution = tuProlog.solveNext();
177 array = oneSolution();
178 if (array.length > 0 && !contains(all, array)) {
179 m = array.length > m ? array.length : m;
180 all.add(array);
181 index++;
182 }
183
184 } catch (NoMoreSolutionException e) {
185
186 }
187
188 }
189
190 PrologTerm[][] allSolutions = new PrologTerm[n][m];
191 for (int i = 0; i < n; i++) {
192 array = all.get(i);
193 for (int j = 0; j < m; j++) {
194 allSolutions[i][j] = array[j];
195 }
196 }
197 return allSolutions;
198 }
199 return new PrologTerm[0][0];
200 }
201
202 public Map<String, PrologTerm>[] nVariablesSolutions(int n) {
203 if (n > 0) {
204 int index = 0;
205 Map<String, PrologTerm>[] solutionMaps = new HashMap[n];
206
207 Map<String, PrologTerm> solutionMap = oneVariablesSolution();
208 solutionMaps[index++] = solutionMap;
209
210 while (hasMoreSolutions() && index < n) {
211 try {
212 TuPrologEngine pe = (TuPrologEngine) engine;
213 solution = pe.engine.solveNext();
214 solutionMap = oneVariablesSolution();
215 solutionMaps[index++] = solutionMap;
216 } catch (NoMoreSolutionException e) {
217
218 }
219 }
220 return solutionMaps;
221 }
222 return new HashMap[0];
223 }
224
225 public PrologTerm[][] allSolutions() {
226
227 int n = 0;
228 int m = 0;
229 List<PrologTerm[]> all = new ArrayList<PrologTerm[]>();
230
231 PrologTerm[] array = oneSolution();
232 if (array.length > 0) {
233 m = array.length > m ? array.length : m;
234 n++;
235 all.add(array);
236 }
237
238 while (hasMoreSolutions()) {
239 try {
240 solution = tuProlog.solveNext();
241 array = oneSolution();
242 if (array.length > 0 && !contains(all, array)) {
243 m = array.length > m ? array.length : m;
244 n++;
245 all.add(array);
246 }
247 } catch (NoMoreSolutionException e) {
248
249 }
250
251 }
252
253 PrologTerm[][] allSolutions = new PrologTerm[n][m];
254 for (int i = 0; i < n; i++) {
255 array = all.get(i);
256 for (int j = 0; j < m; j++) {
257 allSolutions[i][j] = array[j];
258 }
259 }
260 return allSolutions;
261 }
262
263 public Map<String, PrologTerm>[] allVariablesSolutions() {
264 return all().toArray(new Map[0]);
265 }
266
267 public List<Map<String, PrologTerm>> all() {
268 List<Map<String, PrologTerm>> allVariables = new ArrayList<Map<String, PrologTerm>>();
269
270 Map<String, PrologTerm> variables = oneVariablesSolution();
271 if (!variables.isEmpty()) {
272 allVariables.add(variables);
273 }
274
275 while (hasMoreSolutions()) {
276 try {
277 solution = tuProlog.solveNext();
278 variables = oneVariablesSolution();
279 if (!variables.isEmpty() && !contains(allVariables, variables)) {
280 allVariables.add(variables);
281 }
282 } catch (NoMoreSolutionException e) {
283
284 }
285 }
286
287 return allVariables;
288 }
289
290 @Override
291 public String toString() {
292 return "" + solution.getQuery() + "";
293 }
294
295 public void dispose() {
296 solution = null;
297 }
298
299 @Override
300 public int hashCode() {
301 final int prime = 31;
302 int result = super.hashCode();
303 result = prime * result + ((solution == null) ? 0 : solution.hashCode());
304 result = prime * result + ((tuProlog == null) ? 0 : tuProlog.hashCode());
305 return result;
306 }
307
308 @Override
309 public boolean equals(Object obj) {
310 if (this == obj)
311 return true;
312 if (!super.equals(obj))
313 return false;
314 if (getClass() != obj.getClass())
315 return false;
316 TuPrologQuery other = (TuPrologQuery) obj;
317 if (solution == null) {
318 if (other.solution != null)
319 return false;
320 } else if (!solution.getQuery().equals(other.solution.getQuery())) {
321 return false;
322 }
323 return true;
324 }
325
326 }