11package net .sansa_stack .inference .spark .forwardchaining .axioms
22
33import scala .collection .JavaConverters ._
4- import java .io .File
5- import java .util .stream .Collectors
64
75import org .apache .spark .rdd .RDD
86import org .apache .spark .sql .SparkSession
@@ -11,7 +9,6 @@ import org.semanticweb.owlapi.model._
119import org .semanticweb .owlapi .apibinding .OWLManager
1210import net .sansa_stack .inference .utils .{CollectionUtils , Logging }
1311import net .sansa_stack .owl .spark .rdd .FunctionalSyntaxOWLAxiomsRDDBuilder
14- import net .sansa_stack .owl .spark .rdd .OWLAxiomsRDD
1512import org .apache .spark .broadcast .Broadcast
1613
1714
@@ -34,9 +31,9 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
3431
3532
3633 def apply (axioms : RDD [OWLAxiom ]): RDD [OWLAxiom ] = {
34+
3735 val manager = OWLManager .createOWLOntologyManager()
3836 val dataFactory = manager.getOWLDataFactory
39-
4037 val axiomsRDD = axioms.cache() // cache this RDD because it will be used quiet often
4138
4239 // ------------ extract the schema data -------------------
@@ -52,7 +49,8 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
5249
5350 // OWLClassAssertionAxiom
5451 val classAsserAxiom = axiomsRDD
55- .filter(axiom => axiom.getAxiomType.equals(AxiomType .CLASS_ASSERTION )).asInstanceOf [RDD [OWLClassAssertionAxiom ]].cache()
52+ .filter(axiom => axiom.getAxiomType.equals(AxiomType .CLASS_ASSERTION ))
53+ .asInstanceOf [RDD [OWLClassAssertionAxiom ]].cache()
5654
5755// val cmap: Map[OWLClassExpression, Set[OWLIndividual]] = CollectionUtils
5856// .toMultiMap(classAsserAxiom.asInstanceOf[RDD[OWLClassAssertionAxiom]]
@@ -78,61 +76,73 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
7876 // OWLSubDataPropertyofAxiom
7977 val subDataPropertyofAxiom = axiomsRDD
8078 .filter(axiom => axiom.getAxiomType.equals(AxiomType .SUB_DATA_PROPERTY ))
81- // .asInstanceOf[RDD[OWLSubDataPropertyOfAxiom]]
79+
8280// println("\n\nOWLSubDataPropertyofAxioms\n-------\n")
8381// subDataPropertyofAxiom.collect().foreach(println)
8482
8583 // OWLSubObjectPropertyofAxiom
86- val subObjectPropertyofAxiom : RDD [ OWLAxiom ] = axiomsRDD
84+ val subObjectPropertyofAxiom = axiomsRDD
8785 .filter(axiom => axiom.getAxiomType.equals(AxiomType .SUB_OBJECT_PROPERTY ))
8886
8987// println("\n\nOWLSubObjectPropertyofAxioms\n-------\n")
9088// subObjectPropertyofAxiom.collect().foreach(println)
9189
9290 // OWLObjectPropertyDomainAxiom
93- val objectProDomain : RDD [ OWLAxiom ] = axiomsRDD
91+ val objectProDomain = axiomsRDD
9492 .filter(axiom => axiom.getAxiomType.equals(AxiomType .OBJECT_PROPERTY_DOMAIN ))
9593
9694// println("\n\nOWLObjectPropertyDomainAxiom\n-------\n")
9795// objectProDomain.collect().foreach(println)
9896
9997 // OWLDataPropertyDomainAxiom
100- val dataProDomain : RDD [ OWLAxiom ] = axiomsRDD
98+ val dataProDomain = axiomsRDD
10199 .filter(axiom => axiom.getAxiomType.equals(AxiomType .DATA_PROPERTY_DOMAIN ))
102100
103101// println("\n\nOWLDataPropertyDomainAxiom\n-------\n")
104102// dataProDomain.collect().foreach(println)
105103
104+ // OWLAnnotationPropertyDomainAxiom
105+ val AnnProDomain = axiomsRDD
106+ .filter(axiom => axiom.getAxiomType.equals(AxiomType .ANNOTATION_PROPERTY_DOMAIN ))
107+
106108 // OWLDataPropertyRangeAxiom
107- val dataProRange : RDD [ OWLAxiom ] = axiomsRDD
109+ val dataProRange = axiomsRDD
108110 .filter(axiom => axiom.getAxiomType.equals(AxiomType .DATA_PROPERTY_RANGE ))
109111
110112// println("\n\nOWLDataPropertyRangeAxiom\n-------\n")
111113// dataProRange.collect().foreach(println)
112114
113115 // OWLObjectPropertyRangeAxiom
114- val objProRange : RDD [ OWLAxiom ] = axiomsRDD
116+ val objProRange = axiomsRDD
115117 .filter(axiom => axiom.getAxiomType.equals(AxiomType .OBJECT_PROPERTY_RANGE ))
116118
117119// println("\n\nOWLObjectPropertyRangeAxiom\n-------\n")
118120// objProRange.collect().foreach(println)
119121
122+ // OWLAnnotationPropertyRangeAxiom
123+ val AnnProRange = axiomsRDD
124+ .filter(axiom => axiom.getAxiomType.equals(AxiomType .ANNOTATION_PROPERTY_RANGE ))
125+
120126 // OWLDataPropertyAssertionAxiom
121- val dataPropAsserAxiom : RDD [ OWLAxiom ] = axiomsRDD
127+ val dataPropAsserAxiom = axiomsRDD
122128 .filter(axiom => axiom.getAxiomType.equals(AxiomType .DATA_PROPERTY_ASSERTION ))
123129
124130// println("\n\nOWLDataPropertyAssertionAxiom\n-------\n")
125131// dataPropAsserAxiom.collect().foreach(println)
126132
127133 // OWLObjectPropertyAssertionAxiom
128- val objPropAsserAxiom : RDD [ OWLAxiom ] = axiomsRDD
134+ val objPropAsserAxiom = axiomsRDD
129135 .filter(axiom => axiom.getAxiomType.equals(AxiomType .OBJECT_PROPERTY_ASSERTION ))
130136
131137// println("\n\nOWLObjectPropertyAssertionAxiom\n-------\n")
132138// objPropAsserAxiom.collect().foreach(println)
133139
140+ // OWLAnnotationPropertyAssertionAxiom
141+ val AnnAsserAxiom = axiomsRDD
142+ .filter(axiom => axiom.getAxiomType.equals(AxiomType .ANNOTATION_ASSERTION ))
143+
134144 // OWLSubAnnotationPropertyAssertionAxiom
135- val subAnnProp : RDD [ OWLAxiom ] = axiomsRDD
145+ val subAnnProp = axiomsRDD
136146 .filter(axiom => axiom.getAxiomType.equals(AxiomType .SUB_ANNOTATION_PROPERTY_OF ))
137147
138148// println("\n\nOWLSubAnnotationPropertyOAxiom\n-------\n")
@@ -148,7 +158,8 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
148158 */
149159
150160 val tr = new TransitiveReasoner ()
151- val subClassOfAxiomsTrans = tr.computeTransitiveClosure(subClassofAxiom, AxiomType .SUBCLASS_OF ).setName(" rdfs11" )
161+ val subClassOfAxiomsTrans = tr.computeTransitiveClosure(subClassofAxiom, AxiomType .SUBCLASS_OF )
162+ .setName(" rdfs11" )
152163
153164// println("\n Transitive subClassOfAxiom closures: \n----------------\n")
154165// subClassOfAxiomsTrans.collect().foreach(println)
@@ -160,18 +171,20 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
160171 */
161172
162173 // val subDataPropertyOfAxiomsTrans = tr.computeSubDataPropertyTransitiveClosure(subDataPropertyofAxiom).setName("rdfs5")
163- val subDataPropertyOfAxiomsTrans = tr.computeTransitiveClosure(subDataPropertyofAxiom, AxiomType .SUB_DATA_PROPERTY ).setName(" rdfs5" )
174+ val subDataPropertyOfAxiomsTrans = tr.computeTransitiveClosure(subDataPropertyofAxiom, AxiomType .SUB_DATA_PROPERTY )
175+ .setName(" rdfs5a" )
164176
165177// println("\n Transitive subDataPropertyOfAxiom closures: \n----------------\n")
166178// subDataPropertyOfAxiomsTrans.collect().foreach(println)
167179
168- val subObjectPropertyOfAxiomsTrans = tr.computeTransitiveClosure(subObjectPropertyofAxiom, AxiomType .SUB_OBJECT_PROPERTY ).setName(" rdfs5" )
180+ val subObjectPropertyOfAxiomsTrans = tr.computeTransitiveClosure(subObjectPropertyofAxiom, AxiomType .SUB_OBJECT_PROPERTY )
181+ .setName(" rdfs5b" )
169182
170183// println("\n Transitive subObjectPropertyOfAxiom closures: \n----------------\n")
171184// subObjectPropertyOfAxiomsTrans.collect().foreach(println)
172185
173186 val subAnnotationPropertyOfAxiomsTrans = tr.computeTransitiveClosure(subAnnProp, AxiomType .SUB_ANNOTATION_PROPERTY_OF )
174-
187+ .setName( " rdfs5c " )
175188// println("\n Transitive subAnnotationPropertyOfAxiom closures: \n----------------\n")
176189// subAnnotationPropertyOfAxiomsTrans.collect().foreach(println)
177190
@@ -193,10 +206,15 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
193206 .toMultiMap(subObjectPropertyOfAxiomsTrans.asInstanceOf [RDD [OWLSubObjectPropertyOfAxiom ]]
194207 .map(a => (a.getSubProperty, a.getSuperProperty)).collect())
195208
209+ val subAnnPropMap = CollectionUtils
210+ .toMultiMap(subAnnotationPropertyOfAxiomsTrans.asInstanceOf [RDD [OWLSubAnnotationPropertyOfAxiom ]]
211+ .map(a => (a.getSubProperty, a.getSuperProperty)).collect())
212+
196213 // distribute the schema data structures by means of shared variables
197214 val subClassOfBC = sc.broadcast(subClassMap)
198215 val subDataPropertyBC = sc.broadcast(subDataPropMap)
199216 val subObjectPropertyBC = sc.broadcast(subObjectPropMap)
217+ val subAnnPropertyBC = sc.broadcast(subAnnPropMap)
200218
201219 // split ontology Axioms based on type, sameAs, and the rest of axioms
202220
@@ -222,8 +240,17 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
222240 .map(s => dataFactory.getOWLObjectPropertyAssertionAxiom(s, a.getSubject, a.getObject)))
223241 .setName(" rdfs7b" )
224242
225- SPOAxioms = SPOAxioms .union(RDFS7a .asInstanceOf [RDD [OWLAxiom ]])
226- .union(RDFS7b .asInstanceOf [RDD [OWLAxiom ]]).setName(" SPO Axioms + rule 7a + rule 7b " )
243+ val RDFS7c = AnnAsserAxiom .asInstanceOf [RDD [OWLAnnotationAssertionAxiom ]]
244+ .filter(a => subAnnPropertyBC.value.contains(a.getProperty))
245+ .flatMap(a => subAnnPropertyBC.value(a.getProperty)
246+ .map(s => dataFactory.getOWLAnnotationAssertionAxiom(s, a.getSubject, a.getValue)))
247+ .setName(" rdfs7b" )
248+
249+ SPOAxioms = sc.union(SPOAxioms ,
250+ RDFS7a .asInstanceOf [RDD [OWLAxiom ]],
251+ RDFS7b .asInstanceOf [RDD [OWLAxiom ]],
252+ RDFS7c .asInstanceOf [RDD [OWLAxiom ]])
253+ .setName(" SPO Axioms + rule 7a + rule 7b + rule 7c " )
227254
228255 /* 3. Domain and Range inheritance according to rdfs2 and rdfs3 is computed
229256
@@ -233,58 +260,74 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
233260 */
234261
235262 // val dataProDomain = extractAxiom(SPOAxioms, AxiomType.DATA_PROPERTY_DOMAIN)
236- val dataDomainMap : Map [ OWLDataPropertyExpression , OWLClassExpression ] = dataProDomain.asInstanceOf [RDD [OWLDataPropertyDomainAxiom ]]
263+ val dataDomainMap = dataProDomain.asInstanceOf [RDD [OWLDataPropertyDomainAxiom ]]
237264 .map(a => (a.getProperty, a.getDomain)).collect().toMap
238- val dataDomainMapBC : Broadcast [Map [OWLDataPropertyExpression , OWLClassExpression ]] = sc.broadcast(dataDomainMap)
265+
266+ val dataDomainMapBC = sc.broadcast(dataDomainMap)
239267
240268 val RDFS2a = dataPropAsserAxiom.asInstanceOf [RDD [OWLDataPropertyAssertionAxiom ]]
241269 .filter(a => dataDomainMapBC.value.contains(a.getProperty))
242270 .map(a => dataFactory.getOWLClassAssertionAxiom(dataDomainMapBC.value(a.getProperty), a.getSubject))
243271 .setName(" rdfs2a" )
244272
245- val objDomainMap : Map [ OWLObjectPropertyExpression , OWLClassExpression ] = objectProDomain.asInstanceOf [RDD [OWLObjectPropertyDomainAxiom ]]
273+ val objDomainMap = objectProDomain.asInstanceOf [RDD [OWLObjectPropertyDomainAxiom ]]
246274 .map(a => (a.getProperty, a.getDomain)).collect().toMap
247275
248- val objDomainMapBC : Broadcast [ Map [ OWLObjectPropertyExpression , OWLClassExpression ]] = sc.broadcast(objDomainMap)
276+ val objDomainMapBC = sc.broadcast(objDomainMap)
249277
250278 val RDFS2b = objPropAsserAxiom.asInstanceOf [RDD [OWLObjectPropertyAssertionAxiom ]]
251279 .filter(a => objDomainMapBC.value.contains(a.getProperty))
252280 .map(a => dataFactory.getOWLClassAssertionAxiom(objDomainMapBC.value(a.getProperty), a.getSubject))
253281 .setName(" rdfs2b" )
254282
283+ val AnnDomainMap = AnnProDomain .asInstanceOf [RDD [OWLAnnotationPropertyDomainAxiom ]]
284+ .map(a => (a.getProperty, a.getDomain)).collect().toMap
285+
286+ val AnnDomainMapBC = sc.broadcast(AnnDomainMap )
287+
288+ val RDFS2c = AnnAsserAxiom .asInstanceOf [RDD [OWLAnnotationAssertionAxiom ]]
289+ .filter(a => AnnDomainMapBC .value.contains(a.getProperty))
290+ .map(a => dataFactory
291+ .getOWLClassAssertionAxiom(dataFactory.getOWLClass(AnnDomainMapBC .value(a.getProperty)),
292+ dataFactory.getOWLNamedIndividual(a.getSubject.toString)))
293+ .setName(" rdfs2c" )
294+
295+ // println("\n Annotation domain: \n----------------\n")
296+ // RDFS2c.collect().foreach(println)
297+
298+
255299 /* rule 5: --> rule 5a, rule 5b
256300
257301 rdfs3: a rdfs:range x . y a z --> z rdf:type x .
258302 */
259303
260- val dataRangeMap : Map [ OWLDataPropertyExpression , OWLDataRange ] = dataProRange.asInstanceOf [RDD [OWLDataPropertyRangeAxiom ]]
304+ val dataRangeMap = dataProRange.asInstanceOf [RDD [OWLDataPropertyRangeAxiom ]]
261305 .map(a => (a.getProperty, a.getRange)).collect().toMap
262- val dataRangeMapBC : Broadcast [ Map [ OWLDataPropertyExpression , OWLDataRange ]] = sc.broadcast(dataRangeMap)
306+ val dataRangeMapBC = sc.broadcast(dataRangeMap)
263307
264308 val RDFS3a = dataPropAsserAxiom.asInstanceOf [RDD [OWLDataPropertyAssertionAxiom ]]
265309 .filter(a => dataRangeMapBC.value.contains(a.getProperty) && ! a.getObject.isLiteral) // Add checking for non-literals
266310 .map(a => dataFactory.getOWLClassAssertionAxiom
267- (dataRangeMapBC.value(a.getProperty).asInstanceOf [OWLClassExpression ], a.getObject.asInstanceOf [OWLIndividual ]))
311+ (dataRangeMapBC.value(a.getProperty).asInstanceOf [OWLClassExpression ],
312+ a.getObject.asInstanceOf [OWLIndividual ]))
268313 .setName(" rdfs3a" )
269314
270- val objRangeMap : Map [ OWLObjectPropertyExpression , OWLClassExpression ] = objProRange.asInstanceOf [RDD [OWLObjectPropertyRangeAxiom ]]
315+ val objRangeMap = objProRange.asInstanceOf [RDD [OWLObjectPropertyRangeAxiom ]]
271316 .map(a => (a.getProperty, a.getRange)).collect().toMap
272317
273- val objRangeMapBC : Broadcast [ Map [ OWLObjectPropertyExpression , OWLClassExpression ]] = sc.broadcast(objRangeMap)
318+ val objRangeMapBC = sc.broadcast(objRangeMap)
274319
275320 val RDFS3b = objPropAsserAxiom.asInstanceOf [RDD [OWLObjectPropertyAssertionAxiom ]]
276321 .filter(a => objRangeMapBC.value.contains(a.getProperty)) // Add checking for non-literals
277322 .map(a => dataFactory.getOWLClassAssertionAxiom(objRangeMapBC.value(a.getProperty), a.getObject))
278323 .setName(" rdfs3b" )
279324
280325 // rdfs2 and rdf3 generate classAssertionAxiom which we will add to typeAxioms
281- val axiome23ab = RDFS2a .union(RDFS2b ).union(RDFS3a )
282- .union(RDFS3b ).distinct(parallelism)
283- .asInstanceOf [RDD [OWLAxiom ]]
284- .setName(" rdfs2a + rdfs2b + rdfs3a + rdfs3b" )
285-
286- typeAxioms = typeAxioms.union(axiome23ab).distinct.setName(" classAssertion + rdfs2ab + rdfs3ab" )
326+ val axiome23abc = sc.union(RDFS2a , RDFS2b , RDFS2c , RDFS3a , RDFS3b )
327+ .distinct(parallelism).asInstanceOf [RDD [OWLAxiom ]]
328+ .setName(" rdfs2a + rdfs2b + rdfs2c+ rdfs3a + rdfs3b" )
287329
330+ typeAxioms = typeAxioms.union(axiome23abc).distinct.setName(" classAssertion + rdfs2abc + rdfs3ab" )
288331
289332 // 4. SubClass inheritance according to rdfs9
290333 /* rule 6
@@ -294,7 +337,8 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
294337
295338 val RDFs9 = typeAxioms.asInstanceOf [RDD [OWLClassAssertionAxiom ]]
296339 .filter(a => subClassOfBC.value.contains(a.getClassExpression))
297- .flatMap(a => subClassOfBC.value(a.getClassExpression).map(s => dataFactory.getOWLClassAssertionAxiom(s, a.getIndividual)))
340+ .flatMap(a => subClassOfBC.value(a.getClassExpression)
341+ .map(s => dataFactory.getOWLClassAssertionAxiom(s, a.getIndividual)))
298342 .setName(" rdfs9" )
299343
300344 typeAxioms = typeAxioms.union(RDFs9 .asInstanceOf [RDD [OWLAxiom ]])
@@ -317,32 +361,33 @@ class ForwardRuleReasonerRDFS(sc: SparkContext, parallelism: Int = 2) extends Lo
317361 }
318362}
319363
320- // object ForwardRuleReasonerRDFS{
321- //
322- // def main(args: Array[String]): Unit = {
323- //
324- // val input = getClass.getResource("/ont_functional.owl").getPath
325- //
326- // println("=====================================")
327- // println("| OWLAxioms Forward Rule Reasoner |")
328- // println("=====================================")
329- //
330- // val sparkSession = SparkSession.builder
331- // .master("local[*]")
332- // .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
333- // // .config("spark.kryo.registrator", "net.sansa_stack.inference.spark.forwardchaining.axioms.Registrator")
334- // .appName("OWL Axioms Forward Rule Reasoner")
335- // .getOrCreate()
336- //
337- // val sc: SparkContext = sparkSession.sparkContext
338- //
339- // // Call the functional syntax OWLAxiom builder
340- //
341- // var owlAxiomsRDD: OWLAxiomsRDD = FunctionalSyntaxOWLAxiomsRDDBuilder.build(sparkSession, input)
342- // owlAxiomsRDD.collect().foreach(println)
343- //
344- // val ruleReasoner = new ForwardRuleReasonerRDFS(sc, 2).apply(owlAxiomsRDD, input)
345- //
346- // sparkSession.stop
347- // }
348- // }
364+ object ForwardRuleReasonerRDFS {
365+
366+ def main (args : Array [String ]): Unit = {
367+
368+ val input = getClass.getResource(" /ont_functional.owl" ).getPath
369+
370+ println(" =====================================" )
371+ println(" | OWLAxioms Forward Rule Reasoner |" )
372+ println(" =====================================" )
373+
374+ val sparkSession = SparkSession .builder
375+ .master(" local[*]" )
376+ .config(" spark.serializer" , " org.apache.spark.serializer.KryoSerializer" )
377+ // .config("spark.kryo.registrator", "net.sansa_stack.inference.spark.forwardchaining.axioms.Registrator")
378+ .appName(" OWL Axioms Forward Rule Reasoner" )
379+ .getOrCreate()
380+
381+ val sc : SparkContext = sparkSession.sparkContext
382+
383+ // Call the functional syntax OWLAxiom builder
384+
385+ var owlAxiomsRDD = FunctionalSyntaxOWLAxiomsRDDBuilder .build(sparkSession, input)
386+ // owlAxiomsRDD.collect().foreach(println)
387+
388+ val ruleReasoner = new ForwardRuleReasonerRDFS (sc, 2 )
389+ val res : RDD [OWLAxiom ] = ruleReasoner(owlAxiomsRDD)
390+
391+ sparkSession.stop
392+ }
393+ }
0 commit comments