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/approximators/LimitedSkolemisationApproximator.java116
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java2
2 files changed, 97 insertions, 21 deletions
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 e53ae49..4444c00 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/LimitedSkolemisationApproximator.java
@@ -1,26 +1,29 @@
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.*;
4import org.semanticweb.HermiT.model.Individual;
5import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID; 4import uk.ac.ox.cs.pagoda.multistage.AnswerTupleID;
5import uk.ac.ox.cs.pagoda.multistage.MultiStageUpperProgram;
6import uk.ac.ox.cs.pagoda.rules.ExistConstantApproximator; 6import uk.ac.ox.cs.pagoda.rules.ExistConstantApproximator;
7import uk.ac.ox.cs.pagoda.util.tuples.Tuple; 7import uk.ac.ox.cs.pagoda.util.tuples.Tuple;
8import uk.ac.ox.cs.pagoda.util.tuples.TupleBuilder;
8 9
9import java.util.*; 10import java.util.*;
10 11
11/** 12/**
12 * Approximates existential rules by a limited form of Skolemisation. 13 * Approximates existential rules through a limited form of Skolemisation.
13 * <p> 14 * <p>
14 * Given a rule and a grounding substitution, 15 * Given a rule and a ground substitution,
15 * it Skolemises the rule if 16 * it Skolemises the rule
16 * all the terms in the substitution have depth less than a given depth, 17 * if all the terms in the substitution have depth less than a given depth,
17 * otherwise it approximates using an alternative <tt>TupleDependentApproximator</tt>. 18 * otherwise it approximates using an alternative <tt>TupleDependentApproximator</tt>.
18 *
19 * */ 19 * */
20public class LimitedSkolemisationApproximator implements TupleDependentApproximator { 20public class LimitedSkolemisationApproximator implements TupleDependentApproximator {
21 21
22 private static final Atom[] EMPTY_BODY = new Atom[0];
23
22 private final int maxTermDepth; 24 private final int maxTermDepth;
23 private final TupleDependentApproximator alternativeApproximator; 25 private final TupleDependentApproximator alternativeApproximator;
26 private final SkolemTermsManager skolemTermsManager;
24 27
25 private Map<AnswerTupleID, Integer> mapIndividualsToDepth; 28 private Map<AnswerTupleID, Integer> mapIndividualsToDepth;
26 29
@@ -32,19 +35,21 @@ public class LimitedSkolemisationApproximator implements TupleDependentApproxima
32 this.maxTermDepth = maxTermDepth; 35 this.maxTermDepth = maxTermDepth;
33 this.alternativeApproximator = alternativeApproximator; 36 this.alternativeApproximator = alternativeApproximator;
34 this.mapIndividualsToDepth = new HashMap<>(); 37 this.mapIndividualsToDepth = new HashMap<>();
38 this.skolemTermsManager = SkolemTermsManager.getInstance();
35 } 39 }
36 40
37 @Override 41 @Override
38 public Collection<DLClause> convert(DLClause clause, DLClause originalClause, Collection<Tuple<Individual>> violationTuples) { 42 public Collection<DLClause> convert(DLClause clause,
43 DLClause originalClause,
44 Collection<Tuple<Individual>> violationTuples) {
39 switch (clause.getHeadLength()) { 45 switch (clause.getHeadLength()) {
40 case 1: 46 case 1:
41 return overApprox(clause, originalClause, violationTuples); 47 return overApprox(clause, originalClause, violationTuples);
42 case 0: 48 case 0:
43 return Arrays.asList(clause); 49 return Arrays.asList(clause);
44 default: 50 default:
45 ArrayList<DLClause> result = new ArrayList<>(); 51 throw new IllegalArgumentException(
46 // TODO implement 52 "Expected clause with head length < 1, but it is " + clause.getHeadLength());
47 return result;
48 } 53 }
49 54
50 55
@@ -54,23 +59,94 @@ public class LimitedSkolemisationApproximator implements TupleDependentApproxima
54 ArrayList<DLClause> result = new ArrayList<>(); 59 ArrayList<DLClause> result = new ArrayList<>();
55 60
56 for (Tuple<Individual> violationTuple : violationTuples) 61 for (Tuple<Individual> violationTuple : violationTuples)
57 if (getDepth(violationTuple) > maxTermDepth) 62 if (getMaxDepth(violationTuple) > maxTermDepth)
58 result.addAll(alternativeApproximator.convert(clause, originalClause, null)); 63 result.addAll(alternativeApproximator.convert(clause, originalClause, null));
59 else 64 else
60 result.add(getGroundSkolemisation(clause, originalClause, violationTuple)); 65 result.addAll(getGroundSkolemisation(clause, originalClause, violationTuple));
61 66
62 return result; 67 return result;
63 } 68 }
64 69
70 private static final Variable X = Variable.create("X");
71
72 private Collection<DLClause> getGroundSkolemisation(DLClause clause,
73 DLClause originalClause,
74 Tuple<Individual> violationTuple) {
75
76 String[] commonVars = MultiStageUpperProgram.getCommonVars(clause);
77
78 // TODO check: strong assumption, the first tuples are the common ones
79 TupleBuilder<Individual> commonIndividualsBuilder = new TupleBuilder<>();
80 for (int i = 0; i < commonVars.length; i++)
81 commonIndividualsBuilder.add(violationTuple.get(i));
82
83 Atom headAtom = clause.getHeadAtom(0);
84 Atom[] bodyAtoms = clause.getBodyAtoms();
85 int offset = OverApproxExist.indexOfExistential(headAtom, originalClause);
86
87 // BEGIN: copy and paste
88 ArrayList<DLClause> ret = new ArrayList<>();
89 DLPredicate predicate = headAtom.getDLPredicate();
90 if (predicate instanceof AtLeastConcept) {
91 AtLeastConcept atLeastConcept = (AtLeastConcept) predicate;
92 LiteralConcept concept = atLeastConcept.getToConcept();
93 Role role = atLeastConcept.getOnRole();
94 AtomicConcept atomicConcept;
95
96 if (concept instanceof AtomicNegationConcept) {
97 // TODO CHECK: is this already in MultiStageUpperProgram?
98 Atom atom1 = Atom.create(atomicConcept = ((AtomicNegationConcept) concept).getNegatedAtomicConcept(), X);
99 Atom atom2 = Atom.create(atomicConcept = OverApproxExist.getNegationConcept(atomicConcept), X);
100 ret.add(DLClause.create(new Atom[0], new Atom[] {atom1, atom2}));
101 }
102 else {
103 atomicConcept = (AtomicConcept) concept;
104 if (atomicConcept.equals(AtomicConcept.THING))
105 atomicConcept = null;
106 }
107
108 int card = atLeastConcept.getNumber();
109 Individual[] individuals = new Individual[card];
110 SkolemTermsManager termsManager = SkolemTermsManager.getInstance();
111 for (int i = 0; i < card; ++i)
112 individuals[i] = termsManager.getFreshIndividual(originalClause,
113 offset + i,
114 commonIndividualsBuilder.create());
115
116 for (int i = 0; i < card; ++i) {
117 if (atomicConcept != null)
118 ret.add(DLClause.create(new Atom[] {Atom.create(atomicConcept, individuals[i])}, EMPTY_BODY));
119
120 Atom atom = role instanceof AtomicRole ?
121 Atom.create((AtomicRole) role, X, individuals[i]) :
122 Atom.create(((InverseRole) role).getInverseOf(), individuals[i], X);
123
124 ret.add(DLClause.create(new Atom[] {atom}, EMPTY_BODY));
125 }
126
127 for (int i = 0; i < card; ++i)
128 for (int j = i + 1; j < card; ++j)
129 // TODO to be checked ... different as
130 ret.add(DLClause.create(new Atom[] {Atom.create(Inequality.INSTANCE, individuals[i], individuals[j])}, EMPTY_BODY));
131
132 }
133 else if (predicate instanceof AtLeastDataRange) {
134 // TODO to be implemented ...
135 }
136 else
137 ret.add(DLClause.create(new Atom[] {headAtom}, EMPTY_BODY));
65 138
66 private DLClause getGroundSkolemisation(DLClause clause, DLClause originalClause, Tuple<Individual> violationTuple) { 139 return ret;
67 // TODO implement 140
68 // filter the violation tuples appearing on both the sides of the rule 141 // END: copy and paste
69 return null;
70 } 142 }
71 143
72 private int getDepth(Tuple<Individual> violationTuple) { 144
73 if (!mapIndividualsToDepth.containsKey(violationTuple)) return 0; 145 public int getMaxDepth(Tuple<Individual> violationTuple) {
74 return mapIndividualsToDepth.get(violationTuple); 146 int maxDepth = 0;
147 for (Individual individual : violationTuple)
148 maxDepth = Integer.max(maxDepth, skolemTermsManager.getDepth(individual));
149
150 return maxDepth;
75 } 151 }
76} 152}
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 d71c472..028568c 100644
--- a/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java
+++ b/src/uk/ac/ox/cs/pagoda/rules/approximators/OverApproxExist.java
@@ -12,7 +12,7 @@ public class OverApproxExist implements Approximator {
12 public static final String negativeSuffix = "_neg"; 12 public static final String negativeSuffix = "_neg";
13 private static final Variable X = Variable.create("X"); 13 private static final Variable X = Variable.create("X");
14 14
15 private static int indexOfExistential(Atom headAtom, DLClause originalClause) { 15 static int indexOfExistential(Atom headAtom, DLClause originalClause) {
16 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1; 16 if (!(headAtom.getDLPredicate() instanceof AtLeast)) return -1;
17 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate(); 17 AtLeastConcept alc = (AtLeastConcept) headAtom.getDLPredicate();
18 if (alc.getToConcept() instanceof AtomicConcept) { 18 if (alc.getToConcept() instanceof AtomicConcept) {