aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs
diff options
context:
space:
mode:
authorRncLsn <rnc.lsn@gmail.com>2015-05-13 16:04:41 +0100
committerRncLsn <rnc.lsn@gmail.com>2015-05-13 16:04:41 +0100
commitd0c209780ac209ba20de1ef2ba68551dd3321b3c (patch)
treee3ed5f293fc7889d7d66e2bbce0fd03cc2d07a4a /src/uk/ac/ox/cs
parent7e0ecc07285209e65f9d4d022065d06a4997fc86 (diff)
downloadACQuA-d0c209780ac209ba20de1ef2ba68551dd3321b3c.tar.gz
ACQuA-d0c209780ac209ba20de1ef2ba68551dd3321b3c.zip
Implemented SkolemTermsManager.
Diffstat (limited to 'src/uk/ac/ox/cs')
-rw-r--r--src/uk/ac/ox/cs/pagoda/multistage/IndividualCollector.java6
-rw-r--r--src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java3
-rw-r--r--src/uk/ac/ox/cs/pagoda/multistage/Normalisation.java8
-rw-r--r--src/uk/ac/ox/cs/pagoda/multistage/ViolationTuple.java19
-rw-r--r--src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java17
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java5
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java14
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java51
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsDispenser.java74
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsManager.java116
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/TupleDependentApproximator.java9
-rw-r--r--src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java11
-rw-r--r--src/uk/ac/ox/cs/pagoda/util/tuples/Tuple.java44
-rw-r--r--src/uk/ac/ox/cs/pagoda/util/tuples/TupleBuilder.java25
14 files changed, 259 insertions, 143 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/multistage/IndividualCollector.java b/src/uk/ac/ox/cs/pagoda/multistage/IndividualCollector.java
index 22d90c4..a9c127b 100644
--- a/src/uk/ac/ox/cs/pagoda/multistage/IndividualCollector.java
+++ b/src/uk/ac/ox/cs/pagoda/multistage/IndividualCollector.java
@@ -7,7 +7,7 @@ import org.openrdf.model.impl.URIImpl;
7import org.openrdf.rio.RDFHandler; 7import org.openrdf.rio.RDFHandler;
8import org.openrdf.rio.RDFHandlerException; 8import org.openrdf.rio.RDFHandlerException;
9import uk.ac.ox.cs.JRDFox.model.Individual; 9import uk.ac.ox.cs.JRDFox.model.Individual;
10import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; 10import uk.ac.ox.cs.pagoda.rules.approximators.SkolemTermsManager;
11import uk.ac.ox.cs.pagoda.util.Namespace; 11import uk.ac.ox.cs.pagoda.util.Namespace;
12 12
13import java.util.Collection; 13import java.util.Collection;
@@ -58,9 +58,9 @@ public class IndividualCollector implements RDFHandler {
58 58
59 public Collection<Individual> getAllIndividuals() { 59 public Collection<Individual> getAllIndividuals() {
60 if (!addedSkolemised) { 60 if (!addedSkolemised) {
61 int number = OverApproxExist.getNumberOfSkolemisedIndividual(); 61 int number = SkolemTermsManager.getInstance().getNumberOfSkolemisedIndividual();
62 for (int i = 0; i < number; ++i) 62 for (int i = 0; i < number; ++i)
63 individuals.add(Individual.create(OverApproxExist.skolemisedIndividualPrefix + i)); 63 individuals.add(Individual.create(SkolemTermsManager.skolemisedIndividualPrefix + i));
64 addedSkolemised = true; 64 addedSkolemised = true;
65 } 65 }
66 return individuals; 66 return individuals;
diff --git a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java
index 33ba345..1664c99 100644
--- a/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java
+++ b/src/uk/ac/ox/cs/pagoda/multistage/MultiStageUpperProgram.java
@@ -15,6 +15,7 @@ import uk.ac.ox.cs.pagoda.util.Namespace;
15import uk.ac.ox.cs.pagoda.util.SparqlHelper; 15import uk.ac.ox.cs.pagoda.util.SparqlHelper;
16import uk.ac.ox.cs.pagoda.util.Timer; 16import uk.ac.ox.cs.pagoda.util.Timer;
17import uk.ac.ox.cs.pagoda.util.Utility; 17import uk.ac.ox.cs.pagoda.util.Utility;
18import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
18 19
19import java.io.*; 20import java.io.*;
20import java.util.*; 21import java.util.*;
@@ -376,7 +377,7 @@ public abstract class MultiStageUpperProgram {
376 return m_bottom.process(m_approxExist.convert(clause, originalDLClause, null)); 377 return m_bottom.process(m_approxExist.convert(clause, originalDLClause, null));
377 } 378 }
378 379
379 public Collection<DLClause> convertExist(DLClause clause, DLClause originalDLClause, List<AnswerTupleID> violationTuples) { 380 public Collection<DLClause> convertExist(DLClause clause, DLClause originalDLClause, Collection<Tuple<Individual>> violationTuples) {
380 return m_bottom.process(m_approxExist.convert(clause, originalDLClause, violationTuples)); 381 return m_bottom.process(m_approxExist.convert(clause, originalDLClause, violationTuples));
381 } 382 }
382 383
diff --git a/src/uk/ac/ox/cs/pagoda/multistage/Normalisation.java b/src/uk/ac/ox/cs/pagoda/multistage/Normalisation.java
index b31d138..c5482e7 100644
--- a/src/uk/ac/ox/cs/pagoda/multistage/Normalisation.java
+++ b/src/uk/ac/ox/cs/pagoda/multistage/Normalisation.java
@@ -7,6 +7,7 @@ import uk.ac.ox.cs.pagoda.approx.Clause;
7import uk.ac.ox.cs.pagoda.approx.Clausifier; 7import uk.ac.ox.cs.pagoda.approx.Clausifier;
8import uk.ac.ox.cs.pagoda.constraints.BottomStrategy; 8import uk.ac.ox.cs.pagoda.constraints.BottomStrategy;
9import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; 9import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist;
10import uk.ac.ox.cs.pagoda.rules.approximators.SkolemTermsManager;
10import uk.ac.ox.cs.pagoda.util.Namespace; 11import uk.ac.ox.cs.pagoda.util.Namespace;
11import uk.ac.ox.cs.pagoda.util.Utility; 12import uk.ac.ox.cs.pagoda.util.Utility;
12 13
@@ -102,7 +103,9 @@ public class Normalisation {
102 return ; 103 return ;
103 } 104 }
104 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate(); 105 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate();
105 AtomicConcept ac = getRightAuxiliaryConcept(alc, OverApproxExist.getNewIndividual(clause, 0)); 106 // TODO test
107// AtomicConcept ac = getRightAuxiliaryConcept(alc, OverApproxExist.getNewIndividual(clause, 0));
108 AtomicConcept ac = getRightAuxiliaryConcept(alc, SkolemTermsManager.getInstance().getFreshIndividual(clause, 0));
106 DLClause newClause; 109 DLClause newClause;
107 m_normClauses.add(DLClause.create(new Atom[] {Atom.create(ac, headAtom.getArgument(0)) }, clause.getBodyAtoms())); 110 m_normClauses.add(DLClause.create(new Atom[] {Atom.create(ac, headAtom.getArgument(0)) }, clause.getBodyAtoms()));
108 m_normClauses.add(newClause = DLClause.create(new Atom[] {Atom.create(alc, X)}, new Atom[] {Atom.create(ac, X)})); 111 m_normClauses.add(newClause = DLClause.create(new Atom[] {Atom.create(alc, X)}, new Atom[] {Atom.create(ac, X)}));
@@ -140,7 +143,8 @@ public class Normalisation {
140 } 143 }
141 } else { 144 } else {
142 AtLeastConcept alc = toAtLeastConcept((AtLeast) headAtom.getDLPredicate()); 145 AtLeastConcept alc = toAtLeastConcept((AtLeast) headAtom.getDLPredicate());
143 AtomicConcept ac = getRightAuxiliaryConcept(alc, OverApproxExist.getNewIndividual(clause, 0)); 146// AtomicConcept ac = getRightAuxiliaryConcept(alc, OverApproxExist.getNewIndividual(clause, 0));
147 AtomicConcept ac = getRightAuxiliaryConcept(alc, SkolemTermsManager.getInstance().getFreshIndividual(clause, 0));
144 newHeadAtoms[index] = Atom.create(ac, headAtom.getArgument(0)); 148 newHeadAtoms[index] = Atom.create(ac, headAtom.getArgument(0));
145 m_normClauses.add(newClause = DLClause.create(new Atom[] {Atom.create(alc, headAtom.getArgument(0))}, new Atom[] {newHeadAtoms[index]})); 149 m_normClauses.add(newClause = DLClause.create(new Atom[] {Atom.create(alc, headAtom.getArgument(0))}, new Atom[] {newHeadAtoms[index]}));
146 exist2original.put(newClause, clause); 150 exist2original.put(newClause, clause);
diff --git a/src/uk/ac/ox/cs/pagoda/multistage/ViolationTuple.java b/src/uk/ac/ox/cs/pagoda/multistage/ViolationTuple.java
new file mode 100644
index 0000000..129f5dd
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/multistage/ViolationTuple.java
@@ -0,0 +1,19 @@
1package uk.ac.ox.cs.pagoda.multistage;
2
3import org.semanticweb.HermiT.model.Individual;
4
5import java.util.ArrayList;
6
7/**
8 * Just a list of <tt>Individual</tt>s.
9 * */
10public class ViolationTuple extends ArrayList<Individual> {
11
12 public ViolationTuple() {
13 super();
14 }
15
16 public ViolationTuple(int size) {
17 super(size);
18 }
19}
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 244eb7a..fefb8b2 100644
--- a/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java
+++ b/src/uk/ac/ox/cs/pagoda/multistage/treatement/Pick4NegativeConcept.java
@@ -14,6 +14,8 @@ import uk.ac.ox.cs.pagoda.reasoner.light.RDFoxTripleManager;
14import uk.ac.ox.cs.pagoda.util.Namespace; 14import uk.ac.ox.cs.pagoda.util.Namespace;
15import uk.ac.ox.cs.pagoda.util.SparqlHelper; 15import uk.ac.ox.cs.pagoda.util.SparqlHelper;
16import uk.ac.ox.cs.pagoda.util.Utility; 16import uk.ac.ox.cs.pagoda.util.Utility;
17import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
18import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder;
17 19
18import java.util.*; 20import java.util.*;
19 21
@@ -99,7 +101,20 @@ public abstract class Pick4NegativeConcept implements Treatment {
99 } 101 }
100 else { 102 else {
101 Set<Atom> headAtoms = new HashSet<Atom>(); 103 Set<Atom> headAtoms = new HashSet<Atom>();
102 for (DLClause clause : program.convertExist(constraint, violation.getClause(), violation.getTuples())) { 104
105 ArrayList<Tuple<Individual>> violationTuples = new ArrayList<>(violation.getTuples().size());
106 for (int i = 0; i < violation.getTuples().size(); i++) {
107 AnswerTupleID answerTupleID = violation.getTuples().get(i);
108 TupleBuilder<Individual> tupleBuilder = new TupleBuilder<>();
109 for (int j = 0; j < answerTupleID.getArity(); j++) {
110 String rawTerm = tripleManager.getRawTerm(answerTupleID.getTerm(j));
111 Individual individual = Individual.create(rawTerm.substring(1, rawTerm.length()-1));
112 tupleBuilder.add(individual);
113 }
114 violationTuples.add(tupleBuilder.create());
115 }
116
117 for (DLClause clause : program.convertExist(constraint, violation.getClause(), violationTuples)) {
103 118
104 if (!DLClauseHelper.hasSubsetBodyAtoms(clause, constraint)) { 119 if (!DLClauseHelper.hasSubsetBodyAtoms(clause, constraint)) {
105 Utility.logError("There might be an error here... Cannot happen!!!"); 120 Utility.logError("There might be an error here... Cannot happen!!!");
diff --git a/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java
index 7c9562f..a7afa2e 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java
@@ -1,9 +1,10 @@
1package uk.ac.ox.cs.pagoda.rules; 1package uk.ac.ox.cs.pagoda.rules;
2 2
3import org.semanticweb.HermiT.model.DLClause; 3import org.semanticweb.HermiT.model.DLClause;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; 4import org.semanticweb.HermiT.model.Individual;
5import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; 5import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist;
6import uk.ac.ox.cs.pagoda.rules.approximators.TupleDependentApproximator; 6import uk.ac.ox.cs.pagoda.rules.approximators.TupleDependentApproximator;
7import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
7 8
8import java.util.Collection; 9import java.util.Collection;
9 10
@@ -19,7 +20,7 @@ public class ExistConstantApproximator implements TupleDependentApproximator {
19 } 20 }
20 21
21 @Override 22 @Override
22 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) { 23 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<Tuple<Individual>> violationTuples) {
23 return overApproxExist.convert(clause, originalClause); 24 return overApproxExist.convert(clause, originalClause);
24 } 25 }
25} 26}
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 8fc6b77..e53ae49 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java
@@ -1,8 +1,10 @@
1package uk.ac.ox.cs.pagoda.rules.approximators; 1package uk.ac.ox.cs.pagoda.rules.approximators;
2 2
3import org.semanticweb.HermiT.model.DLClause; 3import org.semanticweb.HermiT.model.DLClause;
4import org.semanticweb.HermiT.model.Individual;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; 5import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
5import uk.ac.ox.cs.pagoda.rules.ExistConstantApproximator; 6import uk.ac.ox.cs.pagoda.rules.ExistConstantApproximator;
7import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
6 8
7import java.util.*; 9import java.util.*;
8 10
@@ -33,7 +35,7 @@ public class LimitedSkolemisationApproximator implements TupleDependentApproxima
33 } 35 }
34 36
35 @Override 37 @Override
36 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) { 38 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<Tuple<Individual>> violationTuples) {
37 switch (clause.getHeadLength()) { 39 switch (clause.getHeadLength()) {
38 case 1: 40 case 1:
39 return overApprox(clause, originalClause, violationTuples); 41 return overApprox(clause, originalClause, violationTuples);
@@ -48,26 +50,26 @@ public class LimitedSkolemisationApproximator implements TupleDependentApproxima
48 50
49 } 51 }
50 52
51 private Collection<DLClause> overApprox(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) { 53 private Collection<DLClause> overApprox(DLClause clause, DLClause originalClause, Collection<Tuple<Individual>> violationTuples) {
52 ArrayList<DLClause> result = new ArrayList<>(); 54 ArrayList<DLClause> result = new ArrayList<>();
53 55
54 for (AnswerTupleID violationTuple : violationTuples) 56 for (Tuple<Individual> violationTuple : violationTuples)
55 if (getDepth(violationTuple) > maxTermDepth) 57 if (getDepth(violationTuple) > maxTermDepth)
56 result.addAll(alternativeApproximator.convert(clause, originalClause, null)); 58 result.addAll(alternativeApproximator.convert(clause, originalClause, null));
57 else 59 else
58 result.add(getInstantiatedSkolemisation(clause, originalClause, violationTuple)); 60 result.add(getGroundSkolemisation(clause, originalClause, violationTuple));
59 61
60 return result; 62 return result;
61 } 63 }
62 64
63 65
64 private DLClause getInstantiatedSkolemisation(DLClause clause, DLClause originalClause, AnswerTupleID violationTuple) { 66 private DLClause getGroundSkolemisation(DLClause clause, DLClause originalClause, Tuple<Individual> violationTuple) {
65 // TODO implement 67 // TODO implement
66 // filter the violation tuples appearing on both the sides of the rule 68 // filter the violation tuples appearing on both the sides of the rule
67 return null; 69 return null;
68 } 70 }
69 71
70 private int getDepth(AnswerTupleID violationTuple) { 72 private int getDepth(Tuple<Individual> violationTuple) {
71 if (!mapIndividualsToDepth.containsKey(violationTuple)) return 0; 73 if (!mapIndividualsToDepth.containsKey(violationTuple)) return 0;
72 return mapIndividualsToDepth.get(violationTuple); 74 return mapIndividualsToDepth.get(violationTuple);
73 } 75 }
diff --git a/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java b/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java
index e0bafe0..d71c472 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java
@@ -2,27 +2,15 @@ package uk.ac.ox.cs.pagoda.rules.approximators;
2 2
3import org.semanticweb.HermiT.model.*; 3import org.semanticweb.HermiT.model.*;
4import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; 4import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
5import uk.ac.ox.cs.pagoda.util.Namespace;
6 5
7import java.util.*; 6import java.util.Collection;
7import java.util.Iterator;
8import java.util.LinkedList;
8 9
9public class OverApproxExist implements Approximator { 10public class OverApproxExist implements Approximator {
10 11
11 public static final String negativeSuffix = "_neg"; 12 public static final String negativeSuffix = "_neg";
12 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
13 private static final Variable X = Variable.create("X"); 13 private static final Variable X = Variable.create("X");
14 //DEBUG
15 public static Collection<String> createdIndividualIRIs = new HashSet<>();
16 private static int individualCounter = 0;
17 private static Map<DLClause, Integer> individualNumber = new HashMap<DLClause, Integer>();
18
19 private static int noOfExistential(DLClause originalClause) {
20 int no = 0;
21 for (Atom atom: originalClause.getHeadAtoms())
22 if (atom.getDLPredicate() instanceof AtLeast)
23 no += ((AtLeast) atom.getDLPredicate()).getNumber();
24 return no;
25 }
26 14
27 private static int indexOfExistential(Atom headAtom, DLClause originalClause) { 15 private static int indexOfExistential(Atom headAtom, DLClause originalClause) {
28 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1; 16 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1;
@@ -65,36 +53,6 @@ public class OverApproxExist implements Approximator {
65 return null; 53 return null;
66 } 54 }
67 55
68 public static int getNumberOfSkolemisedIndividual() {
69 return individualCounter;
70 }
71 //DEBUG
72
73 public static Individual getNewIndividual(DLClause originalClause, int offset) {
74 Individual ret;
75 int individualID;
76 if (individualNumber.containsKey(originalClause)) {
77 individualID = individualNumber.get(originalClause) + offset;
78 ret = Individual.create(skolemisedIndividualPrefix + individualID);
79 }
80 else {
81 individualNumber.put(originalClause, individualCounter);
82 individualID = individualCounter + offset;
83 ret = Individual.create(skolemisedIndividualPrefix + individualID);
84 individualCounter += noOfExistential(originalClause);
85 }
86 return ret;
87 }
88
89 public static int indexOfSkolemisedIndividual(Atom atom) {
90 Term t;
91 for (int index = 0; index < atom.getArity(); ++index) {
92 t = atom.getArgument(index);
93 if (t instanceof Individual && ((Individual) t).getIRI().contains(skolemisedIndividualPrefix)) return index;
94 }
95 return -1;
96 }
97
98 @Override 56 @Override
99 public Collection<DLClause> convert(DLClause clause, DLClause originalClause) { 57 public Collection<DLClause> convert(DLClause clause, DLClause originalClause) {
100 Collection<DLClause> ret; 58 Collection<DLClause> ret;
@@ -140,7 +98,8 @@ public class OverApproxExist implements Approximator {
140 98
141 int card = atLeastConcept.getNumber(); 99 int card = atLeastConcept.getNumber();
142 Individual[] individuals = new Individual[card]; 100 Individual[] individuals = new Individual[card];
143 for (int i = 0; i < card; ++i) individuals[i] = getNewIndividual(originalClause, offset + i); 101 SkolemTermsManager termsManager = SkolemTermsManager.getInstance();
102 for (int i = 0; i < card; ++i) individuals[i] = termsManager.getFreshIndividual(originalClause, offset + i);
144 103
145 for (int i = 0; i < card; ++i) { 104 for (int i = 0; i < card; ++i) {
146 if (atomicConcept != null) 105 if (atomicConcept != null)
diff --git a/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsDispenser.java b/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsDispenser.java
deleted file mode 100644
index a920ec5..0000000
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsDispenser.java
+++ /dev/null
@@ -1,74 +0,0 @@
1package uk.ac.ox.cs.pagoda.rules.approximators;
2
3import org.semanticweb.HermiT.model.AtLeast;
4import org.semanticweb.HermiT.model.Atom;
5import org.semanticweb.HermiT.model.DLClause;
6import org.semanticweb.HermiT.model.Individual;
7import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
8import uk.ac.ox.cs.pagoda.util.Namespace;
9
10import java.util.HashMap;
11import java.util.Map;
12
13/**
14 * If you need a Skolem term (i.e. fresh individual), ask this class.
15 */
16public class SkolemTermsDispenser {
17
18 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
19 private static SkolemTermsDispenser skolemTermsDispenser;
20 private int individualCounter = 0;
21 private Map<DLClause, Integer> termNumber = new HashMap<>();
22 private Map<SkolemTermId, Integer> mapTermToDepth = new HashMap<>();
23 private int dependenciesCounter = 0;
24 private Map<AnswerTupleID, Integer> mapDependencyToId = new HashMap<>();
25
26 private SkolemTermsDispenser() {
27 }
28
29 public static SkolemTermsDispenser getInstance() {
30 if (skolemTermsDispenser == null) skolemTermsDispenser = new SkolemTermsDispenser();
31 return skolemTermsDispenser;
32 }
33
34 private int getDependencyId(AnswerTupleID answerTupleID) {
35 if (mapDependencyToId.containsKey(answerTupleID)) return mapDependencyToId.get(answerTupleID);
36 else return mapDependencyToId.put(answerTupleID, dependenciesCounter++);
37 }
38
39 public Individual getNewIndividual(DLClause originalClause, int offset, AnswerTupleID dependency) {
40 if (!termNumber.containsKey(originalClause)) {
41 termNumber.put(originalClause, individualCounter);
42 individualCounter += noOfExistential(originalClause);
43 }
44 if (!mapDependencyToId.containsKey(dependency)) {
45 mapDependencyToId.put(dependency, dependenciesCounter++);
46 }
47
48 SkolemTermId termId = new SkolemTermId(termNumber.get(originalClause) + offset, getDependencyId(dependency));
49 return Individual.create(skolemisedIndividualPrefix + termId);
50 }
51
52 private int noOfExistential(DLClause originalClause) {
53 int no = 0;
54 for (Atom atom : originalClause.getHeadAtoms())
55 if (atom.getDLPredicate() instanceof AtLeast)
56 no += ((AtLeast) atom.getDLPredicate()).getNumber();
57 return no;
58 }
59
60 private class SkolemTermId {
61 private final int idBase;
62 private final int idOffset;
63
64 private SkolemTermId(int idBase, int idOffset) {
65 this.idBase = idBase;
66 this.idOffset = idOffset;
67 }
68
69 @Override
70 public String toString() {
71 return idBase + "_" + idOffset;
72 }
73 }
74}
diff --git a/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsManager.java b/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsManager.java
new file mode 100644
index 0000000..0413e65
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/SkolemTermsManager.java
@@ -0,0 +1,116 @@
1package uk.ac.ox.cs.pagoda.rules.approximators;
2
3import org.semanticweb.HermiT.model.*;
4import uk.ac.ox.cs.pagoda.util.Namespace;
5import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
6
7import java.util.HashMap;
8import java.util.Map;
9
10/**
11 * If you need a Skolem term (i.e. fresh individual), ask this class.
12 */
13public class SkolemTermsManager {
14
15 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
16
17 private static SkolemTermsManager skolemTermsManager;
18
19 private int individualCounter = 0;
20 private Map<DLClause, Integer> termNumber = new HashMap<>();
21 private Map<Individual, Integer> mapIndividualToDepth = new HashMap<>();
22 private int dependenciesCounter = 0;
23
24 // replace with hashcode. in case of collision you get only a different upper bound model.
25 private Map<Tuple<Individual>, Integer> mapDependencyToId = new HashMap<>();
26
27 /**
28 * Get a fresh Individual, unique for the clause, the offset and the dependency.
29 * */
30 public Individual getFreshIndividual(DLClause originalClause, int offset, Tuple<Individual> dependency) {
31 if (!termNumber.containsKey(originalClause)) {
32 termNumber.put(originalClause, individualCounter);
33 individualCounter += noOfExistential(originalClause);
34 }
35 if (!mapDependencyToId.containsKey(dependency)) {
36 mapDependencyToId.put(dependency, dependenciesCounter++);
37 }
38
39 String termId = termNumber.get(originalClause) + offset + "_" + mapDependencyToId(dependency);
40 Individual newIndividual = Individual.create(skolemisedIndividualPrefix + termId);
41
42 int depth = 0;
43 for (Individual individual : dependency)
44 depth = Integer.max(depth, mapIndividualToDepth(individual));
45 mapIndividualToDepth.put(newIndividual, depth);
46
47 return newIndividual;
48 }
49
50 /**
51 * Get a fresh Individual, unique for the clause and the offset.
52 * */
53 public Individual getFreshIndividual(DLClause originalClause, int offset) {
54 if (!termNumber.containsKey(originalClause)) {
55 termNumber.put(originalClause, individualCounter);
56 individualCounter += noOfExistential(originalClause);
57 }
58
59 String termId = "" + termNumber.get(originalClause) + offset;
60 Individual newIndividual = Individual.create(skolemisedIndividualPrefix + termId);
61 mapIndividualToDepth.put(newIndividual, 0);
62
63 return newIndividual;
64 }
65
66 /**
67 * Get the depth of a term.
68 * <p>
69 * The term must have been generated by this manager.
70 * */
71 public int getDepth(Individual individual) {
72 return mapIndividualToDepth(individual);
73 }
74
75 /**
76 * Get the number of individuals generated by this manager.
77 * */
78 public int getNumberOfSkolemisedIndividual() {
79 return mapIndividualToDepth.keySet().size();
80 }
81
82 public static int indexOfSkolemisedIndividual(Atom atom) {
83 Term t;
84 for (int index = 0; index < atom.getArity(); ++index) {
85 t = atom.getArgument(index);
86 if (t instanceof Individual && ((Individual) t).getIRI().contains(skolemisedIndividualPrefix)) return index;
87 }
88 return -1;
89 }
90
91 private SkolemTermsManager() {
92 }
93
94 public static SkolemTermsManager getInstance() {
95 if (skolemTermsManager == null) skolemTermsManager = new SkolemTermsManager();
96 return skolemTermsManager;
97 }
98
99 private int mapDependencyToId(Tuple<Individual> dependency) {
100 if (mapDependencyToId.containsKey(dependency)) return mapDependencyToId.get(dependency);
101 else return mapDependencyToId.put(dependency, dependenciesCounter++);
102 }
103
104 private int mapIndividualToDepth(Individual dependency) {
105 if (mapIndividualToDepth.containsKey(dependency)) return mapIndividualToDepth.get(dependency);
106 else return 0;
107 }
108
109 private int noOfExistential(DLClause originalClause) {
110 int no = 0;
111 for (Atom atom : originalClause.getHeadAtoms())
112 if (atom.getDLPredicate() instanceof AtLeast)
113 no += ((AtLeast) atom.getDLPredicate()).getNumber();
114 return no;
115 }
116}
diff --git a/src/uk/ac/ox/cs/pagoda/rules/approximators/TupleDependentApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/approximators/TupleDependentApproximator.java
index 1a729e5..c99a1ad 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/TupleDependentApproximator.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/TupleDependentApproximator.java
@@ -1,16 +1,19 @@
1package uk.ac.ox.cs.pagoda.rules.approximators; 1package uk.ac.ox.cs.pagoda.rules.approximators;
2 2
3import org.semanticweb.HermiT.model.DLClause; 3import org.semanticweb.HermiT.model.DLClause;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; 4import org.semanticweb.HermiT.model.Individual;
5import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
5 6
6import java.util.Collection; 7import java.util.Collection;
7 8
8/** 9/**
9 * It approximates rules according to a specific instantiation of the body. 10 * It can approximate clauses according to a collection of tuples of individuals.
11 * <p>
12 * In particular it can be used to approximate rules given some body instantiations.
10 */ 13 */
11public interface TupleDependentApproximator { 14public interface TupleDependentApproximator {
12 15
13 Collection<DLClause> convert(DLClause clause, 16 Collection<DLClause> convert(DLClause clause,
14 DLClause originalClause, 17 DLClause originalClause,
15 Collection<AnswerTupleID> violationTuples); 18 Collection<Tuple<Individual>> individualsTuples);
16} 19}
diff --git a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java
index 331ad12..b169053 100644
--- a/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java
+++ b/src/uk/ac/ox/cs/pagoda/tracking/TrackingRuleEncoderDisj.java
@@ -4,7 +4,7 @@ import org.semanticweb.HermiT.model.*;
4import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper; 4import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
5import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine; 5import uk.ac.ox.cs.pagoda.reasoner.light.BasicQueryEngine;
6import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram; 6import uk.ac.ox.cs.pagoda.rules.UpperDatalogProgram;
7import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist; 7import uk.ac.ox.cs.pagoda.rules.approximators.SkolemTermsManager;
8import uk.ac.ox.cs.pagoda.util.Namespace; 8import uk.ac.ox.cs.pagoda.util.Namespace;
9 9
10import java.util.*; 10import java.util.*;
@@ -22,8 +22,9 @@ public abstract class TrackingRuleEncoderDisj extends TrackingRuleEncoderWithGap
22 */ 22 */
23 protected void processDisjunctiveRules() { 23 protected void processDisjunctiveRules() {
24 Map<Atom, Collection<DLClause>> auxiliaryAtoms = new HashMap<Atom, Collection<DLClause>>(); 24 Map<Atom, Collection<DLClause>> auxiliaryAtoms = new HashMap<Atom, Collection<DLClause>>();
25 Map<Individual, Collection<DLClause>> skolemisedAtoms = new HashMap<Individual, Collection<DLClause>>(); 25 Map<Individual, Collection<DLClause>> skolemisedAtoms = new HashMap<Individual, Collection<DLClause>>();
26 26 SkolemTermsManager termsManager = SkolemTermsManager.getInstance();
27
27 for (Map.Entry<DLClause, Collection<DLClause>> entry: disjunctiveRules.entrySet()) { 28 for (Map.Entry<DLClause, Collection<DLClause>> entry: disjunctiveRules.entrySet()) {
28 DLClause original = entry.getKey(); 29 DLClause original = entry.getKey();
29 Collection<DLClause> overClauses = entry.getValue(); 30 Collection<DLClause> overClauses = entry.getValue();
@@ -33,7 +34,7 @@ public abstract class TrackingRuleEncoderDisj extends TrackingRuleEncoderWithGap
33 DLClause subClause = iter.next(); 34 DLClause subClause = iter.next();
34 if (DLClauseHelper.hasSubsetBodyAtoms(subClause, original)) { 35 if (DLClauseHelper.hasSubsetBodyAtoms(subClause, original)) {
35 Atom headAtom = subClause.getHeadAtom(0); 36 Atom headAtom = subClause.getHeadAtom(0);
36 if ((index = OverApproxExist.indexOfSkolemisedIndividual(headAtom)) != -1) { 37 if ((index = SkolemTermsManager.indexOfSkolemisedIndividual(headAtom)) != -1) {
37 Individual i = (Individual) headAtom.getArgument(index); 38 Individual i = (Individual) headAtom.getArgument(index);
38 Collection<DLClause> clauses = skolemisedAtoms.get(i); 39 Collection<DLClause> clauses = skolemisedAtoms.get(i);
39 if (clauses == null) { 40 if (clauses == null) {
@@ -55,7 +56,7 @@ public abstract class TrackingRuleEncoderDisj extends TrackingRuleEncoderWithGap
55 Collection<DLClause> clauses = new HashSet<DLClause>(); 56 Collection<DLClause> clauses = new HashSet<DLClause>();
56 Individual[] individuals = new Individual[alc.getNumber()]; 57 Individual[] individuals = new Individual[alc.getNumber()];
57 for (int i = 0; i < alc.getNumber(); ++i) { 58 for (int i = 0; i < alc.getNumber(); ++i) {
58 individuals[i] = OverApproxExist.getNewIndividual(original, i); 59 individuals[i] = termsManager.getFreshIndividual(original, i);
59 clauses.addAll(skolemisedAtoms.get(individuals[i])); 60 clauses.addAll(skolemisedAtoms.get(individuals[i]));
60 } 61 }
61 auxiliaryAtoms.put(getAuxiliaryAtom(original, headAtom, individuals), clauses); 62 auxiliaryAtoms.put(getAuxiliaryAtom(original, headAtom, individuals), clauses);
diff --git a/src/uk/ac/ox/cs/pagoda/util/tuples/Tuple.java b/src/uk/ac/ox/cs/pagoda/util/tuples/Tuple.java
new file mode 100644
index 0000000..3e72748
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/util/tuples/Tuple.java
@@ -0,0 +1,44 @@
1package uk.ac.ox.cs.pagoda.util.tuples;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.Spliterator;
6import java.util.function.Consumer;
7
8public class Tuple<T> implements Iterable<T> {
9
10 final ArrayList<T> elements = new ArrayList<>();
11
12 Tuple() { }
13
14 public Tuple(T... elements) {
15 for(T t: elements) {
16 this.elements.add(t);
17 }
18 }
19
20 public Tuple(Iterable<T> iterable) {
21 for (T t : iterable) {
22 this.elements.add(t);
23 }
24 }
25
26 public T get(int i) {
27 return elements.get(i);
28 }
29
30 @Override
31 public Iterator<T> iterator() {
32 return elements.iterator();
33 }
34
35 @Override
36 public void forEach(Consumer<? super T> action) {
37 elements.forEach(action);
38 }
39
40 @Override
41 public Spliterator<T> spliterator() {
42 return elements.spliterator();
43 }
44}
diff --git a/src/uk/ac/ox/cs/pagoda/util/tuples/TupleBuilder.java b/src/uk/ac/ox/cs/pagoda/util/tuples/TupleBuilder.java
new file mode 100644
index 0000000..aacd15e
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/util/tuples/TupleBuilder.java
@@ -0,0 +1,25 @@
1package uk.ac.ox.cs.pagoda.util.tuples;
2
3/**
4 * Allows to create an immutable <tt>Tuple</tt> in a non-atomic way.
5 * It can create only one <tt>Tuple</tt>.
6 * */
7public class TupleBuilder<T> {
8
9 private Tuple tuple = new Tuple();
10
11 private boolean building = true;
12
13 public boolean add(T t) {
14 if(building) tuple.elements.add(t);
15 return building;
16 }
17
18 public Tuple<T> create() {
19 if(building) {
20 building = false;
21 return tuple;
22 }
23 return null;
24 }
25}