diff options
author | Federico Igne <git@federicoigne.com> | 2021-08-06 13:31:54 +0100 |
---|---|---|
committer | Federico Igne <git@federicoigne.com> | 2021-08-06 13:31:54 +0100 |
commit | 75eb39dd0fd31c295b9ed9a6d3b0fd3b25611b2a (patch) | |
tree | 885cb3a76a5bdcbb685ac697e297ea8d91eb2ed8 | |
parent | 19c22a38ccaf1685e345a18883ffbac891f97df3 (diff) | |
download | RSAComb-75eb39dd0fd31c295b9ed9a6d3b0fd3b25611b2a.tar.gz RSAComb-75eb39dd0fd31c295b9ed9a6d3b0fd3b25611b2a.zip |
Add new fresh data factory
This will help write more significant test.
14 files changed, 455 insertions, 376 deletions
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala index ca54054..3467d3c 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/CanonicalModel.scala | |||
@@ -39,7 +39,7 @@ import implicits.JavaCollections._ | |||
39 | 39 | ||
40 | import uk.ac.ox.cs.rsacomb.converter._ | 40 | import uk.ac.ox.cs.rsacomb.converter._ |
41 | import uk.ac.ox.cs.rsacomb.suffix._ | 41 | import uk.ac.ox.cs.rsacomb.suffix._ |
42 | import uk.ac.ox.cs.rsacomb.util.RSA | 42 | import uk.ac.ox.cs.rsacomb.util.{DataFactory, RSA} |
43 | 43 | ||
44 | /** Canonical model generator | 44 | /** Canonical model generator |
45 | * | 45 | * |
@@ -92,7 +92,7 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
92 | val (facts, rules): (List[TupleTableAtom], List[Rule]) = { | 92 | val (facts, rules): (List[TupleTableAtom], List[Rule]) = { |
93 | // Compute rules from ontology axioms | 93 | // Compute rules from ontology axioms |
94 | val (facts, rules) = { | 94 | val (facts, rules) = { |
95 | val term = RSAUtil.genFreshVariable() | 95 | val term = Variable.create("X") |
96 | val unsafe = ontology.unsafe | 96 | val unsafe = ontology.unsafe |
97 | ontology.axioms | 97 | ontology.axioms |
98 | .map(a => | 98 | .map(a => |
@@ -216,13 +216,13 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
216 | unsafe: List[OWLObjectPropertyExpression], | 216 | unsafe: List[OWLObjectPropertyExpression], |
217 | skolem: SkolemStrategy, | 217 | skolem: SkolemStrategy, |
218 | suffix: RSASuffix | 218 | suffix: RSASuffix |
219 | ): Result = | 219 | )(implicit fresh: DataFactory): Result = |
220 | axiom match { | 220 | axiom match { |
221 | 221 | ||
222 | case a: OWLSubClassOfAxiom if a.isT5 => { | 222 | case a: OWLSubClassOfAxiom if a.isT5 => { |
223 | val role = axiom.objectPropertyExpressionsInSignature(0) | 223 | val role = axiom.objectPropertyExpressionsInSignature(0) |
224 | if (unsafe contains role) | 224 | if (unsafe contains role) |
225 | super.convert(a, term, unsafe, new Standard(a), Forward) | 225 | super.convert(a, term, unsafe, new Standard(a), Forward)(fresh) |
226 | else { | 226 | else { |
227 | val (f1, r1) = rules1(a) | 227 | val (f1, r1) = rules1(a) |
228 | (f1, r1 ::: rules2(a) ::: rules3(a)) | 228 | (f1, r1 ::: rules2(a) ::: rules3(a)) |
@@ -231,12 +231,12 @@ class CanonicalModel(val ontology: RSAOntology) { | |||
231 | 231 | ||
232 | case a: OWLSubObjectPropertyOfAxiom => { | 232 | case a: OWLSubObjectPropertyOfAxiom => { |
233 | val (facts, rules) = List(Empty, Forward, Backward) | 233 | val (facts, rules) = List(Empty, Forward, Backward) |
234 | .map(super.convert(a, term, unsafe, NoSkolem, _)) | 234 | .map(super.convert(a, term, unsafe, NoSkolem, _)(fresh)) |
235 | .unzip | 235 | .unzip |
236 | (facts.flatten, rules.flatten) | 236 | (facts.flatten, rules.flatten) |
237 | } | 237 | } |
238 | 238 | ||
239 | case a => super.convert(a, term, unsafe, skolem, suffix) | 239 | case a => super.convert(a, term, unsafe, skolem, suffix)(fresh) |
240 | 240 | ||
241 | } | 241 | } |
242 | } | 242 | } |
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 4c63e17..a1fd20f 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/Main.scala | |||
@@ -28,7 +28,7 @@ import sparql.ConjunctiveQuery | |||
28 | 28 | ||
29 | import uk.ac.ox.cs.rsacomb.ontology.Ontology | 29 | import uk.ac.ox.cs.rsacomb.ontology.Ontology |
30 | import uk.ac.ox.cs.rsacomb.converter.Normalizer | 30 | import uk.ac.ox.cs.rsacomb.converter.Normalizer |
31 | import uk.ac.ox.cs.rsacomb.approximation.Lowerbound | 31 | import uk.ac.ox.cs.rsacomb.approximation.{Upperbound, Lowerbound} |
32 | 32 | ||
33 | case class RSAOption[+T](opt: T) { | 33 | case class RSAOption[+T](opt: T) { |
34 | def get[T]: T = opt.asInstanceOf[T] | 34 | def get[T]: T = opt.asInstanceOf[T] |
@@ -133,7 +133,7 @@ object RSAComb extends App { | |||
133 | ).normalize(new Normalizer) | 133 | ).normalize(new Normalizer) |
134 | 134 | ||
135 | /* Approximate the ontology to RSA */ | 135 | /* Approximate the ontology to RSA */ |
136 | val toRSA = new Lowerbound | 136 | val toRSA = new Upperbound |
137 | val rsa = ontology approximate toRSA | 137 | val rsa = ontology approximate toRSA |
138 | 138 | ||
139 | if (config contains 'query) { | 139 | if (config contains '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 30e1305..869dd88 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/RSAOntology.scala | |||
@@ -81,30 +81,6 @@ import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} | |||
81 | import uk.ac.ox.cs.rsacomb.util.Logger | 81 | import uk.ac.ox.cs.rsacomb.util.Logger |
82 | import uk.ac.ox.cs.rsacomb.ontology.Ontology | 82 | import uk.ac.ox.cs.rsacomb.ontology.Ontology |
83 | 83 | ||
84 | object RSAUtil { | ||
85 | |||
86 | // implicit def axiomsToOntology(axioms: Seq[OWLAxiom]) = { | ||
87 | // val manager = OWLManager.createOWLOntologyManager() | ||
88 | // manager.createOntology(axioms.asJava) | ||
89 | // } | ||
90 | |||
91 | /** Manager instance to interface with OWLAPI */ | ||
92 | val manager = OWLManager.createOWLOntologyManager() | ||
93 | val factory = manager.getOWLDataFactory() | ||
94 | |||
95 | /** Simple fresh variable/class generator */ | ||
96 | private var counter = -1; | ||
97 | def genFreshVariable(): Variable = { | ||
98 | counter += 1 | ||
99 | Variable.create(f"I$counter%05d") | ||
100 | } | ||
101 | def getFreshOWLClass(): OWLClass = { | ||
102 | counter += 1 | ||
103 | factory.getOWLClass(s"X$counter") | ||
104 | } | ||
105 | |||
106 | } | ||
107 | |||
108 | object RSAOntology { | 84 | object RSAOntology { |
109 | 85 | ||
110 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | 86 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ |
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 290cbaf..88732d5 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 | |||
@@ -13,8 +13,8 @@ import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | |||
13 | import scalax.collection.GraphTraversal._ | 13 | import scalax.collection.GraphTraversal._ |
14 | 14 | ||
15 | import uk.ac.ox.cs.rsacomb.RSAOntology | 15 | import uk.ac.ox.cs.rsacomb.RSAOntology |
16 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
17 | import uk.ac.ox.cs.rsacomb.ontology.Ontology | 16 | import uk.ac.ox.cs.rsacomb.ontology.Ontology |
17 | import uk.ac.ox.cs.rsacomb.util.DataFactory | ||
18 | 18 | ||
19 | object Lowerbound { | 19 | object Lowerbound { |
20 | 20 | ||
@@ -38,7 +38,8 @@ object Lowerbound { | |||
38 | * | 38 | * |
39 | * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]] | 39 | * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]] |
40 | */ | 40 | */ |
41 | class Lowerbound extends Approximation[RSAOntology] { | 41 | class Lowerbound(implicit fresh: DataFactory) |
42 | extends Approximation[RSAOntology] { | ||
42 | 43 | ||
43 | /** Simplify conversion between Java and Scala collections */ | 44 | /** Simplify conversion between Java and Scala collections */ |
44 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | 45 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ |
@@ -122,12 +123,10 @@ class Lowerbound extends Approximation[RSAOntology] { | |||
122 | val sup = a.getSuperClass.getNNF | 123 | val sup = a.getSuperClass.getNNF |
123 | sup match { | 124 | sup match { |
124 | case sup: OWLObjectUnionOf => { | 125 | case sup: OWLObjectUnionOf => { |
125 | val body = sub.asConjunctSet.map((atom) => | 126 | val body = |
126 | (atom, RSAUtil.getFreshOWLClass()) | 127 | sub.asConjunctSet.map((atom) => (atom, fresh.getOWLClass)) |
127 | ) | 128 | val head = |
128 | val head = sup.asDisjunctSet.map((atom) => | 129 | sup.asDisjunctSet.map((atom) => (atom, fresh.getOWLClass)) |
129 | (atom, RSAUtil.getFreshOWLClass()) | ||
130 | ) | ||
131 | 130 | ||
132 | val r1 = | 131 | val r1 = |
133 | Lowerbound.factory.getOWLSubClassOfAxiom( | 132 | Lowerbound.factory.getOWLSubClassOfAxiom( |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala index ad924aa..1ae7941 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/approximation/Upperbound.scala | |||
@@ -13,8 +13,8 @@ import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | |||
13 | import scalax.collection.GraphTraversal._ | 13 | import scalax.collection.GraphTraversal._ |
14 | 14 | ||
15 | import uk.ac.ox.cs.rsacomb.RSAOntology | 15 | import uk.ac.ox.cs.rsacomb.RSAOntology |
16 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
17 | import uk.ac.ox.cs.rsacomb.ontology.Ontology | 16 | import uk.ac.ox.cs.rsacomb.ontology.Ontology |
17 | import uk.ac.ox.cs.rsacomb.util.DataFactory | ||
18 | 18 | ||
19 | object Upperbound { | 19 | object Upperbound { |
20 | 20 | ||
@@ -38,7 +38,8 @@ object Upperbound { | |||
38 | * | 38 | * |
39 | * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]] | 39 | * @see [[uk.ac.ox.cs.rsacomb.converter.Normalizer]] |
40 | */ | 40 | */ |
41 | class Upperbound extends Approximation[RSAOntology] { | 41 | class Upperbound(implicit fresh: DataFactory) |
42 | extends Approximation[RSAOntology] { | ||
42 | 43 | ||
43 | /** Simplify conversion between Java and Scala collections */ | 44 | /** Simplify conversion between Java and Scala collections */ |
44 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | 45 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ |
@@ -138,15 +139,17 @@ class Upperbound extends Approximation[RSAOntology] { | |||
138 | import uk.ac.ox.cs.rsacomb.implicits.RSAAxiom._ | 139 | import uk.ac.ox.cs.rsacomb.implicits.RSAAxiom._ |
139 | axiom.toTriple match { | 140 | axiom.toTriple match { |
140 | case Some((subclass, role, filler)) => { | 141 | case Some((subclass, role, filler)) => { |
141 | val skolem = Upperbound.factory.getOWLNamedIndividual(s"i_${axiom.toString.hashCode}") | 142 | val skolem = Upperbound.factory.getOWLNamedIndividual( |
142 | val fresh = RSAUtil.getFreshOWLClass() | 143 | s"i_${axiom.toString.hashCode}" |
144 | ) | ||
145 | val cls = fresh.getOWLClass | ||
143 | List( | 146 | List( |
144 | Upperbound.factory.getOWLSubClassOfAxiom( | 147 | Upperbound.factory.getOWLSubClassOfAxiom( |
145 | subclass, | 148 | subclass, |
146 | Upperbound.factory.getOWLObjectSomeValuesFrom(role, fresh) | 149 | Upperbound.factory.getOWLObjectSomeValuesFrom(role, cls) |
147 | ), | 150 | ), |
148 | Upperbound.factory.getOWLSubClassOfAxiom( | 151 | Upperbound.factory.getOWLSubClassOfAxiom( |
149 | fresh, | 152 | cls, |
150 | Upperbound.factory.getOWLObjectOneOf(skolem) | 153 | Upperbound.factory.getOWLObjectOneOf(skolem) |
151 | ), | 154 | ), |
152 | Upperbound.factory.getOWLClassAssertionAxiom(filler, skolem) | 155 | Upperbound.factory.getOWLClassAssertionAxiom(filler, skolem) |
@@ -169,5 +172,5 @@ class Upperbound extends Approximation[RSAOntology] { | |||
169 | // val edges2 = Seq('I ~> 'M, 'I ~> 'L, 'L ~> 'N, 'M ~> 'N) | 172 | // val edges2 = Seq('I ~> 'M, 'I ~> 'L, 'L ~> 'N, 'M ~> 'N) |
170 | // val edges3 = Seq('P ~> 'O) | 173 | // val edges3 = Seq('P ~> 'O) |
171 | // val graph = Graph.from(edges = edges1 ++ edges2 ++ edges3) | 174 | // val graph = Graph.from(edges = edges1 ++ edges2 ++ edges3) |
172 | 175 | ||
173 | } | 176 | } |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala index b5da3cc..c24f99d 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/Normalizer.scala | |||
@@ -19,9 +19,8 @@ package uk.ac.ox.cs.rsacomb.converter | |||
19 | import org.semanticweb.owlapi.apibinding.OWLManager | 19 | import org.semanticweb.owlapi.apibinding.OWLManager |
20 | import org.semanticweb.owlapi.model._ | 20 | import org.semanticweb.owlapi.model._ |
21 | 21 | ||
22 | import uk.ac.ox.cs.rsacomb.util.Logger | 22 | import uk.ac.ox.cs.rsacomb.util.{Logger, DataFactory} |
23 | import uk.ac.ox.cs.rsacomb.RSAOntology | 23 | import uk.ac.ox.cs.rsacomb.RSAOntology |
24 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
25 | 24 | ||
26 | object Normalizer { | 25 | object Normalizer { |
27 | 26 | ||
@@ -45,7 +44,9 @@ class Normalizer() { | |||
45 | 44 | ||
46 | /** Normalizes a [[OWLLogicalAxiom]] | 45 | /** Normalizes a [[OWLLogicalAxiom]] |
47 | */ | 46 | */ |
48 | def normalize(axiom: OWLLogicalAxiom): Seq[OWLLogicalAxiom] = | 47 | def normalize( |
48 | axiom: OWLLogicalAxiom | ||
49 | )(implicit fresh: DataFactory): Seq[OWLLogicalAxiom] = | ||
49 | axiom match { | 50 | axiom match { |
50 | case a: OWLSubClassOfAxiom => { | 51 | case a: OWLSubClassOfAxiom => { |
51 | val sub = a.getSubClass.getNNF | 52 | val sub = a.getSubClass.getNNF |
@@ -56,11 +57,11 @@ class Normalizer() { | |||
56 | * C c D -> { C c X, X c D } | 57 | * C c D -> { C c X, X c D } |
57 | */ | 58 | */ |
58 | case _ if !sub.isOWLClass && !sup.isOWLClass => { | 59 | case _ if !sub.isOWLClass && !sup.isOWLClass => { |
59 | val cls = RSAUtil.getFreshOWLClass() | 60 | val cls = fresh.getOWLClass |
60 | Seq( | 61 | Seq( |
61 | factory.getOWLSubClassOfAxiom(sub, cls), | 62 | factory.getOWLSubClassOfAxiom(sub, cls), |
62 | factory.getOWLSubClassOfAxiom(cls, sup) | 63 | factory.getOWLSubClassOfAxiom(cls, sup) |
63 | ).flatMap(normalize) | 64 | ).flatMap(normalize(_)(fresh)) |
64 | } | 65 | } |
65 | /** Conjunction on the lhs | 66 | /** Conjunction on the lhs |
66 | * | 67 | * |
@@ -77,7 +78,7 @@ class Normalizer() { | |||
77 | if (conj.isOWLClass) | 78 | if (conj.isOWLClass) |
78 | (acc1 :+ conj, acc2) | 79 | (acc1 :+ conj, acc2) |
79 | else { | 80 | else { |
80 | val cls = RSAUtil.getFreshOWLClass() | 81 | val cls = fresh.getOWLClass |
81 | ( | 82 | ( |
82 | acc1 :+ cls, | 83 | acc1 :+ cls, |
83 | acc2 :+ factory.getOWLSubClassOfAxiom(conj, cls) | 84 | acc2 :+ factory.getOWLSubClassOfAxiom(conj, cls) |
@@ -89,9 +90,11 @@ class Normalizer() { | |||
89 | factory.getOWLObjectIntersectionOf(acc1: _*), | 90 | factory.getOWLObjectIntersectionOf(acc1: _*), |
90 | sup | 91 | sup |
91 | )) | 92 | )) |
92 | .flatMap(normalize) | 93 | .flatMap(normalize(_)(fresh)) |
93 | } else { | 94 | } else { |
94 | normalize(factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup)) | 95 | normalize( |
96 | factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup) | ||
97 | )(fresh) | ||
95 | } | 98 | } |
96 | } | 99 | } |
97 | /** Conjunction on the rhs | 100 | /** Conjunction on the rhs |
@@ -103,9 +106,11 @@ class Normalizer() { | |||
103 | if (conjuncts.length > 0) { | 106 | if (conjuncts.length > 0) { |
104 | conjuncts | 107 | conjuncts |
105 | .map(cls => factory.getOWLSubClassOfAxiom(sub, cls)) | 108 | .map(cls => factory.getOWLSubClassOfAxiom(sub, cls)) |
106 | .flatMap(normalize) | 109 | .flatMap(normalize(_)(fresh)) |
107 | } else { | 110 | } else { |
108 | normalize(factory.getOWLSubClassOfAxiom(sub, factory.getOWLThing)) | 111 | normalize( |
112 | factory.getOWLSubClassOfAxiom(sub, factory.getOWLThing) | ||
113 | )(fresh) | ||
109 | } | 114 | } |
110 | } | 115 | } |
111 | /** Disjunction on the lhs | 116 | /** Disjunction on the lhs |
@@ -117,11 +122,11 @@ class Normalizer() { | |||
117 | if (disjuncts.length > 0) { | 122 | if (disjuncts.length > 0) { |
118 | disjuncts | 123 | disjuncts |
119 | .map(cls => factory.getOWLSubClassOfAxiom(cls, sup)) | 124 | .map(cls => factory.getOWLSubClassOfAxiom(cls, sup)) |
120 | .flatMap(normalize) | 125 | .flatMap(normalize(_)(fresh)) |
121 | } else { | 126 | } else { |
122 | normalize( | 127 | normalize( |
123 | factory.getOWLSubClassOfAxiom(factory.getOWLNothing, sup) | 128 | factory.getOWLSubClassOfAxiom(factory.getOWLNothing, sup) |
124 | ) | 129 | )(fresh) |
125 | } | 130 | } |
126 | } | 131 | } |
127 | /** Disjunction on the rhs | 132 | /** Disjunction on the rhs |
@@ -137,9 +142,10 @@ class Normalizer() { | |||
137 | if (disjuncts.length > 0) { | 142 | if (disjuncts.length > 0) { |
138 | val acc = (Seq[OWLClassExpression](), Seq[OWLLogicalAxiom]()) | 143 | val acc = (Seq[OWLClassExpression](), Seq[OWLLogicalAxiom]()) |
139 | val (acc1, acc2) = disjuncts.foldLeft(acc)( | 144 | val (acc1, acc2) = disjuncts.foldLeft(acc)( |
140 | { case ((acc1, acc2), disj: OWLClass) => (acc1 :+ disj, acc2) | 145 | { |
146 | case ((acc1, acc2), disj: OWLClass) => (acc1 :+ disj, acc2) | ||
141 | case ((acc1, acc2), disj) => { | 147 | case ((acc1, acc2), disj) => { |
142 | val cls = RSAUtil.getFreshOWLClass() | 148 | val cls = fresh.getOWLClass |
143 | ( | 149 | ( |
144 | acc1 :+ cls, | 150 | acc1 :+ cls, |
145 | acc2 :+ factory.getOWLSubClassOfAxiom(cls, disj) | 151 | acc2 :+ factory.getOWLSubClassOfAxiom(cls, disj) |
@@ -150,9 +156,11 @@ class Normalizer() { | |||
150 | (acc2 :+ factory.getOWLSubClassOfAxiom( | 156 | (acc2 :+ factory.getOWLSubClassOfAxiom( |
151 | sub, | 157 | sub, |
152 | factory.getOWLObjectUnionOf(acc1: _*) | 158 | factory.getOWLObjectUnionOf(acc1: _*) |
153 | )).flatMap(normalize) | 159 | )).flatMap(normalize(_)(fresh)) |
154 | } else { | 160 | } else { |
155 | normalize(factory.getOWLSubClassOfAxiom(sub, factory.getOWLNothing)) | 161 | normalize( |
162 | factory.getOWLSubClassOfAxiom(sub, factory.getOWLNothing) | ||
163 | )(fresh) | ||
156 | } | 164 | } |
157 | } | 165 | } |
158 | /** Complex class expression on existential restriction on the lhs | 166 | /** Complex class expression on existential restriction on the lhs |
@@ -161,14 +169,14 @@ class Normalizer() { | |||
161 | */ | 169 | */ |
162 | case (sub: OWLObjectSomeValuesFrom, _) | 170 | case (sub: OWLObjectSomeValuesFrom, _) |
163 | if !sub.getFiller.isOWLClass => { | 171 | if !sub.getFiller.isOWLClass => { |
164 | val cls = RSAUtil.getFreshOWLClass() | 172 | val cls = fresh.getOWLClass |
165 | Seq( | 173 | Seq( |
166 | factory.getOWLSubClassOfAxiom(sub.getFiller, cls), | 174 | factory.getOWLSubClassOfAxiom(sub.getFiller, cls), |
167 | factory.getOWLSubClassOfAxiom( | 175 | factory.getOWLSubClassOfAxiom( |
168 | factory.getOWLObjectSomeValuesFrom(sub.getProperty, cls), | 176 | factory.getOWLObjectSomeValuesFrom(sub.getProperty, cls), |
169 | sup | 177 | sup |
170 | ) | 178 | ) |
171 | ).flatMap(normalize) | 179 | ).flatMap(normalize(_)(fresh)) |
172 | } | 180 | } |
173 | /** Complex class expression on existential restriction on the rhs | 181 | /** Complex class expression on existential restriction on the rhs |
174 | * | 182 | * |
@@ -176,14 +184,14 @@ class Normalizer() { | |||
176 | */ | 184 | */ |
177 | case (_, sup: OWLObjectSomeValuesFrom) | 185 | case (_, sup: OWLObjectSomeValuesFrom) |
178 | if !sup.getFiller.isOWLClass => { | 186 | if !sup.getFiller.isOWLClass => { |
179 | val cls = RSAUtil.getFreshOWLClass() | 187 | val cls = fresh.getOWLClass |
180 | Seq( | 188 | Seq( |
181 | factory.getOWLSubClassOfAxiom(cls, sup.getFiller), | 189 | factory.getOWLSubClassOfAxiom(cls, sup.getFiller), |
182 | factory.getOWLSubClassOfAxiom( | 190 | factory.getOWLSubClassOfAxiom( |
183 | sub, | 191 | sub, |
184 | factory.getOWLObjectSomeValuesFrom(sup.getProperty, cls) | 192 | factory.getOWLObjectSomeValuesFrom(sup.getProperty, cls) |
185 | ) | 193 | ) |
186 | ).flatMap(normalize) | 194 | ).flatMap(normalize(_)(fresh)) |
187 | } | 195 | } |
188 | /** Object universal quantification on the lhs | 196 | /** Object universal quantification on the lhs |
189 | * | 197 | * |
@@ -197,7 +205,7 @@ class Normalizer() { | |||
197 | case (sub: OWLObjectAllValuesFrom, _) => { | 205 | case (sub: OWLObjectAllValuesFrom, _) => { |
198 | val role = sub.getProperty | 206 | val role = sub.getProperty |
199 | val filler = sub.getFiller | 207 | val filler = sub.getFiller |
200 | val (c, d) = (RSAUtil.getFreshOWLClass, RSAUtil.getFreshOWLClass) | 208 | val (c, d) = (fresh.getOWLClass, fresh.getOWLClass) |
201 | Seq( | 209 | Seq( |
202 | factory.getOWLSubClassOfAxiom( | 210 | factory.getOWLSubClassOfAxiom( |
203 | factory.getOWLThing, | 211 | factory.getOWLThing, |
@@ -208,12 +216,13 @@ class Normalizer() { | |||
208 | factory.getOWLNothing | 216 | factory.getOWLNothing |
209 | ), | 217 | ), |
210 | factory.getOWLSubClassOfAxiom( | 218 | factory.getOWLSubClassOfAxiom( |
211 | c, factory.getOWLObjectSomeValuesFrom(role, d) | 219 | c, |
220 | factory.getOWLObjectSomeValuesFrom(role, d) | ||
212 | ) | 221 | ) |
213 | ) | 222 | ) |
214 | } | 223 | } |
215 | /** Object/Data universal quantification on the lhs */ | 224 | /** Object/Data universal quantification on the lhs */ |
216 | case (sub: OWLDataAllValuesFrom, _) => notSupported(a) | 225 | case (sub: OWLDataAllValuesFrom, _) => notSupported(a) |
217 | /** Object universal quantification on the rhs | 226 | /** Object universal quantification on the rhs |
218 | * | 227 | * |
219 | * C c forall R . D -> exists R- . C c D | 228 | * C c forall R . D -> exists R- . C c D |
@@ -228,7 +237,7 @@ class Normalizer() { | |||
228 | ), | 237 | ), |
229 | sup.getFiller | 238 | sup.getFiller |
230 | ) | 239 | ) |
231 | ) | 240 | )(fresh) |
232 | /** Object universal quantification on the rhs not supported */ | 241 | /** Object universal quantification on the rhs not supported */ |
233 | case (_, sup: OWLDataAllValuesFrom) => notSupported(a) | 242 | case (_, sup: OWLDataAllValuesFrom) => notSupported(a) |
234 | /** Exact object/data cardinality restriction on the lhs/rhs | 243 | /** Exact object/data cardinality restriction on the lhs/rhs |
@@ -238,19 +247,19 @@ class Normalizer() { | |||
238 | case (sub: OWLObjectExactCardinality, _) => | 247 | case (sub: OWLObjectExactCardinality, _) => |
239 | normalize( | 248 | normalize( |
240 | factory.getOWLSubClassOfAxiom(sub.asIntersectionOfMinMax, sup) | 249 | factory.getOWLSubClassOfAxiom(sub.asIntersectionOfMinMax, sup) |
241 | ) | 250 | )(fresh) |
242 | case (sub: OWLDataExactCardinality, _) => | 251 | case (sub: OWLDataExactCardinality, _) => |
243 | normalize( | 252 | normalize( |
244 | factory.getOWLSubClassOfAxiom(sub.asIntersectionOfMinMax, sup) | 253 | factory.getOWLSubClassOfAxiom(sub.asIntersectionOfMinMax, sup) |
245 | ) | 254 | )(fresh) |
246 | case (_, sup: OWLObjectExactCardinality) => | 255 | case (_, sup: OWLObjectExactCardinality) => |
247 | normalize( | 256 | normalize( |
248 | factory.getOWLSubClassOfAxiom(sub, sup.asIntersectionOfMinMax) | 257 | factory.getOWLSubClassOfAxiom(sub, sup.asIntersectionOfMinMax) |
249 | ) | 258 | )(fresh) |
250 | case (_, sup: OWLDataExactCardinality) => | 259 | case (_, sup: OWLDataExactCardinality) => |
251 | normalize( | 260 | normalize( |
252 | factory.getOWLSubClassOfAxiom(sub, sup.asIntersectionOfMinMax) | 261 | factory.getOWLSubClassOfAxiom(sub, sup.asIntersectionOfMinMax) |
253 | ) | 262 | )(fresh) |
254 | /** Min object/data cardinality restriction on the lhs/rhs | 263 | /** Min object/data cardinality restriction on the lhs/rhs |
255 | * | 264 | * |
256 | * >= 0 R . C -> top | 265 | * >= 0 R . C -> top |
@@ -263,7 +272,7 @@ class Normalizer() { | |||
263 | case 0 => | 272 | case 0 => |
264 | normalize( | 273 | normalize( |
265 | factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup) | 274 | factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup) |
266 | ) | 275 | )(fresh) |
267 | case 1 => | 276 | case 1 => |
268 | normalize( | 277 | normalize( |
269 | factory.getOWLSubClassOfAxiom( | 278 | factory.getOWLSubClassOfAxiom( |
@@ -273,7 +282,7 @@ class Normalizer() { | |||
273 | ), | 282 | ), |
274 | sup | 283 | sup |
275 | ) | 284 | ) |
276 | ) | 285 | )(fresh) |
277 | case _ => notSupported(a) | 286 | case _ => notSupported(a) |
278 | } | 287 | } |
279 | case (sub: OWLDataMinCardinality, _) => | 288 | case (sub: OWLDataMinCardinality, _) => |
@@ -281,7 +290,7 @@ class Normalizer() { | |||
281 | case 0 => | 290 | case 0 => |
282 | normalize( | 291 | normalize( |
283 | factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup) | 292 | factory.getOWLSubClassOfAxiom(factory.getOWLThing, sup) |
284 | ) | 293 | )(fresh) |
285 | case 1 => | 294 | case 1 => |
286 | normalize( | 295 | normalize( |
287 | factory.getOWLSubClassOfAxiom( | 296 | factory.getOWLSubClassOfAxiom( |
@@ -291,7 +300,7 @@ class Normalizer() { | |||
291 | ), | 300 | ), |
292 | sup | 301 | sup |
293 | ) | 302 | ) |
294 | ) | 303 | )(fresh) |
295 | case _ => notSupported(a) | 304 | case _ => notSupported(a) |
296 | } | 305 | } |
297 | case (_, sup: OWLObjectMinCardinality) => | 306 | case (_, sup: OWLObjectMinCardinality) => |
@@ -306,7 +315,7 @@ class Normalizer() { | |||
306 | sup.getFiller | 315 | sup.getFiller |
307 | ) | 316 | ) |
308 | ) | 317 | ) |
309 | ) | 318 | )(fresh) |
310 | case _ => notSupported(a) | 319 | case _ => notSupported(a) |
311 | } | 320 | } |
312 | case (_, sup: OWLDataMinCardinality) => | 321 | case (_, sup: OWLDataMinCardinality) => |
@@ -321,7 +330,7 @@ class Normalizer() { | |||
321 | sup.getFiller | 330 | sup.getFiller |
322 | ) | 331 | ) |
323 | ) | 332 | ) |
324 | ) | 333 | )(fresh) |
325 | case _ => notSupported(a) | 334 | case _ => notSupported(a) |
326 | } | 335 | } |
327 | /** Max object/data cardinality restriction on the lhs not supported */ | 336 | /** Max object/data cardinality restriction on the lhs not supported */ |
@@ -344,17 +353,17 @@ class Normalizer() { | |||
344 | ), | 353 | ), |
345 | factory.getOWLNothing | 354 | factory.getOWLNothing |
346 | ) | 355 | ) |
347 | ) | 356 | )(fresh) |
348 | case (_, sup: OWLObjectMaxCardinality) | 357 | case (_, sup: OWLObjectMaxCardinality) |
349 | if sup.getCardinality == 1 && !sup.getFiller.isOWLClass => { | 358 | if sup.getCardinality == 1 && !sup.getFiller.isOWLClass => { |
350 | val cls = RSAUtil.getFreshOWLClass() | 359 | val cls = fresh.getOWLClass |
351 | Seq( | 360 | Seq( |
352 | factory.getOWLSubClassOfAxiom(cls, sup.getFiller), | 361 | factory.getOWLSubClassOfAxiom(cls, sup.getFiller), |
353 | factory.getOWLSubClassOfAxiom( | 362 | factory.getOWLSubClassOfAxiom( |
354 | sub, | 363 | sub, |
355 | factory.getOWLObjectMaxCardinality(1, sup.getProperty, cls) | 364 | factory.getOWLObjectMaxCardinality(1, sup.getProperty, cls) |
356 | ) | 365 | ) |
357 | ).flatMap(normalize) | 366 | ).flatMap(normalize(_)(fresh)) |
358 | } | 367 | } |
359 | case (_, sup: OWLObjectMaxCardinality) if sup.getCardinality >= 2 => | 368 | case (_, sup: OWLObjectMaxCardinality) if sup.getCardinality >= 2 => |
360 | notSupported(a) | 369 | notSupported(a) |
@@ -368,7 +377,7 @@ class Normalizer() { | |||
368 | ), | 377 | ), |
369 | factory.getOWLNothing | 378 | factory.getOWLNothing |
370 | ) | 379 | ) |
371 | ) | 380 | )(fresh) |
372 | case (_, sup: OWLDataMaxCardinality) if sup.getCardinality >= 1 => | 381 | case (_, sup: OWLDataMaxCardinality) if sup.getCardinality >= 1 => |
373 | notSupported(a) | 382 | notSupported(a) |
374 | /** HasValue expression on the lhs/rhs | 383 | /** HasValue expression on the lhs/rhs |
@@ -384,7 +393,7 @@ class Normalizer() { | |||
384 | ), | 393 | ), |
385 | sup | 394 | sup |
386 | ) | 395 | ) |
387 | ) | 396 | )(fresh) |
388 | case (sub: OWLDataHasValue, _) => | 397 | case (sub: OWLDataHasValue, _) => |
389 | normalize( | 398 | normalize( |
390 | factory.getOWLSubClassOfAxiom( | 399 | factory.getOWLSubClassOfAxiom( |
@@ -394,7 +403,7 @@ class Normalizer() { | |||
394 | ), | 403 | ), |
395 | sup | 404 | sup |
396 | ) | 405 | ) |
397 | ) | 406 | )(fresh) |
398 | case (_, sup: OWLObjectHasValue) => | 407 | case (_, sup: OWLObjectHasValue) => |
399 | normalize( | 408 | normalize( |
400 | factory.getOWLSubClassOfAxiom( | 409 | factory.getOWLSubClassOfAxiom( |
@@ -404,7 +413,7 @@ class Normalizer() { | |||
404 | factory.getOWLObjectOneOf(sup.getFiller) | 413 | factory.getOWLObjectOneOf(sup.getFiller) |
405 | ) | 414 | ) |
406 | ) | 415 | ) |
407 | ) | 416 | )(fresh) |
408 | case (_, sup: OWLDataHasValue) => | 417 | case (_, sup: OWLDataHasValue) => |
409 | normalize( | 418 | normalize( |
410 | factory.getOWLSubClassOfAxiom( | 419 | factory.getOWLSubClassOfAxiom( |
@@ -414,7 +423,7 @@ class Normalizer() { | |||
414 | factory.getOWLDataOneOf(sup.getFiller) | 423 | factory.getOWLDataOneOf(sup.getFiller) |
415 | ) | 424 | ) |
416 | ) | 425 | ) |
417 | ) | 426 | )(fresh) |
418 | /** Enumeration of individuals on the lhs | 427 | /** Enumeration of individuals on the lhs |
419 | * | 428 | * |
420 | * {a1, ... ,an} c D -> { D(a1), ..., D(an) } | 429 | * {a1, ... ,an} c D -> { D(a1), ..., D(an) } |
@@ -433,7 +442,7 @@ class Normalizer() { | |||
433 | sup.getIndividuals.map(factory.getOWLObjectOneOf(_)) | 442 | sup.getIndividuals.map(factory.getOWLObjectOneOf(_)) |
434 | ) | 443 | ) |
435 | ) | 444 | ) |
436 | ) | 445 | )(fresh) |
437 | /** Class complement on the lhs | 446 | /** Class complement on the lhs |
438 | * | 447 | * |
439 | * ~C c D -> top c C u D | 448 | * ~C c D -> top c C u D |
@@ -444,7 +453,7 @@ class Normalizer() { | |||
444 | factory.getOWLThing, | 453 | factory.getOWLThing, |
445 | factory.getOWLObjectUnionOf(sub.getComplementNNF, sup) | 454 | factory.getOWLObjectUnionOf(sub.getComplementNNF, sup) |
446 | ) | 455 | ) |
447 | ) | 456 | )(fresh) |
448 | /** Class complement on the rhs | 457 | /** Class complement on the rhs |
449 | * | 458 | * |
450 | * C c ~D -> C n D c bot | 459 | * C c ~D -> C n D c bot |
@@ -455,7 +464,7 @@ class Normalizer() { | |||
455 | factory.getOWLObjectIntersectionOf(sup.getComplementNNF, sub), | 464 | factory.getOWLObjectIntersectionOf(sup.getComplementNNF, sub), |
456 | factory.getOWLNothing | 465 | factory.getOWLNothing |
457 | ) | 466 | ) |
458 | ) | 467 | )(fresh) |
459 | /** Self-restriction over an object property */ | 468 | /** Self-restriction over an object property */ |
460 | case (sub: OWLObjectHasSelf, _) => notSupported(a) | 469 | case (sub: OWLObjectHasSelf, _) => notSupported(a) |
461 | case (_, sup: OWLObjectHasSelf) => notSupported(a) | 470 | case (_, sup: OWLObjectHasSelf) => notSupported(a) |
@@ -466,32 +475,34 @@ class Normalizer() { | |||
466 | } | 475 | } |
467 | 476 | ||
468 | case a: OWLEquivalentClassesAxiom => { | 477 | case a: OWLEquivalentClassesAxiom => { |
469 | a.getAxiomWithoutAnnotations.asOWLSubClassOfAxioms.flatMap(normalize) | 478 | a.getAxiomWithoutAnnotations.asOWLSubClassOfAxioms.flatMap( |
479 | normalize(_)(fresh) | ||
480 | ) | ||
470 | } | 481 | } |
471 | 482 | ||
472 | case a: OWLEquivalentObjectPropertiesAxiom => { | 483 | case a: OWLEquivalentObjectPropertiesAxiom => { |
473 | a.getAxiomWithoutAnnotations.asSubObjectPropertyOfAxioms.flatMap( | 484 | a.getAxiomWithoutAnnotations.asSubObjectPropertyOfAxioms.flatMap( |
474 | normalize | 485 | normalize(_)(fresh) |
475 | ) | 486 | ) |
476 | } | 487 | } |
477 | 488 | ||
478 | case a: OWLEquivalentDataPropertiesAxiom => { | 489 | case a: OWLEquivalentDataPropertiesAxiom => { |
479 | a.getAxiomWithoutAnnotations.asSubDataPropertyOfAxioms.flatMap( | 490 | a.getAxiomWithoutAnnotations.asSubDataPropertyOfAxioms.flatMap( |
480 | normalize | 491 | normalize(_)(fresh) |
481 | ) | 492 | ) |
482 | } | 493 | } |
483 | 494 | ||
484 | case a: OWLObjectPropertyDomainAxiom => | 495 | case a: OWLObjectPropertyDomainAxiom => |
485 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 496 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
486 | 497 | ||
487 | case a: OWLObjectPropertyRangeAxiom => | 498 | case a: OWLObjectPropertyRangeAxiom => |
488 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 499 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
489 | 500 | ||
490 | case a: OWLDataPropertyDomainAxiom => | 501 | case a: OWLDataPropertyDomainAxiom => |
491 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 502 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
492 | 503 | ||
493 | case a: OWLDataPropertyRangeAxiom => | 504 | case a: OWLDataPropertyRangeAxiom => |
494 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 505 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
495 | 506 | ||
496 | case a: OWLDisjointClassesAxiom => | 507 | case a: OWLDisjointClassesAxiom => |
497 | a.asPairwiseAxioms.map((a) => { | 508 | a.asPairwiseAxioms.map((a) => { |
@@ -504,20 +515,22 @@ class Normalizer() { | |||
504 | 515 | ||
505 | case a: OWLInverseObjectPropertiesAxiom => | 516 | case a: OWLInverseObjectPropertiesAxiom => |
506 | a.getAxiomWithoutAnnotations.asSubObjectPropertyOfAxioms.flatMap( | 517 | a.getAxiomWithoutAnnotations.asSubObjectPropertyOfAxioms.flatMap( |
507 | normalize | 518 | normalize(_)(fresh) |
508 | ) | 519 | ) |
509 | 520 | ||
510 | case a: OWLFunctionalObjectPropertyAxiom => | 521 | case a: OWLFunctionalObjectPropertyAxiom => |
511 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 522 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
512 | 523 | ||
513 | case a: OWLFunctionalDataPropertyAxiom => | 524 | case a: OWLFunctionalDataPropertyAxiom => |
514 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 525 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
515 | 526 | ||
516 | case a: OWLInverseFunctionalObjectPropertyAxiom => | 527 | case a: OWLInverseFunctionalObjectPropertyAxiom => |
517 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 528 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
518 | 529 | ||
519 | case a: OWLSymmetricObjectPropertyAxiom => | 530 | case a: OWLSymmetricObjectPropertyAxiom => |
520 | a.getAxiomWithoutAnnotations.asSubPropertyAxioms.flatMap(normalize) | 531 | a.getAxiomWithoutAnnotations.asSubPropertyAxioms.flatMap( |
532 | normalize(_)(fresh) | ||
533 | ) | ||
521 | 534 | ||
522 | case a: OWLDifferentIndividualsAxiom => | 535 | case a: OWLDifferentIndividualsAxiom => |
523 | a.asPairwiseAxioms.map((a) => { | 536 | a.asPairwiseAxioms.map((a) => { |
@@ -529,42 +542,44 @@ class Normalizer() { | |||
529 | }) | 542 | }) |
530 | 543 | ||
531 | case a: OWLIrreflexiveObjectPropertyAxiom => | 544 | case a: OWLIrreflexiveObjectPropertyAxiom => |
532 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 545 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
533 | 546 | ||
534 | case a: OWLSameIndividualAxiom => | 547 | case a: OWLSameIndividualAxiom => |
535 | a.getAxiomWithoutAnnotations.asOWLSubClassOfAxioms.flatMap(normalize) | 548 | a.getAxiomWithoutAnnotations.asOWLSubClassOfAxioms.flatMap( |
549 | normalize(_)(fresh) | ||
550 | ) | ||
536 | 551 | ||
537 | case a: OWLDisjointUnionAxiom => | 552 | case a: OWLDisjointUnionAxiom => |
538 | Seq(a.getOWLDisjointClassesAxiom, a.getOWLEquivalentClassesAxiom) | 553 | Seq(a.getOWLDisjointClassesAxiom, a.getOWLEquivalentClassesAxiom) |
539 | .flatMap(normalize) | 554 | .flatMap(normalize(_)(fresh)) |
540 | 555 | ||
541 | /** Complex class assertion | 556 | /** Complex class assertion |
542 | * | 557 | * |
543 | * C(a) -> { X(a), X c C } | 558 | * C(a) -> { X(a), X c C } |
544 | */ | 559 | */ |
545 | case a: OWLClassAssertionAxiom if !a.getClassExpression.isOWLClass => { | 560 | case a: OWLClassAssertionAxiom if !a.getClassExpression.isOWLClass => { |
546 | val cls = RSAUtil.getFreshOWLClass() | 561 | val cls = fresh.getOWLClass |
547 | Seq( | 562 | Seq( |
548 | factory.getOWLClassAssertionAxiom(cls, a.getIndividual), | 563 | factory.getOWLClassAssertionAxiom(cls, a.getIndividual), |
549 | factory.getOWLSubClassOfAxiom(cls, a.getClassExpression) | 564 | factory.getOWLSubClassOfAxiom(cls, a.getClassExpression) |
550 | ).flatMap(normalize) | 565 | ).flatMap(normalize(_)(fresh)) |
551 | } | 566 | } |
552 | 567 | ||
553 | case a: OWLNegativeObjectPropertyAssertionAxiom => | 568 | case a: OWLNegativeObjectPropertyAssertionAxiom => |
554 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 569 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
555 | 570 | ||
556 | case a: OWLNegativeDataPropertyAssertionAxiom => | 571 | case a: OWLNegativeDataPropertyAssertionAxiom => |
557 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 572 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
558 | 573 | ||
559 | case a: OWLTransitiveObjectPropertyAxiom => { | 574 | case a: OWLTransitiveObjectPropertyAxiom => { |
560 | val role = a.getProperty | 575 | val role = a.getProperty |
561 | normalize( | 576 | normalize( |
562 | factory.getOWLSubPropertyChainOfAxiom( List(role, role), role) | 577 | factory.getOWLSubPropertyChainOfAxiom(List(role, role), role) |
563 | ) | 578 | )(fresh) |
564 | } | 579 | } |
565 | 580 | ||
566 | case a: OWLReflexiveObjectPropertyAxiom => | 581 | case a: OWLReflexiveObjectPropertyAxiom => |
567 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom) | 582 | normalize(a.getAxiomWithoutAnnotations.asOWLSubClassOfAxiom)(fresh) |
568 | 583 | ||
569 | case a: OWLAsymmetricObjectPropertyAxiom => notSupported(a) | 584 | case a: OWLAsymmetricObjectPropertyAxiom => notSupported(a) |
570 | 585 | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala index 03c1246..266c158 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/converter/RDFoxConverter.scala | |||
@@ -27,10 +27,9 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
27 | TupleTableAtom | 27 | TupleTableAtom |
28 | } | 28 | } |
29 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} | 29 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, IRI, FunctionCall} |
30 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
31 | import uk.ac.ox.cs.rsacomb.RSAOntology | 30 | import uk.ac.ox.cs.rsacomb.RSAOntology |
32 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} | 31 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Inverse, RSASuffix} |
33 | import uk.ac.ox.cs.rsacomb.util.{RSA, RDFoxUtil} | 32 | import uk.ac.ox.cs.rsacomb.util.{DataFactory, RSA, RDFoxUtil} |
34 | 33 | ||
35 | /** Horn-ALCHOIQ to RDFox axiom converter. | 34 | /** Horn-ALCHOIQ to RDFox axiom converter. |
36 | * | 35 | * |
@@ -129,16 +128,16 @@ trait RDFoxConverter { | |||
129 | unsafe: List[OWLObjectPropertyExpression], | 128 | unsafe: List[OWLObjectPropertyExpression], |
130 | skolem: SkolemStrategy, | 129 | skolem: SkolemStrategy, |
131 | suffix: RSASuffix | 130 | suffix: RSASuffix |
132 | ): Result = | 131 | )(implicit fresh: DataFactory): Result = |
133 | axiom match { | 132 | axiom match { |
134 | 133 | ||
135 | case a: OWLSubClassOfAxiom => { | 134 | case a: OWLSubClassOfAxiom => { |
136 | val subcls = a.getSubClass | 135 | val subcls = a.getSubClass |
137 | val supcls = a.getSuperClass | 136 | val supcls = a.getSuperClass |
138 | val (sub, _) = | 137 | val (sub, _) = |
139 | convert(subcls, term, unsafe, NoSkolem, suffix) | 138 | convert(subcls, term, unsafe, NoSkolem, suffix)(fresh) |
140 | val (sup, ext) = | 139 | val (sup, ext) = |
141 | convert(supcls, term, unsafe, skolem, suffix) | 140 | convert(supcls, term, unsafe, skolem, suffix)(fresh) |
142 | val rule = Rule.create(sup, ext ::: sub) | 141 | val rule = Rule.create(sup, ext ::: sub) |
143 | ResultR(List(rule)) | 142 | ResultR(List(rule)) |
144 | } | 143 | } |
@@ -148,7 +147,7 @@ trait RDFoxConverter { | |||
148 | case a: OWLEquivalentClassesAxiom => { | 147 | case a: OWLEquivalentClassesAxiom => { |
149 | val (atoms, rules) = a.asPairwiseAxioms | 148 | val (atoms, rules) = a.asPairwiseAxioms |
150 | .flatMap(_.asOWLSubClassOfAxioms) | 149 | .flatMap(_.asOWLSubClassOfAxioms) |
151 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)) | 150 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)(fresh)) |
152 | .unzip | 151 | .unzip |
153 | (atoms.flatten, rules.flatten) | 152 | (atoms.flatten, rules.flatten) |
154 | } | 153 | } |
@@ -156,61 +155,64 @@ trait RDFoxConverter { | |||
156 | case a: OWLEquivalentObjectPropertiesAxiom => { | 155 | case a: OWLEquivalentObjectPropertiesAxiom => { |
157 | val (atoms, rules) = a.asPairwiseAxioms | 156 | val (atoms, rules) = a.asPairwiseAxioms |
158 | .flatMap(_.asSubObjectPropertyOfAxioms) | 157 | .flatMap(_.asSubObjectPropertyOfAxioms) |
159 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)) | 158 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)(fresh)) |
160 | .unzip | 159 | .unzip |
161 | (atoms.flatten, rules.flatten) | 160 | (atoms.flatten, rules.flatten) |
162 | } | 161 | } |
163 | 162 | ||
164 | case a: OWLSubObjectPropertyOfAxiom => { | 163 | case a: OWLSubObjectPropertyOfAxiom => { |
165 | val term1 = RSAUtil.genFreshVariable() | 164 | val term1 = fresh.getVariable |
166 | val body = convert(a.getSubProperty, term, term1, suffix) | 165 | val body = convert(a.getSubProperty, term, term1, suffix)(fresh) |
167 | val head = convert(a.getSuperProperty, term, term1, suffix) | 166 | val head = convert(a.getSuperProperty, term, term1, suffix)(fresh) |
168 | ResultR(List(Rule.create(head, body))) | 167 | ResultR(List(Rule.create(head, body))) |
169 | } | 168 | } |
170 | 169 | ||
171 | case a: OWLSubDataPropertyOfAxiom => { | 170 | case a: OWLSubDataPropertyOfAxiom => { |
172 | val term1 = RSAUtil.genFreshVariable() | 171 | val term1 = fresh.getVariable |
173 | val body = convert(a.getSubProperty, term, term1, suffix) | 172 | val body = convert(a.getSubProperty, term, term1, suffix)(fresh) |
174 | val head = convert(a.getSuperProperty, term, term1, suffix) | 173 | val head = convert(a.getSuperProperty, term, term1, suffix)(fresh) |
175 | ResultR(List(Rule.create(head, body))) | 174 | ResultR(List(Rule.create(head, body))) |
176 | } | 175 | } |
177 | 176 | ||
178 | case a: OWLObjectPropertyDomainAxiom => | 177 | case a: OWLObjectPropertyDomainAxiom => |
179 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix) | 178 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix)(fresh) |
180 | 179 | ||
181 | case a: OWLObjectPropertyRangeAxiom => { | 180 | case a: OWLObjectPropertyRangeAxiom => { |
182 | val term1 = RSAUtil.genFreshVariable() | 181 | val term1 = fresh.getVariable |
183 | val (res, ext) = convert(a.getRange, term, unsafe, skolem, suffix) | 182 | val (res, ext) = |
184 | val prop = convert(a.getProperty, term1, term, suffix) | 183 | convert(a.getRange, term, unsafe, skolem, suffix)(fresh) |
184 | val prop = convert(a.getProperty, term1, term, suffix)(fresh) | ||
185 | ResultR(List(Rule.create(res, prop :: ext))) | 185 | ResultR(List(Rule.create(res, prop :: ext))) |
186 | } | 186 | } |
187 | 187 | ||
188 | case a: OWLDataPropertyDomainAxiom => | 188 | case a: OWLDataPropertyDomainAxiom => |
189 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix) | 189 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix)(fresh) |
190 | 190 | ||
191 | case a: OWLDisjointClassesAxiom => { | 191 | case a: OWLDisjointClassesAxiom => { |
192 | val body = a.getOperandsAsList.asScala.toSeq | 192 | val body = a.getOperandsAsList.asScala.toSeq |
193 | .flatMap((cls) => convert(cls, term, unsafe, NoSkolem, suffix)._1) | 193 | .flatMap((cls) => |
194 | convert(cls, term, unsafe, NoSkolem, suffix)(fresh)._1 | ||
195 | ) | ||
194 | val bottom = TupleTableAtom.rdf(term, IRI.RDF_TYPE, IRI.NOTHING) | 196 | val bottom = TupleTableAtom.rdf(term, IRI.RDF_TYPE, IRI.NOTHING) |
195 | ResultR(List(Rule.create(bottom, body: _*))) | 197 | ResultR(List(Rule.create(bottom, body: _*))) |
196 | } | 198 | } |
197 | 199 | ||
198 | case a: OWLInverseObjectPropertiesAxiom => { | 200 | case a: OWLInverseObjectPropertiesAxiom => { |
199 | val (atoms, rules) = a.asSubObjectPropertyOfAxioms | 201 | val (atoms, rules) = a.asSubObjectPropertyOfAxioms |
200 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)) | 202 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)(fresh)) |
201 | .unzip | 203 | .unzip |
202 | (atoms.flatten, rules.flatten) | 204 | (atoms.flatten, rules.flatten) |
203 | } | 205 | } |
204 | 206 | ||
205 | case a: OWLFunctionalObjectPropertyAxiom => | 207 | case a: OWLFunctionalObjectPropertyAxiom => |
206 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix) | 208 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix)(fresh) |
207 | 209 | ||
208 | case a: OWLInverseFunctionalObjectPropertyAxiom => | 210 | case a: OWLInverseFunctionalObjectPropertyAxiom => |
209 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix) | 211 | convert(a.asOWLSubClassOfAxiom, term, unsafe, skolem, suffix)(fresh) |
210 | 212 | ||
211 | case a: OWLSymmetricObjectPropertyAxiom => { | 213 | case a: OWLSymmetricObjectPropertyAxiom => { |
212 | val (atoms, rules) = a.asSubPropertyAxioms | 214 | val (atoms, rules) = a.asSubPropertyAxioms |
213 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)) | 215 | .map(a => convert(a, term, unsafe, skolem dup a, suffix)(fresh)) |
214 | .unzip | 216 | .unzip |
215 | (atoms.flatten, rules.flatten) | 217 | (atoms.flatten, rules.flatten) |
216 | } | 218 | } |
@@ -221,7 +223,7 @@ trait RDFoxConverter { | |||
221 | case i: OWLNamedIndividual => { | 223 | case i: OWLNamedIndividual => { |
222 | val cls = a.getClassExpression | 224 | val cls = a.getClassExpression |
223 | val (res, _) = | 225 | val (res, _) = |
224 | convert(cls, i.getIRI, unsafe, NoSkolem, suffix) | 226 | convert(cls, i.getIRI, unsafe, NoSkolem, suffix)(fresh) |
225 | ResultF(res) | 227 | ResultF(res) |
226 | } | 228 | } |
227 | case _ => Result() | 229 | case _ => Result() |
@@ -234,7 +236,7 @@ trait RDFoxConverter { | |||
234 | else { | 236 | else { |
235 | val subj = a.getSubject.asOWLNamedIndividual.getIRI | 237 | val subj = a.getSubject.asOWLNamedIndividual.getIRI |
236 | val obj = a.getObject.asOWLNamedIndividual.getIRI | 238 | val obj = a.getObject.asOWLNamedIndividual.getIRI |
237 | val prop = convert(a.getProperty, subj, obj, suffix) | 239 | val prop = convert(a.getProperty, subj, obj, suffix)(fresh) |
238 | ResultF(List(prop)) | 240 | ResultF(List(prop)) |
239 | } | 241 | } |
240 | 242 | ||
@@ -248,29 +250,29 @@ trait RDFoxConverter { | |||
248 | else { | 250 | else { |
249 | val subj = a.getSubject.asOWLNamedIndividual.getIRI | 251 | val subj = a.getSubject.asOWLNamedIndividual.getIRI |
250 | val obj = a.getObject | 252 | val obj = a.getObject |
251 | val prop = convert(a.getProperty, subj, obj, suffix) | 253 | val prop = convert(a.getProperty, subj, obj, suffix)(fresh) |
252 | ResultF(List(prop)) | 254 | ResultF(List(prop)) |
253 | } | 255 | } |
254 | 256 | ||
255 | case a: OWLSubPropertyChainOfAxiom => { | 257 | case a: OWLSubPropertyChainOfAxiom => { |
256 | val (term1, body) = a.getPropertyChain.foldLeft((term, List[TupleTableAtom]())){ | 258 | val (term1, body) = |
257 | case ((term, atoms), prop) => { | 259 | a.getPropertyChain.foldLeft((term, List[TupleTableAtom]())) { |
258 | val term1 = RSAUtil.genFreshVariable() | 260 | case ((term, atoms), prop) => { |
259 | val atom = convert(prop, term, term1, suffix) | 261 | val term1 = fresh.getVariable |
260 | (term1, atoms :+ atom) | 262 | val atom = convert(prop, term, term1, suffix)(fresh) |
263 | (term1, atoms :+ atom) | ||
264 | } | ||
261 | } | 265 | } |
262 | } | 266 | val head = convert(a.getSuperProperty, term, term1, suffix)(fresh) |
263 | val head = convert(a.getSuperProperty, term, term1, suffix) | 267 | val rule = Rule.create(head, body) |
264 | ResultR(List(Rule.create(head, body))) | 268 | println(rule) |
269 | ResultR(List(rule)) | ||
265 | } | 270 | } |
266 | 271 | ||
267 | /** Catch-all case for all unhandled axiom types. */ | 272 | /** Catch-all case for all unhandled axiom types. */ |
268 | case a => unsupported(axiom) | 273 | case a => unsupported(axiom) |
269 | } | 274 | } |
270 | 275 | ||
271 | protected def toBeNormalised(axiom: OWLLogicalAxiom): Result = | ||
272 | throw new RuntimeException(s"Axiom '$axiom' should be normalised!") | ||
273 | |||
274 | protected def unsupported(axiom: OWLLogicalAxiom): Result = | 276 | protected def unsupported(axiom: OWLLogicalAxiom): Result = |
275 | throw new RuntimeException(s"Axiom '$axiom' is not supported (yet?)") | 277 | throw new RuntimeException(s"Axiom '$axiom' is not supported (yet?)") |
276 | 278 | ||
@@ -299,7 +301,7 @@ trait RDFoxConverter { | |||
299 | unsafe: List[OWLObjectPropertyExpression], | 301 | unsafe: List[OWLObjectPropertyExpression], |
300 | skolem: SkolemStrategy, | 302 | skolem: SkolemStrategy, |
301 | suffix: RSASuffix | 303 | suffix: RSASuffix |
302 | ): Shards = | 304 | )(implicit fresh: DataFactory): Shards = |
303 | expr match { | 305 | expr match { |
304 | 306 | ||
305 | /** Simple class name. | 307 | /** Simple class name. |
@@ -318,7 +320,7 @@ trait RDFoxConverter { | |||
318 | */ | 320 | */ |
319 | case e: OWLObjectIntersectionOf => { | 321 | case e: OWLObjectIntersectionOf => { |
320 | val (res, ext) = e.asConjunctSet | 322 | val (res, ext) = e.asConjunctSet |
321 | .map(convert(_, term, unsafe, skolem, suffix)) | 323 | .map(convert(_, term, unsafe, skolem, suffix)(fresh)) |
322 | .unzip | 324 | .unzip |
323 | (res.flatten, ext.flatten) | 325 | (res.flatten, ext.flatten) |
324 | } | 326 | } |
@@ -352,14 +354,14 @@ trait RDFoxConverter { | |||
352 | case e: OWLObjectSomeValuesFrom => { | 354 | case e: OWLObjectSomeValuesFrom => { |
353 | val cls = e.getFiller() | 355 | val cls = e.getFiller() |
354 | val role = e.getProperty() | 356 | val role = e.getProperty() |
355 | val varX = RSAUtil.genFreshVariable | 357 | val varX = fresh.getVariable |
356 | val (bind, term1) = skolem match { | 358 | val (bind, term1) = skolem match { |
357 | case NoSkolem => (None, varX) | 359 | case NoSkolem => (None, varX) |
358 | case c: Constant => (None, c.iri) | 360 | case c: Constant => (None, c.iri) |
359 | case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX) | 361 | case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX) |
360 | } | 362 | } |
361 | val (res, ext) = convert(cls, term1, unsafe, skolem, suffix) | 363 | val (res, ext) = convert(cls, term1, unsafe, skolem, suffix)(fresh) |
362 | val prop = convert(role, term, term1, suffix) | 364 | val prop = convert(role, term, term1, suffix)(fresh) |
363 | (prop :: res, ext ++ bind) | 365 | (prop :: res, ext ++ bind) |
364 | } | 366 | } |
365 | 367 | ||
@@ -379,13 +381,13 @@ trait RDFoxConverter { | |||
379 | // Computes the result of rule skolemization. Depending on the used | 381 | // Computes the result of rule skolemization. Depending on the used |
380 | // technique it might involve the introduction of additional atoms, | 382 | // technique it might involve the introduction of additional atoms, |
381 | // and/or fresh constants and variables. | 383 | // and/or fresh constants and variables. |
382 | val varX = RSAUtil.genFreshVariable | 384 | val varX = fresh.getVariable |
383 | val (bind, term1) = skolem match { | 385 | val (bind, term1) = skolem match { |
384 | case NoSkolem => (None, varX) | 386 | case NoSkolem => (None, varX) |
385 | case c: Constant => (None, c.iri) | 387 | case c: Constant => (None, c.iri) |
386 | case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX) | 388 | case s: Standard => (Some(RDFoxUtil.skolem(s.name, term, varX)), varX) |
387 | } | 389 | } |
388 | val prop = convert(role, term, term1, suffix) | 390 | val prop = convert(role, term, term1, suffix)(fresh) |
389 | (List(prop), bind.toList) | 391 | (List(prop), bind.toList) |
390 | } | 392 | } |
391 | 393 | ||
@@ -404,11 +406,12 @@ trait RDFoxConverter { | |||
404 | s"Class expression '$e' has cardinality restriction != 1." | 406 | s"Class expression '$e' has cardinality restriction != 1." |
405 | ) | 407 | ) |
406 | val vars @ (y :: z :: _) = | 408 | val vars @ (y :: z :: _) = |
407 | Seq(RSAUtil.genFreshVariable(), RSAUtil.genFreshVariable()) | 409 | Seq(fresh.getVariable, fresh.getVariable) |
408 | val cls = e.getFiller | 410 | val cls = e.getFiller |
409 | val role = e.getProperty | 411 | val role = e.getProperty |
410 | val (res, ext) = vars.map(convert(cls, _, unsafe, skolem, suffix)).unzip | 412 | val (res, ext) = |
411 | val props = vars.map(convert(role, term, _, suffix)) | 413 | vars.map(convert(cls, _, unsafe, skolem, suffix)(fresh)).unzip |
414 | val props = vars.map(convert(role, term, _, suffix)(fresh)) | ||
412 | val eq = TupleTableAtom.rdf(y, IRI.SAME_AS, z) | 415 | val eq = TupleTableAtom.rdf(y, IRI.SAME_AS, z) |
413 | (List(eq), res.flatten ++ props) | 416 | (List(eq), res.flatten ++ props) |
414 | } | 417 | } |
@@ -431,7 +434,7 @@ trait RDFoxConverter { | |||
431 | val filler = e.getFiller | 434 | val filler = e.getFiller |
432 | val property = e.getProperty | 435 | val property = e.getProperty |
433 | val expr = factory.getOWLObjectSomeValuesFrom(property, filler) | 436 | val expr = factory.getOWLObjectSomeValuesFrom(property, filler) |
434 | convert(expr, term, unsafe, skolem, suffix) | 437 | convert(expr, term, unsafe, skolem, suffix)(fresh) |
435 | } | 438 | } |
436 | 439 | ||
437 | /** Minimum cardinality restriction class | 440 | /** Minimum cardinality restriction class |
@@ -452,7 +455,7 @@ trait RDFoxConverter { | |||
452 | val filler = e.getFiller | 455 | val filler = e.getFiller |
453 | val property = e.getProperty | 456 | val property = e.getProperty |
454 | val expr = factory.getOWLDataSomeValuesFrom(property, filler) | 457 | val expr = factory.getOWLDataSomeValuesFrom(property, filler) |
455 | convert(expr, term, unsafe, skolem, suffix) | 458 | convert(expr, term, unsafe, skolem, suffix)(fresh) |
456 | } | 459 | } |
457 | 460 | ||
458 | //case (_, sup: OWLObjectExactCardinality) => { | 461 | //case (_, sup: OWLObjectExactCardinality) => { |
@@ -475,7 +478,7 @@ trait RDFoxConverter { | |||
475 | case i: OWLNamedIndividual => i.getIRI | 478 | case i: OWLNamedIndividual => i.getIRI |
476 | case i: OWLAnonymousIndividual => i.getID | 479 | case i: OWLAnonymousIndividual => i.getID |
477 | } | 480 | } |
478 | (List(convert(e.getProperty, term, term1, suffix)), List()) | 481 | (List(convert(e.getProperty, term, term1, suffix)(fresh)), List()) |
479 | } | 482 | } |
480 | 483 | ||
481 | /** Existential quantification with singleton literal filler | 484 | /** Existential quantification with singleton literal filler |
@@ -484,7 +487,7 @@ trait RDFoxConverter { | |||
484 | * [[http://www.w3.org/TR/owl2-syntax/#Literal_Value_Restriction]] | 487 | * [[http://www.w3.org/TR/owl2-syntax/#Literal_Value_Restriction]] |
485 | */ | 488 | */ |
486 | case e: OWLDataHasValue => | 489 | case e: OWLDataHasValue => |
487 | (List(convert(e.getProperty, term, e.getFiller, suffix)), List()) | 490 | (List(convert(e.getProperty, term, e.getFiller, suffix)(fresh)), List()) |
488 | 491 | ||
489 | case e: OWLObjectUnionOf => { | 492 | case e: OWLObjectUnionOf => { |
490 | (List(), List()) | 493 | (List(), List()) |
@@ -503,7 +506,7 @@ trait RDFoxConverter { | |||
503 | term1: Term, | 506 | term1: Term, |
504 | term2: Term, | 507 | term2: Term, |
505 | suffix: RSASuffix | 508 | suffix: RSASuffix |
506 | ): TupleTableAtom = | 509 | )(implicit fresh: DataFactory): TupleTableAtom = |
507 | expr match { | 510 | expr match { |
508 | 511 | ||
509 | /** Simple named role/object property. | 512 | /** Simple named role/object property. |
@@ -524,7 +527,7 @@ trait RDFoxConverter { | |||
524 | */ | 527 | */ |
525 | case e: OWLObjectInverseOf => | 528 | case e: OWLObjectInverseOf => |
526 | //convert(e.getInverse, term1, term2, suffix + Inverse) | 529 | //convert(e.getInverse, term1, term2, suffix + Inverse) |
527 | convert(e.getInverse, term2, term1, suffix) | 530 | convert(e.getInverse, term2, term1, suffix)(fresh) |
528 | 531 | ||
529 | /** The infamous impossible case. | 532 | /** The infamous impossible case. |
530 | * | 533 | * |
@@ -543,7 +546,7 @@ trait RDFoxConverter { | |||
543 | term1: Term, | 546 | term1: Term, |
544 | term2: Term, | 547 | term2: Term, |
545 | suffix: RSASuffix | 548 | suffix: RSASuffix |
546 | ): TupleTableAtom = | 549 | )(implicit fresh: DataFactory): TupleTableAtom = |
547 | expr match { | 550 | expr match { |
548 | 551 | ||
549 | /** Simple named role/data property | 552 | /** Simple named role/data property |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala index 09bfa1e..795e039 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/implicits/RSAAtom.scala | |||
@@ -25,10 +25,9 @@ import tech.oxfordsemantic.jrdfox.logic.datalog.{ | |||
25 | } | 25 | } |
26 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} | 26 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} |
27 | 27 | ||
28 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
29 | import uk.ac.ox.cs.rsacomb.RSAOntology | 28 | import uk.ac.ox.cs.rsacomb.RSAOntology |
30 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth} | 29 | import uk.ac.ox.cs.rsacomb.suffix.{RSASuffix, Nth} |
31 | import uk.ac.ox.cs.rsacomb.util.RDFoxUtil | 30 | import uk.ac.ox.cs.rsacomb.util.{DataFactory, RDFoxUtil} |
32 | 31 | ||
33 | /* Is this the best way to determine if an atom is an RDF triple? | 32 | /* Is this the best way to determine if an atom is an RDF triple? |
34 | * Note that we can't use `getNumberOfArguments()` because is not | 33 | * Note that we can't use `getNumberOfArguments()` because is not |
@@ -91,11 +90,13 @@ object RSAAtom { | |||
91 | TupleTableAtom.create(ttname, atom.getArguments()) | 90 | TupleTableAtom.create(ttname, atom.getArguments()) |
92 | } | 91 | } |
93 | 92 | ||
94 | lazy val reified: (Option[TupleTableAtom], List[TupleTableAtom]) = | 93 | def reified(implicit |
94 | fresh: DataFactory | ||
95 | ): (Option[TupleTableAtom], List[TupleTableAtom]) = | ||
95 | if (isRDF) { | 96 | if (isRDF) { |
96 | (None, List(atom)) | 97 | (None, List(atom)) |
97 | } else { | 98 | } else { |
98 | val varS = RSAUtil.genFreshVariable() | 99 | val varS = fresh.getVariable |
99 | val skolem = RDFoxUtil.skolem(name, (args :+ varS): _*) | 100 | val skolem = RDFoxUtil.skolem(name, (args :+ varS): _*) |
100 | val atom = TupleTableAtom.rdf(varS, IRI.RDF_TYPE, name) | 101 | val atom = TupleTableAtom.rdf(varS, IRI.RDF_TYPE, name) |
101 | val atoms = args.zipWithIndex | 102 | val atoms = args.zipWithIndex |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala index ba44605..1f44ce1 100644 --- a/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/ontology/Ontology.scala | |||
@@ -35,9 +35,7 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{Resource, Term, Variable} | |||
35 | import uk.ac.ox.cs.rsacomb.approximation.Approximation | 35 | import uk.ac.ox.cs.rsacomb.approximation.Approximation |
36 | import uk.ac.ox.cs.rsacomb.converter._ | 36 | import uk.ac.ox.cs.rsacomb.converter._ |
37 | import uk.ac.ox.cs.rsacomb.suffix._ | 37 | import uk.ac.ox.cs.rsacomb.suffix._ |
38 | import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} | 38 | import uk.ac.ox.cs.rsacomb.util.{DataFactory, RDFoxUtil, RSA} |
39 | |||
40 | import uk.ac.ox.cs.rsacomb.RSAUtil | ||
41 | 39 | ||
42 | object Ontology { | 40 | object Ontology { |
43 | 41 | ||
@@ -95,12 +93,13 @@ object Ontology { | |||
95 | unsafe: List[OWLObjectPropertyExpression], | 93 | unsafe: List[OWLObjectPropertyExpression], |
96 | skolem: SkolemStrategy, | 94 | skolem: SkolemStrategy, |
97 | suffix: RSASuffix | 95 | suffix: RSASuffix |
98 | ): Shards = | 96 | )(implicit fresh: DataFactory): Shards = |
99 | (expr, skolem) match { | 97 | (expr, skolem) match { |
100 | 98 | ||
101 | case (e: OWLObjectSomeValuesFrom, c: Constant) => { | 99 | case (e: OWLObjectSomeValuesFrom, c: Constant) => { |
102 | nodemap.update(c.iri.getIRI, c.axiom) | 100 | nodemap.update(c.iri.getIRI, c.axiom) |
103 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) | 101 | val (res, ext) = |
102 | super.convert(e, term, unsafe, skolem, suffix)(fresh) | ||
104 | if (unsafe contains e.getProperty) | 103 | if (unsafe contains e.getProperty) |
105 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) | 104 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) |
106 | else | 105 | else |
@@ -109,19 +108,20 @@ object Ontology { | |||
109 | 108 | ||
110 | case (e: OWLDataSomeValuesFrom, c: Constant) => { | 109 | case (e: OWLDataSomeValuesFrom, c: Constant) => { |
111 | nodemap.update(c.iri.getIRI, c.axiom) | 110 | nodemap.update(c.iri.getIRI, c.axiom) |
112 | val (res, ext) = super.convert(e, term, unsafe, skolem, suffix) | 111 | val (res, ext) = |
112 | super.convert(e, term, unsafe, skolem, suffix)(fresh) | ||
113 | if (unsafe contains e.getProperty) | 113 | if (unsafe contains e.getProperty) |
114 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) | 114 | (RSA.PE(term, c.iri) :: RSA.U(c.iri) :: res, ext) |
115 | else | 115 | else |
116 | (RSA.PE(term, c.iri) :: res, ext) | 116 | (RSA.PE(term, c.iri) :: res, ext) |
117 | } | 117 | } |
118 | 118 | ||
119 | case _ => super.convert(expr, term, unsafe, skolem, suffix) | 119 | case _ => super.convert(expr, term, unsafe, skolem, suffix)(fresh) |
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | /* Ontology convertion into LP rules */ | 123 | /* Ontology convertion into LP rules */ |
124 | val term = RSAUtil.genFreshVariable() | 124 | val term = Variable.create("X") |
125 | val result = axioms.map(a => | 125 | val result = axioms.map(a => |
126 | RSAConverter.convert(a, term, unsafe, new Constant(a), Empty) | 126 | RSAConverter.convert(a, term, unsafe, new Constant(a), Empty) |
127 | ) | 127 | ) |
@@ -216,8 +216,6 @@ class Ontology(val axioms: List[OWLLogicalAxiom], val datafiles: List[File]) { | |||
216 | /** Simplify conversion between Java and Scala collections */ | 216 | /** Simplify conversion between Java and Scala collections */ |
217 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ | 217 | import uk.ac.ox.cs.rsacomb.implicits.JavaCollections._ |
218 | 218 | ||
219 | println(s"Axioms: ${axioms.length}") | ||
220 | |||
221 | /** OWLOntology based on input axioms | 219 | /** OWLOntology based on input axioms |
222 | * | 220 | * |
223 | * This is mainly used to instantiate a new reasoner to be used in | 221 | * This is mainly used to instantiate a new reasoner to be used in |
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/package.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/package.scala new file mode 100644 index 0000000..53fa095 --- /dev/null +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/package.scala | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright 2020, 2021 KRR Oxford | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | package uk.ac.ox.cs | ||
18 | package object rsacomb { | ||
19 | |||
20 | implicit val seed: util.DataFactory = util.DataFactory(0) | ||
21 | } | ||
diff --git a/src/main/scala/uk/ac/ox/cs/rsacomb/util/DataFactory.scala b/src/main/scala/uk/ac/ox/cs/rsacomb/util/DataFactory.scala new file mode 100644 index 0000000..848c6b5 --- /dev/null +++ b/src/main/scala/uk/ac/ox/cs/rsacomb/util/DataFactory.scala | |||
@@ -0,0 +1,29 @@ | |||
1 | package uk.ac.ox.cs.rsacomb.util | ||
2 | |||
3 | import org.semanticweb.owlapi.apibinding.OWLManager | ||
4 | import org.semanticweb.owlapi.model.OWLClass | ||
5 | import tech.oxfordsemantic.jrdfox.logic.expression.Variable | ||
6 | |||
7 | /** Simple fresh variable/class generator */ | ||
8 | object DataFactory { | ||
9 | |||
10 | /** Manager instance to interface with OWLAPI */ | ||
11 | private val manager = OWLManager.createOWLOntologyManager() | ||
12 | private val factory = manager.getOWLDataFactory() | ||
13 | |||
14 | def apply(counter: Integer = -1): DataFactory = new DataFactory(counter) | ||
15 | } | ||
16 | |||
17 | class DataFactory(private var counter: Integer) { | ||
18 | |||
19 | private def getNext(): Integer = { | ||
20 | counter += 1 | ||
21 | counter | ||
22 | } | ||
23 | |||
24 | def getVariable(): Variable = | ||
25 | Variable.create(f"I${this.getNext()}%05d") | ||
26 | |||
27 | def getOWLClass(): OWLClass = | ||
28 | DataFactory.factory.getOWLClass(s"X${this.getNext()}") | ||
29 | } | ||
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala index abfe1ee..8d363e9 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/CanonicalModelSpec.scala | |||
@@ -31,6 +31,8 @@ import tech.oxfordsemantic.jrdfox.logic.expression.Variable | |||
31 | import scala.collection.JavaConverters._ | 31 | import scala.collection.JavaConverters._ |
32 | 32 | ||
33 | import uk.ac.ox.cs.rsacomb.RSAOntology | 33 | import uk.ac.ox.cs.rsacomb.RSAOntology |
34 | import uk.ac.ox.cs.rsacomb.approximation.Lowerbound | ||
35 | import uk.ac.ox.cs.rsacomb.ontology.Ontology | ||
34 | import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem} | 36 | import uk.ac.ox.cs.rsacomb.converter.{SkolemStrategy, NoSkolem} |
35 | import uk.ac.ox.cs.rsacomb.suffix.Empty | 37 | import uk.ac.ox.cs.rsacomb.suffix.Empty |
36 | import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} | 38 | import uk.ac.ox.cs.rsacomb.util.{RDFoxUtil, RSA} |
@@ -44,7 +46,7 @@ object Ontology1_CanonicalModelSpec { | |||
44 | IRI.create("http://example.com/rsa_example.owl#" + str) | 46 | IRI.create("http://example.com/rsa_example.owl#" + str) |
45 | 47 | ||
46 | val ontology_path: File = new File("examples/example1.ttl") | 48 | val ontology_path: File = new File("examples/example1.ttl") |
47 | val ontology = RSAOntology(ontology_path) | 49 | val ontology = Ontology(ontology_path, List()).approximate(new Lowerbound) |
48 | val program = ontology.canonicalModel | 50 | val program = ontology.canonicalModel |
49 | val converter = program.CanonicalModelConverter | 51 | val converter = program.CanonicalModelConverter |
50 | 52 | ||
@@ -109,7 +111,7 @@ class Ontology1_CanonicalModelSpec | |||
109 | 111 | ||
110 | renderer.render(AsubClassOfD) should "be converted into a single Rule" in { | 112 | renderer.render(AsubClassOfD) should "be converted into a single Rule" in { |
111 | val term = Variable.create("X") | 113 | val term = Variable.create("X") |
112 | val unsafe = ontology.unsafeRoles | 114 | val unsafe = ontology.unsafe |
113 | val (facts, rules) = | 115 | val (facts, rules) = |
114 | converter.convert(AsubClassOfD, term, unsafe, NoSkolem, Empty) | 116 | converter.convert(AsubClassOfD, term, unsafe, NoSkolem, Empty) |
115 | facts shouldBe empty | 117 | facts shouldBe empty |
@@ -119,7 +121,7 @@ class Ontology1_CanonicalModelSpec | |||
119 | // Role R // | 121 | // Role R // |
120 | 122 | ||
121 | renderer.render(roleR) should "be safe" in { | 123 | renderer.render(roleR) should "be safe" in { |
122 | ontology.unsafeRoles should not contain roleR | 124 | ontology.unsafe should not contain roleR |
123 | } | 125 | } |
124 | 126 | ||
125 | it should "have 3 elements in its conflict set" in { | 127 | it should "have 3 elements in its conflict set" in { |
@@ -143,7 +145,7 @@ class Ontology1_CanonicalModelSpec | |||
143 | // Role S // | 145 | // Role S // |
144 | 146 | ||
145 | renderer.render(roleS) should "be safe" in { | 147 | renderer.render(roleS) should "be safe" in { |
146 | ontology.unsafeRoles should not contain roleS | 148 | ontology.unsafe should not contain roleS |
147 | } | 149 | } |
148 | 150 | ||
149 | it should "have 3 elements in its conflict set" in { | 151 | it should "have 3 elements in its conflict set" in { |
@@ -169,14 +171,14 @@ class Ontology1_CanonicalModelSpec | |||
169 | // S⁻ | 171 | // S⁻ |
170 | 172 | ||
171 | renderer.render(roleS_inv) should "be unsafe" in { | 173 | renderer.render(roleS_inv) should "be unsafe" in { |
172 | ontology.unsafeRoles should contain(roleS_inv) | 174 | ontology.unsafe should contain(roleS_inv) |
173 | } | 175 | } |
174 | 176 | ||
175 | renderer.render( | 177 | renderer.render( |
176 | AsomeValuesFromSiC | 178 | AsomeValuesFromSiC |
177 | ) should "produce 1 rule" ignore { | 179 | ) should "produce 1 rule" ignore { |
178 | val term = Variable.create("X") | 180 | val term = Variable.create("X") |
179 | val unsafe = ontology.unsafeRoles | 181 | val unsafe = ontology.unsafe |
180 | val (facts, rules) = | 182 | val (facts, rules) = |
181 | converter.convert(AsomeValuesFromSiC, term, unsafe, NoSkolem, Empty) | 183 | converter.convert(AsomeValuesFromSiC, term, unsafe, NoSkolem, Empty) |
182 | facts shouldBe empty | 184 | facts shouldBe empty |
@@ -200,7 +202,7 @@ class Ontology1_CanonicalModelSpec | |||
200 | // Rule 2 provides 0 rules | 202 | // Rule 2 provides 0 rules |
201 | // Rule 3 provides 48 rule (split in 2) | 203 | // Rule 3 provides 48 rule (split in 2) |
202 | val term = Variable.create("X") | 204 | val term = Variable.create("X") |
203 | val unsafe = ontology.unsafeRoles | 205 | val unsafe = ontology.unsafe |
204 | val (facts, rules) = | 206 | val (facts, rules) = |
205 | converter.convert(DsomeValuesFromRB, term, unsafe, NoSkolem, Empty) | 207 | converter.convert(DsomeValuesFromRB, term, unsafe, NoSkolem, Empty) |
206 | facts should have length 48 | 208 | facts should have length 48 |
@@ -225,7 +227,7 @@ class Ontology1_CanonicalModelSpec | |||
225 | // Rule 3 provides 32 rule (split in 2) | 227 | // Rule 3 provides 32 rule (split in 2) |
226 | // Then (1*2 + 32) + (0) + (32*2) = 98 | 228 | // Then (1*2 + 32) + (0) + (32*2) = 98 |
227 | val term = Variable.create("X") | 229 | val term = Variable.create("X") |
228 | val unsafe = ontology.unsafeRoles | 230 | val unsafe = ontology.unsafe |
229 | val (facts, rules) = | 231 | val (facts, rules) = |
230 | converter.convert(BsomeValuesFromSD, term, unsafe, NoSkolem, Empty) | 232 | converter.convert(BsomeValuesFromSD, term, unsafe, NoSkolem, Empty) |
231 | facts should have length 32 | 233 | facts should have length 32 |
@@ -236,7 +238,7 @@ class Ontology1_CanonicalModelSpec | |||
236 | SsubPropertyOfT | 238 | SsubPropertyOfT |
237 | ) should "produce 3 rules" in { | 239 | ) should "produce 3 rules" in { |
238 | val term = Variable.create("X") | 240 | val term = Variable.create("X") |
239 | val unsafe = ontology.unsafeRoles | 241 | val unsafe = ontology.unsafe |
240 | val (facts, rules) = | 242 | val (facts, rules) = |
241 | converter.convert(SsubPropertyOfT, term, unsafe, NoSkolem, Empty) | 243 | converter.convert(SsubPropertyOfT, term, unsafe, NoSkolem, Empty) |
242 | facts shouldBe empty | 244 | facts shouldBe empty |
@@ -245,167 +247,167 @@ class Ontology1_CanonicalModelSpec | |||
245 | 247 | ||
246 | } | 248 | } |
247 | 249 | ||
248 | object Ontology2_CanonicalModelSpec { | 250 | // object Ontology2_CanonicalModelSpec { |
249 | 251 | ||
250 | /* Renderer to display OWL Axioms with DL syntax*/ | 252 | // /* Renderer to display OWL Axioms with DL syntax*/ |
251 | val renderer = new DLSyntaxObjectRenderer() | 253 | // val renderer = new DLSyntaxObjectRenderer() |
252 | 254 | ||
253 | def base(str: String): IRI = | 255 | // def base(str: String): IRI = |
254 | IRI.create("http://example.com/rsa_example.owl#" + str) | 256 | // IRI.create("http://example.com/rsa_example.owl#" + str) |
255 | 257 | ||
256 | val ontology_path: File = new File("examples/example2.owl") | 258 | // val ontology_path: File = new File("examples/example2.owl") |
257 | val ontology = RSAOntology(ontology_path) | 259 | // val ontology = Ontology(ontology_path, List()).approximate(new Lowerbound) |
258 | val program = ontology.canonicalModel | 260 | // val program = ontology.canonicalModel |
259 | val converter = program.CanonicalModelConverter | 261 | // val converter = program.CanonicalModelConverter |
260 | 262 | ||
261 | val roleR = new OWLObjectPropertyImpl(base("R")) | 263 | // val roleR = new OWLObjectPropertyImpl(base("R")) |
262 | val roleS = new OWLObjectPropertyImpl(base("S")) | 264 | // val roleS = new OWLObjectPropertyImpl(base("S")) |
263 | val roleT = new OWLObjectPropertyImpl(base("T")) | 265 | // val roleT = new OWLObjectPropertyImpl(base("T")) |
264 | val roleP = new OWLObjectPropertyImpl(base("P")) | 266 | // val roleP = new OWLObjectPropertyImpl(base("P")) |
265 | val roleR_inv = roleR.getInverseProperty() | 267 | // val roleR_inv = roleR.getInverseProperty() |
266 | val roleS_inv = roleS.getInverseProperty() | 268 | // val roleS_inv = roleS.getInverseProperty() |
267 | val roleT_inv = roleT.getInverseProperty() | 269 | // val roleT_inv = roleT.getInverseProperty() |
268 | val roleP_inv = roleP.getInverseProperty() | 270 | // val roleP_inv = roleP.getInverseProperty() |
269 | 271 | ||
270 | val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( | 272 | // val AsomeValuesFromRB = new OWLSubClassOfAxiomImpl( |
271 | new OWLClassImpl(base("A")), | 273 | // new OWLClassImpl(base("A")), |
272 | new OWLObjectSomeValuesFromImpl( | 274 | // new OWLObjectSomeValuesFromImpl( |
273 | roleR, | 275 | // roleR, |
274 | new OWLClassImpl(base("B")) | 276 | // new OWLClassImpl(base("B")) |
275 | ), | 277 | // ), |
276 | Seq().asJava | 278 | // Seq().asJava |
277 | ) | 279 | // ) |
278 | 280 | ||
279 | val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( | 281 | // val BsomeValuesFromSC = new OWLSubClassOfAxiomImpl( |
280 | new OWLClassImpl(base("B")), | 282 | // new OWLClassImpl(base("B")), |
281 | new OWLObjectSomeValuesFromImpl( | 283 | // new OWLObjectSomeValuesFromImpl( |
282 | roleS, | 284 | // roleS, |
283 | new OWLClassImpl(base("C")) | 285 | // new OWLClassImpl(base("C")) |
284 | ), | 286 | // ), |
285 | Seq().asJava | 287 | // Seq().asJava |
286 | ) | 288 | // ) |
287 | 289 | ||
288 | val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( | 290 | // val CsomeValuesFromTD = new OWLSubClassOfAxiomImpl( |
289 | new OWLClassImpl(base("C")), | 291 | // new OWLClassImpl(base("C")), |
290 | new OWLObjectSomeValuesFromImpl( | 292 | // new OWLObjectSomeValuesFromImpl( |
291 | roleT, | 293 | // roleT, |
292 | new OWLClassImpl(base("D")) | 294 | // new OWLClassImpl(base("D")) |
293 | ), | 295 | // ), |
294 | Seq().asJava | 296 | // Seq().asJava |
295 | ) | 297 | // ) |
296 | 298 | ||
297 | val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( | 299 | // val DsomeValuesFromPA = new OWLSubClassOfAxiomImpl( |
298 | new OWLClassImpl(base("D")), | 300 | // new OWLClassImpl(base("D")), |
299 | new OWLObjectSomeValuesFromImpl( | 301 | // new OWLObjectSomeValuesFromImpl( |
300 | roleP, | 302 | // roleP, |
301 | new OWLClassImpl(base("A")) | 303 | // new OWLClassImpl(base("A")) |
302 | ), | 304 | // ), |
303 | Seq().asJava | 305 | // Seq().asJava |
304 | ) | 306 | // ) |
305 | 307 | ||
306 | } | 308 | // } |
307 | 309 | ||
308 | class Ontology2_CanonicalModelSpec | 310 | // class Ontology2_CanonicalModelSpec |
309 | extends AnyFlatSpec | 311 | // extends AnyFlatSpec |
310 | with Matchers | 312 | // with Matchers |
311 | with LoneElement { | 313 | // with LoneElement { |
312 | 314 | ||
313 | import Ontology2_CanonicalModelSpec._ | 315 | // import Ontology2_CanonicalModelSpec._ |
314 | 316 | ||
315 | "The program generated from Example #1" should "not be empty" in { | 317 | // "The program generated from Example #1" should "not be empty" in { |
316 | program.rules should not be empty | 318 | // program.rules should not be empty |
317 | } | 319 | // } |
318 | 320 | ||
319 | // Role R // | 321 | // // Role R // |
320 | 322 | ||
321 | renderer.render(roleR) should "be unsafe" in { | 323 | // renderer.render(roleR) should "be unsafe" in { |
322 | ontology.unsafeRoles should contain(roleR) | 324 | // ontology.unsafe should contain(roleR) |
323 | } | 325 | // } |
324 | 326 | ||
325 | it should "have only its inverse in its conflict set" in { | 327 | // it should "have only its inverse in its conflict set" in { |
326 | ontology.confl(roleR).loneElement shouldBe roleR_inv | 328 | // ontology.confl(roleR).loneElement shouldBe roleR_inv |
327 | } | 329 | // } |
328 | 330 | ||
329 | // Role S // | 331 | // // Role S // |
330 | 332 | ||
331 | renderer.render(roleS) should "be unsafe" in { | 333 | // renderer.render(roleS) should "be unsafe" in { |
332 | ontology.unsafeRoles should contain(roleS) | 334 | // ontology.unsafe should contain(roleS) |
333 | } | 335 | // } |
334 | 336 | ||
335 | it should "have only its inverse in its conflict set" in { | 337 | // it should "have only its inverse in its conflict set" in { |
336 | ontology.confl(roleS).loneElement shouldBe roleS_inv | 338 | // ontology.confl(roleS).loneElement shouldBe roleS_inv |
337 | } | 339 | // } |
338 | 340 | ||
339 | // Role T // | 341 | // // Role T // |
340 | 342 | ||
341 | renderer.render(roleT) should "be unsafe" in { | 343 | // renderer.render(roleT) should "be unsafe" in { |
342 | ontology.unsafeRoles should contain(roleT) | 344 | // ontology.unsafe should contain(roleT) |
343 | } | 345 | // } |
344 | 346 | ||
345 | it should "have only its inverse in its conflict set" in { | 347 | // it should "have only its inverse in its conflict set" in { |
346 | ontology.confl(roleT).loneElement shouldBe roleT_inv | 348 | // ontology.confl(roleT).loneElement shouldBe roleT_inv |
347 | } | 349 | // } |
348 | 350 | ||
349 | // Role P // | 351 | // // Role P // |
350 | 352 | ||
351 | renderer.render(roleP) should "be unsafe" in { | 353 | // renderer.render(roleP) should "be unsafe" in { |
352 | ontology.unsafeRoles should contain(roleP) | 354 | // ontology.unsafe should contain(roleP) |
353 | } | 355 | // } |
354 | 356 | ||
355 | it should "have only its inverse in its conflict set" in { | 357 | // it should "have only its inverse in its conflict set" in { |
356 | ontology.confl(roleP).loneElement shouldBe roleP_inv | 358 | // ontology.confl(roleP).loneElement shouldBe roleP_inv |
357 | } | 359 | // } |
358 | 360 | ||
359 | // A ⊑ ∃ R.B | 361 | // // A ⊑ ∃ R.B |
360 | 362 | ||
361 | renderer.render( | 363 | // renderer.render( |
362 | AsomeValuesFromRB | 364 | // AsomeValuesFromRB |
363 | ) should "produce 1 rule" in { | 365 | // ) should "produce 1 rule" in { |
364 | val term = Variable.create("X") | 366 | // val term = Variable.create("X") |
365 | val unsafe = ontology.unsafeRoles | 367 | // val unsafe = ontology.unsafe |
366 | val (facts, rules) = | 368 | // val (facts, rules) = |
367 | converter.convert(AsomeValuesFromRB, term, unsafe, NoSkolem, Empty) | 369 | // converter.convert(AsomeValuesFromRB, term, unsafe, NoSkolem, Empty) |
368 | facts shouldBe empty | 370 | // facts shouldBe empty |
369 | rules should have length 1 | 371 | // rules should have length 1 |
370 | } | 372 | // } |
371 | 373 | ||
372 | // B ⊑ ∃ S.C | 374 | // // B ⊑ ∃ S.C |
373 | 375 | ||
374 | renderer.render( | 376 | // renderer.render( |
375 | BsomeValuesFromSC | 377 | // BsomeValuesFromSC |
376 | ) should "produce 1 rule" in { | 378 | // ) should "produce 1 rule" in { |
377 | val term = Variable.create("X") | 379 | // val term = Variable.create("X") |
378 | val unsafe = ontology.unsafeRoles | 380 | // val unsafe = ontology.unsafe |
379 | val (facts, rules) = | 381 | // val (facts, rules) = |
380 | converter.convert(BsomeValuesFromSC, term, unsafe, NoSkolem, Empty) | 382 | // converter.convert(BsomeValuesFromSC, term, unsafe, NoSkolem, Empty) |
381 | facts shouldBe empty | 383 | // facts shouldBe empty |
382 | rules should have length 1 | 384 | // rules should have length 1 |
383 | } | 385 | // } |
384 | 386 | ||
385 | // C ⊑ ∃ T.D | 387 | // // C ⊑ ∃ T.D |
386 | 388 | ||
387 | renderer.render( | 389 | // renderer.render( |
388 | CsomeValuesFromTD | 390 | // CsomeValuesFromTD |
389 | ) should "produce 1 rule" in { | 391 | // ) should "produce 1 rule" in { |
390 | val term = Variable.create("X") | 392 | // val term = Variable.create("X") |
391 | val unsafe = ontology.unsafeRoles | 393 | // val unsafe = ontology.unsafe |
392 | val (facts, rules) = | 394 | // val (facts, rules) = |
393 | converter.convert(CsomeValuesFromTD, term, unsafe, NoSkolem, Empty) | 395 | // converter.convert(CsomeValuesFromTD, term, unsafe, NoSkolem, Empty) |
394 | facts shouldBe empty | 396 | // facts shouldBe empty |
395 | rules should have length 1 | 397 | // rules should have length 1 |
396 | } | 398 | // } |
397 | 399 | ||
398 | // D ⊑ ∃ P.A | 400 | // // D ⊑ ∃ P.A |
399 | 401 | ||
400 | renderer.render( | 402 | // renderer.render( |
401 | DsomeValuesFromPA | 403 | // DsomeValuesFromPA |
402 | ) should "produce 1 rule" in { | 404 | // ) should "produce 1 rule" in { |
403 | val term = Variable.create("X") | 405 | // val term = Variable.create("X") |
404 | val unsafe = ontology.unsafeRoles | 406 | // val unsafe = ontology.unsafe |
405 | val (facts, rules) = | 407 | // val (facts, rules) = |
406 | converter.convert(DsomeValuesFromPA, term, unsafe, NoSkolem, Empty) | 408 | // converter.convert(DsomeValuesFromPA, term, unsafe, NoSkolem, Empty) |
407 | facts shouldBe empty | 409 | // facts shouldBe empty |
408 | rules should have length 1 | 410 | // rules should have length 1 |
409 | } | 411 | // } |
410 | 412 | ||
411 | } | 413 | // } |
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala index 1df0757..9653546 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/SuiteAll.scala | |||
@@ -32,7 +32,7 @@ import uk.ac.ox.cs.rsacomb.sparql.{ | |||
32 | class SuiteAll | 32 | class SuiteAll |
33 | extends Suites( | 33 | extends Suites( |
34 | new Ontology1_CanonicalModelSpec, | 34 | new Ontology1_CanonicalModelSpec, |
35 | new Ontology2_CanonicalModelSpec, | 35 | //new Ontology2_CanonicalModelSpec, |
36 | new NaiveFilteringProgramSpec, | 36 | new NaiveFilteringProgramSpec, |
37 | new OWLAxiomSpec, | 37 | new OWLAxiomSpec, |
38 | new OWLClassSpec, | 38 | new OWLClassSpec, |
diff --git a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala index 7285df2..5047e12 100644 --- a/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala +++ b/src/test/scala/uk/ac/ox/cs/rsacomb/converter/NormalizerSpec.scala | |||
@@ -27,6 +27,7 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} | |||
27 | import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter | 27 | import uk.ac.ox.cs.rsacomb.converter.RDFoxConverter |
28 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} | 28 | import uk.ac.ox.cs.rsacomb.suffix.{Empty, Forward, Backward, Inverse} |
29 | import uk.ac.ox.cs.rsacomb.converter.{Normalizer, SkolemStrategy, NoSkolem} | 29 | import uk.ac.ox.cs.rsacomb.converter.{Normalizer, SkolemStrategy, NoSkolem} |
30 | import uk.ac.ox.cs.rsacomb.util.DataFactory | ||
30 | 31 | ||
31 | object NormalizerSpec { | 32 | object NormalizerSpec { |
32 | val manager = OWLManager.createOWLOntologyManager() | 33 | val manager = OWLManager.createOWLOntologyManager() |
@@ -89,27 +90,58 @@ class NormalizerSpec extends AnyFlatSpec with Matchers with LoneElement { | |||
89 | ).flatMap(normalizer.normalize) | 90 | ).flatMap(normalizer.normalize) |
90 | } | 91 | } |
91 | 92 | ||
92 | "Disjunction on the rhs" should "be shifted" in { | 93 | "A c \\exists R . D" should "be normalised to { A c \\exists R . C, C c D } if D is not a concept name" in { |
93 | def cls(n: Int) = factory.getOWLClass(s"_:class$n") | 94 | val seed = 42 |
94 | val axiom1 = | 95 | val test = normalizer.normalize( |
95 | factory.getOWLSubClassOfAxiom( | 96 | factory |
96 | factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), | 97 | .getOWLSubClassOfAxiom( |
97 | factory.getOWLObjectUnionOf(cls(4), cls(5)) | 98 | factory.getOWLClass("A"), |
98 | ) | 99 | factory.getOWLObjectSomeValuesFrom( |
99 | val axiom2 = | 100 | factory.getOWLObjectProperty("R"), |
100 | factory.getOWLSubClassOfAxiom( | 101 | factory.getOWLObjectIntersectionOf( |
101 | cls(1), | 102 | factory.getOWLClass("D1"), |
102 | factory.getOWLObjectUnionOf(cls(2), cls(3), cls(4)) | 103 | factory.getOWLClass("D2") |
103 | ) | 104 | ) |
104 | val axiom3 = | 105 | ) |
105 | factory.getOWLSubClassOfAxiom( | 106 | ) |
106 | factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), | 107 | )(DataFactory(seed)) |
107 | factory.getOWLObjectUnionOf(cls(4)) | 108 | val cls = DataFactory(seed).getOWLClass |
108 | ) | 109 | val result = List( |
109 | normalizer.normalize(axiom1) should have length 5 | 110 | factory |
110 | normalizer.normalize(axiom2) should have length 5 | 111 | .getOWLSubClassOfAxiom( |
111 | normalizer.normalize(axiom3) should have length 4 | 112 | factory.getOWLClass("A"), |
113 | factory.getOWLObjectSomeValuesFrom( | ||
114 | factory.getOWLObjectProperty("R"), | ||
115 | cls | ||
116 | ) | ||
117 | ), | ||
118 | factory.getOWLSubClassOfAxiom(cls, factory.getOWLClass("D1")), | ||
119 | factory.getOWLSubClassOfAxiom(cls, factory.getOWLClass("D2")) | ||
120 | ) | ||
121 | test should contain theSameElementsAs result | ||
112 | } | 122 | } |
123 | |||
124 | // "Disjunction on the rhs" should "be shifted" in { | ||
125 | // def cls(n: Int) = factory.getOWLClass(s"_:class$n") | ||
126 | // val axiom1 = | ||
127 | // factory.getOWLSubClassOfAxiom( | ||
128 | // factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), | ||
129 | // factory.getOWLObjectUnionOf(cls(4), cls(5)) | ||
130 | // ) | ||
131 | // val axiom2 = | ||
132 | // factory.getOWLSubClassOfAxiom( | ||
133 | // cls(1), | ||
134 | // factory.getOWLObjectUnionOf(cls(2), cls(3), cls(4)) | ||
135 | // ) | ||
136 | // val axiom3 = | ||
137 | // factory.getOWLSubClassOfAxiom( | ||
138 | // factory.getOWLObjectIntersectionOf(cls(1), cls(2), cls(3)), | ||
139 | // factory.getOWLObjectUnionOf(cls(4)) | ||
140 | // ) | ||
141 | // normalizer.normalize(axiom1) should have length 5 | ||
142 | // normalizer.normalize(axiom2) should have length 5 | ||
143 | // normalizer.normalize(axiom3) should have length 4 | ||
144 | // } | ||
113 | //"A class name" should "be converted into a single atom" in { | 145 | //"A class name" should "be converted into a single atom" in { |
114 | // val cls = factory.getOWLClass(iriString0) | 146 | // val cls = factory.getOWLClass(iriString0) |
115 | // val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0)) | 147 | // val atom = TupleTableAtom.rdf(term0, IRI.RDF_TYPE, IRI.create(iriString0)) |