def testUnivInversion(self): UniversalNominalRangeTransformer().transform(self.ontGraph) self.failUnlessEqual(len(list(self.foo.subClassOf)), 1, "There should still be one subsumed restriction") subC = CastClass(first(self.foo.subClassOf)) self.failUnless(not isinstance(subC, Restriction), "subclass of a restriction") self.failUnless(subC.complementOf is not None, "Should be a complement.") innerC = CastClass(subC.complementOf) self.failUnless(isinstance(innerC, Restriction), "complement of a restriction, not %r" % innerC) self.failUnlessEqual(innerC.onProperty, EX_NS.propFoo, "restriction on propFoo") self.failUnless( innerC.someValuesFrom, "converted to an existential restriction not %r" % innerC) invertedC = CastClass(innerC.someValuesFrom) self.failUnless(isinstance(invertedC, EnumeratedClass), "existential restriction on enumerated class") self.assertEqual( len(invertedC), 2, "existencial restriction on enumerated class of length 2") self.assertEqual(repr(invertedC), "{ ex:individual2 ex:individual3 }", "The negated partition should exclude individual1") NominalRangeTransformer().transform(self.ontGraph) DemorganTransformer().transform(self.ontGraph) subC = CastClass(first(self.foo.subClassOf)) self.assertEqual( repr(subC), "( ( not ( ex:propFoo value ex:individual2 ) ) and ( not ( ex:propFoo value ex:individual3 ) ) )" )
def SubSumptionExpansion(owlClass): owlClass = CastClass(owlClass) if isinstance(owlClass, BooleanClass) and owlClass._operator == OWL_NS.unionOf: for member in owlClass: expanded = False for innerMember in SubSumptionExpansion(Class(member)): expanded = True yield innerMember if not expanded: yield member else: for member in owlClass.subSumpteeIds(): expanded = False for innerMember in SubSumptionExpansion(Class(member)): expanded = True yield innerMember if not expanded: yield member
def testHiddenDemorgan(self): NormalFormReduction(self.ontGraph) self.failUnless(first(self.foo.subClassOf).complementOf, "should be the negation of a boolean class") innerC = CastClass(first(self.foo.subClassOf).complementOf) self.failUnless(isinstance(innerC, BooleanClass) and innerC._operator == OWL_NS.intersectionOf, "should be the negation of a conjunct") self.assertEqual(repr(innerC), "( ex:alpha and ex:omega )")
def ComplementExpansion(owlClass, debug=False): """ For binary conjunctions of a positive conjunction concept and a negative atomic concept """ owlClass = CastClass(owlClass.identifier, owlClass.graph) if isinstance(owlClass, BooleanClass) and \ len(owlClass) == 2 and owlClass._operator == OWL_NS.intersectionOf: oldRepr = owlClass.__repr__() # A boolean-constructed class negativeClasses = set() otherClasses = set() for member in owlClass: member = Class(member) if member.complementOf: # A negative class, expand it and add to bucket of classes to # 'remove' for expandedClass in SubSumptionExpansion(member.complementOf): negativeClasses.add(expandedClass) else: # A positive class, expand it and add to bucket of base classes expanded = False for expandedClass in SubSumptionExpansion(member): expanded = True otherClasses.add(expandedClass) if not expanded: otherClasses.add(member.identifier) if negativeClasses: # Delete the old list of operands for the boolean class oldList = owlClass._rdfList oldList.clear() # Recreate the list of operands, exluding the expanded negative # classes for allowedClasses in otherClasses.difference(negativeClasses): oldList.append(classOrIdentifier(allowedClasses)) owlClass.changeOperator(OWL_NS.unionOf) if debug: print("Incoming boolean class: ", oldRepr) print("Expanded boolean class: ", owlClass.__repr__()) return owlClass else: if debug: print("There were no negative classes.")
def ProcessConcept(klass, owlGraph, FreshConcept, newOwlGraph): """ This method implements the pre-processing portion of the completion-based procedure and recursively transforms the input ontology one concept at a time """ iD = klass.identifier # maps the identifier to skolem:bnodeLabel if # the identifier is a BNode or to skolem:newBNodeLabel # if its a URI FreshConcept[iD] = SkolemizeExistentialClasses( BNode() if isinstance(iD, URIRef) else iD ) # A fresh atomic concept (A_c) newCls = Class(FreshConcept[iD], graph=newOwlGraph) cls = CastClass(klass, owlGraph) # determine if the concept is the left, right (or both) # operand of a subsumption axiom in the ontology location = WhichSubsumptionOperand(iD, owlGraph) # log.debug(repr(cls)) if isinstance(iD, URIRef): # An atomic concept? if location in [LEFT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: log.debug( "Original (atomic) concept appears in the left HS of a subsumption axiom") # If class is left operand of subsumption operator, # assert (in new OWL graph) that A_c subsumes the concept _cls = Class(cls.identifier, graph=newOwlGraph) newCls += _cls log.debug("%s subsumes %s" % (newCls, _cls)) if location in [RIGHT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: log.debug( "Original (atomic) concept appears in the right HS of a subsumption axiom") # If class is right operand of subsumption operator, # assert that it subsumes A_c _cls = Class(cls.identifier, graph=newOwlGraph) _cls += newCls log.debug("%s subsumes %s" % (_cls, newCls)) elif isinstance(cls, Restriction): if location != NEITHER_SUBSUMPTION_OPERAND: # appears in at least one subsumption operator # An existential role restriction log.debug( "Original (role restriction) appears in a subsumption axiom") role = Property(cls.onProperty, graph=newOwlGraph) fillerCls = ProcessConcept( Class(cls.restrictionRange), owlGraph, FreshConcept, newOwlGraph) # leftCls is (role SOME fillerCls) leftCls = role | some | fillerCls log.debug("let leftCls be %s" % leftCls) if location in [LEFT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: # if appears as the left operand, we say A_c subsumes # leftCls newCls += leftCls log.debug("%s subsumes leftCls" % newCls) if location in [RIGHT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: # if appears as right operand, we say left Cls subsumes A_c leftCls += newCls log.debug("leftCls subsumes %s" % newCls) else: assert isinstance(cls, BooleanClass), "Not ELH ontology: %r" % cls assert cls._operator == OWL_NS.intersectionOf, "Not ELH ontology" log.debug( "Original conjunction (or boolean operator wlog ) appears in a subsumption axiom") # A boolean conjunction if location != NEITHER_SUBSUMPTION_OPERAND: members = [ProcessConcept(Class(c), owlGraph, FreshConcept, newOwlGraph) for c in cls] newBoolean = BooleanClass( BNode(), members=members, graph=newOwlGraph) # create a boolean conjunction of the fresh concepts corresponding # to processing each member of the existing conjunction if location in [LEFT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: # if appears as the left operand, we say the new conjunction # is subsumed by A_c newCls += newBoolean log.debug("%s subsumes %s" % (newCls, newBoolean)) if location in [RIGHT_SUBSUMPTION_OPERAND, BOTH_SUBSUMPTION_OPERAND]: # if appears as the right operand, we say A_c is subsumed by # the new conjunction newBoolean += newCls log.debug("%s subsumes %s" % (newBoolean, newCls)) return newCls