Example #1
0
    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 ) ) )"
        )
Example #2
0
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
Example #3
0
 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 )")
Example #4
0
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.")
Example #5
0
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
Example #6
0
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.")
Example #7
0
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