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