@@ -62,7 +62,7 @@ object Main extends ZCaseApp[Config] {
6262 _ <- effectBlockingIO(rdfWriter.triple(Triple .create(NodeFactory .createBlankNode(" redundant" ), RDFType , OWLOntology )))
6363 .when(config.mode == OWLMode )
6464 start <- ZIO .succeed(System .currentTimeMillis())
65- triplesStream = computeRelations(ontology, indexedWhelk, specifiedProperties, config.outputSubclasses.bool, config.reflexiveSubclasses.bool, config.equivalenceAsSubclass.bool, config.mode)
65+ triplesStream = computeRelations(ontology, indexedWhelk, specifiedProperties, config.outputSubclasses.bool, config.reflexiveSubclasses.bool, config.equivalenceAsSubclass.bool, config.outputClasses.bool, config.outputIndividuals.bool, config. mode)
6666 _ <- triplesStream.foreach {
6767 case TriplesGroup (triples) => ZIO .effect(triples.foreach(rdfWriter.triple))
6868 }
@@ -78,18 +78,18 @@ object Main extends ZCaseApp[Config] {
7878 }
7979 }
8080
81- def computeRelations (ontology : OWLOntology , whelk : IndexedReasonerState , specifiedProperties : Set [AtomicConcept ], outputSubclasses : Boolean , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean , mode : Config .OutputMode ): UStream [TriplesGroup ] = {
81+ def computeRelations (ontology : OWLOntology , whelk : IndexedReasonerState , specifiedProperties : Set [AtomicConcept ], outputSubclasses : Boolean , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean , outputClasses : Boolean , outputIndividuals : Boolean , mode : Config .OutputMode ): UStream [TriplesGroup ] = {
8282 val classes = classHierarchy(whelk.state)
8383 val properties = propertyHierarchy(ontology)
8484 val classesTasks = if (outputSubclasses) {
85- allClasses(ontology).map(c => ZIO .succeed(processSuperclasses (c, whelk.state, reflexiveSubclasses, equivalenceAsSubclass)))
85+ allClasses(ontology).map(c => ZIO .succeed(processSubclasses (c, whelk.state, reflexiveSubclasses, equivalenceAsSubclass, outputClasses, outputIndividuals )))
8686 } else Stream .empty
8787 val streamZ = for {
8888 queue <- Queue .unbounded[Restriction ]
8989 activeRestrictions <- Ref .make(0 )
9090 seenRef <- Ref .make(Map .empty[AtomicConcept , Set [AtomicConcept ]])
9191 _ <- traverse(specifiedProperties, properties, classes, queue, activeRestrictions, seenRef)
92- restrictionsStream = Stream .fromQueue(queue).map(r => processRestrictionAndExtendQueue(r, properties, classes, whelk, mode, specifiedProperties.isEmpty, queue, activeRestrictions, seenRef))
92+ restrictionsStream = Stream .fromQueue(queue).map(r => processRestrictionAndExtendQueue(r, properties, classes, whelk, mode, specifiedProperties.isEmpty, outputClasses, outputIndividuals, queue, activeRestrictions, seenRef))
9393 allTasks = classesTasks ++ restrictionsStream
9494 } yield allTasks.mapMParUnordered(JRuntime .getRuntime.availableProcessors)(identity)
9595 Stream .unwrap(streamZ)
@@ -141,8 +141,8 @@ object Main extends ZCaseApp[Config] {
141141 } yield ()
142142 }
143143
144- def processRestrictionAndExtendQueue (restriction : Restriction , properties : Hierarchy , classes : Hierarchy , whelk : IndexedReasonerState , mode : Config .OutputMode , descendProperties : Boolean , queue : Queue [Restriction ], activeRestrictions : Ref [Int ], seenRef : Ref [Map [AtomicConcept , Set [AtomicConcept ]]]): UIO [TriplesGroup ] = {
145- val triples = processRestriction(restriction, whelk, mode)
144+ def processRestrictionAndExtendQueue (restriction : Restriction , properties : Hierarchy , classes : Hierarchy , whelk : IndexedReasonerState , mode : Config .OutputMode , descendProperties : Boolean , outputClasses : Boolean , outputIndividuals : Boolean , queue : Queue [Restriction ], activeRestrictions : Ref [Int ], seenRef : Ref [Map [AtomicConcept , Set [AtomicConcept ]]]): UIO [TriplesGroup ] = {
145+ val triples = processRestriction(restriction, whelk, mode, outputClasses, outputIndividuals )
146146 for {
147147 directFillerSubclassesRestrictions <- if (triples.redundant.nonEmpty) seenRef.modify { seen =>
148148 val propertyConcept = AtomicConcept (restriction.property.id)
@@ -170,21 +170,30 @@ object Main extends ZCaseApp[Config] {
170170 } yield triples
171171 }
172172
173- def processRestriction (restriction : Restriction , whelk : IndexedReasonerState , mode : Config .OutputMode ): TriplesGroup = {
174- val subclasses = queryExistentialSubclasses(restriction, whelk)
175- if (subclasses.nonEmpty) {
176- val predicate = NodeFactory .createURI(restriction.property.id)
177- val target = NodeFactory .createURI(restriction.filler.id)
178- val outputTriples = mode match {
179- case RDFMode => subclasses.map(sc => Triple .create(NodeFactory .createURI(sc.id), predicate, target))
180- case OWLMode => subclasses.flatMap(sc => owlTriples(NodeFactory .createURI(sc.id), predicate, target))
173+ def processRestriction (restriction : Restriction , whelk : IndexedReasonerState , mode : Config .OutputMode , outputClasses : Boolean , outputIndividuals : Boolean ): TriplesGroup = {
174+ val subConcepts = queryExistentialSubclasses(restriction, whelk)
175+ val subclasses = if (outputClasses) (subConcepts - Bottom ).collect { case AtomicConcept (id) => id } else Set .empty[String ]
176+ val instances = if (outputIndividuals) subConcepts.collect { case Nominal (Individual (id)) => id } else Set .empty[String ]
177+ val predicate = NodeFactory .createURI(restriction.property.id)
178+ val target = NodeFactory .createURI(restriction.filler.id)
179+ val subclassTriples = subclasses.flatMap { id =>
180+ mode match {
181+ case RDFMode => Set (Triple .create(NodeFactory .createURI(id), predicate, target))
182+ case OWLMode => owlTriples(NodeFactory .createURI(id), predicate, target, RDFSSubClassOf )
181183 }
182- TriplesGroup (outputTriples)
183- } else TriplesGroup .empty
184+ }
185+ val instanceTriples = instances.flatMap { id =>
186+ mode match {
187+ case RDFMode => Set (Triple .create(NodeFactory .createURI(id), predicate, target))
188+ case OWLMode => owlTriples(NodeFactory .createURI(id), predicate, target, RDFType )
189+ }
190+ }
191+ val outputTriples = subclassTriples ++ instanceTriples
192+ TriplesGroup (outputTriples)
184193 }
185194
186195 // This is a faster way to compute these than the standard Whelk algorithm
187- def queryExistentialSubclasses (restriction : Restriction , whelk : IndexedReasonerState ): Set [AtomicConcept ] = {
196+ def queryExistentialSubclasses (restriction : Restriction , whelk : IndexedReasonerState ): Set [Concept ] = {
188197 val er = ExistentialRestriction (restriction.property, restriction.filler)
189198 val rs = whelk.reverseRoleHierarchy.getOrElse(er.role, Set .empty)
190199 val cs = whelk.state.closureSubsBySuperclass.getOrElse(er.concept, Set .empty)
@@ -193,7 +202,7 @@ object Main extends ZCaseApp[Config] {
193202 target <- validTargets
194203 (r, es) <- whelk.linksByTargetList.getOrElse(target, Map .empty)
195204 if rs(r)
196- } yield es.iterator).flatten.to(Set ).collect { case x : AtomicConcept => x } - Bottom
205+ } yield es.iterator).flatten.to(Set )
197206 }
198207
199208 def classHierarchy (reasoner : ReasonerState ): Hierarchy = {
@@ -223,37 +232,45 @@ object Main extends ZCaseApp[Config] {
223232 classHierarchy(whelk)
224233 }
225234
226- def processSuperclasses (cls : OWLClass , whelk : ReasonerState , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean ): TriplesGroup = {
227- val subject = NodeFactory .createURI(cls.getIRI.toString)
235+ def processSubclasses (cls : OWLClass , whelk : ReasonerState , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean , outputClasses : Boolean , outputIndividuals : Boolean ): TriplesGroup = {
236+ val obj = NodeFactory .createURI(cls.getIRI.toString)
228237 val concept = AtomicConcept (cls.getIRI.toString)
229- val allSuperclasses = (whelk.closureSubsBySubclass.getOrElse(concept, Set .empty) - BuiltIn .Top )
230- .collect { case ac @ AtomicConcept (_) => ac }
231- if (allSuperclasses(BuiltIn .Bottom )) TriplesGroup .empty // unsatisfiable
232- else {
238+ val subConcepts = (whelk.closureSubsBySuperclass.getOrElse(concept, Set .empty) - BuiltIn .Bottom )
239+ val individualsTriples = if (outputIndividuals) {
240+ subConcepts.collect { case Nominal (Individual (id)) =>
241+ Triple .create(NodeFactory .createURI(id), RDFType , obj)
242+ }
243+ } else Set .empty[Triple ]
244+ val classesTriples = if (outputClasses) {
245+ val allSubclasses = subConcepts.collect { case ac @ AtomicConcept (_) => ac }
233246 val (equivs, _) = whelk.directlySubsumedBy(concept)
234- val adjustedEquivs = if (reflexiveSubclasses) equivs + concept else equivs - concept
235- val equivalentClassTriples = if (equivalenceAsSubclass)
236- adjustedEquivs.map(c => Triple .create(subject, RDFSSubClassOf , NodeFactory .createURI(c.id)))
237- else
238- adjustedEquivs.map(c => Triple .create(subject, OWLEquivalentClass , NodeFactory .createURI(c.id)))
239- val adjustedSuperclasses = if (reflexiveSubclasses) allSuperclasses + concept else allSuperclasses - concept
240- val outputTriples = if (equivalenceAsSubclass)
241- adjustedSuperclasses.map(c => Triple .create(subject, RDFSSubClassOf , NodeFactory .createURI(c.id)))
247+ val unsatisfiable = equivs(BuiltIn .Bottom )
248+ if (unsatisfiable) Set .empty[Triple ]
242249 else {
243- val superclassesMinusEquiv = adjustedSuperclasses -- adjustedEquivs
244- superclassesMinusEquiv.map(c => Triple .create(subject, RDFSSubClassOf , NodeFactory .createURI(c.id))) ++
245- equivalentClassTriples
250+ val adjustedEquivs = if (reflexiveSubclasses) equivs + concept else equivs - concept
251+ val equivalentClassTriples = if (equivalenceAsSubclass)
252+ adjustedEquivs.map(c => Triple .create(NodeFactory .createURI(c.id), RDFSSubClassOf , obj))
253+ else
254+ adjustedEquivs.map(c => Triple .create(NodeFactory .createURI(c.id), OWLEquivalentClass , obj))
255+ val adjustedSubclasses = if (reflexiveSubclasses) allSubclasses + concept else allSubclasses - concept
256+ if (equivalenceAsSubclass)
257+ adjustedSubclasses.map(c => Triple .create(NodeFactory .createURI(c.id), RDFSSubClassOf , obj))
258+ else {
259+ val subclassesMinusEquiv = adjustedSubclasses -- adjustedEquivs
260+ subclassesMinusEquiv.map(c => Triple .create(NodeFactory .createURI(c.id), RDFSSubClassOf , obj)) ++ equivalentClassTriples
261+ }
246262 }
247- TriplesGroup (outputTriples)
248- }
263+ } else Set .empty[Triple ]
264+ val outputTriples = classesTriples ++ individualsTriples
265+ TriplesGroup (outputTriples)
249266 }
250267
251- def owlTriples (subj : Node , pred : Node , obj : Node ): Set [Triple ] = {
268+ def owlTriples (subj : Node , pred : Node , obj : Node , relation : Node ): Set [Triple ] = {
252269 val hash = MessageDigest .getInstance(" SHA-256" ).digest(s " $subj$pred$obj" .getBytes(StandardCharsets .UTF_8 ))
253270 val id = Base64 .getEncoder.encodeToString(hash)
254271 val restrictionNode = NodeFactory .createBlankNode(id)
255272 Set (
256- Triple .create(subj, RDFSSubClassOf , restrictionNode),
273+ Triple .create(subj, relation , restrictionNode),
257274 Triple .create(restrictionNode, RDFType , OWLRestriction ),
258275 Triple .create(restrictionNode, OWLOnProperty , pred),
259276 Triple .create(restrictionNode, OWLSomeValuesFrom , obj)
0 commit comments