diff options
Diffstat (limited to 'src/main/scala/rsacomb')
-rw-r--r-- | src/main/scala/rsacomb/CanonicalModel.scala | 62 | ||||
-rw-r--r-- | src/main/scala/rsacomb/FilteringProgram.scala | 284 | ||||
-rw-r--r-- | src/main/scala/rsacomb/Main.scala | 232 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxAxiomConverter.scala | 2 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxClassExprConverter.scala | 19 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala | 2 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RDFoxUtil.scala | 113 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSA.scala | 105 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSAAtom.scala | 6 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSAAxiom.scala | 13 | ||||
-rw-r--r-- | src/main/scala/rsacomb/RSAOntology.scala | 31 | ||||
-rw-r--r-- | src/main/scala/rsacomb/implicits/JavaCollections.scala | 13 | ||||
-rw-r--r-- | src/main/scala/rsacomb/implicits/RDFox.scala | 20 | ||||
-rw-r--r-- | src/main/scala/rsacomb/util/RDFoxHelpers.scala | 100 |
14 files changed, 502 insertions, 500 deletions
diff --git a/src/main/scala/rsacomb/CanonicalModel.scala b/src/main/scala/rsacomb/CanonicalModel.scala index f7a45a7..5f781d1 100644 --- a/src/main/scala/rsacomb/CanonicalModel.scala +++ b/src/main/scala/rsacomb/CanonicalModel.scala | |||
@@ -24,16 +24,15 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ | |||
24 | } | 24 | } |
25 | 25 | ||
26 | import suffix.{Empty, Forward, Backward, Inverse} | 26 | import suffix.{Empty, Forward, Backward, Inverse} |
27 | import util.RSA | ||
27 | 28 | ||
28 | class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | 29 | class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { |
29 | 30 | ||
30 | // Makes working with IRIs less painful | 31 | import implicits.RDFox._ |
31 | import RDFoxUtil._ | 32 | import implicits.JavaCollections._ |
32 | 33 | ||
33 | val named: List[Rule] = | 34 | val named: List[Rule] = |
34 | ontology.individuals.map(a => | 35 | ontology.individuals.map(a => Rule.create(RSA.Named(a))) |
35 | Rule.create(TupleTableAtom.rdf(a, IRI.RDF_TYPE, RSA.Named)) | ||
36 | ) | ||
37 | 36 | ||
38 | val rolesAdditionalRules: List[Rule] = { | 37 | val rolesAdditionalRules: List[Rule] = { |
39 | // Given a role (predicate) compute additional logic rules | 38 | // Given a role (predicate) compute additional logic rules |
@@ -69,7 +68,7 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
69 | val varY = Variable.create("Y") | 68 | val varY = Variable.create("Y") |
70 | val concepts = ontology.concepts.map(c => { | 69 | val concepts = ontology.concepts.map(c => { |
71 | Rule.create( | 70 | Rule.create( |
72 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, IRI.THING), | 71 | RSA.Thing(varX), |
73 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, c.getIRI) | 72 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, c.getIRI) |
74 | ) | 73 | ) |
75 | }) | 74 | }) |
@@ -80,10 +79,7 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
80 | x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse | 79 | x.getInverse.getNamedProperty.getIRI.getIRIString :: Inverse |
81 | } | 80 | } |
82 | Rule.create( | 81 | Rule.create( |
83 | List( | 82 | List(RSA.Thing(varX), RSA.Thing(varY)), |
84 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, IRI.THING), | ||
85 | TupleTableAtom.rdf(varY, IRI.RDF_TYPE, IRI.THING) | ||
86 | ), | ||
87 | List(TupleTableAtom.rdf(varX, name, varY)) | 83 | List(TupleTableAtom.rdf(varX, name, varY)) |
88 | ) | 84 | ) |
89 | }) | 85 | }) |
@@ -95,18 +91,15 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
95 | val varY = Variable.create("Y") | 91 | val varY = Variable.create("Y") |
96 | val varZ = Variable.create("Z") | 92 | val varZ = Variable.create("Z") |
97 | List( | 93 | List( |
94 | // Reflexivity | ||
95 | Rule.create(RSA.EquivTo(varX, varX), RSA.Thing(varX)), | ||
96 | // Simmetry | ||
97 | Rule.create(RSA.EquivTo(varY, varX), RSA.EquivTo(varX, varY)), | ||
98 | // Transitivity | ||
98 | Rule.create( | 99 | Rule.create( |
99 | TupleTableAtom.rdf(varX, RSA.EquivTo, varX), | 100 | RSA.EquivTo(varX, varZ), |
100 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, IRI.THING) | 101 | RSA.EquivTo(varX, varY), |
101 | ), | 102 | RSA.EquivTo(varY, varZ) |
102 | Rule.create( | ||
103 | TupleTableAtom.rdf(varY, RSA.EquivTo, varX), | ||
104 | TupleTableAtom.rdf(varX, RSA.EquivTo, varY) | ||
105 | ), | ||
106 | Rule.create( | ||
107 | TupleTableAtom.rdf(varX, RSA.EquivTo, varZ), | ||
108 | TupleTableAtom.rdf(varX, RSA.EquivTo, varY), | ||
109 | TupleTableAtom.rdf(varY, RSA.EquivTo, varZ) | ||
110 | ) | 103 | ) |
111 | ) | 104 | ) |
112 | } | 105 | } |
@@ -129,21 +122,14 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
129 | private def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = { | 122 | private def rules1(axiom: OWLSubClassOfAxiom): List[Rule] = { |
130 | val unfold = ontology.unfold(axiom).toList | 123 | val unfold = ontology.unfold(axiom).toList |
131 | // Fresh Variables | 124 | // Fresh Variables |
132 | val v0 = RSA.rsa("v0_" ++ RSA.hashed(axiom)) | 125 | val v0 = RSA("v0_" ++ axiom.hashed) |
133 | val varX = Variable.create("X") | 126 | val varX = Variable.create("X") |
134 | // Predicates | 127 | implicit val unfoldTerm = RSA(unfold.hashCode.toString) |
128 | // TODO: use axiom.toTriple instead | ||
135 | val atomA: TupleTableAtom = { | 129 | val atomA: TupleTableAtom = { |
136 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 130 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
137 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls) | 131 | TupleTableAtom.rdf(varX, IRI.RDF_TYPE, cls) |
138 | } | 132 | } |
139 | def predIN(t: Term): TupleTableAtom = { | ||
140 | TupleTableAtom.rdf( | ||
141 | t, | ||
142 | RSA.rsa("IN"), | ||
143 | RSA.rsa(unfold.hashCode.toString) | ||
144 | ) | ||
145 | } | ||
146 | def notIn(t: Term): Negation = Negation.create(predIN(t)) | ||
147 | val roleRf: TupleTableAtom = { | 133 | val roleRf: TupleTableAtom = { |
148 | val visitor = | 134 | val visitor = |
149 | new RDFoxPropertyExprConverter(varX, v0, Forward) | 135 | new RDFoxPropertyExprConverter(varX, v0, Forward) |
@@ -165,10 +151,10 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
165 | // returning facts as `Rule`s with true body. While this is correct | 151 | // returning facts as `Rule`s with true body. While this is correct |
166 | // there is an easier way to import facts into RDFox. Are we able to | 152 | // there is an easier way to import facts into RDFox. Are we able to |
167 | // do that? | 153 | // do that? |
168 | val facts = unfold.map(x => Rule.create(predIN(x))) | 154 | val facts = unfold.map(x => Rule.create(RSA.In(x))) |
169 | val rules = List( | 155 | val rules = List( |
170 | Rule.create(roleRf, atomA, notIn(varX)), | 156 | Rule.create(roleRf, atomA, RSA.notIn(varX)), |
171 | Rule.create(atomB, atomA, notIn(varX)) | 157 | Rule.create(atomB, atomA, RSA.notIn(varX)) |
172 | ) | 158 | ) |
173 | facts ++ rules | 159 | facts ++ rules |
174 | } | 160 | } |
@@ -180,9 +166,9 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
180 | .getProperty | 166 | .getProperty |
181 | if (ontology.confl(roleR) contains roleR) { | 167 | if (ontology.confl(roleR) contains roleR) { |
182 | // Fresh Variables | 168 | // Fresh Variables |
183 | val v0 = RSA.rsa("v0_" ++ RSA.hashed(axiom)) | 169 | val v0 = RSA("v0_" ++ axiom.hashed) |
184 | val v1 = RSA.rsa("v1_" ++ RSA.hashed(axiom)) | 170 | val v1 = RSA("v1_" ++ axiom.hashed) |
185 | val v2 = RSA.rsa("v2_" ++ RSA.hashed(axiom)) | 171 | val v2 = RSA("v2_" ++ axiom.hashed) |
186 | // Predicates | 172 | // Predicates |
187 | def atomA(t: Term): TupleTableAtom = { | 173 | def atomA(t: Term): TupleTableAtom = { |
188 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 174 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
@@ -220,7 +206,7 @@ class CanonicalModel(val ontology: RSAOntology) extends RSAAxiom { | |||
220 | .asInstanceOf[OWLObjectSomeValuesFrom] | 206 | .asInstanceOf[OWLObjectSomeValuesFrom] |
221 | .getProperty | 207 | .getProperty |
222 | // Fresh Variables | 208 | // Fresh Variables |
223 | val v1 = RSA.rsa("v1_" ++ RSA.hashed(axiom)) | 209 | val v1 = RSA("v1_" ++ axiom.hashed) |
224 | // Predicates | 210 | // Predicates |
225 | def atomA(t: Term): TupleTableAtom = { | 211 | def atomA(t: Term): TupleTableAtom = { |
226 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI | 212 | val cls = axiom.getSubClass.asInstanceOf[OWLClass].getIRI |
diff --git a/src/main/scala/rsacomb/FilteringProgram.scala b/src/main/scala/rsacomb/FilteringProgram.scala index af07ac3..5aaf5b0 100644 --- a/src/main/scala/rsacomb/FilteringProgram.scala +++ b/src/main/scala/rsacomb/FilteringProgram.scala | |||
@@ -29,44 +29,43 @@ import scala.collection.JavaConverters._ | |||
29 | 29 | ||
30 | import implicits.RSAAtom | 30 | import implicits.RSAAtom |
31 | import suffix.{RSASuffix, Forward, Backward} | 31 | import suffix.{RSASuffix, Forward, Backward} |
32 | import util.RSA | ||
32 | 33 | ||
33 | class FilteringProgram(query: SelectQuery, constants: List[Term]) | 34 | class FilteringProgram(query: SelectQuery, constants: List[Term]) |
34 | extends RSAAtom { | 35 | extends RSAAtom { |
35 | 36 | ||
36 | /* Makes mplicit conversion OWLAPI IRI <-> RDFox IRI available */ | 37 | /* Makes mplicit conversion OWLAPI IRI <-> RDFox IRI available */ |
37 | import RDFoxUtil._ | 38 | // import implicits.RDFox._ |
38 | 39 | ||
39 | lazy val variables = { | 40 | implicit val variables: (List[Term], List[Term]) = { |
40 | query.getQueryBody.getWherePattern match { | 41 | val all: Set[Variable] = query.getQueryBody.getWherePattern match { |
41 | case b: ConjunctionPattern => { | 42 | case b: ConjunctionPattern => { |
42 | b.getConjuncts.asScala.toSet.flatMap { conj: QueryPattern => | 43 | b.getConjuncts.asScala.toSet.flatMap { conj: QueryPattern => |
43 | conj match { | 44 | conj match { |
44 | case c: TriplePattern => | 45 | case c: TriplePattern => |
45 | Set(c.getSubject, c.getPredicate, c.getObject) | 46 | Set(c.getSubject, c.getPredicate, c.getObject).collect { |
46 | .filter(_.isInstanceOf[Variable]) | 47 | case v: Variable => v |
48 | } | ||
47 | case _ => Set() | 49 | case _ => Set() |
48 | } | 50 | } |
49 | } | 51 | } |
50 | } | 52 | } |
51 | case _ => Set() | 53 | case _ => Set() |
52 | } | 54 | } |
53 | }.toList | ||
54 | |||
55 | val answer: List[Term] = | ||
56 | if (query.getAllPossibleVariables) { | 55 | if (query.getAllPossibleVariables) { |
57 | variables | 56 | (all.toList, List()) |
58 | } else { | 57 | } else { |
59 | query.getSelection.asScala.map(_.getVariable).toList | 58 | val answer = query.getSelection.asScala.map(_.getVariable).toSet |
59 | (answer.toList, (all &~ answer).toList) | ||
60 | } | 60 | } |
61 | val bounded: List[Term] = this.variables.filterNot(answer.contains(_)) | 61 | } |
62 | |||
63 | val (answer, bounded) = variables | ||
62 | 64 | ||
63 | val facts: List[Rule] = constants.map(c => Rule.create(predNI(c))) | 65 | val facts: List[Rule] = constants.map(c => Rule.create(RSA.NI(c))) |
64 | val rules: List[Rule] = | 66 | val rules: List[Rule] = |
65 | this.generateFilteringProgram().map(reifyRule) ++ facts | 67 | this.generateFilteringProgram().map(reifyRule) ++ facts |
66 | 68 | ||
67 | private def predNI(t: Term): TupleTableAtom = | ||
68 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA.rsa("NI")) | ||
69 | |||
70 | /* NOTE: we are restricting to queries that contain conjunctions of | 69 | /* NOTE: we are restricting to queries that contain conjunctions of |
71 | * atoms for the time being. This might need to be reviewed in the | 70 | * atoms for the time being. This might need to be reviewed in the |
72 | * future. | 71 | * future. |
@@ -97,64 +96,54 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
97 | val body = queryToBody(query.getQueryBody.getWherePattern) | 96 | val body = queryToBody(query.getQueryBody.getWherePattern) |
98 | // Auxiliar predicates/helpers | 97 | // Auxiliar predicates/helpers |
99 | def not(atom: TupleTableAtom): BodyFormula = Negation.create(atom) | 98 | def not(atom: TupleTableAtom): BodyFormula = Negation.create(atom) |
100 | val predQM = | 99 | // val predQM = |
101 | TupleTableAtom.create( | 100 | // TupleTableAtom.create( |
102 | TupleTableName.create(RSA.rsa("QM").getIRI), | 101 | // TupleTableName.create(RSA.Qm.getIRI), |
103 | (answer ++ bounded): _* | 102 | // (answer ++ bounded): _* |
104 | ) | 103 | // ) |
105 | def predID(t1: Term, t2: Term) = | 104 | // def predID(t1: Term, t2: Term) = |
106 | TupleTableAtom.create( | 105 | // TupleTableAtom.create( |
107 | TupleTableName.create(RSA.rsa("ID").getIRI), | 106 | // TupleTableName.create(RSA.rsa("ID").getIRI), |
108 | (answer ++ bounded).appended(t1).appended(t2): _* | 107 | // (answer ++ bounded).appended(t1).appended(t2): _* |
109 | ) | 108 | // ) |
110 | def predNAMED(t1: Term): TupleTableAtom = | 109 | // def predNAMED(t1: Term): TupleTableAtom = |
111 | TupleTableAtom.rdf(t1, IRI.RDF_TYPE, RSA.rsa("NAMED")) | 110 | // TupleTableAtom.rdf(t1, IRI.RDF_TYPE, RSA.rsa("NAMED")) |
112 | def predTQ(t1: Term, t2: Term, sx: RSASuffix) = | 111 | // def predTQ(t1: Term, t2: Term, sx: RSASuffix) = |
113 | TupleTableAtom.create( | 112 | // TupleTableAtom.create( |
114 | TupleTableName.create(RSA.rsa("TQ" :: sx).getIRI), | 113 | // TupleTableName.create(RSA.rsa("TQ" :: sx).getIRI), |
115 | (answer ++ bounded).appended(t1).appended(t2): _* | 114 | // (answer ++ bounded).appended(t1).appended(t2): _* |
116 | ) | 115 | // ) |
117 | def predAQ(t1: Term, t2: Term, sx: RSASuffix) = | 116 | // def predAQ(t1: Term, t2: Term, sx: RSASuffix) = |
118 | TupleTableAtom.create( | 117 | // TupleTableAtom.create( |
119 | TupleTableName.create(RSA.rsa("AQ" :: sx).getIRI), | 118 | // TupleTableName.create(RSA.rsa("AQ" :: sx).getIRI), |
120 | (answer ++ bounded).appended(t1).appended(t2): _* | 119 | // (answer ++ bounded).appended(t1).appended(t2): _* |
121 | ) | 120 | // ) |
122 | val predFK = | 121 | // val predFK = |
123 | TupleTableAtom.create( | 122 | // TupleTableAtom.create( |
124 | TupleTableName.create(RSA.rsa("FK").getIRI), | 123 | // TupleTableName.create(RSA.rsa("FK").getIRI), |
125 | (answer ++ bounded): _* | 124 | // (answer ++ bounded): _* |
126 | ) | 125 | // ) |
127 | val predSP = | 126 | // val predSP = |
128 | TupleTableAtom.create( | 127 | // TupleTableAtom.create( |
129 | TupleTableName.create(RSA.rsa("SP").getIRI), | 128 | // TupleTableName.create(RSA.rsa("SP").getIRI), |
130 | (answer ++ bounded): _* | 129 | // (answer ++ bounded): _* |
131 | ) | 130 | // ) |
132 | val predANS = | 131 | // val predANS = |
133 | TupleTableAtom.create( | 132 | // TupleTableAtom.create( |
134 | TupleTableName.create(RSA.rsa("ANS").getIRI), | 133 | // TupleTableName.create(RSA.rsa("ANS").getIRI), |
135 | answer: _* | 134 | // answer: _* |
136 | ) | 135 | // ) |
137 | 136 | ||
138 | /* Rule 1 */ | 137 | /* Rule 1 */ |
139 | val r1 = Rule.create(predQM, body: _*) | 138 | val r1 = Rule.create(RSA.QM, body: _*) |
140 | 139 | ||
141 | /* Rules 3x */ | 140 | /* Rules 3x */ |
142 | val r3a = | 141 | val r3a = |
143 | for ((v, i) <- bounded.zipWithIndex) | 142 | for ((v, i) <- bounded.zipWithIndex) |
144 | yield Rule.create( | 143 | yield Rule.create(RSA.ID(RSA(i), RSA(i)), RSA.QM, not(RSA.NI(v))) |
145 | predID(RSA.rsa(i), RSA.rsa(i)), | 144 | val r3b = Rule.create(RSA.ID(varV, varU), RSA.ID(varU, varV)) |
146 | predQM, | 145 | val r3c = |
147 | not(predNI(v)) | 146 | Rule.create(RSA.ID(varU, varW), RSA.ID(varU, varV), RSA.ID(varV, varW)) |
148 | ) | ||
149 | val r3b = Rule.create( | ||
150 | predID(varV, varU), | ||
151 | predID(varU, varV) | ||
152 | ) | ||
153 | val r3c = Rule.create( | ||
154 | predID(varU, varW), | ||
155 | predID(varU, varV), | ||
156 | predID(varV, varW) | ||
157 | ) | ||
158 | 147 | ||
159 | /* Rules 4x */ | 148 | /* Rules 4x */ |
160 | val r4a = for { | 149 | val r4a = for { |
@@ -163,20 +152,14 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
163 | role2 <- body.filter(_.isRoleAssertion) | 152 | role2 <- body.filter(_.isRoleAssertion) |
164 | if bounded contains (role2.getArguments.get(2)) | 153 | if bounded contains (role2.getArguments.get(2)) |
165 | } yield Rule.create( | 154 | } yield Rule.create( |
166 | predFK, | 155 | RSA.FK, |
167 | role1 << Forward, | 156 | role1 << Forward, |
168 | role2 << Forward, | 157 | role2 << Forward, |
169 | predID( | 158 | RSA.ID( |
170 | RSA.rsa(bounded.indexOf(role1.getArguments.get(2))), | 159 | RSA(bounded.indexOf(role1.getArguments.get(2))), |
171 | RSA.rsa(bounded.indexOf(role2.getArguments.get(2))) | 160 | RSA(bounded.indexOf(role2.getArguments.get(2))) |
172 | ), | 161 | ), |
173 | not( | 162 | not(RSA.EquivTo(role1.getArguments.get(0), role2.getArguments.get(0))) |
174 | TupleTableAtom.rdf( | ||
175 | role1.getArguments.get(0), | ||
176 | RSA.EquivTo, | ||
177 | role2.getArguments.get(0) | ||
178 | ) | ||
179 | ) | ||
180 | ) | 163 | ) |
181 | val r4b = for { | 164 | val r4b = for { |
182 | role1 <- body.filter(_.isRoleAssertion) | 165 | role1 <- body.filter(_.isRoleAssertion) |
@@ -184,20 +167,14 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
184 | role2 <- body.filter(_.isRoleAssertion) | 167 | role2 <- body.filter(_.isRoleAssertion) |
185 | if bounded contains (role2.getArguments.get(0)) | 168 | if bounded contains (role2.getArguments.get(0)) |
186 | } yield Rule.create( | 169 | } yield Rule.create( |
187 | predFK, | 170 | RSA.FK, |
188 | role1 << Forward, | 171 | role1 << Forward, |
189 | role2 << Backward, | 172 | role2 << Backward, |
190 | predID( | 173 | RSA.ID( |
191 | RSA.rsa(bounded.indexOf(role1.getArguments.get(2))), | 174 | RSA(bounded.indexOf(role1.getArguments.get(2))), |
192 | RSA.rsa(bounded.indexOf(role2.getArguments.get(0))) | 175 | RSA(bounded.indexOf(role2.getArguments.get(0))) |
193 | ), | 176 | ), |
194 | not( | 177 | not(RSA.EquivTo(role1.getArguments.get(0), role2.getArguments.get(2))) |
195 | TupleTableAtom.rdf( | ||
196 | role1.getArguments.get(0), | ||
197 | RSA.EquivTo, | ||
198 | role2.getArguments.get(2) | ||
199 | ) | ||
200 | ) | ||
201 | ) | 178 | ) |
202 | val r4c = for { | 179 | val r4c = for { |
203 | role1 <- body.filter(_.isRoleAssertion) | 180 | role1 <- body.filter(_.isRoleAssertion) |
@@ -205,20 +182,14 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
205 | role2 <- body.filter(_.isRoleAssertion) | 182 | role2 <- body.filter(_.isRoleAssertion) |
206 | if bounded contains (role2.getArguments.get(0)) | 183 | if bounded contains (role2.getArguments.get(0)) |
207 | } yield Rule.create( | 184 | } yield Rule.create( |
208 | predFK, | 185 | RSA.FK, |
209 | role1 << Backward, | 186 | role1 << Backward, |
210 | role2 << Backward, | 187 | role2 << Backward, |
211 | predID( | 188 | RSA.ID( |
212 | RSA.rsa(bounded.indexOf(role1.getArguments.get(0))), | 189 | RSA(bounded.indexOf(role1.getArguments.get(0))), |
213 | RSA.rsa(bounded.indexOf(role2.getArguments.get(0))) | 190 | RSA(bounded.indexOf(role2.getArguments.get(0))) |
214 | ), | 191 | ), |
215 | not( | 192 | not(RSA.EquivTo(role1.getArguments.get(2), role2.getArguments.get(2))) |
216 | TupleTableAtom.rdf( | ||
217 | role1.getArguments.get(2), | ||
218 | RSA.EquivTo, | ||
219 | role2.getArguments.get(2) | ||
220 | ) | ||
221 | ) | ||
222 | ) | 193 | ) |
223 | 194 | ||
224 | /* Rules 5x */ | 195 | /* Rules 5x */ |
@@ -234,18 +205,18 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
234 | if bounded contains role2arg0 | 205 | if bounded contains role2arg0 |
235 | if bounded contains role2arg2 | 206 | if bounded contains role2arg2 |
236 | } yield Rule.create( | 207 | } yield Rule.create( |
237 | predID( | 208 | RSA.ID( |
238 | RSA.rsa(bounded indexOf role1arg0), | 209 | RSA(bounded indexOf role1arg0), |
239 | RSA.rsa(bounded indexOf role2arg0) | 210 | RSA(bounded indexOf role2arg0) |
240 | ), | 211 | ), |
241 | role1 << Forward, | 212 | role1 << Forward, |
242 | role2 << Forward, | 213 | role2 << Forward, |
243 | predID( | 214 | RSA.ID( |
244 | RSA.rsa(bounded indexOf role1arg2), | 215 | RSA(bounded indexOf role1arg2), |
245 | RSA.rsa(bounded indexOf role2arg2) | 216 | RSA(bounded indexOf role2arg2) |
246 | ), | 217 | ), |
247 | TupleTableAtom.rdf(role1arg0, RSA.EquivTo, role2arg0), | 218 | RSA.EquivTo(role1arg0, role2arg0), |
248 | not(predNI(role1arg0)) | 219 | not(RSA.NI(role1arg0)) |
249 | ) | 220 | ) |
250 | val r5b = for { | 221 | val r5b = for { |
251 | role1 <- body.filter(_.isRoleAssertion) | 222 | role1 <- body.filter(_.isRoleAssertion) |
@@ -259,18 +230,18 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
259 | if bounded contains role2arg0 | 230 | if bounded contains role2arg0 |
260 | if bounded contains role2arg2 | 231 | if bounded contains role2arg2 |
261 | } yield Rule.create( | 232 | } yield Rule.create( |
262 | predID( | 233 | RSA.ID( |
263 | RSA.rsa(bounded indexOf role1arg0), | 234 | RSA(bounded indexOf role1arg0), |
264 | RSA.rsa(bounded indexOf role2arg2) | 235 | RSA(bounded indexOf role2arg2) |
265 | ), | 236 | ), |
266 | role1 << Forward, | 237 | role1 << Forward, |
267 | role2 << Backward, | 238 | role2 << Backward, |
268 | predID( | 239 | RSA.ID( |
269 | RSA.rsa(bounded indexOf role1arg2), | 240 | RSA(bounded indexOf role1arg2), |
270 | RSA.rsa(bounded indexOf role2arg0) | 241 | RSA(bounded indexOf role2arg0) |
271 | ), | 242 | ), |
272 | TupleTableAtom.rdf(role1arg0, RSA.EquivTo, role2arg2), | 243 | RSA.EquivTo(role1arg0, role2arg2), |
273 | not(predNI(role1arg0)) | 244 | not(RSA.NI(role1arg0)) |
274 | ) | 245 | ) |
275 | val r5c = for { | 246 | val r5c = for { |
276 | role1 <- body.filter(_.isRoleAssertion) | 247 | role1 <- body.filter(_.isRoleAssertion) |
@@ -284,18 +255,18 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
284 | if bounded contains role2arg0 | 255 | if bounded contains role2arg0 |
285 | if bounded contains role2arg2 | 256 | if bounded contains role2arg2 |
286 | } yield Rule.create( | 257 | } yield Rule.create( |
287 | predID( | 258 | RSA.ID( |
288 | RSA.rsa(bounded indexOf role1arg2), | 259 | RSA(bounded indexOf role1arg2), |
289 | RSA.rsa(bounded indexOf role2arg2) | 260 | RSA(bounded indexOf role2arg2) |
290 | ), | 261 | ), |
291 | role1 << Backward, | 262 | role1 << Backward, |
292 | role2 << Backward, | 263 | role2 << Backward, |
293 | predID( | 264 | RSA.ID( |
294 | RSA.rsa(bounded indexOf role1arg0), | 265 | RSA(bounded indexOf role1arg0), |
295 | RSA.rsa(bounded indexOf role2arg0) | 266 | RSA(bounded indexOf role2arg0) |
296 | ), | 267 | ), |
297 | TupleTableAtom.rdf(role1arg2, RSA.EquivTo, role2arg2), | 268 | RSA.EquivTo(role1arg2, role2arg2), |
298 | not(predNI(role1arg2)) | 269 | not(RSA.NI(role1arg2)) |
299 | ) | 270 | ) |
300 | 271 | ||
301 | /* Rules 6 */ | 272 | /* Rules 6 */ |
@@ -308,10 +279,10 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
308 | if bounded contains arg2 | 279 | if bounded contains arg2 |
309 | suffix <- Seq(Forward, Backward) | 280 | suffix <- Seq(Forward, Backward) |
310 | } yield Rule.create( | 281 | } yield Rule.create( |
311 | predAQ(varV, varW, suffix), | 282 | RSA.AQ(varV, varW, suffix), |
312 | role << suffix, | 283 | role << suffix, |
313 | predID(RSA.rsa(bounded indexOf arg0), varV), | 284 | RSA.ID(RSA(bounded indexOf arg0), varV), |
314 | predID(RSA.rsa(bounded indexOf arg2), varW) | 285 | RSA.ID(RSA(bounded indexOf arg2), varW) |
315 | ) | 286 | ) |
316 | } | 287 | } |
317 | 288 | ||
@@ -319,52 +290,33 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
319 | val r7a = { | 290 | val r7a = { |
320 | for (suffix <- List(Forward, Backward)) | 291 | for (suffix <- List(Forward, Backward)) |
321 | yield Rule.create( | 292 | yield Rule.create( |
322 | predTQ(varU, varV, suffix), | 293 | RSA.TQ(varU, varV, suffix), |
323 | predAQ(varU, varV, suffix) | 294 | RSA.AQ(varU, varV, suffix) |
324 | ) | 295 | ) |
325 | } | 296 | } |
326 | val r7b = { | 297 | val r7b = { |
327 | for (suffix <- List(Forward, Backward)) | 298 | for (suffix <- List(Forward, Backward)) |
328 | yield Rule.create( | 299 | yield Rule.create( |
329 | predTQ(varU, varW, suffix), | 300 | RSA.TQ(varU, varW, suffix), |
330 | predAQ(varU, varV, suffix), | 301 | RSA.AQ(varU, varV, suffix), |
331 | predTQ(varV, varW, suffix) | 302 | RSA.TQ(varV, varW, suffix) |
332 | ) | 303 | ) |
333 | } | 304 | } |
334 | 305 | ||
335 | /* Rules 8x */ | 306 | /* Rules 8x */ |
336 | val r8a = | 307 | val r8a = |
337 | for (v <- answer) yield Rule.create(predSP, predQM, not(predNAMED(v))) | 308 | for (v <- answer) yield Rule.create(RSA.SP, RSA.QM, not(RSA.Named(v))) |
338 | val r8b = | 309 | val r8b = |
339 | Rule.create(predSP, predFK) | 310 | Rule.create(RSA.SP, RSA.FK) |
340 | val r8c = | 311 | val r8c = |
341 | for (suffix <- List(Forward, Backward)) | 312 | for (suffix <- List(Forward, Backward)) |
342 | yield Rule.create( | 313 | yield Rule.create( |
343 | predSP, | 314 | RSA.SP, |
344 | predTQ(varV, varV, suffix) | 315 | RSA.TQ(varV, varV, suffix) |
345 | ) | 316 | ) |
346 | 317 | ||
347 | /* Rule 9 */ | 318 | /* Rule 9 */ |
348 | val r9 = Rule.create(predANS, predQM, not(predSP)) | 319 | val r9 = Rule.create(RSA.Ans, RSA.QM, not(RSA.SP)) |
349 | |||
350 | // List.empty | ||
351 | // .prepended(r9) | ||
352 | // .prependedAll(r8c) | ||
353 | // .prepended(r8b) | ||
354 | // .prependedAll(r8a) | ||
355 | // .prependedAll(r7b) | ||
356 | // .prependedAll(r7a) | ||
357 | // .prependedAll(r6) | ||
358 | // .prependedAll(r5c) | ||
359 | // .prependedAll(r5b) | ||
360 | // .prependedAll(r5a) | ||
361 | // .prependedAll(r4c) | ||
362 | // .prependedAll(r4b) | ||
363 | // .prependedAll(r4a) | ||
364 | // .prepended(r3c) | ||
365 | // .prepended(r3b) | ||
366 | // .prependedAll(r3a) | ||
367 | // .prepended(r1) | ||
368 | 320 | ||
369 | r1 :: | 321 | r1 :: |
370 | r3a ::: r3b :: r3c :: | 322 | r3a ::: r3b :: r3c :: |
@@ -377,26 +329,6 @@ class FilteringProgram(query: SelectQuery, constants: List[Term]) | |||
377 | List() | 329 | List() |
378 | } | 330 | } |
379 | 331 | ||
380 | // private def reifyTupleTableAtom( | ||
381 | // atom: TupleTableAtom | ||
382 | // ): (Option[BindAtom], List[TupleTableAtom]) = { | ||
383 | // if (!atom.isRDF) { | ||
384 | // // Compute binding atom | ||
385 | // val bvar = RSA.getFreshVariable() | ||
386 | // val name = | ||
387 | // Literal.create(atom.getTupleTableName.toString(), Datatype.XSD_STRING) | ||
388 | // val args = atom.getArguments.asScala.toList.prepended(name) | ||
389 | // val bind = BindAtom.create(FunctionCall.create("SKOLEM", args: _*), bvar) | ||
390 | // // Compute reified atom | ||
391 | // def reifiedIRI(i: Int) = atom.getTupleTableName.getName ++ s"_$i" | ||
392 | // val atoms = atom.getArguments.asScala.toList.zipWithIndex | ||
393 | // .map { case (t, i) => TupleTableAtom.rdf(bvar, reifiedIRI(i), t) } | ||
394 | // (Some(bind), atoms) | ||
395 | // } else { | ||
396 | // (None, List(atom)) | ||
397 | // } | ||
398 | // } | ||
399 | |||
400 | private def reifyAtom(atom: Atom): (Option[BindAtom], List[Atom]) = { | 332 | private def reifyAtom(atom: Atom): (Option[BindAtom], List[Atom]) = { |
401 | atom match { | 333 | atom match { |
402 | case atom: TupleTableAtom => atom.reified | 334 | case atom: TupleTableAtom => atom.reified |
diff --git a/src/main/scala/rsacomb/Main.scala b/src/main/scala/rsacomb/Main.scala index 8270205..31dd5a0 100644 --- a/src/main/scala/rsacomb/Main.scala +++ b/src/main/scala/rsacomb/Main.scala | |||
@@ -10,7 +10,7 @@ import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | |||
10 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Term} | 10 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI, Term} |
11 | 11 | ||
12 | /* Local imports */ | 12 | /* Local imports */ |
13 | import rsacomb.RSA._ | 13 | import util.{RDFoxHelpers, RSA} |
14 | 14 | ||
15 | object RSAComb extends App { | 15 | object RSAComb extends App { |
16 | 16 | ||
@@ -56,8 +56,10 @@ object RSAComb extends App { | |||
56 | if (ontology.isRSA) { | 56 | if (ontology.isRSA) { |
57 | 57 | ||
58 | /* Load query */ | 58 | /* Load query */ |
59 | val query = RDFoxUtil.parseQuery( | 59 | val query = RDFoxHelpers.parseSelectQuery( |
60 | """ | 60 | """ |
61 | PREFIX : <http://example.com/rsa_example.owl#> | ||
62 | |||
61 | SELECT ?X | 63 | SELECT ?X |
62 | WHERE { | 64 | WHERE { |
63 | ?X a :D ; | 65 | ?X a :D ; |
@@ -71,8 +73,11 @@ object RSAComb extends App { | |||
71 | /* Compute answers to query */ | 73 | /* Compute answers to query */ |
72 | query match { | 74 | query match { |
73 | case Some(query) => { | 75 | case Some(query) => { |
76 | |||
77 | import implicits.JavaCollections._ | ||
78 | |||
74 | // Open connection to RDFox | 79 | // Open connection to RDFox |
75 | val (server, data) = RDFoxUtil.openConnection("AnswerComputation") | 80 | val (server, data) = RDFoxHelpers.openConnection("AnswerComputation") |
76 | 81 | ||
77 | { | 82 | { |
78 | println("\nQuery") | 83 | println("\nQuery") |
@@ -81,7 +86,7 @@ object RSAComb extends App { | |||
81 | 86 | ||
82 | // Step 1. Computing the canonical model | 87 | // Step 1. Computing the canonical model |
83 | val canon = ontology.canonicalModel | 88 | val canon = ontology.canonicalModel |
84 | data.addRules(canon.rules.asJava) | 89 | data.addRules(canon.rules) |
85 | 90 | ||
86 | { | 91 | { |
87 | println("\nCanonical Model rules:") | 92 | println("\nCanonical Model rules:") |
@@ -90,129 +95,136 @@ object RSAComb extends App { | |||
90 | 95 | ||
91 | // Step 2. Computing the canonical model | 96 | // Step 2. Computing the canonical model |
92 | val nis = { | 97 | val nis = { |
93 | val query = | 98 | val query = "SELECT ?Y WHERE { ?X rsa:EquivTo ?Y ; a rsa:Named . }" |
94 | "SELECT ?Y WHERE { ?X rsa:EquivTo ?Y ; a rsa:NAMED . }" | 99 | RDFoxHelpers.submitSelectQuery(data, query, RSA.Prefixes).flatten |
95 | val cursor = | ||
96 | data.createCursor( | ||
97 | RSA.Prefixes, | ||
98 | query, | ||
99 | new HashMap[String, String]() | ||
100 | ); | ||
101 | var mul = cursor.open() | ||
102 | var iris: List[IRI] = List() | ||
103 | while (mul > 0) { | ||
104 | println(cursor.getResource(0)) | ||
105 | iris = cursor.getResource(0) match { | ||
106 | case iri: IRI => iri :: iris | ||
107 | case _ => iris | ||
108 | } | ||
109 | mul = cursor.advance() | ||
110 | } | ||
111 | iris | ||
112 | } | 100 | } |
113 | val filter = ontology.filteringProgram(query, nis) | 101 | val filter = ontology.filteringProgram(query, nis) |
114 | data.addRules(filter.rules.asJava) | 102 | data.addRules(filter.rules) |
115 | 103 | ||
116 | { | 104 | { |
117 | println("\nFiltering rules") | 105 | println("\nFiltering rules") |
118 | filter.rules.foreach(println) | 106 | filter.rules.foreach(println) |
119 | } | 107 | } |
120 | 108 | ||
121 | def retrieveInstances(pred: String, arity: Int): Unit = { | ||
122 | // Build query | ||
123 | var query = "SELECT" | ||
124 | for (i <- 0 until arity) { | ||
125 | query ++= s" ?X$i" | ||
126 | } | ||
127 | query ++= " WHERE {" | ||
128 | for (i <- 0 until arity) { | ||
129 | query ++= s" ?S rsa:${pred}_$i ?X$i ." | ||
130 | } | ||
131 | query ++= " }" | ||
132 | // Collect answers | ||
133 | RDFoxUtil.submitQuery( | ||
134 | data, | ||
135 | RSA.Prefixes, | ||
136 | query, | ||
137 | arity | ||
138 | ) | ||
139 | } | ||
140 | |||
141 | // Retrieve answers | 109 | // Retrieve answers |
142 | println("\nAnswers:") | 110 | println("\nAnswers:") |
143 | retrieveInstances("ANS", filter.answer.length) | 111 | val ans = |
112 | RDFoxHelpers.queryInternalPredicate(data, "Ans", filter.answer.length) | ||
113 | println(ans) | ||
144 | 114 | ||
145 | /* DEBUG: adding additional checks | 115 | /* DEBUG: adding additional checks |
146 | */ | 116 | */ |
147 | println("\nIndividuals:") | ||
148 | ontology.individuals.foreach(println) | ||
149 | |||
150 | println("\nThings:") | ||
151 | RDFoxUtil.submitQuery( | ||
152 | data, | ||
153 | RSA.Prefixes, | ||
154 | "SELECT ?X { ?X a owl:Thing }", | ||
155 | 1 | ||
156 | ) | ||
157 | |||
158 | println("\nNAMEDs:") | ||
159 | RDFoxUtil.submitQuery( | ||
160 | data, | ||
161 | RSA.Prefixes, | ||
162 | "SELECT ?X { ?X a rsa:NAMED }", | ||
163 | 1 | ||
164 | ) | ||
165 | |||
166 | println("\nNIs:") | ||
167 | RDFoxUtil.submitQuery( | ||
168 | data, | ||
169 | RSA.Prefixes, | ||
170 | "SELECT ?X { ?X a rsa:NI }", | ||
171 | 1 | ||
172 | ) | ||
173 | |||
174 | // ID instances | ||
175 | println("\nID instances:") | ||
176 | retrieveInstances("ID", filter.variables.length + 2) | ||
177 | |||
178 | println("\nSameAs instances:") | ||
179 | RDFoxUtil.submitQuery( | ||
180 | data, | ||
181 | RSA.Prefixes, | ||
182 | "SELECT ?X ?Y { ?X rsa:EquivTo ?Y }", | ||
183 | 2 | ||
184 | ) | ||
185 | |||
186 | // Unfiltered answers | ||
187 | println("\nPossible answers:") | ||
188 | retrieveInstances("QM", filter.variables.length) | ||
189 | |||
190 | // Cycle detected | ||
191 | println("\nCycle detection:") | ||
192 | retrieveInstances("AQ_f", filter.variables.length + 2) | ||
193 | retrieveInstances("AQ_b", filter.variables.length + 2) | ||
194 | |||
195 | // Forks detected | ||
196 | println("\nForks:") | ||
197 | retrieveInstances("FK", filter.variables.length) | ||
198 | |||
199 | // Spurious answers | ||
200 | println("\nSpurious answers") | ||
201 | retrieveInstances("SP", filter.variables.length) | ||
202 | |||
203 | { | 117 | { |
204 | val cursor = data.createCursor( | 118 | import suffix.{Forward, Backward} |
205 | RSA.Prefixes, | 119 | |
206 | "ASK { :a a :D }", | 120 | val arity = filter.answer.length + filter.bounded.length |
207 | new HashMap[String, String]() | 121 | |
208 | ); | 122 | println("\nIndividuals:") |
209 | var mul = cursor.open() | 123 | ontology.individuals.foreach(println) |
210 | println(s"Answer: ${mul > 0}") | 124 | |
211 | cursor.close(); | 125 | println("\nThings:") |
126 | val things = RDFoxHelpers.submitSelectQuery( | ||
127 | data, | ||
128 | """ | ||
129 | PREFIX owl: <http://www.w3.org/2002/07/owl#> | ||
130 | |||
131 | SELECT ?X { | ||
132 | ?X a owl:Thing | ||
133 | } | ||
134 | """ | ||
135 | ) | ||
136 | println(things) | ||
137 | |||
138 | println("\nNAMEDs:") | ||
139 | val named = RDFoxHelpers.submitSelectQuery( | ||
140 | data, | ||
141 | """ | ||
142 | SELECT ?X { | ||
143 | ?X a rsa:Named | ||
144 | } | ||
145 | """, | ||
146 | RSA.Prefixes | ||
147 | ) | ||
148 | println(named) | ||
149 | |||
150 | println("\nNIs:") | ||
151 | val nis = RDFoxHelpers.submitSelectQuery( | ||
152 | data, | ||
153 | """ | ||
154 | SELECT ?X { | ||
155 | ?X a rsa:NI | ||
156 | } | ||
157 | """, | ||
158 | RSA.Prefixes | ||
159 | ) | ||
160 | println(nis) | ||
161 | |||
162 | // ID instances | ||
163 | println("\nIDs:") | ||
164 | val ids = RDFoxHelpers.queryInternalPredicate( | ||
165 | data, | ||
166 | "ID", | ||
167 | arity + 2 | ||
168 | ) | ||
169 | println(ids) | ||
170 | |||
171 | println("\nEquivTo:") | ||
172 | val equivs = RDFoxHelpers.submitSelectQuery( | ||
173 | data, | ||
174 | """ | ||
175 | SELECT ?X ?Y { | ||
176 | ?X rsa:EquivTo ?Y | ||
177 | } | ||
178 | """, | ||
179 | RSA.Prefixes | ||
180 | ) | ||
181 | println(equivs) | ||
182 | |||
183 | // Unfiltered answers | ||
184 | println("\nPossible answers:") | ||
185 | val qms = RDFoxHelpers.queryInternalPredicate( | ||
186 | data, | ||
187 | "QM", | ||
188 | arity | ||
189 | ) | ||
190 | println(qms) | ||
191 | |||
192 | // Cycle detected | ||
193 | println("\nCycle detection:") | ||
194 | val aqf = RDFoxHelpers.queryInternalPredicate( | ||
195 | data, | ||
196 | "AQ" :: Forward, | ||
197 | arity + 2 | ||
198 | ) | ||
199 | val aqb = RDFoxHelpers.queryInternalPredicate( | ||
200 | data, | ||
201 | "AQ" :: Backward, | ||
202 | arity + 2 | ||
203 | ) | ||
204 | println(aqf) | ||
205 | println(aqb) | ||
206 | |||
207 | // Forks detected | ||
208 | println("\nForks:") | ||
209 | val fk = RDFoxHelpers.queryInternalPredicate( | ||
210 | data, | ||
211 | "FK", | ||
212 | arity | ||
213 | ) | ||
214 | println(fk) | ||
215 | |||
216 | // Spurious answers | ||
217 | println("\nSpurious answers") | ||
218 | val sp = RDFoxHelpers.queryInternalPredicate( | ||
219 | data, | ||
220 | "SP", | ||
221 | arity | ||
222 | ) | ||
223 | println(sp) | ||
212 | } | 224 | } |
213 | 225 | ||
214 | // Close connection to RDFox | 226 | // Close connection to RDFox |
215 | RDFoxUtil.closeConnection(server, data) | 227 | RDFoxHelpers.closeConnection(server, data) |
216 | } | 228 | } |
217 | case None => {} | 229 | case None => {} |
218 | } | 230 | } |
diff --git a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala index 0368b7c..9b78e8e 100644 --- a/src/main/scala/rsacomb/RDFoxAxiomConverter.scala +++ b/src/main/scala/rsacomb/RDFoxAxiomConverter.scala | |||
@@ -78,7 +78,7 @@ class RDFoxAxiomConverter( | |||
78 | } | 78 | } |
79 | 79 | ||
80 | override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { | 80 | override def visit(axiom: OWLSubObjectPropertyOfAxiom): List[Rule] = { |
81 | val term1 = RSA.getFreshVariable() | 81 | val term1 = RSAOntology.genFreshVariable() |
82 | val subVisitor = | 82 | val subVisitor = |
83 | new RDFoxPropertyExprConverter(term, term1, suffix) | 83 | new RDFoxPropertyExprConverter(term, term1, suffix) |
84 | val superVisitor = new RDFoxPropertyExprConverter(term, term1, suffix) | 84 | val superVisitor = new RDFoxPropertyExprConverter(term, term1, suffix) |
diff --git a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala index f3a0dfc..f4187ed 100644 --- a/src/main/scala/rsacomb/RDFoxClassExprConverter.scala +++ b/src/main/scala/rsacomb/RDFoxClassExprConverter.scala | |||
@@ -26,12 +26,11 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{ | |||
26 | IRI | 26 | IRI |
27 | } | 27 | } |
28 | 28 | ||
29 | import rsacomb.SkolemStrategy | ||
30 | import rsacomb.RDFoxRuleShards | ||
31 | import org.semanticweb.owlapi.model.OWLObjectPropertyExpression | 29 | import org.semanticweb.owlapi.model.OWLObjectPropertyExpression |
32 | import org.semanticweb.owlapi.model.OWLObjectProperty | 30 | import org.semanticweb.owlapi.model.OWLObjectProperty |
33 | 31 | ||
34 | import suffix.{RSASuffix, Empty} | 32 | import suffix.{RSASuffix, Empty} |
33 | import util.RSA | ||
35 | 34 | ||
36 | object RDFoxClassExprConverter { | 35 | object RDFoxClassExprConverter { |
37 | 36 | ||
@@ -61,7 +60,7 @@ class RDFoxClassExprConverter( | |||
61 | suffix: RSASuffix | 60 | suffix: RSASuffix |
62 | ) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { | 61 | ) extends OWLClassExpressionVisitorEx[RDFoxRuleShards] { |
63 | 62 | ||
64 | import RDFoxUtil.owlapi2rdfox; | 63 | import implicits.RDFox._ |
65 | 64 | ||
66 | // OWLClass | 65 | // OWLClass |
67 | override def visit(expr: OWLClass): RDFoxRuleShards = { | 66 | override def visit(expr: OWLClass): RDFoxRuleShards = { |
@@ -99,7 +98,7 @@ class RDFoxClassExprConverter( | |||
99 | 98 | ||
100 | // OWLObjectSomeValuesFrom | 99 | // OWLObjectSomeValuesFrom |
101 | override def visit(expr: OWLObjectSomeValuesFrom): RDFoxRuleShards = { | 100 | override def visit(expr: OWLObjectSomeValuesFrom): RDFoxRuleShards = { |
102 | val y = RSA.getFreshVariable() | 101 | val y = RSAOntology.genFreshVariable() |
103 | // Here we are assuming a role name | 102 | // Here we are assuming a role name |
104 | val prop = expr.getProperty() | 103 | val prop = expr.getProperty() |
105 | // Computes the result of rule skolemization. Depending on the used | 104 | // Computes the result of rule skolemization. Depending on the used |
@@ -110,14 +109,7 @@ class RDFoxClassExprConverter( | |||
110 | case SkolemStrategy.Constant(c) => (List(), List(), c) | 109 | case SkolemStrategy.Constant(c) => (List(), List(), c) |
111 | case SkolemStrategy.ConstantRSA(c) => { | 110 | case SkolemStrategy.ConstantRSA(c) => { |
112 | if (unsafe.contains(prop)) | 111 | if (unsafe.contains(prop)) |
113 | ( | 112 | (List(RSA.PE(term, c), RSA.U(c)), List(), c) |
114 | List( | ||
115 | TupleTableAtom.rdf(term, RSA.rsa("PE"), c), | ||
116 | TupleTableAtom.rdf(c, IRI.RDF_TYPE, RSA.rsa("U")) | ||
117 | ), | ||
118 | List(), | ||
119 | c | ||
120 | ) | ||
121 | else | 113 | else |
122 | (List(), List(), c) | 114 | (List(), List(), c) |
123 | } | 115 | } |
@@ -143,7 +135,8 @@ class RDFoxClassExprConverter( | |||
143 | // OWLObjectMaxCardinality | 135 | // OWLObjectMaxCardinality |
144 | override def visit(expr: OWLObjectMaxCardinality): RDFoxRuleShards = { | 136 | override def visit(expr: OWLObjectMaxCardinality): RDFoxRuleShards = { |
145 | // TODO: again, no hardcoded variables | 137 | // TODO: again, no hardcoded variables |
146 | val vars = List(RSA.getFreshVariable(), RSA.getFreshVariable()) | 138 | val vars = |
139 | List(RSAOntology.genFreshVariable(), RSAOntology.genFreshVariable()) | ||
147 | val classResult = RDFoxClassExprConverter.merge( | 140 | val classResult = RDFoxClassExprConverter.merge( |
148 | vars | 141 | vars |
149 | .map(new RDFoxClassExprConverter(_, unsafe, skolem, suffix)) | 142 | .map(new RDFoxClassExprConverter(_, unsafe, skolem, suffix)) |
diff --git a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala index 525ec62..826e965 100644 --- a/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala +++ b/src/main/scala/rsacomb/RDFoxPropertyExprConverter.scala | |||
@@ -17,7 +17,7 @@ class RDFoxPropertyExprConverter( | |||
17 | ) extends OWLPropertyExpressionVisitorEx[List[TupleTableAtom]] { | 17 | ) extends OWLPropertyExpressionVisitorEx[List[TupleTableAtom]] { |
18 | 18 | ||
19 | // Automatically converts OWLAPI types into RDFox equivalent types. | 19 | // Automatically converts OWLAPI types into RDFox equivalent types. |
20 | import RDFoxUtil.owlapi2rdfox; | 20 | import implicits.RDFox._ |
21 | 21 | ||
22 | override def visit(expr: OWLObjectProperty): List[TupleTableAtom] = { | 22 | override def visit(expr: OWLObjectProperty): List[TupleTableAtom] = { |
23 | val base = expr.getIRI.getIRIString | 23 | val base = expr.getIRI.getIRIString |
diff --git a/src/main/scala/rsacomb/RDFoxUtil.scala b/src/main/scala/rsacomb/RDFoxUtil.scala deleted file mode 100644 index 653c51f..0000000 --- a/src/main/scala/rsacomb/RDFoxUtil.scala +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | package rsacomb | ||
2 | |||
3 | /* Java imports */ | ||
4 | import java.util.HashMap | ||
5 | import java.io.StringReader | ||
6 | import tech.oxfordsemantic.jrdfox.Prefixes | ||
7 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.{Query, SelectQuery} | ||
8 | import tech.oxfordsemantic.jrdfox.client.{ | ||
9 | ConnectionFactory, | ||
10 | ServerConnection, | ||
11 | DataStoreConnection | ||
12 | } | ||
13 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser | ||
14 | |||
15 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFox_IRI} | ||
16 | import org.semanticweb.owlapi.model.{IRI => OWL_IRI} | ||
17 | |||
18 | import scala.collection.JavaConverters._ | ||
19 | |||
20 | object RDFoxUtil { | ||
21 | |||
22 | implicit def rdfox2owlapi(iri: RDFox_IRI): OWL_IRI = { | ||
23 | OWL_IRI.create(iri.getIRI) | ||
24 | } | ||
25 | |||
26 | implicit def owlapi2rdfox(iri: OWL_IRI): RDFox_IRI = { | ||
27 | RDFox_IRI.create(iri.getIRIString()) | ||
28 | } | ||
29 | |||
30 | implicit def stringToRDFoxIRI(iri: String): RDFox_IRI = { | ||
31 | RDFox_IRI.create(iri) | ||
32 | } | ||
33 | |||
34 | implicit def javaToScalaList[A](list: java.util.List[A]): List[A] = { | ||
35 | list.asScala.toList | ||
36 | } | ||
37 | |||
38 | implicit def scalaToJavaList[A](list: List[A]): java.util.List[A] = { | ||
39 | list.asJava | ||
40 | } | ||
41 | |||
42 | def openConnection( | ||
43 | dataStore: String | ||
44 | ): (ServerConnection, DataStoreConnection) = { | ||
45 | /* Create local server connection | ||
46 | */ | ||
47 | val serverUrl = "rdfox:local" | ||
48 | val role = "" | ||
49 | val password = "" | ||
50 | val server = | ||
51 | ConnectionFactory.newServerConnection(serverUrl, role, password) | ||
52 | |||
53 | /* Create datastore connection | ||
54 | */ | ||
55 | val parameters = new HashMap[String, String]() | ||
56 | parameters.put("owl-in-rdf-support", "relaxed") | ||
57 | //parameters.put("equality", "noUNA") | ||
58 | server.createDataStore(dataStore, "par-complex-nn", parameters) | ||
59 | val data = server.newDataStoreConnection(dataStore) | ||
60 | |||
61 | (server, data) | ||
62 | } | ||
63 | |||
64 | def parseQuery( | ||
65 | query: String, | ||
66 | prefixes: Prefixes = RSA.Prefixes | ||
67 | ): Option[SelectQuery] = { | ||
68 | val parser = new SPARQLParser( | ||
69 | prefixes, | ||
70 | new StringReader(query) | ||
71 | ) | ||
72 | // NOTE: return only conjunctive queries for now (SelectQuery) | ||
73 | parser.parseSingleQuery() match { | ||
74 | case q: SelectQuery => Some(q) | ||
75 | case _ => None | ||
76 | } | ||
77 | } | ||
78 | |||
79 | def submitQuery( | ||
80 | data: DataStoreConnection, | ||
81 | prefixes: Prefixes, | ||
82 | query: String, | ||
83 | answers: Int | ||
84 | ): Unit = { | ||
85 | println(s"\nQUERY {\n$query\n}") | ||
86 | val cursor = data.createCursor( | ||
87 | prefixes, | ||
88 | query, | ||
89 | new HashMap[String, String]() | ||
90 | ); | ||
91 | var mul = cursor.open() | ||
92 | while (mul > 0) { | ||
93 | print("Answer: ") | ||
94 | for (i <- 0 until answers) { | ||
95 | val res = cursor.getResource(i) | ||
96 | print(s"$res ") | ||
97 | } | ||
98 | println() | ||
99 | mul = cursor.advance() | ||
100 | } | ||
101 | cursor.close(); | ||
102 | println(s"QUERY END") | ||
103 | } | ||
104 | |||
105 | def closeConnection( | ||
106 | server: ServerConnection, | ||
107 | data: DataStoreConnection | ||
108 | ): Unit = { | ||
109 | server.close(); | ||
110 | data.close(); | ||
111 | } | ||
112 | |||
113 | } // object RDFoxUtil | ||
diff --git a/src/main/scala/rsacomb/RSA.scala b/src/main/scala/rsacomb/RSA.scala index b0e140b..1b2aa9c 100644 --- a/src/main/scala/rsacomb/RSA.scala +++ b/src/main/scala/rsacomb/RSA.scala | |||
@@ -1,11 +1,16 @@ | |||
1 | package rsacomb | 1 | package rsacomb.util |
2 | 2 | ||
3 | /* Java imports */ | 3 | /* Java imports */ |
4 | import java.util.Map | 4 | import java.util.Map |
5 | 5 | ||
6 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser | 6 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser |
7 | import tech.oxfordsemantic.jrdfox.Prefixes | 7 | import tech.oxfordsemantic.jrdfox.Prefixes |
8 | import tech.oxfordsemantic.jrdfox.logic.expression.{Variable, IRI} | 8 | import tech.oxfordsemantic.jrdfox.logic.datalog.{ |
9 | TupleTableAtom, | ||
10 | TupleTableName, | ||
11 | Negation | ||
12 | } | ||
13 | import tech.oxfordsemantic.jrdfox.logic.expression.{Term, Variable, IRI} | ||
9 | import org.semanticweb.owlapi.model.OWLOntology | 14 | import org.semanticweb.owlapi.model.OWLOntology |
10 | import org.semanticweb.owlapi.model.{ | 15 | import org.semanticweb.owlapi.model.{ |
11 | OWLAxiom, | 16 | OWLAxiom, |
@@ -13,51 +18,83 @@ import org.semanticweb.owlapi.model.{ | |||
13 | OWLObjectPropertyExpression | 18 | OWLObjectPropertyExpression |
14 | } | 19 | } |
15 | 20 | ||
21 | import rsacomb.suffix.RSASuffix | ||
22 | |||
16 | // Debug only | 23 | // Debug only |
17 | import scala.collection.JavaConverters._ | 24 | import scala.collection.JavaConverters._ |
18 | 25 | ||
19 | object RSA extends RSAAxiom { | 26 | object RSA { |
20 | 27 | ||
21 | val Prefixes: Prefixes = new Prefixes() | 28 | val Prefixes: Prefixes = new Prefixes() |
22 | Prefixes.declarePrefix(":", "http://example.com/rsa_example.owl#") | ||
23 | Prefixes.declarePrefix("rsa:", "http://127.0.0.1/") | 29 | Prefixes.declarePrefix("rsa:", "http://127.0.0.1/") |
24 | Prefixes.declarePrefix("rdf:", "http://www.w3.org/1999/02/22-rdf-syntax-ns#") | ||
25 | Prefixes.declarePrefix("rdfs:", "http://www.w3.org/2000/01/rdf-schema#") | ||
26 | Prefixes.declarePrefix("owl:", "http://www.w3.org/2002/07/owl#") | ||
27 | 30 | ||
28 | val EquivTo: IRI = this.rsa("EquivTo") | 31 | private def atom(name: IRI, vars: List[Term]) = |
29 | val Named: IRI = this.rsa("NAMED") | 32 | TupleTableAtom.create(TupleTableName.create(name.getIRI), vars: _*) |
33 | |||
34 | def PE(t1: Term, t2: Term) = | ||
35 | TupleTableAtom.rdf(t1, RSA("PE"), t2) | ||
36 | |||
37 | def U(t: Term) = | ||
38 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("U")) | ||
39 | |||
40 | def In(t: Term)(implicit set: Term) = | ||
41 | TupleTableAtom.rdf(t, RSA("In"), set) | ||
42 | |||
43 | def notIn(t: Term)(implicit set: Term) = Negation.create(In(t)(set)) | ||
30 | 44 | ||
31 | // Counter used to implement a simple fresh variable generator | 45 | def EquivTo(t1: Term, t2: Term) = |
32 | private var counter = -1; | 46 | TupleTableAtom.rdf(t1, RSA("EquivTo"), t2) |
33 | 47 | ||
34 | def getFreshVariable(): Variable = { | 48 | def QM(implicit variables: (List[Term], List[Term])) = { |
35 | counter += 1 | 49 | val (answer, bounded) = variables |
36 | Variable.create(f"I$counter%03d") | 50 | atom(RSA("QM"), answer ::: bounded) |
37 | } | 51 | } |
38 | 52 | ||
39 | def base(name: Any): IRI = | 53 | def ID(t1: Term, t2: Term)(implicit variables: (List[Term], List[Term])) = { |
40 | IRI.create( | 54 | val (answer, bounded) = variables |
41 | Prefixes.getPrefixIRIsByPrefixName.get(":").getIRI | 55 | atom(RSA("ID"), (answer ::: bounded) :+ t1 :+ t2) |
42 | + name.toString | 56 | } |
43 | ) | ||
44 | 57 | ||
45 | def rsa(name: Any): IRI = | 58 | def Named(t: Term) = |
46 | IRI.create( | 59 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("Named")) |
47 | Prefixes.getPrefixIRIsByPrefixName.get("rsa:").getIRI | 60 | |
48 | + name.toString | 61 | def Thing(t: Term) = |
49 | ) | 62 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, IRI.THING) |
50 | 63 | ||
51 | def hashed( | 64 | def NI(t: Term) = |
52 | cls1: OWLClass, | 65 | TupleTableAtom.rdf(t, IRI.RDF_TYPE, RSA("NI")) |
53 | prop: OWLObjectPropertyExpression, | ||
54 | cls2: OWLClass | ||
55 | ): String = | ||
56 | (cls1, prop, cls2).hashCode.toString | ||
57 | 66 | ||
58 | def hashed(axiom: OWLAxiom): String = { | 67 | def TQ(t1: Term, t2: Term, sx: RSASuffix)(implicit |
59 | val (cls1, prop, cls2) = axiom.toTriple.get | 68 | variables: (List[Term], List[Term]) |
60 | this.hashed(cls1, prop, cls2) | 69 | ) = { |
70 | val (answer, bounded) = variables | ||
71 | atom(RSA("TQ" :: sx), (answer ::: bounded) :+ t1 :+ t2) | ||
61 | } | 72 | } |
62 | 73 | ||
63 | } // object RSA | 74 | def AQ(t1: Term, t2: Term, sx: RSASuffix)(implicit |
75 | variables: (List[Term], List[Term]) | ||
76 | ) = { | ||
77 | val (answer, bounded) = variables | ||
78 | atom(RSA("AQ" :: sx), (answer ::: bounded) :+ t1 :+ t2) | ||
79 | } | ||
80 | |||
81 | def FK(implicit variables: (List[Term], List[Term])) = { | ||
82 | val (answer, bounded) = variables | ||
83 | atom(RSA("FK"), answer ::: bounded) | ||
84 | } | ||
85 | |||
86 | def SP(implicit variables: (List[Term], List[Term])) = { | ||
87 | val (answer, bounded) = variables | ||
88 | atom(RSA("SP"), answer ::: bounded) | ||
89 | } | ||
90 | |||
91 | def Ans(implicit variables: (List[Term], List[Term])) = { | ||
92 | val (answer, _) = variables | ||
93 | atom(RSA("Ans"), answer) | ||
94 | } | ||
95 | |||
96 | def apply(name: Any): IRI = | ||
97 | IRI.create( | ||
98 | Prefixes.getPrefixIRIsByPrefixName.get("rsa:").getIRI + name.toString | ||
99 | ) | ||
100 | } | ||
diff --git a/src/main/scala/rsacomb/RSAAtom.scala b/src/main/scala/rsacomb/RSAAtom.scala index a65c168..8832226 100644 --- a/src/main/scala/rsacomb/RSAAtom.scala +++ b/src/main/scala/rsacomb/RSAAtom.scala | |||
@@ -11,7 +11,7 @@ import tech.oxfordsemantic.jrdfox.logic.expression.{IRI} | |||
11 | import scala.collection.JavaConverters._ | 11 | import scala.collection.JavaConverters._ |
12 | 12 | ||
13 | import rsacomb.suffix.{RSASuffix, Nth} | 13 | import rsacomb.suffix.{RSASuffix, Nth} |
14 | import rsacomb.RSA | 14 | import rsacomb.RSAOntology |
15 | 15 | ||
16 | /* Is this the best way to determine if an atom is an RDF triple? | 16 | /* Is this the best way to determine if an atom is an RDF triple? |
17 | * Note that we can't use `getNumberOfArguments()` because is not | 17 | * Note that we can't use `getNumberOfArguments()` because is not |
@@ -32,7 +32,7 @@ trait RSAAtom { | |||
32 | 32 | ||
33 | implicit class RSAAtom(val atom: TupleTableAtom) { | 33 | implicit class RSAAtom(val atom: TupleTableAtom) { |
34 | 34 | ||
35 | import rsacomb.RDFoxUtil.stringToRDFoxIRI | 35 | import RDFox._ |
36 | 36 | ||
37 | val name: String = atom.getTupleTableName.getName | 37 | val name: String = atom.getTupleTableName.getName |
38 | 38 | ||
@@ -74,7 +74,7 @@ trait RSAAtom { | |||
74 | if (isRDF) { | 74 | if (isRDF) { |
75 | (None, List(atom)) | 75 | (None, List(atom)) |
76 | } else { | 76 | } else { |
77 | val bvar = RSA.getFreshVariable() | 77 | val bvar = RSAOntology.genFreshVariable() |
78 | val str = Literal.create(name, Datatype.XSD_STRING) | 78 | val str = Literal.create(name, Datatype.XSD_STRING) |
79 | val args = atom.getArguments.asScala.toList | 79 | val args = atom.getArguments.asScala.toList |
80 | val skolem = FunctionCall.create("SKOLEM", str :: args: _*) | 80 | val skolem = FunctionCall.create("SKOLEM", str :: args: _*) |
diff --git a/src/main/scala/rsacomb/RSAAxiom.scala b/src/main/scala/rsacomb/RSAAxiom.scala index 3cd9a9d..08de5b7 100644 --- a/src/main/scala/rsacomb/RSAAxiom.scala +++ b/src/main/scala/rsacomb/RSAAxiom.scala | |||
@@ -38,6 +38,17 @@ trait RSAAxiom { | |||
38 | case object T5 extends RSAAxiomType // A ⊑ ∃R.B | 38 | case object T5 extends RSAAxiomType // A ⊑ ∃R.B |
39 | } | 39 | } |
40 | 40 | ||
41 | object RSAAxiom { | ||
42 | |||
43 | def hashed( | ||
44 | cls1: OWLClass, | ||
45 | prop: OWLObjectPropertyExpression, | ||
46 | cls2: OWLClass | ||
47 | ): String = | ||
48 | (cls1, prop, cls2).hashCode.toString | ||
49 | |||
50 | } | ||
51 | |||
41 | /* Implements additional features on top of `OWLAxiom` from | 52 | /* Implements additional features on top of `OWLAxiom` from |
42 | * the OWLAPI. | 53 | * the OWLAPI. |
43 | */ | 54 | */ |
@@ -137,6 +148,8 @@ trait RSAAxiom { | |||
137 | } | 148 | } |
138 | cls2 <- Some(someValues.getFiller) collect { case a: OWLClass => a } | 149 | cls2 <- Some(someValues.getFiller) collect { case a: OWLClass => a } |
139 | } yield (cls1, prop, cls2) | 150 | } yield (cls1, prop, cls2) |
151 | |||
152 | lazy val hashed: String = (RSAAxiom.hashed _) tupled toTriple.get | ||
140 | } | 153 | } |
141 | 154 | ||
142 | } // trait RSAAxiom | 155 | } // trait RSAAxiom |
diff --git a/src/main/scala/rsacomb/RSAOntology.scala b/src/main/scala/rsacomb/RSAOntology.scala index 52bff37..1a5e4ca 100644 --- a/src/main/scala/rsacomb/RSAOntology.scala +++ b/src/main/scala/rsacomb/RSAOntology.scala | |||
@@ -47,14 +47,23 @@ import tech.oxfordsemantic.jrdfox.logic._ | |||
47 | import org.semanticweb.owlapi.model.OWLObjectInverseOf | 47 | import org.semanticweb.owlapi.model.OWLObjectInverseOf |
48 | 48 | ||
49 | import suffix.{Empty, Forward, Backward, Inverse} | 49 | import suffix.{Empty, Forward, Backward, Inverse} |
50 | import util.{RDFoxHelpers, RSA} | ||
50 | 51 | ||
51 | object RSAOntology { | 52 | object RSAOntology { |
52 | 53 | ||
54 | // Counter used to implement a simple fresh variable generator | ||
55 | private var counter = -1; | ||
56 | |||
53 | def apply(ontology: OWLOntology): RSAOntology = new RSAOntology(ontology) | 57 | def apply(ontology: OWLOntology): RSAOntology = new RSAOntology(ontology) |
54 | 58 | ||
55 | def apply(ontology: File): RSAOntology = | 59 | def apply(ontology: File): RSAOntology = |
56 | new RSAOntology(loadOntology(ontology)) | 60 | new RSAOntology(loadOntology(ontology)) |
57 | 61 | ||
62 | def genFreshVariable(): Variable = { | ||
63 | counter += 1 | ||
64 | Variable.create(f"I$counter%03d") | ||
65 | } | ||
66 | |||
58 | private def loadOntology(onto: File): OWLOntology = { | 67 | private def loadOntology(onto: File): OWLOntology = { |
59 | val manager = OWLManager.createOWLOntologyManager() | 68 | val manager = OWLManager.createOWLOntologyManager() |
60 | manager.loadOntologyFromOntologyDocument(onto) | 69 | manager.loadOntologyFromOntologyDocument(onto) |
@@ -94,7 +103,7 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
94 | .getIndividualsInSignature() | 103 | .getIndividualsInSignature() |
95 | .asScala | 104 | .asScala |
96 | .map(_.getIRI) | 105 | .map(_.getIRI) |
97 | .map(RDFoxUtil.owlapi2rdfox) | 106 | .map(implicits.RDFox.owlapiToRdfoxIri) |
98 | .toList | 107 | .toList |
99 | 108 | ||
100 | val concepts: List[OWLClass] = | 109 | val concepts: List[OWLClass] = |
@@ -133,7 +142,7 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
133 | val datalog = for { | 142 | val datalog = for { |
134 | axiom <- axioms | 143 | axiom <- axioms |
135 | visitor = new RDFoxAxiomConverter( | 144 | visitor = new RDFoxAxiomConverter( |
136 | RSA.getFreshVariable(), | 145 | RSAOntology.genFreshVariable(), |
137 | unsafe, | 146 | unsafe, |
138 | SkolemStrategy.ConstantRSA(axiom.toString), | 147 | SkolemStrategy.ConstantRSA(axiom.toString), |
139 | Empty | 148 | Empty |
@@ -146,9 +155,9 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
146 | //datalog.foreach(println) | 155 | //datalog.foreach(println) |
147 | 156 | ||
148 | // Open connection with RDFox | 157 | // Open connection with RDFox |
149 | val (server, data) = RDFoxUtil.openConnection("RSACheck") | 158 | val (server, data) = RDFoxHelpers.openConnection("RSACheck") |
150 | // Add Data (hardcoded for now) | 159 | // Add Data (hardcoded for now) |
151 | data.importData(UpdateType.ADDITION, RSA.Prefixes, ":a a :A .") | 160 | //data.importData(UpdateType.ADDITION, RSA.Prefixes, ":a a :A .") |
152 | 161 | ||
153 | /* Add built-in rules | 162 | /* Add built-in rules |
154 | */ | 163 | */ |
@@ -176,7 +185,7 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
176 | //println(graph) | 185 | //println(graph) |
177 | 186 | ||
178 | // Close connection to RDFox | 187 | // Close connection to RDFox |
179 | RDFoxUtil.closeConnection(server, data) | 188 | RDFoxHelpers.closeConnection(server, data) |
180 | 189 | ||
181 | /* To check if the graph is tree-like we check for acyclicity in a | 190 | /* To check if the graph is tree-like we check for acyclicity in a |
182 | * undirected graph. | 191 | * undirected graph. |
@@ -291,8 +300,8 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
291 | val role = axiom.objectPropertyExpressionsInSignature(0) | 300 | val role = axiom.objectPropertyExpressionsInSignature(0) |
292 | if (this.confl(role).contains(role)) { | 301 | if (this.confl(role).contains(role)) { |
293 | Set( | 302 | Set( |
294 | RSA.rsa("v0_" ++ RSA.hashed(axiom)), | 303 | RSA("v0_" ++ axiom.hashed), |
295 | RSA.rsa("v1_" ++ RSA.hashed(axiom)) | 304 | RSA("v1_" ++ axiom.hashed) |
296 | ) | 305 | ) |
297 | } else { | 306 | } else { |
298 | Set() | 307 | Set() |
@@ -354,15 +363,15 @@ class RSAOntology(val ontology: OWLOntology) extends RSAAxiom { | |||
354 | classC <- classes | 363 | classC <- classes |
355 | // Keeping this check for now | 364 | // Keeping this check for now |
356 | if !unsafeRoles.contains(roleS) | 365 | if !unsafeRoles.contains(roleS) |
357 | tripleARB = RSA.hashed(classA, roleR, classB) | 366 | tripleARB = RSAAxiom.hashed(classA, roleR, classB) |
358 | tripleDSC = RSA.hashed(classD, roleS, classC) | 367 | tripleDSC = RSAAxiom.hashed(classD, roleS, classC) |
359 | individual = | 368 | individual = |
360 | if (tripleARB > tripleDSC) { | 369 | if (tripleARB > tripleDSC) { |
361 | RSA.rsa("v1_" ++ tripleDSC) | 370 | RSA("v1_" ++ tripleDSC) |
362 | } else { | 371 | } else { |
363 | // Note that this is also the case for | 372 | // Note that this is also the case for |
364 | // `tripleARB == tripleDSC` | 373 | // `tripleARB == tripleDSC` |
365 | RSA.rsa("v0_" ++ tripleDSC) | 374 | RSA("v0_" ++ tripleDSC) |
366 | } | 375 | } |
367 | } yield individual | 376 | } yield individual |
368 | } | 377 | } |
diff --git a/src/main/scala/rsacomb/implicits/JavaCollections.scala b/src/main/scala/rsacomb/implicits/JavaCollections.scala new file mode 100644 index 0000000..69e825b --- /dev/null +++ b/src/main/scala/rsacomb/implicits/JavaCollections.scala | |||
@@ -0,0 +1,13 @@ | |||
1 | package rsacomb.implicits | ||
2 | |||
3 | import scala.collection.JavaConverters._ | ||
4 | |||
5 | object JavaCollections { | ||
6 | |||
7 | implicit def javaToScalaList[A](list: java.util.List[A]): List[A] = | ||
8 | list.asScala.toList | ||
9 | |||
10 | implicit def scalaToJavaList[A](list: List[A]): java.util.List[A] = | ||
11 | list.asJava | ||
12 | |||
13 | } | ||
diff --git a/src/main/scala/rsacomb/implicits/RDFox.scala b/src/main/scala/rsacomb/implicits/RDFox.scala new file mode 100644 index 0000000..44b7c01 --- /dev/null +++ b/src/main/scala/rsacomb/implicits/RDFox.scala | |||
@@ -0,0 +1,20 @@ | |||
1 | package rsacomb.implicits | ||
2 | |||
3 | import tech.oxfordsemantic.jrdfox.logic.expression.{IRI => RDFoxIRI} | ||
4 | import org.semanticweb.owlapi.model.{IRI => OWLIRI} | ||
5 | |||
6 | object RDFox { | ||
7 | |||
8 | implicit def rdfoxToOwlapiIri(iri: RDFoxIRI): OWLIRI = { | ||
9 | OWLIRI.create(iri.getIRI) | ||
10 | } | ||
11 | |||
12 | implicit def owlapiToRdfoxIri(iri: OWLIRI): RDFoxIRI = { | ||
13 | RDFoxIRI.create(iri.getIRIString()) | ||
14 | } | ||
15 | |||
16 | implicit def stringToRdfoxIri(iri: String): RDFoxIRI = { | ||
17 | RDFoxIRI.create(iri) | ||
18 | } | ||
19 | |||
20 | } | ||
diff --git a/src/main/scala/rsacomb/util/RDFoxHelpers.scala b/src/main/scala/rsacomb/util/RDFoxHelpers.scala new file mode 100644 index 0000000..9856e27 --- /dev/null +++ b/src/main/scala/rsacomb/util/RDFoxHelpers.scala | |||
@@ -0,0 +1,100 @@ | |||
1 | package rsacomb.util | ||
2 | |||
3 | import java.util.{Map => JMap, HashMap => JHashMap} | ||
4 | import java.io.StringReader | ||
5 | import tech.oxfordsemantic.jrdfox.Prefixes | ||
6 | import tech.oxfordsemantic.jrdfox.client.{ | ||
7 | ConnectionFactory, | ||
8 | ServerConnection, | ||
9 | DataStoreConnection | ||
10 | } | ||
11 | import tech.oxfordsemantic.jrdfox.formats.SPARQLParser | ||
12 | import tech.oxfordsemantic.jrdfox.logic.expression.Resource | ||
13 | import tech.oxfordsemantic.jrdfox.logic.sparql.statement.SelectQuery | ||
14 | |||
15 | import rsacomb.suffix.Nth | ||
16 | |||
17 | object RDFoxHelpers { | ||
18 | |||
19 | def openConnection( | ||
20 | dataStore: String, | ||
21 | opts: JMap[String, String] = new JHashMap[String, String]() | ||
22 | ): (ServerConnection, DataStoreConnection) = { | ||
23 | /* Create local server connection | ||
24 | */ | ||
25 | val serverUrl = "rdfox:local" | ||
26 | val role = "" | ||
27 | val password = "" | ||
28 | val server = | ||
29 | ConnectionFactory.newServerConnection(serverUrl, role, password) | ||
30 | |||
31 | /* Create datastore connection | ||
32 | */ | ||
33 | // parameters.put("owl-in-rdf-support", "relaxed") | ||
34 | // parameters.put("equality", "noUNA") | ||
35 | server.createDataStore(dataStore, "par-complex-nn", opts) | ||
36 | val data = server.newDataStoreConnection(dataStore) | ||
37 | |||
38 | (server, data) | ||
39 | } | ||
40 | |||
41 | def parseSelectQuery( | ||
42 | query: String, | ||
43 | prefixes: Prefixes = new Prefixes() | ||
44 | ): Option[SelectQuery] = { | ||
45 | val parser = new SPARQLParser( | ||
46 | prefixes, | ||
47 | new StringReader(query) | ||
48 | ) | ||
49 | parser.parseSingleQuery() match { | ||
50 | case q: SelectQuery => Some(q) | ||
51 | case _ => None | ||
52 | } | ||
53 | } | ||
54 | |||
55 | def submitSelectQuery( | ||
56 | data: DataStoreConnection, | ||
57 | query: String, | ||
58 | prefixes: Prefixes = new Prefixes(), | ||
59 | opts: JMap[String, String] = new JHashMap[String, String]() | ||
60 | ): List[List[Resource]] = { | ||
61 | val cursor = data.createCursor(prefixes, query, opts) | ||
62 | var answers: List[List[Resource]] = List() | ||
63 | var mul = cursor.open() | ||
64 | while (mul > 0) { | ||
65 | val answer = | ||
66 | (0 until cursor.getArity).map(cursor.getResource(_)).toList | ||
67 | answers = answer :: answers | ||
68 | mul = cursor.advance() | ||
69 | } | ||
70 | cursor.close(); | ||
71 | answers | ||
72 | } | ||
73 | |||
74 | def queryInternalPredicate( | ||
75 | data: DataStoreConnection, | ||
76 | pred: String, | ||
77 | arity: Int, | ||
78 | opts: JMap[String, String] = new JHashMap[String, String]() | ||
79 | ): List[List[Resource]] = { | ||
80 | var query = "SELECT" | ||
81 | for (i <- 0 until arity) { | ||
82 | query ++= s" ?X$i" | ||
83 | } | ||
84 | query ++= " WHERE {" | ||
85 | for (i <- 0 until arity) { | ||
86 | query ++= s" ?S rsa:${pred :: Nth(i)} ?X$i ." | ||
87 | } | ||
88 | query ++= " }" | ||
89 | submitSelectQuery(data, query, RSA.Prefixes, opts) | ||
90 | } | ||
91 | |||
92 | def closeConnection( | ||
93 | server: ServerConnection, | ||
94 | data: DataStoreConnection | ||
95 | ): Unit = { | ||
96 | server.close(); | ||
97 | data.close(); | ||
98 | } | ||
99 | |||
100 | } | ||