diff options
| author | yzhou <yujiao.zhou@gmail.com> | 2015-04-21 10:34:27 +0100 |
|---|---|---|
| committer | yzhou <yujiao.zhou@gmail.com> | 2015-04-21 10:34:27 +0100 |
| commit | 9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8 (patch) | |
| tree | 47511c0fb89dccff0db4b5990522e04f294d795b /src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java | |
| parent | b1ac207612ee8b045244253fb94b866104bc34f2 (diff) | |
| download | ACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.tar.gz ACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.zip | |
initial version
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java')
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java b/src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java new file mode 100644 index 0000000..11b0c75 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/query/rollup/QueryGraph.java | |||
| @@ -0,0 +1,383 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.query.rollup; | ||
| 2 | |||
| 3 | import java.util.HashMap; | ||
| 4 | import java.util.HashSet; | ||
| 5 | import java.util.Iterator; | ||
| 6 | import java.util.Map; | ||
| 7 | import java.util.Set; | ||
| 8 | |||
| 9 | import org.semanticweb.HermiT.model.Atom; | ||
| 10 | import org.semanticweb.HermiT.model.AtomicConcept; | ||
| 11 | import org.semanticweb.HermiT.model.AtomicRole; | ||
| 12 | import org.semanticweb.HermiT.model.Constant; | ||
| 13 | import org.semanticweb.HermiT.model.Individual; | ||
| 14 | import org.semanticweb.HermiT.model.Term; | ||
| 15 | import org.semanticweb.HermiT.model.Variable; | ||
| 16 | import org.semanticweb.owlapi.model.IRI; | ||
| 17 | import org.semanticweb.owlapi.model.OWLAxiom; | ||
| 18 | import org.semanticweb.owlapi.model.OWLClass; | ||
| 19 | import org.semanticweb.owlapi.model.OWLClassExpression; | ||
| 20 | import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; | ||
| 21 | import org.semanticweb.owlapi.model.OWLDataAllValuesFrom; | ||
| 22 | import org.semanticweb.owlapi.model.OWLDataExactCardinality; | ||
| 23 | import org.semanticweb.owlapi.model.OWLDataFactory; | ||
| 24 | import org.semanticweb.owlapi.model.OWLDataHasValue; | ||
| 25 | import org.semanticweb.owlapi.model.OWLDataMaxCardinality; | ||
| 26 | import org.semanticweb.owlapi.model.OWLDataMinCardinality; | ||
| 27 | import org.semanticweb.owlapi.model.OWLDataSomeValuesFrom; | ||
| 28 | import org.semanticweb.owlapi.model.OWLIndividual; | ||
| 29 | import org.semanticweb.owlapi.model.OWLLiteral; | ||
| 30 | import org.semanticweb.owlapi.model.OWLNamedIndividual; | ||
| 31 | import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom; | ||
| 32 | import org.semanticweb.owlapi.model.OWLObjectComplementOf; | ||
| 33 | import org.semanticweb.owlapi.model.OWLObjectExactCardinality; | ||
| 34 | import org.semanticweb.owlapi.model.OWLObjectHasSelf; | ||
| 35 | import org.semanticweb.owlapi.model.OWLObjectHasValue; | ||
| 36 | import org.semanticweb.owlapi.model.OWLObjectIntersectionOf; | ||
| 37 | import org.semanticweb.owlapi.model.OWLObjectMaxCardinality; | ||
| 38 | import org.semanticweb.owlapi.model.OWLObjectMinCardinality; | ||
| 39 | import org.semanticweb.owlapi.model.OWLObjectOneOf; | ||
| 40 | import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; | ||
| 41 | import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; | ||
| 42 | import org.semanticweb.owlapi.model.OWLObjectUnionOf; | ||
| 43 | import org.semanticweb.owlapi.model.OWLOntology; | ||
| 44 | |||
| 45 | public class QueryGraph { | ||
| 46 | |||
| 47 | Set<Variable> freeVars = new HashSet<Variable>(); | ||
| 48 | Set<Variable> existVars = new HashSet<Variable>(); | ||
| 49 | Set<Individual> constants = new HashSet<Individual>(); | ||
| 50 | |||
| 51 | MultiMap<Term, OWLClassExpression> concepts = new MultiMap<Term, OWLClassExpression>(); | ||
| 52 | MultiMap<Term, ObjectEdge> rollable_edges = new MultiMap<Term, ObjectEdge>(); | ||
| 53 | MultiMap<Term, ObjectEdge> edges = new MultiMap<Term, ObjectEdge>(); | ||
| 54 | OWLOntology ontology; | ||
| 55 | OWLDataFactory factory; | ||
| 56 | |||
| 57 | public QueryGraph(Atom[] bodyAtoms, String[] distinguishedVars, OWLOntology onto) { | ||
| 58 | for (String vName: distinguishedVars) | ||
| 59 | freeVars.add(Variable.create(vName)); | ||
| 60 | |||
| 61 | ontology = onto; | ||
| 62 | factory = onto.getOWLOntologyManager().getOWLDataFactory(); | ||
| 63 | |||
| 64 | for (Atom atom: bodyAtoms) { | ||
| 65 | if (atom.getArity() == 1) { | ||
| 66 | updateExistentiallyVariables(atom.getArgumentVariable(0)); | ||
| 67 | IRI iri = IRI.create(((AtomicConcept) atom.getDLPredicate()).getIRI()); | ||
| 68 | if (ontology.containsClassInSignature(iri)) | ||
| 69 | concepts.add(atom.getArgument(0), factory.getOWLClass(IRI.create(((AtomicConcept) atom.getDLPredicate()).getIRI()))); | ||
| 70 | } | ||
| 71 | else if (atom.getArity() == 2) { | ||
| 72 | updateExistentiallyVariables(atom.getArgumentVariable(0)); | ||
| 73 | updateExistentiallyVariables(atom.getArgumentVariable(1)); | ||
| 74 | if (atom.getArgument(0).equals(atom.getArgument(1)) && atom.getArgument(0) instanceof Variable) { | ||
| 75 | concepts.add(atom.getArgument(0), factory.getOWLObjectHasSelf(factory.getOWLObjectProperty(IRI.create(((AtomicRole) atom.getDLPredicate()).getIRI())))); | ||
| 76 | } | ||
| 77 | else createEdges(atom.getArgument(0), (AtomicRole) atom.getDLPredicate(), atom.getArgument(1)); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | rollup(); | ||
| 82 | } | ||
| 83 | |||
| 84 | private void updateExistentiallyVariables(Variable argumentVariable) { | ||
| 85 | if (freeVars.contains(argumentVariable)) return ; | ||
| 86 | existVars.add(argumentVariable); | ||
| 87 | } | ||
| 88 | |||
| 89 | public void createEdges(Term u, AtomicRole r, Term v) { | ||
| 90 | if (ontology.containsDataPropertyInSignature(IRI.create(r.getIRI()))) { | ||
| 91 | // edges.add(u, new DataEdge(r, v)); | ||
| 92 | Constant c = (Constant) v; | ||
| 93 | OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); | ||
| 94 | concepts.add(u, factory.getOWLDataHasValue(factory.getOWLDataProperty(IRI.create(r.getIRI())), l)); | ||
| 95 | } | ||
| 96 | else { | ||
| 97 | boolean rollable = existVars.contains(u) || existVars.contains(v); | ||
| 98 | |||
| 99 | ObjectEdge edge = new ObjectEdge(r, v, false); | ||
| 100 | if (rollable) { | ||
| 101 | rollable_edges.add(u, edge); | ||
| 102 | edge = new ObjectEdge(r, u, true); | ||
| 103 | rollable_edges.add(v, edge); | ||
| 104 | } | ||
| 105 | else edges.add(u, edge); | ||
| 106 | |||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | private void rollup() { | ||
| 111 | for (boolean updated = true; updated; ) { | ||
| 112 | updated = false; | ||
| 113 | |||
| 114 | Set<ObjectEdge> set; | ||
| 115 | for (Variable var: existVars) { | ||
| 116 | if ((set = rollable_edges.map.get(var)) != null && set.size() == 1) { | ||
| 117 | updated = true; | ||
| 118 | ObjectEdge edge = set.iterator().next(); | ||
| 119 | rollupEdge(edge.v, edge.p.getInverseProperty().getSimplified(), var, true); | ||
| 120 | set.clear(); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | if (updated) continue; | ||
| 124 | |||
| 125 | for (Variable var: existVars) { | ||
| 126 | set = rollable_edges.map.get(var); | ||
| 127 | if (set == null) continue; | ||
| 128 | for (Iterator<ObjectEdge> iter = set.iterator(); iter.hasNext(); ) { | ||
| 129 | ObjectEdge edge = iter.next(); | ||
| 130 | if (constants.contains(edge.v) || freeVars.contains(edge.v)) { | ||
| 131 | updated = true; | ||
| 132 | rollupEdge(var, edge.p, edge.v, false); | ||
| 133 | iter.remove(); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | } | ||
| 140 | |||
| 141 | private void rollupEdge(Term u, OWLObjectPropertyExpression op, Term v, boolean inverse) { | ||
| 142 | if (existVars.contains(v)) { | ||
| 143 | concepts.add(u, factory.getOWLObjectSomeValuesFrom(op, factory.getOWLObjectIntersectionOf(concepts.get(v)))); | ||
| 144 | } | ||
| 145 | else { | ||
| 146 | OWLIndividual obj = getOWLIndividual(v); | ||
| 147 | concepts.add(u, factory.getOWLObjectHasValue(op, obj)); | ||
| 148 | } | ||
| 149 | |||
| 150 | if (inverse) | ||
| 151 | removeRollableEdge(u, op, v); | ||
| 152 | else | ||
| 153 | removeRollableEdge(v, op.getInverseProperty().getSimplified(), u); | ||
| 154 | } | ||
| 155 | |||
| 156 | private void removeRollableEdge(Term u, OWLObjectPropertyExpression op, Term v) { | ||
| 157 | Set<ObjectEdge> set = rollable_edges.get(u); | ||
| 158 | ObjectEdge edge; | ||
| 159 | if (set != null) | ||
| 160 | for (Iterator<ObjectEdge> iter = set.iterator(); iter.hasNext(); ) { | ||
| 161 | edge = iter.next(); | ||
| 162 | if (edge.p.equals(op) && edge.v.equals(v)) iter.remove(); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | OWLNamedIndividual getOWLIndividual(Term t) { | ||
| 167 | if (freeVars.contains(t)) | ||
| 168 | return new VariableIndividual((Variable) t); | ||
| 169 | else if (t instanceof Variable) | ||
| 170 | return null; | ||
| 171 | else | ||
| 172 | return factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI())); | ||
| 173 | } | ||
| 174 | |||
| 175 | class ObjectEdge { | ||
| 176 | OWLObjectPropertyExpression p; | ||
| 177 | Term v; | ||
| 178 | |||
| 179 | public ObjectEdge(AtomicRole r, Term t, boolean inverse) { | ||
| 180 | p = factory.getOWLObjectProperty(IRI.create(r.getIRI())); | ||
| 181 | if (inverse) p = p.getInverseProperty(); | ||
| 182 | v = t; | ||
| 183 | |||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | class MultiMap<K, V> { | ||
| 188 | |||
| 189 | HashMap<K, Set<V>> map = new HashMap<K, Set<V>>(); | ||
| 190 | |||
| 191 | void add(K key, V value) { | ||
| 192 | Set<V> list = map.get(key); | ||
| 193 | if (list == null) | ||
| 194 | map.put(key, list = new HashSet<V>()); | ||
| 195 | list.add(value); | ||
| 196 | } | ||
| 197 | |||
| 198 | public Set<V> get(K v) { | ||
| 199 | return map.get(v); | ||
| 200 | } | ||
| 201 | |||
| 202 | public boolean isEmpty() { | ||
| 203 | for (Map.Entry<K, Set<V>> entry: map.entrySet()) | ||
| 204 | if (!entry.getValue().isEmpty()) | ||
| 205 | return false; | ||
| 206 | return true; | ||
| 207 | } | ||
| 208 | |||
| 209 | } | ||
| 210 | |||
| 211 | public Set<OWLAxiom> getPropertyAssertions(Map<Variable, Term> assignment) { | ||
| 212 | OWLIndividual sub, obj; | ||
| 213 | Set<OWLAxiom> axioms = new HashSet<OWLAxiom>(); | ||
| 214 | for (Map.Entry<Term, Set<ObjectEdge>> entry: edges.map.entrySet()) { | ||
| 215 | sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); | ||
| 216 | for (ObjectEdge edge: entry.getValue()) { | ||
| 217 | obj = factory.getOWLNamedIndividual(IRI.create(getIndividual(edge.v, assignment).getIRI())); | ||
| 218 | axioms.add(factory.getOWLObjectPropertyAssertionAxiom(edge.p, sub, obj)); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | return axioms; | ||
| 222 | } | ||
| 223 | |||
| 224 | public Set<OWLAxiom> getAssertions(Map<Variable, Term> assignment) { | ||
| 225 | if (!rollable_edges.isEmpty()) return null; | ||
| 226 | |||
| 227 | OWLIndividual sub; | ||
| 228 | Visitor visitor = new Visitor(factory, assignment); | ||
| 229 | Set<OWLAxiom> axioms = getPropertyAssertions(assignment); | ||
| 230 | for (Map.Entry<Term, Set<OWLClassExpression>> entry: concepts.map.entrySet()) { | ||
| 231 | if (existVars.contains(entry.getKey())) continue; | ||
| 232 | sub = factory.getOWLNamedIndividual(IRI.create(getIndividual(entry.getKey(), assignment).getIRI())); | ||
| 233 | for (OWLClassExpression clsExp: entry.getValue()) { | ||
| 234 | axioms.add(factory.getOWLClassAssertionAxiom(clsExp.accept(visitor), sub)); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | return axioms; | ||
| 238 | } | ||
| 239 | |||
| 240 | private Individual getIndividual(Term key, Map<Variable, Term> assignment) { | ||
| 241 | if (key instanceof Individual) | ||
| 242 | return (Individual) key; | ||
| 243 | else | ||
| 244 | return (Individual) assignment.get(key); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | class Visitor implements OWLClassExpressionVisitorEx<OWLClassExpression> { | ||
| 249 | |||
| 250 | OWLDataFactory factory; | ||
| 251 | Map<Variable, Term> assignment; | ||
| 252 | |||
| 253 | public Visitor(OWLDataFactory factory, Map<Variable, Term> assignment) { | ||
| 254 | this.factory = factory; | ||
| 255 | this.assignment = assignment; | ||
| 256 | } | ||
| 257 | |||
| 258 | @Override | ||
| 259 | public OWLClassExpression visit(OWLClass ce) { | ||
| 260 | // TODO Auto-generated method stub | ||
| 261 | return ce; | ||
| 262 | } | ||
| 263 | |||
| 264 | @Override | ||
| 265 | public OWLClassExpression visit(OWLObjectIntersectionOf ce) { | ||
| 266 | Set<OWLClassExpression> clsExps = new HashSet<OWLClassExpression>(); | ||
| 267 | OWLClassExpression newExp; | ||
| 268 | boolean updated = false; | ||
| 269 | for (OWLClassExpression clsExp: ce.asConjunctSet()) { | ||
| 270 | clsExps.add(newExp = clsExp.accept(this)); | ||
| 271 | if (newExp != clsExp) updated = true; | ||
| 272 | } | ||
| 273 | |||
| 274 | if (updated) return factory.getOWLObjectIntersectionOf(clsExps); | ||
| 275 | else return ce; | ||
| 276 | } | ||
| 277 | |||
| 278 | @Override | ||
| 279 | public OWLClassExpression visit(OWLObjectUnionOf ce) { | ||
| 280 | // TODO Auto-generated method stub | ||
| 281 | return ce; | ||
| 282 | } | ||
| 283 | |||
| 284 | @Override | ||
| 285 | public OWLClassExpression visit(OWLObjectComplementOf ce) { | ||
| 286 | // TODO Auto-generated method stub | ||
| 287 | return ce; | ||
| 288 | } | ||
| 289 | |||
| 290 | @Override | ||
| 291 | public OWLClassExpression visit(OWLObjectSomeValuesFrom ce) { | ||
| 292 | OWLClassExpression newFiller = ce.getFiller().accept(this); | ||
| 293 | if (newFiller == ce.getFiller()) return ce; | ||
| 294 | return factory.getOWLObjectSomeValuesFrom(ce.getProperty(), newFiller); | ||
| 295 | } | ||
| 296 | |||
| 297 | @Override | ||
| 298 | public OWLClassExpression visit(OWLObjectAllValuesFrom ce) { | ||
| 299 | // TODO Auto-generated method stub | ||
| 300 | return ce; | ||
| 301 | } | ||
| 302 | |||
| 303 | @Override | ||
| 304 | public OWLClassExpression visit(OWLObjectHasValue ce) { | ||
| 305 | if (ce.getFiller() instanceof VariableIndividual) { | ||
| 306 | Individual c = (Individual) assignment.get(((VariableIndividual) ce.getFiller()).var); | ||
| 307 | OWLIndividual l = factory.getOWLNamedIndividual(IRI.create(c.getIRI())); | ||
| 308 | return factory.getOWLObjectHasValue(ce.getProperty(), l); | ||
| 309 | } | ||
| 310 | return ce; | ||
| 311 | } | ||
| 312 | |||
| 313 | @Override | ||
| 314 | public OWLClassExpression visit(OWLObjectMinCardinality ce) { | ||
| 315 | // TODO Auto-generated method stub | ||
| 316 | return ce; | ||
| 317 | } | ||
| 318 | |||
| 319 | @Override | ||
| 320 | public OWLClassExpression visit(OWLObjectExactCardinality ce) { | ||
| 321 | // TODO Auto-generated method stub | ||
| 322 | return ce; | ||
| 323 | } | ||
| 324 | |||
| 325 | @Override | ||
| 326 | public OWLClassExpression visit(OWLObjectMaxCardinality ce) { | ||
| 327 | // TODO Auto-generated method stub | ||
| 328 | return ce; | ||
| 329 | } | ||
| 330 | |||
| 331 | @Override | ||
| 332 | public OWLClassExpression visit(OWLObjectHasSelf ce) { | ||
| 333 | // TODO Auto-generated method stub | ||
| 334 | return ce; | ||
| 335 | } | ||
| 336 | |||
| 337 | @Override | ||
| 338 | public OWLClassExpression visit(OWLObjectOneOf ce) { | ||
| 339 | // TODO Auto-generated method stub | ||
| 340 | return ce; | ||
| 341 | } | ||
| 342 | |||
| 343 | @Override | ||
| 344 | public OWLClassExpression visit(OWLDataSomeValuesFrom ce) { | ||
| 345 | // TODO Auto-generated method stub | ||
| 346 | return ce; | ||
| 347 | } | ||
| 348 | |||
| 349 | @Override | ||
| 350 | public OWLClassExpression visit(OWLDataAllValuesFrom ce) { | ||
| 351 | // TODO Auto-generated method stub | ||
| 352 | return ce; | ||
| 353 | } | ||
| 354 | |||
| 355 | @Override | ||
| 356 | public OWLClassExpression visit(OWLDataHasValue ce) { | ||
| 357 | if (ce.getFiller() instanceof VariableConstant) { | ||
| 358 | Constant c = (Constant) assignment.get(((VariableConstant) ce.getFiller()).var); | ||
| 359 | OWLLiteral l = factory.getOWLLiteral(c.getLexicalForm(), c.getDatatypeURI()); | ||
| 360 | return factory.getOWLDataHasValue(ce.getProperty(), l); | ||
| 361 | } | ||
| 362 | return ce; | ||
| 363 | } | ||
| 364 | |||
| 365 | @Override | ||
| 366 | public OWLClassExpression visit(OWLDataMinCardinality ce) { | ||
| 367 | // TODO Auto-generated method stub | ||
| 368 | return ce; | ||
| 369 | } | ||
| 370 | |||
| 371 | @Override | ||
| 372 | public OWLClassExpression visit(OWLDataExactCardinality ce) { | ||
| 373 | // TODO Auto-generated method stub | ||
| 374 | return ce; | ||
| 375 | } | ||
| 376 | |||
| 377 | @Override | ||
| 378 | public OWLClassExpression visit(OWLDataMaxCardinality ce) { | ||
| 379 | // TODO Auto-generated method stub | ||
| 380 | return ce; | ||
| 381 | } | ||
| 382 | |||
| 383 | } \ No newline at end of file | ||
