aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/rules
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/rules')
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java23
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/LimitedSkolemisationApproximator.java72
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java104
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/TupleDependentApproximator.java16
4 files changed, 162 insertions, 53 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java
new file mode 100644
index 0000000..74c531f
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/ExistConstantApproximator.java
@@ -0,0 +1,23 @@
1package uk.ac.ox.cs.pagoda.rules;
2
3import org.semanticweb.HermiT.model.DLClause;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
5
6import java.util.Collection;
7
8/**
9 * A wrapper for <tt>OverApproxExist</tt>.
10 * */
11public class ExistConstantApproximator implements TupleDependentApproximator {
12
13 private final OverApproxExist overApproxExist;
14
15 public ExistConstantApproximator() {
16 overApproxExist = new OverApproxExist();
17 }
18
19 @Override
20 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) {
21 return overApproxExist.convert(clause, originalClause);
22 }
23}
diff --git a/src/uk/ac/ox/cs/pagoda/rules/LimitedSkolemisationApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/LimitedSkolemisationApproximator.java
new file mode 100644
index 0000000..284edd2
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/LimitedSkolemisationApproximator.java
@@ -0,0 +1,72 @@
1package uk.ac.ox.cs.pagoda.rules;
2
3import org.semanticweb.HermiT.model.DLClause;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
5
6import java.util.*;
7
8/**
9 * Approximates existential rules by a limited form of Skolemisation.
10 * <p>
11 * Given a rule and a grounding substitution,
12 * it Skolemises the rule if
13 * all the terms in the substitution have depth less than a given depth,
14 * otherwise it approximates using an alternative <tt>TupleDependentApproximator</tt>.
15 *
16 * */
17public class LimitedSkolemisationApproximator implements TupleDependentApproximator {
18
19 private final int maxTermDepth;
20 private final TupleDependentApproximator alternativeApproximator;
21
22 private Map<AnswerTupleID, Integer> mapIndividualsToDepth;
23
24 public LimitedSkolemisationApproximator(int maxTermDepth) {
25 this(maxTermDepth, new ExistConstantApproximator());
26 }
27
28 public LimitedSkolemisationApproximator(int maxTermDepth, TupleDependentApproximator alternativeApproximator) {
29 this.maxTermDepth = maxTermDepth;
30 this.alternativeApproximator = alternativeApproximator;
31 this.mapIndividualsToDepth = new HashMap<>();
32 }
33
34 @Override
35 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) {
36 switch (clause.getHeadLength()) {
37 case 1:
38 return overApprox(clause, originalClause, violationTuples);
39 case 0:
40 return Arrays.asList(clause);
41 default:
42 ArrayList<DLClause> result = new ArrayList<>();
43 // TODO implement
44 return result;
45 }
46
47
48 }
49
50 private Collection<DLClause> overApprox(DLClause clause, DLClause originalClause, Collection<AnswerTupleID> violationTuples) {
51 ArrayList<DLClause> result = new ArrayList<>();
52
53 for (AnswerTupleID violationTuple : violationTuples)
54 if (getDepth(violationTuple) > maxTermDepth)
55 result.addAll(alternativeApproximator.convert(clause, originalClause, null));
56 else
57 result.add(getInstantiatedSkolemisation(clause, originalClause, violationTuple));
58
59 return result;
60 }
61
62
63 private DLClause getInstantiatedSkolemisation(DLClause clause, DLClause originalClause, AnswerTupleID violationTuple) {
64 // TODO implement
65 return null;
66 }
67
68 private int getDepth(AnswerTupleID violationTuple) {
69 if (!mapIndividualsToDepth.containsKey(violationTuple)) return 0;
70 return mapIndividualsToDepth.get(violationTuple);
71 }
72}
diff --git a/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java b/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
index 2ff1673..1099acf 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/OverApproxExist.java
@@ -8,87 +8,67 @@ import java.util.*;
8 8
9public class OverApproxExist implements Approximator { 9public class OverApproxExist implements Approximator {
10 10
11 @Override 11 public static final String negativeSuffix = "_neg";
12 public Collection<DLClause> convert(DLClause clause, DLClause originalClause) { 12 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
13 Collection<DLClause> ret; 13 private static final Variable X = Variable.create("X");
14 switch (clause.getHeadLength()) { 14 private static int individualCounter = 0;
15 case 1: 15 private static Map<DLClause, Integer> individualNumber = new HashMap<DLClause, Integer>();
16 return overApprox(clause.getHeadAtom(0), clause.getBodyAtoms(), originalClause); 16
17 case 0:
18 ret = new LinkedList<DLClause>();
19 ret.add(clause);
20 return ret;
21 default:
22 ret = new LinkedList<DLClause>();
23 for (Iterator<DLClause> iter = new DisjunctiveHeads(clause, originalClause); iter.hasNext(); )
24 ret.add(iter.next());
25 return ret;
26 }
27 }
28
29 private static int noOfExistential(DLClause originalClause) { 17 private static int noOfExistential(DLClause originalClause) {
30 int no = 0; 18 int no = 0;
31 for (Atom atom: originalClause.getHeadAtoms()) 19 for (Atom atom: originalClause.getHeadAtoms())
32 if (atom.getDLPredicate() instanceof AtLeast) 20 if (atom.getDLPredicate() instanceof AtLeast)
33 no += ((AtLeast) atom.getDLPredicate()).getNumber(); 21 no += ((AtLeast) atom.getDLPredicate()).getNumber();
34 return no; 22 return no;
35 } 23 }
36 24
37 private static int indexOfExistential(Atom headAtom, DLClause originalClause) { 25 private static int indexOfExistential(Atom headAtom, DLClause originalClause) {
38 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1; 26 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1;
39 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate(); 27 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate();
40 if (alc.getToConcept() instanceof AtomicConcept) { 28 if (alc.getToConcept() instanceof AtomicConcept) {
41 AtomicConcept ac = (AtomicConcept) alc.getToConcept(); 29 AtomicConcept ac = (AtomicConcept) alc.getToConcept();
42 if (ac.getIRI().endsWith(negativeSuffix)) { 30 if (ac.getIRI().endsWith(negativeSuffix)) {
43 alc = AtLeastConcept.create(alc.getNumber(), alc.getOnRole(), AtomicNegationConcept.create(getNegationConcept(ac))); 31 alc = AtLeastConcept.create(alc.getNumber(), alc.getOnRole(), AtomicNegationConcept.create(getNegationConcept(ac)));
44 headAtom = Atom.create(alc, headAtom.getArgument(0)); 32 headAtom = Atom.create(alc, headAtom.getArgument(0));
45 } 33 }
46 } 34 }
47 35
48 int index = 0; 36 int index = 0;
49 for (Atom atom: originalClause.getHeadAtoms()) { 37 for (Atom atom: originalClause.getHeadAtoms()) {
50 if (atom.equals(headAtom)) 38 if (atom.equals(headAtom))
51 return index; 39 return index;
52 if (atom.getDLPredicate() instanceof AtLeast) 40 if (atom.getDLPredicate() instanceof AtLeast)
53 index += ((AtLeast) atom.getDLPredicate()).getNumber(); 41 index += ((AtLeast) atom.getDLPredicate()).getNumber();
54 } 42 }
55 return -1; 43 return -1;
56 } 44 }
57
58 private static final Variable X = Variable.create("X");
59 public static final String negativeSuffix = "_neg";
60 45
61 public static AtomicConcept getNegationConcept(DLPredicate p) { 46 public static AtomicConcept getNegationConcept(DLPredicate p) {
62 if (p.equals(AtomicConcept.THING)) return AtomicConcept.NOTHING; 47 if (p.equals(AtomicConcept.THING)) return AtomicConcept.NOTHING;
63 if (p.equals(AtomicConcept.NOTHING)) return AtomicConcept.THING; 48 if (p.equals(AtomicConcept.NOTHING)) return AtomicConcept.THING;
64 49
65 if (p instanceof AtomicConcept) { 50 if (p instanceof AtomicConcept) {
66 String iri = ((AtomicConcept) p).getIRI(); 51 String iri = ((AtomicConcept) p).getIRI();
67 if (iri.endsWith(negativeSuffix)) 52 if (iri.endsWith(negativeSuffix))
68 iri = iri.substring(0, iri.length() - 4); 53 iri = iri.substring(0, iri.length() - 4);
69 else 54 else
70 iri += negativeSuffix; 55 iri += negativeSuffix;
71 56
72 return AtomicConcept.create(iri); 57 return AtomicConcept.create(iri);
73 } 58 }
74 if (p instanceof AtLeastConcept) { 59 if (p instanceof AtLeastConcept) {
75 // FIXME !!! here 60 // FIXME !!! here
76 return null; 61 return null;
77 } 62 }
78 return null; 63 return null;
79 } 64 }
80 65
81 public static final String skolemisedIndividualPrefix = Namespace.PAGODA_ANONY + "individual";
82
83 private static int individualCounter = 0;
84 private static Map<DLClause, Integer> individualNumber = new HashMap<DLClause, Integer>();
85
86 public static int getNumberOfSkolemisedIndividual() { 66 public static int getNumberOfSkolemisedIndividual() {
87 return individualCounter; 67 return individualCounter;
88 } 68 }
89 69
90 public static Individual getNewIndividual(DLClause originalClause, int offset) { 70 public static Individual getNewIndividual(DLClause originalClause, int offset) {
91 Individual ret; 71 Individual ret;
92 if (individualNumber.containsKey(originalClause)) { 72 if (individualNumber.containsKey(originalClause)) {
93 ret = Individual.create(skolemisedIndividualPrefix + (individualNumber.get(originalClause) + offset)); 73 ret = Individual.create(skolemisedIndividualPrefix + (individualNumber.get(originalClause) + offset));
94 } 74 }
@@ -97,16 +77,34 @@ public class OverApproxExist implements Approximator {
97 ret = Individual.create(skolemisedIndividualPrefix + (individualCounter + offset)); 77 ret = Individual.create(skolemisedIndividualPrefix + (individualCounter + offset));
98 individualCounter += noOfExistential(originalClause); 78 individualCounter += noOfExistential(originalClause);
99 } 79 }
100 return ret; 80 return ret;
101 } 81 }
102 82
103 public static int indexOfSkolemisedIndividual(Atom atom) { 83 public static int indexOfSkolemisedIndividual(Atom atom) {
104 Term t; 84 Term t;
105 for (int index = 0; index < atom.getArity(); ++index) { 85 for (int index = 0; index < atom.getArity(); ++index) {
106 t = atom.getArgument(index); 86 t = atom.getArgument(index);
107 if (t instanceof Individual && ((Individual) t).getIRI().contains(skolemisedIndividualPrefix)) return index; 87 if (t instanceof Individual && ((Individual) t).getIRI().contains(skolemisedIndividualPrefix)) return index;
108 } 88 }
109 return -1; 89 return -1;
90 }
91
92 @Override
93 public Collection<DLClause> convert(DLClause clause, DLClause originalClause) {
94 Collection<DLClause> ret;
95 switch (clause.getHeadLength()) {
96 case 1:
97 return overApprox(clause.getHeadAtom(0), clause.getBodyAtoms(), originalClause);
98 case 0:
99 ret = new LinkedList<DLClause>();
100 ret.add(clause);
101 return ret;
102 default:
103 ret = new LinkedList<DLClause>();
104 for (Iterator<DLClause> iter = new DisjunctiveHeads(clause, originalClause); iter.hasNext(); )
105 ret.add(iter.next());
106 return ret;
107 }
110 } 108 }
111 109
112 public Collection<DLClause> overApprox(Atom headAtom, Atom[] bodyAtoms, DLClause originalClause) { 110 public Collection<DLClause> overApprox(Atom headAtom, Atom[] bodyAtoms, DLClause originalClause) {
@@ -123,7 +121,7 @@ public class OverApproxExist implements Approximator {
123 AtomicConcept atomicConcept = null; 121 AtomicConcept atomicConcept = null;
124 122
125 if (concept instanceof AtomicNegationConcept) { 123 if (concept instanceof AtomicNegationConcept) {
126 // is this already in MultiStageUpperProgram? 124 // TODO CHECK: is this already in MultiStageUpperProgram?
127 Atom atom1 = Atom.create(atomicConcept = ((AtomicNegationConcept) concept).getNegatedAtomicConcept(), X); 125 Atom atom1 = Atom.create(atomicConcept = ((AtomicNegationConcept) concept).getNegatedAtomicConcept(), X);
128 Atom atom2 = Atom.create(atomicConcept = getNegationConcept(atomicConcept), X); 126 Atom atom2 = Atom.create(atomicConcept = getNegationConcept(atomicConcept), X);
129 ret.add(DLClause.create(new Atom[0], new Atom[] {atom1, atom2})); 127 ret.add(DLClause.create(new Atom[0], new Atom[] {atom1, atom2}));
diff --git a/src/uk/ac/ox/cs/pagoda/rules/TupleDependentApproximator.java b/src/uk/ac/ox/cs/pagoda/rules/TupleDependentApproximator.java
new file mode 100644
index 0000000..63057c4
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/TupleDependentApproximator.java
@@ -0,0 +1,16 @@
1package uk.ac.ox.cs.pagoda.rules;
2
3import org.semanticweb.HermiT.model.DLClause;
4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
5
6import java.util.Collection;
7
8/**
9 * It approximates rules according to a specific instantiation of the body.
10 */
11public interface TupleDependentApproximator {
12
13 Collection<DLClause> convert(DLClause clause,
14 DLClause originalClause,
15 Collection<AnswerTupleID> violationTuples);
16}