@@ -17,7 +17,7 @@ import zio._
1717import zio .blocking ._
1818import zio .stream ._
1919
20- import java .io .{File , FileOutputStream , OutputStream }
20+ import java .io .{File , FileOutputStream }
2121import java .lang .{Runtime => JRuntime }
2222import java .nio .charset .StandardCharsets
2323import java .security .MessageDigest
@@ -46,12 +46,13 @@ object Main extends ZCaseApp[Config] {
4646 whelkOntology = Bridge .ontologyToAxioms(ontology)
4747 _ <- ZIO .succeed(scribe.info(" Running reasoner" ))
4848 whelk = Reasoner .assert(whelkOntology)
49+ indexedWhelk = IndexedReasonerState (whelk)
4950 _ <- ZIO .succeed(scribe.info(" Done running reasoner" ))
5051 _ <- ZIO .fail(new Exception (" Ontology is incoherent; please correct unsatisfiable classes." )).when(isIncoherent(whelk))
5152 _ <- effectBlockingIO(rdfWriter.triple(Triple .create(NodeFactory .createBlankNode(" redundant" ), RDFType , OWLOntology )))
5253 .when(config.mode == OWLMode )
5354 start <- ZIO .succeed(System .currentTimeMillis())
54- triplesStream = computeRelations(ontology, whelk , specifiedProperties, config.outputSubclasses.bool, config.reflexiveSubclasses.bool, config.equivalenceAsSubclass.bool, config.mode)
55+ triplesStream = computeRelations(ontology, indexedWhelk , specifiedProperties, config.outputSubclasses.bool, config.reflexiveSubclasses.bool, config.equivalenceAsSubclass.bool, config.mode)
5556 _ <- triplesStream.foreach {
5657 case TriplesGroup (triples) => ZIO .effect(triples.foreach(rdfWriter.triple))
5758 }
@@ -62,11 +63,11 @@ object Main extends ZCaseApp[Config] {
6263 program.exitCode
6364 }
6465
65- def computeRelations (ontology : OWLOntology , whelk : ReasonerState , specifiedProperties : Set [AtomicConcept ], outputSubclasses : Boolean , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean , mode : Config .OutputMode ): UStream [TriplesGroup ] = {
66- val classes = classHierarchy(whelk)
66+ def computeRelations (ontology : OWLOntology , whelk : IndexedReasonerState , specifiedProperties : Set [AtomicConcept ], outputSubclasses : Boolean , reflexiveSubclasses : Boolean , equivalenceAsSubclass : Boolean , mode : Config .OutputMode ): UStream [TriplesGroup ] = {
67+ val classes = classHierarchy(whelk.state )
6768 val properties = propertyHierarchy(ontology)
6869 val classesTasks = if (outputSubclasses) {
69- allClasses(ontology).map(c => ZIO .succeed(processSuperclasses(c, whelk, reflexiveSubclasses, equivalenceAsSubclass)))
70+ allClasses(ontology).map(c => ZIO .succeed(processSuperclasses(c, whelk.state , reflexiveSubclasses, equivalenceAsSubclass)))
7071 } else Stream .empty
7172 val streamZ = for {
7273 queue <- Queue .unbounded[Restriction ]
@@ -124,7 +125,7 @@ object Main extends ZCaseApp[Config] {
124125 } yield ()
125126 }
126127
127- def processRestrictionAndExtendQueue (restriction : Restriction , properties : Hierarchy , classes : Hierarchy , whelk : ReasonerState , mode : Config .OutputMode , descendProperties : Boolean , queue : Queue [Restriction ], activeRestrictions : Ref [Int ], seenRef : Ref [Map [AtomicConcept , Set [AtomicConcept ]]]): UIO [TriplesGroup ] = {
128+ 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 ] = {
128129 val triples = processRestriction(restriction, whelk, mode)
129130 for {
130131 directFillerSubclassesRestrictions <- if (triples.redundant.nonEmpty) seenRef.modify { seen =>
@@ -153,7 +154,7 @@ object Main extends ZCaseApp[Config] {
153154 } yield triples
154155 }
155156
156- def processRestriction (restriction : Restriction , whelk : ReasonerState , mode : Config .OutputMode ): TriplesGroup = {
157+ def processRestriction (restriction : Restriction , whelk : IndexedReasonerState , mode : Config .OutputMode ): TriplesGroup = {
157158 val subclasses = queryExistentialSubclasses(restriction, whelk)
158159 if (subclasses.nonEmpty) {
159160 val predicate = NodeFactory .createURI(restriction.property.id)
@@ -166,12 +167,17 @@ object Main extends ZCaseApp[Config] {
166167 } else TriplesGroup .empty
167168 }
168169
169- def queryExistentialSubclasses ( restriction : Restriction , whelk : ReasonerState ) : Set [ AtomicConcept ] = {
170- val queryConcept = AtomicConcept ( s " ${restriction.property.id}${restriction.filler.id} " )
170+ // This is a faster way to compute these than the standard Whelk algorithm
171+ def queryExistentialSubclasses ( restriction : Restriction , whelk : IndexedReasonerState ) : Set [ AtomicConcept ] = {
171172 val er = ExistentialRestriction (restriction.property, restriction.filler)
172- val axioms = Set (ConceptInclusion (queryConcept, er), ConceptInclusion (er, queryConcept))
173- val updatedWhelk = Reasoner .assert(axioms, whelk)
174- updatedWhelk.closureSubsBySuperclass(queryConcept).collect { case x : AtomicConcept => x } - queryConcept - Bottom
173+ val rs = whelk.reverseRoleHierarchy.getOrElse(er.role, Set .empty)
174+ val cs = whelk.state.closureSubsBySuperclass.getOrElse(er.concept, Set .empty)
175+ val validTargets = cs.intersect(whelk.allTargets)
176+ (for {
177+ target <- validTargets
178+ (r, es) <- whelk.linksByTargetList.getOrElse(target, Map .empty)
179+ if rs(r)
180+ } yield es.iterator).flatten.to(Set ).collect { case x : AtomicConcept => x } - Bottom
175181 }
176182
177183 def classHierarchy (reasoner : ReasonerState ): Hierarchy = {
@@ -253,4 +259,22 @@ object Main extends ZCaseApp[Config] {
253259
254260 }
255261
262+ final case class IndexedReasonerState (state : ReasonerState ) {
263+
264+ val negativeExistentials : Set [ExistentialRestriction ] = state.negExistsMapByConcept.flatMap(_._2).to(Set )
265+
266+ val reverseRoleHierarchy : Map [Role , Set [Role ]] = (for {
267+ (r, ss) <- state.hier.toList
268+ s <- ss
269+ } yield {
270+ s -> r
271+ }).groupMapReduce(_._1)(e => Set (e._2))(_ ++ _)
272+
273+ val allTargets : Set [Concept ] = state.linksByTarget.keySet
274+
275+ val linksByTargetList : Map [Concept , List [(Role , List [Concept ])]] =
276+ state.linksByTarget.view.mapValues(_.to(List )).toMap
277+
278+ }
279+
256280}
0 commit comments