From c3480bb733b8bca976718a3dc2f09a21cb4b1b45 Mon Sep 17 00:00:00 2001 From: RncLsn Date: Tue, 4 Aug 2015 18:30:46 +0100 Subject: Rules parsing. --- src/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java | 83 ++++++++++++++++++++-- .../pagoda/multistage/MultiStageUpperProgram.java | 1 + .../treatement/Pick4NegativeConcept.java | 1 + .../ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java | 2 +- .../ac/ox/cs/pagoda/reasoner/HermiTReasoner.java | 2 +- .../ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java | 8 +-- src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java | 51 +++++++------ src/uk/ac/ox/cs/pagoda/rules/GeneralProgram.java | 2 +- .../ac/ox/cs/pagoda/rules/LowerDatalogProgram.java | 3 +- src/uk/ac/ox/cs/pagoda/rules/Program.java | 37 ++++++++-- .../LimitedSkolemisationApproximator.java | 2 +- .../ac/ox/cs/pagoda/rules/clauses/Conjunction.java | 4 -- src/uk/ac/ox/cs/pagoda/rules/clauses/DLClause.java | 12 ---- 13 files changed, 151 insertions(+), 57 deletions(-) delete mode 100644 src/uk/ac/ox/cs/pagoda/rules/clauses/Conjunction.java delete mode 100644 src/uk/ac/ox/cs/pagoda/rules/clauses/DLClause.java (limited to 'src/uk') diff --git a/src/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java b/src/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java index 81c99a4..43c5849 100644 --- a/src/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java +++ b/src/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java @@ -2,9 +2,16 @@ package uk.ac.ox.cs.pagoda.hermit; import org.semanticweb.HermiT.model.*; import uk.ac.ox.cs.pagoda.MyPrefixes; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; import uk.ac.ox.cs.pagoda.util.Namespace; +import java.security.InvalidParameterException; +import java.util.ArrayList; + public class RuleHelper { + private static final String OR = "|"; + private static final String IF = ":-"; + private static final String AND = ","; // public static String abbreviateIRI(String text) { // String prefixName, prefixIRI; @@ -37,16 +44,16 @@ public class RuleHelper { boolean lastSpace = true; for (Atom headAtom: clause.getHeadAtoms()) { if ((atomText = getText(headAtom)) == null) continue; - if (!lastSpace) buf.append(" v "); + if (!lastSpace) buf.append(" ").append(OR).append(" "); buf.append(atomText); lastSpace = false; } - buf.append(" :- "); + buf.append(" ").append(IF).append(" "); lastSpace = true; for (Atom bodyAtom: clause.getBodyAtoms()) { // for (String str: strs[1].split(", ")) { if ((atomText = getText(bodyAtom)) == null) continue; - if (!lastSpace) buf.append(", "); + if (!lastSpace) buf.append(AND).append(" "); buf.append(atomText); lastSpace = false; } @@ -74,7 +81,7 @@ public class RuleHelper { else builder.append(getText(p)); builder.append("("); builder.append(getText(atom.getArgument(0))); - builder.append(","); + builder.append(","); builder.append(getText(atom.getArgument(1))); builder.append(")"); } @@ -95,4 +102,72 @@ public class RuleHelper { return MyPrefixes.PAGOdAPrefixes.abbreviateIRI(t.toString()); } + public static Term parseTerm(String s) { + s = s.trim(); + if(s.startsWith("?")) return Variable.create(s.substring(1)); + return Individual.create(MyPrefixes.PAGOdAPrefixes.expandIRI(s)); + } + + public static Atom parseAtom(String s) { + s = s.trim(); + + String[] split = s.split("\\("); + String predicateIri = OWLHelper.removeAngles(MyPrefixes.PAGOdAPrefixes.expandText(split[0])); + String[] predicateArgs = split[1].substring(0, split[1].length() - 1).split(","); + int numOfargs = predicateArgs.length; + Term terms[] = new Term[predicateArgs.length]; + for (int i = 0; i < terms.length; i++) + terms[i] = parseTerm(predicateArgs[i]); + if(numOfargs == 1) { + AtomicConcept atomicConcept = AtomicConcept.create(predicateIri); + return Atom.create(atomicConcept, terms); + } + else if(numOfargs == 2) { + AtomicRole atomicRole = AtomicRole.create(predicateIri); + return Atom.create(atomicRole, terms); + } + else + throw new InvalidParameterException(); + // TODO? add equality (owl:sameAs)? + } + + public static DLClause parseClause(String s) { + s = s.trim(); + if(s.endsWith(".")) s = s.substring(0, s.length()-1).trim(); + + String[] headAndBody = s.split(IF); + String[] headAtomsStr = splitAtoms(headAndBody[0], OR); + String[] bodyAtomsStr = splitAtoms(headAndBody[1], AND); + + Atom[] headAtoms = new Atom[headAtomsStr.length]; + Atom[] bodyAtoms = new Atom[bodyAtomsStr.length]; + for (int i = 0; i < headAtoms.length; i++) + headAtoms[i] = parseAtom(headAtomsStr[i]); + for (int i = 0; i < bodyAtoms.length; i++) + bodyAtoms[i] = parseAtom(bodyAtomsStr[i]); + + return DLClause.create(headAtoms, bodyAtoms); + } + + private static String[] splitAtoms(String s, String operator) { + char op = operator.charAt(0); + ArrayList result = new ArrayList<>(); + + int b = 0; + boolean betweenParenthesis = false; + for (int i = 0; i < s.length(); i++) { + if(s.charAt(i) == '(') + betweenParenthesis = true; + else if(s.charAt(i) == ')') + betweenParenthesis = false; + else if(s.charAt(i) == op && !betweenParenthesis) { + result.add(s.substring(b, i)); + b = i + 1; + } + } + if(b < s.length()) result.add(s.substring(b)); + + return result.toArray(new String[0]); + } + } diff --git a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java index 1664c99..e64c5e6 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java @@ -193,6 +193,7 @@ public abstract class MultiStageUpperProgram { public abstract Collection isIntegrated(MultiStageQueryEngine engine, boolean incrementally); + // TODO -RULE- protected Violation violate(MultiStageQueryEngine engine, DLClause clause, boolean incrementally) { Utility.logTrace("checking constraint: " + clause); 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 687fa4a..3528788 100644 --- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java +++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java @@ -49,6 +49,7 @@ public abstract class Pick4NegativeConcept extends Treatment { tripleManager.addTripleByID(tripleManager.getInstance(gapAtom, assignment)); } + // TODO -RULE- protected boolean makeSatisfied(Violation violation, Comparator comp) { LinkedList tuples = violation.getTuples(); DLClause constraint = violation.getConstraint(); diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java index a56a793..15dfa03 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/ELHOUQueryReasoner.java @@ -117,7 +117,7 @@ class ELHOUQueryReasoner extends QueryReasoner { } OWLOntology ontology = o; - program = new DatalogProgram(ontology, properties.getToClassify()); + program = new DatalogProgram(ontology); importData(program.getAdditionalDataFile()); diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java index 15eb9e8..ac62488 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/HermiTReasoner.java @@ -52,7 +52,7 @@ class HermiTReasoner extends QueryReasoner { e.printStackTrace(); } - DatalogProgram datalogProgram = new DatalogProgram(tbox, false); + DatalogProgram datalogProgram = new DatalogProgram(tbox); importData(datalogProgram.getAdditionalDataFile()); upperStore = new MultiStageQueryEngine("rl-upper", false); upperStore.importRDFData("data", getImportedData()); diff --git a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java index 8e28142..71d5752 100644 --- a/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java +++ b/src/uk/ac/ox/cs/pagoda/reasoner/MyQueryReasoner.java @@ -68,7 +68,7 @@ class MyQueryReasoner extends QueryReasoner { } ontology = o; - program = new DatalogProgram(ontology, properties.getToClassify()); + program = new DatalogProgram(ontology); // program.getLower().save(); // program.getUpper().save(); // program.getGeneral().save(); @@ -154,7 +154,7 @@ class MyQueryReasoner extends QueryReasoner { // encoder = new TrackingRuleEncoderDisjVar2(program.getUpper(), trackingStore); // encoder = new TrackingRuleEncoderDisj2(program.getUpper(), trackingStore); - // TODO add consistency check by Skolem-upper-bound + // TODO? add consistency check by Skolem-upper-bound if(!isConsistent()) return false; @@ -225,7 +225,7 @@ class MyQueryReasoner extends QueryReasoner { @Override public void evaluateUpper(QueryRecord queryRecord) { if(isDisposed()) throw new DisposedException(); - // TODO add new upper store + // TODO? add new upper store AnswerTuples rlAnswer = null; boolean useFull = queryRecord.isBottom() || lazyUpperStore == null; try { @@ -388,7 +388,7 @@ class MyQueryReasoner extends QueryReasoner { Utility.logInfo(">> Semi-Skolemisation <<"); t.reset(); - DatalogProgram relevantProgram = new DatalogProgram(relevantSubset, false); // toClassify is false + DatalogProgram relevantProgram = new DatalogProgram(relevantSubset); MultiStageQueryEngine relevantStore = new MultiStageQueryEngine("Relevant-store", true); // checkValidity is true diff --git a/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java b/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java index 29e74c2..e2a171d 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java +++ b/src/uk/ac/ox/cs/pagoda/rules/DatalogProgram.java @@ -2,11 +2,12 @@ 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 java.io.InputStream; + public class DatalogProgram extends Disposable { UpperDatalogProgram upperProgram = new UpperDatalogProgram(); @@ -15,14 +16,36 @@ public class DatalogProgram extends Disposable { BottomStrategy upperBottom; - public DatalogProgram(OWLOntology o) { + public DatalogProgram(InputStream inputStream) { lowerProgram = new LowerDatalogProgram(); - init(o, false); + + upperProgram.load(inputStream, upperBottom = new UpperUnaryBottom()); + lowerProgram.clone(upperProgram); + program.clone(upperProgram); + + upperProgram.transform(); + lowerProgram.transform(); + program.transform(); + + program.buildDependencyGraph(); + lowerProgram.dependencyGraph = upperProgram.buildDependencyGraph(); } - public DatalogProgram(OWLOntology o, boolean toClassify) { - lowerProgram = new LowerDatalogProgram(toClassify); - init(o, toClassify); + public DatalogProgram(OWLOntology o) { + lowerProgram = new LowerDatalogProgram(); + + 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(); + lowerProgram.dependencyGraph = upperProgram.buildDependencyGraph(); } public LowerDatalogProgram getLower() { @@ -55,20 +78,4 @@ public class DatalogProgram extends Disposable { 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(); - - upperProgram.transform(); - lowerProgram.transform(); - program.transform(); - - program.buildDependencyGraph(); - PredicateDependency graph = upperProgram.buildDependencyGraph(); - lowerProgram.dependencyGraph = graph; - } } diff --git a/src/uk/ac/ox/cs/pagoda/rules/GeneralProgram.java b/src/uk/ac/ox/cs/pagoda/rules/GeneralProgram.java index 01ab427..e390a29 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/GeneralProgram.java +++ b/src/uk/ac/ox/cs/pagoda/rules/GeneralProgram.java @@ -15,7 +15,7 @@ public class GeneralProgram extends Program { ontology = relevantOntology; ontologyDirectory = null; - dlOntology = null; +// dlOntology = null; botStrategy = new UnaryBottom(); clauses = botStrategy.process(relevantClauses); diff --git a/src/uk/ac/ox/cs/pagoda/rules/LowerDatalogProgram.java b/src/uk/ac/ox/cs/pagoda/rules/LowerDatalogProgram.java index 9930009..a2676e8 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/LowerDatalogProgram.java +++ b/src/uk/ac/ox/cs/pagoda/rules/LowerDatalogProgram.java @@ -39,6 +39,7 @@ public class LowerDatalogProgram extends ApproxProgram implements IncrementalPro } + // TODO -RULE- filter out unsafe rules @Override public void transform() { if (m_toClassify) { @@ -56,7 +57,7 @@ public class LowerDatalogProgram extends ApproxProgram implements IncrementalPro else super.transform(); - Normalisation norm = new Normalisation(dlOntology.getDLClauses(), ontology, new NullaryBottom()); + Normalisation norm = new Normalisation(dlClauses, ontology, new NullaryBottom()); BottomStrategy tBottom = new NullaryBottom(); norm.process(); for (DLClause nClause: norm.getNormlisedClauses()) { diff --git a/src/uk/ac/ox/cs/pagoda/rules/Program.java b/src/uk/ac/ox/cs/pagoda/rules/Program.java index a0edf85..de06f52 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/Program.java +++ b/src/uk/ac/ox/cs/pagoda/rules/Program.java @@ -4,6 +4,7 @@ import org.apache.commons.io.FilenameUtils; import org.semanticweb.HermiT.Configuration; import org.semanticweb.HermiT.model.*; import org.semanticweb.HermiT.structural.OWLClausification; +import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; import org.semanticweb.simpleETL.SimpleETL; import uk.ac.ox.cs.pagoda.MyPrefixes; @@ -13,6 +14,7 @@ import uk.ac.ox.cs.pagoda.constraints.BottomStrategy; import uk.ac.ox.cs.pagoda.constraints.NullaryBottom; import uk.ac.ox.cs.pagoda.constraints.PredicateDependency; import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; +import uk.ac.ox.cs.pagoda.hermit.RuleHelper; import uk.ac.ox.cs.pagoda.owl.OWLHelper; import uk.ac.ox.cs.pagoda.util.Utility; @@ -23,7 +25,9 @@ public abstract class Program implements KnowledgeBase { protected String ontologyDirectory = null; protected OWLOntology ontology; - protected DLOntology dlOntology; +// protected DLOntology dlOntology; + protected Set dlClauses = new HashSet<>(); + protected Set positiveFacts = new HashSet<>(); protected BottomStrategy botStrategy; protected Collection clauses = new HashSet(); // protected Set used = new HashSet(); @@ -40,6 +44,24 @@ protected PredicateDependency dependencyGraph; return sb.toString(); } + public void load(InputStream rules, BottomStrategy botStrategy) { +// this.botStrategy = botStrategy; +// // fake instantiation + try { + load(OWLManager.createOWLOntologyManager().createOntology(), botStrategy); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } + + try(BufferedReader br = new BufferedReader(new InputStreamReader(rules))) { + String line; + while((line = br.readLine()) != null) + dlClauses.add(RuleHelper.parseClause(line)); + } catch (IOException e) { + e.printStackTrace(); + } + } + public void load(OWLOntology o, BottomStrategy botStrategy) { this.botStrategy = botStrategy; RLPlusOntology owlOntology = new RLPlusOntology(); @@ -57,7 +79,7 @@ protected PredicateDependency dependencyGraph; OWLOntology abox = OWLHelper.loadOntology(aboxOWLFile); OWLOntologyManager manager = abox.getOWLOntologyManager(); OWLAxiom axiom; - for (Atom atom: dlOntology.getPositiveFacts()) { + for (Atom atom: positiveFacts) { if ((axiom = OWLHelper.getABoxAssertion(manager.getOWLDataFactory(), atom)) != null) manager.addAxiom(abox, axiom); } @@ -90,7 +112,7 @@ protected PredicateDependency dependencyGraph; @Override public void transform() { - for(DLClause dlClause : dlOntology.getDLClauses()) { + for(DLClause dlClause : dlClauses) { DLClause simplifiedDLClause = DLClauseHelper.removeNominalConcept(dlClause); simplifiedDLClause = removeAuxiliaryBodyAtoms(simplifiedDLClause); simplifiedDLClause = DLClauseHelper.replaceWithDataValue(simplifiedDLClause); @@ -190,7 +212,9 @@ protected PredicateDependency dependencyGraph; void clone(Program program) { this.ontologyDirectory = program.ontologyDirectory; this.ontology = program.ontology; - this.dlOntology = program.dlOntology; +// this.dlOntology = program.dlOntology; + this.dlClauses = program.dlClauses; + this.positiveFacts = program.positiveFacts; this.botStrategy = program.botStrategy; this.additionalDataFile = program.additionalDataFile; this.transitiveAxioms = program.transitiveAxioms; @@ -248,8 +272,9 @@ protected PredicateDependency dependencyGraph; } Utility.logInfo("The number of data property range axioms that are ignored: " + noOfDataPropertyRangeAxioms + "(" + noOfAxioms + ")"); - dlOntology = (DLOntology) clausifier.preprocessAndClausify(filteredOntology, null)[1]; - clausifier = null; + DLOntology dlOntology = (DLOntology) clausifier.preprocessAndClausify(filteredOntology, null)[1]; + dlClauses = dlOntology.getDLClauses(); + positiveFacts = dlOntology.getPositiveFacts(); } private DLClause removeAuxiliaryBodyAtoms(DLClause dlClause) { diff --git a/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java index 7d29c74..a140225 100644 --- a/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java +++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -/** +/*** * Approximates existential rules through a limited form of Skolemisation. *

* Given a rule and a ground substitution, diff --git a/src/uk/ac/ox/cs/pagoda/rules/clauses/Conjunction.java b/src/uk/ac/ox/cs/pagoda/rules/clauses/Conjunction.java deleted file mode 100644 index 91bb3e7..0000000 --- a/src/uk/ac/ox/cs/pagoda/rules/clauses/Conjunction.java +++ /dev/null @@ -1,4 +0,0 @@ -package uk.ac.ox.cs.pagoda.rules.clauses; - -public class Conjunction { -} diff --git a/src/uk/ac/ox/cs/pagoda/rules/clauses/DLClause.java b/src/uk/ac/ox/cs/pagoda/rules/clauses/DLClause.java deleted file mode 100644 index 7394be0..0000000 --- a/src/uk/ac/ox/cs/pagoda/rules/clauses/DLClause.java +++ /dev/null @@ -1,12 +0,0 @@ -package uk.ac.ox.cs.pagoda.rules.clauses; - -public class DLClause extends Clause { - -// private DLClause(Atom[] headAtoms, Atom[] bodyAtoms) { -// super(headAtoms, bodyAtoms); -// } -// -// public static DLClause create(Atom[] headAtoms, Atom[] bodyAtoms) { -// return s_interningManager.intern(new DLClause(headAtoms, bodyAtoms)); -// } -} -- cgit v1.2.3