aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
diff options
context:
space:
mode:
authoryzhou <yujiao.zhou@gmail.com>2015-04-21 10:34:27 +0100
committeryzhou <yujiao.zhou@gmail.com>2015-04-21 10:34:27 +0100
commit9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8 (patch)
tree47511c0fb89dccff0db4b5990522e04f294d795b /src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
parentb1ac207612ee8b045244253fb94b866104bc34f2 (diff)
downloadACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.tar.gz
ACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.zip
initial version
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java')
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java279
1 files changed, 279 insertions, 0 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java b/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
new file mode 100644
index 0000000..7e66411
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
@@ -0,0 +1,279 @@
1package uk.ac.ox.cs.pagoda.rules;
2
3import java.util.Collection;
4import java.util.HashMap;
5import java.util.Iterator;
6import java.util.LinkedList;
7import java.util.Map;
8
9import org.semanticweb.HermiT.model.AtLeast;
10import org.semanticweb.HermiT.model.AtLeastConcept;
11import org.semanticweb.HermiT.model.AtLeastDataRange;
12import org.semanticweb.HermiT.model.Atom;
13import org.semanticweb.HermiT.model.AtomicConcept;
14import org.semanticweb.HermiT.model.AtomicNegationConcept;
15import org.semanticweb.HermiT.model.AtomicRole;
16import org.semanticweb.HermiT.model.DLClause;
17import org.semanticweb.HermiT.model.DLPredicate;
18import org.semanticweb.HermiT.model.Individual;
19import org.semanticweb.HermiT.model.Inequality;
20import org.semanticweb.HermiT.model.InverseRole;
21import org.semanticweb.HermiT.model.LiteralConcept;
22import org.semanticweb.HermiT.model.Role;
23import org.semanticweb.HermiT.model.Term;
24import org.semanticweb.HermiT.model.Variable;
25import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
26import uk.ac.ox.cs.pagoda.util.Namespace;
27
28public class OverApproxExist implements Approximator {
29
30 @Override
31 public Collection<DLClause> convert(DLClause clause, DLClause originalClause) {
32 Collection<DLClause> ret;
33 switch (clause.getHeadLength()) {
34 case 1:
35 return overApprox(clause.getHeadAtom(0), clause.getBodyAtoms(), originalClause);
36 case 0:
37 ret = new LinkedList<DLClause>();
38 ret.add(clause);
39 return ret;
40 default:
41 ret = new LinkedList<DLClause>();
42 for (Iterator<DLClause> iter = new DisjunctiveHeads(clause, originalClause); iter.hasNext(); )
43 ret.add(iter.next());
44 return ret;
45 }
46 }
47
48 private static int noOfExistential(DLClause originalClause) {
49 int no = 0;
50 for (Atom atom: originalClause.getHeadAtoms())
51 if (atom.getDLPredicate() instanceof AtLeast)
52 no += ((AtLeast) atom.getDLPredicate()).getNumber();
53 return no;
54 }
55
56 private static int indexOfExistential(Atom headAtom, DLClause originalClause) {
57 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1;
58 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate();
59 if (alc.getToConcept() instanceof AtomicConcept) {
60 AtomicConcept ac = (AtomicConcept) alc.getToConcept();
61 if (ac.getIRI().endsWith(negativeSuffix)) {
62 alc = AtLeastConcept.create(alc.getNumber(), alc.getOnRole(), AtomicNegationConcept.create(getNegationConcept(ac)));
63 headAtom = Atom.create(alc, headAtom.getArgument(0));
64 }
65 }
66
67 int index = 0;
68 for (Atom atom: originalClause.getHeadAtoms()) {
69 if (atom.equals(headAtom))
70 return index;
71 if (atom.getDLPredicate() instanceof AtLeast)
72 index += ((AtLeast) atom.getDLPredicate()).getNumber();
73 }
74 return -1;
75 }
76
77 private static final Variable X = Variable.create("X");
78 public static final String negativeSuffix = "_neg";
79
80 public static AtomicConcept getNegationConcept(DLPredicate p) {
81 if (p.equals(AtomicConcept.THING)) return AtomicConcept.NOTHING;
82 if (p.equals(AtomicConcept.NOTHING)) return AtomicConcept.THING;
83
84 if (p instanceof AtomicConcept) {
85 String iri = ((AtomicConcept) p).getIRI();
86 if (iri.endsWith(negativeSuffix))
87 iri = iri.substring(0, iri.length() - 4);
88 else
89 iri += negativeSuffix;
90
91 return AtomicConcept.create(iri);
92 }
93 if (p instanceof AtLeastConcept) {
94 // FIXME !!! here
95 return null;
96 }
97 return null;
98 }
99
100 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
101
102 private static int individualCounter = 0;
103 private static Map<DLClause, Integer> individualNumber = new HashMap<DLClause, Integer>();
104
105 public static int getNumberOfSkolemisedIndividual() {
106 return individualCounter;
107 }
108
109 public static Individual getNewIndividual(DLClause originalClause, int offset) {
110 Individual ret;
111 if (individualNumber.containsKey(originalClause)) {
112 ret = Individual.create(skolemisedIndividualPrefix + (individualNumber.get(originalClause) + offset));
113 }
114 else {
115 individualNumber.put(originalClause, individualCounter);
116 ret = Individual.create(skolemisedIndividualPrefix + (individualCounter + offset));
117 individualCounter += noOfExistential(originalClause);
118 }
119 return ret;
120 }
121
122 public static int indexOfSkolemisedIndividual(Atom atom) {
123 Term t;
124 for (int index = 0; index < atom.getArity(); ++index) {
125 t = atom.getArgument(index);
126 if (t instanceof Individual && ((Individual) t).getIRI().contains(skolemisedIndividualPrefix)) return index;
127 }
128 return -1;
129 }
130
131 public Collection<DLClause> overApprox(Atom headAtom, Atom[] bodyAtoms, DLClause originalClause) {
132 return overApprox(headAtom, bodyAtoms, originalClause, indexOfExistential(headAtom, originalClause));
133 }
134
135 public Collection<DLClause> overApprox(Atom headAtom, Atom[] bodyAtoms, DLClause originalClause, int offset) {
136 Collection<DLClause> ret = new LinkedList<DLClause>();
137 DLPredicate predicate = headAtom.getDLPredicate();
138 if (predicate instanceof AtLeastConcept) {
139 AtLeastConcept atLeastConcept = (AtLeastConcept) predicate;
140 LiteralConcept concept = atLeastConcept.getToConcept();
141 Role role = atLeastConcept.getOnRole();
142 AtomicConcept atomicConcept = null;
143
144 if (concept instanceof AtomicNegationConcept) {
145 Atom atom1 = Atom.create(atomicConcept = ((AtomicNegationConcept) concept).getNegatedAtomicConcept(), X);
146 Atom atom2 = Atom.create(atomicConcept = getNegationConcept(atomicConcept), X);
147 ret.add(DLClause.create(new Atom[0], new Atom[] {atom1, atom2}));
148 }
149 else {
150 atomicConcept = (AtomicConcept) concept;
151 if (atomicConcept.equals(AtomicConcept.THING))
152 atomicConcept = null;
153 }
154
155 int card = atLeastConcept.getNumber();
156 Individual[] individuals = new Individual[card];
157 for (int i = 0; i < card; ++i) individuals[i] = getNewIndividual(originalClause, offset + i);
158
159 for (int i = 0; i < card; ++i) {
160 if (atomicConcept != null)
161 ret.add(DLClause.create(new Atom[] {Atom.create(atomicConcept, individuals[i])}, bodyAtoms));
162
163 Atom atom = role instanceof AtomicRole ?
164 Atom.create((AtomicRole) role, X, individuals[i]) :
165 Atom.create(((InverseRole) role).getInverseOf(), individuals[i], X);
166
167 ret.add(DLClause.create(new Atom[] {atom}, bodyAtoms));
168 }
169
170 for (int i = 0; i < card; ++i)
171 for (int j = i + 1; j < card; ++j)
172 // TODO to be checked ... different as
173 ret.add(DLClause.create(new Atom[] {Atom.create(Inequality.INSTANCE, individuals[i], individuals[j])}, bodyAtoms));
174 //DLClauseHelper.contructor_differentAs(individuals[i], individuals[j]));
175
176 }
177 else if (predicate instanceof AtLeastDataRange) {
178 // TODO to be implemented ...
179 }
180 else
181 ret.add(DLClause.create(new Atom[] {headAtom}, bodyAtoms));
182
183 return ret;
184 }
185
186 class DisjunctiveHeads implements Iterator<DLClause> {
187
188 Atom[] bodyAtoms;
189 Atom[][] disjunctHeadAtoms;
190 int[] pointer;
191 int length, l;
192 LinkedList<DLClause> auxiliaryClauses = new LinkedList<DLClause>();
193
194 public DisjunctiveHeads(DLClause clause, DLClause originalClause) {
195 length = clause.getHeadLength();
196
197 bodyAtoms = clause.getBodyAtoms();
198 disjunctHeadAtoms = new Atom[length][];
199 pointer = new int[length];
200 if (length > 0) l = length - 1;
201 else length = 0;
202
203 int index = 0, offset = 0;
204 Collection<DLClause> datalogRules;
205 DLClause newClause;
206 for (Atom headAtom: clause.getHeadAtoms()) {
207 pointer[index] = 0;
208
209 datalogRules = overApprox(headAtom, bodyAtoms, originalClause, offset);
210
211 if (datalogRules.isEmpty()) {
212 l = -1;
213 auxiliaryClauses.clear();
214 return ;
215 }
216
217 for (Iterator<DLClause> iter = datalogRules.iterator(); iter.hasNext(); ) {
218 newClause = iter.next();
219 if (!DLClauseHelper.hasSubsetBodyAtoms(newClause, clause)) {
220 auxiliaryClauses.add(newClause);
221 iter.remove();
222 }
223 }
224
225 disjunctHeadAtoms[index] = new Atom[datalogRules.size()];
226
227 int j = 0;
228 for (DLClause disjunct: datalogRules) {
229 disjunctHeadAtoms[index][j++] = disjunct.getHeadAtom(0);
230 }
231
232 ++index;
233 if (headAtom.getDLPredicate() instanceof AtLeast)
234 offset += ((AtLeast) headAtom.getDLPredicate()).getNumber();
235
236 }
237
238 }
239
240 @Override
241 public boolean hasNext() {
242 return l != -1 || !auxiliaryClauses.isEmpty();
243 }
244
245 @Override
246 public DLClause next() {
247 if (l == -1)
248 return auxiliaryClauses.removeFirst();
249
250 if (length > 0) {
251 Atom[] headAtoms = new Atom[length];
252 for (int i = 0; i < length; ++i)
253 headAtoms[i] = disjunctHeadAtoms[i][pointer[i]];
254
255 ++pointer[l];
256 while (l >= 0 && pointer[l] >= disjunctHeadAtoms[l].length) {
257 pointer[l] = 0;
258 --l;
259 if (l >= 0)
260 ++pointer[l];
261 }
262
263 if (l >= 0) l = length - 1;
264
265 return DLClauseHelper.simplified(DLClause.create(headAtoms, bodyAtoms));
266// return DLClause.create(headAtoms, bodyAtoms);
267 }
268 else {
269 --l;
270 return DLClauseHelper.simplified(DLClause.create(new Atom[0], bodyAtoms));
271// return DLClause.create(new Atom[0], bodyAtoms);
272 }
273 }
274
275 @Override
276 public void remove() { }
277
278 }
279}