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.ATOM_TYPE;
25 import static io.github.prolobjectlink.prolog.PrologTermType.CLASS_TYPE;
26 import static io.github.prolobjectlink.prolog.PrologTermType.CUT_TYPE;
27 import static io.github.prolobjectlink.prolog.PrologTermType.DOUBLE_TYPE;
28 import static io.github.prolobjectlink.prolog.PrologTermType.FAIL_TYPE;
29 import static io.github.prolobjectlink.prolog.PrologTermType.FALSE_TYPE;
30 import static io.github.prolobjectlink.prolog.PrologTermType.FIELD_TYPE;
31 import static io.github.prolobjectlink.prolog.PrologTermType.FLOAT_TYPE;
32 import static io.github.prolobjectlink.prolog.PrologTermType.INTEGER_TYPE;
33 import static io.github.prolobjectlink.prolog.PrologTermType.LIST_TYPE;
34 import static io.github.prolobjectlink.prolog.PrologTermType.LONG_TYPE;
35 import static io.github.prolobjectlink.prolog.PrologTermType.MAP_ENTRY_TYPE;
36 import static io.github.prolobjectlink.prolog.PrologTermType.MAP_TYPE;
37 import static io.github.prolobjectlink.prolog.PrologTermType.MIXIN_TYPE;
38 import static io.github.prolobjectlink.prolog.PrologTermType.NIL_TYPE;
39 import static io.github.prolobjectlink.prolog.PrologTermType.OBJECT_TYPE;
40 import static io.github.prolobjectlink.prolog.PrologTermType.PARAMETER_TYPE;
41 import static io.github.prolobjectlink.prolog.PrologTermType.RESULT_TYPE;
42 import static io.github.prolobjectlink.prolog.PrologTermType.STRUCTURE_TYPE;
43 import static io.github.prolobjectlink.prolog.PrologTermType.TRUE_TYPE;
44 import static io.github.prolobjectlink.prolog.PrologTermType.VARIABLE_TYPE;
45
46 import java.util.ArrayList;
47 import java.util.List;
48
49 import io.github.prolobjectlink.prolog.AbstractConverter;
50 import io.github.prolobjectlink.prolog.PrologAtom;
51 import io.github.prolobjectlink.prolog.PrologConverter;
52 import io.github.prolobjectlink.prolog.PrologDouble;
53 import io.github.prolobjectlink.prolog.PrologFloat;
54 import io.github.prolobjectlink.prolog.PrologInteger;
55 import io.github.prolobjectlink.prolog.PrologLong;
56 import io.github.prolobjectlink.prolog.PrologStructure;
57 import io.github.prolobjectlink.prolog.PrologTerm;
58 import io.github.prolobjectlink.prolog.PrologVariable;
59 import io.github.prolobjectlink.prolog.UnknownTermError;
60 import jpl.Atom;
61 import jpl.Compound;
62 import jpl.Float;
63 import jpl.Integer;
64 import jpl.JPL;
65 import jpl.JPLException;
66 import jpl.Query;
67 import jpl.Term;
68 import jpl.Variable;
69
70
71
72
73
74 public abstract class JplConverter extends AbstractConverter<Term> implements PrologConverter<Term> {
75
76 public final PrologTerm toTerm(Term prologTerm) {
77 if (prologTerm.isAtom()) {
78 String functor = prologTerm.name();
79 if (functor.equals("nil")) {
80 return new JplNil(provider);
81 } else if (functor.equals("!")) {
82 return new JplCut(createProvider());
83 } else if (functor.equals("fail")) {
84 return new JplFail(provider);
85 } else if (functor.equals("true")) {
86 return new JplTrue(provider);
87 } else if (functor.equals("false")) {
88 return new JplFalse(provider);
89 } else if (functor.equals("[]")) {
90 return new JplEmpty(provider);
91 }
92 return new JplAtom(provider, functor);
93 } else if (prologTerm.equals(JplList.EMPTY)) {
94 return new JplEmpty(provider);
95 } else if (prologTerm.isFloat()) {
96 return new JplFloat(provider, ((Float) prologTerm).floatValue());
97 } else if (prologTerm.isInteger()) {
98 try {
99 return new JplInteger(provider, ((Integer) prologTerm).intValue());
100 } catch (JPLException e) {
101 return new JplLong(provider, ((Integer) prologTerm).longValue());
102 }
103 } else if (prologTerm.isVariable()) {
104 String name = ((Variable) prologTerm).name();
105 PrologVariable variable = sharedVariables.get(name);
106 if (variable == null) {
107 variable = new JplVariable(provider, name);
108 sharedVariables.put(variable.getName(), variable);
109 }
110 return variable;
111 } else if (prologTerm.hasFunctor(".", 2)) {
112 Term[] a = new Term[0];
113 List<Term> l = new ArrayList<Term>();
114 Term ptr = prologTerm;
115 while (!ptr.isVariable() && ptr.hasFunctor(".", 2)) {
116 l.add(ptr.arg(1));
117 ptr = ptr.arg(2);
118 }
119 return new JplList(provider, l.toArray(a));
120 } else if (prologTerm.isCompound()) {
121
122 Compound compound = (Compound) prologTerm;
123 int arity = compound.arity();
124 String functor = compound.name();
125 Term[] arguments = new Term[arity];
126
127
128 if (functor.equals("@") && arity == 1) {
129 return new JplReference(provider, compound);
130 }
131
132
133 else if (arity == 2) {
134 String key = "LIST";
135 String opQuery = "findall(OP,current_op(_,_,OP)," + key + ")";
136 Query query = new Query(opQuery);
137 if (query.hasSolution()) {
138
139 Term term = (Term) query.oneSolution().get(key);
140 Term[] termArray = term.toTermArray();
141 for (Term termArray1 : termArray) {
142 if (termArray1.name().equals(functor)) {
143 Term left = compound.arg(1);
144 Term right = compound.arg(2);
145 return new JplStructure(provider, left, functor, right);
146 }
147 }
148
149 }
150 query.close();
151 }
152
153 for (int i = 0; i < arity; i++) {
154 arguments[i] = compound.arg(i + 1);
155 }
156 return new JplStructure(provider, functor, arguments);
157
158 }
159
160 throw new UnknownTermError(prologTerm);
161 }
162
163 public final Term fromTerm(PrologTerm term) {
164 switch (term.getType()) {
165 case NIL_TYPE:
166 return new Atom("nil");
167 case CUT_TYPE:
168 return new Atom("!");
169 case FAIL_TYPE:
170 return new Atom("fail");
171 case TRUE_TYPE:
172 return new Atom("true");
173 case FALSE_TYPE:
174 return new Atom("false");
175 case ATOM_TYPE:
176 return new Atom(removeQuoted(((PrologAtom) term).getStringValue()));
177 case FLOAT_TYPE:
178 return new Float(((PrologFloat) term).getFloatValue());
179 case INTEGER_TYPE:
180 return new Integer(((PrologInteger) term).getIntegerValue());
181 case DOUBLE_TYPE:
182 return new Float(((PrologDouble) term).getDoubleValue());
183 case LONG_TYPE:
184 return new Integer(((PrologLong) term).getLongValue());
185 case VARIABLE_TYPE:
186 String name = ((PrologVariable) term).getName();
187 Term variable = sharedPrologVariables.get(name);
188 if (variable == null) {
189 variable = new Variable(name);
190 sharedPrologVariables.put(name, variable);
191 }
192 return variable;
193 case LIST_TYPE:
194 case MAP_TYPE:
195 PrologTerm[] array = term.getArguments();
196 Term list = JplEmpty.EMPTY;
197 for (int i = array.length - 1; i >= 0; --i) {
198 list = new Compound(".", new Term[] { fromTerm(array[i]), list });
199 }
200 return list;
201 case STRUCTURE_TYPE:
202 case MAP_ENTRY_TYPE:
203 String functor = term.getFunctor();
204 Term[] arguments = fromTermArray(((PrologStructure) term).getArguments());
205 return new Compound(functor, arguments);
206 case OBJECT_TYPE:
207 return JPL.newJRef(term.getObject());
208 case PARAMETER_TYPE:
209 case RESULT_TYPE:
210 case FIELD_TYPE:
211 name = ((PrologVariable) term).getName();
212 variable = sharedPrologVariables.get(name);
213 if (variable == null) {
214 variable = new Variable(name);
215 sharedPrologVariables.put(name, variable);
216 }
217 return variable;
218 case MIXIN_TYPE:
219 case CLASS_TYPE:
220 functor = removeQuoted(term.getFunctor());
221 arguments = fromTermArray(term.getArguments());
222 return new Compound(functor, arguments);
223 default:
224 throw new UnknownTermError(term);
225 }
226 }
227
228 public final Term[] fromTermArray(PrologTerm[] terms) {
229 Term[] prologTerms = new Term[terms.length];
230 for (int i = 0; i < terms.length; i++) {
231 prologTerms[i] = fromTerm(terms[i]);
232 }
233 return prologTerms;
234 }
235
236 public final Term fromTerm(PrologTerm head, PrologTerm[] body) {
237 Term clauseHead = fromTerm(head);
238 if (body != null && body.length > 0) {
239 Term clauseBody = fromTerm(body[body.length - 1]);
240 for (int i = body.length - 2; i >= 0; --i) {
241 clauseBody = new Compound(",", new Term[] { fromTerm(body[i]), clauseBody });
242 }
243 return new Compound(":-", new Term[] { clauseHead, clauseBody });
244 }
245 return clauseHead;
246 }
247
248 }