diff options
author | Federico Igne <federico.igne@cs.ox.ac.uk> | 2021-05-31 16:58:15 +0100 |
---|---|---|
committer | Federico Igne <federico.igne@cs.ox.ac.uk> | 2021-05-31 16:58:15 +0100 |
commit | 5f9815c3f67114645593840a8648bffb1207b8d0 (patch) | |
tree | 2a2e14d7fd9c686a8167447b91500bb86de696e4 | |
parent | e932527e33b6f4c1634995224188b26d870d92b2 (diff) | |
download | RSAComb-5f9815c3f67114645593840a8648bffb1207b8d0.tar.gz RSAComb-5f9815c3f67114645593840a8648bffb1207b8d0.zip |
Multiple fixes
4 files changed, 80 insertions, 54 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala index 74084af..a807f75 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | |||
@@ -108,10 +108,10 @@ object RSAComb extends App { | |||
108 | 108 | ||
109 | val ontology = RSAOntology( | 109 | val ontology = RSAOntology( |
110 | config('ontology).get[File], | 110 | config('ontology).get[File], |
111 | config('data).get[List[File]]: _* | 111 | config('data).get[List[File]], |
112 | None | ||
112 | ) | 113 | ) |
113 | val rsa = ontology.toRSA() | 114 | val rsa = ontology.toRSA() |
114 | ontology.statistics() | ||
115 | 115 | ||
116 | if (config contains 'query) { | 116 | if (config contains 'query) { |
117 | val query = | 117 | val query = |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala index e048c28..4d0f13d 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
@@ -50,13 +50,13 @@ import scala.collection.JavaConverters._ | |||
50 | import scala.collection.mutable.{Set, Map} | 50 | import scala.collection.mutable.{Set, Map} |
51 | import scalax.collection.Graph | 51 | import scalax.collection.Graph |
52 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | 52 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ |
53 | import scalax.collection.GraphTraversal._ | ||
54 | 53 | ||
55 | /* Debug only */ | 54 | /* Debug only */ |
56 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer | 55 | import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxObjectRenderer |
57 | import tech.oxfordsemantic.jrdfox.logic._ | 56 | import tech.oxfordsemantic.jrdfox.logic._ |
58 | import org.semanticweb.owlapi.model.OWLObjectInverseOf | 57 | import org.semanticweb.owlapi.model.OWLObjectInverseOf |
59 | 58 | ||
59 | import uk.ac.ox.cs.rsacomb.approximation.Approximation | ||
60 | import uk.ac.ox.cs.rsacomb.converter._ | 60 | import uk.ac.ox.cs.rsacomb.converter._ |
61 | import uk.ac.ox.cs.rsacomb.filtering.{FilteringProgram, FilterType} | 61 | import uk.ac.ox.cs.rsacomb.filtering.{FilteringProgram, FilterType} |
62 | import uk.ac.ox.cs.rsacomb.suffix._ | 62 | import uk.ac.ox.cs.rsacomb.suffix._ |
@@ -66,10 +66,10 @@ import uk.ac.ox.cs.rsacomb.util.Logger | |||
66 | 66 | ||
67 | object RSAUtil { | 67 | object RSAUtil { |
68 | 68 | ||
69 | implicit def axiomsToOntology(axioms: Seq[OWLAxiom]) = { | 69 | // implicit def axiomsToOntology(axioms: Seq[OWLAxiom]) = { |
70 | val manager = OWLManager.createOWLOntologyManager() | 70 | // val manager = OWLManager.createOWLOntologyManager() |
71 | manager.createOntology(axioms.asJava) | 71 | // manager.createOntology(axioms.asJava) |
72 | } | 72 | // } |
73 | 73 | ||
74 | /** Compute the RSA dependency graph for a set of axioms | 74 | /** Compute the RSA dependency graph for a set of axioms |
75 | * | 75 | * |
@@ -81,10 +81,10 @@ object RSAUtil { | |||
81 | * input axioms are assumed to be normalized. | 81 | * input axioms are assumed to be normalized. |
82 | */ | 82 | */ |
83 | private def dependencyGraph( | 83 | private def dependencyGraph( |
84 | axioms: Seq[OWLAxiom], | 84 | axioms: List[OWLLogicalAxiom], |
85 | datafiles: Seq[File] | 85 | datafiles: List[File] |
86 | ): (Graph[Resource, DiEdge], Map[String, OWLAxiom]) = { | 86 | ): (Graph[Resource, DiEdge], Map[String, OWLAxiom]) = { |
87 | val unsafe = this.unsafeRoles | 87 | val unsafe = RSAOntology(axioms, datafiles).unsafeRoles |
88 | var nodemap = Map.empty[String, OWLAxiom] | 88 | var nodemap = Map.empty[String, OWLAxiom] |
89 | 89 | ||
90 | object RSAConverter extends RDFoxConverter { | 90 | object RSAConverter extends RDFoxConverter { |
@@ -164,6 +164,8 @@ object RSAUtil { | |||
164 | 164 | ||
165 | object RSAOntology { | 165 | object RSAOntology { |
166 | 166 | ||
167 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | ||
168 | |||
167 | /** Name of the RDFox data store used for CQ answering */ | 169 | /** Name of the RDFox data store used for CQ answering */ |
168 | private val DataStore = "answer_computation" | 170 | private val DataStore = "answer_computation" |
169 | 171 | ||
@@ -178,9 +180,14 @@ object RSAOntology { | |||
178 | val manager = OWLManager.createOWLOntologyManager() | 180 | val manager = OWLManager.createOWLOntologyManager() |
179 | 181 | ||
180 | def apply( | 182 | def apply( |
183 | axioms: List[OWLLogicalAxiom], | ||
184 | datafiles: List[File] | ||
185 | ): RSAOntology = new RSAOntology(axioms, datafiles: _*) | ||
186 | |||
187 | def apply( | ||
181 | ontofile: File, | 188 | ontofile: File, |
182 | datafiles: Seq[File], | 189 | datafiles: List[File], |
183 | approx: Option[Approximation] = None | 190 | approx: Option[Approximation] |
184 | ): RSAOntology = { | 191 | ): RSAOntology = { |
185 | val ontology = manager.loadOntologyFromOntologyDocument(ontofile) | 192 | val ontology = manager.loadOntologyFromOntologyDocument(ontofile) |
186 | RSAOntology(ontology, datafiles, approx) | 193 | RSAOntology(ontology, datafiles, approx) |
@@ -188,14 +195,14 @@ object RSAOntology { | |||
188 | 195 | ||
189 | def apply( | 196 | def apply( |
190 | ontology: OWLOntology, | 197 | ontology: OWLOntology, |
191 | datafiles: Seq[File], | 198 | datafiles: List[File], |
192 | approx: Option[Approximation] = None | 199 | approx: Option[Approximation] |
193 | ): RSAOntology = { | 200 | ): RSAOntology = { |
194 | val normalizer = new Normalizer() | 201 | val normalizer = new Normalizer() |
195 | 202 | ||
196 | /** TBox axioms */ | 203 | /** TBox axioms */ |
197 | var tbox: List[OWLLogicalAxiom] = | 204 | var tbox: List[OWLLogicalAxiom] = |
198 | original | 205 | ontology |
199 | .tboxAxioms(Imports.INCLUDED) | 206 | .tboxAxioms(Imports.INCLUDED) |
200 | .collect(Collectors.toList()) | 207 | .collect(Collectors.toList()) |
201 | .collect { case a: OWLLogicalAxiom => a } | 208 | .collect { case a: OWLLogicalAxiom => a } |
@@ -203,7 +210,7 @@ object RSAOntology { | |||
203 | 210 | ||
204 | /** RBox axioms */ | 211 | /** RBox axioms */ |
205 | var rbox: List[OWLLogicalAxiom] = | 212 | var rbox: List[OWLLogicalAxiom] = |
206 | original | 213 | ontology |
207 | .rboxAxioms(Imports.INCLUDED) | 214 | .rboxAxioms(Imports.INCLUDED) |
208 | .collect(Collectors.toList()) | 215 | .collect(Collectors.toList()) |
209 | .collect { case a: OWLLogicalAxiom => a } | 216 | .collect { case a: OWLLogicalAxiom => a } |
@@ -217,7 +224,7 @@ object RSAOntology { | |||
217 | * large data files via OWLAPI. | 224 | * large data files via OWLAPI. |
218 | */ | 225 | */ |
219 | var abox: List[OWLLogicalAxiom] = | 226 | var abox: List[OWLLogicalAxiom] = |
220 | original | 227 | ontology |
221 | .aboxAxioms(Imports.INCLUDED) | 228 | .aboxAxioms(Imports.INCLUDED) |
222 | .collect(Collectors.toList()) | 229 | .collect(Collectors.toList()) |
223 | .collect { case a: OWLLogicalAxiom => a } | 230 | .collect { case a: OWLLogicalAxiom => a } |
@@ -231,9 +238,10 @@ object RSAOntology { | |||
231 | case Some(a) => a.approximate(axioms, datafiles) | 238 | case Some(a) => a.approximate(axioms, datafiles) |
232 | case None => axioms | 239 | case None => axioms |
233 | }, | 240 | }, |
234 | datafiles | 241 | datafiles: _* |
235 | ) | 242 | ) |
236 | } | 243 | } |
244 | |||
237 | } | 245 | } |
238 | 246 | ||
239 | /** Wrapper class for an ontology in RSA | 247 | /** Wrapper class for an ontology in RSA |
@@ -241,7 +249,7 @@ object RSAOntology { | |||
241 | * @param ontology the input OWL2 ontology. | 249 | * @param ontology the input OWL2 ontology. |
242 | * @param datafiles additinal data (treated as part of the ABox) | 250 | * @param datafiles additinal data (treated as part of the ABox) |
243 | */ | 251 | */ |
244 | class RSAOntology(val axioms: Seq[OWLAxiom], val datafiles: File*) { | 252 | class RSAOntology(val axioms: List[OWLLogicalAxiom], val datafiles: File*) { |
245 | 253 | ||
246 | /** Simplify conversion between OWLAPI and RDFox concepts */ | 254 | /** Simplify conversion between OWLAPI and RDFox concepts */ |
247 | import implicits.RDFox._ | 255 | import implicits.RDFox._ |
@@ -697,28 +705,28 @@ class RSAOntology(val axioms: Seq[OWLAxiom], val datafiles: File*) { | |||
697 | this.self(axiom) | this.cycle(axiom) | 705 | this.self(axiom) | this.cycle(axiom) |
698 | 706 | ||
699 | /** Log normalization/approximation statistics */ | 707 | /** Log normalization/approximation statistics */ |
700 | def statistics(level: Logger.Level = Logger.DEBUG): Unit = { | 708 | // def statistics(level: Logger.Level = Logger.DEBUG): Unit = { |
701 | Logger.print( | 709 | // Logger.print( |
702 | s"Logical axioms in original input ontology: ${original.getLogicalAxiomCount(true)}", | 710 | // s"Logical axioms in original input ontology: ${original.getLogicalAxiomCount(true)}", |
703 | level | 711 | // level |
704 | ) | 712 | // ) |
705 | Logger.print( | 713 | // Logger.print( |
706 | s"Logical axioms discarded in Horn-ALCHOIQ approximation: ${normalizer.discarded}", | 714 | // s"Logical axioms discarded in Horn-ALCHOIQ approximation: ${normalizer.discarded}", |
707 | level | 715 | // level |
708 | ) | 716 | // ) |
709 | Logger.print( | 717 | // Logger.print( |
710 | s"Logical axioms shifted in Horn-ALCHOIQ approximation: ${normalizer.shifted}", | 718 | // s"Logical axioms shifted in Horn-ALCHOIQ approximation: ${normalizer.shifted}", |
711 | level | 719 | // level |
712 | ) | 720 | // ) |
713 | Logger.print( | 721 | // Logger.print( |
714 | s"Logical axioms in Horn-ALCHOIQ ontology: ${ontology | 722 | // s"Logical axioms in Horn-ALCHOIQ ontology: ${ontology |
715 | .getLogicalAxiomCount(true)} (${axioms.length}/${axioms.length}/${axioms.length})", | 723 | // .getLogicalAxiomCount(true)} (${axioms.length}/${axioms.length}/${axioms.length})", |
716 | level | 724 | // level |
717 | ) | 725 | // ) |
718 | Logger.print( | 726 | // Logger.print( |
719 | s"Logical axioms discarded in RSA approximation: ${removed.length}", | 727 | // s"Logical axioms discarded in RSA approximation: ${removed.length}", |
720 | level | 728 | // level |
721 | ) | 729 | // ) |
722 | } | 730 | // } |
723 | 731 | ||
724 | } // class RSAOntology | 732 | } // class RSAOntology |
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 073d0d9..1b49413 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 | |||
@@ -1,7 +1,7 @@ | |||
1 | package uk.ac.ox.cs.rsacomb.approximation | 1 | package uk.ac.ox.cs.rsacomb.approximation |
2 | 2 | ||
3 | import java.io.File | 3 | import java.io.File |
4 | import org.semanticweb.owlapi.model.OWLAxiom | 4 | import org.semanticweb.owlapi.model.OWLLogicalAxiom |
5 | 5 | ||
6 | /** Ontology approximation technique. */ | 6 | /** Ontology approximation technique. */ |
7 | trait Approximation { | 7 | trait Approximation { |
@@ -11,6 +11,9 @@ trait Approximation { | |||
11 | * @param ontology input ontology | 11 | * @param ontology input ontology |
12 | * @return a new approximated ontology | 12 | * @return a new approximated ontology |
13 | */ | 13 | */ |
14 | def approximate(ontology: Seq[OWLAxiom], datafiles: Seq[File]): Seq[OWLAxiom] | 14 | def approximate( |
15 | ontology: List[OWLLogicalAxiom], | ||
16 | datafiles: List[File] | ||
17 | ): List[OWLLogicalAxiom] | ||
15 | 18 | ||
16 | } | 19 | } |
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 8036250..3437bcd 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 | |||
@@ -1,5 +1,16 @@ | |||
1 | package uk.ac.ox.cs.rsacomb.approximation | 1 | package uk.ac.ox.cs.rsacomb.approximation |
2 | 2 | ||
3 | import java.io.File | ||
4 | |||
5 | import org.semanticweb.owlapi.model._ | ||
6 | |||
7 | import scala.collection.mutable.{Set, Map} | ||
8 | import scalax.collection.Graph | ||
9 | import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | ||
10 | import scalax.collection.GraphTraversal._ | ||
11 | |||
12 | import uk.ac.ox.cs.rsacomb.converter.Normalizer | ||
13 | |||
3 | /** Approximation algorithm that mantains soundness for CQ answering. | 14 | /** Approximation algorithm that mantains soundness for CQ answering. |
4 | * | 15 | * |
5 | * The input OWL 2 ontology is assumed to be normalized and the output | 16 | * The input OWL 2 ontology is assumed to be normalized and the output |
@@ -21,11 +32,11 @@ class LowerBound extends Approximation { | |||
21 | 32 | ||
22 | /** Main entry point for the approximation algorithm */ | 33 | /** Main entry point for the approximation algorithm */ |
23 | def approximate( | 34 | def approximate( |
24 | ontology: Seq[OWLAxiom], | 35 | ontology: List[OWLLogicalAxiom], |
25 | datafiles: Seq[File] | 36 | datafiles: List[File] |
26 | ): Seq[OWLAxiom] = { | 37 | ): List[OWLLogicalAxiom] = { |
27 | /* Normalize axioms */ | 38 | /* Normalize axioms */ |
28 | val axioms1 = axioms flatMap normalizer.normalize | 39 | val axioms1 = axioms flatMap normalizer.normalize(_) |
29 | /* Delete any axiom outside of ALCHOIQ */ | 40 | /* Delete any axiom outside of ALCHOIQ */ |
30 | val axioms2 = axioms1 filterNot inHornLACHOIQ | 41 | val axioms2 = axioms1 filterNot inHornLACHOIQ |
31 | /* Shift any axiom with disjunction on the rhs */ | 42 | /* Shift any axiom with disjunction on the rhs */ |
@@ -95,7 +106,7 @@ class LowerBound extends Approximation { | |||
95 | * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to | 106 | * where nA, nB1, nB2, nB3 are fresh predicates "corresponding" to |
96 | * the negation of A, B1, B2, B3 respectively. | 107 | * the negation of A, B1, B2, B3 respectively. |
97 | */ | 108 | */ |
98 | def shift(axiom: OWLLogicalAxiom): Seq[OWLLogicalAxiom] = | 109 | def shift(axiom: OWLLogicalAxiom): List[OWLLogicalAxiom] = |
99 | axiom match { | 110 | axiom match { |
100 | case a: OWLSubClassOfAxiom => { | 111 | case a: OWLSubClassOfAxiom => { |
101 | val sub = a.getSubClass.getNNF | 112 | val sub = a.getSubClass.getNNF |
@@ -135,12 +146,12 @@ class LowerBound extends Approximation { | |||
135 | na | 146 | na |
136 | ) | 147 | ) |
137 | 148 | ||
138 | Seq(r1) ++ r2s ++ r3s | 149 | List(r1) ++ r2s ++ r3s |
139 | } | 150 | } |
140 | case _ => Seq(axiom) | 151 | case _ => List(axiom) |
141 | } | 152 | } |
142 | } | 153 | } |
143 | case _ => Seq(axiom) | 154 | case _ => List(axiom) |
144 | } | 155 | } |
145 | 156 | ||
146 | /** Approximate a Horn-ALCHOIQ ontology to RSA | 157 | /** Approximate a Horn-ALCHOIQ ontology to RSA |
@@ -151,7 +162,10 @@ class LowerBound extends Approximation { | |||
151 | * @param axioms the set of axioms to approximate. | 162 | * @param axioms the set of axioms to approximate. |
152 | * @return the approximated set of axioms. | 163 | * @return the approximated set of axioms. |
153 | */ | 164 | */ |
154 | def toRSA(axioms: Seq[OWLAxiom], datafiles: Seq[File]): Seq[OWLAxiom] = { | 165 | def toRSA( |
166 | axioms: List[OWLLogicalAxiom], | ||
167 | datafiles: List[File] | ||
168 | ): List[OWLLogicalAxiom] = { | ||
155 | /* Compute the dependency graph for the ontology */ | 169 | /* Compute the dependency graph for the ontology */ |
156 | val (graph, nodemap) = RSAUtil.dependencyGraph(axioms, datafiles) | 170 | val (graph, nodemap) = RSAUtil.dependencyGraph(axioms, datafiles) |
157 | 171 | ||
@@ -192,11 +206,12 @@ class LowerBound extends Approximation { | |||
192 | 206 | ||
193 | val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => | 207 | val toDelete = color.iterator.collect { case (resource: IRI, ToDelete) => |
194 | nodemap(resource.getIRI) | 208 | nodemap(resource.getIRI) |
195 | }.toSeq | 209 | }.toList |
196 | 210 | ||
197 | /* Remove axioms from approximated ontology */ | 211 | /* Remove axioms from approximated ontology */ |
198 | axioms diff toDelete | 212 | axioms diff toDelete |
199 | } | 213 | } |
214 | |||
200 | // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> | 215 | // val edges1 = Seq('A ~> 'B, 'B ~> 'C, 'C ~> 'D, 'D ~> 'H, 'H ~> |
201 | // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, | 216 | // 'G, 'G ~> 'F, 'E ~> 'A, 'E ~> 'F, 'B ~> 'E, 'F ~> 'G, 'B ~> 'F, |
202 | // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) | 217 | // 'C ~> 'G, 'D ~> 'C, 'H ~> 'D) |