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.jtrolog;
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.Iterator;
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.PrologProvider;
57 import io.github.prolobjectlink.prolog.PrologStructure;
58 import io.github.prolobjectlink.prolog.PrologTerm;
59 import io.github.prolobjectlink.prolog.PrologVariable;
60 import io.github.prolobjectlink.prolog.UnknownTermError;
61 import jTrolog.terms.Double;
62 import jTrolog.terms.Float;
63 import jTrolog.terms.Int;
64 import jTrolog.terms.Long;
65 import jTrolog.terms.Struct;
66 import jTrolog.terms.StructAtom;
67 import jTrolog.terms.Term;
68 import jTrolog.terms.Var;
69
70
71
72
73
74
75 final class JTrologConverter extends AbstractConverter<Term> implements PrologConverter<Term> {
76
77 private static final JTrologOperatorSet OPERATORS = new JTrologOperatorSet();
78
79 public PrologTerm toTerm(Term prologTerm) {
80 if (prologTerm.equals(Term.TRUE)) {
81 return new JTrologTrue(provider);
82 } else if (prologTerm.equals(Term.FALSE)) {
83 return new JTrologFalse(provider);
84 }
85
86
87
88
89 else if (prologTerm instanceof Double) {
90 return new JTrologDouble(provider, ((Double) prologTerm).doubleValue());
91 } else if (prologTerm instanceof Float) {
92 return new JTrologFloat(provider, ((Float) prologTerm).floatValue());
93 } else if (prologTerm instanceof Long) {
94 return new JTrologLong(provider, ((Long) prologTerm).longValue());
95 } else if (prologTerm instanceof Int) {
96 return new JTrologInteger(provider, ((Int) prologTerm).intValue());
97 } else if (prologTerm instanceof Var) {
98 Var var = (Var) prologTerm;
99 String name = var.toString();
100 PrologVariable v = sharedVariables.get(name);
101 if (v == null) {
102 v = new JTrologVariable(provider, name, var.nrInStruct);
103 sharedVariables.put(v.toString(), v);
104 }
105 return v;
106 } else if (prologTerm instanceof Struct) {
107
108 Struct struct = (Struct) prologTerm;
109 int arity = struct.arity;
110 String functor = struct.name;
111 Term[] arguments = new Term[arity];
112
113 if (struct == Term.emptyList) {
114 return new JTrologEmpty(provider);
115 }
116
117
118 else if (prologTerm instanceof StructAtom) {
119 if (functor.equals("nil")) {
120 return new JTrologNil(provider);
121 } else if (functor.equals("!")) {
122 return new JTrologCut(provider);
123 } else if (functor.equals("fail")) {
124 return new JTrologFail(provider);
125 } else {
126 return new JTrologAtom(provider, functor);
127 }
128 }
129
130
131 else if (struct.name.equals(".") && struct.arity == 2) {
132 ArrayList<Term> args = new ArrayList<Term>();
133 Iterator<?> i = Struct.iterator(struct);
134 while (i.hasNext()) {
135 Term term = (Term) i.next();
136 args.add(term);
137 }
138 return new JTrologList(provider, args.toArray(arguments));
139 }
140
141
142 else if (arity == 2 && OPERATORS.currentOp(functor)) {
143 Term left = struct.getArg(0);
144 Term right = struct.getArg(1);
145 return new JTrologStructure(provider, left, functor, right);
146 }
147
148
149 else {
150 for (int i = 0; i < arity; i++) {
151 arguments[i] = struct.getArg(i);
152 }
153 return new JTrologStructure(provider, functor, arguments);
154 }
155
156 } else {
157 throw new UnknownTermError(prologTerm);
158 }
159 }
160
161 public Term fromTerm(PrologTerm term) {
162 switch (term.getType()) {
163 case NIL_TYPE:
164 return new StructAtom("nil");
165 case CUT_TYPE:
166 return new StructAtom("!");
167 case FAIL_TYPE:
168 return new StructAtom("fail");
169 case TRUE_TYPE:
170 return Term.TRUE;
171 case FALSE_TYPE:
172 return Term.FALSE;
173 case ATOM_TYPE:
174 return new StructAtom(removeQuoted(((PrologAtom) term).getStringValue()));
175 case FLOAT_TYPE:
176 return new Float(((PrologFloat) term).getFloatValue());
177 case INTEGER_TYPE:
178 return new Int(((PrologInteger) term).getIntegerValue());
179 case DOUBLE_TYPE:
180 return new Double(((PrologDouble) term).getDoubleValue());
181 case LONG_TYPE:
182 return new Long(((PrologLong) term).getLongValue());
183 case VARIABLE_TYPE:
184 PrologVariable v = (PrologVariable) term;
185 String name = v.getName();
186 Term variable = sharedPrologVariables.get(name);
187 if (variable == null) {
188 variable = new Var(name, v.getPosition());
189 sharedPrologVariables.put(name, variable);
190 }
191 return variable;
192 case LIST_TYPE:
193 case MAP_TYPE:
194 PrologTerm[] elements = term.getArguments();
195 if (elements != null && elements.length > 0) {
196 Term list = Term.emptyList;
197 int offset = elements[elements.length - 1].isEmptyList() ? 2 : 1;
198 for (int i = elements.length - offset; i >= 0; --i) {
199 list = new Struct(".", new Term[] { fromTerm(elements[i], Term.class), list });
200 }
201 return list;
202 }
203 return Term.emptyList;
204 case STRUCTURE_TYPE:
205 case MAP_ENTRY_TYPE:
206 String functor = term.getFunctor();
207 if (term.getArity() < 1) {
208 if (!functor.matches(SIMPLE_ATOM_REGEX)) {
209 return new StructAtom("'" + functor + "'");
210 } else {
211 return new StructAtom(functor);
212 }
213 }
214 Term[] arguments = fromTermArray(((PrologStructure) term).getArguments());
215 return new Struct(functor, arguments);
216 case OBJECT_TYPE:
217 return new Struct("'@'", new Term[] { new StructAtom("'" + term.getObject() + "'") });
218 case PARAMETER_TYPE:
219 case RESULT_TYPE:
220 case FIELD_TYPE:
221 name = ((PrologVariable) term).getName();
222 int position = ((PrologVariable) term).getPosition();
223 return new Var(name, position);
224 case MIXIN_TYPE:
225 case CLASS_TYPE:
226 functor = removeQuoted(term.getFunctor());
227 arguments = fromTermArray(term.getArguments());
228 return new Struct(functor, arguments);
229 default:
230 throw new UnknownTermError(term);
231 }
232 }
233
234 public Term[] fromTermArray(PrologTerm[] terms) {
235 Term[] prologTerms = new Term[terms.length];
236 for (int i = 0; i < terms.length; i++) {
237 prologTerms[i] = fromTerm(terms[i]);
238 }
239 return prologTerms;
240 }
241
242 public Term fromTerm(PrologTerm head, PrologTerm[] body) {
243 Term h = fromTerm(head);
244 if (body != null && body.length > 0) {
245 Term b = fromTerm(body[body.length - 1]);
246 for (int i = body.length - 2; i >= 0; --i) {
247 b = new Struct(",", new Term[] { fromTerm(body[i]), b });
248 }
249 return new Struct(":-", new Term[] { h, b });
250 }
251 return new Struct(":-", new Term[] { h, Term.TRUE });
252 }
253
254 public PrologProvider createProvider() {
255 return new JTrolog(this);
256 }
257
258 @Override
259 public String toString() {
260 return "JTrologConverter";
261 }
262
263 }