From 4b7253559c290b6fdd1c4122830f153fda85dd62 Mon Sep 17 00:00:00 2001 From: RncLsn Date: Fri, 29 May 2015 18:35:51 +0100 Subject: Disposable. --- src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java | 1132 ++++++++--------- .../pagoda/multistage/MultiStageQueryEngine.java | 304 ++--- .../ox/cs/pagoda/multistage/StageQueryEngine.java | 4 - .../treatement/Pick4NegativeConcept.java | 357 +++--- .../treatement/Pick4NegativeConceptNaive.java | 12 +- .../Pick4NegativeConceptQuerySpecific.java | 136 +- .../multistage/treatement/SkolemTreatment.java | 33 - .../cs/pagoda/multistage/treatement/Treatment.java | 12 +- src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java | 2 +- src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java | 37 +- src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java | 5 +- src/uk/ac/ox/cs/pagoda/query/QueryRecord.java | 1327 +++++++++++--------- .../ox/cs/pagoda/reasoner/ConsistencyManager.java | 275 ++-- .../ox/cs/pagoda/reasoner/ELHOQueryReasoner.java | 160 +-- .../ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java | 352 +++--- .../ac/ox/cs/pagoda/reasoner/HermiTReasoner.java | 196 +-- .../ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java | 662 +++++----- src/uk/ac/ox/cs/pagoda/reasoner/QueryEngine.java | 18 +- src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java | 436 +++---- .../ac/ox/cs/pagoda/reasoner/RLQueryReasoner.java | 10 +- .../ac/ox/cs/pagoda/reasoner/RLUQueryReasoner.java | 13 +- .../cs/pagoda/reasoner/light/BasicQueryEngine.java | 720 +++++------ .../cs/pagoda/reasoner/light/KarmaQueryEngine.java | 155 +-- .../pagoda/reasoner/light/RDFoxAnswerTuples.java | 44 +- .../cs/pagoda/reasoner/light/RDFoxQueryEngine.java | 219 ++-- src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java | 116 +- src/uk/ac/ox/cs/pagoda/rules/Program.java | 456 ++++--- .../ox/cs/pagoda/tracking/TrackingRuleEncoder.java | 736 +++++------ .../tracking/TrackingRuleEncoderWithGap.java | 4 +- .../tracking/TrackingRuleEncoderWithoutGap.java | 16 +- .../ox/cs/pagoda/util/disposable/Disposable.java | 39 + .../pagoda/util/disposable/DisposedException.java | 12 + 32 files changed, 4103 insertions(+), 3897 deletions(-) delete mode 100644 src/uk/ac/ox/cs/pagoda/multistage/treatement/SkolemTreatment.java create mode 100644 src/uk/ac/ox/cs/pagoda/util/disposable/Disposable.java create mode 100644 src/uk/ac/ox/cs/pagoda/util/disposable/DisposedException.java (limited to 'src/uk/ac/ox/cs/pagoda') diff --git a/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java b/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java index b92bceb..638a151 100644 --- a/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java +++ b/src/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java @@ -23,577 +23,585 @@ import java.util.regex.Pattern; public class RLPlusOntology implements KnowledgeBase { - private static final String DEFAULT_ONTOLOGY_FILE_EXTENSION = "owl"; - private static final Pattern ONTOLOGY_ID_REGEX = Pattern.compile("ontologyid\\((?[a-z0-9\\-]+)\\)"); - OWLOntologyManager manager; - OWLDataFactory factory; - String ontologyIRI; - String corrFileName = null; - String outputPath, aBoxPath; - OWLOntology inputOntology = null; - OWLOntology tBox = null; - OWLOntology aBox = null; - OWLOntology restOntology = null; - OWLOntology outputOntology = null; //RL ontology - DLOntology dlOntology = null; - int rlCounter = 0; - LinkedList clauses; - Map correspondence; - BottomStrategy botStrategy; - Random random = new Random(19900114); - private Map subCounter = null; - private Map atomic2negation = new HashMap(); - - // FIXME multiple anonymous ontologies - @Override - public void load(OWLOntology ontology, uk.ac.ox.cs.pagoda.constraints.BottomStrategy bottomStrategy) { - if (bottomStrategy instanceof UnaryBottom) - botStrategy = BottomStrategy.UNARY; - else if (bottomStrategy instanceof NullaryBottom) - botStrategy = BottomStrategy.NULLARY; - else - botStrategy = BottomStrategy.TOREMOVE; - - if(corrFileName == null) - corrFileName = "rlplus.crr"; - manager = ontology.getOWLOntologyManager(); + private static final String DEFAULT_ONTOLOGY_FILE_EXTENSION = "owl"; + private static final Pattern ONTOLOGY_ID_REGEX = Pattern.compile("ontologyid\\((?[a-z0-9\\-]+)\\)"); + OWLOntologyManager manager; + OWLDataFactory factory; + String ontologyIRI; + String corrFileName = null; + String outputPath, aBoxPath; + OWLOntology inputOntology = null; + OWLOntology tBox = null; + OWLOntology aBox = null; + OWLOntology restOntology = null; + OWLOntology outputOntology = null; //RL ontology + DLOntology dlOntology = null; + int rlCounter = 0; + LinkedList clauses; + Map correspondence; + BottomStrategy botStrategy; + Random random = new Random(19900114); + private Map subCounter = null; + private Map atomic2negation = new HashMap(); + + // TODO don't know if it is correct + @Override + public void load(OWLOntology ontology, uk.ac.ox.cs.pagoda.constraints.BottomStrategy bottomStrategy) { + if(bottomStrategy instanceof UnaryBottom) + botStrategy = BottomStrategy.UNARY; + else if(bottomStrategy instanceof NullaryBottom) + botStrategy = BottomStrategy.NULLARY; + else + botStrategy = BottomStrategy.TOREMOVE; + + if(corrFileName == null) + corrFileName = "rlplus.crr"; + manager = ontology.getOWLOntologyManager(); // manager = OWLManager.createOWLOntologyManager(); - factory = manager.getOWLDataFactory(); - inputOntology = ontology; - - try { - IRI ontologyIri; - if(ontology.isAnonymous()) { - Matcher matcher = ONTOLOGY_ID_REGEX.matcher(ontology.getOntologyID().toString().toLowerCase()); - if(!matcher.matches()) throw new Error("Anonymous ontology without internal id"); - ontologyIri = - IRI.create("http://www.example.org/", matcher.group("id") + "." + DEFAULT_ONTOLOGY_FILE_EXTENSION); - } - else - ontologyIri = inputOntology.getOntologyID().getOntologyIRI(); - - String ontologyIriPrefix = ontologyIri.getNamespace(); - ontologyIRI = ontologyIri.toString(); - String ontologyIriFragment = ontologyIri.getFragment(); - String originalFileName = FilenameUtils.removeExtension(ontologyIriFragment); - String originalExtension = FilenameUtils.getExtension(ontologyIriFragment); - if(originalExtension.isEmpty()) originalExtension = DEFAULT_ONTOLOGY_FILE_EXTENSION; - - - IRI rlOntologyIRI = IRI.create(ontologyIriPrefix, originalFileName + "-RL." + originalExtension); - outputPath = Paths.get(Utility.getGlobalTempDirAbsolutePath(), - originalFileName + "-RL." + originalExtension).toString(); - IRI rlDocumentIRI = IRI.create("file://" + outputPath); - outputOntology = manager.createOntology(rlOntologyIRI); - manager.setOntologyDocumentIRI(outputOntology, rlDocumentIRI); - - String tBoxOntologyFragment = originalFileName + "-TBox." + originalExtension; - IRI tBoxOntologyIRI = IRI.create(ontologyIriPrefix, tBoxOntologyFragment); - IRI tBoxDocumentIRI = - IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), tBoxOntologyFragment)); - - String aBoxOntologyFragment = originalFileName + "-ABox." + originalExtension; - IRI aBoxOntologyIRI = IRI.create(ontologyIriPrefix, aBoxOntologyFragment); - aBoxPath = Paths.get(Utility.getGlobalTempDirAbsolutePath()) + aBoxOntologyFragment; - IRI aBoxDocumentIRI = - IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), aBoxOntologyFragment)); - - tBox = manager.createOntology(tBoxOntologyIRI); - aBox = manager.createOntology(aBoxOntologyIRI); - manager.setOntologyDocumentIRI(tBox, tBoxDocumentIRI); - manager.setOntologyDocumentIRI(aBox, aBoxDocumentIRI); - - FileOutputStream aBoxOut = new FileOutputStream(aBoxPath); - manager.saveOntology(aBox, aBoxOut); - aBoxOut.close(); - - restOntology = manager.createOntology(); - } catch(OWLOntologyCreationException | OWLOntologyStorageException | IOException e) { - e.printStackTrace(); - System.exit(1); - } - } - - public OWLOntology getTBox() { - return tBox; - } - - public String getABoxPath() { - return aBoxPath; - } - - private void add2SubCounter(OWLClassExpression exp) { - Integer count = subCounter.get(exp); - if (count == null) count = 0; - ++count; - subCounter.put(exp, count); - } - - public void simplify() { - if(simplifyABox()) { - save(aBox); + factory = manager.getOWLDataFactory(); + inputOntology = ontology; + + try { + IRI ontologyIri; + if(ontology.isAnonymous()) { + Matcher matcher = ONTOLOGY_ID_REGEX.matcher(ontology.getOntologyID().toString().toLowerCase()); + if(!matcher.matches()) throw new Error("Anonymous ontology without internal id"); + ontologyIri = + IRI.create("http://www.example.org/", matcher.group("id") + "." + DEFAULT_ONTOLOGY_FILE_EXTENSION); + } + else + ontologyIri = inputOntology.getOntologyID().getOntologyIRI(); + + String ontologyIriPrefix = ontologyIri.getNamespace(); + ontologyIRI = ontologyIri.toString(); + String ontologyIriFragment = ontologyIri.getFragment(); + String originalFileName = FilenameUtils.removeExtension(ontologyIriFragment); + String originalExtension = FilenameUtils.getExtension(ontologyIriFragment); + if(originalExtension.isEmpty()) originalExtension = DEFAULT_ONTOLOGY_FILE_EXTENSION; + + + IRI rlOntologyIRI = IRI.create(ontologyIriPrefix, originalFileName + "-RL." + originalExtension); + outputPath = Paths.get(Utility.getGlobalTempDirAbsolutePath(), + originalFileName + "-RL." + originalExtension).toString(); + IRI rlDocumentIRI = IRI.create("file://" + outputPath); + outputOntology = manager.createOntology(rlOntologyIRI); + manager.setOntologyDocumentIRI(outputOntology, rlDocumentIRI); + + String tBoxOntologyFragment = originalFileName + "-TBox." + originalExtension; + IRI tBoxOntologyIRI = IRI.create(ontologyIriPrefix, tBoxOntologyFragment); + IRI tBoxDocumentIRI = + IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), tBoxOntologyFragment)); + + String aBoxOntologyFragment = originalFileName + "-ABox." + originalExtension; + IRI aBoxOntologyIRI = IRI.create(ontologyIriPrefix, aBoxOntologyFragment); + aBoxPath = Paths.get(Utility.getGlobalTempDirAbsolutePath(), aBoxOntologyFragment).toString(); + IRI aBoxDocumentIRI = + IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), aBoxOntologyFragment)); + + tBox = manager.createOntology(tBoxOntologyIRI); + aBox = manager.createOntology(aBoxOntologyIRI); + manager.setOntologyDocumentIRI(tBox, tBoxDocumentIRI); + manager.setOntologyDocumentIRI(aBox, aBoxDocumentIRI); + + FileOutputStream aBoxOut = new FileOutputStream(aBoxPath); + manager.saveOntology(aBox, aBoxOut); + aBoxOut.close(); + + restOntology = manager.createOntology(); + } catch(OWLOntologyCreationException | OWLOntologyStorageException | IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + public OWLOntology getTBox() { + return tBox; + } + + public String getABoxPath() { + return aBoxPath; + } + + public void simplify() { + if(simplifyABox()) { + save(aBox); // save(tBox); - } else - tBox = inputOntology; - } + } + else + tBox = inputOntology; + } - @Override - public void transform() { - simplify(); - filter(); - clausify(); + @Override + public void transform() { + simplify(); + filter(); + clausify(); - subCounter = new HashMap(); - clauses = new LinkedList(); - Clausifier clausifier = Clausifier.getInstance(restOntology); + subCounter = new HashMap(); + clauses = new LinkedList(); + Clausifier clausifier = Clausifier.getInstance(restOntology); - for (DLClause c: dlOntology.getDLClauses()) { - Clause clause = new Clause(clausifier, c); - clauses.add(clause); + for(DLClause c : dlOntology.getDLClauses()) { + Clause clause = new Clause(clausifier, c); + clauses.add(clause); /* - * count the expressions in the left + * count the expressions in the left */ - for (OWLClassExpression exp: clause.getSubClasses()) { - if(exp instanceof OWLClass) - add2SubCounter(exp); - else if (exp instanceof OWLObjectSomeValuesFrom) { - OWLObjectSomeValuesFrom someValue = (OWLObjectSomeValuesFrom)exp; - add2SubCounter(factory.getOWLObjectSomeValuesFrom(someValue.getProperty(), factory.getOWLThing())); - add2SubCounter(someValue.getFiller()); - } - else if (exp instanceof OWLObjectMinCardinality) { - OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; - add2SubCounter(factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing())); - add2SubCounter(minCard.getFiller()); - } else - Utility.logError("strange class expression: " + exp); - - } - } - - correspondence = new HashMap(); - Set addedAxioms = new HashSet(); - OWLClassExpression subExp; - for (Clause clause: clauses) { - subExp = uk.ac.ox.cs.pagoda.owl.OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses()); - addedAxioms.clear(); - for (OWLClassExpression exp: getDisjunctionApprox0(clause.getSuperClasses())) { - addedAxioms.add(factory.getOWLSubClassOfAxiom(subExp, transform(exp, addedAxioms))); - for(OWLAxiom a : addedAxioms) - addAxiom2output(a, factory.getOWLSubClassOfAxiom(subExp, - OWLHelper.getSimplifiedDisjunction(factory, clause.getSuperClasses()))); - } - } - - subCounter.clear(); - } - - @Override - public void save() { - if (corrFileName != null) - save(correspondence, corrFileName); - save(outputOntology); - } - - private void save(Map map, String corrFileName) { - if (corrFileName == null) return ; - ObjectOutput output; - try { - output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(corrFileName))); - output.writeObject(map); - output.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - protected void save(OWLOntology onto) { - try { - onto.getOWLOntologyManager().saveOntology(onto); - } catch (OWLOntologyStorageException e) { - e.printStackTrace(); - } - } - - /* - * treat disjunction as conjunction - */ - private Set getDisjunctionApprox0(Set superClasses) { - return superClasses; - } - - /* - * choose one simple class disjunct - */ - @SuppressWarnings("unused") - private Set getDisjunctionApprox1(Set superClasses) { - if(superClasses.isEmpty() || superClasses.size() == 1) - return superClasses; - - OWLClassExpression rep = null; - int min = Integer.MAX_VALUE, o; - for(OWLClassExpression exp : superClasses) - if(exp instanceof OWLClass && (o = getOccurrence(exp)) < min) { - min = o; - rep = exp; - } - - if(rep == null) rep = superClasses.iterator().next(); - - return Collections.singleton(rep); - } - - /* - * randomly choose a class expression to represent this disjunction - */ - @SuppressWarnings("unused") - private Set getDisjunctionApprox2(Set superClasses) { - if(superClasses.isEmpty() || superClasses.size() == 1) - return superClasses; - - int index = random.nextInt() % superClasses.size(); - if (index < 0) index += superClasses.size(); - - int i = 0; - for(OWLClassExpression exp : superClasses) - if (i++ == index) - return Collections.singleton(exp); - return null; - } - - /* - * choose the one that appears least in the l.h.s. - */ - @SuppressWarnings("unused") - private Set getDisjunctionApprox3(Set superClasses) { - if(superClasses.isEmpty() || superClasses.size() == 1) - return superClasses; - - OWLClassExpression rep = null, exp1; - int occurrence = Integer.MAX_VALUE, o; - for (OWLClassExpression exp: superClasses) { - o = 0; - exp1 = exp; - if (exp instanceof OWLObjectMinCardinality) { - OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; - if (minCard.getCardinality() == 1) - exp1 = factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), minCard.getFiller()); - } - - if (!subCounter.containsKey(exp1) || (o = subCounter.get(exp1)) < occurrence) { - rep = exp; - occurrence = o; - } - } - - return Collections.singleton(rep); - } - - private int getOccurrence(OWLClassExpression exp) { - if (!subCounter.containsKey(exp)) - return 0; - return subCounter.get(exp); - } - - @SuppressWarnings("unused") - private Set getDisjunctionApprox4(Set superClasses) { - if(superClasses.isEmpty() || superClasses.size() == 1) - return superClasses; - - OWLClassExpression rep = null; - int occurrence = Integer.MAX_VALUE, o; - for (OWLClassExpression exp: superClasses) { - o = 0; - if (exp instanceof OWLObjectMinCardinality) { - OWLObjectMinCardinality minCard = (OWLObjectMinCardinality)exp; - if (minCard.getCardinality() == 1) { - o = getOccurrence((factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing()))); - o += getOccurrence(minCard.getFiller()); + for(OWLClassExpression exp : clause.getSubClasses()) { + if(exp instanceof OWLClass) + add2SubCounter(exp); + else if(exp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValue = (OWLObjectSomeValuesFrom) exp; + add2SubCounter(factory.getOWLObjectSomeValuesFrom(someValue.getProperty(), factory.getOWLThing())); + add2SubCounter(someValue.getFiller()); + } + else if(exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp; + add2SubCounter(factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing())); + add2SubCounter(minCard.getFiller()); + } + else + Utility.logError("strange class expression: " + exp); + + } + } + + correspondence = new HashMap(); + Set addedAxioms = new HashSet(); + OWLClassExpression subExp; + for(Clause clause : clauses) { + subExp = uk.ac.ox.cs.pagoda.owl.OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses()); + addedAxioms.clear(); + for(OWLClassExpression exp : getDisjunctionApprox0(clause.getSuperClasses())) { + addedAxioms.add(factory.getOWLSubClassOfAxiom(subExp, transform(exp, addedAxioms))); + for(OWLAxiom a : addedAxioms) + addAxiom2output(a, factory.getOWLSubClassOfAxiom(subExp, + OWLHelper.getSimplifiedDisjunction(factory, clause.getSuperClasses()))); + } + } + + subCounter.clear(); + } + + @Override + public void save() { + if(corrFileName != null) + save(correspondence, corrFileName); + save(outputOntology); + } + + public OWLOntologyManager getOWLOntologyManager() { + return inputOntology.getOWLOntologyManager(); + } + + public String getOntologyIRI() { + return ontologyIRI; + } + + public OWLOntology getOutputOntology() { + return outputOntology; + } + + @Override + public String getOutputPath() { + return outputPath; + } + + @Override + public String getDirectory() { + return outputPath.substring(0, outputPath.lastIndexOf(Utility.FILE_SEPARATOR)); + } + + public void setCorrespondenceFileLoc(String path) { + corrFileName = path; + } + + private void add2SubCounter(OWLClassExpression exp) { + Integer count = subCounter.get(exp); + if(count == null) count = 0; + ++count; + subCounter.put(exp, count); + } + + private void save(Map map, String corrFileName) { + if(corrFileName == null) return; + ObjectOutput output; + try { + output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(corrFileName))); + output.writeObject(map); + output.close(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + protected void save(OWLOntology onto) { + try { + onto.getOWLOntologyManager().saveOntology(onto); + } catch(OWLOntologyStorageException e) { + e.printStackTrace(); + } + } + + /* + * treat disjunction as conjunction + */ + private Set getDisjunctionApprox0(Set superClasses) { + return superClasses; + } + + /* + * choose one simple class disjunct + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox1(Set superClasses) { + if(superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null; + int min = Integer.MAX_VALUE, o; + for(OWLClassExpression exp : superClasses) + if(exp instanceof OWLClass && (o = getOccurrence(exp)) < min) { + min = o; + rep = exp; + } + + if(rep == null) rep = superClasses.iterator().next(); + + return Collections.singleton(rep); + } + + /* + * randomly choose a class expression to represent this disjunction + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox2(Set superClasses) { + if(superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + int index = random.nextInt() % superClasses.size(); + if(index < 0) index += superClasses.size(); + + int i = 0; + for(OWLClassExpression exp : superClasses) + if(i++ == index) + return Collections.singleton(exp); + return null; + } + + /* + * choose the one that appears least in the l.h.s. + */ + @SuppressWarnings("unused") + private Set getDisjunctionApprox3(Set superClasses) { + if(superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null, exp1; + int occurrence = Integer.MAX_VALUE, o; + for(OWLClassExpression exp : superClasses) { + o = 0; + exp1 = exp; + if(exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp; + if(minCard.getCardinality() == 1) + exp1 = factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), minCard.getFiller()); + } + + if(!subCounter.containsKey(exp1) || (o = subCounter.get(exp1)) < occurrence) { + rep = exp; + occurrence = o; + } + } + + return Collections.singleton(rep); + } + + private int getOccurrence(OWLClassExpression exp) { + if(!subCounter.containsKey(exp)) + return 0; + return subCounter.get(exp); + } + + @SuppressWarnings("unused") + private Set getDisjunctionApprox4(Set superClasses) { + if(superClasses.isEmpty() || superClasses.size() == 1) + return superClasses; + + OWLClassExpression rep = null; + int occurrence = Integer.MAX_VALUE, o; + for(OWLClassExpression exp : superClasses) { + o = 0; + if(exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp; + if(minCard.getCardinality() == 1) { + o = + getOccurrence((factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing()))); + o += getOccurrence(minCard.getFiller()); // if (o < o1) o = o1; - } - } else - o = getOccurrence(exp); - - if (o < occurrence || o == occurrence && !(rep instanceof OWLClass)) { - rep = exp; - occurrence = o; - } - } - - return Collections.singleton(rep); - } - - private boolean simplifyABox() { - boolean flag = false; - Map complex2atomic= new HashMap(); - - OWLDatatype anyURI = factory.getOWLDatatype(IRI.create(Namespace.XSD_NS + "anyURI")); - OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY)); - OWLObjectProperty differentFrom = factory.getOWLObjectProperty(IRI.create(Namespace.INEQUALITY)); - - for (OWLOntology imported: inputOntology.getImportsClosure()) - for (OWLAxiom axiom: imported.getAxioms()) { - if (axiom instanceof OWLClassAssertionAxiom) { - flag = true; - OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom)axiom; - OWLClassExpression clsExp = assertion.getClassExpression(); - OWLClass cls; - if (clsExp instanceof OWLClass) { - if (((OWLClass) clsExp).toStringID().startsWith("owl:")) - manager.addAxiom(tBox, axiom); - else manager.addAxiom(aBox, axiom); - } - else { - if ((cls = complex2atomic.get(clsExp)) == null) { - complex2atomic.put(clsExp, cls = getNewConcept(tBox, rlCounter++)); - manager.addAxiom(tBox, factory.getOWLSubClassOfAxiom(cls, clsExp)); - } - manager.addAxiom(aBox, factory.getOWLClassAssertionAxiom(cls, assertion.getIndividual())); - } - } - else if (axiom instanceof OWLObjectPropertyAssertionAxiom || axiom instanceof OWLDataPropertyAssertionAxiom || axiom instanceof OWLAnnotationAssertionAxiom) { - if(axiom.getDataPropertiesInSignature().contains(anyURI)) continue; - flag = true; - manager.addAxiom(aBox, axiom); - } - else if (axiom instanceof OWLSameIndividualAxiom) { - OWLIndividual firstIndividual = null, previousIndividual = null, lastIndividual = null; - for (OWLIndividual next: ((OWLSameIndividualAxiom) axiom).getIndividuals()) { - if(firstIndividual == null) firstIndividual = previousIndividual = next; - else - manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, previousIndividual, next)); - previousIndividual = lastIndividual = next; - } - manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, lastIndividual, firstIndividual)); - } - else if (axiom instanceof OWLDifferentIndividualsAxiom) { - int index1 = 0, index2; - for (OWLIndividual individual1: ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) { - ++index1; - index2 = 0; - for (OWLIndividual individual2: ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) { - if (index2++ < index1) { - manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(differentFrom, individual1, individual2)); - } else break; - } - } - } else - manager.addAxiom(tBox, axiom); - } - - return flag; - } - - private void filter() { - OWL2RLProfile profile = new OWL2RLProfile(); - OWLProfileReport report = profile.checkOntology(tBox); - Set rlAxioms = tBox.getAxioms(); - OWLAxiom axiom; - - for (OWLProfileViolation violation: report.getViolations()) { - manager.addAxiom(restOntology, axiom = violation.getAxiom()); - rlAxioms.remove(axiom); - } - - for (Iterator iter = rlAxioms.iterator(); iter.hasNext(); ) - addAxiom2output(iter.next(), null); - } - - private void clausify() { - Configuration conf = new Configuration(); - OWLClausification clausifier = new OWLClausification(conf); - dlOntology = (DLOntology)clausifier.preprocessAndClausify(restOntology, null)[1]; - clausifier = null; - } - - protected void addAxiom2output(OWLAxiom axiom, OWLAxiom correspondingAxiom) { - manager.addAxiom(outputOntology, axiom); - if (correspondingAxiom != null) - correspondence.put(axiom, correspondingAxiom); - } - - private OWLClassExpression transform(OWLClassExpression exp, Set addedAxioms) { - if (exp instanceof OWLClass) - return exp; - - if (exp instanceof OWLObjectHasValue) - return exp; - - if (exp instanceof OWLObjectSomeValuesFrom) { - OWLObjectSomeValuesFrom someValueExp = (OWLObjectSomeValuesFrom)exp; - - OWLClassExpression tExp = someValueExp.getFiller(); - if (tExp.equals(factory.getOWLThing())) - exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty()); - else - exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty(), someValueExp.getFiller()); - } - - if (exp instanceof OWLObjectMinCardinality) { - OWLObjectMinCardinality minExp = (OWLObjectMinCardinality)exp; - OWLObjectPropertyExpression r; - - if (minExp.getFiller().equals(factory.getOWLThing())) { - r = minExp.getProperty(); - } - //TODO to be restored ... - //else if ((r = exists2role.get(someValueExp)) == null) { - // deal with r' \subseteq r & range(r') \subseteq C - else { - r = getNewRole(outputOntology, rlCounter); - addedAxioms.add(factory.getOWLSubObjectPropertyOfAxiom(r, minExp.getProperty())); - OWLClassExpression tExp = minExp.getFiller(); - if (!(tExp instanceof OWLObjectComplementOf)) { - if (tExp.equals(factory.getOWLThing())); - else - addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, tExp)); - } - else if (botStrategy != BottomStrategy.TOREMOVE) { - OWLClass cls = (OWLClass) tExp.getComplementNNF(); - OWLClass neg; - if ((neg = atomic2negation.get(cls)) == null) { - neg = getNewConcept(outputOntology, rlCounter); - addedAxioms.add(factory.getOWLDisjointClassesAxiom(neg, cls)); - atomic2negation.put(cls, neg); - } - addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, neg)); - } + } + } + else + o = getOccurrence(exp); + + if(o < occurrence || o == occurrence && !(rep instanceof OWLClass)) { + rep = exp; + occurrence = o; + } + } + + return Collections.singleton(rep); + } + + private boolean simplifyABox() { + boolean flag = false; + Map complex2atomic = new HashMap(); + + OWLDatatype anyURI = factory.getOWLDatatype(IRI.create(Namespace.XSD_NS + "anyURI")); + OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY)); + OWLObjectProperty differentFrom = factory.getOWLObjectProperty(IRI.create(Namespace.INEQUALITY)); + + for(OWLOntology imported : inputOntology.getImportsClosure()) + for(OWLAxiom axiom : imported.getAxioms()) { + if(axiom instanceof OWLClassAssertionAxiom) { + flag = true; + OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom) axiom; + OWLClassExpression clsExp = assertion.getClassExpression(); + OWLClass cls; + if(clsExp instanceof OWLClass) { + if(((OWLClass) clsExp).toStringID().startsWith("owl:")) + manager.addAxiom(tBox, axiom); + else manager.addAxiom(aBox, axiom); + } + else { + if((cls = complex2atomic.get(clsExp)) == null) { + complex2atomic.put(clsExp, cls = getNewConcept(tBox, rlCounter++)); + manager.addAxiom(tBox, factory.getOWLSubClassOfAxiom(cls, clsExp)); + } + manager.addAxiom(aBox, factory.getOWLClassAssertionAxiom(cls, assertion.getIndividual())); + } + } + else if(axiom instanceof OWLObjectPropertyAssertionAxiom || axiom instanceof OWLDataPropertyAssertionAxiom || axiom instanceof OWLAnnotationAssertionAxiom) { + if(axiom.getDataPropertiesInSignature().contains(anyURI)) continue; + flag = true; + manager.addAxiom(aBox, axiom); + } + else if(axiom instanceof OWLSameIndividualAxiom) { + OWLIndividual firstIndividual = null, previousIndividual = null, lastIndividual = null; + for(OWLIndividual next : ((OWLSameIndividualAxiom) axiom).getIndividuals()) { + if(firstIndividual == null) firstIndividual = previousIndividual = next; + else + manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, previousIndividual, next)); + previousIndividual = lastIndividual = next; + } + manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, lastIndividual, firstIndividual)); + } + else if(axiom instanceof OWLDifferentIndividualsAxiom) { + int index1 = 0, index2; + for(OWLIndividual individual1 : ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) { + ++index1; + index2 = 0; + for(OWLIndividual individual2 : ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) { + if(index2++ < index1) { + manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(differentFrom, individual1, individual2)); + } + else break; + } + } + } + else + manager.addAxiom(tBox, axiom); + } + + return flag; + } + + private void filter() { + OWL2RLProfile profile = new OWL2RLProfile(); + OWLProfileReport report = profile.checkOntology(tBox); + Set rlAxioms = tBox.getAxioms(); + OWLAxiom axiom; + + for(OWLProfileViolation violation : report.getViolations()) { + manager.addAxiom(restOntology, axiom = violation.getAxiom()); + rlAxioms.remove(axiom); + } + + for(Iterator iter = rlAxioms.iterator(); iter.hasNext(); ) + addAxiom2output(iter.next(), null); + } + + private void clausify() { + Configuration conf = new Configuration(); + OWLClausification clausifier = new OWLClausification(conf); + dlOntology = (DLOntology) clausifier.preprocessAndClausify(restOntology, null)[1]; + clausifier = null; + } + + protected void addAxiom2output(OWLAxiom axiom, OWLAxiom correspondingAxiom) { + manager.addAxiom(outputOntology, axiom); + if(correspondingAxiom != null) + correspondence.put(axiom, correspondingAxiom); + } + + private OWLClassExpression transform(OWLClassExpression exp, Set addedAxioms) { + if(exp instanceof OWLClass) + return exp; + + if(exp instanceof OWLObjectHasValue) + return exp; + + if(exp instanceof OWLObjectSomeValuesFrom) { + OWLObjectSomeValuesFrom someValueExp = (OWLObjectSomeValuesFrom) exp; + + OWLClassExpression tExp = someValueExp.getFiller(); + if(tExp.equals(factory.getOWLThing())) + exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty()); + else + exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty(), someValueExp.getFiller()); + } + + if(exp instanceof OWLObjectMinCardinality) { + OWLObjectMinCardinality minExp = (OWLObjectMinCardinality) exp; + OWLObjectPropertyExpression r; + + if(minExp.getFiller().equals(factory.getOWLThing())) { + r = minExp.getProperty(); + } + //TODO to be restored ... + //else if ((r = exists2role.get(someValueExp)) == null) { + // deal with r' \subseteq r & range(r') \subseteq C + else { + r = getNewRole(outputOntology, rlCounter); + addedAxioms.add(factory.getOWLSubObjectPropertyOfAxiom(r, minExp.getProperty())); + OWLClassExpression tExp = minExp.getFiller(); + if(!(tExp instanceof OWLObjectComplementOf)) { + if(tExp.equals(factory.getOWLThing())) ; + else + addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, tExp)); + } + else if(botStrategy != BottomStrategy.TOREMOVE) { + OWLClass cls = (OWLClass) tExp.getComplementNNF(); + OWLClass neg; + if((neg = atomic2negation.get(cls)) == null) { + neg = getNewConcept(outputOntology, rlCounter); + addedAxioms.add(factory.getOWLDisjointClassesAxiom(neg, cls)); + atomic2negation.put(cls, neg); + } + addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, neg)); + } // exists2role.put(someValueExp, (OWLObjectProperty) r); - } - - // deal with r'(x,c) - Set ret = new HashSet(); - int num = minExp.getCardinality(); - - Set cs = new HashSet(); - OWLNamedIndividual c; - for (int i = 0; i < num; ++i) { - c = getNewIndividual(outputOntology, rlCounter++); - ret.add(factory.getOWLObjectHasValue(r, c)); - cs.add(c); - } - - if (botStrategy != BottomStrategy.TOREMOVE && cs.size() > 1) { - addedAxioms.add(factory.getOWLDifferentIndividualsAxiom(cs)); - } - - return OWLHelper.getSimplifiedConjunction(factory, ret); - } - - if (exp instanceof OWLObjectMaxCardinality) { - OWLObjectMaxCardinality maxExp = (OWLObjectMaxCardinality)exp; - OWLClassExpression tExp = maxExp.getFiller(); - int card = maxExp.getCardinality() >= 1 ? 1 : 0; - if (!(tExp instanceof OWLObjectComplementOf)) - return factory.getOWLObjectMaxCardinality(card, maxExp.getProperty(), tExp); - else { - Utility.logDebug("oh, to be tested ... "); - OWLClassExpression tExp1 = factory.getOWLObjectAllValuesFrom(maxExp.getProperty(), tExp.getComplementNNF()); - if (card == 0) - return tExp1; - else { - OWLClassExpression tExp2 = factory.getOWLObjectMaxCardinality(1, maxExp.getProperty()); - return factory.getOWLObjectIntersectionOf(tExp1, tExp2); - } - } - } - - if (exp instanceof OWLObjectAllValuesFrom) - return exp; - - if (exp instanceof OWLObjectOneOf) - if (((OWLObjectOneOf) exp).getIndividuals().size() == 1) - return exp; - else - return null; - - if (exp instanceof OWLDataHasValue) - return exp; - - //TODO overapproximation - dealing with OWLDataMinCardinality - - if (exp instanceof OWLDataSomeValuesFrom) { - return exp; - } - - if (exp instanceof OWLDataMinCardinality) { - return exp; - } - - if (exp instanceof OWLDataMaxCardinality) { - return exp; - } - - - Set exps = exp.asConjunctSet(); - if (exps.size() == 1 && exps.iterator().next() == exp) { - Utility.logError(exp, "error in transform of Ontology~~~~"); - } - Set nexps = new HashSet(); - OWLClassExpression ne; - boolean changes = false; - for (OWLClassExpression e: exps) { - ne = transform(e, addedAxioms); - if (ne != e) changes = true; - nexps.add(ne); - } - if (changes) - return OWLHelper.getSimplifiedConjunction(factory, nexps); - else - return exp; - } - - protected OWLNamedIndividual getNewIndividual(OWLOntology onto, int number) { - OWLOntologyManager manager = onto.getOWLOntologyManager(); - OWLDataFactory factory = manager.getOWLDataFactory(); - OWLNamedIndividual newIndividual = factory.getOWLNamedIndividual(IRI.create(Namespace.PAGODA_ANONY + "NI" + number)); - manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newIndividual)); - return newIndividual; - } - - protected OWLObjectProperty getNewRole(OWLOntology onto, int number) { - OWLOntologyManager manager = onto.getOWLOntologyManager(); - OWLDataFactory factory = manager.getOWLDataFactory(); - OWLObjectProperty newProperty = factory.getOWLObjectProperty(IRI.create(Namespace.PAGODA_AUX + "NR" + number)); - manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newProperty)); - return newProperty; - } - - private OWLClass getNewConcept(OWLOntology onto, int number) { - OWLOntologyManager manager = onto.getOWLOntologyManager(); - OWLDataFactory factory = manager.getOWLDataFactory(); - OWLClass newClass = factory.getOWLClass(IRI.create(Namespace.PAGODA_AUX + "NC" + number)); - manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newClass)); - return newClass; - } - - public OWLOntologyManager getOWLOntologyManager() { - return inputOntology.getOWLOntologyManager(); - } - - public String getOntologyIRI() { - return ontologyIRI; - } - - public OWLOntology getOutputOntology() { - return outputOntology; - } - - @Override - public String getOutputPath() { - return outputPath; - } - - @Override - public String getDirectory() { - return outputPath.substring(0, outputPath.lastIndexOf(Utility.FILE_SEPARATOR)); - } - - public void setCorrespondenceFileLoc(String path) { - corrFileName = path; - } - - private enum BottomStrategy { TOREMOVE, NULLARY, UNARY } + } + + // deal with r'(x,c) + Set ret = new HashSet(); + int num = minExp.getCardinality(); + + Set cs = new HashSet(); + OWLNamedIndividual c; + for(int i = 0; i < num; ++i) { + c = getNewIndividual(outputOntology, rlCounter++); + ret.add(factory.getOWLObjectHasValue(r, c)); + cs.add(c); + } + + if(botStrategy != BottomStrategy.TOREMOVE && cs.size() > 1) { + addedAxioms.add(factory.getOWLDifferentIndividualsAxiom(cs)); + } + + return OWLHelper.getSimplifiedConjunction(factory, ret); + } + + if(exp instanceof OWLObjectMaxCardinality) { + OWLObjectMaxCardinality maxExp = (OWLObjectMaxCardinality) exp; + OWLClassExpression tExp = maxExp.getFiller(); + int card = maxExp.getCardinality() >= 1 ? 1 : 0; + if(!(tExp instanceof OWLObjectComplementOf)) + return factory.getOWLObjectMaxCardinality(card, maxExp.getProperty(), tExp); + else { + Utility.logDebug("oh, to be tested ... "); + OWLClassExpression tExp1 = + factory.getOWLObjectAllValuesFrom(maxExp.getProperty(), tExp.getComplementNNF()); + if(card == 0) + return tExp1; + else { + OWLClassExpression tExp2 = factory.getOWLObjectMaxCardinality(1, maxExp.getProperty()); + return factory.getOWLObjectIntersectionOf(tExp1, tExp2); + } + } + } + + if(exp instanceof OWLObjectAllValuesFrom) + return exp; + + if(exp instanceof OWLObjectOneOf) + if(((OWLObjectOneOf) exp).getIndividuals().size() == 1) + return exp; + else + return null; + + if(exp instanceof OWLDataHasValue) + return exp; + + //TODO overapproximation - dealing with OWLDataMinCardinality + + if(exp instanceof OWLDataSomeValuesFrom) { + return exp; + } + + if(exp instanceof OWLDataMinCardinality) { + return exp; + } + + if(exp instanceof OWLDataMaxCardinality) { + return exp; + } + + + Set exps = exp.asConjunctSet(); + if(exps.size() == 1 && exps.iterator().next() == exp) { + Utility.logError(exp, "error in transform of Ontology~~~~"); + } + Set nexps = new HashSet(); + OWLClassExpression ne; + boolean changes = false; + for(OWLClassExpression e : exps) { + ne = transform(e, addedAxioms); + if(ne != e) changes = true; + nexps.add(ne); + } + if(changes) + return OWLHelper.getSimplifiedConjunction(factory, nexps); + else + return exp; + } + + protected OWLNamedIndividual getNewIndividual(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLNamedIndividual newIndividual = + factory.getOWLNamedIndividual(IRI.create(Namespace.PAGODA_ANONY + "NI" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newIndividual)); + return newIndividual; + } + + protected OWLObjectProperty getNewRole(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLObjectProperty newProperty = factory.getOWLObjectProperty(IRI.create(Namespace.PAGODA_AUX + "NR" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newProperty)); + return newProperty; + } + + private OWLClass getNewConcept(OWLOntology onto, int number) { + OWLOntologyManager manager = onto.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLClass newClass = factory.getOWLClass(IRI.create(Namespace.PAGODA_AUX + "NC" + number)); + manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newClass)); + return newClass; + } + + private enum BottomStrategy {TOREMOVE, NULLARY, UNARY} } diff --git a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageQueryEngine.java b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageQueryEngine.java index 50996d0..b708bee 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageQueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageQueryEngine.java @@ -11,161 +11,173 @@ import uk.ac.ox.cs.pagoda.rules.DatalogProgram; import uk.ac.ox.cs.pagoda.rules.Program; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.util.Collection; public class MultiStageQueryEngine extends StageQueryEngine { - public MultiStageQueryEngine(String name, boolean checkValidity) { - super(name, checkValidity); - } - - /** - * c-chase - */ - @Override - public void materialiseFoldedly(DatalogProgram dProgram, GapByStore4ID gap) { - materialise("lower program", dProgram.getLower().toString()); - Program generalProgram = dProgram.getGeneral(); - FoldedApplication program = new FoldedApplication(generalProgram, dProgram.getUpperBottomStrategy()); - Treatment treatment = new Pick4NegativeConceptNaive(this, program); - materialise(program, treatment, gap); - } - - /** - * c-chase^f - */ - @Override - public int materialiseRestrictedly(DatalogProgram dProgram, GapByStore4ID gap) { - if (gap != null) - materialise("lower program", dProgram.getLower().toString()); - - Program generalProgram = dProgram.getGeneral(); - RestrictedApplication program = new RestrictedApplication(generalProgram, dProgram.getUpperBottomStrategy()); - Treatment treatment = new Pick4NegativeConceptNaive(this, program); - int ret = materialise(program, treatment, gap); - treatment.dispose(); // does nothing - return ret; - } - - public int materialise4SpecificQuery(Program generalProgram, QueryRecord record, BottomStrategy upperBottom) { - RestrictedApplication program = new RestrictedApplication(generalProgram, upperBottom); - Treatment treatment = new Pick4NegativeConceptQuerySpecific(this, program, record); - int ret = materialise(program, treatment, null); - treatment.dispose(); - return ret; - } - - /** - * delta-chase - */ - @Override - public int materialiseSkolemly(DatalogProgram dProgram, GapByStore4ID gap) { - materialise("lower program", dProgram.getLower().toString()); - Program generalProgram = dProgram.getGeneral(); - LimitedSkolemisationApplication program = new LimitedSkolemisationApplication(generalProgram, dProgram.getUpperBottomStrategy()); - Treatment treatment = new Pick4NegativeConceptNaive(this, program); - return materialise(program, treatment, gap); - } - - private int materialise(MultiStageUpperProgram program, Treatment treatment, GapByStore4ID gap) { - if (gap != null) - treatment.addAdditionalGapTuples(); - String programName = "multi-stage upper program"; - Utility.logInfo(name + " store is materialising " + programName + " ..."); - Timer t = new Timer(); - - String datalogProgram = program.getDatalogRuleText(); - long tripleCountBeforeMat = 0; - - // TODO to be removed ... + public MultiStageQueryEngine(String name, boolean checkValidity) { + super(name, checkValidity); + } + + /** + * c-chase + */ + @Override + public void materialiseFoldedly(DatalogProgram dProgram, GapByStore4ID gap) { + if(isDisposed()) throw new DisposedException(); + + materialise("lower program", dProgram.getLower().toString()); + Program generalProgram = dProgram.getGeneral(); + FoldedApplication program = new FoldedApplication(generalProgram, dProgram.getUpperBottomStrategy()); + Treatment treatment = new Pick4NegativeConceptNaive(this, program); + materialise(program, treatment, gap); + } + + /** + * c-chase^f + */ + @Override + public int materialiseRestrictedly(DatalogProgram dProgram, GapByStore4ID gap) { + if(isDisposed()) throw new DisposedException(); + + if(gap != null) + materialise("lower program", dProgram.getLower().toString()); + + Program generalProgram = dProgram.getGeneral(); + RestrictedApplication program = new RestrictedApplication(generalProgram, dProgram.getUpperBottomStrategy()); + Treatment treatment = new Pick4NegativeConceptNaive(this, program); + int ret = materialise(program, treatment, gap); + treatment.dispose(); // does nothing + return ret; + } + + public int materialise4SpecificQuery(Program generalProgram, QueryRecord record, BottomStrategy upperBottom) { + if(isDisposed()) throw new DisposedException(); + + RestrictedApplication program = new RestrictedApplication(generalProgram, upperBottom); + Treatment treatment = new Pick4NegativeConceptQuerySpecific(this, program, record); + int ret = materialise(program, treatment, null); + treatment.dispose(); + return ret; + } + + /** + * delta-chase + */ + @Override + public int materialiseSkolemly(DatalogProgram dProgram, GapByStore4ID gap) { + if(isDisposed()) throw new DisposedException(); + + materialise("lower program", dProgram.getLower().toString()); + Program generalProgram = dProgram.getGeneral(); + LimitedSkolemisationApplication program = + new LimitedSkolemisationApplication(generalProgram, dProgram.getUpperBottomStrategy()); + Treatment treatment = new Pick4NegativeConceptNaive(this, program); + return materialise(program, treatment, gap); + } + + private int materialise(MultiStageUpperProgram program, Treatment treatment, GapByStore4ID gap) { + if(gap != null) + treatment.addAdditionalGapTuples(); + String programName = "multi-stage upper program"; + Utility.logInfo(name + " store is materialising " + programName + " ..."); + Timer t = new Timer(); + + String datalogProgram = program.getDatalogRuleText(); + long tripleCountBeforeMat = 0; + + // TODO to be removed ... // if (gap == null) // program.save("output/multi.dlog"); - Collection violations; - int iteration = 0; - Timer subTimer = new Timer(); - boolean incrementally; - try { - while (true) { - long oldTripleCount = store.getTriplesCount(); - - subTimer.reset(); - Utility.logInfo("Iteration " + ++iteration + ": "); - - incrementally = (iteration != 1); - - if (!incrementally) - tripleCountBeforeMat = oldTripleCount; - - if (gap != null) { - try { - gap.compile(incrementally ? null : datalogProgram); - gap.addBackTo(); - } finally { - gap.clear(); - } - } - else { - if (!incrementally) { + Collection violations; + int iteration = 0; + Timer subTimer = new Timer(); + boolean incrementally; + try { + while(true) { + long oldTripleCount = store.getTriplesCount(); + + subTimer.reset(); + Utility.logInfo("Iteration " + ++iteration + ": "); + + incrementally = (iteration != 1); + + if(!incrementally) + tripleCountBeforeMat = oldTripleCount; + + if(gap != null) { + try { + gap.compile(incrementally ? null : datalogProgram); + gap.addBackTo(); + } finally { + gap.clear(); + } + } + else { + if(!incrementally) { // store.addRules(new String[] {datalogProgram}); - store.importRules(datalogProgram); - } - store.applyReasoning(incrementally); - } - + store.importRules(datalogProgram); + } + store.applyReasoning(incrementally); + } + // Utility.logInfo("The number of sameAs assertions in the current store: " + getSameAsNumber()); - - if (!isValid()) { - if (iteration == 1) { - Utility.logInfo("The ontology is inconsistent."); - return -1; - } - Utility.logInfo(name + " store FAILED for multi-stage materialisation in " + t.duration() + " seconds."); - return 0; - } - else validMaterialisation = null; - - long tripleCount = store.getTriplesCount(); - Utility.logDebug(name + " store after materialising datalog-rules: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); - Utility.logDebug("Time to materialise datalog-rules: " + subTimer.duration()); - - subTimer.reset(); - if ((violations = program.isIntegrated(this, incrementally)) == null || violations.size() == 0) { - store.clearRulesAndMakeFactsExplicit(); - Utility.logInfo(name + " store after materialising " + programName + ": " + tripleCount + " (" + (tripleCount - tripleCountBeforeMat) + " new)"); - Utility.logInfo(name + " store is DONE for multi-stage materialising in " + t.duration() + " seconds."); - return isValid() ? 1 : 0; - } - Utility.logDebug("Time to detect violations: " + subTimer.duration()); - - store.makeFactsExplicit(); - subTimer.reset(); - oldTripleCount = store.getTriplesCount(); - for (Violation v : violations) { - - Utility.logDebug("Dealing with violation: " + v.constraint); - Utility.logDebug("Number of violation tuples: " + v.size()); - - Timer localTimer = new Timer(); - int number = v.size(); - long vOldCounter = store.getTriplesCount(); - if (!treatment.makeSatisfied(v)) { - validMaterialisation = false; - Utility.logInfo(name + " store FAILED for multi-stage materialisation in " + t.duration() + " seconds."); - return 0; - } - Utility.logDebug("Time to make the constraint being satisfied: " + localTimer.duration()); - Utility.logDebug("Triples in the store: before=" + vOldCounter + ", after=" + store.getTriplesCount() + ", new=" + (store.getTriplesCount() - vOldCounter)); - } - Utility.logDebug(name + " store after adding facts for violations: " + (tripleCount = store.getTriplesCount()) + " (" + (tripleCount - oldTripleCount) + " new)"); - Utility.logDebug("Time to add triples for violations: " + subTimer.duration()); - } - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - return 0; - } - + + if(!isValid()) { + if(iteration == 1) { + Utility.logInfo("The ontology is inconsistent."); + return -1; + } + Utility.logInfo(name + " store FAILED for multi-stage materialisation in " + t.duration() + " seconds."); + return 0; + } + else validMaterialisation = null; + + long tripleCount = store.getTriplesCount(); + Utility.logDebug(name + " store after materialising datalog-rules: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); + Utility.logDebug("Time to materialise datalog-rules: " + subTimer.duration()); + + subTimer.reset(); + if((violations = program.isIntegrated(this, incrementally)) == null || violations.size() == 0) { + store.clearRulesAndMakeFactsExplicit(); + Utility.logInfo(name + " store after materialising " + programName + ": " + tripleCount + " (" + (tripleCount - tripleCountBeforeMat) + " new)"); + Utility.logInfo(name + " store is DONE for multi-stage materialising in " + t.duration() + " seconds."); + return isValid() ? 1 : 0; + } + Utility.logDebug("Time to detect violations: " + subTimer.duration()); + + store.makeFactsExplicit(); + subTimer.reset(); + oldTripleCount = store.getTriplesCount(); + for(Violation v : violations) { + + Utility.logDebug("Dealing with violation: " + v.constraint); + Utility.logDebug("Number of violation tuples: " + v.size()); + + Timer localTimer = new Timer(); + int number = v.size(); + long vOldCounter = store.getTriplesCount(); + if(!treatment.makeSatisfied(v)) { + validMaterialisation = false; + Utility.logInfo(name + " store FAILED for multi-stage materialisation in " + t.duration() + " seconds."); + return 0; + } + Utility.logDebug("Time to make the constraint being satisfied: " + localTimer.duration()); + Utility.logDebug("Triples in the store: before=" + vOldCounter + ", after=" + store.getTriplesCount() + ", new=" + (store + .getTriplesCount() - vOldCounter)); + } + Utility.logDebug(name + " store after adding facts for violations: " + (tripleCount = + store.getTriplesCount()) + " (" + (tripleCount - oldTripleCount) + " new)"); + Utility.logDebug("Time to add triples for violations: " + subTimer.duration()); + } + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + return 0; + } + } diff --git a/src/uk/ac/ox/cs/pagoda/multistage/StageQueryEngine.java b/src/uk/ac/ox/cs/pagoda/multistage/StageQueryEngine.java index e652f66..c8776fe 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/StageQueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/StageQueryEngine.java @@ -23,10 +23,6 @@ public abstract class StageQueryEngine extends BasicQueryEngine { public abstract int materialiseSkolemly(DatalogProgram dProgram, GapByStore4ID gap); - public void dispose() { - super.dispose(); - } - public boolean isValid() { if (!checkValidity) return true; if (validMaterialisation != null) return validMaterialisation; diff --git a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java index 00e7e2b..687fa4a 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java @@ -14,194 +14,193 @@ import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; import uk.ac.ox.cs.pagoda.util.Namespace; import uk.ac.ox.cs.pagoda.util.SparqlHelper; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import uk.ac.ox.cs.pagoda.util.tuples.Tuple; import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; import java.util.*; -public abstract class Pick4NegativeConcept implements Treatment { - - public Set addedGroundAtoms = new HashSet(); - MultiStageQueryEngine engine; - MultiStageUpperProgram program; - RDFoxTripleManager tripleManager; - PredicateDependency dependencyGraph; - boolean addGap = false; - - public Pick4NegativeConcept(MultiStageQueryEngine store, MultiStageUpperProgram multiProgram) { - this.engine = store; - this.program = multiProgram; - this.tripleManager = new RDFoxTripleManager(store.getDataStore(), true); - } - - void addTripleByID(Atom atom, Atom gapAtom, Map assignment) { - int[] newTuple = tripleManager.getInstance(atom, assignment); - tripleManager.addTripleByID(newTuple); - if (addGap) - tripleManager.addTripleByID(tripleManager.getInstance(gapAtom, assignment)); - } - - protected boolean makeSatisfied(Violation violation, Comparator comp) { - LinkedList tuples = violation.getTuples(); - DLClause constraint = violation.getConstraint(); - Map assignment = new HashMap(); - - if (constraint.getHeadLength() > 1) { - Atom[] orderedAtoms = Arrays.copyOf(constraint.getHeadAtoms(), constraint.getHeadLength()); - Arrays.sort(orderedAtoms, comp); - - Set negTuples = new HashSet(); - String negativeQuery; - String[] subVars; - for (Atom headAtom: orderedAtoms) { - Atom negativeAtom = MultiStageUpperProgram.getNegativeAtom(headAtom); - if (negativeAtom == null) continue; - negativeQuery = SparqlHelper.getSPARQLQuery(new Atom[] { negativeAtom }, - subVars = MultiStageUpperProgram.getVarSubset(violation.getVariables(), headAtom)); - negTuples.clear(); - Atom gapHeadAtom = addGap ? getGapAtom(headAtom) : null; - TupleIterator negAnswers = null; - try { - negAnswers = engine.internal_evaluateNotExpanded(negativeQuery); - for (long multi = negAnswers.open(); multi != 0; multi = negAnswers.getNext()) - negTuples.add(new AnswerTupleID(negAnswers)); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (negAnswers != null) negAnswers.dispose(); - } - - if (!tuples.isEmpty()) +public abstract class Pick4NegativeConcept extends Treatment { + + public Set addedGroundAtoms = new HashSet(); + MultiStageQueryEngine engine; + MultiStageUpperProgram program; + RDFoxTripleManager tripleManager; + PredicateDependency dependencyGraph; + boolean addGap = false; + + public Pick4NegativeConcept(MultiStageQueryEngine store, MultiStageUpperProgram multiProgram) { + this.engine = store; + this.program = multiProgram; + this.tripleManager = new RDFoxTripleManager(store.getDataStore(), true); + } + + @Override + public void addAdditionalGapTuples() { + if(isDisposed()) throw new DisposedException(); + addGap = true; + } + + void addTripleByID(Atom atom, Atom gapAtom, Map assignment) { + if(isDisposed()) throw new DisposedException(); + int[] newTuple = tripleManager.getInstance(atom, assignment); + tripleManager.addTripleByID(newTuple); + if(addGap) + tripleManager.addTripleByID(tripleManager.getInstance(gapAtom, assignment)); + } + + protected boolean makeSatisfied(Violation violation, Comparator comp) { + LinkedList tuples = violation.getTuples(); + DLClause constraint = violation.getConstraint(); + Map assignment = new HashMap(); + + if(constraint.getHeadLength() > 1) { + Atom[] orderedAtoms = Arrays.copyOf(constraint.getHeadAtoms(), constraint.getHeadLength()); + Arrays.sort(orderedAtoms, comp); + + Set negTuples = new HashSet(); + String negativeQuery; + String[] subVars; + for(Atom headAtom : orderedAtoms) { + Atom negativeAtom = MultiStageUpperProgram.getNegativeAtom(headAtom); + if(negativeAtom == null) continue; + negativeQuery = SparqlHelper.getSPARQLQuery(new Atom[]{negativeAtom}, + subVars = + MultiStageUpperProgram.getVarSubset(violation.getVariables(), headAtom)); + negTuples.clear(); + Atom gapHeadAtom = addGap ? getGapAtom(headAtom) : null; + TupleIterator negAnswers = null; + try { + negAnswers = engine.internal_evaluateNotExpanded(negativeQuery); + for(long multi = negAnswers.open(); multi != 0; multi = negAnswers.getNext()) + negTuples.add(new AnswerTupleID(negAnswers)); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(negAnswers != null) negAnswers.dispose(); + } + + if(!tuples.isEmpty()) // program.addUpdatedPredicates(dependencyGraph.getDependence(headAtom.getDLPredicate())); - program.addUpdatedPredicate(headAtom.getDLPredicate()); - - Comparator tComp = new TupleComparator(subVars); - Collections.sort(tuples, tComp); - - AnswerTupleID lastAdded = null; - - for (Iterator iter = tuples.iterator(); iter.hasNext(); ) { - - AnswerTupleID tuple = iter.next(); - if (!negTuples.contains(MultiStageUpperProgram.project(tuple, violation.getVariables(), subVars))) { - if (lastAdded == null || tComp.compare(lastAdded, tuple) != 0) { - lastAdded = tuple; - tuple.getAssignment(violation.getVariables(), assignment); - addTripleByID(headAtom, gapHeadAtom, assignment); - } - iter.remove(); - } - } + program.addUpdatedPredicate(headAtom.getDLPredicate()); + + Comparator tComp = new TupleComparator(subVars); + Collections.sort(tuples, tComp); + + AnswerTupleID lastAdded = null; + + for(Iterator iter = tuples.iterator(); iter.hasNext(); ) { + + AnswerTupleID tuple = iter.next(); + if(!negTuples.contains(MultiStageUpperProgram.project(tuple, violation.getVariables(), subVars))) { + if(lastAdded == null || tComp.compare(lastAdded, tuple) != 0) { + lastAdded = tuple; + tuple.getAssignment(violation.getVariables(), assignment); + addTripleByID(headAtom, gapHeadAtom, assignment); + } + iter.remove(); + } + } // tuples.reset(); - - if (tuples.isEmpty()) - return true; - } - if (!tuples.isEmpty()) return false; - } - else { - Set headAtoms = new HashSet(); - - ArrayList> violationTuples = new ArrayList<>(violation.getTuples().size()); - for (int i = 0; i < violation.getTuples().size(); i++) { - AnswerTupleID answerTupleID = violation.getTuples().get(i); - TupleBuilder tupleBuilder = new TupleBuilder<>(); - for (int j = 0; j < answerTupleID.getArity(); j++) { - String rawTerm = tripleManager.getRawTerm(answerTupleID.getTerm(j)); - Individual individual = Individual.create(rawTerm.substring(1, rawTerm.length()-1)); - tupleBuilder.append(individual); - } - violationTuples.add(tupleBuilder.build()); - } - - for (DLClause clause : program.convertExist(constraint, violation.getClause(), violationTuples)) { - - if (!DLClauseHelper.hasSubsetBodyAtoms(clause, constraint)) { - Utility.logError("There might be an error here... Cannot happen!!!"); - throw new Error("This condition should not happen!!!"); - } - - Atom tHeadAtom = clause.getHeadAtom(0); - Atom tGapHeadAtom = addGap ? getGapAtom(tHeadAtom) : null; - if (DLClauseHelper.isGround(tHeadAtom)) { - if (!addedGroundAtoms.contains(tHeadAtom)) { - program.addUpdatedPredicate(tHeadAtom.getDLPredicate()); - addTripleByID(tHeadAtom, tGapHeadAtom, null); - addedGroundAtoms.add(tHeadAtom); - } - } else headAtoms.add(tHeadAtom); - } - if (!tuples.isEmpty()) - for (Atom atom: headAtoms) - program.addUpdatedPredicate(atom.getDLPredicate()); - - for (AnswerTupleID tuple: tuples) { - tuple.getAssignment(violation.getVariables(), assignment); - for (Atom atom: headAtoms) { - addTripleByID(atom, getGapAtom(atom), assignment); - } - } - } - - assignment.clear(); - return true; - } - - private Atom getGapAtom(Atom atom) { - if (!addGap) return null; - String gapPredicate = GapTupleIterator.getGapPredicate(getPredicateIRI(atom.getDLPredicate())); - Atom gapAtom = atom.getArity() == 1 ? Atom.create(AtomicConcept.create(gapPredicate), atom.getArgument(0)) : - Atom.create(AtomicRole.create(gapPredicate), atom.getArgument(0), atom.getArgument(1)); - return gapAtom; - } - - private String getPredicateIRI(DLPredicate dlPredicate) { - if (dlPredicate instanceof Equality || dlPredicate instanceof AnnotatedEquality) - return Namespace.EQUALITY; - if (dlPredicate instanceof Inequality) - return Namespace.INEQUALITY; - if (dlPredicate instanceof AtomicConcept) - return ((AtomicConcept) dlPredicate).getIRI(); - if (dlPredicate instanceof AtomicRole) - return ((AtomicRole) dlPredicate).getIRI(); - return null; - } - - @Override - public void dispose() { -// tripleManager.outputAddedInstance(); -// addedGroundAtoms.clear(); - } - - @Override - public void addAdditionalGapTuples() { - addGap = true; - } - + + if(tuples.isEmpty()) + return true; + } + if(!tuples.isEmpty()) return false; + } + else { + Set headAtoms = new HashSet(); + + ArrayList> violationTuples = new ArrayList<>(violation.getTuples().size()); + for(int i = 0; i < violation.getTuples().size(); i++) { + AnswerTupleID answerTupleID = violation.getTuples().get(i); + TupleBuilder tupleBuilder = new TupleBuilder<>(); + for(int j = 0; j < answerTupleID.getArity(); j++) { + String rawTerm = tripleManager.getRawTerm(answerTupleID.getTerm(j)); + Individual individual = Individual.create(rawTerm.substring(1, rawTerm.length() - 1)); + tupleBuilder.append(individual); + } + violationTuples.add(tupleBuilder.build()); + } + + for(DLClause clause : program.convertExist(constraint, violation.getClause(), violationTuples)) { + + if(!DLClauseHelper.hasSubsetBodyAtoms(clause, constraint)) { + Utility.logError("There might be an error here... Cannot happen!!!"); + throw new Error("This condition should not happen!!!"); + } + + Atom tHeadAtom = clause.getHeadAtom(0); + Atom tGapHeadAtom = addGap ? getGapAtom(tHeadAtom) : null; + if(DLClauseHelper.isGround(tHeadAtom)) { + if(!addedGroundAtoms.contains(tHeadAtom)) { + program.addUpdatedPredicate(tHeadAtom.getDLPredicate()); + addTripleByID(tHeadAtom, tGapHeadAtom, null); + addedGroundAtoms.add(tHeadAtom); + } + } + else headAtoms.add(tHeadAtom); + } + if(!tuples.isEmpty()) + for(Atom atom : headAtoms) + program.addUpdatedPredicate(atom.getDLPredicate()); + + for(AnswerTupleID tuple : tuples) { + tuple.getAssignment(violation.getVariables(), assignment); + for(Atom atom : headAtoms) { + addTripleByID(atom, getGapAtom(atom), assignment); + } + } + } + + assignment.clear(); + return true; + } + + private Atom getGapAtom(Atom atom) { + if(!addGap) return null; + String gapPredicate = GapTupleIterator.getGapPredicate(getPredicateIRI(atom.getDLPredicate())); + Atom gapAtom = atom.getArity() == 1 ? Atom.create(AtomicConcept.create(gapPredicate), atom.getArgument(0)) : + Atom.create(AtomicRole.create(gapPredicate), atom.getArgument(0), atom.getArgument(1)); + return gapAtom; + } + + private String getPredicateIRI(DLPredicate dlPredicate) { + if(dlPredicate instanceof Equality || dlPredicate instanceof AnnotatedEquality) + return Namespace.EQUALITY; + if(dlPredicate instanceof Inequality) + return Namespace.INEQUALITY; + if(dlPredicate instanceof AtomicConcept) + return ((AtomicConcept) dlPredicate).getIRI(); + if(dlPredicate instanceof AtomicRole) + return ((AtomicRole) dlPredicate).getIRI(); + return null; + } + } class TupleComparator implements Comparator { - int[] validIndexes; - - public TupleComparator(String[] validTerms) { - int num = 0; - for (int i = 0; i < validTerms.length; ++i) - if (validTerms[i] != null) - ++num; - validIndexes = new int[num]; - for (int i = 0, j = 0; i < validTerms.length; ++i) - if (validTerms[i] != null) - validIndexes[j++] = i; - } - - @Override - public int compare(AnswerTupleID o1, AnswerTupleID o2) { - int delta = 0; - for (int i = 0; i < validIndexes.length; ++i) - if ((delta = o1.getTerm(validIndexes[i]) - o2.getTerm(validIndexes[i])) != 0) - return delta; - return 0; - } - + int[] validIndexes; + + public TupleComparator(String[] validTerms) { + int num = 0; + for(int i = 0; i < validTerms.length; ++i) + if(validTerms[i] != null) + ++num; + validIndexes = new int[num]; + for(int i = 0, j = 0; i < validTerms.length; ++i) + if(validTerms[i] != null) + validIndexes[j++] = i; + } + + @Override + public int compare(AnswerTupleID o1, AnswerTupleID o2) { + int delta = 0; + for(int i = 0; i < validIndexes.length; ++i) + if((delta = o1.getTerm(validIndexes[i]) - o2.getTerm(validIndexes[i])) != 0) + return delta; + return 0; + } + } \ No newline at end of file diff --git a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptNaive.java b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptNaive.java index b0c5d46..af190fc 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptNaive.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptNaive.java @@ -1,25 +1,25 @@ package uk.ac.ox.cs.pagoda.multistage.treatement; +import uk.ac.ox.cs.JRDFox.JRDFStoreException; import uk.ac.ox.cs.pagoda.constraints.PredicateDependency; import uk.ac.ox.cs.pagoda.multistage.MultiStageQueryEngine; import uk.ac.ox.cs.pagoda.multistage.MultiStageUpperProgram; import uk.ac.ox.cs.pagoda.multistage.Violation; - -import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; public class Pick4NegativeConceptNaive extends Pick4NegativeConcept { + SimpleComparator comp = new SimpleComparator(); + public Pick4NegativeConceptNaive(MultiStageQueryEngine store, MultiStageUpperProgram multiProgram) { super(store, multiProgram); - dependencyGraph = new PredicateDependency(multiProgram.getClauses()); + dependencyGraph = new PredicateDependency(multiProgram.getClauses()); } - SimpleComparator comp = new SimpleComparator(); - @Override public boolean makeSatisfied(Violation violation) throws JRDFStoreException { + if(isDisposed()) throw new DisposedException(); return makeSatisfied(violation, comp); } - } diff --git a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptQuerySpecific.java b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptQuerySpecific.java index 10aa22f..20b4376 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptQuerySpecific.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConceptQuerySpecific.java @@ -11,77 +11,81 @@ import uk.ac.ox.cs.pagoda.multistage.Violation; import uk.ac.ox.cs.pagoda.query.QueryRecord; import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.util.Comparator; import java.util.Set; public class Pick4NegativeConceptQuerySpecific extends Pick4NegativeConcept { - QueryRecord record; - Comparator comp; - Normalisation norm; - - public Pick4NegativeConceptQuerySpecific(MultiStageQueryEngine multiStageQueryEngine, RestrictedApplication program, QueryRecord record) { - super(multiStageQueryEngine, program); - this.record = record; - norm = program.getNormalisation(); - dependencyGraph = new PredicateDependency(record.getRelevantClauses()); - comp = new DisjunctComparator(new SimpleComparator()); - } - - @Override - public boolean makeSatisfied(Violation violation) throws JRDFStoreException { - return makeSatisfied(violation, comp); - } - - class DisjunctComparator implements Comparator { - -// Map dist = new HashMap(); - Comparator m_reference; - Set dsts; - - public DisjunctComparator(Comparator referenceComp) { - m_reference = referenceComp; - dsts = dependencyGraph.collectPredicate(DLClauseHelper.getQuery(record.getQueryText(), null).getBodyAtoms()); - } - - @Override - public int compare(Atom arg0, Atom arg1) { - int dist0 = getDistance(arg0.getDLPredicate()); - int dist1 = getDistance(arg1.getDLPredicate()); - int ret = dist1 - dist0; - if (ret != 0) return ret; - - return - m_reference.compare(arg0, arg1); - } - - private int getDistance(DLPredicate p) { - if (p instanceof Equality || p instanceof AnnotatedEquality) - return -1; - if (p instanceof Inequality) - p = AtomicRole.create(Namespace.INEQUALITY); - - AtLeastConcept alc; - if (p instanceof AtomicConcept) - if ((alc = norm.getRightAtLeastConcept((AtomicConcept) p)) != null) { - AtomicRole r = alc.getOnRole() instanceof AtomicRole ? - (AtomicRole) alc.getOnRole() : - ((InverseRole) alc.getOnRole()).getInverseOf(); - AtomicConcept c = alc.getToConcept() instanceof AtomicConcept ? - (AtomicConcept) alc.getToConcept() : - OverApproxExist.getNegationConcept(((AtomicNegationConcept) alc.getToConcept()).getNegatedAtomicConcept()); - - if (c.equals(AtomicConcept.THING)) - return dependencyGraph.distance(dsts, r); - else - return dependencyGraph.distance(dsts, r, c); - } else if ((alc = norm.getLeftAtLeastConcept((AtomicConcept) p)) != null) { - return 2; - } - - return dependencyGraph.distance(dsts, p); - } - - } + QueryRecord record; + Comparator comp; + Normalisation norm; + + public Pick4NegativeConceptQuerySpecific(MultiStageQueryEngine multiStageQueryEngine, RestrictedApplication program, QueryRecord record) { + super(multiStageQueryEngine, program); + this.record = record; + norm = program.getNormalisation(); + dependencyGraph = new PredicateDependency(record.getRelevantClauses()); + comp = new DisjunctComparator(new SimpleComparator()); + } + + @Override + public boolean makeSatisfied(Violation violation) throws JRDFStoreException { + if(isDisposed()) throw new DisposedException(); + return makeSatisfied(violation, comp); + } + + class DisjunctComparator implements Comparator { + + // Map dist = new HashMap(); + Comparator m_reference; + Set dsts; + + public DisjunctComparator(Comparator referenceComp) { + m_reference = referenceComp; + dsts = dependencyGraph.collectPredicate(DLClauseHelper.getQuery(record.getQueryText(), null) + .getBodyAtoms()); + } + + @Override + public int compare(Atom arg0, Atom arg1) { + int dist0 = getDistance(arg0.getDLPredicate()); + int dist1 = getDistance(arg1.getDLPredicate()); + int ret = dist1 - dist0; + if(ret != 0) return ret; + + return -m_reference.compare(arg0, arg1); + } + + private int getDistance(DLPredicate p) { + if(p instanceof Equality || p instanceof AnnotatedEquality) + return -1; + if(p instanceof Inequality) + p = AtomicRole.create(Namespace.INEQUALITY); + + AtLeastConcept alc; + if(p instanceof AtomicConcept) + if((alc = norm.getRightAtLeastConcept((AtomicConcept) p)) != null) { + AtomicRole r = alc.getOnRole() instanceof AtomicRole ? + (AtomicRole) alc.getOnRole() : + ((InverseRole) alc.getOnRole()).getInverseOf(); + AtomicConcept c = alc.getToConcept() instanceof AtomicConcept ? + (AtomicConcept) alc.getToConcept() : + OverApproxExist.getNegationConcept(((AtomicNegationConcept) alc.getToConcept()).getNegatedAtomicConcept()); + + if(c.equals(AtomicConcept.THING)) + return dependencyGraph.distance(dsts, r); + else + return dependencyGraph.distance(dsts, r, c); + } + else if((alc = norm.getLeftAtLeastConcept((AtomicConcept) p)) != null) { + return 2; + } + + return dependencyGraph.distance(dsts, p); + } + + } } diff --git a/src/uk/ac/ox/cs/pagoda/multistage/treatement/SkolemTreatment.java b/src/uk/ac/ox/cs/pagoda/multistage/treatement/SkolemTreatment.java deleted file mode 100644 index 7a92b79..0000000 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/SkolemTreatment.java +++ /dev/null @@ -1,33 +0,0 @@ -package uk.ac.ox.cs.pagoda.multistage.treatement; - -import uk.ac.ox.cs.JRDFox.JRDFStoreException; -import uk.ac.ox.cs.pagoda.multistage.FoldedApplication; -import uk.ac.ox.cs.pagoda.multistage.MultiStageQueryEngine; -import uk.ac.ox.cs.pagoda.multistage.Violation; - -// TODO should I implement something like this? -public class SkolemTreatment implements Treatment { - - public SkolemTreatment(MultiStageQueryEngine multiStageQueryEngine, FoldedApplication program) { - // TODO Auto-generated constructor stub - } - - @Override - public boolean makeSatisfied(Violation violation) throws JRDFStoreException { - // TODO Auto-generated method stub - return false; - } - - @Override - public void dispose() { - // TODO Auto-generated method stub - - } - - @Override - public void addAdditionalGapTuples() { - // TODO Auto-generated method stub - - } - -} diff --git a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Treatment.java b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Treatment.java index 686379a..cb81af0 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Treatment.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Treatment.java @@ -1,14 +1,12 @@ package uk.ac.ox.cs.pagoda.multistage.treatement; -import uk.ac.ox.cs.pagoda.multistage.Violation; - import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.pagoda.multistage.Violation; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; -public interface Treatment { +public abstract class Treatment extends Disposable { - public boolean makeSatisfied(Violation violation) throws JRDFStoreException; - - public void dispose(); + public abstract boolean makeSatisfied(Violation violation) throws JRDFStoreException; - public void addAdditionalGapTuples(); + public abstract void addAdditionalGapTuples(); } diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java index cb2b0a3..78aced1 100644 --- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java +++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuple.java @@ -172,7 +172,7 @@ public class AnswerTuple { String lexicalForm = matcher.group("lexicalForm"); String dataTypeIRI = matcher.group("dataType"); Datatype dataType; - if (dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL; + if(dataTypeIRI == null || dataTypeIRI.isEmpty()) dataType = Datatype.RDF_PLAIN_LITERAL; else dataType = uk.ac.ox.cs.JRDFox.model.Datatype.value(dataTypeIRI); terms[i] = uk.ac.ox.cs.JRDFox.model.Literal.create(lexicalForm, dataType); } diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java index e1e5302..81efed0 100644 --- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java +++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuples.java @@ -1,23 +1,22 @@ package uk.ac.ox.cs.pagoda.query; -public interface AnswerTuples { - - public void reset(); - - public boolean isValid(); - - public int getArity(); - - public String[] getAnswerVariables(); - - public void moveNext(); - - public void dispose(); - - public AnswerTuple getTuple(); - - public boolean contains(AnswerTuple t); - - public void remove(); +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +public abstract class AnswerTuples extends Disposable { + + public abstract void reset(); + + public abstract boolean isValid(); + + public abstract int getArity(); + + public abstract String[] getAnswerVariables(); + + public abstract void moveNext(); + + public abstract AnswerTuple getTuple(); + + public abstract boolean contains(AnswerTuple t); + + public abstract void remove(); } diff --git a/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java b/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java index 3e0f320..fd3fb1f 100644 --- a/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java +++ b/src/uk/ac/ox/cs/pagoda/query/AnswerTuplesImp.java @@ -3,7 +3,7 @@ package uk.ac.ox.cs.pagoda.query; import java.util.Iterator; import java.util.Set; -public class AnswerTuplesImp implements AnswerTuples { +public class AnswerTuplesImp extends AnswerTuples { int m_index; Iterator m_iter; @@ -53,9 +53,6 @@ public class AnswerTuplesImp implements AnswerTuples { m_tuple = null; } - @Override - public void dispose() {} - @Override public void reset() { if (m_answers1 == null || m_answers1.isEmpty()) { diff --git a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java index 1f81a78..742b7da 100644 --- a/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java +++ b/src/uk/ac/ox/cs/pagoda/query/QueryRecord.java @@ -11,6 +11,8 @@ import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; import uk.ac.ox.cs.pagoda.util.Namespace; import uk.ac.ox.cs.pagoda.util.PagodaProperties; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import uk.ac.ox.cs.pagoda.util.tuples.Tuple; import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder; @@ -18,162 +20,180 @@ import java.io.*; import java.lang.reflect.Type; import java.util.*; -public class QueryRecord { - - public static final String botQueryText = "SELECT ?X WHERE { ?X }"; - public static final String SEPARATOR = "----------------------------------------"; - private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString(); - boolean processed = false; - String stringQueryID = null; - OWLOntology relevantOntology = null; - Set relevantClauses = new HashSet(); - double[] timer; - int subID; - DLClause queryClause = null; - int queryID = -1; - Set soundAnswerTuples = new HashSet(); - private Step difficulty; - private String queryText; - private String[][] answerVariables = null; - private Set gapAnswerTuples = null; - private QueryManager m_manager; - - private QueryRecord() { - } +public class QueryRecord extends Disposable { + + public static final String botQueryText = + "SELECT ?X WHERE { ?X }"; + public static final String SEPARATOR = "----------------------------------------"; + private static final String RDF_TYPE = "a"; //"rdf:type"; //RDF.type.toString(); + boolean processed = false; + String stringQueryID = null; + OWLOntology relevantOntology = null; + Set relevantClauses = new HashSet(); + double[] timer; + int subID; + DLClause queryClause = null; + int queryID = -1; + Set soundAnswerTuples = new HashSet(); + private Step difficulty; + private String queryText; + private String[][] answerVariables = null; + private Set gapAnswerTuples = null; + private QueryManager m_manager; + + private QueryRecord() { + } // private boolean containsAuxPredicate(String str) { // return str.contains(Namespace.PAGODA_AUX) || str.contains("_AUX") || str.contains("owl#Nothing") || // str.contains("internal:def"); // } - public QueryRecord(QueryManager manager, String text, int id, int subID) { - m_manager = manager; - resetInfo(text, id, subID); - resetTimer(); - } - - public static Collection collectQueryTexts(Collection queryRecords) { - Collection texts = new LinkedList(); - for(QueryRecord record : queryRecords) - texts.add(record.queryText); - return texts; - } - - public void resetInfo(String text, int id, int subid) { - queryID = id; - subID = subid; - stringQueryID = id + (subID == 0 ? "" : "_" + subID); - m_manager.remove(queryText); - m_manager.put(text, this); - queryClause = null; - answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); - queryText = text; // .replace("_:", "?"); - } - - public void resetTimer() { - int length = Step.values().length; - timer = new double[length]; - for(int i = 0; i < length; ++i) timer[i] = 0; - } - - public AnswerTuples getAnswers() { - if(isProcessed()) - return getLowerBoundAnswers(); - - return getUpperBoundAnswers(); - } - - public AnswerTuples getLowerBoundAnswers() { - return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); - } - - public AnswerTuples getUpperBoundAnswers() { - return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); - } - - public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { - if(answerTuples == null) return false; - boolean update = false; - for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { - tuple = answerTuples.getTuple(); - if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { - soundAnswerTuples.add(tuple); - if(gapAnswerTuples != null) - gapAnswerTuples.remove(tuple); - update = true; - } - } - - if(soundAnswerTuples.isEmpty()) - Utility.logInfo("Lower bound answers empty"); - else if(update) - Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size()); - else - Utility.logInfo("Lower bound answers unchanged"); - - return update; - } - - public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { - return updateUpperBoundAnswers(answerTuples, false); - } - - public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { - if(!(answerTuples instanceof RDFoxAnswerTuples)) { - String msg = "The upper bound must be computed by RDFox!"; - Utility.logError(msg); - throw new IllegalArgumentException(msg); - } - - RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples; - - Set candidateGapAnswerTuples = new HashSet(); - AnswerTuple tuple; - for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { - tuple = rdfoxAnswerTuples.getTuple(); - if(isBottom() || !tuple.hasAnonymousIndividual()) - if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) - candidateGapAnswerTuples.add(tuple); - } - - /*** START: debugging ***/ - if(PagodaProperties.isDebuggingMode()) { - if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length) - throw new IllegalArgumentException( - "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " + - "is different from the number of answer variables (" + - getAnswerVariables().length + ")"); - - Set namedAnswerTuples = new HashSet<>(); - rdfoxAnswerTuples.reset(); - for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { - tuple = rdfoxAnswerTuples.getTuple(); + public QueryRecord(QueryManager manager, String text, int id, int subID) { + m_manager = manager; + resetInfo(text, id, subID); + resetTimer(); + } + + public static Collection collectQueryTexts(Collection queryRecords) { + Collection texts = new LinkedList(); + for(QueryRecord record : queryRecords) + texts.add(record.queryText); + return texts; + } + + public void resetInfo(String text, int id, int subid) { + if(isDisposed()) throw new DisposedException(); + + queryID = id; + subID = subid; + stringQueryID = id + (subID == 0 ? "" : "_" + subID); + m_manager.remove(queryText); + m_manager.put(text, this); + queryClause = null; + answerVariables = ConjunctiveQueryHelper.getAnswerVariables(text); + queryText = text; // .replace("_:", "?"); + } + + public void resetTimer() { + if(isDisposed()) throw new DisposedException(); + + int length = Step.values().length; + timer = new double[length]; + for(int i = 0; i < length; ++i) timer[i] = 0; + } + + public AnswerTuples getAnswers() { + if(isDisposed()) throw new DisposedException(); + + if(isProcessed()) + return getLowerBoundAnswers(); + + return getUpperBoundAnswers(); + } + + public AnswerTuples getLowerBoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples); + } + + public AnswerTuples getUpperBoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], soundAnswerTuples, gapAnswerTuples); + } + + public boolean updateLowerBoundAnswers(AnswerTuples answerTuples) { + if(isDisposed()) throw new DisposedException(); + + if(answerTuples == null) return false; + boolean update = false; + for(AnswerTuple tuple; answerTuples.isValid(); answerTuples.moveNext()) { + tuple = answerTuples.getTuple(); + if(!soundAnswerTuples.contains(tuple) && (gapAnswerTuples == null || gapAnswerTuples.contains(tuple))) { + soundAnswerTuples.add(tuple); + if(gapAnswerTuples != null) + gapAnswerTuples.remove(tuple); + update = true; + } + } + + if(soundAnswerTuples.isEmpty()) + Utility.logInfo("Lower bound answers empty"); + else if(update) + Utility.logInfo("Lower bound answers updated: " + soundAnswerTuples.size()); + else + Utility.logInfo("Lower bound answers unchanged"); + + return update; + } + + public boolean updateUpperBoundAnswers(AnswerTuples answerTuples) { + if(isDisposed()) throw new DisposedException(); + + return updateUpperBoundAnswers(answerTuples, false); + } + + public boolean updateUpperBoundAnswers(AnswerTuples answerTuples, boolean toCheckAux) { + if(isDisposed()) throw new DisposedException(); + + if(!(answerTuples instanceof RDFoxAnswerTuples)) { + String msg = "The upper bound must be computed by RDFox!"; + Utility.logError(msg); + throw new IllegalArgumentException(msg); + } + + RDFoxAnswerTuples rdfoxAnswerTuples = (RDFoxAnswerTuples) answerTuples; + + Set candidateGapAnswerTuples = new HashSet(); + AnswerTuple tuple; + for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { + tuple = rdfoxAnswerTuples.getTuple(); + if(isBottom() || !tuple.hasAnonymousIndividual()) + if((!toCheckAux || !tuple.hasAuxPredicate()) && !soundAnswerTuples.contains(tuple)) + candidateGapAnswerTuples.add(tuple); + } + + /*** START: debugging ***/ + if(PagodaProperties.isDebuggingMode()) { + if(rdfoxAnswerTuples.getArity() != getAnswerVariables().length) + throw new IllegalArgumentException( + "The arity of answers (" + rdfoxAnswerTuples.getArity() + ") " + + "is different from the number of answer variables (" + + getAnswerVariables().length + ")"); + + Set namedAnswerTuples = new HashSet<>(); + rdfoxAnswerTuples.reset(); + for(; rdfoxAnswerTuples.isValid(); rdfoxAnswerTuples.moveNext()) { + tuple = rdfoxAnswerTuples.getTuple(); // if(isBottom() || !tuple.hasAnonymousIndividual()) { - namedAnswerTuples.add(tuple); + namedAnswerTuples.add(tuple); // } - } - HashSet difference = new HashSet<>(soundAnswerTuples); - difference.removeAll(namedAnswerTuples); - if(!difference.isEmpty()) - throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference - .size()); - } - /*** END: debugging ***/ - - boolean update; - if(gapAnswerTuples == null) { - gapAnswerTuples = candidateGapAnswerTuples; - update = true; - } else { - update = gapAnswerTuples.retainAll(candidateGapAnswerTuples); - } - - if(update) - Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers()); - else - Utility.logInfo("Upper bound answers unchanged"); - - return update; + } + HashSet difference = new HashSet<>(soundAnswerTuples); + difference.removeAll(namedAnswerTuples); + if(!difference.isEmpty()) + throw new IllegalArgumentException("The upper bound does not contain the lower bound! Missing answers: " + difference + .size()); + } + /*** END: debugging ***/ + + boolean update; + if(gapAnswerTuples == null) { + gapAnswerTuples = candidateGapAnswerTuples; + update = true; + } + else { + update = gapAnswerTuples.retainAll(candidateGapAnswerTuples); + } + + if(update) + Utility.logInfo("Upper bound answers updated: " + getNumberOfAnswers()); + else + Utility.logInfo("Upper bound answers unchanged"); + + return update; // boolean update = false; // for(Iterator iter = gapAnswerTuples.iterator(); iter.hasNext(); ) { @@ -183,96 +203,116 @@ public class QueryRecord { // update = true; // } // } - } - - public int getNumberOfAnswers() { - return soundAnswerTuples.size() + gapAnswerTuples.size(); - } - - public void markAsProcessed() { - processed = true; - } - - public boolean isProcessed() { - if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; - return processed; - } - - public String[] getDistinguishedVariables() { - return answerVariables[1]; - } - - public String[] getAnswerVariables() { - return answerVariables[0]; - } - - public String[][] getVariables() { - return answerVariables; - } - - public String getQueryText() { - return queryText; - } - - public String getQueryID() { - return stringQueryID; - } - - public AnswerTuples getGapAnswers() { - return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); - } - - public String toString() { - return queryText; - } - - public void outputAnswers(BufferedWriter writer) throws IOException { - - int answerCounter = soundAnswerTuples.size(); - if(!isProcessed()) answerCounter += gapAnswerTuples.size(); - - Utility.logInfo("The number of answer tuples: " + answerCounter); - - if (writer != null) { - writer.write("-------------- Query " + queryID + " ---------------------"); - writer.newLine(); - writer.write(queryText); - writer.newLine(); - StringBuilder space = new StringBuilder(); - int arity = getArity(), varSpace = 0; - for (int i = 0; i < arity; ++i) - varSpace += answerVariables[0][i].length(); - for (int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) - space.append(" "); - for (int i = 0; i < getArity(); ++i) { - writer.write(space.toString()); - writer.write(answerVariables[0][i]); - } - writer.newLine(); - writer.write(SEPARATOR); - writer.newLine(); - for (AnswerTuple tuple: soundAnswerTuples) { - writer.write(tuple.toString()); - writer.newLine(); - } - if(!isProcessed()) - for (AnswerTuple tuple: gapAnswerTuples) { - writer.write("*"); - writer.write(tuple.toString()); - writer.newLine(); - } + } + + public int getNumberOfAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size() + gapAnswerTuples.size(); + } + + public void markAsProcessed() { + processed = true; + } + + public boolean isProcessed() { + if(isDisposed()) throw new DisposedException(); + + if(gapAnswerTuples != null && gapAnswerTuples.isEmpty()) processed = true; + return processed; + } + + public String[] getDistinguishedVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[1]; + } + + public String[] getAnswerVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[0]; + } + + public String[][] getVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables; + } + + public String getQueryText() { + if(isDisposed()) throw new DisposedException(); + + return queryText; + } + + public String getQueryID() { + if(isDisposed()) throw new DisposedException(); + + return stringQueryID; + } + + public AnswerTuples getGapAnswers() { + if(isDisposed()) throw new DisposedException(); + + return new AnswerTuplesImp(answerVariables[0], gapAnswerTuples); + } + + public String toString() { + if(isDisposed()) throw new DisposedException(); + + return queryText; + } + + public void outputAnswers(BufferedWriter writer) throws IOException { + if(isDisposed()) throw new DisposedException(); + + int answerCounter = soundAnswerTuples.size(); + if(!isProcessed()) answerCounter += gapAnswerTuples.size(); + + Utility.logInfo("The number of answer tuples: " + answerCounter); + + if(writer != null) { + writer.write("-------------- Query " + queryID + " ---------------------"); + writer.newLine(); + writer.write(queryText); + writer.newLine(); + StringBuilder space = new StringBuilder(); + int arity = getArity(), varSpace = 0; + for(int i = 0; i < arity; ++i) + varSpace += answerVariables[0][i].length(); + for(int i = 0; i < (SEPARATOR.length() - varSpace) / (arity + 1); ++i) + space.append(" "); + for(int i = 0; i < getArity(); ++i) { + writer.write(space.toString()); + writer.write(answerVariables[0][i]); + } + writer.newLine(); + writer.write(SEPARATOR); + writer.newLine(); + for(AnswerTuple tuple : soundAnswerTuples) { + writer.write(tuple.toString()); + writer.newLine(); + } + if(!isProcessed()) + for(AnswerTuple tuple : gapAnswerTuples) { + writer.write("*"); + writer.write(tuple.toString()); + writer.newLine(); + } // writer.write(SEPARATOR); - writer.newLine(); - } + writer.newLine(); + } - } + } - public void outputAnswerStatistics() { + public void outputAnswerStatistics() { + if(isDisposed()) throw new DisposedException(); - int answerCounter = soundAnswerTuples.size(); - if(!isProcessed()) answerCounter += gapAnswerTuples.size(); + int answerCounter = soundAnswerTuples.size(); + if(!isProcessed()) answerCounter += gapAnswerTuples.size(); - Utility.logInfo("The number of answer tuples: " + answerCounter); + Utility.logInfo("The number of answer tuples: " + answerCounter); // if (jsonAnswers != null) { // JSONObject jsonAnswer = new JSONObject(); // @@ -297,407 +337,476 @@ public class QueryRecord { // // jsonAnswers.put(Integer.toString(queryID), jsonAnswer); // } - } - - public void outputTimes() { - for (Step step: Step.values()) { - Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); - } - } - - public String outputSoundAnswerTuple() { - StringBuilder builder = new StringBuilder(); - for (AnswerTuple tuple: soundAnswerTuples) - builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); - return builder.toString(); - } - - public String outputGapAnswerTuple() { - StringBuilder builder = new StringBuilder(); - for(AnswerTuple tuple : gapAnswerTuples) - builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); - return builder.toString(); - } - - public Step getDifficulty() { - return difficulty; - } - - public void setDifficulty(Step step) { - this.difficulty = step; - } - - public OWLOntology getRelevantOntology() { - return relevantOntology; - } - - public void setRelevantOntology(OWLOntology knowledgebase) { - relevantOntology = knowledgebase; - } - - public void saveRelevantOntology(String filename) { - if(relevantOntology == null) return; - OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); - try { - FileOutputStream outputStream = new FileOutputStream(filename); - manager.saveOntology(relevantOntology, outputStream); - outputStream.close(); - } catch (OWLOntologyStorageException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void saveRelevantClause() { - if(relevantClauses == null) return; - GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); - p.save(); - } - - public void removeUpperBoundAnswers(Collection answers) { - for (AnswerTuple answer: answers) { + } + + public void outputTimes() { + if(isDisposed()) throw new DisposedException(); + + for(Step step : Step.values()) { + Utility.logDebug("time for " + step + ": " + timer[step.ordinal()]); + } + } + + public String outputSoundAnswerTuple() { + if(isDisposed()) throw new DisposedException(); + + StringBuilder builder = new StringBuilder(); + for(AnswerTuple tuple : soundAnswerTuples) + builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); + return builder.toString(); + } + + public String outputGapAnswerTuple() { + if(isDisposed()) throw new DisposedException(); + + StringBuilder builder = new StringBuilder(); + for(AnswerTuple tuple : gapAnswerTuples) + builder.append(tuple.toString()).append(Utility.LINE_SEPARATOR); + return builder.toString(); + } + + public Step getDifficulty() { + if(isDisposed()) throw new DisposedException(); + + return difficulty; + } + + public void setDifficulty(Step step) { + if(isDisposed()) throw new DisposedException(); + + this.difficulty = step; + } + + public OWLOntology getRelevantOntology() { + if(isDisposed()) throw new DisposedException(); + + return relevantOntology; + } + + public void setRelevantOntology(OWLOntology knowledgebase) { + if(isDisposed()) throw new DisposedException(); + + relevantOntology = knowledgebase; + } + + public void saveRelevantOntology(String filename) { + if(isDisposed()) throw new DisposedException(); + + if(relevantOntology == null) return; + OWLOntologyManager manager = relevantOntology.getOWLOntologyManager(); + try { + FileOutputStream outputStream = new FileOutputStream(filename); + manager.saveOntology(relevantOntology, outputStream); + outputStream.close(); + } catch(OWLOntologyStorageException e) { + e.printStackTrace(); + } catch(FileNotFoundException e) { + e.printStackTrace(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + public void saveRelevantClause() { + if(isDisposed()) throw new DisposedException(); + + if(relevantClauses == null) return; + GeneralProgram p = new GeneralProgram(relevantClauses, relevantOntology); + p.save(); + } + + public void removeUpperBoundAnswers(Collection answers) { + if(isDisposed()) throw new DisposedException(); + + for(AnswerTuple answer : answers) { // if (soundAnswerTuples.contains(answer)) // Utility.logError("The answer (" + answer + ") cannot be removed, because it is in the lower bound."); - if (!gapAnswerTuples.contains(answer)) - Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound."); - gapAnswerTuples.remove(answer); - } - } - - public void addLowerBoundAnswers(Collection answers) { - for (AnswerTuple answer: answers) { - if (!gapAnswerTuples.contains(answer)) - Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); - gapAnswerTuples.remove(answer); - - answer = AnswerTuple.getInstance(answer, answerVariables[0].length); + if(!gapAnswerTuples.contains(answer)) + Utility.logError("The answer (" + answer + ") cannot be removed, because it is not in the upper bound."); + gapAnswerTuples.remove(answer); + } + } + + public void addLowerBoundAnswers(Collection answers) { + if(isDisposed()) throw new DisposedException(); + + for(AnswerTuple answer : answers) { + if(!gapAnswerTuples.contains(answer)) + Utility.logError("The answer (" + answer + ") cannot be added, because it is not in the upper bound."); + gapAnswerTuples.remove(answer); + + answer = AnswerTuple.getInstance(answer, answerVariables[0].length); // if (soundAnswerTuples.contains(answer)) // Utility.logError("The answer (" + answer + ") cannot be added, because it is in the lower bound."); - soundAnswerTuples.add(answer); - } - } - - public int getNoOfSoundAnswers() { - return soundAnswerTuples.size(); - } - - public void addProcessingTime(Step step, double time) { - timer[step.ordinal()] += time; - } - - public int getArity() { - return answerVariables[0].length; - } - - public void addRelevantClauses(DLClause clause) { - relevantClauses.add(clause); - } - - public Set getRelevantClauses() { - return relevantClauses; - } - - public void clearClauses() { - relevantClauses.clear(); - } - - public boolean isHorn() { - for (DLClause clause: relevantClauses) - if (clause.getHeadLength() > 1) - return false; - return true; - } - - public void saveABoxInTurtle(String filename) { - try { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); - OWLIndividual a, b; - StringBuilder builder = new StringBuilder(); - for (OWLAxiom axiom: relevantOntology.getABoxAxioms(true)) { - if (axiom instanceof OWLClassAssertionAxiom) { - OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; - OWLClass c = (OWLClass) classAssertion.getClassExpression(); - a = classAssertion.getIndividual(); - builder.append(a.toString()) - .append(" <") - .append(Namespace.RDF_TYPE) - .append("> ") - .append(c.toString()); - } - else if (axiom instanceof OWLObjectPropertyAssertionAxiom) { - OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; - OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); - a = propertyAssertion.getSubject(); - b = propertyAssertion.getObject(); - builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); - } - else if (axiom instanceof OWLDataPropertyAssertionAxiom) { - OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; - OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); - a = propertyAssertion.getSubject(); - OWLLiteral l = propertyAssertion.getObject(); - builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); - } - - writer.write(builder.toString()); - writer.write(" ."); - writer.newLine(); - builder.setLength(0); - } - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - - } - } - - public void updateSubID() { - ++subID; - stringQueryID = String.valueOf(queryID) + "_" + subID; - } - - public DLClause getClause() { - if (queryClause != null) - return queryClause; - return queryClause = DLClauseHelper.getQuery(queryText, null); - } - - public boolean isBottom() { - return queryID == 0; - } - - public int getNoOfCompleteAnswers() { - return soundAnswerTuples.size() + gapAnswerTuples.size(); - } - - public int getSubID() { - return subID; - } - - public boolean hasSameGapAnswers(QueryRecord that) { - return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); - } - - public void dispose() { - m_manager.remove(queryText); - if(gapAnswerTuples != null) gapAnswerTuples = null; - if(soundAnswerTuples != null) soundAnswerTuples = null; - if (relevantClauses != null) relevantClauses.clear(); - if (relevantOntology != null) - relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); - answerVariables = null; - } - - public boolean canBeEncodedIntoAtom() { - // FIXME - return true; + soundAnswerTuples.add(answer); + } + } + + public int getNoOfSoundAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size(); + } + + public void addProcessingTime(Step step, double time) { + if(isDisposed()) throw new DisposedException(); + + timer[step.ordinal()] += time; + } + + public int getArity() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[0].length; + } + + public void addRelevantClauses(DLClause clause) { + if(isDisposed()) throw new DisposedException(); + + relevantClauses.add(clause); + } + + public Set getRelevantClauses() { + if(isDisposed()) throw new DisposedException(); + + return relevantClauses; + } + + public void clearClauses() { + if(isDisposed()) throw new DisposedException(); + + relevantClauses.clear(); + } + + public boolean isHorn() { + if(isDisposed()) throw new DisposedException(); + + for(DLClause clause : relevantClauses) + if(clause.getHeadLength() > 1) + return false; + return true; + } + + public void saveABoxInTurtle(String filename) { + if(isDisposed()) throw new DisposedException(); + + try { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename))); + OWLIndividual a, b; + StringBuilder builder = new StringBuilder(); + for(OWLAxiom axiom : relevantOntology.getABoxAxioms(true)) { + if(axiom instanceof OWLClassAssertionAxiom) { + OWLClassAssertionAxiom classAssertion = (OWLClassAssertionAxiom) axiom; + OWLClass c = (OWLClass) classAssertion.getClassExpression(); + a = classAssertion.getIndividual(); + builder.append(a.toString()) + .append(" <") + .append(Namespace.RDF_TYPE) + .append("> ") + .append(c.toString()); + } + else if(axiom instanceof OWLObjectPropertyAssertionAxiom) { + OWLObjectPropertyAssertionAxiom propertyAssertion = (OWLObjectPropertyAssertionAxiom) axiom; + OWLObjectProperty p = (OWLObjectProperty) propertyAssertion.getProperty(); + a = propertyAssertion.getSubject(); + b = propertyAssertion.getObject(); + builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(b.toString()); + } + else if(axiom instanceof OWLDataPropertyAssertionAxiom) { + OWLDataPropertyAssertionAxiom propertyAssertion = (OWLDataPropertyAssertionAxiom) axiom; + OWLDataProperty p = (OWLDataProperty) propertyAssertion.getProperty(); + a = propertyAssertion.getSubject(); + OWLLiteral l = propertyAssertion.getObject(); + builder.append(a.toString()).append(" ").append(p.toString()).append(" ").append(l.toString()); + } + + writer.write(builder.toString()); + writer.write(" ."); + writer.newLine(); + builder.setLength(0); + } + writer.close(); + } catch(IOException e) { + e.printStackTrace(); + } finally { + + } + } + + public void updateSubID() { + if(isDisposed()) throw new DisposedException(); + + ++subID; + stringQueryID = String.valueOf(queryID) + "_" + subID; + } + + public DLClause getClause() { + if(isDisposed()) throw new DisposedException(); + + if(queryClause != null) + return queryClause; + return queryClause = DLClauseHelper.getQuery(queryText, null); + } + + public boolean isBottom() { + if(isDisposed()) throw new DisposedException(); + + return queryID == 0; + } + + public int getNoOfCompleteAnswers() { + if(isDisposed()) throw new DisposedException(); + + return soundAnswerTuples.size() + gapAnswerTuples.size(); + } + + public int getSubID() { + if(isDisposed()) throw new DisposedException(); + + return subID; + } + + public boolean hasSameGapAnswers(QueryRecord that) { + if(isDisposed()) throw new DisposedException(); + + return gapAnswerTuples.containsAll(that.gapAnswerTuples) && that.gapAnswerTuples.containsAll(gapAnswerTuples); + } + + @Override + public void dispose() { + super.dispose(); + m_manager.remove(queryText); + if(gapAnswerTuples != null) gapAnswerTuples = null; + if(soundAnswerTuples != null) soundAnswerTuples = null; + if(relevantClauses != null) relevantClauses.clear(); + if(relevantOntology != null) + relevantOntology.getOWLOntologyManager().removeOntology(relevantOntology); + answerVariables = null; + } + + public boolean canBeEncodedIntoAtom() { + if(isDisposed()) throw new DisposedException(); + + // FIXME + return true; // return false; - } - - public boolean isPredicate(AnswerTuple a, int i) { - Atom[] atoms = getClause().getBodyAtoms(); - Variable v = Variable.create(answerVariables[1][i]); - String iri; - for(Atom atom : atoms) { - DLPredicate p = atom.getDLPredicate(); - if (p instanceof AtomicConcept) { - if(((AtomicConcept) p).getIRI().equals(v.toString())) return true; - } - else if (p instanceof AtomicRole) { - iri = ((AtomicRole) p).getIRI(); - if (iri.equals(v.toString())) return true; - if(iri.startsWith("?")) - iri = a.getGroundTerm(i).toString(); - if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; - } - } - return false; - } - - // TODO remove fully extended query - public Tuple getExtendedQueryText() { + } + + public boolean isPredicate(AnswerTuple a, int i) { + if(isDisposed()) throw new DisposedException(); + + Atom[] atoms = getClause().getBodyAtoms(); + Variable v = Variable.create(answerVariables[1][i]); + String iri; + for(Atom atom : atoms) { + DLPredicate p = atom.getDLPredicate(); + if(p instanceof AtomicConcept) { + if(((AtomicConcept) p).getIRI().equals(v.toString())) return true; + } + else if(p instanceof AtomicRole) { + iri = ((AtomicRole) p).getIRI(); + if(iri.equals(v.toString())) return true; + if(iri.startsWith("?")) + iri = a.getGroundTerm(i).toString(); + if(iri.equals(Namespace.RDF_TYPE) && atom.getArgument(1).equals(v)) return true; + } + } + return false; + } + + // TODO remove fully extended query + public Tuple getExtendedQueryText() { + if(isDisposed()) throw new DisposedException(); + // String[] ret = new String[2];s - int index = queryText.toUpperCase().indexOf(" WHERE"); - String extendedSelect = queryText.substring(0, index); - String extendedWhere= queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); - - String sub, obj; - Map> links = new HashMap>(); - Set list; - for (Atom atom: getClause().getBodyAtoms()) - if (atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { - sub = atom.getArgumentVariable(0).getName(); - obj = atom.getArgumentVariable(1).getName(); - if((list = links.get(sub)) == null) - links.put(sub, list = new HashSet()); - list.add(obj); - if((list = links.get(obj)) == null) - links.put(obj, list = new HashSet()); - list.add(sub); - } - - StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); + int index = queryText.toUpperCase().indexOf(" WHERE"); + String extendedSelect = queryText.substring(0, index); + String extendedWhere = queryText.substring(index + 1), fullyExtendedWhere = queryText.substring(index + 1); + + String sub, obj; + Map> links = new HashMap>(); + Set list; + for(Atom atom : getClause().getBodyAtoms()) + if(atom.getDLPredicate() instanceof AtomicRole && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) { + sub = atom.getArgumentVariable(0).getName(); + obj = atom.getArgumentVariable(1).getName(); + if((list = links.get(sub)) == null) + links.put(sub, list = new HashSet()); + list.add(obj); + if((list = links.get(obj)) == null) + links.put(obj, list = new HashSet()); + list.add(sub); + } + + StringBuilder extra = new StringBuilder(), fullyExtra = new StringBuilder(); // if (answerVariables[0] != answerVariables[1]) { - for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { + for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) { // for (int i = 0; i < answerVariables[1].length; ++i) { - fullyExtra.append(" . ?") - .append(answerVariables[1][i]) - .append(" " + RDF_TYPE + " <") - .append(Namespace.PAGODA_ORIGINAL) - .append(">"); - if ((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; - else { - extra.append(" . ?") - .append(answerVariables[1][i]) - .append(" " + RDF_TYPE + " <") - .append(Namespace.PAGODA_ORIGINAL) - .append(">"); - } - } - - if(extra.length() > 0) { - extra.append(" }"); - extendedWhere = extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); - } - - if(fullyExtra.length() > 0) { - fullyExtra.append(" }"); - fullyExtendedWhere = fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra.toString()); - } + fullyExtra.append(" . ?") + .append(answerVariables[1][i]) + .append(" " + RDF_TYPE + " <") + .append(Namespace.PAGODA_ORIGINAL) + .append(">"); + if((list = links.get(answerVariables[1][i])) == null || list.size() < 2) ; + else { + extra.append(" . ?") + .append(answerVariables[1][i]) + .append(" " + RDF_TYPE + " <") + .append(Namespace.PAGODA_ORIGINAL) + .append(">"); + } + } + + if(extra.length() > 0) { + extra.append(" }"); + extendedWhere = + extendedWhere.replace(" }", extendedWhere.contains(". }") ? extra.substring(2) : extra.toString()); + } + + if(fullyExtra.length() > 0) { + fullyExtra.append(" }"); + fullyExtendedWhere = + fullyExtendedWhere.replace(" }", fullyExtendedWhere.contains(". }") ? fullyExtra.substring(2) : fullyExtra + .toString()); + } // } - TupleBuilder result = new TupleBuilder(); - result.append(extendedSelect + " " + fullyExtendedWhere); - - extra.setLength(0); - if (answerVariables[0] != answerVariables[1]) { - for (int i = answerVariables[0].length; i < answerVariables[1].length; ++i) - extra.append(" ?").append(answerVariables[1][i]); - extendedSelect = extendedSelect + extra.toString(); - } - result.append(extendedSelect + " " + extendedWhere); - - return result.build(); - } - - public boolean hasNonAnsDistinguishedVariables() { - return answerVariables[1].length > answerVariables[0].length; - } - - /** - * Two QueryRecords are equal iff - * they have the same queryText, - * soundAnswerTuples. - */ - @Override - public boolean equals(Object o) { - if(!o.getClass().equals(getClass())) return false; - QueryRecord that = (QueryRecord) o; - return this.queryText.equals(that.queryText) - && soundAnswerTuples.equals(that.soundAnswerTuples); - } - - @Override - public int hashCode() { - return Objects.hash(queryText, soundAnswerTuples); - } - - public enum Step { - LOWER_BOUND, - UPPER_BOUND, - SIMPLE_UPPER_BOUND, - LAZY_UPPER_BOUND, - L_SKOLEM_UPPER_BOUND, - EL_LOWER_BOUND, - FRAGMENT, - FRAGMENT_REFINEMENT, - SUMMARISATION, - DEPENDENCY, - FULL_REASONING - } - - /** - * A Json serializer, which considers the main attributes. - */ - public static class QueryRecordSerializer implements JsonSerializer { - public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - JsonObject object = new JsonObject(); - object.addProperty("queryID", src.queryID); - object.addProperty("queryText", src.queryText); + TupleBuilder result = new TupleBuilder(); + result.append(extendedSelect + " " + fullyExtendedWhere); + + extra.setLength(0); + if(answerVariables[0] != answerVariables[1]) { + for(int i = answerVariables[0].length; i < answerVariables[1].length; ++i) + extra.append(" ?").append(answerVariables[1][i]); + extendedSelect = extendedSelect + extra.toString(); + } + result.append(extendedSelect + " " + extendedWhere); + + return result.build(); + } + + public boolean hasNonAnsDistinguishedVariables() { + if(isDisposed()) throw new DisposedException(); + + return answerVariables[1].length > answerVariables[0].length; + } + + /** + * Two QueryRecords are equal iff + * they have the same queryText, + * soundAnswerTuples. + */ + @Override + public boolean equals(Object o) { + if(isDisposed()) throw new DisposedException(); + + if(!o.getClass().equals(getClass())) return false; + QueryRecord that = (QueryRecord) o; + return this.queryText.equals(that.queryText) + && soundAnswerTuples.equals(that.soundAnswerTuples); + } + + @Override + public int hashCode() { + if(isDisposed()) throw new DisposedException(); + + return Objects.hash(queryText, soundAnswerTuples); + } + + public enum Step { + LOWER_BOUND, + UPPER_BOUND, + SIMPLE_UPPER_BOUND, + LAZY_UPPER_BOUND, + L_SKOLEM_UPPER_BOUND, + EL_LOWER_BOUND, + FRAGMENT, + FRAGMENT_REFINEMENT, + SUMMARISATION, + DEPENDENCY, + FULL_REASONING + } + + /** + * A Json serializer, which considers the main attributes. + */ + public static class QueryRecordSerializer implements JsonSerializer { + public JsonElement serialize(QueryRecord src, Type typeOfSrc, JsonSerializationContext context) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonObject object = new JsonObject(); + object.addProperty("queryID", src.queryID); + object.addProperty("queryText", src.queryText); // object.addProperty("difficulty", src.difficulty != null ? src.difficulty.toString() : ""); - object.add("answerVariables", context.serialize(src.getAnswerVariables())); - object.add("answers", context.serialize(src.soundAnswerTuples)); + object.add("answerVariables", context.serialize(src.getAnswerVariables())); + object.add("answers", context.serialize(src.soundAnswerTuples)); // object.add("gapAnswers", context.serialize(src.gapAnswerTuples)); - return object; - } - } - - /** - * A Json deserializer, compliant to the output of the serializer defined above. - */ - public static class QueryRecordDeserializer implements JsonDeserializer { - public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - - QueryRecord record = new QueryRecord(); - JsonObject object = json.getAsJsonObject(); - record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); - record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); + return object; + } + } + + /** + * A Json deserializer, compliant to the output of the serializer defined above. + */ + public static class QueryRecordDeserializer implements JsonDeserializer { + public QueryRecord deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + + QueryRecord record = new QueryRecord(); + JsonObject object = json.getAsJsonObject(); + record.queryID = object.getAsJsonPrimitive("queryID").getAsInt(); + record.queryText = object.getAsJsonPrimitive("queryText").getAsString(); // record.difficulty = Step.valueOf(object.getAsJsonPrimitive("difficulty").getAsString()); - JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); - record.answerVariables = new String[2][]; - record.answerVariables[0] = new String[answerVariablesJson.size()]; - for(int i = 0; i < answerVariablesJson.size(); i++) - record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); + JsonArray answerVariablesJson = object.getAsJsonArray("answerVariables"); + record.answerVariables = new String[2][]; + record.answerVariables[0] = new String[answerVariablesJson.size()]; + for(int i = 0; i < answerVariablesJson.size(); i++) + record.answerVariables[0][i] = answerVariablesJson.get(i).getAsString(); - record.soundAnswerTuples = new HashSet<>(); + record.soundAnswerTuples = new HashSet<>(); // record.gapAnswerTuples = new HashSet<>(); - Type type = new TypeToken() { }.getType(); - for (JsonElement answer : object.getAsJsonArray("answers")) { - record.soundAnswerTuples.add(context.deserialize(answer, type)); - } + Type type = new TypeToken() { + }.getType(); + for(JsonElement answer : object.getAsJsonArray("answers")) { + record.soundAnswerTuples.add(context.deserialize(answer, type)); + } // for (JsonElement answer : object.getAsJsonArray("gapAnswers")) { // record.soundAnswerTuples.add(context.deserialize(answer, type)); // } - return record; - } - } - - /** - * Provides an instance (singleton) of Gson, having a specific configuration. - * */ - public static class GsonCreator { - - private static Gson gson; - - private GsonCreator() {} - - public static Gson getInstance() { - if(gson == null) { - gson = new GsonBuilder() - .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer()) - .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer()) - .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer()) - .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer()) - .disableHtmlEscaping() - .setPrettyPrinting() - .create(); - } - return gson; - } + return record; + } + } + + /** + * Provides an instance (singleton) of Gson, having a specific configuration. + */ + public static class GsonCreator { + + private static Gson gson; + + private GsonCreator() { + } + + public static Gson getInstance() { + if(gson == null) { + gson = new GsonBuilder() + .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleSerializer()) + .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordSerializer()) + .registerTypeAdapter(QueryRecord.class, new QueryRecord.QueryRecordDeserializer()) + .registerTypeAdapter(AnswerTuple.class, new AnswerTuple.AnswerTupleDeserializer()) + .disableHtmlEscaping() + .setPrettyPrinting() + .create(); + } + return gson; + } // public static void dispose() { // gson = null; // } - } + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/ConsistencyManager.java b/src/uk/ac/ox/cs/pagoda/reasoner/ConsistencyManager.java index ef9338a..b4a1775 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/ConsistencyManager.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/ConsistencyManager.java @@ -22,10 +22,11 @@ import uk.ac.ox.cs.pagoda.tracking.QueryTracker; import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoder; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; import java.util.LinkedList; -public class ConsistencyManager { +public class ConsistencyManager extends Disposable { protected MyQueryReasoner m_reasoner; protected QueryManager m_queryManager; @@ -40,7 +41,109 @@ public class ConsistencyManager { m_reasoner = reasoner; m_queryManager = reasoner.getQueryManager(); } - + + @Override + public void dispose() { + super.dispose(); + fullQueryRecord.dispose(); + } + + public void extractBottomFragment() { + if(fragmentExtracted) return; + fragmentExtracted = true; + + UpperDatalogProgram upperProgram = m_reasoner.program.getUpper(); + int number = upperProgram.getBottomNumber(); + + if(number <= 1) { + botQueryRecords = new QueryRecord[]{fullQueryRecord}; + } + else { + QueryRecord[] tempQueryRecords = new QueryRecord[number - 1]; + QueryRecord record; + for(int i = 0; i < number - 1; ++i) { + tempQueryRecords[i] = record = + m_queryManager.create(QueryRecord.botQueryText.replace("Nothing", "Nothing" + (i + 1)), 0, i + 1); + AnswerTuples iter = null; + try { + iter = m_reasoner.trackingStore.evaluate(record.getQueryText(), record.getAnswerVariables()); + record.updateUpperBoundAnswers(iter); + } finally { + if(iter != null) iter.dispose(); + iter = null; + } + } + + int bottomNumber = 0; + int[] group = new int[number - 1]; + for(int i = 0; i < number - 1; ++i) group[i] = i; + for(int i = 0; i < number - 1; ++i) + if(tempQueryRecords[i].isProcessed()) tempQueryRecords[i].dispose(); + else if(group[i] == i) { + ++bottomNumber; + record = tempQueryRecords[i]; + for(int j = i + 1; j < number - 1; ++j) + if(record.hasSameGapAnswers(tempQueryRecords[j])) + group[j] = i; + } + + Utility.logInfo("There are " + bottomNumber + " different bottom fragments."); + toAddClauses = new LinkedList(); + int bottomCounter = 0; + botQueryRecords = new QueryRecord[bottomNumber]; + Variable X = Variable.create("X"); + for(int i = 0; i < number - 1; ++i) + if(!tempQueryRecords[i].isDisposed() && !tempQueryRecords[i].isProcessed()) + if(group[i] == i) { + botQueryRecords[bottomCounter] = record = tempQueryRecords[i]; + record.resetInfo(QueryRecord.botQueryText.replace("Nothing", "Nothing_final" + (++bottomCounter)), 0, + group[i] = bottomCounter); + toAddClauses.add( + DLClause.create( + new Atom[]{Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + "_final" + bottomCounter), X)}, + new Atom[]{Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + (i + 1)), X)})); + } + else { + toAddClauses.add( + DLClause.create( + new Atom[]{Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + "_final" + group[group[i]]), X)}, + new Atom[]{Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + (i + 1)), X)})); + tempQueryRecords[i].dispose(); + } + + upperProgram.updateDependencyGraph(toAddClauses); + } + + String[] programs = collectTrackingProgramAndImport(); + if(programs.length == 0) + return; + + DataStore store = m_reasoner.trackingStore.getDataStore(); + long oldTripleCount, tripleCount; + try { + Timer t1 = new Timer(); + oldTripleCount = store.getTriplesCount(); + for(String program : programs) + store.importRules(program, UpdateType.ScheduleForAddition); + store.applyReasoning(true); + tripleCount = store.getTriplesCount(); + + Utility.logInfo("tracking store after materialising tracking program: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)", + "tracking store finished the materialisation of tracking program in " + t1.duration() + " seconds."); + + extractAxioms(); + store.clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } catch(OWLOntologyCreationException e) { + e.printStackTrace(); + } + } + + public QueryRecord[] getQueryRecords() { + return botQueryRecords; + } + boolean checkRLLowerBound() { fullQueryRecord = m_queryManager.create(QueryRecord.botQueryText, 0); AnswerTuples iter = null; @@ -59,9 +162,22 @@ public class ConsistencyManager { return true; } +// protected boolean unsatisfiability(double duration) { +// fullQueryRecord.dispose(); +// Utility.logDebug("The ontology and dataset is unsatisfiable."); +// return false; +// } + +// protected boolean satisfiability(double duration) { +// fullQueryRecord.dispose(); +// Utility.logDebug("The ontology and dataset is satisfiable."); +// return true; +// } + boolean checkELLowerBound() { - fullQueryRecord.updateLowerBoundAnswers(m_reasoner.elLowerStore.evaluate(fullQueryRecord.getQueryText(), fullQueryRecord.getAnswerVariables())); - if (fullQueryRecord.getNoOfSoundAnswers() > 0) { + fullQueryRecord.updateLowerBoundAnswers(m_reasoner.elLowerStore.evaluate(fullQueryRecord.getQueryText(), fullQueryRecord + .getAnswerVariables())); + if(fullQueryRecord.getNoOfSoundAnswers() > 0) { Utility.logInfo("Answers to bottom in the lower bound: ", fullQueryRecord.outputSoundAnswerTuple()); return true; } @@ -69,39 +185,22 @@ public class ConsistencyManager { } boolean checkUpper(BasicQueryEngine upperStore) { - if (upperStore != null) { + if(upperStore != null) { AnswerTuples tuples = null; try { tuples = upperStore.evaluate(fullQueryRecord.getQueryText(), fullQueryRecord.getAnswerVariables()); - if (!tuples.isValid()) { - Utility.logInfo("There are no contradictions derived in "+ upperStore.getName() +" materialisation."); + if(!tuples.isValid()) { + Utility.logInfo("There are no contradictions derived in " + upperStore.getName() + " materialisation."); Utility.logDebug("The ontology and dataset is satisfiable."); return true; } - } - finally { - if (tuples != null) tuples.dispose(); + } finally { + if(tuples != null) tuples.dispose(); } } return false; } - void dispose() { - fullQueryRecord.dispose(); - } - -// protected boolean unsatisfiability(double duration) { -// fullQueryRecord.dispose(); -// Utility.logDebug("The ontology and dataset is unsatisfiable."); -// return false; -// } - -// protected boolean satisfiability(double duration) { -// fullQueryRecord.dispose(); -// Utility.logDebug("The ontology and dataset is satisfiable."); -// return true; -// } - boolean check() { // if (!checkRLLowerBound()) return false; // if (!checkELLowerBound()) return false; @@ -148,148 +247,54 @@ public class ConsistencyManager { return true; } - public void extractBottomFragment() { - if (fragmentExtracted) return ; - fragmentExtracted = true; - - UpperDatalogProgram upperProgram = m_reasoner.program.getUpper(); - int number = upperProgram.getBottomNumber(); - - if (number <= 1) { - botQueryRecords = new QueryRecord[] { fullQueryRecord }; - } - else { - QueryRecord[] tempQueryRecords = new QueryRecord[number - 1]; - QueryRecord record; - for (int i = 0; i < number - 1; ++i) { - tempQueryRecords[i] = record = m_queryManager.create(QueryRecord.botQueryText.replace("Nothing", "Nothing" + (i + 1)), 0, i + 1); - AnswerTuples iter = null; - try { - iter = m_reasoner.trackingStore.evaluate(record.getQueryText(), record.getAnswerVariables()); - record.updateUpperBoundAnswers(iter); - } finally { - if (iter != null) iter.dispose(); - iter = null; - } - } - - int bottomNumber = 0; - int[] group = new int[number - 1]; - for (int i = 0; i < number - 1; ++i) group[i] = i; - for (int i = 0; i < number - 1; ++i) - if(tempQueryRecords[i].isProcessed()) tempQueryRecords[i].dispose(); - else if (group[i] == i) { - ++bottomNumber; - record = tempQueryRecords[i]; - for (int j = i + 1; j < number - 1; ++j) - if (record.hasSameGapAnswers(tempQueryRecords[j])) - group[j] = i; - } - - Utility.logInfo("There are " + bottomNumber + " different bottom fragments."); - toAddClauses = new LinkedList(); - int bottomCounter = 0; - botQueryRecords = new QueryRecord[bottomNumber]; - Variable X = Variable.create("X"); - for (int i = 0; i < number - 1; ++i) - if(!tempQueryRecords[i].isProcessed()) - if (group[i] == i) { - botQueryRecords[bottomCounter] = record = tempQueryRecords[i]; - record.resetInfo(QueryRecord.botQueryText.replace("Nothing", "Nothing_final" + (++bottomCounter)), 0, group[i] = bottomCounter); - toAddClauses.add( - DLClause.create( - new Atom[] {Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + "_final" + bottomCounter), X)}, - new Atom[] {Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + (i + 1)), X)})); - } - else { - toAddClauses.add( - DLClause.create( - new Atom[] {Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + "_final" + group[group[i]]), X)}, - new Atom[] {Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + (i + 1)), X)})); - tempQueryRecords[i].dispose(); - } - - upperProgram.updateDependencyGraph(toAddClauses); - } - - String[] programs = collectTrackingProgramAndImport(); - if (programs.length == 0) - return ; - - DataStore store = m_reasoner.trackingStore.getDataStore(); - long oldTripleCount, tripleCount; - try { - Timer t1 = new Timer(); - oldTripleCount = store.getTriplesCount(); - for (String program: programs) - store.importRules(program, UpdateType.ScheduleForAddition); - store.applyReasoning(true); - tripleCount = store.getTriplesCount(); - - Utility.logInfo("tracking store after materialising tracking program: " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)", - "tracking store finished the materialisation of tracking program in " + t1.duration() + " seconds."); - - extractAxioms(); - store.clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } catch (OWLOntologyCreationException e) { - e.printStackTrace(); - } - } - private void extractAxioms4Full() throws OWLOntologyCreationException { - OWLOntologyManager manager = m_reasoner.encoder.getProgram().getOntology().getOWLOntologyManager(); + OWLOntologyManager manager = m_reasoner.encoder.getProgram().getOntology().getOWLOntologyManager(); OWLOntology fullOntology = manager.createOntology(); for (QueryRecord record: botQueryRecords) { for (DLClause clause: record.getRelevantClauses()) { fullQueryRecord.addRelevantClauses(clause); } - manager.addAxioms(fullOntology, record.getRelevantOntology().getAxioms()); + manager.addAxioms(fullOntology, record.getRelevantOntology().getAxioms()); } fullQueryRecord.setRelevantOntology(fullOntology); } private void extractAxioms() throws OWLOntologyCreationException { - OWLOntologyManager manager = m_reasoner.encoder.getProgram().getOntology().getOWLOntologyManager(); + OWLOntologyManager manager = m_reasoner.encoder.getProgram().getOntology().getOWLOntologyManager(); for (QueryRecord record: botQueryRecords) { record.setRelevantOntology(manager.createOntology()); - QueryTracker tracker = new QueryTracker(m_reasoner.encoder, m_reasoner.rlLowerStore, record); + QueryTracker tracker = new QueryTracker(m_reasoner.encoder, m_reasoner.rlLowerStore, record); m_reasoner.encoder.setCurrentQuery(record); tracker.extractAxioms(m_reasoner.trackingStore); // record.saveRelevantClause(); // record.saveRelevantOntology("bottom" + record.getQueryID() + ".owl"); Utility.logInfo("finish extracting axioms for bottom " + record.getQueryID()); - } + } } private String[] collectTrackingProgramAndImport() { - String[] programs = new String[botQueryRecords.length]; + String[] programs = new String[botQueryRecords.length]; TrackingRuleEncoder encoder = m_reasoner.encoder; - + StringBuilder builder; - LinkedList currentClauses = new LinkedList(); - + LinkedList currentClauses = new LinkedList(); + for (int i = 0; i < botQueryRecords.length; ++i) { encoder.setCurrentQuery(botQueryRecords[i]); builder = new StringBuilder(encoder.getTrackingProgram()); // encoder.saveTrackingRules("tracking_bottom" + (i + 1) + ".dlog"); - + for (DLClause clause: toAddClauses) if (clause.getHeadAtom(0).getDLPredicate().toString().contains("_final" + (i + 1))) - currentClauses.add(clause); - + currentClauses.add(clause); + builder.append(DLClauseHelper.toString(currentClauses)); - programs[i] = builder.toString(); - + programs[i] = builder.toString(); + currentClauses.clear(); } - - return programs; - } - public QueryRecord[] getQueryRecords() { - return botQueryRecords; + return programs; } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOQueryReasoner.java index f5a8093..0a151bc 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOQueryReasoner.java @@ -10,86 +10,92 @@ import uk.ac.ox.cs.pagoda.reasoner.light.KarmaQueryEngine; import uk.ac.ox.cs.pagoda.rules.LowerDatalogProgram; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; class ELHOQueryReasoner extends QueryReasoner { - LowerDatalogProgram program; - - OWLOntology elho_ontology; - KarmaQueryEngine elLowerStore = null; - - private Timer t = new Timer(); - - public ELHOQueryReasoner() { - elLowerStore = new KarmaQueryEngine("el"); - } - - @Override - public void evaluate(QueryRecord queryRecord) { - AnswerTuples elAnswer = null; - t.reset(); - try { - elAnswer = elLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - queryRecord.updateLowerBoundAnswers(elAnswer); - } finally { - if (elAnswer != null) elAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); - - queryRecord.setDifficulty(Step.EL_LOWER_BOUND); - queryRecord.markAsProcessed(); - } - - @Override - public void evaluateUpper(QueryRecord queryRecord) { - evaluate(queryRecord); - } - - @Override - public void dispose() { - if (elLowerStore != null) elLowerStore.dispose(); - super.dispose(); - } - - @Override - public void loadOntology(OWLOntology ontology) { - program = new LowerDatalogProgram(properties.getToClassify()); - program.load(ontology, new UnaryBottom()); - program.transform(); - - importData(program.getAdditionalDataFile()); - - elho_ontology = new ELHOProfile().getFragment(ontology); - elLowerStore.processOntology(elho_ontology); - } - - @Override - public boolean preprocess() { - elLowerStore.importRDFData("data", importedData.toString()); - String rlLowerProgramText = program.toString(); + LowerDatalogProgram program; + + OWLOntology elho_ontology; + KarmaQueryEngine elLowerStore = null; + + private Timer t = new Timer(); + + public ELHOQueryReasoner() { + elLowerStore = new KarmaQueryEngine("el"); + } + + @Override + public void evaluate(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + AnswerTuples elAnswer = null; + t.reset(); + try { + elAnswer = elLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + queryRecord.updateLowerBoundAnswers(elAnswer); + } finally { + if(elAnswer != null) elAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); + + queryRecord.setDifficulty(Step.EL_LOWER_BOUND); + queryRecord.markAsProcessed(); + } + + @Override + public void evaluateUpper(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + evaluate(queryRecord); + } + + @Override + public void dispose() { + super.dispose(); + if(elLowerStore != null) elLowerStore.dispose(); + } + + @Override + public void loadOntology(OWLOntology ontology) { + if(isDisposed()) throw new DisposedException(); + program = new LowerDatalogProgram(properties.getToClassify()); + program.load(ontology, new UnaryBottom()); + program.transform(); + + importData(program.getAdditionalDataFile()); + + elho_ontology = new ELHOProfile().getFragment(ontology); + elLowerStore.processOntology(elho_ontology); + } + + @Override + public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); + elLowerStore.importRDFData("data", importedData.toString()); + String rlLowerProgramText = program.toString(); // program.save(); - elLowerStore.materialise("lower program", rlLowerProgramText); - elLowerStore.initialiseKarma(); - - if (!isConsistent()) { - Utility.logDebug("The dataset is not consistent with the ontology."); - return false; - } - return true; - } - - @Override - public boolean isConsistent() { - String[] X = new String[] {"X"}; - AnswerTuples ans = null; - try { - ans = elLowerStore.evaluate(QueryRecord.botQueryText, X); - if (ans.isValid()) return false; - } finally { - if (ans != null) ans.dispose(); - } - - return true; - } + elLowerStore.materialise("lower program", rlLowerProgramText); + elLowerStore.initialiseKarma(); + + if(!isConsistent()) { + Utility.logDebug("The dataset is not consistent with the ontology."); + return false; + } + return true; + } + + @Override + public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); + String[] X = new String[]{"X"}; + AnswerTuples ans = null; + try { + ans = elLowerStore.evaluate(QueryRecord.botQueryText, X); + if(ans.isValid()) return false; + } finally { + if(ans != null) ans.dispose(); + } + + return true; + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java index c74ea58..771190e 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java @@ -13,181 +13,187 @@ import uk.ac.ox.cs.pagoda.reasoner.light.KarmaQueryEngine; import uk.ac.ox.cs.pagoda.rules.DatalogProgram; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; class ELHOUQueryReasoner extends QueryReasoner { - DatalogProgram program; - - BasicQueryEngine rlLowerStore; - BasicQueryEngine rlUpperStore; - - OWLOntology elho_ontology; - KarmaQueryEngine elLowerStore = null; - - boolean multiStageTag, equalityTag; - String originalMarkProgram; - private Timer t = new Timer(); - - public ELHOUQueryReasoner(boolean multiStageTag, boolean considerEqualities) { - this.multiStageTag = multiStageTag; - this.equalityTag = considerEqualities; - rlLowerStore = new BasicQueryEngine("rl-lower-bound"); - elLowerStore = new KarmaQueryEngine("el-lower-bound"); - - if(!multiStageTag) - rlUpperStore = new BasicQueryEngine("rl-upper-bound"); - else - rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false); - } - - @Override - public void evaluate(QueryRecord queryRecord) { - AnswerTuples rlAnswer = null; - t.reset(); - try { - rlAnswer = rlLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - queryRecord.updateLowerBoundAnswers(rlAnswer); - } finally { - if(rlAnswer != null) rlAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.LOWER_BOUND, t.duration()); - - String extendedQueryText = queryRecord.getExtendedQueryText().get(0); - String[] toQuery = queryRecord.getQueryText().equals(extendedQueryText) ? - new String[]{queryRecord.getQueryText()} : - new String[] {queryRecord.getQueryText(), extendedQueryText}; - - for (String queryText: toQuery) { - rlAnswer = null; - t.reset(); - try { - rlAnswer = rlUpperStore.evaluate(queryText, queryRecord.getAnswerVariables()); - queryRecord.updateUpperBoundAnswers(rlAnswer); - } finally { - if(rlAnswer != null) rlAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.UPPER_BOUND, t.duration()); - - if(queryRecord.isProcessed()) { - queryRecord.setDifficulty(Step.UPPER_BOUND); - return; - } - } - - AnswerTuples elAnswer = null; - t.reset(); - try { - elAnswer = - elLowerStore.evaluate(extendedQueryText, queryRecord.getAnswerVariables(), queryRecord.getLowerBoundAnswers()); - queryRecord.updateLowerBoundAnswers(elAnswer); - } finally { - if (elAnswer != null) elAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); - } - - @Override - public void evaluateUpper(QueryRecord queryRecord) { - AnswerTuples rlAnswer = null; - try { - rlAnswer = rlUpperStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - queryRecord.updateUpperBoundAnswers(rlAnswer, true); - } finally { - if(rlAnswer != null) rlAnswer.dispose(); - } - } - - @Override - public void dispose() { - if (elLowerStore != null) elLowerStore.dispose(); - if(rlUpperStore != null) rlUpperStore.dispose(); - super.dispose(); - } - - @Override - public void loadOntology(OWLOntology o) { - if (!equalityTag) { - EqualitiesEliminator eliminator = new EqualitiesEliminator(o); - o = eliminator.getOutputOntology(); - eliminator.save(); - } - - OWLOntology ontology = o; - program = new DatalogProgram(ontology, properties.getToClassify()); - - importData(program.getAdditionalDataFile()); - - elho_ontology = new ELHOProfile().getFragment(ontology); - elLowerStore.processOntology(elho_ontology); - originalMarkProgram = OWLHelper.getOriginalMarkProgram(ontology); - } - - @Override - public boolean preprocess() { - String name = "data", datafile = importedData.toString(); - - String lowername = "lower program"; - String rlLowerProgramText = program.getLower().toString(); - - rlUpperStore.importRDFData(name, datafile); - rlUpperStore.materialise("saturate named individuals", originalMarkProgram); - - int flag = rlUpperStore.materialiseRestrictedly(program, null); - if (flag != 1) { - if (flag == -1) return false; - rlUpperStore.dispose(); - - if (!multiStageTag) - rlUpperStore = new BasicQueryEngine("rl-upper-bound"); - else - rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false); - rlUpperStore.importRDFData(name, datafile); - rlUpperStore.materialise("saturate named individuals", originalMarkProgram); - rlUpperStore.materialiseFoldedly(program, null); - } - Utility.logInfo("upper store ready."); - - rlLowerStore.importRDFData(name, datafile); - rlLowerStore.materialise(lowername, rlLowerProgramText); - Utility.logInfo("lower store ready."); - - elLowerStore.importRDFData(name, datafile); - elLowerStore.materialise("saturate named individuals", originalMarkProgram); - elLowerStore.materialise(lowername, rlLowerProgramText); - - elLowerStore.initialiseKarma(); - Utility.logInfo("EL lower store ready."); - - if (!isConsistent()) { - Utility.logInfo("The dataset is not consistent with the ontology."); - return false; - } - Utility.logInfo("The dataset is consistent."); - return true; - } - - @Override - public boolean isConsistent() { - Utility.logInfo("Start checking consistency... "); - String[] X = new String[] {"X"}; - AnswerTuples ans = null; - try { - ans = rlUpperStore.evaluate(QueryRecord.botQueryText, X); - if (!ans.isValid()) return true; - } finally { - if (ans != null) ans.dispose(); - } - - ans = null; - try { - ans = elLowerStore.evaluate(QueryRecord.botQueryText, X); - if (ans.isValid()) return false; - } finally { - if (ans != null) ans.dispose(); - } - - Utility.logDebug("The consistency of the data has not been determined yet."); - return true; - } + DatalogProgram program; + + BasicQueryEngine rlLowerStore; + BasicQueryEngine rlUpperStore; + + OWLOntology elho_ontology; + KarmaQueryEngine elLowerStore = null; + + boolean multiStageTag, equalityTag; + String originalMarkProgram; + private Timer t = new Timer(); + + public ELHOUQueryReasoner(boolean multiStageTag, boolean considerEqualities) { + this.multiStageTag = multiStageTag; + this.equalityTag = considerEqualities; + rlLowerStore = new BasicQueryEngine("rl-lower-bound"); + elLowerStore = new KarmaQueryEngine("el-lower-bound"); + + if(!multiStageTag) + rlUpperStore = new BasicQueryEngine("rl-upper-bound"); + else + rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false); + } + + @Override + public void evaluate(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + AnswerTuples rlAnswer = null; + t.reset(); + try { + rlAnswer = rlLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + queryRecord.updateLowerBoundAnswers(rlAnswer); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.LOWER_BOUND, t.duration()); + + String extendedQueryText = queryRecord.getExtendedQueryText().get(0); + String[] toQuery = queryRecord.getQueryText().equals(extendedQueryText) ? + new String[]{queryRecord.getQueryText()} : + new String[]{queryRecord.getQueryText(), extendedQueryText}; + + for(String queryText : toQuery) { + rlAnswer = null; + t.reset(); + try { + rlAnswer = rlUpperStore.evaluate(queryText, queryRecord.getAnswerVariables()); + queryRecord.updateUpperBoundAnswers(rlAnswer); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.UPPER_BOUND, t.duration()); + + if(queryRecord.isProcessed()) { + queryRecord.setDifficulty(Step.UPPER_BOUND); + return; + } + } + + AnswerTuples elAnswer = null; + t.reset(); + try { + elAnswer = + elLowerStore.evaluate(extendedQueryText, queryRecord.getAnswerVariables(), queryRecord.getLowerBoundAnswers()); + queryRecord.updateLowerBoundAnswers(elAnswer); + } finally { + if(elAnswer != null) elAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); + } + + @Override + public void evaluateUpper(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + AnswerTuples rlAnswer = null; + try { + rlAnswer = rlUpperStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + queryRecord.updateUpperBoundAnswers(rlAnswer, true); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + } + + @Override + public void dispose() { + super.dispose(); + if(elLowerStore != null) elLowerStore.dispose(); + if(rlUpperStore != null) rlUpperStore.dispose(); + } + + @Override + public void loadOntology(OWLOntology o) { + if(isDisposed()) throw new DisposedException(); + if(!equalityTag) { + EqualitiesEliminator eliminator = new EqualitiesEliminator(o); + o = eliminator.getOutputOntology(); + eliminator.save(); + } + + OWLOntology ontology = o; + program = new DatalogProgram(ontology, properties.getToClassify()); + + importData(program.getAdditionalDataFile()); + + elho_ontology = new ELHOProfile().getFragment(ontology); + elLowerStore.processOntology(elho_ontology); + originalMarkProgram = OWLHelper.getOriginalMarkProgram(ontology); + } + + @Override + public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); + String name = "data", datafile = importedData.toString(); + + String lowername = "lower program"; + String rlLowerProgramText = program.getLower().toString(); + + rlUpperStore.importRDFData(name, datafile); + rlUpperStore.materialise("saturate named individuals", originalMarkProgram); + + int flag = rlUpperStore.materialiseRestrictedly(program, null); + if(flag != 1) { + if(flag == -1) return false; + rlUpperStore.dispose(); + + if(!multiStageTag) + rlUpperStore = new BasicQueryEngine("rl-upper-bound"); + else + rlUpperStore = new MultiStageQueryEngine("rl-upper-bound", false); + rlUpperStore.importRDFData(name, datafile); + rlUpperStore.materialise("saturate named individuals", originalMarkProgram); + rlUpperStore.materialiseFoldedly(program, null); + } + Utility.logInfo("upper store ready."); + + rlLowerStore.importRDFData(name, datafile); + rlLowerStore.materialise(lowername, rlLowerProgramText); + Utility.logInfo("lower store ready."); + + elLowerStore.importRDFData(name, datafile); + elLowerStore.materialise("saturate named individuals", originalMarkProgram); + elLowerStore.materialise(lowername, rlLowerProgramText); + + elLowerStore.initialiseKarma(); + Utility.logInfo("EL lower store ready."); + + if(!isConsistent()) { + Utility.logInfo("The dataset is not consistent with the ontology."); + return false; + } + Utility.logInfo("The dataset is consistent."); + return true; + } + + @Override + public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); + Utility.logInfo("Start checking consistency... "); + String[] X = new String[]{"X"}; + AnswerTuples ans = null; + try { + ans = rlUpperStore.evaluate(QueryRecord.botQueryText, X); + if(!ans.isValid()) return true; + } finally { + if(ans != null) ans.dispose(); + } + + ans = null; + try { + ans = elLowerStore.evaluate(QueryRecord.botQueryText, X); + if(ans.isValid()) return false; + } finally { + if(ans != null) ans.dispose(); + } + + Utility.logDebug("The consistency of the data has not been determined yet."); + return true; + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java index d1856c9..78b9a0b 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java @@ -10,6 +10,7 @@ import uk.ac.ox.cs.pagoda.query.*; import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; import uk.ac.ox.cs.pagoda.rules.DatalogProgram; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.io.File; import java.io.IOException; @@ -17,100 +18,105 @@ import java.util.HashSet; import java.util.Set; class HermiTReasoner extends QueryReasoner { - - Reasoner hermit; - - BasicQueryEngine upperStore = null; - - OWLOntology onto; - OWLDataFactory factory; - - String importedOntologyPath = null; - - QueryRoller roller; - boolean toCheckSatisfiability; - - public HermiTReasoner(boolean toCheckSatisfiability) { - this.toCheckSatisfiability = toCheckSatisfiability; - } - - @Override - public void loadOntology(OWLOntology ontology) { - onto = ontology; - } - - @Override - public boolean preprocess() { - OWLOntology tbox = onto; - try { - onto = OWLHelper.getImportedOntology(tbox, importedData.toString().split(ImportDataFileSeparator)); - importedOntologyPath = OWLHelper.getOntologyPath(onto); - } catch(OWLOntologyCreationException | OWLOntologyStorageException | IOException e) { - e.printStackTrace(); - } - - DatalogProgram datalogProgram = new DatalogProgram(tbox, false); - importData(datalogProgram.getAdditionalDataFile()); - upperStore = new MultiStageQueryEngine("rl-upper", false); - upperStore.importRDFData("data", importedData.toString()); - GapByStore4ID gap = new GapByStore4ID(upperStore); - upperStore.materialiseFoldedly(datalogProgram, gap); - gap.clear(); - - factory = onto.getOWLOntologyManager().getOWLDataFactory(); - roller = new QueryRoller(factory); - - hermit = new Reasoner(onto); - return isConsistent(); - } - - @Override - public boolean isConsistent() { - if (toCheckSatisfiability) - return hermit.isConsistent(); - return true; - } - - @Override - public void evaluate(QueryRecord record) { - String[] disVars = record.getDistinguishedVariables(); - Set individuals = onto.getIndividualsInSignature(true); - if (disVars.length == 1) { - OWLClassExpression clsExp = roller.rollUp(record.getClause(), record.getAnswerVariables()[0]); - Set answers = new HashSet(); - for (OWLNamedIndividual individual: individuals) { - Utility.logDebug("checking ... " + individual); - if (hermit.isEntailed(factory.getOWLClassAssertionAxiom(clsExp, individual))) { - answers.add(new AnswerTuple(new Individual[] {Individual.create(individual.toStringID())})); - } - } - record.updateLowerBoundAnswers(new AnswerTuplesImp(record.getAnswerVariables(), answers)); - record.markAsProcessed(); - } - else { - // FIXME join here - record.markAsProcessed(); - } - } - - @Override - public void evaluateUpper(QueryRecord record) { - AnswerTuples rlAnswer = null; - try { - rlAnswer = upperStore.evaluate(record.getQueryText(), record.getAnswerVariables()); - record.updateUpperBoundAnswers(rlAnswer, true); - } finally { - if (rlAnswer != null) rlAnswer.dispose(); - } - } - - @Override - public void dispose() { - if (importedOntologyPath != null) { - File tmp = new File(importedOntologyPath); - if (tmp.exists()) tmp.delete(); - } - super.dispose(); - } + + Reasoner hermit; + + BasicQueryEngine upperStore = null; + + OWLOntology onto; + OWLDataFactory factory; + + String importedOntologyPath = null; + + QueryRoller roller; + boolean toCheckSatisfiability; + + public HermiTReasoner(boolean toCheckSatisfiability) { + this.toCheckSatisfiability = toCheckSatisfiability; + } + + @Override + public void loadOntology(OWLOntology ontology) { + if(isDisposed()) throw new DisposedException(); + onto = ontology; + } + + @Override + public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); + OWLOntology tbox = onto; + try { + onto = OWLHelper.getImportedOntology(tbox, importedData.toString().split(ImportDataFileSeparator)); + importedOntologyPath = OWLHelper.getOntologyPath(onto); + } catch(OWLOntologyCreationException | OWLOntologyStorageException | IOException e) { + e.printStackTrace(); + } + + DatalogProgram datalogProgram = new DatalogProgram(tbox, false); + importData(datalogProgram.getAdditionalDataFile()); + upperStore = new MultiStageQueryEngine("rl-upper", false); + upperStore.importRDFData("data", importedData.toString()); + GapByStore4ID gap = new GapByStore4ID(upperStore); + upperStore.materialiseFoldedly(datalogProgram, gap); + gap.clear(); + + factory = onto.getOWLOntologyManager().getOWLDataFactory(); + roller = new QueryRoller(factory); + + hermit = new Reasoner(onto); + return isConsistent(); + } + + @Override + public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); + if(toCheckSatisfiability) + return hermit.isConsistent(); + return true; + } + + @Override + public void evaluate(QueryRecord record) { + if(isDisposed()) throw new DisposedException(); + String[] disVars = record.getDistinguishedVariables(); + Set individuals = onto.getIndividualsInSignature(true); + if(disVars.length == 1) { + OWLClassExpression clsExp = roller.rollUp(record.getClause(), record.getAnswerVariables()[0]); + Set answers = new HashSet(); + for(OWLNamedIndividual individual : individuals) { + Utility.logDebug("checking ... " + individual); + if(hermit.isEntailed(factory.getOWLClassAssertionAxiom(clsExp, individual))) { + answers.add(new AnswerTuple(new Individual[]{Individual.create(individual.toStringID())})); + } + } + record.updateLowerBoundAnswers(new AnswerTuplesImp(record.getAnswerVariables(), answers)); + record.markAsProcessed(); + } + else { + // FIXME join here + record.markAsProcessed(); + } + } + + @Override + public void evaluateUpper(QueryRecord record) { + if(isDisposed()) throw new DisposedException(); + AnswerTuples rlAnswer = null; + try { + rlAnswer = upperStore.evaluate(record.getQueryText(), record.getAnswerVariables()); + record.updateUpperBoundAnswers(rlAnswer, true); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + } + + @Override + public void dispose() { + super.dispose(); + if(importedOntologyPath != null) { + File tmp = new File(importedOntologyPath); + if(tmp.exists()) tmp.delete(); + } + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java index 618fb70..8445713 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java @@ -21,362 +21,364 @@ import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoderDisjVar1; import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoderWithGap; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import uk.ac.ox.cs.pagoda.util.tuples.Tuple; import java.util.Collection; class MyQueryReasoner extends QueryReasoner { - OWLOntology ontology; - DatalogProgram program; - -// String additonalDataFile; - BasicQueryEngine rlLowerStore = null; - BasicQueryEngine lazyUpperStore = null; - // BasicQueryEngine limitedSkolemUpperStore; - OWLOntology elho_ontology; -// boolean[] namedIndividuals_lazyUpper; - KarmaQueryEngine elLowerStore = null; - BasicQueryEngine trackingStore = null; - // boolean[] namedIndividuals_tracking; - TrackingRuleEncoder encoder; - private boolean equalityTag; - private boolean multiStageTag; - private Timer t = new Timer(); - private Collection predicatesWithGap = null; - private SatisfiabilityStatus satisfiable; - private ConsistencyManager consistency = new ConsistencyManager(this); - private boolean useUpperStores = false; - public MyQueryReasoner() { - setup(true, true); - } - public MyQueryReasoner(boolean multiStageTag, boolean considerEqualities) { - setup(multiStageTag, considerEqualities); - } - - private BasicQueryEngine getUpperStore(String name, boolean checkValidity) { - if (multiStageTag) - return new MultiStageQueryEngine(name, checkValidity); -// return new TwoStageQueryEngine(name, checkValidity); - else - return new BasicQueryEngine(name); - } - - public void setup(boolean multiStageTag, boolean considerEqualities) { - satisfiable = SatisfiabilityStatus.UNCHECKED; - this.multiStageTag = multiStageTag; - this.equalityTag = considerEqualities; - - rlLowerStore = new BasicQueryEngine("rl-lower-bound"); - elLowerStore = new KarmaQueryEngine("elho-lower-bound"); - - trackingStore = getUpperStore("tracking", false); - } - - protected void internal_importDataFile(String name, String datafile) { -// addDataFile(datafile); - rlLowerStore.importRDFData(name, datafile); - if (lazyUpperStore != null) - lazyUpperStore.importRDFData(name, datafile); - elLowerStore.importRDFData(name, datafile); - trackingStore.importRDFData(name, datafile); - } - - @Override - public void loadOntology(OWLOntology o) { - if(!equalityTag) { - EqualitiesEliminator eliminator = new EqualitiesEliminator(o); - o = eliminator.getOutputOntology(); - eliminator.save(); - } - - ontology = o; - program = new DatalogProgram(ontology, properties.getToClassify()); + OWLOntology ontology; + DatalogProgram program; + + // String additonalDataFile; + BasicQueryEngine rlLowerStore = null; + BasicQueryEngine lazyUpperStore = null; + MultiStageQueryEngine limitedSkolemUpperStore; + OWLOntology elho_ontology; + // boolean[] namedIndividuals_lazyUpper; + KarmaQueryEngine elLowerStore = null; + BasicQueryEngine trackingStore = null; + // boolean[] namedIndividuals_tracking; + TrackingRuleEncoder encoder; + private boolean equalityTag; + private boolean multiStageTag; + private Timer t = new Timer(); + private Collection predicatesWithGap = null; + private SatisfiabilityStatus satisfiable; + private ConsistencyManager consistency = new ConsistencyManager(this); + private boolean useUpperStores = false; + + public MyQueryReasoner() { + setup(true, true); + } + + public MyQueryReasoner(boolean multiStageTag, boolean considerEqualities) { + setup(multiStageTag, considerEqualities); + } + + public void setup(boolean multiStageTag, boolean considerEqualities) { + if(isDisposed()) throw new DisposedException(); + satisfiable = SatisfiabilityStatus.UNCHECKED; + this.multiStageTag = multiStageTag; + this.equalityTag = considerEqualities; + + rlLowerStore = new BasicQueryEngine("rl-lower-bound"); + elLowerStore = new KarmaQueryEngine("elho-lower-bound"); + + trackingStore = getUpperStore("tracking", false); + } + + @Override + public void loadOntology(OWLOntology o) { + if(isDisposed()) throw new DisposedException(); + if(!equalityTag) { + EqualitiesEliminator eliminator = new EqualitiesEliminator(o); + o = eliminator.getOutputOntology(); + eliminator.save(); + } + + ontology = o; + program = new DatalogProgram(ontology, properties.getToClassify()); // program.getLower().save(); // program.getUpper().save(); // program.getGeneral().save(); - useUpperStores = multiStageTag && !program.getGeneral().isHorn(); - if(useUpperStores) { - lazyUpperStore = getUpperStore("lazy-upper-bound", true); -// limitedSkolemUpperStore = getUpperStore("limited-skolem-upper-bound", true); - } + useUpperStores = multiStageTag && !program.getGeneral().isHorn(); + if(useUpperStores) { + lazyUpperStore = getUpperStore("lazy-upper-bound", true); + limitedSkolemUpperStore = new MultiStageQueryEngine("limited-skolem-upper-bound", true); + } - importData(program.getAdditionalDataFile()); + importData(program.getAdditionalDataFile()); - elho_ontology = new ELHOProfile().getFragment(ontology); - elLowerStore.processOntology(elho_ontology); - } + elho_ontology = new ELHOProfile().getFragment(ontology); + elLowerStore.processOntology(elho_ontology); + } - public Collection getPredicatesWithGap() { - return predicatesWithGap; - } + public Collection getPredicatesWithGap() { + if(isDisposed()) throw new DisposedException(); + return predicatesWithGap; + } - @Override - public boolean preprocess() { - t.reset(); - Utility.logInfo("Preprocessing... checking satisfiability... "); + @Override + public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); + t.reset(); + Utility.logInfo("Preprocessing... checking satisfiability... "); - String name = "data", datafile = importedData.toString(); - rlLowerStore.importRDFData(name, datafile); - rlLowerStore.materialise("lower program", program.getLower().toString()); + String name = "data", datafile = importedData.toString(); + rlLowerStore.importRDFData(name, datafile); + rlLowerStore.materialise("lower program", program.getLower().toString()); // program.getLower().save(); - if(!consistency.checkRLLowerBound()) return false; - Utility.logInfo("The number of sameAs assertions in RL lower store: " + rlLowerStore.getSameAsNumber()); - - String originalMarkProgram = OWLHelper.getOriginalMarkProgram(ontology); - - elLowerStore.importRDFData(name, datafile); - elLowerStore.materialise("saturate named individuals", originalMarkProgram); - elLowerStore.materialise("lower program", program.getLower().toString()); - elLowerStore.initialiseKarma(); - if(!consistency.checkELLowerBound()) return false; - - if(lazyUpperStore != null) { - lazyUpperStore.importRDFData(name, datafile); - lazyUpperStore.materialise("saturate named individuals", originalMarkProgram); - int tag = lazyUpperStore.materialiseRestrictedly(program, null); - if(tag != 1) { - lazyUpperStore.dispose(); - lazyUpperStore = null; - } - if(tag == -1) return false; - } - if(consistency.checkUpper(lazyUpperStore)) { - satisfiable = SatisfiabilityStatus.SATISFIABLE; - Utility.logInfo("time for satisfiability checking: " + t.duration()); - } - -// if(limitedSkolemUpperStore != null) { -// limitedSkolemUpperStore.importRDFData(name, datafile); -// limitedSkolemUpperStore.materialise("saturate named individuals", originalMarkProgram); -// int tag = limitedSkolemUpperStore.materialiseSkolemly(program, null); -// if(tag != 1) { -// limitedSkolemUpperStore.dispose(); -// limitedSkolemUpperStore = null; -// } -// if(tag == -1) return false; -// } -// if(satisfiable == SatisfiabilityStatus.UNCHECKED && consistency.checkUpper(limitedSkolemUpperStore)) { -// satisfiable = SatisfiabilityStatus.SATISFIABLE; -// Utility.logInfo("time for satisfiability checking: " + t.duration()); -// } - - trackingStore.importRDFData(name, datafile); - trackingStore.materialise("saturate named individuals", originalMarkProgram); + if(!consistency.checkRLLowerBound()) return false; + Utility.logInfo("The number of sameAs assertions in RL lower store: " + rlLowerStore.getSameAsNumber()); + + String originalMarkProgram = OWLHelper.getOriginalMarkProgram(ontology); + + elLowerStore.importRDFData(name, datafile); + elLowerStore.materialise("saturate named individuals", originalMarkProgram); + elLowerStore.materialise("lower program", program.getLower().toString()); + elLowerStore.initialiseKarma(); + if(!consistency.checkELLowerBound()) return false; + + if(lazyUpperStore != null) { + lazyUpperStore.importRDFData(name, datafile); + lazyUpperStore.materialise("saturate named individuals", originalMarkProgram); + int tag = lazyUpperStore.materialiseRestrictedly(program, null); + if(tag != 1) { + lazyUpperStore.dispose(); + lazyUpperStore = null; + } + if(tag == -1) return false; + } + if(consistency.checkUpper(lazyUpperStore)) { + satisfiable = SatisfiabilityStatus.SATISFIABLE; + Utility.logInfo("time for satisfiability checking: " + t.duration()); + } + + if(limitedSkolemUpperStore != null) { + limitedSkolemUpperStore.importRDFData(name, datafile); + limitedSkolemUpperStore.materialise("saturate named individuals", originalMarkProgram); + int tag = limitedSkolemUpperStore.materialiseSkolemly(program, null); + if(tag != 1) { + limitedSkolemUpperStore.dispose(); + limitedSkolemUpperStore = null; + } + if(tag == -1) return false; + } + if(satisfiable == SatisfiabilityStatus.UNCHECKED && consistency.checkUpper(limitedSkolemUpperStore)) { + satisfiable = SatisfiabilityStatus.SATISFIABLE; + Utility.logInfo("time for satisfiability checking: " + t.duration()); + } + + trackingStore.importRDFData(name, datafile); + trackingStore.materialise("saturate named individuals", originalMarkProgram); // materialiseFullUpper(); -// GapByStore4ID gap = new GapByStore4ID(trackingStore); - GapByStore4ID gap = new GapByStore4ID2(trackingStore, rlLowerStore); - trackingStore.materialiseFoldedly(program, gap); - predicatesWithGap = gap.getPredicatesWithGap(); - gap.clear(); - - if(program.getGeneral().isHorn()) - encoder = new TrackingRuleEncoderWithGap(program.getUpper(), trackingStore); - else - encoder = new TrackingRuleEncoderDisjVar1(program.getUpper(), trackingStore); +// GapByStore4ID gap = new GapByStore4ID(trackingStore); + GapByStore4ID gap = new GapByStore4ID2(trackingStore, rlLowerStore); + trackingStore.materialiseFoldedly(program, gap); + predicatesWithGap = gap.getPredicatesWithGap(); + gap.clear(); + + if(program.getGeneral().isHorn()) + encoder = new TrackingRuleEncoderWithGap(program.getUpper(), trackingStore); + else + encoder = new TrackingRuleEncoderDisjVar1(program.getUpper(), trackingStore); // encoder = new TrackingRuleEncoderDisj1(program.getUpper(), trackingStore); // encoder = new TrackingRuleEncoderDisjVar2(program.getUpper(), trackingStore); // encoder = new TrackingRuleEncoderDisj2(program.getUpper(), trackingStore); - program.deleteABoxTurtleFile(); - - if(!isConsistent()) - return false; - - consistency.extractBottomFragment(); - consistency.dispose(); - - return true; - } - - @Override - public boolean isConsistent() { - if(satisfiable == SatisfiabilityStatus.UNCHECKED) { - satisfiable = consistency.check() ? SatisfiabilityStatus.SATISFIABLE : SatisfiabilityStatus.UNSATISFIABLE; - Utility.logInfo("time for satisfiability checking: " + t.duration()); - } - return satisfiable == SatisfiabilityStatus.SATISFIABLE; - } - - /** - * It deals with blanks nodes differently from variables - * according to SPARQL semantics for OWL2 Entailment Regime. - *

- * In particular variables are matched only against named individuals, - * and blank nodes against named and anonymous individuals. - */ - private boolean queryUpperStore(BasicQueryEngine upperStore, QueryRecord queryRecord, - Tuple extendedQuery, Step step) { - - if(queryRecord.hasNonAnsDistinguishedVariables()) - queryUpperBound(upperStore, queryRecord, extendedQuery.get(0), queryRecord.getAnswerVariables()); - else - queryUpperBound(upperStore, queryRecord, queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - - queryRecord.addProcessingTime(step, t.duration()); - if(queryRecord.isProcessed()) { - queryRecord.setDifficulty(step); - return true; - } - return false; - } - - /** - * Returns the part of the ontology relevant for Hermit, while computing the bound answers. - * */ - private boolean queryBounds(QueryRecord queryRecord) { - AnswerTuples rlAnswer = null, elAnswer = null; - - t.reset(); - try { - rlAnswer = rlLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - Utility.logDebug(t.duration()); - queryRecord.updateLowerBoundAnswers(rlAnswer); - } finally { - if (rlAnswer != null) rlAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.LOWER_BOUND, t.duration()); - - t.reset(); - - Tuple extendedQueryTexts = queryRecord.getExtendedQueryText(); - - Utility.logDebug("Tracking store"); - if(queryUpperStore(trackingStore, queryRecord, extendedQueryTexts, Step.SIMPLE_UPPER_BOUND)) - return true; - - if(!queryRecord.isBottom()) { - Utility.logDebug("Lazy store"); - if(lazyUpperStore != null && queryUpperStore(lazyUpperStore, queryRecord, extendedQueryTexts, Step.LAZY_UPPER_BOUND)) - return true; + if(!isConsistent()) + return false; + + consistency.extractBottomFragment(); + consistency.dispose(); + + program.dispose(); + + return true; + } + + @Override + public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); + if(satisfiable == SatisfiabilityStatus.UNCHECKED) { + satisfiable = consistency.check() ? SatisfiabilityStatus.SATISFIABLE : SatisfiabilityStatus.UNSATISFIABLE; + Utility.logInfo("time for satisfiability checking: " + t.duration()); + } + return satisfiable == SatisfiabilityStatus.SATISFIABLE; + } + + @Override + public void evaluate(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + if(queryBounds(queryRecord)) + return; + + OWLOntology relevantOntologySubset = extractRelevantOntologySubset(queryRecord); + + int aBoxCount = relevantOntologySubset.getABoxAxioms(true).size(); + Utility.logInfo("Relevant ontology subset: ABox_axioms=" + aBoxCount + " TBox_axioms=" + (relevantOntologySubset + .getAxiomCount() - aBoxCount)); +// queryRecord.saveRelevantOntology("fragment_query" + queryRecord.getQueryID() + ".owl"); + + if(querySkolemisedRelevantSubset(relevantOntologySubset, queryRecord)) + return; + + Timer t = new Timer(); + Checker summarisedChecker = new HermitSummaryFilter(queryRecord, properties.getToCallHermiT()); + summarisedChecker.check(queryRecord.getGapAnswers()); + summarisedChecker.dispose(); + Utility.logDebug("Total time for full reasoner: " + t.duration()); + queryRecord.markAsProcessed(); + Utility.logDebug("Difficulty of this query: " + queryRecord.getDifficulty()); + } + + @Override + public void evaluateUpper(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); + // TODO add new upper store + AnswerTuples rlAnswer = null; + boolean useFull = queryRecord.isBottom() || lazyUpperStore == null; + try { + rlAnswer = + (useFull ? trackingStore : lazyUpperStore).evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + queryRecord.updateUpperBoundAnswers(rlAnswer, true); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + } + + @Override + public void dispose() { + super.dispose(); + + if(encoder != null) encoder.dispose(); + if(rlLowerStore != null) rlLowerStore.dispose(); + if(lazyUpperStore != null) lazyUpperStore.dispose(); + if(elLowerStore != null) elLowerStore.dispose(); + if(trackingStore != null) trackingStore.dispose(); + if(limitedSkolemUpperStore != null) limitedSkolemUpperStore.dispose(); + + } + + private BasicQueryEngine getUpperStore(String name, boolean checkValidity) { + if(multiStageTag) + return new MultiStageQueryEngine(name, checkValidity); +// return new TwoStageQueryEngine(name, checkValidity); + else + return new BasicQueryEngine(name); + } + + protected void internal_importDataFile(String name, String datafile) { +// addDataFile(datafile); + rlLowerStore.importRDFData(name, datafile); + if(lazyUpperStore != null) + lazyUpperStore.importRDFData(name, datafile); + elLowerStore.importRDFData(name, datafile); + trackingStore.importRDFData(name, datafile); + } + + /** + * It deals with blanks nodes differently from variables + * according to SPARQL semantics for OWL2 Entailment Regime. + *

+ * In particular variables are matched only against named individuals, + * and blank nodes against named and anonymous individuals. + */ + private boolean queryUpperStore(BasicQueryEngine upperStore, QueryRecord queryRecord, + Tuple extendedQuery, Step step) { + + if(queryRecord.hasNonAnsDistinguishedVariables()) + queryUpperBound(upperStore, queryRecord, extendedQuery.get(0), queryRecord.getAnswerVariables()); + else + queryUpperBound(upperStore, queryRecord, queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + + queryRecord.addProcessingTime(step, t.duration()); + if(queryRecord.isProcessed()) { + queryRecord.setDifficulty(step); + return true; + } + return false; + } + + /** + * Returns the part of the ontology relevant for Hermit, while computing the bound answers. + */ + private boolean queryBounds(QueryRecord queryRecord) { + AnswerTuples rlAnswer = null, elAnswer = null; + + t.reset(); + try { + rlAnswer = rlLowerStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); + Utility.logDebug(t.duration()); + queryRecord.updateLowerBoundAnswers(rlAnswer); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.LOWER_BOUND, t.duration()); + + t.reset(); + + Tuple extendedQueryTexts = queryRecord.getExtendedQueryText(); + + Utility.logDebug("Tracking store"); + if(queryUpperStore(trackingStore, queryRecord, extendedQueryTexts, Step.SIMPLE_UPPER_BOUND)) + return true; + + if(!queryRecord.isBottom()) { + Utility.logDebug("Lazy store"); + if(lazyUpperStore != null && queryUpperStore(lazyUpperStore, queryRecord, extendedQueryTexts, Step.LAZY_UPPER_BOUND)) + return true; // Utility.logDebug("Skolem store"); // if(limitedSkolemUpperStore != null && queryUpperStore(limitedSkolemUpperStore, queryRecord, extendedQueryTexts, Step.L_SKOLEM_UPPER_BOUND)) // return null; - } - - t.reset(); - try { - elAnswer = elLowerStore.evaluate(extendedQueryTexts.get(0), - queryRecord.getAnswerVariables(), - queryRecord.getLowerBoundAnswers()); - Utility.logDebug(t.duration()); - queryRecord.updateLowerBoundAnswers(elAnswer); - } finally { - if (elAnswer != null) elAnswer.dispose(); - } - queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); - - if(queryRecord.isProcessed()) { - queryRecord.setDifficulty(Step.EL_LOWER_BOUND); - return true; - } - - return false; - } - - private OWLOntology extractRelevantOntologySubset(QueryRecord queryRecord) { - t.reset(); - - QueryTracker tracker = new QueryTracker(encoder, rlLowerStore, queryRecord); - OWLOntology relevantOntologySubset = tracker.extract(trackingStore, consistency.getQueryRecords(), true); - - queryRecord.addProcessingTime(Step.FRAGMENT, t.duration()); - - return relevantOntologySubset; - } - - private void queryUpperBound(BasicQueryEngine upperStore, QueryRecord queryRecord, String queryText, String[] answerVariables) { - AnswerTuples rlAnswer = null; - try { - Utility.logDebug(queryText); - rlAnswer = upperStore.evaluate(queryText, answerVariables); - Utility.logDebug(t.duration()); - queryRecord.updateUpperBoundAnswers(rlAnswer); - } finally { - if(rlAnswer != null) rlAnswer.dispose(); - } - } - - @Override - public void evaluate(QueryRecord queryRecord) { - if(queryBounds(queryRecord)) - return; - - OWLOntology relevantOntologySubset = extractRelevantOntologySubset(queryRecord); - - int aBoxCount = relevantOntologySubset.getABoxAxioms(true).size(); - Utility.logInfo("Relevant ontology subset: ABox_axioms=" + aBoxCount + " TBox_axioms=" + (relevantOntologySubset - .getAxiomCount() - aBoxCount)); -// queryRecord.saveRelevantOntology("fragment_query" + queryRecord.getQueryID() + ".owl"); - - if(querySkolemisedRelevantSubset(relevantOntologySubset, queryRecord)) - return; - - Timer t = new Timer(); - Checker summarisedChecker = new HermitSummaryFilter(queryRecord, properties.getToCallHermiT()); - summarisedChecker.check(queryRecord.getGapAnswers()); - summarisedChecker.dispose(); - Utility.logDebug("Total time for full reasoner: " + t.duration()); - queryRecord.markAsProcessed(); - Utility.logDebug("Difficulty of this query: " + queryRecord.getDifficulty()); - } - - private boolean querySkolemisedRelevantSubset(OWLOntology relevantSubset, QueryRecord queryRecord) { - MultiStageQueryEngine relevantStore = - new MultiStageQueryEngine("Relevant-store", true); // checkValidity is true - DatalogProgram relevantProgram = new DatalogProgram(relevantSubset, false); // toClassify is false - -// relevantStore.importRDFData("data", importedData.toString()); // 2 answers more - relevantStore.importDataFromABoxOf(relevantSubset); - - int materialisationResult = relevantStore.materialiseSkolemly(relevantProgram, null); - if(materialisationResult != 1) - throw new RuntimeException("Skolemised materialisation error"); // TODO check consistency + } + + t.reset(); + try { + elAnswer = elLowerStore.evaluate(extendedQueryTexts.get(0), + queryRecord.getAnswerVariables(), + queryRecord.getLowerBoundAnswers()); + Utility.logDebug(t.duration()); + queryRecord.updateLowerBoundAnswers(elAnswer); + } finally { + if(elAnswer != null) elAnswer.dispose(); + } + queryRecord.addProcessingTime(Step.EL_LOWER_BOUND, t.duration()); + + if(queryRecord.isProcessed()) { + queryRecord.setDifficulty(Step.EL_LOWER_BOUND); + return true; + } + + return false; + } + + private OWLOntology extractRelevantOntologySubset(QueryRecord queryRecord) { + t.reset(); + + QueryTracker tracker = new QueryTracker(encoder, rlLowerStore, queryRecord); + OWLOntology relevantOntologySubset = tracker.extract(trackingStore, consistency.getQueryRecords(), true); + + queryRecord.addProcessingTime(Step.FRAGMENT, t.duration()); + + return relevantOntologySubset; + } + + private void queryUpperBound(BasicQueryEngine upperStore, QueryRecord queryRecord, String queryText, String[] answerVariables) { + AnswerTuples rlAnswer = null; + try { + Utility.logDebug(queryText); + rlAnswer = upperStore.evaluate(queryText, answerVariables); + Utility.logDebug(t.duration()); + queryRecord.updateUpperBoundAnswers(rlAnswer); + } finally { + if(rlAnswer != null) rlAnswer.dispose(); + } + } + + private boolean querySkolemisedRelevantSubset(OWLOntology relevantSubset, QueryRecord queryRecord) { + DatalogProgram relevantProgram = new DatalogProgram(relevantSubset, false); // toClassify is false + + MultiStageQueryEngine relevantStore = + new MultiStageQueryEngine("Relevant-store", true); // checkValidity is true +// relevantStore.importRDFData("data", relevantProgram.getAdditionalDataFile()); // tried, doesn't work + relevantStore.importDataFromABoxOf(relevantSubset); + + int materialisationResult = relevantStore.materialiseSkolemly(relevantProgram, null); +// int materialisationResult = relevantStore.materialiseRestrictedly(relevantProgram, null); // DOESN'T WORK!!! + if(materialisationResult != 1) + throw new RuntimeException("Skolemised materialisation error"); // TODO check consistency // relevantStore.materialiseRestrictedly(relevantProgram, null); // it has been tried - return queryUpperStore(relevantStore, queryRecord, queryRecord.getExtendedQueryText(), Step.L_SKOLEM_UPPER_BOUND); - - // the following has been tried -// Tuple extendedQueryText = queryRecord.getExtendedQueryText(); -// if(queryRecord.hasNonAnsDistinguishedVariables()) { -// queryUpperBound(relevantStore, queryRecord, extendedQueryText.get(0), queryRecord.getAnswerVariables()); -// queryUpperBound(relevantStore, queryRecord, extendedQueryText.get(1), queryRecord.getDistinguishedVariables()); -// } -// else -// queryUpperBound(relevantStore, queryRecord, queryRecord.getQueryText(), queryRecord.getAnswerVariables()); -// -// return queryRecord.isProcessed(); - - } - - @Override - public void evaluateUpper(QueryRecord queryRecord) { - // TODO add new upper store - AnswerTuples rlAnswer = null; - boolean useFull = queryRecord.isBottom() || lazyUpperStore == null; - try { - rlAnswer = - (useFull ? trackingStore : lazyUpperStore).evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); - queryRecord.updateUpperBoundAnswers(rlAnswer, true); - } finally { - if(rlAnswer != null) rlAnswer.dispose(); - } - } - - @Override - public void dispose() { - if (encoder != null) encoder.dispose(); - if (rlLowerStore != null) rlLowerStore.dispose(); - if (lazyUpperStore != null) lazyUpperStore.dispose(); - if (elLowerStore != null) elLowerStore.dispose(); - if (trackingStore != null) trackingStore.dispose(); - -// if(limitedSkolemUpperStore != null) limitedSkolemUpperStore.dispose(); - super.dispose(); - } - - enum SatisfiabilityStatus {SATISFIABLE, UNSATISFIABLE, UNCHECKED} + return queryUpperStore(relevantStore, queryRecord, queryRecord.getExtendedQueryText(), Step.L_SKOLEM_UPPER_BOUND); + +// return queryUpperStore(limitedSkolemUpperStore, queryRecord, queryRecord.getExtendedQueryText(), Step.L_SKOLEM_UPPER_BOUND); + } + + enum SatisfiabilityStatus {SATISFIABLE, UNSATISFIABLE, UNCHECKED} } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/QueryEngine.java b/src/uk/ac/ox/cs/pagoda/reasoner/QueryEngine.java index b9abf07..3200216 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/QueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/QueryEngine.java @@ -1,17 +1,15 @@ package uk.ac.ox.cs.pagoda.reasoner; +import uk.ac.ox.cs.pagoda.query.AnswerTuples; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; + import java.util.Collection; -import uk.ac.ox.cs.pagoda.query.AnswerTuples; +public abstract class QueryEngine extends Disposable { + + public abstract void evaluate(Collection queryTexts, String answerFile); -public interface QueryEngine { + public abstract AnswerTuples evaluate(String queryText); - public void evaluate(Collection queryTexts, String answerFile); - - public AnswerTuples evaluate(String queryText); - - public AnswerTuples evaluate(String queryText, String[] answerVariables); - - public void dispose(); - + public abstract AnswerTuples evaluate(String queryText, String[] answerVariables); } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java index 118c1b2..962a78f 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/QueryReasoner.java @@ -9,6 +9,8 @@ import uk.ac.ox.cs.pagoda.query.QueryRecord; import uk.ac.ox.cs.pagoda.util.PagodaProperties; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.io.BufferedWriter; import java.io.File; @@ -18,230 +20,242 @@ import java.nio.file.Paths; import java.util.Collection; // TODO clean APIs -public abstract class QueryReasoner { - - public static final String ImportDataFileSeparator = ";"; - private static final boolean DEFAULT_MULTI_STAGES = true; - private static final boolean DEFAULT_EQUALITIES = true; - public boolean fullReasoner = this instanceof MyQueryReasoner; - protected StringBuilder importedData = new StringBuilder(); -// protected boolean forSemFacet = false; -PagodaProperties properties; - BufferedWriter answerWriter = null; - private QueryManager m_queryManager = new QueryManager(); - - public static QueryReasoner getInstance(PagodaProperties p) { - OWLOntology ontology = OWLHelper.loadOntology(p.getOntologyPath()); - QueryReasoner pagoda = getInstance(ontology, p); - pagoda.properties = p; - pagoda.loadOntology(ontology); - pagoda.importData(p.getDataPath()); - if (pagoda.preprocess()) { - Utility.logInfo("The ontology is consistent!"); - return pagoda; - } - else { - System.out.println("The ontology is inconsistent!"); - pagoda.dispose(); - return null; - } - } - - public static QueryReasoner getInstance(OWLOntology o) { - QueryReasoner pagoda = getInstance(Type.Full, o, DEFAULT_MULTI_STAGES, DEFAULT_EQUALITIES); - pagoda.properties = new PagodaProperties(); - return pagoda; - } - - private static QueryReasoner getInstance(OWLOntology o, PagodaProperties p) { - return getInstance(Type.Full, o, DEFAULT_MULTI_STAGES, DEFAULT_EQUALITIES); - } - - public static QueryReasoner getInstance(Type type, OWLOntology o, boolean performMultiStages, boolean considerEqualities) { +public abstract class QueryReasoner extends Disposable { + + public static final String ImportDataFileSeparator = ";"; + private static final boolean DEFAULT_MULTI_STAGES = true; + private static final boolean DEFAULT_EQUALITIES = true; + public boolean fullReasoner = this instanceof MyQueryReasoner; + protected StringBuilder importedData = new StringBuilder(); + // protected boolean forSemFacet = false; + PagodaProperties properties; + BufferedWriter answerWriter = null; + private QueryManager m_queryManager = new QueryManager(); + + public static QueryReasoner getInstance(PagodaProperties p) { + OWLOntology ontology = OWLHelper.loadOntology(p.getOntologyPath()); + QueryReasoner pagoda = getInstance(ontology, p); + pagoda.properties = p; + pagoda.loadOntology(ontology); + pagoda.importData(p.getDataPath()); + if(pagoda.preprocess()) { + Utility.logInfo("The ontology is consistent!"); + return pagoda; + } + else { + System.out.println("The ontology is inconsistent!"); + pagoda.dispose(); + return null; + } + } + + public static QueryReasoner getInstance(OWLOntology o) { + QueryReasoner pagoda = getInstance(Type.Full, o, DEFAULT_MULTI_STAGES, DEFAULT_EQUALITIES); + pagoda.properties = new PagodaProperties(); + return pagoda; + } + + private static QueryReasoner getInstance(OWLOntology o, PagodaProperties p) { + return getInstance(Type.Full, o, DEFAULT_MULTI_STAGES, DEFAULT_EQUALITIES); + } + + public static QueryReasoner getInstance(Type type, OWLOntology o, boolean performMultiStages, boolean considerEqualities) { // Utility.initialise(); - QueryReasoner reasoner; - if (OWLHelper.isInOWL2RL(o)) reasoner = new RLQueryReasoner(); - else if (OWLHelper.isInELHO(o)) reasoner = new ELHOQueryReasoner(); - else - switch (type) { - case RLU: - reasoner = new RLUQueryReasoner(performMultiStages, considerEqualities); - break; - case ELHOU: - reasoner = new ELHOUQueryReasoner(performMultiStages, considerEqualities); - break; - default: - reasoner = new MyQueryReasoner(performMultiStages, considerEqualities); - } - return reasoner; - } - - public static QueryReasoner getHermiTReasoner(boolean toCheckSatisfiability) { - return new HermiTReasoner(toCheckSatisfiability); - } - - public void setToClassify(boolean flag) { - properties.setToClassify(flag); - } - - public void setToCallHermiT(boolean flag) { - properties.setToCallHermiT(flag); - } - - public void importData(String datafile) { - if (datafile != null && !datafile.equalsIgnoreCase("null")) - importData(datafile.split(ImportDataFileSeparator)); - } - - public void importData(String[] datafiles) { - if (datafiles != null) { - for (String datafile: datafiles) { - File file = new File(datafile); - if (file.exists()) { - if (file.isFile()) importDataFile(file); - else importDataDirectory(file); - } - else { - Utility.logError("warning: file " + datafile + " doesn't exists."); - } - } - } - } - - private void importDataDirectory(File file) { - for (File child: file.listFiles()) - if (child.isFile()) importDataFile(child); - else importDataDirectory(child); - } - - private void importDataFile(File file) { - String datafile; - try { - datafile = file.getCanonicalPath(); - } catch (IOException e) { - e.printStackTrace(); - return; - } - importDataFile(datafile); - } - - protected final void importDataFile(String datafile) { - if (importedData.length() == 0) - importedData.append(datafile); - else - importedData.append(ImportDataFileSeparator).append(datafile); - - } - - public abstract void loadOntology(OWLOntology ontology); - - public abstract boolean preprocess(); - - public abstract boolean isConsistent(); - - public abstract void evaluate(QueryRecord record); - - public abstract void evaluateUpper(QueryRecord record); - - public AnswerTuples evaluate(String queryText, boolean forFacetGeneration) { - if (forFacetGeneration) { - QueryRecord record = m_queryManager.create(queryText); - Utility.logInfo("---------- start evaluating upper bound for Query " + record.getQueryID() + " ----------", queryText); - if(!record.isProcessed()) - evaluateUpper(record); + QueryReasoner reasoner; + if(OWLHelper.isInOWL2RL(o)) reasoner = new RLQueryReasoner(); + else if(OWLHelper.isInELHO(o)) reasoner = new ELHOQueryReasoner(); + else + switch(type) { + case RLU: + reasoner = new RLUQueryReasoner(performMultiStages, considerEqualities); + break; + case ELHOU: + reasoner = new ELHOUQueryReasoner(performMultiStages, considerEqualities); + break; + default: + reasoner = new MyQueryReasoner(performMultiStages, considerEqualities); + } + return reasoner; + } + + public static QueryReasoner getHermiTReasoner(boolean toCheckSatisfiability) { + return new HermiTReasoner(toCheckSatisfiability); + } + + public void setToClassify(boolean flag) { + if(isDisposed()) throw new DisposedException(); + properties.setToClassify(flag); + } + + public void setToCallHermiT(boolean flag) { + if(isDisposed()) throw new DisposedException(); + properties.setToCallHermiT(flag); + } + + public void importData(String datafile) { + if(isDisposed()) throw new DisposedException(); + if(datafile != null && !datafile.equalsIgnoreCase("null")) + importData(datafile.split(ImportDataFileSeparator)); + } + + public void importData(String[] datafiles) { + if(isDisposed()) throw new DisposedException(); + if(datafiles != null) { + for(String datafile : datafiles) { + File file = new File(datafile); + if(file.exists()) { + if(file.isFile()) importDataFile(file); + else importDataDirectory(file); + } + else { + Utility.logError("warning: file " + datafile + " doesn't exists."); + } + } + } + } + + public abstract void loadOntology(OWLOntology ontology); + + public abstract boolean preprocess(); + + public abstract boolean isConsistent(); + + public abstract void evaluate(QueryRecord record); + + public abstract void evaluateUpper(QueryRecord record); + + public AnswerTuples evaluate(String queryText, boolean forFacetGeneration) { + if(isDisposed()) throw new DisposedException(); + if(forFacetGeneration) { + QueryRecord record = m_queryManager.create(queryText); + Utility.logInfo("---------- start evaluating upper bound for Query " + record.getQueryID() + " ----------", queryText); + if(!record.isProcessed()) + evaluateUpper(record); // AnswerTuples tuples = record.getUpperBoundAnswers(); // for (AnswerTuple tuple; tuples.isValid(); tuples.moveNext()) { // tuple = tuples.getTuple(); // if (tuple.toString().contains("NC")) // System.out.println(tuple.toString()); // } - return record.getUpperBoundAnswers(); - } else - return evaluate(queryText); - } - -// public void evaluate(Collection queryRecords) { -// evaluate(queryRecords); -// } + return record.getUpperBoundAnswers(); + } + else + return evaluate(queryText); + } + + public AnswerTuples evaluate(String queryText) { + if(isDisposed()) throw new DisposedException(); + QueryRecord record = m_queryManager.create(queryText); + Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", queryText); + if(!record.isProcessed()) + evaluate(record); + AnswerTuples answer = record.getAnswers(); + record.dispose(); + return answer; + + } + + public void evaluate_shell(String queryText) { + if(isDisposed()) throw new DisposedException(); + QueryRecord record = m_queryManager.create(queryText); + Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", queryText); + if(!record.isProcessed()) + evaluate(record); + Utility.logInfo("Answers to this query: ", record.outputSoundAnswerTuple()); + record.dispose(); + + } - public AnswerTuples evaluate(String queryText) { - QueryRecord record = m_queryManager.create(queryText); - Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", queryText); - if(!record.isProcessed()) - evaluate(record); - AnswerTuples answer = record.getAnswers(); - record.dispose(); - return answer; - - } - - public void evaluate_shell(String queryText) { - QueryRecord record = m_queryManager.create(queryText); - Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", queryText); - if(!record.isProcessed()) - evaluate(record); - Utility.logInfo("Answers to this query: ", record.outputSoundAnswerTuple()); - record.dispose(); - - } - - public void evaluate(Collection queryRecords) { - if (!isConsistent()) { - Utility.logDebug("The ontology and dataset is inconsistent."); - return; - } - - if(properties.getAnswerPath() != null && answerWriter == null) { - try { - answerWriter = Files.newBufferedWriter(Paths.get(properties.getAnswerPath())); - } catch (IOException e) { - Utility.logError("The answer path is not valid!"); - e.printStackTrace(); - } - } - - Timer t = new Timer(); - Gson gson = QueryRecord.GsonCreator.getInstance(); - for (QueryRecord record: queryRecords) { + public void evaluate(Collection queryRecords) { + if(isDisposed()) throw new DisposedException(); + if(!isConsistent()) { + Utility.logDebug("The ontology and dataset is inconsistent."); + return; + } + + if(properties.getAnswerPath() != null && answerWriter == null) { + try { + answerWriter = Files.newBufferedWriter(Paths.get(properties.getAnswerPath())); + } catch(IOException e) { + Utility.logError("The answer path is not valid!"); + e.printStackTrace(); + } + } + + Timer t = new Timer(); + Gson gson = QueryRecord.GsonCreator.getInstance(); + for(QueryRecord record : queryRecords) { // if (Integer.parseInt(record.getQueryID()) != 218) continue; - Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", - record.getQueryText()); - if(!record.isProcessed()) { - t.reset(); - if(!record.isProcessed()) - evaluate(record); - Utility.logInfo("Total time to answer this query: " + t.duration()); - if(!fullReasoner && !record.isProcessed()) { - Utility.logInfo("The query has not been fully answered in " + t.duration() + " seconds."); - continue; - } - } - record.outputAnswerStatistics(); - record.outputTimes(); - } - /* TODO it can handle one call only + Utility.logInfo("---------- start evaluating Query " + record.getQueryID() + " ----------", + record.getQueryText()); + if(!record.isProcessed()) { + t.reset(); + if(!record.isProcessed()) + evaluate(record); + Utility.logInfo("Total time to answer this query: " + t.duration()); + if(!fullReasoner && !record.isProcessed()) { + Utility.logInfo("The query has not been fully answered in " + t.duration() + " seconds."); + continue; + } + } + record.outputAnswerStatistics(); + record.outputTimes(); + } + /* TODO it can handle one call only if you call twice, you will end up with a json file with multiple roots */ - if(answerWriter != null) gson.toJson(queryRecords, answerWriter); + if(answerWriter != null) gson.toJson(queryRecords, answerWriter); // queryRecords.stream().forEach(record -> Utility.logDebug(gson.toJson(record))); - queryRecords.stream().forEach(record -> record.dispose()); - } - - public void dispose() { - if (answerWriter != null) { - try { - answerWriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + queryRecords.stream().forEach(record -> record.dispose()); + } + +// public void evaluate(Collection queryRecords) { +// evaluate(queryRecords); +// } + + @Override + public void dispose() { + super.dispose(); + if(answerWriter != null) { + try { + answerWriter.close(); + } catch(IOException e) { + e.printStackTrace(); + } + } // Utility.cleanup(); - } - - public QueryManager getQueryManager() { - return m_queryManager; - } + } + + public QueryManager getQueryManager() { + if(isDisposed()) throw new DisposedException(); + return m_queryManager; + } + + private void importDataDirectory(File file) { + for(File child : file.listFiles()) + if(child.isFile()) importDataFile(child); + else importDataDirectory(child); + } + + private void importDataFile(File file) { + String datafile; + try { + datafile = file.getCanonicalPath(); + } catch(IOException e) { + e.printStackTrace(); + return; + } + importDataFile(datafile); + } + + protected final void importDataFile(String datafile) { + if(importedData.length() == 0) + importedData.append(datafile); + else + importedData.append(ImportDataFileSeparator).append(datafile); + + } - public enum Type {Full, RLU, ELHOU} + public enum Type {Full, RLU, ELHOU} } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/RLQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/RLQueryReasoner.java index bea5bbf..16e2627 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/RLQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/RLQueryReasoner.java @@ -9,6 +9,7 @@ import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxQueryEngine; import uk.ac.ox.cs.pagoda.rules.LowerDatalogProgram; import uk.ac.ox.cs.pagoda.util.Timer; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; class RLQueryReasoner extends QueryReasoner { @@ -16,13 +17,14 @@ class RLQueryReasoner extends QueryReasoner { LowerDatalogProgram program; Timer t = new Timer(); - + public RLQueryReasoner() { rlLowerStore = new BasicQueryEngine("rl"); } @Override public void evaluate(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); AnswerTuples rlAnswer = null; t.reset(); try { @@ -38,12 +40,13 @@ class RLQueryReasoner extends QueryReasoner { @Override public void dispose() { - if (rlLowerStore != null) rlLowerStore.dispose(); super.dispose(); + if(rlLowerStore != null) rlLowerStore.dispose(); } @Override public void loadOntology(OWLOntology ontology) { + if(isDisposed()) throw new DisposedException(); program = new LowerDatalogProgram(); program.load(ontology, new UnaryBottom()); program.transform(); @@ -53,6 +56,7 @@ class RLQueryReasoner extends QueryReasoner { @Override public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); rlLowerStore.importRDFData("data", importedData.toString()); rlLowerStore.materialise("lower program", program.toString()); @@ -61,6 +65,7 @@ class RLQueryReasoner extends QueryReasoner { @Override public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); AnswerTuples ans = null; try { ans = rlLowerStore.evaluate(QueryRecord.botQueryText, new String[] {"X"}); @@ -74,6 +79,7 @@ class RLQueryReasoner extends QueryReasoner { @Override public void evaluateUpper(QueryRecord record) { + if(isDisposed()) throw new DisposedException(); evaluate(record); } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/RLUQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/RLUQueryReasoner.java index 547140a..d0712e1 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/RLUQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/RLUQueryReasoner.java @@ -10,6 +10,7 @@ import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; import uk.ac.ox.cs.pagoda.rules.DatalogProgram; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; class RLUQueryReasoner extends QueryReasoner { @@ -19,7 +20,7 @@ class RLUQueryReasoner extends QueryReasoner { boolean multiStageTag, equalityTag; Timer t = new Timer(); - + public RLUQueryReasoner(boolean multiStageTag, boolean considerEqualities) { this.multiStageTag = multiStageTag; this.equalityTag = considerEqualities; @@ -32,6 +33,7 @@ class RLUQueryReasoner extends QueryReasoner { @Override public void evaluate(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); AnswerTuples ans = null; t.reset(); try { @@ -60,6 +62,7 @@ class RLUQueryReasoner extends QueryReasoner { @Override public void evaluateUpper(QueryRecord queryRecord) { + if(isDisposed()) throw new DisposedException(); AnswerTuples ans = null; try { ans = rlUpperStore.evaluate(queryRecord.getQueryText(), queryRecord.getAnswerVariables()); @@ -72,13 +75,14 @@ class RLUQueryReasoner extends QueryReasoner { @Override public void dispose() { + super.dispose(); if (rlLowerStore != null) rlLowerStore.dispose(); if (rlUpperStore != null) rlUpperStore.dispose(); - super.dispose(); } @Override public void loadOntology(OWLOntology o) { + if(isDisposed()) throw new DisposedException(); if (!equalityTag) { EqualitiesEliminator eliminator = new EqualitiesEliminator(o); o = eliminator.getOutputOntology(); @@ -92,6 +96,7 @@ class RLUQueryReasoner extends QueryReasoner { @Override public boolean preprocess() { + if(isDisposed()) throw new DisposedException(); String datafile = importedData.toString(); rlLowerStore.importRDFData("data", datafile); rlLowerStore.materialise("lower program", program.getLower().toString()); @@ -105,6 +110,7 @@ class RLUQueryReasoner extends QueryReasoner { @Override public boolean isConsistent() { + if(isDisposed()) throw new DisposedException(); String[] X = new String[] { "X" }; AnswerTuples ans = null; try { @@ -125,6 +131,5 @@ class RLUQueryReasoner extends QueryReasoner { Utility.logDebug("The consistency of the data has not been determined yet."); return true; } - - + } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/light/BasicQueryEngine.java b/src/uk/ac/ox/cs/pagoda/reasoner/light/BasicQueryEngine.java index 79be8aa..fe43e09 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/light/BasicQueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/light/BasicQueryEngine.java @@ -1,375 +1,377 @@ package uk.ac.ox.cs.pagoda.reasoner.light; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - import org.semanticweb.HermiT.model.DLClause; - +import uk.ac.ox.cs.JRDFox.JRDFStoreException; +import uk.ac.ox.cs.JRDFox.store.DataStore; +import uk.ac.ox.cs.JRDFox.store.DataStore.UpdateType; +import uk.ac.ox.cs.JRDFox.store.Parameters; +import uk.ac.ox.cs.JRDFox.store.TripleStatus; +import uk.ac.ox.cs.JRDFox.store.TupleIterator; import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; import uk.ac.ox.cs.pagoda.query.AnswerTuples; import uk.ac.ox.cs.pagoda.query.GapByStore4ID; import uk.ac.ox.cs.pagoda.rules.DatalogProgram; import uk.ac.ox.cs.pagoda.rules.Program; -import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; -import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.*; import uk.ac.ox.cs.pagoda.util.Timer; -import uk.ac.ox.cs.pagoda.util.UFS; -import uk.ac.ox.cs.pagoda.util.Utility; -import uk.ac.ox.cs.JRDFox.JRDFStoreException; -import uk.ac.ox.cs.JRDFox.store.DataStore; -import uk.ac.ox.cs.JRDFox.store.Parameters; -import uk.ac.ox.cs.JRDFox.store.TripleStatus; -import uk.ac.ox.cs.JRDFox.store.TupleIterator; -import uk.ac.ox.cs.JRDFox.store.DataStore.UpdateType; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; + +import java.util.*; public class BasicQueryEngine extends RDFoxQueryEngine { - protected DataStore store; - protected Parameters parameters = new Parameters(); - - public BasicQueryEngine(String name) { - super(name); - store = RDFoxQueryEngine.createDataStore(); - parameters.m_allAnswersInRoot = true; - parameters.m_useBushy = true; - } - - public void materialiseFoldedly(DatalogProgram dProgram, GapByStore4ID gap) { - if (gap != null) { - materialise("lower program", dProgram.getLower().toString()); - String program = dProgram.getUpper().toString(); - try { - gap.compile(program); - gap.addBackTo(); - getDataStore().clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - gap.clear(); - } - } - else - materialise("upper program", dProgram.getUpper().toString()); - } - - public int materialiseRestrictedly(DatalogProgram dProgram, GapByStore4ID gap) { - if (gap != null) { - materialise("lower program", dProgram.getLower().toString()); - String program = dProgram.getUpper().toString(); - try { - gap.compile(program); - gap.addBackTo(); - getDataStore().clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - gap.clear(); - } - } - else - materialise("upper program", dProgram.getUpper().toString()); - - return 1; - } - - @Override - public AnswerTuples evaluate(String queryText) { - return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0]); - } - - @Override - public AnswerTuples evaluate(String queryText, String[] answerVars) { - TupleIterator tupleIterator; - try { - tupleIterator = store.compileQuery(queryText.replace("_:", "?"), prefixes, parameters); - } catch (JRDFStoreException e) { - e.printStackTrace(); - return null; - } - return new RDFoxAnswerTuples(answerVars, tupleIterator); - } - - @Override - public DataStore getDataStore() { - return store; - } - - @Override - public void dispose() { - store.dispose(); - } - - protected void outputClassAssertions(String filename) { - TupleIterator allTuples = null; - boolean redirect = false; - try { - allTuples = getDataStore().compileQuery("SELECT ?X ?Z WHERE { ?X <" + Namespace.RDF_TYPE + "> ?Z }", prefixes, parameters); - redirect = Utility.redirectCurrentOut(filename); - for (long multi = allTuples.open(); multi != 0; multi = allTuples.getNext()) - System.out.println(RDFoxTripleManager.getQuotedTerm(allTuples.getResource(0)) + " " + RDFoxTripleManager.getQuotedTerm(allTuples.getResource(1))); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (redirect) Utility.closeCurrentOut(); - if (allTuples != null) allTuples.dispose(); - } - } - - public void outputInstance4BinaryPredicate(String iri, String filename) { - Utility.redirectCurrentOut(filename); - outputInstance4BinaryPredicate(iri); - Utility.closeCurrentOut(); - } - - public void outputInstance4BinaryPredicate(String iri) { - outputAnswers("select ?x ?y where { ?x <" + iri + "> ?y . }"); - } - - public void outputInstanceNumbers(String filename) { - TupleIterator predicateTuples = null; - TupleIterator instanceTuples; - Set number = new HashSet(); - String predicate; - try { - predicateTuples = getDataStore().compileQuery("SELECT DISTINCT ?Y WHERE { ?X <" + Namespace.RDF_TYPE + "> ?Y }", prefixes, parameters); - for (long multi = predicateTuples.open(); multi != 0; multi = predicateTuples.getNext()) { - predicate = RDFoxTripleManager.getQuotedTerm(predicateTuples.getResource(0)); - instanceTuples = null; - try { - instanceTuples = getDataStore().compileQuery("SELECT ?X WHERE { ?X <" + Namespace.RDF_TYPE + "> " + predicate + " }", prefixes, parameters); - long totalCount = 0; - for (long multi1 = instanceTuples.open(); multi1 != 0; multi1 = instanceTuples.getNext()) { - totalCount += instanceTuples.getMultiplicity(); - } - number.add(predicate + " * " + totalCount); - } finally { - if (instanceTuples != null) instanceTuples.dispose(); - } - } - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (predicateTuples != null) predicateTuples.dispose(); - predicateTuples = null; - } - - try { - predicateTuples = getDataStore().compileQuery("SELECT DISTINCT ?Y WHERE { ?X ?Y ?Z }", prefixes, parameters); - for (long multi = predicateTuples.open(); multi != 0; multi = predicateTuples.getNext()) { - predicate = RDFoxTripleManager.getQuotedTerm(predicateTuples.getResource(0)); - instanceTuples = null; - try { - instanceTuples = getDataStore().compileQuery("SELECT ?X ?Z WHERE { ?X " + predicate + " ?Z }", prefixes, parameters); - ; - long totalCount = 0; - for (long multi1 = instanceTuples.open(); multi1 != 0; multi1 = instanceTuples.getNext()) - totalCount += instanceTuples.getMultiplicity(); - number.add(predicate + " * " + totalCount); - } finally { - if (instanceTuples != null) instanceTuples.dispose(); - } - } - - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (predicateTuples != null) predicateTuples.dispose(); - predicateTuples = null; - } - - Utility.redirectCurrentOut(filename); - String[] ordered = number.toArray(new String[0]); - Arrays.sort(ordered, new DLPredicateComparator()); - for (String line: ordered) System.out.println(line); - Utility.closeCurrentOut(); - - } - - public TupleIterator internal_evaluateAgainstIDBs(String queryText) throws JRDFStoreException { - TupleIterator iter = store.compileQuery(queryText, prefixes, parameters, TripleStatus.TUPLE_STATUS_IDB.union(TripleStatus.TUPLE_STATUS_EDB), TripleStatus.TUPLE_STATUS_IDB); + protected DataStore store; + protected Parameters parameters = new Parameters(); + Set materialisedRules = new HashSet(); + private UFS equalityGroups = null; + + public BasicQueryEngine(String name) { + super(name); + store = RDFoxQueryEngine.createDataStore(); + parameters.m_allAnswersInRoot = true; + parameters.m_useBushy = true; + } + + public void materialiseFoldedly(DatalogProgram dProgram, GapByStore4ID gap) { + if(isDisposed()) throw new DisposedException(); + if(gap != null) { + materialise("lower program", dProgram.getLower().toString()); + String program = dProgram.getUpper().toString(); + try { + gap.compile(program); + gap.addBackTo(); + getDataStore().clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + gap.clear(); + } + } + else + materialise("upper program", dProgram.getUpper().toString()); + } + + public int materialiseRestrictedly(DatalogProgram dProgram, GapByStore4ID gap) { + if(isDisposed()) throw new DisposedException(); + if(gap != null) { + materialise("lower program", dProgram.getLower().toString()); + String program = dProgram.getUpper().toString(); + try { + gap.compile(program); + gap.addBackTo(); + getDataStore().clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + gap.clear(); + } + } + else + materialise("upper program", dProgram.getUpper().toString()); + + return 1; + } + + @Override + public AnswerTuples evaluate(String queryText) { + if(isDisposed()) throw new DisposedException(); + return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0]); + } + + @Override + public AnswerTuples evaluate(String queryText, String[] answerVars) { + if(isDisposed()) throw new DisposedException(); + TupleIterator tupleIterator; + try { + tupleIterator = store.compileQuery(queryText.replace("_:", "?"), prefixes, parameters); + } catch(JRDFStoreException e) { + e.printStackTrace(); + return null; + } + return new RDFoxAnswerTuples(answerVars, tupleIterator); + } + + @Override + public DataStore getDataStore() { + if(isDisposed()) throw new DisposedException(); + return store; + } + + @Override + public void dispose() { + super.dispose(); + store.dispose(); + } + + public void outputInstance4BinaryPredicate(String iri, String filename) { + Utility.redirectCurrentOut(filename); + outputInstance4BinaryPredicate(iri); + Utility.closeCurrentOut(); + } + + public void outputInstance4BinaryPredicate(String iri) { + outputAnswers("select ?x ?y where { ?x <" + iri + "> ?y . }"); + } + + public void outputInstanceNumbers(String filename) { + TupleIterator predicateTuples = null; + TupleIterator instanceTuples; + Set number = new HashSet(); + String predicate; + try { + predicateTuples = + getDataStore().compileQuery("SELECT DISTINCT ?Y WHERE { ?X <" + Namespace.RDF_TYPE + "> ?Y }", prefixes, parameters); + for(long multi = predicateTuples.open(); multi != 0; multi = predicateTuples.getNext()) { + predicate = RDFoxTripleManager.getQuotedTerm(predicateTuples.getResource(0)); + instanceTuples = null; + try { + instanceTuples = + getDataStore().compileQuery("SELECT ?X WHERE { ?X <" + Namespace.RDF_TYPE + "> " + predicate + " }", prefixes, parameters); + long totalCount = 0; + for(long multi1 = instanceTuples.open(); multi1 != 0; multi1 = instanceTuples.getNext()) { + totalCount += instanceTuples.getMultiplicity(); + } + number.add(predicate + " * " + totalCount); + } finally { + if(instanceTuples != null) instanceTuples.dispose(); + } + } + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(predicateTuples != null) predicateTuples.dispose(); + predicateTuples = null; + } + + try { + predicateTuples = + getDataStore().compileQuery("SELECT DISTINCT ?Y WHERE { ?X ?Y ?Z }", prefixes, parameters); + for(long multi = predicateTuples.open(); multi != 0; multi = predicateTuples.getNext()) { + predicate = RDFoxTripleManager.getQuotedTerm(predicateTuples.getResource(0)); + instanceTuples = null; + try { + instanceTuples = + getDataStore().compileQuery("SELECT ?X ?Z WHERE { ?X " + predicate + " ?Z }", prefixes, parameters); + long totalCount = 0; + for(long multi1 = instanceTuples.open(); multi1 != 0; multi1 = instanceTuples.getNext()) + totalCount += instanceTuples.getMultiplicity(); + number.add(predicate + " * " + totalCount); + } finally { + if(instanceTuples != null) instanceTuples.dispose(); + } + } + + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(predicateTuples != null) predicateTuples.dispose(); + predicateTuples = null; + } + + Utility.redirectCurrentOut(filename); + String[] ordered = number.toArray(new String[0]); + Arrays.sort(ordered, new DLPredicateComparator()); + for(String line : ordered) System.out.println(line); + Utility.closeCurrentOut(); + + } + + public TupleIterator internal_evaluateAgainstIDBs(String queryText) throws JRDFStoreException { + TupleIterator iter = + store.compileQuery(queryText, prefixes, parameters, TripleStatus.TUPLE_STATUS_IDB.union(TripleStatus.TUPLE_STATUS_EDB), TripleStatus.TUPLE_STATUS_IDB); +// iter.open(); + return iter; + } + + public TupleIterator internal_evaluate(String queryText) throws JRDFStoreException { + TupleIterator iter = store.compileQuery(queryText, prefixes, parameters); +// iter.open(); + return iter; + } + + public void setExpandEquality(boolean flag) { + parameters.m_expandEquality = flag; + } + + public TupleIterator internal_evaluateNotExpanded(String queryText) throws JRDFStoreException { + parameters.m_expandEquality = false; + TupleIterator iter = store.compileQuery(queryText, prefixes, parameters); // iter.open(); - return iter; - } - - public TupleIterator internal_evaluate(String queryText) throws JRDFStoreException { - TupleIterator iter = store.compileQuery(queryText, prefixes, parameters); -// iter.open(); - return iter; - } - - public void setExpandEquality(boolean flag) { - parameters.m_expandEquality = flag; - } - - public TupleIterator internal_evaluateNotExpanded(String queryText) throws JRDFStoreException { - parameters.m_expandEquality = false; - TupleIterator iter = store.compileQuery(queryText, prefixes, parameters); -// iter.open(); - parameters.m_expandEquality = true; - return iter; - } - - - public TupleIterator internal_evaluate(String queryText, boolean incrementally) throws JRDFStoreException { - return incrementally ? internal_evaluateAgainstIDBs(queryText) : internal_evaluate(queryText); - } - - Set materialisedRules = new HashSet(); - - public String getUnusedRules(Collection clauses, boolean toUpdate) { - DLClause clause; - for (Iterator iter = clauses.iterator(); iter.hasNext(); ) { - if (materialisedRules.contains(clause = iter.next())) - iter.remove(); - else if (toUpdate) materialisedRules.add(clause); - } - - if (clauses.isEmpty()) return null; - - return Program.toString(clauses); - } - - public void outputMaterialisedRules() { - System.out.println(DLClauseHelper.toString(materialisedRules)); - } - - public void outputAnswers(String query) { - TupleIterator iter = null; - try { - iter = internal_evaluate(query); - System.out.println(query); - int arity = iter.getArity(); - for (long multi = iter.open(); multi != 0; multi = iter.getNext()) { - for (int i = 0; i < arity; ++i) - System.out.print(RDFoxTripleManager.getQuotedTerm(iter.getResource(i)) + "\t"); - System.out.println(); - } - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (iter != null) iter.dispose(); - } - } - - public void outputInstance4UnaryPredicate(String iri) { - outputAnswers("select ?x where { ?x " - + " <" - + iri - + "> .}"); - } - - public void outputSubjects(String p, String o) { - outputAnswers("select x where { ?x <" + p + "> <" + o + "> . }"); - } - - public void outputObjects(String s, String p) { - outputAnswers("select ?x where { <" + s + "> <" + p + "> ?x . }"); - } - - public void outputIDBFacts() { - TupleIterator iter = null; - try { - iter = internal_evaluateAgainstIDBs("select distict ?x ?y ?z where { ?x ?y ?z }"); - for (long multi = iter.open(); multi != 0; multi = iter.getNext()) { - for (int i = 0; i < 3; ++i) - System.out.print(RDFoxTripleManager.getQuotedTerm(iter.getResource(i)) + "\t"); - System.out.println(); - } - } catch (JRDFStoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } finally { - if (iter != null) iter.dispose(); - } - - } - - public void outputType4Individual(String iri) { - outputAnswers("select ?z where { <" + iri + "> " + Namespace.RDF_TYPE_QUOTED + " ?z }"); - } - - public int getSameAsNumber() { - TupleIterator iter = null; - int counter = 0; - try { - iter = internal_evaluate("select ?x ?y where {?x " + Namespace.EQUALITY_QUOTED + " ?y . }"); - for (long multi = iter.open(); multi != 0; multi = iter.getNext()) - if (iter.getResourceID(0) != iter.getResourceID(1)) - ++counter; - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (iter != null) iter.dispose(); - } - return counter; - } - - private UFS equalityGroups = null; - - public UFS getEqualityGroups(boolean reuse) { - if (reuse && equalityGroups != null) return equalityGroups; - - equalityGroups = new UFS(); - - TupleIterator answers = null; - try { - Timer t = new Timer(); - answers = internal_evaluate("select ?x ?z where {?x " + Namespace.EQUALITY_QUOTED + "?z . }"); - for (long multi = answers.open(); multi != 0; multi = answers.getNext()) { - if (answers.getResourceID(0) != answers.getResourceID(1)) - equalityGroups.merge(answers.getResource(0).m_lexicalForm, answers.getResource(1).m_lexicalForm); - } - Utility.logInfo("@Time to group individuals by equality: " + t.duration()); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } finally { - if (answers != null) answers.dispose(); - } - - return equalityGroups; - } - - public void clearRulesAndIDBFacts(Collection collection) { -// performDeletion(collection); - collection.clear(); - try { - store.clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - } - - @SuppressWarnings("unused") - private void performDeletion(Collection collection) { - Utility.logInfo("Remove all rules, idb facts and added staff..."); - Timer timer = new Timer(); - TupleIterator iter = null; - try { - UpdateType ut = UpdateType.ScheduleForDeletion; - for (int[] t: collection) - store.addTriplesByResourceIDs(t, ut); - - try { - iter = internal_evaluateAgainstIDBs("select ?x ?y ?z where { ?x ?y ?z . }"); - for (long multi = iter.open(); multi != 0; multi = iter.getNext()) { - int[] triple = new int[3]; - for (int i = 0; i < 3; ++i) - triple[i] = iter.getResourceID(i); - store.addTriplesByResourceIDs(triple, ut); - } - } finally { - if (iter != null) iter.dispose(); - iter = null; - } - store.applyReasoning(true); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - Utility.logInfo("Time for deletion: " + timer.duration()); - } + parameters.m_expandEquality = true; + return iter; + } + + public TupleIterator internal_evaluate(String queryText, boolean incrementally) throws JRDFStoreException { + return incrementally ? internal_evaluateAgainstIDBs(queryText) : internal_evaluate(queryText); + } + + public String getUnusedRules(Collection clauses, boolean toUpdate) { + DLClause clause; + for(Iterator iter = clauses.iterator(); iter.hasNext(); ) { + if(materialisedRules.contains(clause = iter.next())) + iter.remove(); + else if(toUpdate) materialisedRules.add(clause); + } + + if(clauses.isEmpty()) return null; + + return Program.toString(clauses); + } + + public void outputMaterialisedRules() { + System.out.println(DLClauseHelper.toString(materialisedRules)); + } + + public void outputAnswers(String query) { + TupleIterator iter = null; + try { + iter = internal_evaluate(query); + System.out.println(query); + int arity = iter.getArity(); + for(long multi = iter.open(); multi != 0; multi = iter.getNext()) { + for(int i = 0; i < arity; ++i) + System.out.print(RDFoxTripleManager.getQuotedTerm(iter.getResource(i)) + "\t"); + System.out.println(); + } + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(iter != null) iter.dispose(); + } + } + + public void outputInstance4UnaryPredicate(String iri) { + outputAnswers("select ?x where { ?x " + + " <" + + iri + + "> .}"); + } + + public void outputSubjects(String p, String o) { + outputAnswers("select x where { ?x <" + p + "> <" + o + "> . }"); + } + + public void outputObjects(String s, String p) { + outputAnswers("select ?x where { <" + s + "> <" + p + "> ?x . }"); + } + + public void outputIDBFacts() { + TupleIterator iter = null; + try { + iter = internal_evaluateAgainstIDBs("select distict ?x ?y ?z where { ?x ?y ?z }"); + for(long multi = iter.open(); multi != 0; multi = iter.getNext()) { + for(int i = 0; i < 3; ++i) + System.out.print(RDFoxTripleManager.getQuotedTerm(iter.getResource(i)) + "\t"); + System.out.println(); + } + } catch(JRDFStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + if(iter != null) iter.dispose(); + } + + } + + public void outputType4Individual(String iri) { + outputAnswers("select ?z where { <" + iri + "> " + Namespace.RDF_TYPE_QUOTED + " ?z }"); + } + + public int getSameAsNumber() { + TupleIterator iter = null; + int counter = 0; + try { + iter = internal_evaluate("select ?x ?y where {?x " + Namespace.EQUALITY_QUOTED + " ?y . }"); + for(long multi = iter.open(); multi != 0; multi = iter.getNext()) + if(iter.getResourceID(0) != iter.getResourceID(1)) + ++counter; + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(iter != null) iter.dispose(); + } + return counter; + } + + public UFS getEqualityGroups(boolean reuse) { + if(reuse && equalityGroups != null) return equalityGroups; + + equalityGroups = new UFS(); + + TupleIterator answers = null; + try { + Timer t = new Timer(); + answers = internal_evaluate("select ?x ?z where {?x " + Namespace.EQUALITY_QUOTED + "?z . }"); + for(long multi = answers.open(); multi != 0; multi = answers.getNext()) { + if(answers.getResourceID(0) != answers.getResourceID(1)) + equalityGroups.merge(answers.getResource(0).m_lexicalForm, answers.getResource(1).m_lexicalForm); + } + Utility.logInfo("@Time to group individuals by equality: " + t.duration()); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(answers != null) answers.dispose(); + } + + return equalityGroups; + } + + public void clearRulesAndIDBFacts(Collection collection) { +// performDeletion(collection); + collection.clear(); + try { + store.clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + } + + protected void outputClassAssertions(String filename) { + TupleIterator allTuples = null; + boolean redirect = false; + try { + allTuples = + getDataStore().compileQuery("SELECT ?X ?Z WHERE { ?X <" + Namespace.RDF_TYPE + "> ?Z }", prefixes, parameters); + redirect = Utility.redirectCurrentOut(filename); + for(long multi = allTuples.open(); multi != 0; multi = allTuples.getNext()) + System.out.println(RDFoxTripleManager.getQuotedTerm(allTuples.getResource(0)) + " " + RDFoxTripleManager + .getQuotedTerm(allTuples.getResource(1))); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } finally { + if(redirect) Utility.closeCurrentOut(); + if(allTuples != null) allTuples.dispose(); + } + } + + @SuppressWarnings("unused") + private void performDeletion(Collection collection) { + Utility.logInfo("Remove all rules, idb facts and added staff..."); + Timer timer = new Timer(); + TupleIterator iter = null; + try { + UpdateType ut = UpdateType.ScheduleForDeletion; + for(int[] t : collection) + store.addTriplesByResourceIDs(t, ut); + + try { + iter = internal_evaluateAgainstIDBs("select ?x ?y ?z where { ?x ?y ?z . }"); + for(long multi = iter.open(); multi != 0; multi = iter.getNext()) { + int[] triple = new int[3]; + for(int i = 0; i < 3; ++i) + triple[i] = iter.getResourceID(i); + store.addTriplesByResourceIDs(triple, ut); + } + } finally { + if(iter != null) iter.dispose(); + iter = null; + } + store.applyReasoning(true); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + Utility.logInfo("Time for deletion: " + timer.duration()); + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/light/KarmaQueryEngine.java b/src/uk/ac/ox/cs/pagoda/reasoner/light/KarmaQueryEngine.java index f068164..98f0c35 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/light/KarmaQueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/light/KarmaQueryEngine.java @@ -12,6 +12,7 @@ import uk.ac.ox.cs.pagoda.query.AnswerTuples; import uk.ac.ox.cs.pagoda.query.AnswerTuplesImp; import uk.ac.ox.cs.pagoda.util.ConjunctiveQueryHelper; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.io.File; import java.io.FileNotFoundException; @@ -19,82 +20,90 @@ import java.nio.file.Paths; import java.util.Set; public class KarmaQueryEngine extends RDFoxQueryEngine { - - private MyKarma reasoner = null; - - String karmaDataFile = null, karmaRuleFile = null; - - public KarmaQueryEngine(String name) { - super(name); - + + String karmaDataFile = null, karmaRuleFile = null; + private MyKarma reasoner = null; + + public KarmaQueryEngine(String name) { + super(name); + // int Base = 1 << 6; // int index = (new Random().nextInt() % Base + Base) % Base; // karmaDataFile = "karma_data" + index + ".ttl"; // karmaRuleFile = "karma_rule" + index + ".dlog"; - karmaDataFile = Paths.get(Utility.getGlobalTempDirAbsolutePath(), "karma_data.ttl").toString(); - karmaRuleFile = Paths.get(Utility.getGlobalTempDirAbsolutePath(), "karma_rule.dlog").toString(); - - reasoner = new MyKarma(); - } - - public MyKarma getReasoner() { - return reasoner; - } - - public void processOntology(OWLOntology elhoOntology) { - try { - OntologyProcesser.transformOntology(elhoOntology, new File(karmaDataFile), new File(karmaRuleFile)); - } catch (IllegalInputOntologyException e) { - e.printStackTrace(); - } - } - - @Override - public void dispose() { - reasoner.dispose(); - } - - @Override - public AnswerTuples evaluate(String queryText) { - return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0], null); - } - - @Override - public AnswerTuples evaluate(String queryText, String[] answerVars) { - return evaluate(queryText, answerVars, null); - } - - public AnswerTuples evaluate(String queryText, AnswerTuples soundAnswerTuples) { - return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0], soundAnswerTuples); - } - - public AnswerTuples evaluate(String queryText, String[] answerVars, AnswerTuples soundAnswerTuples) { - KarmaQuery karmaQuery = new KarmaQuery(queryText.replace("_:", "?")); - reasoner.setConcurrence(false); - ConjunctiveQuery cq = karmaQuery.getConjunctiveQuery(); - if (cq == null) return null; - Set answers = reasoner.answerCQ(cq, soundAnswerTuples, !queryText.contains("_:")); - return new AnswerTuplesImp(answerVars, answers); - } - - @Override - public DataStore getDataStore() { - return reasoner.getStore(); - } - - public void initialiseKarma() { - try { - reasoner.initializeData(new File(karmaDataFile)); - reasoner.materialise(new File(karmaRuleFile)); - - File tmp; - if (karmaDataFile != null && ((tmp = new File(karmaDataFile)).exists())) tmp.delete(); - if (karmaRuleFile != null && ((tmp = new File(karmaRuleFile)).exists())) tmp.delete(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - } + karmaDataFile = Paths.get(Utility.getGlobalTempDirAbsolutePath(), "karma_data.ttl").toString(); + karmaRuleFile = Paths.get(Utility.getGlobalTempDirAbsolutePath(), "karma_rule.dlog").toString(); + + reasoner = new MyKarma(); + } + + public MyKarma getReasoner() { + if(isDisposed()) throw new DisposedException(); + return reasoner; + } + + public void processOntology(OWLOntology elhoOntology) { + if(isDisposed()) throw new DisposedException(); + try { + OntologyProcesser.transformOntology(elhoOntology, new File(karmaDataFile), new File(karmaRuleFile)); + } catch(IllegalInputOntologyException e) { + e.printStackTrace(); + } + } + + @Override + public void dispose() { + super.dispose(); + reasoner.dispose(); + } + + @Override + public AnswerTuples evaluate(String queryText) { + if(isDisposed()) throw new DisposedException(); + return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0], null); + } + + @Override + public AnswerTuples evaluate(String queryText, String[] answerVars) { + if(isDisposed()) throw new DisposedException(); + return evaluate(queryText, answerVars, null); + } + + public AnswerTuples evaluate(String queryText, AnswerTuples soundAnswerTuples) { + if(isDisposed()) throw new DisposedException(); + return evaluate(queryText, ConjunctiveQueryHelper.getAnswerVariables(queryText)[0], soundAnswerTuples); + } + + public AnswerTuples evaluate(String queryText, String[] answerVars, AnswerTuples soundAnswerTuples) { + if(isDisposed()) throw new DisposedException(); + KarmaQuery karmaQuery = new KarmaQuery(queryText.replace("_:", "?")); + reasoner.setConcurrence(false); + ConjunctiveQuery cq = karmaQuery.getConjunctiveQuery(); + if(cq == null) return null; + Set answers = reasoner.answerCQ(cq, soundAnswerTuples, !queryText.contains("_:")); + return new AnswerTuplesImp(answerVars, answers); + } + + @Override + public DataStore getDataStore() { + if(isDisposed()) throw new DisposedException(); + return reasoner.getStore(); + } + + public void initialiseKarma() { + if(isDisposed()) throw new DisposedException(); + try { + reasoner.initializeData(new File(karmaDataFile)); + reasoner.materialise(new File(karmaRuleFile)); + + File tmp; + if(karmaDataFile != null && ((tmp = new File(karmaDataFile)).exists())) tmp.delete(); + if(karmaRuleFile != null && ((tmp = new File(karmaRuleFile)).exists())) tmp.delete(); + } catch(FileNotFoundException e) { + e.printStackTrace(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxAnswerTuples.java b/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxAnswerTuples.java index dd71809..1e8181f 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxAnswerTuples.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxAnswerTuples.java @@ -3,15 +3,14 @@ package uk.ac.ox.cs.pagoda.reasoner.light; import org.semanticweb.HermiT.model.Constant; import org.semanticweb.HermiT.model.Individual; import org.semanticweb.HermiT.model.Term; - -import uk.ac.ox.cs.pagoda.query.AnswerTuple; -import uk.ac.ox.cs.pagoda.query.AnswerTuples; -import uk.ac.ox.cs.pagoda.util.Utility; import uk.ac.ox.cs.JRDFox.JRDFStoreException; import uk.ac.ox.cs.JRDFox.model.GroundTerm; import uk.ac.ox.cs.JRDFox.store.TupleIterator; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.AnswerTuples; +import uk.ac.ox.cs.pagoda.util.Utility; -public class RDFoxAnswerTuples implements AnswerTuples { +public class RDFoxAnswerTuples extends AnswerTuples { long multi; TupleIterator m_iter; @@ -22,7 +21,18 @@ public class RDFoxAnswerTuples implements AnswerTuples { m_iter = iter; reset(); } - + + public static Term getHermitTerm(GroundTerm t) { + if(t instanceof uk.ac.ox.cs.JRDFox.model.Individual) { + uk.ac.ox.cs.JRDFox.model.Individual individual = (uk.ac.ox.cs.JRDFox.model.Individual) t; + return Individual.create(individual.getIRI()); + } + else { + uk.ac.ox.cs.JRDFox.model.Literal literal = ((uk.ac.ox.cs.JRDFox.model.Literal) t); + return Constant.create(literal.getLexicalForm(), literal.getDatatype().getIRI()); + } + } + @Override public boolean isValid() { return multi != 0; @@ -34,7 +44,7 @@ public class RDFoxAnswerTuples implements AnswerTuples { return m_iter.getArity(); } catch (JRDFStoreException e) { e.printStackTrace(); - return -1; + return -1; } } @@ -44,15 +54,12 @@ public class RDFoxAnswerTuples implements AnswerTuples { multi = m_iter.getNext(); } catch (JRDFStoreException e) { e.printStackTrace(); - } + } } @Override public void dispose() { - m_iter.dispose(); - } - - protected void finalize() { + super.dispose(); m_iter.dispose(); } @@ -85,16 +92,9 @@ public class RDFoxAnswerTuples implements AnswerTuples { public String[] getAnswerVariables() { return m_answerVars; } - - public static Term getHermitTerm(GroundTerm t) { - if (t instanceof uk.ac.ox.cs.JRDFox.model.Individual) { - uk.ac.ox.cs.JRDFox.model.Individual individual = (uk.ac.ox.cs.JRDFox.model.Individual) t; - return Individual.create(individual.getIRI()); - } - else { - uk.ac.ox.cs.JRDFox.model.Literal literal = ((uk.ac.ox.cs.JRDFox.model.Literal) t); - return Constant.create(literal.getLexicalForm(), literal.getDatatype().getIRI()); - } + + protected void finalize() { + m_iter.dispose(); } } diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxQueryEngine.java b/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxQueryEngine.java index 61500f5..f835ba9 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxQueryEngine.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/light/RDFoxQueryEngine.java @@ -13,119 +13,126 @@ import uk.ac.ox.cs.pagoda.reasoner.QueryReasoner; import uk.ac.ox.cs.pagoda.tracking.AnswerTuplesWriter; import uk.ac.ox.cs.pagoda.util.Timer; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; import java.io.File; import java.util.Collection; -public abstract class RDFoxQueryEngine implements QueryEngine { - - public static final int matNoOfThreads = Runtime.getRuntime().availableProcessors() * 2; - protected String name; - protected Prefixes prefixes = MyPrefixes.PAGOdAPrefixes.getRDFoxPrefixes(); +public abstract class RDFoxQueryEngine extends QueryEngine { - public RDFoxQueryEngine(String name) { - this.name = name; - } + public static final int matNoOfThreads = Runtime.getRuntime().availableProcessors() * 2; + protected String name; + protected Prefixes prefixes = MyPrefixes.PAGOdAPrefixes.getRDFoxPrefixes(); - public static DataStore createDataStore() { - DataStore instance = null; - try { + public RDFoxQueryEngine(String name) { + this.name = name; + } + + public static DataStore createDataStore() { + DataStore instance = null; + try { // instance = new DataStore("par-head-n"); - instance = new DataStore(StoreType.NarrowParallelHead); - instance.setNumberOfThreads(matNoOfThreads); - instance.initialize(); - } catch(JRDFStoreException e) { - e.printStackTrace(); - } - return instance; - } - - public String getName() { - return name; - } - - public abstract DataStore getDataStore(); - - public abstract void dispose(); - - public void importRDFData(String fileName, String importedFile) { - if(importedFile == null || importedFile.isEmpty()) return; - Timer t = new Timer(); - DataStore store = getDataStore(); - try { - long oldTripleCount = store.getTriplesCount(), tripleCount; - for (String file: importedFile.split(QueryReasoner.ImportDataFileSeparator)) { - store.importTurtleFile(new File(file), prefixes); - } - tripleCount = store.getTriplesCount(); - Utility.logDebug(name + " store after importing " + fileName + ": " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); - store.clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - Utility.logDebug(name + " store finished importing " + fileName + " in " + t.duration() + " seconds."); - } - - public void importDataFromABoxOf(OWLOntology ontology) { - DataStore store = getDataStore(); - try { - long prevTriplesCount = store.getTriplesCount(); - store.importOntology(ontology.getOWLOntologyManager().createOntology(ontology.getABoxAxioms(true))); - long loadedTriples = store.getTriplesCount() - prevTriplesCount; - Utility.logInfo(name + ": loaded " + loadedTriples + " triples from " + ontology.getABoxAxioms(true) - .size() + " ABox axioms"); - } catch(JRDFStoreException | OWLOntologyCreationException e) { - e.printStackTrace(); - System.exit(1); - } - - } - - public void materialise(String programName, String programText) { - if(programText == null) return; - Timer t = new Timer(); - DataStore store = getDataStore(); - try { - long oldTripleCount = store.getTriplesCount(), tripleCount; + instance = new DataStore(StoreType.NarrowParallelHead); + instance.setNumberOfThreads(matNoOfThreads); + instance.initialize(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + return instance; + } + + public String getName() { + if(isDisposed()) throw new DisposedException(); + return name; + } + + public abstract DataStore getDataStore(); + + public void importRDFData(String fileName, String importedFile) { + if(isDisposed()) throw new DisposedException(); + if(importedFile == null || importedFile.isEmpty()) return; + Timer t = new Timer(); + DataStore store = getDataStore(); + try { + long oldTripleCount = store.getTriplesCount(), tripleCount; + for(String file : importedFile.split(QueryReasoner.ImportDataFileSeparator)) { + store.importTurtleFile(new File(file), prefixes); + } + tripleCount = store.getTriplesCount(); + Utility.logDebug(name + " store after importing " + fileName + ": " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); + store.clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + Utility.logDebug(name + " store finished importing " + fileName + " in " + t.duration() + " seconds."); + } + + public void importDataFromABoxOf(OWLOntology ontology) { + if(isDisposed()) throw new DisposedException(); + DataStore store = getDataStore(); + try { + long prevTriplesCount = store.getTriplesCount(); + store.importOntology(ontology.getOWLOntologyManager().createOntology(ontology.getABoxAxioms(true))); + long loadedTriples = store.getTriplesCount() - prevTriplesCount; + Utility.logInfo(name + ": loaded " + loadedTriples + " triples from " + ontology.getABoxAxioms(true) + .size() + " ABox axioms"); + } catch(JRDFStoreException | OWLOntologyCreationException e) { + e.printStackTrace(); + System.exit(1); + } + + } + + public void materialise(String programName, String programText) { + if(isDisposed()) throw new DisposedException(); + if(programText == null) return; + Timer t = new Timer(); + DataStore store = getDataStore(); + try { + long oldTripleCount = store.getTriplesCount(), tripleCount; // store.addRules(new String[] {programText}); - store.importRules(programText); - store.applyReasoning(); - tripleCount = store.getTriplesCount(); - Utility.logDebug(name + " store after materialising " + programName + ": " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); - store.clearRulesAndMakeFactsExplicit(); - } catch (JRDFStoreException e) { - e.printStackTrace(); - } - Utility.logDebug(name + " store finished the materialisation of " + programName + " in " + t.duration() + " seconds."); - } - - @Override - public void evaluate(Collection queryTexts, String answerFile) { - if (queryTexts == null) - return ; - - int queryID = 0; - AnswerTuplesWriter answerWriter = new AnswerTuplesWriter(answerFile); - AnswerTuples answerTuples; - Timer t = new Timer(); - try { - for (String query: queryTexts) { - t.reset(); - answerTuples = null; - try { - answerTuples = evaluate(query); - Utility.logDebug("time to answer Query " + ++queryID + ": " + t.duration()); - answerWriter.write(answerTuples.getAnswerVariables(), answerTuples); - } finally { - if (answerTuples != null) answerTuples.dispose(); - } - } - } finally { - answerWriter.close(); - } - - Utility.logDebug("done computing query answers by RDFox."); - - } + store.importRules(programText); + store.applyReasoning(); + tripleCount = store.getTriplesCount(); + Utility.logDebug(name + " store after materialising " + programName + ": " + tripleCount + " (" + (tripleCount - oldTripleCount) + " new)"); + store.clearRulesAndMakeFactsExplicit(); + } catch(JRDFStoreException e) { + e.printStackTrace(); + } + Utility.logDebug(name + " store finished the materialisation of " + programName + " in " + t.duration() + " seconds."); + } + + @Override + public void evaluate(Collection queryTexts, String answerFile) { + if(isDisposed()) throw new DisposedException(); + if(queryTexts == null) + return; + + int queryID = 0; + AnswerTuplesWriter answerWriter = new AnswerTuplesWriter(answerFile); + AnswerTuples answerTuples; + Timer t = new Timer(); + try { + for(String query : queryTexts) { + t.reset(); + answerTuples = null; + try { + answerTuples = evaluate(query); + Utility.logDebug("time to answer Query " + ++queryID + ": " + t.duration()); + answerWriter.write(answerTuples.getAnswerVariables(), answerTuples); + } finally { + if(answerTuples != null) answerTuples.dispose(); + } + } + } finally { + answerWriter.close(); + } + + Utility.logDebug("done computing query answers by RDFox."); + } + @Override + public void dispose() { + super.dispose(); + } } diff --git a/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java b/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java index 1f7148c..29e74c2 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java +++ b/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java @@ -1,64 +1,74 @@ package uk.ac.ox.cs.pagoda.rules; import org.semanticweb.owlapi.model.OWLOntology; +import uk.ac.ox.cs.pagoda.constraints.BottomStrategy; +import uk.ac.ox.cs.pagoda.constraints.PredicateDependency; +import uk.ac.ox.cs.pagoda.constraints.UpperUnaryBottom; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; -import uk.ac.ox.cs.pagoda.constraints.*; +public class DatalogProgram extends Disposable { -public class DatalogProgram { + UpperDatalogProgram upperProgram = new UpperDatalogProgram(); + LowerDatalogProgram lowerProgram; + GeneralProgram program = new GeneralProgram(); - UpperDatalogProgram upperProgram = new UpperDatalogProgram(); - LowerDatalogProgram lowerProgram; - GeneralProgram program = new GeneralProgram(); - - BottomStrategy upperBottom; - - public DatalogProgram(OWLOntology o) { - lowerProgram = new LowerDatalogProgram(); - init(o, false); - } - - public DatalogProgram(OWLOntology o, boolean toClassify) { - lowerProgram = new LowerDatalogProgram(toClassify); - init(o, toClassify); - } + BottomStrategy upperBottom; - private void init(OWLOntology o, boolean forSemFacet) { - upperProgram.load(o, upperBottom = new UpperUnaryBottom()); -// upperProgram.load(o, upperBottom = new UnaryBottom()); - lowerProgram.clone(upperProgram); - program.clone(upperProgram); -// program.botStrategy = new UnaryBottom(); - - upperProgram.transform(); - lowerProgram.transform(); - program.transform(); - - program.buildDependencyGraph(); - PredicateDependency graph = upperProgram.buildDependencyGraph(); - lowerProgram.dependencyGraph = graph; - } + public DatalogProgram(OWLOntology o) { + lowerProgram = new LowerDatalogProgram(); + init(o, false); + } + + public DatalogProgram(OWLOntology o, boolean toClassify) { + lowerProgram = new LowerDatalogProgram(toClassify); + init(o, toClassify); + } + + public LowerDatalogProgram getLower() { + if(isDisposed()) throw new DisposedException(); + return lowerProgram; + } + + public UpperDatalogProgram getUpper() { + if(isDisposed()) throw new DisposedException(); + return upperProgram; + } + + public GeneralProgram getGeneral() { + if(isDisposed()) throw new DisposedException(); + return program; + } - public LowerDatalogProgram getLower() { - return lowerProgram; - } - - public UpperDatalogProgram getUpper() { - return upperProgram; - } - - public GeneralProgram getGeneral() { - return program; - } - - public String getAdditionalDataFile() { - return upperProgram.getAdditionalDataFile(); - } + public String getAdditionalDataFile() { + if(isDisposed()) throw new DisposedException(); + return upperProgram.getAdditionalDataFile(); + } + + public BottomStrategy getUpperBottomStrategy() { + if(isDisposed()) throw new DisposedException(); + return upperBottom; + } + + @Override + public void dispose() { + super.dispose(); + if(upperProgram != null) upperProgram.deleteABoxTurtleFile(); + } + + private void init(OWLOntology o, boolean forSemFacet) { + upperProgram.load(o, upperBottom = new UpperUnaryBottom()); +// upperProgram.load(o, upperBottom = new UnaryBottom()); + lowerProgram.clone(upperProgram); + program.clone(upperProgram); +// program.botStrategy = new UnaryBottom(); - public BottomStrategy getUpperBottomStrategy() { - return upperBottom; - } + upperProgram.transform(); + lowerProgram.transform(); + program.transform(); - public void deleteABoxTurtleFile() { - if (upperProgram != null) upperProgram.deleteABoxTurtleFile(); - } + program.buildDependencyGraph(); + PredicateDependency graph = upperProgram.buildDependencyGraph(); + lowerProgram.dependencyGraph = graph; + } } diff --git a/src/uk/ac/ox/cs/pagoda/rules/Program.java b/src/uk/ac/ox/cs/pagoda/rules/Program.java index 2e5302b..4e147bb 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/Program.java +++ b/src/uk/ac/ox/cs/pagoda/rules/Program.java @@ -1,5 +1,6 @@ package uk.ac.ox.cs.pagoda.rules; +import org.apache.commons.io.FilenameUtils; import org.semanticweb.HermiT.Configuration; import org.semanticweb.HermiT.model.*; import org.semanticweb.HermiT.structural.OWLClausification; @@ -24,78 +25,180 @@ public abstract class Program implements KnowledgeBase { protected OWLOntology ontology; protected DLOntology dlOntology; protected BottomStrategy botStrategy; - - private String additionalDataFile = null; - protected Collection clauses = new HashSet(); // protected Set used = new HashSet(); - protected PredicateDependency dependencyGraph; - - /** - * clone all information of another program after load() - * - * @param program - */ - void clone(Program program) { - this.ontologyDirectory = program.ontologyDirectory; - this.ontology = program.ontology; - this.dlOntology = program.dlOntology; - this.botStrategy = program.botStrategy; - this.additionalDataFile = program.additionalDataFile; - this.transitiveAxioms = program.transitiveAxioms; - this.transitiveClauses = program.transitiveClauses; - this.subPropChainAxioms = program.subPropChainAxioms; - this.subPropChainClauses = program.subPropChainClauses; +protected PredicateDependency dependencyGraph; + protected LinkedList transitiveAxioms; + protected LinkedList transitiveClauses; + protected LinkedList subPropChainAxioms; + protected LinkedList subPropChainClauses; + private String additionalDataFile = null; + + public static String toString(Collection clauses) { + StringBuilder sb = new StringBuilder(DLClauseHelper.toString(clauses)); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); } - + public void load(OWLOntology o, BottomStrategy botStrategy) { - this.botStrategy = botStrategy; - RLPlusOntology owlOntology = new RLPlusOntology(); + this.botStrategy = botStrategy; + RLPlusOntology owlOntology = new RLPlusOntology(); owlOntology.load(o, new NullaryBottom()); owlOntology.simplify(); - ontology = owlOntology.getTBox(); - String ontologyPath = OWLHelper.getOntologyPath(ontology); - ontologyDirectory = ontologyPath.substring(0, ontologyPath.lastIndexOf(Utility.JAVA_FILE_SEPARATOR)); - clausify(); - + ontology = owlOntology.getTBox(); +// String ontologyPath = OWLHelper.getOntologyPath(ontology); +// ontologyDirectory = ontologyPath.substring(0, ontologyPath.lastIndexOf(Utility.JAVA_FILE_SEPARATOR)); + String ontologyPath = ontology.getOWLOntologyManager().getOntologyDocumentIRI(ontology).toURI().getPath(); + ontologyDirectory = FilenameUtils.getFullPath(ontologyPath); + clausify(); + String aboxOWLFile = owlOntology.getABoxPath(); OWLOntology abox = OWLHelper.loadOntology(aboxOWLFile); - OWLOntologyManager manager = abox.getOWLOntologyManager(); - OWLAxiom axiom; + OWLOntologyManager manager = abox.getOWLOntologyManager(); + OWLAxiom axiom; for (Atom atom: dlOntology.getPositiveFacts()) { if ((axiom = OWLHelper.getABoxAssertion(manager.getOWLDataFactory(), atom)) != null) - manager.addAxiom(abox, axiom); + manager.addAxiom(abox, axiom); } - + try { - FileOutputStream out = new FileOutputStream(aboxOWLFile); + FileOutputStream out = new FileOutputStream(aboxOWLFile); manager.saveOntology(abox, out); out.close(); - } catch (OWLOntologyStorageException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block + } catch(IOException | OWLOntologyStorageException e) { e.printStackTrace(); + System.exit(1); } - + if (!abox.isEmpty()) { SimpleETL rewriter = new SimpleETL(owlOntology.getOntologyIRI(), aboxOWLFile); try { rewriter.rewrite(); } catch (Exception e) { e.printStackTrace(); - } - additionalDataFile = rewriter.getExportedFile(); + } + additionalDataFile = rewriter.getExportedFile(); new File(aboxOWLFile).delete(); } - + + } + + public String getAdditionalDataFile() { + return additionalDataFile; + } + + @Override + public void transform() { + for(DLClause dlClause : dlOntology.getDLClauses()) { + DLClause simplifiedDLClause = DLClauseHelper.removeNominalConcept(dlClause); + simplifiedDLClause = removeAuxiliaryBodyAtoms(simplifiedDLClause); + simplifiedDLClause = DLClauseHelper.replaceWithDataValue(simplifiedDLClause); + convert(simplifiedDLClause); + } + + addingTransitiveAxioms(); + addingSubPropertyChainAxioms(); + + Collection botRelated = new LinkedList(); + Variable X = Variable.create("X"); + botRelated.add(DLClause.create(new Atom[0], new Atom[]{Atom.create(Inequality.INSTANCE, X, X)})); + clauses.addAll(botStrategy.process(botRelated)); + + if(this instanceof GeneralProgram) + Utility.logInfo("The number of rules: " + (clauses.size() - 1)); } + @Override + public void save() { + try { + BufferedWriter ruleWriter = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(getOutputPath()))); + ruleWriter.write(toString()); + ruleWriter.close(); + } catch(IOException e) { + e.printStackTrace(); + } + Utility.logDebug("The rules are saved in " + getOutputPath() + "."); + } + + @Override + public String toString() { + return toString(clauses); + } + + public final void convert(DLClause clause) { + Collection tempClauses = convert2Clauses(clause); + clauses.addAll(tempClauses); + } + + public abstract Collection convert2Clauses(DLClause clause); + + public abstract String getOutputPath(); + + public OWLOntology getOntology() { + return ontology; + } + + public Collection getClauses() { + return clauses; + } + + public Collection getClauses(DLClause queryClause) { +// if (true) return new HashSet(clauses); + Set predicates = new HashSet(); + predicates.addAll(dependencyGraph.collectPredicate(queryClause.getBodyAtoms())); + + Set dependence = new HashSet(); + for(DLPredicate predicate : predicates) + dependence.addAll(dependencyGraph.getAncesters(predicate)); + + Collection relevantClauses = new LinkedList(); + for(DLClause clause : clauses) { + if(relevant(clause, dependence)) + relevantClauses.add(clause); + + } + return relevantClauses; + } + + public PredicateDependency buildDependencyGraph() { + if(dependencyGraph == null) + return dependencyGraph = new PredicateDependency(clauses); + else + return dependencyGraph; + } + + public void getDependencyGraph(PredicateDependency g) { + dependencyGraph = g; + } + + public final String getDirectory() { + return Utility.getGlobalTempDirAbsolutePath(); + } + + public void deleteABoxTurtleFile() { + if(additionalDataFile != null) + new File(additionalDataFile).delete(); + } + + /** + * clone all information of another program after load() + * + * @param program + */ + void clone(Program program) { + this.ontologyDirectory = program.ontologyDirectory; + this.ontology = program.ontology; + this.dlOntology = program.dlOntology; + this.botStrategy = program.botStrategy; + this.additionalDataFile = program.additionalDataFile; + this.transitiveAxioms = program.transitiveAxioms; + this.transitiveClauses = program.transitiveClauses; + this.subPropChainAxioms = program.subPropChainAxioms; + this.subPropChainClauses = program.subPropChainClauses; + } + private void clausify() { Configuration conf = new Configuration(); OWLClausification clausifier = new OWLClausification(conf); @@ -103,121 +206,94 @@ public abstract class Program implements KnowledgeBase { OWLOntologyManager manager = ontology.getOWLOntologyManager(); try { filteredOntology = manager.createOntology(); - } catch (OWLOntologyCreationException e) { + } catch(OWLOntologyCreationException e) { e.printStackTrace(); } - + transitiveAxioms = new LinkedList(); subPropChainAxioms = new LinkedList(); - - OWLDatatype date = ontology.getOWLOntologyManager().getOWLDataFactory().getOWLDatatype(IRI.create("http://www.w3.org/2001/XMLSchema#date")); - int noOfDataPropertyRangeAxioms = 0, noOfAxioms = 0; - for (OWLOntology onto: ontology.getImportsClosure()) - for (OWLAxiom axiom: onto.getAxioms()) { - if (axiom instanceof OWLTransitiveObjectPropertyAxiom) + + OWLDatatype date = ontology.getOWLOntologyManager() + .getOWLDataFactory() + .getOWLDatatype(IRI.create("http://www.w3.org/2001/XMLSchema#date")); + int noOfDataPropertyRangeAxioms = 0, noOfAxioms = 0; + for(OWLOntology onto : ontology.getImportsClosure()) + for(OWLAxiom axiom : onto.getAxioms()) { + if(axiom instanceof OWLTransitiveObjectPropertyAxiom) transitiveAxioms.add((OWLTransitiveObjectPropertyAxiom) axiom); - else if (axiom instanceof OWLSubPropertyChainOfAxiom) + else if(axiom instanceof OWLSubPropertyChainOfAxiom) subPropChainAxioms.add((OWLSubPropertyChainOfAxiom) axiom); - // TODO to filter out datatype axioms - else if (axiom instanceof OWLDataPropertyRangeAxiom) { - ++noOfDataPropertyRangeAxioms; + // TODO to filter out datatype axioms + else if(axiom instanceof OWLDataPropertyRangeAxiom) { + ++noOfDataPropertyRangeAxioms; Utility.logInfo("The axiom: " + axiom + " is being ignored."); } else { - if (axiom.getDatatypesInSignature().contains(date)) { + if(axiom.getDatatypesInSignature().contains(date)) { Utility.logInfo("The axiom: " + axiom + " is being ignored."); } else manager.addAxiom(filteredOntology, axiom); } - - if (axiom instanceof OWLAnnotationAssertionAxiom || + + if(axiom instanceof OWLAnnotationAssertionAxiom || axiom instanceof OWLSubAnnotationPropertyOfAxiom || axiom instanceof OWLDeclarationAxiom || axiom instanceof OWLDataPropertyRangeAxiom) { } else { -// System.out.println(axiom); +// System.out.println(axiom); ++noOfAxioms; } - + } Utility.logInfo("The number of data property range axioms that are ignored: " + noOfDataPropertyRangeAxioms + "(" + noOfAxioms + ")"); - - dlOntology = (DLOntology)clausifier.preprocessAndClausify(filteredOntology, null)[1]; + + dlOntology = (DLOntology) clausifier.preprocessAndClausify(filteredOntology, null)[1]; clausifier = null; } - - public String getAdditionalDataFile() { - return additionalDataFile; - } - - protected LinkedList transitiveAxioms; - protected LinkedList transitiveClauses; - - protected LinkedList subPropChainAxioms; - protected LinkedList subPropChainClauses; - - @Override - public void transform() { - for (DLClause dlClause: dlOntology.getDLClauses()) { - DLClause simplifiedDLClause = DLClauseHelper.removeNominalConcept(dlClause); - simplifiedDLClause = removeAuxiliaryBodyAtoms(simplifiedDLClause); - simplifiedDLClause = DLClauseHelper.replaceWithDataValue(simplifiedDLClause); - convert(simplifiedDLClause); - } - addingTransitiveAxioms(); - addingSubPropertyChainAxioms(); - - Collection botRelated = new LinkedList(); - Variable X = Variable.create("X"); - botRelated.add(DLClause.create(new Atom[0], new Atom[] {Atom.create(Inequality.INSTANCE, X, X)})); - clauses.addAll(botStrategy.process(botRelated)); - - if (this instanceof GeneralProgram) - Utility.logInfo("The number of rules: " + (clauses.size() - 1)); - } - private DLClause removeAuxiliaryBodyAtoms(DLClause dlClause) { Collection newBodyAtoms = new LinkedList(); - DLPredicate p; - for (Atom bodyAtom: dlClause.getBodyAtoms()) { - p = bodyAtom.getDLPredicate(); - if (p instanceof AtomicConcept || + DLPredicate p; + for(Atom bodyAtom : dlClause.getBodyAtoms()) { + p = bodyAtom.getDLPredicate(); + if(p instanceof AtomicConcept || p instanceof AtomicRole || p instanceof InverseRole || p instanceof Equality || p instanceof AnnotatedEquality || p instanceof Inequality) - newBodyAtoms.add(bodyAtom); + newBodyAtoms.add(bodyAtom); } LinkedList newHeadAtoms = new LinkedList(); - Map assign = new HashMap(); - for (Atom headAtom: dlClause.getHeadAtoms()) { - p = headAtom.getDLPredicate(); - if (p instanceof AtomicNegationDataRange) { - AtomicDataRange positive = ((AtomicNegationDataRange) p).getNegatedDataRange(); - if (!(positive instanceof ConstantEnumeration)) + Map assign = new HashMap(); + for(Atom headAtom : dlClause.getHeadAtoms()) { + p = headAtom.getDLPredicate(); + if(p instanceof AtomicNegationDataRange) { + AtomicDataRange positive = ((AtomicNegationDataRange) p).getNegatedDataRange(); + if(!(positive instanceof ConstantEnumeration)) newBodyAtoms.add(Atom.create(positive, headAtom.getArgument(0))); - else if (((ConstantEnumeration) positive).getNumberOfConstants() == 1) { - assign.put((Variable) headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0)); -// newBodyAtoms.add(Atom.create(Equality.INSTANCE, headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0))); + else if(((ConstantEnumeration) positive).getNumberOfConstants() == 1) { + assign.put((Variable) headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0)); +// newBodyAtoms.add(Atom.create(Equality.INSTANCE, headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0))); } - else newHeadAtoms.add(headAtom); + else newHeadAtoms.add(headAtom); } - else - newHeadAtoms.add(headAtom); + else + newHeadAtoms.add(headAtom); } - - if (assign.isEmpty() && newHeadAtoms.isEmpty() && newBodyAtoms.size() == dlClause.getBodyLength()) - return dlClause; - - Atom[] headArray = newHeadAtoms.size() == dlClause.getHeadLength() ? dlClause.getHeadAtoms() : newHeadAtoms.toArray(new Atom[0]); - Atom[] bodyArray = newBodyAtoms.size() == dlClause.getBodyLength() ? dlClause.getBodyAtoms() : newBodyAtoms.toArray(new Atom[0]); - if (!assign.isEmpty()) { - for (int i = 0; i < headArray.length; ++i) - headArray[i] = DLClauseHelper.getInstance(headArray[i], assign); - for (int i = 0; i < bodyArray.length; ++i) - bodyArray[i] = DLClauseHelper.getInstance(bodyArray[i], assign); + + if(assign.isEmpty() && newHeadAtoms.isEmpty() && newBodyAtoms.size() == dlClause.getBodyLength()) + return dlClause; + + Atom[] headArray = + newHeadAtoms.size() == dlClause.getHeadLength() ? dlClause.getHeadAtoms() : newHeadAtoms.toArray(new Atom[0]); + Atom[] bodyArray = + newBodyAtoms.size() == dlClause.getBodyLength() ? dlClause.getBodyAtoms() : newBodyAtoms.toArray(new Atom[0]); + if(!assign.isEmpty()) { + for(int i = 0; i < headArray.length; ++i) + headArray[i] = DLClauseHelper.getInstance(headArray[i], assign); + for(int i = 0; i < bodyArray.length; ++i) + bodyArray[i] = DLClauseHelper.getInstance(bodyArray[i], assign); } - return DLClause.create(headArray, bodyArray); + return DLClause.create(headArray, bodyArray); } private void addingTransitiveAxioms() { @@ -225,136 +301,58 @@ public abstract class Program implements KnowledgeBase { Atom headAtom; Variable X = Variable.create("X"), Y = Variable.create("Y"), Z = Variable.create("Z"); transitiveClauses = new LinkedList(); - for (OWLTransitiveObjectPropertyAxiom axiom: transitiveAxioms) { - OWLObjectPropertyExpression objExp = axiom.getProperty(); + for(OWLTransitiveObjectPropertyAxiom axiom : transitiveAxioms) { + OWLObjectPropertyExpression objExp = axiom.getProperty(); headAtom = getAtom(objExp, X, Z); Atom[] bodyAtoms = new Atom[2]; - bodyAtoms[0] = getAtom(objExp, X, Y); - bodyAtoms[1] = getAtom(objExp, Y, Z); - transitiveClause = DLClause.create(new Atom[] {headAtom}, bodyAtoms); + bodyAtoms[0] = getAtom(objExp, X, Y); + bodyAtoms[1] = getAtom(objExp, Y, Z); + transitiveClause = DLClause.create(new Atom[]{headAtom}, bodyAtoms); clauses.add(transitiveClause); transitiveClauses.add(transitiveClause); } } - + private Atom getAtom(OWLObjectPropertyExpression exp, Variable x, Variable y) { - if (exp instanceof OWLObjectProperty) + if(exp instanceof OWLObjectProperty) return Atom.create(AtomicRole.create(((OWLObjectProperty) exp).toStringID()), x, y); - OWLObjectInverseOf inverseOf; - if (exp instanceof OWLObjectInverseOf && (inverseOf = (OWLObjectInverseOf) exp).getInverse() instanceof OWLObjectProperty) + OWLObjectInverseOf inverseOf; + if(exp instanceof OWLObjectInverseOf && (inverseOf = + (OWLObjectInverseOf) exp).getInverse() instanceof OWLObjectProperty) return Atom.create(AtomicRole.create(((OWLObjectProperty) inverseOf).toStringID()), x, y); return null; } private void addingSubPropertyChainAxioms() { - DLClause dlClause; + DLClause dlClause; subPropChainClauses = new LinkedList(); Atom headAtom; - Iterator iterExp; - OWLObjectPropertyExpression objExp; - for (OWLSubPropertyChainOfAxiom axiom: subPropChainAxioms) { + Iterator iterExp; + OWLObjectPropertyExpression objExp; + for(OWLSubPropertyChainOfAxiom axiom : subPropChainAxioms) { objExp = axiom.getSuperProperty(); List objs = axiom.getPropertyChain(); headAtom = getAtom(objExp, Variable.create("X"), Variable.create("X" + objs.size())); iterExp = objs.iterator(); - int index = 1; - Atom[] bodyAtoms = new Atom[objs.size()]; - bodyAtoms[0] = getAtom(iterExp.next(), Variable.create("X"), Variable.create("X1")); - while (index < objs.size()) { - bodyAtoms[index] = getAtom(iterExp.next(), Variable.create("X" + index), Variable.create("X" + (index + 1))); - ++index; + int index = 1; + Atom[] bodyAtoms = new Atom[objs.size()]; + bodyAtoms[0] = getAtom(iterExp.next(), Variable.create("X"), Variable.create("X1")); + while(index < objs.size()) { + bodyAtoms[index] = + getAtom(iterExp.next(), Variable.create("X" + index), Variable.create("X" + (index + 1))); + ++index; } - dlClause = DLClause.create(new Atom[] {headAtom}, bodyAtoms); - clauses.add(dlClause); - subPropChainClauses.add(dlClause); + dlClause = DLClause.create(new Atom[]{headAtom}, bodyAtoms); + clauses.add(dlClause); + subPropChainClauses.add(dlClause); } } - @Override - public void save() { - try { - BufferedWriter ruleWriter = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(getOutputPath()))); - ruleWriter.write(toString()); - ruleWriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - Utility.logDebug("The rules are saved in " + getOutputPath() + "."); - } - - @Override - public String toString() { - return toString(clauses); - } - - public static String toString(Collection clauses) { - StringBuilder sb = new StringBuilder(DLClauseHelper.toString(clauses)); - sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); - return sb.toString(); - } - - public final void convert(DLClause clause) { - Collection tempClauses = convert2Clauses(clause); - clauses.addAll(tempClauses); - } - - public abstract Collection convert2Clauses(DLClause clause); - - public abstract String getOutputPath(); - - - public OWLOntology getOntology() { - return ontology; - } - - public Collection getClauses() { - return clauses; - } - - public Collection getClauses(DLClause queryClause) { -// if (true) return new HashSet(clauses); - Set predicates = new HashSet(); - predicates.addAll(dependencyGraph.collectPredicate(queryClause.getBodyAtoms())); - - Set dependence = new HashSet(); - for (DLPredicate predicate: predicates) - dependence.addAll(dependencyGraph.getAncesters(predicate)); - - Collection relevantClauses = new LinkedList(); - for (DLClause clause: clauses) { - if (relevant(clause, dependence)) - relevantClauses.add(clause); - - } - return relevantClauses; - } - private boolean relevant(DLClause clause, Set set) { - for (DLPredicate p: dependencyGraph.collectPredicate(clause.getHeadAtoms())) - if (set.contains(p)) + for(DLPredicate p : dependencyGraph.collectPredicate(clause.getHeadAtoms())) + if(set.contains(p)) return true; - return false; - } - - public PredicateDependency buildDependencyGraph() { - if (dependencyGraph == null) - return dependencyGraph = new PredicateDependency(clauses); - else - return dependencyGraph; - } - - public void getDependencyGraph(PredicateDependency g) { - dependencyGraph = g; - } - - public final String getDirectory() { - return Utility.getGlobalTempDirAbsolutePath(); - } - - public void deleteABoxTurtleFile() { - if (additionalDataFile != null) - new File(additionalDataFile).delete(); + return false; } } diff --git a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java index f3cc937..d8ebc55 100644 --- a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java +++ b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoder.java @@ -1,387 +1,387 @@ package uk.ac.ox.cs.pagoda.tracking; -import java.io.BufferedWriter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; - -import org.semanticweb.HermiT.model.AnnotatedEquality; -import org.semanticweb.HermiT.model.Atom; -import org.semanticweb.HermiT.model.AtomicConcept; -import org.semanticweb.HermiT.model.AtomicRole; -import org.semanticweb.HermiT.model.Constant; -import org.semanticweb.HermiT.model.DLClause; -import org.semanticweb.HermiT.model.DLPredicate; -import org.semanticweb.HermiT.model.DatatypeRestriction; -import org.semanticweb.HermiT.model.Equality; -import org.semanticweb.HermiT.model.Individual; -import org.semanticweb.HermiT.model.Inequality; -import org.semanticweb.HermiT.model.Variable; +import org.semanticweb.HermiT.model.*; import org.semanticweb.owlapi.model.OWLOntology; - import uk.ac.ox.cs.JRDFox.model.Datatype; import uk.ac.ox.cs.JRDFox.model.GroundTerm; import uk.ac.ox.cs.JRDFox.model.Literal; import uk.ac.ox.cs.pagoda.MyPrefixes; import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; -import uk.ac.ox.cs.pagoda.query.*; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.AnswerTuples; +import uk.ac.ox.cs.pagoda.query.GapTupleIterator; +import uk.ac.ox.cs.pagoda.query.QueryRecord; import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager; import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; import uk.ac.ox.cs.pagoda.util.Namespace; import uk.ac.ox.cs.pagoda.util.Utility; +import uk.ac.ox.cs.pagoda.util.disposable.Disposable; +import uk.ac.ox.cs.pagoda.util.disposable.DisposedException; + +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.*; + +public abstract class TrackingRuleEncoder extends Disposable { + public static final String trackingPredicateRelation = Namespace.PAGODA_AUX + "isTrackingPredicateFor"; + public static final String QueryPredicate = Namespace.PAGODA_AUX + "Query"; + protected BasicQueryEngine store; + protected QueryRecord currentQuery; + protected Set unaryPredicates = new HashSet(); + protected Set binaryPredicates = new HashSet(); + UpperDatalogProgram program; + Collection trackingClauses = new HashSet(); + Collection queryClauses = new LinkedList(); + Map index2clause = new HashMap(); + Map clause2index = new HashMap(); + String equalityRelatedRuleText = null; + boolean ruleEncoded = false; + DLPredicate selected; + private boolean queryEncoded = false; + private LinkedList addedData = new LinkedList(); + private String trackingSuffix; + + public TrackingRuleEncoder(UpperDatalogProgram program, BasicQueryEngine store) { + this.program = program; + this.store = store; + } + + public static String getRawTerm(GroundTerm r) { + if(r instanceof uk.ac.ox.cs.JRDFox.model.Individual) + return ((uk.ac.ox.cs.JRDFox.model.Individual) r).getIRI(); + else { + Literal l = (Literal) r; + if(l.getDatatype().equals(Datatype.XSD_STRING) && l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) + return "\"" + l.getLexicalForm() + "\""; + else + return "\"" + l.getLexicalForm() + "\"^^<" + l.getDatatype().getIRI() + ">"; + } + } + + protected static String getTrackingSuffix(String queryID) { + return "_AUXt" + queryID; + } + + public boolean encodingRules() { + if(isDisposed()) throw new DisposedException(); + if(ruleEncoded) return false; + ruleEncoded = true; -public abstract class TrackingRuleEncoder { - UpperDatalogProgram program; - Collection trackingClauses = new HashSet(); - Collection queryClauses = new LinkedList(); - - Map index2clause = new HashMap(); - Map clause2index = new HashMap(); - - String equalityRelatedRuleText = null; - protected BasicQueryEngine store; - - public TrackingRuleEncoder(UpperDatalogProgram program, BasicQueryEngine store) { - this.program = program; - this.store = store; - } - - protected abstract String getEqualityRelatedRuleText(); - - boolean ruleEncoded = false; - - public boolean encodingRules() { - if (ruleEncoded) return false; - ruleEncoded = true; - // for (DLClause clause: program.getClauses(currentQuery.getClause())) { - for (DLClause clause: program.getClauses()) { - encodingRule(clause); - } - return true; - } - - protected String getIRI(String name) { - return program.getOntology().getOntologyID().getOntologyIRI().toString() + "#" + name; - } - - protected abstract void encodingRule(DLClause clause); - - protected Individual getIndividual4GeneralRule(DLClause clause) { - clause = program.getCorrespondingClause(clause); + for(DLClause clause : program.getClauses()) { + encodingRule(clause); + } + return true; + } + + public Collection getAddedData() { + if(isDisposed()) throw new DisposedException(); + return addedData; + } + + public String getTrackingPredicate(String predicateIRI) { + if(isDisposed()) throw new DisposedException(); + if(predicateIRI.startsWith("<")) + return predicateIRI.replace(">", getTrackingSuffix(currentQuery.getQueryID()) + ">"); + else + return predicateIRI + getTrackingSuffix(currentQuery.getQueryID()); + } + + public void setCurrentQuery(QueryRecord record) { + if(isDisposed()) throw new DisposedException(); + deprecateTrackingAndQueryRules(); + currentQuery = record; + selected = AtomicConcept.create(getSelectedPredicate()); + trackingSuffix = "_AUXt" + currentQuery.getQueryID(); + } + + @Override + public void dispose() { + super.dispose(); + deprecateTrackingAndQueryRules(); + } + + public String getTrackingProgram() { + if(isDisposed()) throw new DisposedException(); + StringBuilder sb = getTrackingProgramBody(); + sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); + return sb.toString(); + } + + public void saveTrackingRules(String fileName) { + if(isDisposed()) throw new DisposedException(); + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))); + writer.write(getTrackingProgram()); + writer.close(); + } catch(IOException e) { + e.printStackTrace(); + return; + } + Utility.logDebug("The tracking rules are saved in " + fileName + "."); + } + + public String getSelectedPredicate() { + if(isDisposed()) throw new DisposedException(); + return getIRI("_selected" + currentQuery.getQueryID()); + } + + public DLClause getSelectedClause(String iri) { + if(isDisposed()) throw new DisposedException(); + int index = iri.lastIndexOf("_r") + 2; + int ruleIndex = Integer.parseInt(iri.substring(index)); + return index2clause.get(ruleIndex); + } + + /** + * SELECT ?X + * WHERE { + * ?X :_selected? + * } + */ + public String getSelectedSPARQLQuery() { + if(isDisposed()) throw new DisposedException(); + StringBuilder builder = new StringBuilder(); + builder.append("SELECT ?X\nWHERE {\n?X "); + builder.append(selected.toString()).append("\n}"); + return builder.toString(); + } + + public OWLOntology getOntology() { + if(isDisposed()) throw new DisposedException(); + return program.getOntology(); + } + + public UpperDatalogProgram getProgram() { + if(isDisposed()) throw new DisposedException(); + return program; + } + + public String getOriginalPredicate(String p) { + if(isDisposed()) throw new DisposedException(); + if(p.startsWith("<")) { + if(!p.endsWith(trackingSuffix + ">")) return null; + } + else if(!p.endsWith(trackingSuffix)) return null; + + return p.replace(trackingSuffix, ""); + } + + public boolean isAuxPredicate(String p) { + if(isDisposed()) throw new DisposedException(); + return false; + } + + protected abstract String getEqualityRelatedRuleText(); + + protected String getIRI(String name) { + return program.getOntology().getOntologyID().getOntologyIRI().toString() + "#" + name; + } + + protected abstract void encodingRule(DLClause clause); + + protected Individual getIndividual4GeneralRule(DLClause clause) { + clause = program.getCorrespondingClause(clause); // if (clause == null) -// return Individual.create(getIRI("_r0")); - - int index; - if (clause2index.containsKey(clause)) - index = clause2index.get(clause); - else { - index = clause2index.size() + 1; - index2clause.put(index, clause); - clause2index.put(clause, index); - } - - return Individual.create(getIRI("_r" + index)); - } - - private boolean queryEncoded = false; - private LinkedList addedData = new LinkedList(); - - public Collection getAddedData() { - return addedData; - } - - private void encodingQuery(QueryRecord[] botQuerRecords) { - if (queryEncoded) return ; - queryEncoded = true; - - if (currentQuery.getArity() > 0 && currentQuery.getArity() < 3) { - encodingAtomicQuery(botQuerRecords); - - } else { - DLClause queryClause = currentQuery.getClause(); - Atom[] bodyAtoms = queryClause.getBodyAtoms(); - for (Atom bodyAtom: bodyAtoms) - addQueryRule(bodyAtom, bodyAtoms); - } - } - - private void addQueryRule(Atom atom, Atom[] atoms) { - DLClause newClause; - Atom headAtom; - - headAtom = Atom.create( - getTrackingDLPredicate(atom.getDLPredicate()), - DLClauseHelper.getArguments(atom)); - newClause = DLClause.create(new Atom[] {headAtom}, atoms); - queryClauses.add(newClause); - } - - public static final String trackingPredicateRelation = Namespace.PAGODA_AUX + "isTrackingPredicateFor"; - - public static final String QueryPredicate = Namespace.PAGODA_AUX + "Query"; - - protected String getCurrentQueryPredicate() { - return QueryPredicate + currentQuery.getQueryID(); - } - - protected void encodingAtomicQuery(QueryRecord[] botQuerRecords) { - encodingAtomicQuery(botQuerRecords, false); - } - - protected void encodingAtomicQuery(QueryRecord[] botQuerRecords, boolean includingBottom) { - DLClause queryClause = currentQuery.getClause(); - AnswerTuples answerTuples = currentQuery.getGapAnswers(); - String[] answerVariables = currentQuery.getAnswerVariables(); - - String currentQueryPredicate = getCurrentQueryPredicate(); - Atom newAtom; - if (answerVariables.length == 1) { - AtomicConcept queryConcept = AtomicConcept.create(currentQueryPredicate); - newAtom = Atom.create(queryConcept, Variable.create(answerVariables[0])); - } - else { - AtomicRole queryRole = AtomicRole.create(currentQueryPredicate); - newAtom = Atom.create(queryRole, Variable.create(answerVariables[0]), Variable.create(answerVariables[1])); - } - - Atom[] bodyAtoms = queryClause.getBodyAtoms(); - Atom[] newBodyAtoms = new Atom[queryClause.getBodyLength() + 1]; - for (int i = 0; i < bodyAtoms.length; ++i) - newBodyAtoms[i + 1] = bodyAtoms[i]; - newBodyAtoms[0] = newAtom; - - for (Atom bodyAtom: bodyAtoms) - addQueryRule(bodyAtom, newBodyAtoms); - - RDFoxTripleManager tripleManager = new RDFoxTripleManager(store.getDataStore(), true); +// return Individual.create(getIRI("_r0")); + + int index; + if(clause2index.containsKey(clause)) + index = clause2index.get(clause); + else { + index = clause2index.size() + 1; + index2clause.put(index, clause); + clause2index.put(clause, index); + } + + return Individual.create(getIRI("_r" + index)); + } + + private void encodingQuery(QueryRecord[] botQuerRecords) { + if(queryEncoded) return; + queryEncoded = true; + + if(currentQuery.getArity() > 0 && currentQuery.getArity() < 3) { + encodingAtomicQuery(botQuerRecords); + + } + else { + DLClause queryClause = currentQuery.getClause(); + Atom[] bodyAtoms = queryClause.getBodyAtoms(); + for(Atom bodyAtom : bodyAtoms) + addQueryRule(bodyAtom, bodyAtoms); + } + } + + private void addQueryRule(Atom atom, Atom[] atoms) { + DLClause newClause; + Atom headAtom; + + headAtom = Atom.create( + getTrackingDLPredicate(atom.getDLPredicate()), + DLClauseHelper.getArguments(atom)); + newClause = DLClause.create(new Atom[]{headAtom}, atoms); + queryClauses.add(newClause); + } + + protected String getCurrentQueryPredicate() { + return QueryPredicate + currentQuery.getQueryID(); + } + + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords) { + encodingAtomicQuery(botQuerRecords, false); + } + + protected void encodingAtomicQuery(QueryRecord[] botQuerRecords, boolean includingBottom) { + DLClause queryClause = currentQuery.getClause(); + AnswerTuples answerTuples = currentQuery.getGapAnswers(); + String[] answerVariables = currentQuery.getAnswerVariables(); + + String currentQueryPredicate = getCurrentQueryPredicate(); + Atom newAtom; + if(answerVariables.length == 1) { + AtomicConcept queryConcept = AtomicConcept.create(currentQueryPredicate); + newAtom = Atom.create(queryConcept, Variable.create(answerVariables[0])); + } + else { + AtomicRole queryRole = AtomicRole.create(currentQueryPredicate); + newAtom = Atom.create(queryRole, Variable.create(answerVariables[0]), Variable.create(answerVariables[1])); + } + + Atom[] bodyAtoms = queryClause.getBodyAtoms(); + Atom[] newBodyAtoms = new Atom[queryClause.getBodyLength() + 1]; + for(int i = 0; i < bodyAtoms.length; ++i) + newBodyAtoms[i + 1] = bodyAtoms[i]; + newBodyAtoms[0] = newAtom; + + for(Atom bodyAtom : bodyAtoms) + addQueryRule(bodyAtom, newBodyAtoms); + + RDFoxTripleManager tripleManager = new RDFoxTripleManager(store.getDataStore(), true); // MyPrefixes prefixes = MyPrefixes.PAGOdAPrefixes; - int[] triple; - int predicate = tripleManager.getResourceID(AtomicConcept.create(currentQueryPredicate)); - int rdftype = tripleManager.getResourceID(AtomicRole.create(Namespace.RDF_TYPE)); - if (answerVariables.length == 1) { - for (AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { - answer = answerTuples.getTuple(); - triple = new int[] { tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), rdftype, predicate }; - addedData.add(triple); - tripleManager.addTripleByID(triple); -// System.out.println("To be removed ... \n" + tripleManager.getRawTerm(tripleManager.getResourceID(prefixes.expandIRI(answer.getRawTerm(0)))) + " " + tripleManager.getRawTerm(rdftype) + " " + tripleManager.getRawTerm(predicate)); - } - } - else { - for (AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { - answer = answerTuples.getTuple(); - triple = new int[] { tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), predicate, tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(1))) }; - addedData.add(triple); - tripleManager.addTripleByID(triple); - } - } - answerTuples.dispose(); - - if (includingBottom && botQuerRecords != null) { - int index = 0; - GroundTerm t; - String raw; - for (QueryRecord botQueryRecord: botQuerRecords) { - answerTuples = botQueryRecord.getGapAnswers(); - int subID = 0;//botQueryRecord.getSubID(); - String p = subID == 0 ? AtomicConcept.NOTHING.getIRI() : Namespace.OWL_NS + "Nothing_final" + (++index); - predicate = tripleManager.getResourceID(AtomicConcept.create(p = getTrackingPredicate(p))); - for (AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { - answer = answerTuples.getTuple(); + int[] triple; + int predicate = tripleManager.getResourceID(AtomicConcept.create(currentQueryPredicate)); + int rdftype = tripleManager.getResourceID(AtomicRole.create(Namespace.RDF_TYPE)); + if(answerVariables.length == 1) { + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); + triple = + new int[]{tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), rdftype, predicate}; + addedData.add(triple); + tripleManager.addTripleByID(triple); +// System.out.println("To be removed ... \n" + tripleManager.getRawTerm(tripleManager.getResourceID(prefixes.expandIRI(answer.getRawTerm(0)))) + " " + tripleManager.getRawTerm(rdftype) + " " + tripleManager.getRawTerm(predicate)); + } + } + else { + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); + triple = + new int[]{tripleManager.getResourceID(getRawTerm(answer.getGroundTerm(0))), predicate, tripleManager + .getResourceID(getRawTerm(answer.getGroundTerm(1)))}; + addedData.add(triple); + tripleManager.addTripleByID(triple); + } + } +// answerTuples.dispose(); + + if(includingBottom && botQuerRecords != null) { + int index = 0; + GroundTerm t; + String raw; + for(QueryRecord botQueryRecord : botQuerRecords) { + answerTuples = botQueryRecord.getGapAnswers(); + int subID = 0;//botQueryRecord.getSubID(); + String p = subID == 0 ? AtomicConcept.NOTHING.getIRI() : Namespace.OWL_NS + "Nothing_final" + (++index); + predicate = tripleManager.getResourceID(AtomicConcept.create(p = getTrackingPredicate(p))); + for(AnswerTuple answer; answerTuples.isValid(); answerTuples.moveNext()) { + answer = answerTuples.getTuple(); // System.out.println("To be removed ... " + answer.getRawTerm(0)); - raw = ((t = answer.getGroundTerm(0)) instanceof uk.ac.ox.cs.JRDFox.model.Individual) ? ((uk.ac.ox.cs.JRDFox.model.Individual) t).getIRI() : t.toString(); - triple = new int[] { tripleManager.getResourceID(raw), rdftype, predicate }; - addedData.add(triple); - tripleManager.addTripleByID(triple); - } - answerTuples.dispose(); - } - } - - Utility.logInfo(addedData.size() + " triples are added into the store."); - } - - public static String getRawTerm(GroundTerm r) { - if (r instanceof uk.ac.ox.cs.JRDFox.model.Individual) - return ((uk.ac.ox.cs.JRDFox.model.Individual) r).getIRI(); - else { - Literal l = (Literal) r; - if (l.getDatatype().equals(Datatype.XSD_STRING) && l.getDatatype().equals(Datatype.RDF_PLAIN_LITERAL)) - return "\"" + l.getLexicalForm() + "\""; - else - return "\"" + l.getLexicalForm() + "\"^^<" + l.getDatatype().getIRI() + ">"; - } - } - - protected DLPredicate getGapDLPredicate(DLPredicate dlPredicate) { - return getDLPredicate(dlPredicate, GapTupleIterator.gapPredicateSuffix); - } - - DLPredicate getDLPredicate(DLPredicate p, String suffix) { - if (p instanceof AtomicConcept) - return AtomicConcept.create(((AtomicConcept) p).getIRI() + suffix); - else if (p instanceof DatatypeRestriction) { - DatatypeRestriction restriction = (DatatypeRestriction) p; - String newURI = restriction.getDatatypeURI() + suffix; - return getDatatypeRestriction(restriction, newURI); - } - else if (p instanceof AtomicRole) - return AtomicRole.create(((AtomicRole) p).getIRI() + suffix); - else if (p instanceof AnnotatedEquality || p instanceof Equality) - return AtomicRole.create(Namespace.EQUALITY + suffix); - else if (p instanceof Inequality) - return AtomicRole.create(Namespace.INEQUALITY + suffix); - else if (p instanceof DatatypeRestriction) - return AtomicConcept.create(((DatatypeRestriction) p).getDatatypeURI() + suffix); - else { - Utility.logDebug("strange DL predicate appeared ... " + p, - "the program paused here in TrackingRuleEncoderDisj.java"); - return null; - } - } - - protected DLPredicate getTrackingDLPredicate(DLPredicate dlPredicate) { - return getDLPredicate(dlPredicate, getTrackingSuffix(currentQuery.getQueryID())); - } - - protected static String getTrackingSuffix(String queryID) { - return "_AUXt" + queryID; - } - - public String getTrackingPredicate(String predicateIRI) { - if (predicateIRI.startsWith("<")) - return predicateIRI.replace(">", getTrackingSuffix(currentQuery.getQueryID()) + ">"); - else - return predicateIRI + getTrackingSuffix(currentQuery.getQueryID()); - } - - protected DLPredicate getDatatypeRestriction(DatatypeRestriction restriction, String newName) { - int length = restriction.getNumberOfFacetRestrictions(); - String[] facets = new String[length]; - Constant[] values = new Constant[length]; - for (int i = 0; i < length; ++i) { - facets[i] = restriction.getFacetURI(i); - values[i] = restriction.getFacetValue(i); - } - return DatatypeRestriction.create(newName, facets, values); - } - - protected QueryRecord currentQuery; - DLPredicate selected; - - public void setCurrentQuery(QueryRecord record) { - deprecateTrackingAndQueryRules(); - currentQuery = record; - selected = AtomicConcept.create(getSelectedPredicate()); - trackingSuffix = "_AUXt" + currentQuery.getQueryID(); - } - - public void dispose() { - deprecateTrackingAndQueryRules(); - } - - private String getTrackingRuleText() { - return DLClauseHelper.toString(trackingClauses); - } - - private String getQueryRuleText() { - return DLClauseHelper.toString(queryClauses); - } - - public String getTrackingProgram() { - StringBuilder sb = getTrackingProgramBody(); - sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText()); - return sb.toString(); - } - - protected StringBuilder getTrackingProgramBody() { - encodingRules(); - encodingQuery(new QueryRecord[0]); - - StringBuilder sb = new StringBuilder(); - sb.append(getTrackingRuleText()); - sb.append(getEqualityRelatedRuleText()); - sb.append(getQueryRuleText()); - return sb; - } - - public void saveTrackingRules(String fileName) { - BufferedWriter writer = null; - try { - writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))); - writer.write(getTrackingProgram()); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - return ; - } - Utility.logDebug("The tracking rules are saved in " + fileName + "."); - } - - private void deprecateTrackingAndQueryRules() { - trackingClauses.clear(); - queryClauses.clear(); - addedData.clear(); - ruleEncoded = false; - queryEncoded = false; - } - - public String getSelectedPredicate() { - return getIRI("_selected" + currentQuery.getQueryID()); - } - - public DLClause getSelectedClause(String iri) { - int index = iri.lastIndexOf("_r") + 2; - int ruleIndex = Integer.parseInt(iri.substring(index)); - return index2clause.get(ruleIndex); - } - - /** - * SELECT ?X - * WHERE { - * ?X :_selected? - * } - */ - public String getSelectedSPARQLQuery() { - StringBuilder builder = new StringBuilder(); - builder.append("SELECT ?X\nWHERE {\n?X "); - builder.append(selected.toString()).append("\n}"); - return builder.toString(); - } - - public OWLOntology getOntology() { - return program.getOntology(); - } - - public UpperDatalogProgram getProgram() { - return program; - } - - private String trackingSuffix; - - public String getOriginalPredicate(String p) { - if (p.startsWith("<")) { - if (!p.endsWith(trackingSuffix + ">")) return null; - } - else - if (!p.endsWith(trackingSuffix)) return null; - - return p.replace(trackingSuffix, ""); - } - - public boolean isAuxPredicate(String p) { - return false; - } - - protected Set unaryPredicates = new HashSet(); - protected Set binaryPredicates = new HashSet(); - + raw = ((t = + answer.getGroundTerm(0)) instanceof uk.ac.ox.cs.JRDFox.model.Individual) ? ((uk.ac.ox.cs.JRDFox.model.Individual) t) + .getIRI() : t.toString(); + triple = new int[]{tripleManager.getResourceID(raw), rdftype, predicate}; + addedData.add(triple); + tripleManager.addTripleByID(triple); + } +// answerTuples.dispose(); + } + } + + Utility.logInfo(addedData.size() + " triples are added into the store."); + } + + protected DLPredicate getGapDLPredicate(DLPredicate dlPredicate) { + return getDLPredicate(dlPredicate, GapTupleIterator.gapPredicateSuffix); + } + + DLPredicate getDLPredicate(DLPredicate p, String suffix) { + if(isDisposed()) throw new DisposedException(); + if(p instanceof AtomicConcept) + return AtomicConcept.create(((AtomicConcept) p).getIRI() + suffix); + else if(p instanceof DatatypeRestriction) { + DatatypeRestriction restriction = (DatatypeRestriction) p; + String newURI = restriction.getDatatypeURI() + suffix; + return getDatatypeRestriction(restriction, newURI); + } + else if(p instanceof AtomicRole) + return AtomicRole.create(((AtomicRole) p).getIRI() + suffix); + else if(p instanceof AnnotatedEquality || p instanceof Equality) + return AtomicRole.create(Namespace.EQUALITY + suffix); + else if(p instanceof Inequality) + return AtomicRole.create(Namespace.INEQUALITY + suffix); + else if(p instanceof DatatypeRestriction) + return AtomicConcept.create(((DatatypeRestriction) p).getDatatypeURI() + suffix); + else { + Utility.logDebug("strange DL predicate appeared ... " + p, + "the program paused here in TrackingRuleEncoderDisj.java"); + return null; + } + } + + protected DLPredicate getTrackingDLPredicate(DLPredicate dlPredicate) { + return getDLPredicate(dlPredicate, getTrackingSuffix(currentQuery.getQueryID())); + } + + protected DLPredicate getDatatypeRestriction(DatatypeRestriction restriction, String newName) { + int length = restriction.getNumberOfFacetRestrictions(); + String[] facets = new String[length]; + Constant[] values = new Constant[length]; + for(int i = 0; i < length; ++i) { + facets[i] = restriction.getFacetURI(i); + values[i] = restriction.getFacetValue(i); + } + return DatatypeRestriction.create(newName, facets, values); + } + + private String getTrackingRuleText() { + return DLClauseHelper.toString(trackingClauses); + } + + private String getQueryRuleText() { + return DLClauseHelper.toString(queryClauses); + } + + protected StringBuilder getTrackingProgramBody() { + encodingRules(); + encodingQuery(new QueryRecord[0]); + + StringBuilder sb = new StringBuilder(); + sb.append(getTrackingRuleText()); + sb.append(getEqualityRelatedRuleText()); + sb.append(getQueryRuleText()); + return sb; + } + + private void deprecateTrackingAndQueryRules() { + trackingClauses.clear(); + queryClauses.clear(); + addedData.clear(); + ruleEncoded = false; + queryEncoded = false; + } + } diff --git a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java index c3694ad..4ece796 100644 --- a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java +++ b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithGap.java @@ -17,7 +17,7 @@ import java.util.LinkedList; import java.util.Set; public class TrackingRuleEncoderWithGap extends TrackingRuleEncoder { - + public TrackingRuleEncoderWithGap(UpperDatalogProgram program, BasicQueryEngine store) { super(program, store); } @@ -113,6 +113,4 @@ public class TrackingRuleEncoderWithGap extends TrackingRuleEncoder { } } - - } diff --git a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java index be9e45c..f898114 100644 --- a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java +++ b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderWithoutGap.java @@ -1,24 +1,19 @@ package uk.ac.ox.cs.pagoda.tracking; -import java.util.Collection; -import java.util.LinkedList; - -import org.semanticweb.HermiT.model.Atom; -import org.semanticweb.HermiT.model.AtomicConcept; -import org.semanticweb.HermiT.model.AtomicRole; -import org.semanticweb.HermiT.model.DLClause; -import org.semanticweb.HermiT.model.Variable; +import org.semanticweb.HermiT.model.*; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLObjectProperty; import org.semanticweb.owlapi.model.OWLOntology; - import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; import uk.ac.ox.cs.pagoda.util.Namespace; +import java.util.Collection; +import java.util.LinkedList; + public class TrackingRuleEncoderWithoutGap extends TrackingRuleEncoder { - + public TrackingRuleEncoderWithoutGap(UpperDatalogProgram program, BasicQueryEngine store) { super(program, store); } @@ -105,5 +100,4 @@ public class TrackingRuleEncoderWithoutGap extends TrackingRuleEncoder { } } - } diff --git a/src/uk/ac/ox/cs/pagoda/util/disposable/Disposable.java b/src/uk/ac/ox/cs/pagoda/util/disposable/Disposable.java new file mode 100644 index 0000000..b208cc3 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/util/disposable/Disposable.java @@ -0,0 +1,39 @@ +package uk.ac.ox.cs.pagoda.util.disposable; + + +/** + * Every public method of a subclass of this class, + * as first instruction, should check if the object has already been disposed + * and, if so, should throw a DisposedException. + */ +public abstract class Disposable { + + private boolean disposed = false; + + /** + * This method must be called after the use of the object. + *

+ * Every overriding method must call super.dispose() as first instruction. + */ + public void dispose() { + if(isDisposed()) throw new AlreadyDisposedException(); + disposed = true; + } + + public final boolean isDisposed() { + return disposed; + } + + private class AlreadyDisposedException extends RuntimeException { + + public AlreadyDisposedException() { + super(); + } + + public AlreadyDisposedException(String msg) { + super(msg); + } + } + + +} diff --git a/src/uk/ac/ox/cs/pagoda/util/disposable/DisposedException.java b/src/uk/ac/ox/cs/pagoda/util/disposable/DisposedException.java new file mode 100644 index 0000000..eb8c039 --- /dev/null +++ b/src/uk/ac/ox/cs/pagoda/util/disposable/DisposedException.java @@ -0,0 +1,12 @@ +package uk.ac.ox.cs.pagoda.util.disposable; + +public class DisposedException extends RuntimeException { + + public DisposedException() { + super(); + } + + public DisposedException(String msg) { + super(msg); + } +} -- cgit v1.2.3