View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi
4    * %%
5    * Copyright (C) 2019 Prolobjectlink Project
6    * %%
7    * Permission is hereby granted, free of charge, to any person obtaining a copy
8    * of this software and associated documentation files (the "Software"), to deal
9    * in the Software without restriction, including without limitation the rights
10   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   * copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   * 
14   * The above copyright notice and this permission notice shall be included in
15   * all copies or substantial portions of the Software.
16   * 
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   * THE SOFTWARE.
24   * #L%
25   */
26  package io.github.prolobjectlink.prolog;
27  
28  import static io.github.prolobjectlink.prolog.PrologLogger.IO;
29  
30  import java.io.IOException;
31  import java.io.Writer;
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.Collection;
35  import java.util.HashMap;
36  import java.util.HashSet;
37  import java.util.Iterator;
38  import java.util.LinkedHashSet;
39  import java.util.List;
40  import java.util.Map;
41  import java.util.NoSuchElementException;
42  import java.util.Set;
43  
44  /**
45   * Partial implementation of {@link PrologEngine}.
46   * 
47   * @author Jose Zalacain
48   * @since 1.0
49   */
50  public abstract class AbstractEngine implements PrologEngine {
51  
52  	protected final PrologProvider provider;
53  	private static final String UNKNOWN = "unknown";
54  
55  	protected AbstractEngine(PrologProvider provider) {
56  		this.provider = provider;
57  	}
58  
59  	public final PrologProvider getProvider() {
60  		return provider;
61  	}
62  
63  	public final void persist(Writer writer) {
64  		PrologEngine thisEngine = this;
65  		for (PrologClause prologClause : thisEngine) {
66  			try {
67  				writer.write("" + prologClause + "");
68  			} catch (IOException e) {
69  				getLogger().error(getClass(), IO, e);
70  			}
71  		}
72  	}
73  
74  	public final boolean unify(PrologTerm t1, PrologTerm t2) {
75  		return t1.unify(t2);
76  	}
77  
78  	public Map<String, PrologTerm> match(PrologTerm t1, PrologTerm t2) {
79  		return queryOne(t1 + "=" + t2);
80  	}
81  
82  	public final boolean contains(String goal) {
83  		return query(goal).hasSolution();
84  	}
85  
86  	public final boolean contains(PrologTerm goal) {
87  		return query(goal).hasSolution();
88  	}
89  
90  	public final boolean contains(PrologTerm goal, PrologTerm... goals) {
91  		return query(goal, goals).hasSolution();
92  	}
93  
94  	public final Map<String, PrologTerm> queryOne(String goal) {
95  		return query(goal).oneVariablesSolution();
96  	}
97  
98  	public final Map<String, PrologTerm> queryOne(PrologTerm goal) {
99  		return query(goal).oneVariablesSolution();
100 	}
101 
102 	public final Map<String, PrologTerm> queryOne(PrologTerm goal, PrologTerm... goals) {
103 		return query(goal, goals).oneVariablesSolution();
104 	}
105 
106 	public final List<Map<String, PrologTerm>> queryN(int n, String goal) {
107 		return Arrays.asList(query(goal).nVariablesSolutions(n));
108 	}
109 
110 	public final List<Map<String, PrologTerm>> queryN(int n, PrologTerm term) {
111 		return Arrays.asList(query(term).nVariablesSolutions(n));
112 	}
113 
114 	public final List<Map<String, PrologTerm>> queryN(int n, PrologTerm term, PrologTerm... terms) {
115 		return Arrays.asList(query(term, terms).nVariablesSolutions(n));
116 	}
117 
118 	public final List<Map<String, PrologTerm>> queryAll(String goal) {
119 		return query(goal).all();
120 	}
121 
122 	public final List<Map<String, PrologTerm>> queryAll(PrologTerm goal) {
123 		return query(goal).all();
124 	}
125 
126 	public final List<Map<String, PrologTerm>> queryAll(PrologTerm goal, PrologTerm... goals) {
127 		return query(goal, goals).all();
128 	}
129 
130 	public final Map<String, List<PrologClause>> getProgramMap() {
131 		Map<String, List<PrologClause>> m = new HashMap<String, List<PrologClause>>();
132 		for (PrologClause clause : this) {
133 			String key = clause.getIndicator();
134 			List<PrologClause> l = m.get(key);
135 			if (l == null) {
136 				l = new ArrayList<PrologClause>();
137 				l.add(clause);
138 				m.put(key, l);
139 			} else {
140 				l.add(clause);
141 			}
142 		}
143 		return m;
144 	}
145 
146 	public final Set<PrologClause> getProgramClauses() {
147 		Set<PrologClause> c = new LinkedHashSet<PrologClause>();
148 		for (PrologClause prologClause : this) {
149 			c.add(prologClause);
150 		}
151 		return c;
152 	}
153 
154 	public final boolean isProgramEmpty() {
155 		return getProgramSize() == 0;
156 	}
157 
158 	public final Set<PrologIndicator> currentPredicates() {
159 		Set<PrologIndicator> pis = new HashSet<PrologIndicator>();
160 		pis.addAll(getPredicates());
161 		pis.addAll(getBuiltIns());
162 		return pis;
163 	}
164 
165 	public final DefaultQueryBuilder newQueryBuilder() {
166 		return new DefaultQueryBuilder(this);
167 	}
168 
169 	public final DefaultClauseBuilder newClauseBuilder() {
170 		return new DefaultClauseBuilder(this);
171 	}
172 
173 	public final boolean runOnOSX() {
174 		return getOSName().equals("Mac OS X") || getOSName().equals("Darwin");
175 	}
176 
177 	public final boolean runOnWindows() {
178 		return getOSName().startsWith("Windows");
179 	}
180 
181 	public final boolean runOnLinux() {
182 		return getOSName().equals("Linux");
183 	}
184 
185 	public final String getOSName() {
186 		String os = System.getProperty("os.name");
187 		if (os == null)
188 			return UNKNOWN;
189 		return os;
190 	}
191 
192 	public final String getOSVersion() {
193 		return System.getProperty("os.version");
194 	}
195 
196 	public final String getOSArch() {
197 		return System.getProperty("os.arch");
198 	}
199 
200 	public final PrologLogger getLogger() {
201 		return provider.getLogger();
202 	}
203 
204 	protected final <K extends PrologTerm> K toTerm(Object o, Class<K> from) {
205 		return provider.toTerm(o, from);
206 	}
207 
208 	protected final <K extends PrologTerm, V extends Object> Map<String, PrologTerm>[] toTermMapArray(
209 			Map<String, V>[] map, Class<K> from) {
210 		return provider.toTermMapArray(map, from);
211 	}
212 
213 	protected final <K> K fromTerm(PrologTerm term, Class<K> to) {
214 		return provider.fromTerm(term, to);
215 	}
216 
217 	protected final <K> K fromTerm(PrologTerm head, PrologTerm[] body, Class<K> to) {
218 		return provider.fromTerm(head, body, to);
219 	}
220 
221 	protected final String removeQuoted(String functor) {
222 		if (functor != null && functor.startsWith("\'") && functor.endsWith("\'")) {
223 			return functor.substring(1, functor.length() - 1);
224 		}
225 		return functor;
226 	}
227 
228 	@Override
229 	public final String toString() {
230 		return getName() + " " + getVersion();
231 	}
232 
233 	@Override
234 	public int hashCode() {
235 		final int prime = 31;
236 		int result = 1;
237 		result = prime * result + ((provider == null) ? 0 : provider.hashCode());
238 		return result;
239 	}
240 
241 	@Override
242 	public boolean equals(Object object) {
243 		if (this == object)
244 			return true;
245 		if (object == null)
246 			return false;
247 		if (getClass() != object.getClass())
248 			return false;
249 		AbstractEngine other = (AbstractEngine) object;
250 		if (provider == null) {
251 			if (other.provider != null)
252 				return false;
253 		} else if (!provider.equals(other.provider)) {
254 			return false;
255 		}
256 		return true;
257 	}
258 
259 	protected class PrologProgramIterator extends AbstractIterator<PrologClause> implements Iterator<PrologClause> {
260 
261 		private PrologClause last;
262 		private final Iterator<PrologClause> i;
263 
264 		public PrologProgramIterator(Collection<PrologClause> cls) {
265 			i = cls.iterator();
266 		}
267 
268 		public boolean hasNext() {
269 			return i.hasNext();
270 		}
271 
272 		public PrologClause next() {
273 			if (!i.hasNext()) {
274 				throw new NoSuchElementException();
275 			}
276 			last = i.next();
277 			return last;
278 		}
279 
280 		@Override
281 		public void remove() {
282 			PrologTerm h = last.getHead();
283 			PrologTerm b = last.getBody();
284 			retract(h, b);
285 			i.remove();
286 		}
287 
288 	}
289 
290 }