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  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  		
87  	}
88  
89  	public void unmarkDynamic(String functor, int arity) {
90  		
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  		
99  	}
100 
101 	public void unmarkMultifile(String functor, int arity) {
102 		
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 		
111 	}
112 
113 	public void unmarkDiscontiguous(String functor, int arity) {
114 		
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 }