View Javadoc

1   /*-
2    * #%L
3    * prolobjectlink-jpi
4    * %%
5    * Copyright (C) 2020 - 2021 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 java.util.AbstractMap;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Set;
35  
36  public abstract class AbstractProgram extends AbstractMap<String, PrologClauses> implements PrologProgram {
37  
38  	protected final PrologEngine engine;
39  
40  	protected AbstractProgram(PrologEngine engine) {
41  		this.engine = engine;
42  	}
43  
44  	public Iterator<PrologClauses> iterator() {
45  		return getClauses().values().iterator();
46  	}
47  
48  	public PrologClauses get(String functor, int arity) {
49  		String key = functor + "/" + arity;
50  		List<PrologClause> l = engine.getProgramMap().get(key);
51  		PrologClauses clauses = newClauses(functor, arity);
52  		for (PrologClause prologClause : l) {
53  			clauses.add(prologClause);
54  		}
55  		return clauses;
56  	}
57  
58  	public void add(PrologClause clause) {
59  		engine.assertz(clause.getHead(), clause.getBody());
60  	}
61  
62  	public void add(PrologProgram program) {
63  		for (PrologClauses prologClauses : program) {
64  			for (PrologClause clause : prologClauses) {
65  				engine.assertz(clause.getHead(), clause.getBody());
66  			}
67  		}
68  	}
69  
70  	public void push(PrologClause clause) {
71  		engine.asserta(clause.getHead(), clause.getBody());
72  	}
73  
74  	public void removeAll(String key) {
75  		String functor = key.substring(0, key.lastIndexOf('/'));
76  		String number = key.substring(key.lastIndexOf('/') + 1, key.length());
77  		int arity = Integer.parseInt(number);
78  		engine.abolish(functor, arity);
79  	}
80  
81  	public void removeAll(String functor, int arity) {
82  		engine.abolish(functor, arity);
83  	}
84  
85  	public void markDynamic(String functor, int arity) {
86  		// do nothing
87  	}
88  
89  	public void unmarkDynamic(String functor, int arity) {
90  		// do nothing
91  	}
92  
93  	public boolean isDynamic(String functor, int arity) {
94  		return getClauses().get(functor + "/" + arity).isDynamic();
95  	}
96  
97  	public void markMultifile(String functor, int arity) {
98  		// do nothing
99  	}
100 
101 	public void unmarkMultifile(String functor, int arity) {
102 		// do nothing
103 	}
104 
105 	public boolean isMultifile(String functor, int arity) {
106 		return getClauses().get(functor + "/" + arity).isMultifile();
107 	}
108 
109 	public void markDiscontiguous(String functor, int arity) {
110 		// do nothing
111 	}
112 
113 	public void unmarkDiscontiguous(String functor, int arity) {
114 		// do nothing
115 	}
116 
117 	public boolean isDiscontiguous(String functor, int arity) {
118 		return getClauses().get(functor + "/" + arity).isDiscontiguous();
119 	}
120 
121 	public boolean removeAll(PrologProgram program) {
122 		for (Entry<String, PrologClauses> entry : program.entrySet()) {
123 			getClauses().remove(entry.getKey());
124 		}
125 		return true;
126 	}
127 
128 	public boolean removeAll(PrologClauses clauses) {
129 		getClauses().remove(clauses.getIndicator());
130 		return true;
131 	}
132 
133 	public Map<String, PrologClauses> getClauses() {
134 		Map<String, List<PrologClause>> p = engine.getProgramMap();
135 		Map<String, PrologClauses> m = new HashMap<String, PrologClauses>(p.size());
136 		for (List<PrologClause> clauses : p.values()) {
137 			for (PrologClause clause : clauses) {
138 				PrologClauses c = m.get(clause.getIndicator());
139 				if (c == null) {
140 					c = newClauses(clause.getFunctor(), clause.getArity());
141 				}
142 				c.add(clause);
143 			}
144 		}
145 		return m;
146 	}
147 
148 	public Set<String> getIndicators() {
149 		Set<PrologIndicator> is = engine.currentPredicates();
150 		Set<String> i = new HashSet<String>(is.size());
151 		for (PrologIndicator prologIndicator : is) {
152 			i.add(prologIndicator.toString());
153 		}
154 		return i;
155 	}
156 
157 	public void add(PrologClauses clauses) {
158 		for (PrologClause prologClause : clauses) {
159 			engine.assertz(prologClause.getHead(), prologClause.getBody());
160 		}
161 	}
162 
163 	public void addAll(PrologProgram program) {
164 		for (PrologClauses clauses : program) {
165 			for (PrologClause prologClause : clauses) {
166 				engine.assertz(prologClause.getHead(), prologClause.getBody());
167 			}
168 		}
169 	}
170 
171 	public boolean retainAll(PrologClauses parents) {
172 		Map<String, PrologClauses> m = getClauses();
173 		for (PrologClauses prologClauses : m.values()) {
174 			if (!parents.contains((Object) prologClauses)) {
175 				String functor = prologClauses.get(0).getFunctor();
176 				int arity = prologClauses.get(0).getArity();
177 				engine.abolish(functor, arity);
178 			}
179 		}
180 		return true;
181 	}
182 
183 	public Object[] toArray(PrologClauses[] prologClauses) {
184 		return getClauses().values().toArray(prologClauses);
185 	}
186 
187 	public Object[] toArray() {
188 		return getClauses().values().toArray();
189 	}
190 
191 	public Set<Entry<String, PrologClauses>> entrySet() {
192 		return getClauses().entrySet();
193 	}
194 
195 	@Override
196 	public int hashCode() {
197 		final int prime = 31;
198 		int result = super.hashCode();
199 		result = prime * result + ((engine == null) ? 0 : engine.hashCode());
200 		return result;
201 	}
202 
203 	@Override
204 	public boolean equals(Object obj) {
205 		if (this == obj)
206 			return true;
207 		if (!super.equals(obj))
208 			return false;
209 		if (getClass() != obj.getClass())
210 			return false;
211 		AbstractProgram other = (AbstractProgram) obj;
212 		if (engine == null) {
213 			if (other.engine != null)
214 				return false;
215 		} else if (!engine.equals(other.engine)) {
216 			return false;
217 		}
218 		return true;
219 	}
220 
221 	@Override
222 	public String toString() {
223 		return "AbstractProgram [engine=" + engine + "]";
224 	}
225 
226 }