aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/uk/ac/ox/cs/pagoda/constraints
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2022-05-10 18:17:06 +0100
committerFederico Igne <federico.igne@cs.ox.ac.uk>2022-05-11 12:34:47 +0100
commit17bd9beaf7f358a44e5bf36a5855fe6727d506dc (patch)
tree47e9310a0cff869d9ec017dcb2c81876407782c8 /src/main/java/uk/ac/ox/cs/pagoda/constraints
parent8651164cd632a5db310b457ce32d4fbc97bdc41c (diff)
downloadACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.tar.gz
ACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.zip
[pagoda] Move project to Scala
This commit includes a few changes: - The repository still uses Maven to manage dependency but it is now a Scala project. - The code has been ported from OWLAPI 3.4.10 to 5.1.20 - A proof of concept program using both RSAComb and PAGOdA has been added.
Diffstat (limited to 'src/main/java/uk/ac/ox/cs/pagoda/constraints')
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/BottomStrategy.java19
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java119
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/NullaryBottom.java31
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/OWLEntityDependency.java195
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/PredicateDependency.java215
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/ToBeRemovedBottom.java36
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/UnaryBottom.java67
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/constraints/UpperUnaryBottom.java52
8 files changed, 734 insertions, 0 deletions
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/BottomStrategy.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/BottomStrategy.java
new file mode 100644
index 0000000..4d25593
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/BottomStrategy.java
@@ -0,0 +1,19 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.Collection;
4
5import org.semanticweb.HermiT.model.Atom;
6import org.semanticweb.HermiT.model.DLClause;
7import org.semanticweb.HermiT.model.Term;
8
9public interface BottomStrategy {
10
11 public Collection<DLClause> process(Collection<DLClause> clauses);
12
13 public boolean isBottomRule(DLClause clause);
14
15 public Atom[] getEmptyHead(Term t);
16
17 public int getBottomNumber();
18
19}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java
new file mode 100644
index 0000000..d1615c7
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java
@@ -0,0 +1,119 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.LinkedList;
6import java.util.Map;
7import java.util.Queue;
8import java.util.Set;
9
10public abstract class DependencyGraph<T> {
11
12 protected abstract void build();
13
14 protected Map<T, Set<T>> edges = new HashMap<T, Set<T>>();
15 protected Map<T, Set<T>> reverseEdges = new HashMap<T, Set<T>>();
16
17 public void addLink(T subEntity, T superEntity) {
18 Set<T> dests = edges.get(subEntity);
19 if (dests == null)
20 edges.put(subEntity, dests = new HashSet<T>());
21 dests.add(superEntity);
22
23 Set<T> srcs = reverseEdges.get(superEntity);
24 if (srcs == null)
25 reverseEdges.put(superEntity, srcs = new HashSet<T>());
26 srcs.add(subEntity);
27 }
28
29 public void output() {
30 for (Map.Entry<T, Set<T>> pair: edges.entrySet()) {
31 T src = pair.getKey();
32 for (T dest: pair.getValue())
33 System.out.println(src + " -> " + dest);
34 }
35 }
36
37 public int distance(Set<T> dsts, T src) {
38 Set<T> visited = new HashSet<T>();
39 if (dsts.contains(src)) return 0;
40 visited.add(src);
41 return distance(dsts, visited);
42 }
43
44 public int distance(Set<T> dsts, T src1, T src2) {
45 Set<T> visited = new HashSet<T>();
46 if (dsts.contains(src1)) return 0;
47 if (dsts.contains(src2)) return 0;
48 visited.add(src1);
49 visited.add(src2);
50 return distance(dsts, visited);
51 }
52
53 private int distance(Set<T> dsts, Set<T> visited) {
54 Queue<Entry> queue = new LinkedList<Entry>();
55 for (T src: visited)
56 queue.add(new Entry(src, 0, visited));
57
58 Entry entry;
59 Set<T> edge;
60 while (!queue.isEmpty()) {
61 entry = queue.poll();
62 edge = edges.get(entry.m_entity);
63 if (edge != null)
64 for (T next: edge) {
65 if (dsts.contains(next)) return entry.m_dist + 1;
66
67 if (!visited.contains(next))
68 queue.add(new Entry(next, entry.m_dist + 1, visited));
69 }
70 }
71
72 return Integer.MAX_VALUE;
73 }
74
75 public Set<T> getAncesters(T p) {
76 return getDependency(p, false);
77 }
78
79 public Set<T> getSuccessors(T p) {
80 return getDependency(p, true);
81 }
82
83 private Set<T> getDependency(T p, boolean succ) {
84 return succ ? getDependency(p, edges) : getDependency(p, reverseEdges);
85 }
86
87 private Set<T> getDependency(T p, Map<T, Set<T>> graph) {
88 Set<T> visited = new HashSet<T>();
89 Queue<T> queue = new LinkedList<T>();
90 visited.add(p);
91 queue.add(p);
92 Set<T> edge;
93
94 while (!queue.isEmpty()) {
95 if ((edge = graph.get(queue.poll())) != null)
96 for (T next: edge)
97 if (!visited.contains(next)) {
98 queue.add(next);
99 visited.add(next);
100 }
101 }
102
103 return visited;
104 }
105
106 private class Entry {
107
108 T m_entity;
109 int m_dist;
110
111 public Entry(T entity, int distance, Set<T> v) {
112 m_entity = entity;
113 m_dist = distance;
114 v.add(entity);
115 }
116
117 }
118
119}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/NullaryBottom.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/NullaryBottom.java
new file mode 100644
index 0000000..16a9d45
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/NullaryBottom.java
@@ -0,0 +1,31 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.Collection;
4
5import org.semanticweb.HermiT.model.Atom;
6import org.semanticweb.HermiT.model.DLClause;
7import org.semanticweb.HermiT.model.Term;
8
9public class NullaryBottom implements BottomStrategy {
10
11 @Override
12 public Collection<DLClause> process(Collection<DLClause> clauses) {
13 return clauses;
14 }
15
16 @Override
17 public boolean isBottomRule(DLClause clause) {
18 return clause.getHeadLength() == 0;
19 }
20
21 @Override
22 public Atom[] getEmptyHead(Term t) {
23 return new Atom[0];
24 }
25
26 @Override
27 public int getBottomNumber() {
28 return 1;
29 }
30
31}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/OWLEntityDependency.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/OWLEntityDependency.java
new file mode 100644
index 0000000..60fea28
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/OWLEntityDependency.java
@@ -0,0 +1,195 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Map;
6import java.util.Set;
7
8import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
9import org.semanticweb.owlapi.model.OWLAxiom;
10import org.semanticweb.owlapi.model.OWLClass;
11import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
12import org.semanticweb.owlapi.model.OWLClassExpression;
13import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom;
14import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom;
15import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
16import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
17import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
18import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom;
19import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom;
20import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom;
21import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom;
22import org.semanticweb.owlapi.model.OWLLogicalEntity;
23import org.semanticweb.owlapi.model.OWLObject;
24import org.semanticweb.owlapi.model.OWLObjectProperty;
25import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
26import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom;
27import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
28import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
29import org.semanticweb.owlapi.model.OWLOntology;
30import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
31import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
32import org.semanticweb.owlapi.model.OWLSymmetricObjectPropertyAxiom;
33import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
34
35import uk.ac.ox.cs.pagoda.MyPrefixes;
36import uk.ac.ox.cs.pagoda.owl.OWLHelper;
37import uk.ac.ox.cs.pagoda.util.Utility;
38
39public class OWLEntityDependency extends DependencyGraph<OWLLogicalEntity> {
40
41 OWLOntology m_ontology;
42 OWLClass m_nothing;
43 Map<String, OWLLogicalEntity> map = new HashMap<String, OWLLogicalEntity>();
44
45 public OWLEntityDependency(OWLOntology ontology) {
46 m_ontology = ontology;
47 m_nothing = ontology.getOWLOntologyManager().getOWLDataFactory().getOWLNothing();
48 build();
49 }
50
51 @Override
52 protected void build() {
53 for (OWLOntology o: m_ontology.getImportsClosure())
54 for (OWLAxiom a: o.getAxioms())
55 if (a instanceof OWLDisjointClassesAxiom)
56 addLinks((OWLDisjointClassesAxiom) a);
57 else if (a instanceof OWLSymmetricObjectPropertyAxiom)
58 addLinks((OWLSymmetricObjectPropertyAxiom) a);
59 else if (a instanceof OWLFunctionalObjectPropertyAxiom)
60 ;
61 else if (a instanceof OWLInverseFunctionalObjectPropertyAxiom)
62 ;
63 else if (a instanceof OWLTransitiveObjectPropertyAxiom)
64 addLinkes((OWLTransitiveObjectPropertyAxiom) a);
65 else if (a instanceof OWLInverseObjectPropertiesAxiom)
66 addLinks((OWLInverseObjectPropertiesAxiom) a);
67 else if (a instanceof OWLSubClassOfAxiom)
68 addLinks((OWLSubClassOfAxiom) a);
69 else if (a instanceof OWLSubObjectPropertyOfAxiom)
70 addLinks((OWLSubObjectPropertyOfAxiom) a);
71 else if (a instanceof OWLEquivalentClassesAxiom)
72 addLinks((OWLEquivalentClassesAxiom) a);
73 else if (a instanceof OWLEquivalentObjectPropertiesAxiom)
74 addLinks((OWLEquivalentObjectPropertiesAxiom) a);
75 else if (a instanceof OWLObjectPropertyDomainAxiom)
76 addLinks((OWLObjectPropertyDomainAxiom) a);
77 else if (a instanceof OWLObjectPropertyRangeAxiom)
78 addLinks((OWLObjectPropertyRangeAxiom) a);
79 else if (a instanceof OWLDataPropertyDomainAxiom)
80 addLinks((OWLDataPropertyDomainAxiom) a);
81 else if (a instanceof OWLDataPropertyRangeAxiom)
82 addLinks((OWLDataPropertyRangeAxiom) a);
83 else if (a instanceof OWLDeclarationAxiom)
84 ;
85 else if (a instanceof OWLAnnotationAssertionAxiom)
86 ;
87 else if (a instanceof OWLClassAssertionAxiom)
88 ;
89 else if (a instanceof OWLObjectPropertyAssertionAxiom)
90 ;
91 else {
92 Utility.logError("Unknowledge OWL Axiom: " + a.getClass().getName() + "\n" + a);
93 }
94// Utility.LOGS.info("DONE\n----------------------------");
95 }
96
97 private void addLinks(OWLDisjointClassesAxiom a) {
98 for (OWLClassExpression exp: a.getClassExpressions())
99 addLinks(exp, m_nothing);
100 }
101
102 private void addLinks(OWLSymmetricObjectPropertyAxiom a) {
103 // TODO Auto-generated method stub
104
105 }
106
107 private void addLinks(OWLInverseObjectPropertiesAxiom a) {
108 // TODO Auto-generated method stub
109
110 }
111
112 private void addLinks(OWLDataPropertyRangeAxiom a) {
113 addLinks(a.getProperty(), a.getRange());
114 }
115
116 private void addLinks(OWLDataPropertyDomainAxiom a) {
117 addLinks(a.getProperty(), a.getDomain());
118 }
119
120 private void addLinks(OWLEquivalentObjectPropertiesAxiom a) {
121 for (OWLObjectPropertyExpression exp1: a.getProperties())
122 for (OWLObjectPropertyExpression exp2: a.getProperties())
123 if(!exp1.equals(exp2))
124 addLinks(exp1, exp2);
125 }
126
127 private void addLinkes(OWLTransitiveObjectPropertyAxiom a) {
128 addLinks(a.getProperty(), a.getProperty());
129 }
130
131 private void addLinks(OWLObjectPropertyRangeAxiom a) {
132 addLinks(a.getProperty(), a.getRange());
133 }
134
135 private void addLinks(OWLObjectPropertyDomainAxiom a) {
136 addLinks(a.getProperty(), a.getDomain());
137
138 }
139
140 private void addLinks(OWLEquivalentClassesAxiom a) {
141 for (OWLClassExpression exp1: a.getClassExpressions())
142 for (OWLClassExpression exp2: a.getClassExpressions())
143 if (!exp1.equals(exp2))
144 addLinks(exp1, exp2);
145 }
146
147 private void addLinks(OWLSubObjectPropertyOfAxiom a) {
148 addLinks(a.getSubProperty(), a.getSuperProperty());
149 }
150
151 private void addLinks(OWLSubClassOfAxiom a) {
152 addLinks(a.getSubClass(), a.getSuperClass());
153
154 }
155
156 private void addLinks(OWLObject body, OWLObject head) {
157 Set<OWLLogicalEntity> bodyEntities = new HashSet<OWLLogicalEntity>();
158 Set<OWLLogicalEntity> headEntities = new HashSet<OWLLogicalEntity>();
159 for (OWLClass c: body.getClassesInSignature()) {
160 bodyEntities.add(c);
161 map.put(c.toStringID(), c);
162 }
163 for (OWLObjectProperty p: body.getObjectPropertiesInSignature()) {
164 bodyEntities.add(p);
165 map.put(p.toStringID(), p);
166 }
167
168 for (OWLClass c: head.getClassesInSignature()) {
169 headEntities.add(c);
170 map.put(c.toStringID(), c);
171 }
172 for (OWLObjectProperty p: head.getObjectPropertiesInSignature()) {
173 headEntities.add(p);
174 map.put(p.toString(), p);
175 }
176
177 for (OWLLogicalEntity subEntity: bodyEntities)
178 for (OWLLogicalEntity superEntity: headEntities)
179 addLink(subEntity, superEntity);
180 }
181
182 public OWLLogicalEntity getLogicalEntity(String iri) {
183 iri = MyPrefixes.PAGOdAPrefixes.expandIRI(iri);
184 return map.get(iri);
185 }
186
187 public static void main(String[] args) {
188 args = ("/users/yzhou/ontologies/uobm/univ-bench-dl.owl").split("\\ ");
189
190 OWLOntology onto = OWLHelper.loadOntology(args[0]);
191 OWLEntityDependency dependency = new OWLEntityDependency(onto);
192 dependency.output();
193 }
194
195}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/PredicateDependency.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/PredicateDependency.java
new file mode 100644
index 0000000..70f841f
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/PredicateDependency.java
@@ -0,0 +1,215 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import org.semanticweb.HermiT.model.*;
4import uk.ac.ox.cs.pagoda.rules.approximators.OverApproxExist;
5import uk.ac.ox.cs.pagoda.util.Namespace;
6import uk.ac.ox.cs.pagoda.util.Utility;
7
8import java.util.*;
9
10
11public class PredicateDependency extends DependencyGraph<DLPredicate> {
12
13 private static final DLPredicate equality = AtomicRole.create(Namespace.EQUALITY);
14 private static final DLPredicate inequality = AtomicRole.create(Namespace.INEQUALITY);
15 Collection<DLClause> m_clauses;
16 Map<PredicatePair, LinkedList<DLClause>> edgeLabels = new HashMap<PredicatePair, LinkedList<DLClause>>();
17 Set<DLPredicate> reachableToBottom = null;
18
19 public PredicateDependency(Collection<DLClause> clauses) {
20 m_clauses = clauses;
21 build();
22 }
23
24 @Override
25 protected void build() {
26 update(m_clauses);
27
28 addLink(equality, AtomicConcept.NOTHING);
29 addLink(inequality, AtomicConcept.NOTHING);
30 }
31
32 private void addEdgeLabel(DLPredicate body, DLPredicate head, DLClause clause) {
33 PredicatePair key = new PredicatePair(body, head);
34 LinkedList<DLClause> value;
35 if ((value = edgeLabels.get(key)) == null)
36 edgeLabels.put(key, value = new LinkedList<DLClause>());
37 value.add(clause);
38 }
39
40 private void addLinks4Negation(AtomicConcept c, DLClause clause) {
41 addLink(c, AtomicConcept.NOTHING);
42 addEdgeLabel(c, AtomicConcept.NOTHING, clause);
43 String iri = c.getIRI();
44 addLink(c = AtomicConcept.create(iri.substring(0, iri.length() - 4)), AtomicConcept.NOTHING);
45 addEdgeLabel(c, AtomicConcept.NOTHING, clause);
46 }
47
48 public Set<DLPredicate> collectPredicate(Atom[] atoms) {
49 Set<DLPredicate> predicates = new HashSet<DLPredicate>();
50 for (Atom atom : atoms)
51 predicates.addAll(getAtomicPredicates(atom.getDLPredicate()));
52 return predicates;
53 }
54
55 private Set<DLPredicate> getAtomicPredicates(DLPredicate predicate) {
56 Set<DLPredicate> predicates = new HashSet<DLPredicate>();
57 if (predicate instanceof AtLeastConcept)
58 predicates.addAll(getAtomicPredicates((AtLeastConcept) predicate));
59 else {
60 if ((predicate = getAtomicPredicate(predicate)) != null)
61 predicates.add(predicate);
62 }
63 return predicates;
64 }
65
66 private Set<DLPredicate> getAtomicPredicates(AtLeastConcept alc) {
67 Set<DLPredicate> set = new HashSet<DLPredicate>();
68 if (alc.getOnRole() instanceof AtomicRole)
69 set.add((AtomicRole) alc.getOnRole());
70 else
71 set.add(((InverseRole) alc.getOnRole()).getInverseOf());
72
73 if (alc.getToConcept() instanceof AtomicConcept)
74 if (alc.getToConcept().equals(AtomicConcept.THING)) ;
75 else set.add((AtomicConcept) alc.getToConcept());
76 else
77 set.add(OverApproxExist.getNegationConcept(((AtomicNegationConcept) alc.getToConcept()).getNegatedAtomicConcept()));
78 return set;
79 }
80
81 private DLPredicate getAtomicPredicate(DLPredicate p) {
82 if (p instanceof Equality || p instanceof AnnotatedEquality)
83 return equality;
84 if (p instanceof Inequality)
85 return inequality;
86 if (p instanceof AtomicConcept)
87 if (p.equals(AtomicConcept.THING))
88 return null;
89 else return p;
90 if (p instanceof AtomicRole)
91 return p;
92 if (p instanceof AtLeastDataRange) {
93 AtLeastDataRange aldr = (AtLeastDataRange) p;
94 if (aldr.getOnRole() instanceof AtomicRole)
95 return (AtomicRole) aldr.getOnRole();
96 else
97 return ((InverseRole) aldr.getOnRole()).getInverseOf();
98 }
99 Utility.logDebug("Unknown DLPredicate in PredicateDependency: " + p);
100 return null;
101 }
102
103 public Set<DLClause> pathTo(DLPredicate p) {
104 Set<DLClause> rules = new HashSet<DLClause>();
105 Set<DLPredicate> visited = new HashSet<DLPredicate>();
106
107 Queue<DLPredicate> queue = new LinkedList<DLPredicate>();
108 queue.add(p);
109 visited.add(p);
110
111 Set<DLPredicate> edge;
112 Collection<DLClause> clauses;
113
114 while (!queue.isEmpty()) {
115 if ((edge = reverseEdges.get(p = queue.poll())) != null) {
116 for (DLPredicate pred: edge) {
117 if (!visited.contains(pred)) {
118 queue.add(pred);
119 visited.add(pred);
120 }
121 clauses = edgeLabelsBetween(pred, p);
122 if (clauses != null) rules.addAll(clauses);
123 }
124 }
125 }
126 return rules;
127 }
128
129 private LinkedList<DLClause> edgeLabelsBetween(DLPredicate p, DLPredicate q) {
130 PredicatePair pair = new PredicatePair(p, q);
131 return edgeLabels.get(pair);
132 }
133
134 public Set<DLClause> pathToBottom(DLPredicate p) {
135 if (reachableToBottom == null) {
136 reachableToBottom = getAncesters(AtomicConcept.NOTHING);
137 reachableToBottom.add(AtomicConcept.NOTHING);
138 }
139
140 Set<DLClause> rules = new HashSet<DLClause>();
141 Set<DLPredicate> visited = new HashSet<DLPredicate>();
142
143 Queue<DLPredicate> queue = new LinkedList<DLPredicate>();
144 queue.add(p);
145 visited.add(p);
146
147 Set<DLPredicate> edge;
148 Collection<DLClause> clauses;
149
150 while (!queue.isEmpty()) {
151 if ((edge = edges.get(p = queue.poll())) != null) {
152 for (DLPredicate next: edge)
153 if (reachableToBottom.contains(next)) {
154 if (!visited.contains(next)) {
155 queue.add(next);
156 visited.add(next);
157 }
158 clauses = edgeLabelsBetween(p, next);
159 if (clauses != null) rules.addAll(clauses);
160 }
161 }
162 }
163 return rules;
164 }
165
166 public void update(Collection<DLClause> clauses) {
167 Set<DLPredicate> headPredicates, bodyPredicates;
168
169 for (DLClause clause: clauses) {
170 headPredicates = collectPredicate(clause.getHeadAtoms());
171 bodyPredicates = collectPredicate(clause.getBodyAtoms());
172
173 for (DLPredicate body: bodyPredicates)
174 for (DLPredicate head: headPredicates) {
175 addLink(body, head);
176 addEdgeLabel(body, head, clause);
177
178 if (body instanceof AtomicConcept && body.toString().contains("_neg"))
179 addLinks4Negation((AtomicConcept) body, clause);
180 if (head instanceof AtomicConcept && head.toString().contains("_neg"))
181 addLinks4Negation((AtomicConcept) head, clause);
182 }
183
184 for (DLPredicate body: bodyPredicates)
185 addLink(equality, body);
186
187 for (DLPredicate head: headPredicates)
188 addLink(equality, head);
189 }
190 }
191
192}
193
194class PredicatePair {
195
196 DLPredicate p, q;
197
198 public PredicatePair(DLPredicate p, DLPredicate q) {
199 this.p = p; this.q = q;
200 }
201
202 public int hashCode() {
203 return p.hashCode() * 1997 + q.hashCode();
204 }
205
206 public boolean equals(Object o) {
207 if (!(o instanceof PredicatePair)) return false;
208 PredicatePair thatPair = (PredicatePair) o;
209 return p.equals(thatPair.p) && q.equals(thatPair.q);
210 }
211
212 public String toString() {
213 return "<" + p.toString() + "," + q.toString() + ">";
214 }
215}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/ToBeRemovedBottom.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/ToBeRemovedBottom.java
new file mode 100644
index 0000000..415119a
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/ToBeRemovedBottom.java
@@ -0,0 +1,36 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.Collection;
4import java.util.LinkedList;
5
6import org.semanticweb.HermiT.model.Atom;
7import org.semanticweb.HermiT.model.DLClause;
8import org.semanticweb.HermiT.model.Term;
9
10public class ToBeRemovedBottom implements BottomStrategy {
11
12 @Override
13 public Collection<DLClause> process(Collection<DLClause> clauses) {
14 Collection<DLClause> ret = new LinkedList<DLClause>();
15 for (DLClause clause: clauses)
16 if (clause.getHeadLength() != 0)
17 ret.add(clause);
18 return ret;
19 }
20
21 @Override
22 public boolean isBottomRule(DLClause clause) {
23 return false;
24 }
25
26 @Override
27 public Atom[] getEmptyHead(Term t) {
28 return null;
29 }
30
31 @Override
32 public int getBottomNumber() {
33 return 0;
34 }
35
36}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/UnaryBottom.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/UnaryBottom.java
new file mode 100644
index 0000000..5339c50
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/UnaryBottom.java
@@ -0,0 +1,67 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.Collection;
4import java.util.HashSet;
5import java.util.LinkedList;
6import java.util.Set;
7
8import org.semanticweb.HermiT.model.Atom;
9import org.semanticweb.HermiT.model.AtomicConcept;
10import org.semanticweb.HermiT.model.DLClause;
11import org.semanticweb.HermiT.model.Individual;
12import org.semanticweb.HermiT.model.Term;
13import org.semanticweb.HermiT.model.Variable;
14
15public class UnaryBottom implements BottomStrategy {
16
17 @Override
18 public Collection<DLClause> process(Collection<DLClause> clauses) {
19 Collection<DLClause> ret = new LinkedList<DLClause>();
20 for (DLClause clause: clauses)
21 if (clause.getHeadLength() == 0) {
22 ret.add(DLClause.create(getEmptyHead(pickRepresentative(clause.getBodyAtoms())), clause.getBodyAtoms()));
23 }
24 else
25 ret.add(clause);
26 return ret;
27 }
28
29 protected Term pickRepresentative(Atom[] atoms) {
30 Term rep = null;
31 Set<Variable> vars = new HashSet<Variable>();
32 for (Atom atom: atoms) {
33 atom.getVariables(vars);
34 for (Variable v: vars)
35 if (rep == null || ((Variable) rep).getName().compareTo(v.getName()) > 0)
36 rep = v;
37 vars.clear();
38 }
39 if (rep != null) return rep;
40
41 Set<Individual> inds = new HashSet<Individual>();
42 for (Atom atom: atoms) {
43 atom.getIndividuals(inds);
44 for (Individual i: inds)
45 if (rep == null || ((Individual) rep).getIRI().compareTo(i.getIRI()) > 0)
46 rep = i;
47 inds.clear();
48 }
49
50 return rep;
51 }
52
53 @Override
54 public boolean isBottomRule(DLClause clause) {
55 return clause.getHeadLength() == 1 && clause.getHeadAtom(0).getDLPredicate().equals(AtomicConcept.NOTHING);
56 }
57
58 public Atom[] getEmptyHead(Term t) {
59 return new Atom[] {Atom.create(AtomicConcept.NOTHING, t)};
60 }
61
62 @Override
63 public int getBottomNumber() {
64 return 1;
65 }
66
67}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/constraints/UpperUnaryBottom.java b/src/main/java/uk/ac/ox/cs/pagoda/constraints/UpperUnaryBottom.java
new file mode 100644
index 0000000..2b57a52
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/constraints/UpperUnaryBottom.java
@@ -0,0 +1,52 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.Collection;
4import java.util.HashMap;
5import java.util.LinkedList;
6import java.util.Map;
7
8import org.semanticweb.HermiT.model.Atom;
9import org.semanticweb.HermiT.model.AtomicConcept;
10import org.semanticweb.HermiT.model.DLClause;
11import org.semanticweb.HermiT.model.Term;
12import org.semanticweb.HermiT.model.Variable;
13
14public class UpperUnaryBottom extends UnaryBottom {
15
16 static final Variable X = Variable.create("X");
17
18 Map<DLClause, Integer> number = new HashMap<DLClause, Integer>();
19
20 @Override
21 public Collection<DLClause> process(Collection<DLClause> clauses) {
22 Collection<DLClause> ret = new LinkedList<DLClause>();
23 for (DLClause clause: clauses)
24 if (clause.getHeadLength() == 0) {
25 ret.add(DLClause.create(getEmptyHead(pickRepresentative(clause.getBodyAtoms()), clause), clause.getBodyAtoms()));
26 ret.add(DLClause.create(getEmptyHead(X), getEmptyHead(X, clause)));
27 }
28 else
29 ret.add(clause);
30 return ret;
31 }
32
33 @Override
34 public boolean isBottomRule(DLClause clause) {
35 return clause.getHeadLength() == 1 && clause.getHeadAtom(0).getDLPredicate().toString().contains(AtomicConcept.NOTHING.toString());
36 }
37
38 public Atom[] getEmptyHead(Term t, DLClause clause) {
39 Integer index = number.get(clause);
40 if (index == null) {
41 number.put(clause, index = number.size() + 1);
42 }
43
44 return new Atom[] {Atom.create(AtomicConcept.create(AtomicConcept.NOTHING.getIRI() + index), t)};
45 }
46
47 @Override
48 public int getBottomNumber() {
49 return number.size() + 1;
50 }
51
52}