aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala9
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala54
-rw-r--r--src/main/scala/uk/ac/ox/cs/rsacomb/ontologies/Ontology.scala8
3 files changed, 33 insertions, 38 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala
index db2118f..344f0fe 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/approximation.scala
@@ -3,17 +3,16 @@ package uk.ac.ox.cs.rsacomb.approximation
3import java.io.File 3import java.io.File
4import org.semanticweb.owlapi.model.OWLLogicalAxiom 4import org.semanticweb.owlapi.model.OWLLogicalAxiom
5 5
6import uk.ac.ox.cs.rsacomb.ontology.Ontology
7
6/** Ontology approximation technique. */ 8/** Ontology approximation technique. */
7trait Approximation { 9trait Approximation[T] {
8 10
9 /** Approximate an ontology. 11 /** Approximate an ontology.
10 * 12 *
11 * @param ontology input ontology as a list of axioms 13 * @param ontology input ontology as a list of axioms
12 * @return the approximated ontology 14 * @return the approximated ontology
13 */ 15 */
14 def approximate( 16 def approximate(ontology: Ontology): T
15 ontology: List[OWLLogicalAxiom],
16 datafiles: List[File]
17 ): List[OWLLogicalAxiom]
18 17
19} 18}
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala
index 2750cca..07f10a4 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/lowerbound.scala
@@ -15,6 +15,14 @@ import scalax.collection.GraphTraversal._
15import uk.ac.ox.cs.rsacomb.RSAOntology 15import uk.ac.ox.cs.rsacomb.RSAOntology
16import uk.ac.ox.cs.rsacomb.RSAUtil 16import uk.ac.ox.cs.rsacomb.RSAUtil
17import uk.ac.ox.cs.rsacomb.converter.Normalizer 17import uk.ac.ox.cs.rsacomb.converter.Normalizer
18import uk.ac.ox.cs.rsacomb.ontology.Ontology
19
20object LowerBound {
21
22 private val manager = OWLManager.createOWLOntologyManager()
23 private val factory = manager.getOWLDataFactory()
24
25}
18 26
19/** Approximation algorithm that mantains soundness for CQ answering. 27/** Approximation algorithm that mantains soundness for CQ answering.
20 * 28 *
@@ -31,7 +39,7 @@ import uk.ac.ox.cs.rsacomb.converter.Normalizer
31 * 39 *
32 * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]] 40 * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]]
33 */ 41 */
34class LowerBound extends Approximation { 42class LowerBound extends Approximation[RSAOntology] {
35 43
36 /** Simplify conversion between Java and Scala collections */ 44 /** Simplify conversion between Java and Scala collections */
37 import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ 45 import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._
@@ -39,19 +47,12 @@ class LowerBound extends Approximation {
39 /** Simplify conversion between OWLAPI and RDFox concepts */ 47 /** Simplify conversion between OWLAPI and RDFox concepts */
40 import uk.ac.ox.cs.rsacomb.implicits.RDFox._ 48 import uk.ac.ox.cs.rsacomb.implicits.RDFox._
41 49
42 /** Manager instance to interface with OWLAPI */ 50 private val normalizer = new Normalizer()
43 val manager = OWLManager.createOWLOntologyManager()
44 val factory = manager.getOWLDataFactory()
45
46 val normalizer = new Normalizer()
47 51
48 /** Main entry point for the approximation algorithm */ 52 /** Main entry point for the approximation algorithm */
49 def approximate( 53 def approximate(ontology: Ontology): RSAOntology = {
50 ontology: List[OWLLogicalAxiom],
51 datafiles: List[File]
52 ): List[OWLLogicalAxiom] = {
53 /* Normalize axioms */ 54 /* Normalize axioms */
54 val axioms1 = ontology flatMap normalizer.normalize 55 val axioms1 = ontology.axioms flatMap normalizer.normalize
55 /* Delete any axiom outside of ALCHOIQ */ 56 /* Delete any axiom outside of ALCHOIQ */
56 val axioms2 = axioms1 filterNot inALCHOIQ 57 val axioms2 = axioms1 filterNot inALCHOIQ
57 /* Shift any axiom with disjunction on the rhs */ 58 /* Shift any axiom with disjunction on the rhs */
@@ -61,11 +62,11 @@ class LowerBound extends Approximation {
61 a3 <- normalizer.normalize(a2) 62 a3 <- normalizer.normalize(a2)
62 } yield a3 63 } yield a3
63 /* Approximate to RSA */ 64 /* Approximate to RSA */
64 toRSA(axioms3, datafiles) 65 toRSA(new Ontology(axioms3, ontology.datafiles))
65 } 66 }
66 67
67 /** Discards all axioms outside ALCHOIQ */ 68 /** Discards all axioms outside ALCHOIQ */
68 def inALCHOIQ(axiom: OWLLogicalAxiom): Boolean = 69 private def inALCHOIQ(axiom: OWLLogicalAxiom): Boolean =
69 axiom match { 70 axiom match {
70 case a: OWLSubClassOfAxiom => { 71 case a: OWLSubClassOfAxiom => {
71 val sub = a.getSubClass.getNNF 72 val sub = a.getSubClass.getNNF
@@ -121,7 +122,7 @@ class LowerBound extends Approximation {
121 * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to 122 * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to
122 * the negation of A, B1, B2, B3 respectively. 123 * the negation of A, B1, B2, B3 respectively.
123 */ 124 */
124 def shift(axiom: OWLLogicalAxiom): List[OWLLogicalAxiom] = 125 private def shift(axiom: OWLLogicalAxiom): List[OWLLogicalAxiom] =
125 axiom match { 126 axiom match {
126 case a: OWLSubClassOfAxiom => { 127 case a: OWLSubClassOfAxiom => {
127 val sub = a.getSubClass.getNNF 128 val sub = a.getSubClass.getNNF
@@ -136,19 +137,19 @@ class LowerBound extends Approximation {
136 ) 137 )
137 138
138 val r1 = 139 val r1 =
139 factory.getOWLSubClassOfAxiom( 140 LowerBound.factory.getOWLSubClassOfAxiom(
140 factory.getOWLObjectIntersectionOf( 141 LowerBound.factory.getOWLObjectIntersectionOf(
141 (body.map(_._1) ++ head.map(_._2)): _* 142 (body.map(_._1) ++ head.map(_._2)): _*
142 ), 143 ),
143 factory.getOWLNothing 144 LowerBound.factory.getOWLNothing
144 ) 145 )
145 146
146 val r2s = 147 val r2s =
147 for { 148 for {
148 (a, na) <- head 149 (a, na) <- head
149 hs = head.map(_._2).filterNot(_ equals na) 150 hs = head.map(_._2).filterNot(_ equals na)
150 } yield factory.getOWLSubClassOfAxiom( 151 } yield LowerBound.factory.getOWLSubClassOfAxiom(
151 factory.getOWLObjectIntersectionOf( 152 LowerBound.factory.getOWLObjectIntersectionOf(
152 (body.map(_._1) ++ hs): _* 153 (body.map(_._1) ++ hs): _*
153 ), 154 ),
154 a 155 a
@@ -158,8 +159,8 @@ class LowerBound extends Approximation {
158 for { 159 for {
159 (a, na) <- body 160 (a, na) <- body
160 bs = body.map(_._1).filterNot(_ equals a) 161 bs = body.map(_._1).filterNot(_ equals a)
161 } yield factory.getOWLSubClassOfAxiom( 162 } yield LowerBound.factory.getOWLSubClassOfAxiom(
162 factory.getOWLObjectIntersectionOf( 163 LowerBound.factory.getOWLObjectIntersectionOf(
163 (bs ++ head.map(_._2)): _* 164 (bs ++ head.map(_._2)): _*
164 ), 165 ),
165 na 166 na
@@ -179,14 +180,11 @@ class LowerBound extends Approximation {
179 * dependency graph from being tree-shaped, and removing them. 180 * dependency graph from being tree-shaped, and removing them.
180 * 181 *
181 * @param axioms the set of axioms to approximate. 182 * @param axioms the set of axioms to approximate.
182 * @return the approximated set of axioms. 183 * @return the approximated RSA ontology
183 */ 184 */
184 def toRSA( 185 private def toRSA(ontology: Ontology): RSAOntology = {
185 axioms: List[OWLLogicalAxiom],
186 datafiles: List[File]
187 ): List[OWLLogicalAxiom] = {
188 /* Compute the dependency graph for the ontology */ 186 /* Compute the dependency graph for the ontology */
189 val (graph, nodemap) = RSAUtil.dependencyGraph(axioms, datafiles) 187 val (graph, nodemap) = ontology.dependencyGraph
190 188
191 /* Define node colors for the graph visit */ 189 /* Define node colors for the graph visit */
192 sealed trait NodeColor 190 sealed trait NodeColor
@@ -228,7 +226,7 @@ class LowerBound extends Approximation {
228 }.toList 226 }.toList
229 227
230 /* Remove axioms from approximated ontology */ 228 /* Remove axioms from approximated ontology */
231 axioms diff toDelete 229 RSAOntology(ontology.axioms diff toDelete, ontology.datafiles)
232 } 230 }
233 231
234 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> 232 // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~>
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/ontologies/Ontology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/ontologies/Ontology.scala
index 4a23ec7..9d947bc 100644
--- a/src/main/scala/uk/ac/ox/cs/rsacomb/ontologies/Ontology.scala
+++ b/src/main/scala/uk/ac/ox/cs/rsacomb/ontologies/Ontology.scala
@@ -242,10 +242,8 @@ class Ontology(val axioms: List[OWLLogicalAxiom], val datafiles: List[File]) {
242 * technique. 242 * technique.
243 * 243 *
244 * @param approximation the approximation to be used on the ontology. 244 * @param approximation the approximation to be used on the ontology.
245 * @return a new approximated [[Ontology]]. 245 * @return the result of the approximation.
246 */ 246 */
247 def approximate(approximation: Approximation): Ontology = { 247 def approximate[T](approximation: Approximation[T]): T =
248 val approx = approximation.approximate(axioms, datafiles) 248 approximation.approximate(this)
249 new Ontology(approx, datafiles)
250 }
251} 249}