Exemple #1
0
    def transform(self, graph):
        """
        Flattens conjunctions
        ( A1 and ( B1 and B2 ) and A2 )
                         =
        ( A1 and B1 and B2 and A2 )

        """
        Individual.factoryGraph = graph
        for conjunctId in graph.subjects(predicate=OWL_NS.intersectionOf):
            conjunct = BooleanClass(conjunctId)
            nestedConjuncts = [
                BooleanClass(i) for i in conjunct
                        if (i, OWL_NS.intersectionOf, None) in graph]
            if nestedConjuncts:
                def collapseConjunctTerms(left, right):
                    list(left) + list(right)
                if len(nestedConjuncts) == 1:
                    newTopLevelItems = list(nestedConjuncts[0])
                else:
                    newTopLevelItems = reduce(
                        collapseConjunctTerms, nestedConjuncts)
                for nc in nestedConjuncts:
                    nc.clear()
                    del conjunct[conjunct.index(nc.identifier)]
                    nc.delete()
                for newItem in newTopLevelItems:
                    conjunct.append(newItem)
Exemple #2
0
    def transform(self, graph):
        """
        Transforms a universal restriction on a 'pure' nominal range into a
        conjunction of value restriction (using set theory and demorgan's laws)
        """
        Individual.factoryGraph = graph
        for restriction, intermediateCl, \
            nominal, prop, partition in graph.query(
                                 self.NOMINAL_QUERY,
                                 initNs={'owl': OWL_NS,
                                         'rdfs': RDFS}):
            exceptions = EnumeratedClass()
            partition = Collection(graph, partition)
            nominalCollection = Collection(graph, nominal)
            for i in partition:
                if i not in nominalCollection:
                    exceptions._rdfList.append(i)
                    # exceptions += i
            exists = Class(complementOf=(Property(prop) | some | exceptions))
            for s, p, o in graph.triples((None, None, restriction)):
                graph.add((s, p, exists.identifier))
            Individual(restriction).delete()

            #purge nominalization placeholder
            iClass = BooleanClass(intermediateCl)
            iClass.clear()
            iClass.delete()
Exemple #3
0
 def setUp(self):
     self.tBoxGraph = Graph()
     self.tBoxGraph.namespace_manager.bind('ex', EX)
     self.tBoxGraph.namespace_manager.bind('owl', OWL_NS)
     Individual.factoryGraph = self.tBoxGraph
     self.classB = Class(EX.b)
     self.classE = Class(EX.e)
     self.classF = Class(EX.f)
     self.classA = BooleanClass(EX.a,
                                operator=OWL_NS.unionOf,
                                members=[self.classE, self.classF])
     self.classC = BooleanClass(EX.c,
                                operator=OWL_NS.unionOf,
                                members=[self.classA, self.classB])
     self.ruleStore, self.ruleGraph = SetupRuleStore()
Exemple #4
0
def Th(owlGraph, _class, variable=Variable('X'), position=LHS):
    """
    DLP head (antecedent) knowledge assertional forms (ABox assertions, conjunction of
    ABox assertions, and universal role restriction assertions)
    """
    props = list(set(owlGraph.predicates(subject=_class)))
    if OWL_NS.allValuesFrom in props:
        #http://www.w3.org/TR/owl-semantics/#owl_allValuesFrom
        for s, p, o in owlGraph.triples((_class, OWL_NS.allValuesFrom, None)):
            prop = list(owlGraph.objects(subject=_class, predicate=OWL_NS.onProperty))[0]
            newVar = Variable(BNode())
            body = Uniterm(prop, [variable, newVar], newNss=owlGraph.namespaces())
            for head in Th(owlGraph, o, variable=newVar):
                yield Clause(body, head)
    elif OWL_NS.hasValue in props:
        prop = list(owlGraph.objects(subject=_class, predicate=OWL_NS.onProperty))[0]
        o = first(owlGraph.objects(subject=_class, predicate=OWL_NS.hasValue))
        yield Uniterm(prop, [variable, o], newNss=owlGraph.namespaces())
    elif OWL_NS.someValuesFrom in props:
        #http://www.w3.org/TR/owl-semantics/#someValuesFrom
        for s, p, o in owlGraph.triples((_class, OWL_NS.someValuesFrom, None)):
            prop = list(owlGraph.objects(subject=_class, predicate=OWL_NS.onProperty))[0]
            newVar = BNode()
            yield And([Uniterm(prop, [variable, newVar], newNss=owlGraph.namespaces()),
                        generatorFlattener(Th(owlGraph, o, variable=newVar))])
    elif OWL_NS.intersectionOf in props:
        from FuXi.Syntax.InfixOWL import BooleanClass
        yield And([first(Th(owlGraph, h, variable)) for h in BooleanClass(_class)])
    else:
        #Simple class
        yield Uniterm(RDF.type, [variable,
                                isinstance(_class, BNode) and SkolemizeExistentialClasses(_class) or _class],
                                newNss=owlGraph.namespaces())
Exemple #5
0
    def transform(self, graph):
        """
        Transforms a 'pure' nominal range into a disjunction of value
        restrictions
        """
        Individual.factoryGraph = graph
        for restriction, intermediateCl, nominal, prop in graph.query(
                                 self.NOMINAL_QUERY,
                                 initNs={'owl': OWL_NS}):
            nominalCollection = Collection(graph, nominal)
            # purge restriction
            restr = Class(restriction)
            parentSets = [i for i in restr.subClassOf]
            restr.clearOutDegree()
            newConjunct = BooleanClass(restriction,
                                     OWL_NS.unionOf,
                                     [Property(prop) | value | val
                                                 for val in nominalCollection],
                                     graph)
            newConjunct.subClassOf = parentSets

            # purge nominalization placeholder
            iClass = BooleanClass(intermediateCl)
            iClass.clear()
            iClass.delete()
Exemple #6
0
    def transform(self, graph):
        """
        Transforms a universal restriction on a 'pure' nominal range into a
        conjunction of value restriction (using set theory and demorgan's laws)
        """
        Individual.factoryGraph = graph
        for restriction, intermediateCl, nominal, prop, partition in graph.query(
                self.NOMINAL_QUERY, initNs={
                    u'owl': OWL_NS,
                    u'rdfs': str(RDFS)
                }):
            exceptions = EnumeratedClass()
            partition = Collection(graph, partition)
            nominalCollection = Collection(graph, nominal)
            for i in partition:
                if i not in nominalCollection:
                    exceptions._rdfList.append(i)
                    #exceptions+=i
            exists = Class(complementOf=(Property(prop) | some | exceptions))
            for s, p, o in graph.triples((None, None, restriction)):
                graph.add((s, p, exists.identifier))
            Individual(restriction).delete()

            #purge nominalization placeholder
            iClass = BooleanClass(intermediateCl)
            iClass.clear()
            iClass.delete()
Exemple #7
0
    def transform(self, graph):
        """
        Flattens conjunctions
        ( A1 and ( B1 and B2 ) and A2 )
                         =
        ( A1 and B1 and B2 and A2 )

        """
        Individual.factoryGraph = graph
        for conjunctId in graph.subjects(predicate=OWL_NS.intersectionOf):
            conjunct = BooleanClass(conjunctId)
            nestedConjuncts = [
                BooleanClass(i) for i in conjunct
                if (i, OWL_NS.intersectionOf, None) in graph
            ]
            if nestedConjuncts:

                def collapseConjunctTerms(left, right):
                    list(left) + list(right)

                if len(nestedConjuncts) == 1:
                    newTopLevelItems = list(nestedConjuncts[0])
                else:
                    newTopLevelItems = reduce(collapseConjunctTerms,
                                              nestedConjuncts)
                for nc in nestedConjuncts:
                    nc.clear()
                    del conjunct[conjunct.index(nc.identifier)]
                    nc.delete()
                for newItem in newTopLevelItems:
                    conjunct.append(newItem)
Exemple #8
0
    def transform(self, graph):
        """
        Transforms a 'pure' nominal range into a disjunction of value restrictions
        """
        Individual.factoryGraph = graph
        for restriction, intermediateCl, nominal, prop in graph.query(
                self.NOMINAL_QUERY, initNs={u'owl': OWL_NS}):
            nominalCollection = Collection(graph, nominal)
            #purge restriction
            restr = Class(restriction)
            parentSets = [i for i in restr.subClassOf]
            restr.clearOutDegree()
            newConjunct = BooleanClass(
                restriction, OWL_NS.unionOf,
                [Property(prop) | value | val
                 for val in nominalCollection], graph)
            newConjunct.subClassOf = parentSets

            #purge nominalization placeholder
            iClass = BooleanClass(intermediateCl)
            iClass.clear()
            iClass.delete()
Exemple #9
0
 def transform(self, graph):
     """
     Uses DeMorgan's laws to reduce negated disjunctions to a conjunction of
     negated formulae
     """
     Individual.factoryGraph = graph
     for disjunctId in graph.subjects(predicate=OWL_NS.unionOf):
         if (None, OWL_NS.complementOf, disjunctId) in graph and \
            isinstance(disjunctId, BNode):
             # not (     A1 or      A2  or .. or      An )
             #                 =
             #    ( not A1 and not A2 and .. and not An )
             disjunct = BooleanClass(disjunctId, operator=OWL_NS.unionOf)
             items = list(disjunct)
             newConjunct = BooleanClass(
                     members=[~Class(item) for item in items])
             for negation in graph.subjects(predicate=OWL_NS.complementOf,
                                            object=disjunctId):
                 Class(negation).replace(newConjunct)
                 if not isinstance(negation, BNode):
                     newConjunct.identifier = negation
             disjunct.clear()
             disjunct.delete()
         elif ((disjunctId, OWL_NS.unionOf, None) in graph) and not \
                [item for item in BooleanClass(disjunctId,
                                               operator=OWL_NS.unionOf)
                     if not Class(item).complementOf]:
             #( not A1 or  not A2  or .. or  not An )
             #                 =
             #not ( A1 and A2 and .. and An )
             disjunct = BooleanClass(disjunctId, operator=OWL_NS.unionOf)
             items = [Class(item).complementOf for item in disjunct]
             for negation in disjunct:
                 Class(negation).delete()
             negatedConjunct = ~ BooleanClass(members=items)
             disjunct.clear()
             disjunct.replace(negatedConjunct)
Exemple #10
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
Exemple #11
0
 def transform(self, graph):
     """
     Uses demorgan's laws to reduce negated disjunctions to a conjunction of
     negated formulae
     """
     Individual.factoryGraph = graph
     for disjunctId in graph.subjects(predicate=OWL_NS.unionOf):
         if (None, OWL_NS.complementOf, disjunctId) in graph and \
            isinstance(disjunctId, BNode):
             #not (     A1 or      A2  or .. or      An )
             #                 =
             #    ( not A1 and not A2 and .. and not An )
             disjunct = BooleanClass(disjunctId, operator=OWL_NS.unionOf)
             items = list(disjunct)
             newConjunct = BooleanClass(
                 members=[~Class(item) for item in items])
             for negation in graph.subjects(predicate=OWL_NS.complementOf,
                                            object=disjunctId):
                 Class(negation).replace(newConjunct)
                 if not isinstance(negation, BNode):
                     newConjunct.identifier = negation
             disjunct.clear()
             disjunct.delete()
         elif ((disjunctId, OWL_NS.unionOf, None) in graph) and not \
                [item for item in BooleanClass(disjunctId,
                                               operator=OWL_NS.unionOf)
                     if not Class(item).complementOf]:
             #( not A1 or  not A2  or .. or  not An )
             #                 =
             #not ( A1 and A2 and .. and An )
             disjunct = BooleanClass(disjunctId, operator=OWL_NS.unionOf)
             items = [Class(item).complementOf for item in disjunct]
             for negation in disjunct:
                 Class(negation).delete()
             negatedConjunct = ~BooleanClass(members=items)
             disjunct.clear()
             disjunct.replace(negatedConjunct)