Exemple #1
0
    def extractRule(self,rule):
        vars,impl = self.rules[rule]
        body,bodyType,head,headType = self.implications[impl]
        allVars = map(self.extractTerm,Collection(self.graph,vars))
        head = first(self.extractPredication(head,headType))
        if bodyType == RIF_NS.And:
            body = map(
                   lambda i: first(self.extractPredication(
                       i,
                       first(self.graph.objects(i,RDF.type)))
                   ),
                   Collection(self.graph,first(self.graph.objects(body,RIF_NS.formulas)))
            )

        else:
            body = self.extractPredication(body,bodyType)
        if isinstance(body,list):
            body = And([first(body)]) if len(body) == 1 else And(body)
        nsMapping = {}
        nsMapping.update(self.nsBindings)
        return Rule(
            Clause(body,head),
            declare=allVars,
            nsMapping=nsMapping
        )
def IncomingSIPArcs(sip, predOcc):
    """docstring for IncomingSIPArcs"""
    for s, p, o in sip.triples((None, None, predOcc)):
        if (p, RDF.type, MAGIC.SipArc) in sip:
            if (s, RDF.type, MAGIC.BoundHeadPredicate) in sip:
                yield [s], Collection(sip,
                                      first(sip.objects(p, MAGIC.bindings)))
            else:
                yield Collection(sip, s), Collection(
                    sip, first(sip.objects(p, MAGIC.bindings)))
def RenderSIPCollection(sipGraph, dot=None):
    try:
        from pydot import Node, Edge, Dot
    except:
        import warnings
        warnings.warn("Missing pydot library", ImportWarning)
    if not dot:
        dot = Dot(graph_type='digraph')
        dot.leftNodesLookup = {}
    nodes = {}
    for N, prop, q in sipGraph.query(
            'SELECT ?N ?prop ?q {  ?prop a magic:SipArc . ?N ?prop ?q . }',
            initNs={u'magic': MAGIC}):

        if MAGIC.BoundHeadPredicate in sipGraph.objects(subject=N,
                                                        predicate=RDF.type):
            NCol = [N]
        else:
            NCol = Collection(sipGraph, N)

        if q not in nodes:
            newNode = Node(makeMD5Digest(q),
                           label=normalizeTerm(q, sipGraph),
                           shape='plaintext')
            nodes[q] = newNode
            dot.add_node(newNode)

        bNode = BNode()
        nodeLabel = ', '.join([normalizeTerm(term, sipGraph) for term in NCol])
        edgeLabel = ', '.join([
            var.n3() for var in Collection(
                sipGraph, first(sipGraph.objects(prop, MAGIC.bindings)))
        ])
        markedEdgeLabel = ''
        if nodeLabel in dot.leftNodesLookup:
            bNode, leftNode, markedEdgeLabel = dot.leftNodesLookup[nodeLabel]


#            print "\t",nodeLabel,edgeLabel, markedEdgeLabel,not edgeLabel == markedEdgeLabel
        else:
            leftNode = Node(makeMD5Digest(bNode),
                            label=nodeLabel,
                            shape='plaintext')
            dot.leftNodesLookup[nodeLabel] = (bNode, leftNode, edgeLabel)
            nodes[bNode] = leftNode
            dot.add_node(leftNode)

        if not edgeLabel == markedEdgeLabel:
            edge = Edge(leftNode, nodes[q], label=edgeLabel)
            dot.add_edge(edge)
    return dot
Exemple #4
0
    def getRuleset(self):
        """
        >>> parser = RIFCoreParser('http://www.w3.org/2005/rules/test/repository/tc/Frames/Frames-premise.rif')
        >>> for rule in parser.getRuleset(): print rule
        Forall ?Customer ( ns1:discount(?Customer 10) :- ns1:status(?Customer "gold"^^<http://www.w3.org/2001/XMLSchema#string>) )
        Forall ?Customer ( ns1:discount(?Customer 5) :- ns1:status(?Customer "silver"^^<http://www.w3.org/2001/XMLSchema#string>) )
        >>> parser = RIFCoreParser('http://www.w3.org/2005/rules/test/repository/tc/Guards_and_subtypes/Guards_and_subtypes-premise.rif')
        >>> for rule in parser.getRuleset(): print rule
        """
        self.members = dict((_member,(_cls,_inst))
            for _member,_cls,_inst in self.graph.query(MEMBER_PARTS,initNs=rif_namespaces)
        )

        self.exists = dict((exists,(formula, formulaType, vars))
            for exists, formula, formulaType, vars in
                self.graph.query(EXISTS_PARTS,initNs=rif_namespaces)
        )

        self.implications = dict([(impl,(body,bodyType,head,headType))
                                    for impl,body,bodyType,head,headType in
                                        self.graph.query(IMPLIES_PARTS,initNs=rif_namespaces)])
        self.rules = dict([ (rule,(vars,impl))
                                for rule,vars,impl
                                    in self.graph.query(RULE_PARTS,
                                                        initNs=rif_namespaces)])
        self.frames = dict([ (frame,(obj,slots))
            for frame,obj,slots in self.graph.query(FRAME_PARTS,
                                                    initNs=rif_namespaces)])

        self.atoms = dict([ (atom,(args,op))
                                for atom, args, op in self.graph.query(
                                        ATOM_PARTS,
                                        initNs=rif_namespaces) ])

        self.externals = dict([(external,(args,op))
                               for external,args,op in self.graph.query(
                                    EXTERNAL_PARTS,
                                    initNs=rif_namespaces) ])
        rt          = set()
        groundFacts = set()
        for sentenceCollection in self.graph.objects(predicate=RIF_NS.sentences):
            col = Collection(self.graph,sentenceCollection)
            for sentence in col:
                if RIF_NS.Implies in self.graph.objects(sentence,RDF.type):
                    rt.add(self.extractImp(sentence))
                elif RIF_NS.Forall in self.graph.objects(sentence,RDF.type):
                    rt.add(self.extractRule(sentence))
                elif RIF_NS.Frame in self.graph.objects(sentence,RDF.type):
                    frames = self.extractFrame(sentence)
                    for term in frames:
                        if term.isGround():
                            triple = term.toRDFTuple()
                            if triple not in groundFacts:
                                groundFacts.add(triple)
        additionalFacts,additionalRules=self.handleImport()
        if additionalRules:
            rt.update(additionalRules)
        if additionalFacts:
            groundFacts.update(additionalFacts)
        return list(rt),list(groundFacts)
Exemple #5
0
    def extractExists(self,exists_resource):
        formula, formulaType, vars = self.exists[exists_resource]
        allVars = map(self.extractTerm,Collection(self.graph,vars))

        if formulaType == RIF_NS.And:
            formula = And(map(
                lambda i: first(self.extractPredication(
                    i,
                    first(self.graph.objects(i,RDF.type)))
                ),
                Collection(self.graph,first(self.graph.objects(formula,RIF_NS.formulas)))
            ))

        else:
            formula = self.extractPredication(formula,formulaType)
        return Exists(formula,allVars)
Exemple #6
0
def handleConjunct(conjunction, owlGraph, o, conjunctVar=Variable('X')):
    for bodyTerm in Collection(owlGraph, o):
        negatedFormula = False
        addToConjunct = None
        for negatedFormula in owlGraph.objects(subject=bodyTerm,
                                               predicate=OWL_NS.complementOf):
            addToConjunct = Tc(owlGraph, negatedFormula)
        if negatedFormula:
            #addToConjunct will be the term we need to add to the conjunct
            conjunction.append(addToConjunct)
        else:
            normalizedBodyTerm = NormalizeBooleanClassOperand(
                bodyTerm, owlGraph)
            bodyUniTerm = Uniterm(RDF.type, [conjunctVar, normalizedBodyTerm],
                                  newNss=owlGraph.namespaces())
            processedBodyTerm = Tb(owlGraph, bodyTerm, conjunctVar)
            classifyingClause = NormalizeClause(
                Clause(processedBodyTerm, bodyUniTerm))
            redundantClassifierClause = processedBodyTerm == bodyUniTerm
            if isinstance(normalizedBodyTerm,
                          URIRef) and normalizedBodyTerm.find(
                              SKOLEMIZED_CLASS_NS) == -1:
                conjunction.append(bodyUniTerm)
            elif (bodyTerm,OWL_NS.someValuesFrom,None) in owlGraph or\
                 (bodyTerm,OWL_NS.hasValue,None) in owlGraph:
                conjunction.extend(classifyingClause.body)
            elif (bodyTerm, OWL_NS.allValuesFrom, None) in owlGraph:
                raise MalformedDLPFormulaError(
                    "Universal restrictions can only be used as the second argument to rdfs:subClassOf (GCIs)"
                )
            elif (bodyTerm, OWL_NS.unionOf, None) in owlGraph:
                conjunction.append(classifyingClause.body)
            elif (bodyTerm, OWL_NS.intersectionOf, None) in owlGraph:
                conjunction.append(bodyUniTerm)
def SIPRepresentation(sipGraph):
    rt = []
    for N, prop, q in sipGraph.query(
            'SELECT ?N ?prop ?q {  ?prop a magic:SipArc . ?N ?prop ?q . }',
            initNs={u'magic': MAGIC}):
        if MAGIC.BoundHeadPredicate in sipGraph.objects(subject=N,
                                                        predicate=RDF.type):
            NCol = [N]
        else:
            NCol = Collection(sipGraph, N)
        rt.append("{ %s } -> %s %s" % (', '.join(
            [normalizeTerm(term, sipGraph) for term in NCol]), ', '.join([
                var.n3() for var in Collection(
                    sipGraph, first(sipGraph.objects(prop, MAGIC.bindings)))
            ]), normalizeTerm(q, sipGraph)))
    return rt
 def collectSip(left, right):
     if isinstance(left, list):
         vars = CollectSIPArcVars(left, right, phBoundVars)
         if not vars and ignoreUnboundDPreds:
             raise InvalidSIPException("No bound variables for %s" % right)
         leftList = Collection(sipGraph, None)
         left = list(set(left))
         [leftList.append(i) for i in [GetOp(ii) for ii in left]]
         left.append(right)
         arc = SIPGraphArc(leftList.uri,
                           getOccurrenceId(right,
                                           occurLookup), vars, sipGraph)
         return left
     else:
         left.isHead = True
         vars = CollectSIPArcVars(left, right, phBoundVars)
         if not vars and ignoreUnboundDPreds:
             raise InvalidSIPException("No bound variables for %s" % right)
         ph = GetOp(left)
         q = getOccurrenceId(right, occurLookup)
         if boundHead:
             arc = SIPGraphArc(ph, q, vars, sipGraph, headPassing=boundHead)
             sipGraph.add((ph, RDF.type, MAGIC.BoundHeadPredicate))
             rt = [left, right]
         else:
             rt = [right]
     return rt
Exemple #9
0
 def extractAtom(self,atom):
     args,op = self.atoms[atom]
     op      = self.extractTerm(op)
     args    = map(self.extractTerm,Collection(self.graph,args))
     if len(args) > 2:
         raise NotImplementedError(
             "FuXi RIF Core parsing only supports subset involving binary/unary Atoms"
         )
     return Uniterm(op,args,newNss=self.nsBindings)
Exemple #10
0
 def extractFrame(self,frame):
     obj,slots = self.frames[frame]
     rt=[]
     for slot in Collection(self.graph,slots):
         k = self.extractTerm(first(self.graph.objects(slot,RIF_NS.slotkey)))
         v = self.extractTerm(first(self.graph.objects(slot,RIF_NS.slotvalue)))
         rt.append(
             Uniterm(k,[self.extractTerm(obj),v],newNss=self.nsBindings)
         )
     return rt
Exemple #11
0
def Tb(owlGraph, _class, variable=Variable('X')):
    """
    DLP body (consequent knowledge assertional forms (ABox assertions, 
    conjunction / disjunction of ABox assertions, and exisential role restriction assertions)
    These are all common EL++ templates for KR
    """
    props = list(set(owlGraph.predicates(subject=_class)))
    if OWL_NS.intersectionOf in props and not isinstance(_class, URIRef):
        for s, p, o in owlGraph.triples((_class, OWL_NS.intersectionOf, None)):
            conj = []
            handleConjunct(conj, owlGraph, o, variable)
            return And(conj)
    elif OWL_NS.unionOf in props and not isinstance(_class, URIRef):
        #http://www.w3.org/TR/owl-semantics/#owl_unionOf
        for s, p, o in owlGraph.triples((_class, OWL_NS.unionOf, None)):
            return Or([Tb(owlGraph,c,variable=variable) \
                           for c in Collection(owlGraph,o)])
    elif OWL_NS.someValuesFrom in props:
        #http://www.w3.org/TR/owl-semantics/#owl_someValuesFrom
        prop = list(
            owlGraph.objects(subject=_class, predicate=OWL_NS.onProperty))[0]
        o = list(
            owlGraph.objects(subject=_class,
                             predicate=OWL_NS.someValuesFrom))[0]
        newVar = Variable(BNode())
        body = Uniterm(prop, [variable, newVar], newNss=owlGraph.namespaces())
        head = Th(owlGraph, o, variable=newVar)
        return And([
            Uniterm(prop, [variable, newVar], newNss=owlGraph.namespaces()),
            Tb(owlGraph, o, variable=newVar)
        ])
    elif OWL_NS.hasValue in props:
        #http://www.w3.org/TR/owl-semantics/#owl_hasValue
        #Domain-specific rules for hasValue
        #Can be achieved via pD semantics
        prop = list(
            owlGraph.objects(subject=_class, predicate=OWL_NS.onProperty))[0]
        o = first(owlGraph.objects(subject=_class, predicate=OWL_NS.hasValue))
        return Uniterm(prop, [variable, o], newNss=owlGraph.namespaces())
    elif OWL_NS.complementOf in props:
        return Tc(owlGraph, first(owlGraph.objects(_class,
                                                   OWL_NS.complementOf)))
    else:
        #simple class
        #"Named" Uniterm
        _classTerm = SkolemizeExistentialClasses(_class)
        return Uniterm(RDF.type, [variable, _classTerm],
                       newNss=owlGraph.namespaces())
 def __init__(self, left, right, variables, graph=None, headPassing=False):
     self.variables = variables
     self.left = left
     self.right = right
     self.graph = graph is None and Graph() or graph
     self.arc = SKOLEMIZED_CLASS_NS[BNode()]
     self.graph.add((self.arc, RDF.type, MAGIC.SipArc))
     varsCol = Collection(self.graph, BNode())
     [varsCol.append(i) for i in self.variables]
     self.graph.add((self.arc, MAGIC.bindings, varsCol.uri))
     if headPassing:
         self.boundHeadPredicate = True
         self.graph.add((self.left, self.arc, self.right))
     else:
         self.boundHeadPredicate = False
         self.graph.add((self.left, self.arc, self.right))
Exemple #13
0
    def predicate(self, predicate, object, depth=1):
        writer = self.writer
        store = self.store
        writer.push(predicate)
        if isinstance(object, Literal):
            attributes = ""
            if object.language:
                writer.attribute(XMLLANG, object.language)
            if object.datatype:
                writer.attribute(RDF.datatype, object.datatype)
            writer.text(object)
        elif object in self.__serialized or not (object, None, None) in store:
            if isinstance(object, BNode):
                if more_than(store.triples((None, None, object)), 0):
                    writer.attribute(RDF.nodeID, fix(object))
            else:
                writer.attribute(RDF.resource, self.relativize(object))
        else:
            items = []
            for item in store.items(object):  # add a strict option to items?
                if isinstance(item, Literal):
                    items = None  # can not serialize list with literal values in them with rdf/xml
                else:
                    items.append(item)

            if first(store.objects(object,
                                   RDF.first)):  # may not have type RDF.List
                collection = object
                self.__serialized[object] = 1
                # TODO: warn that any assertions on object other than
                # RDF.first and RDF.rest are ignored... including RDF.List
                writer.attribute(RDF.parseType, "Collection")
                col = Collection(store, object)
                for item in col:
                    self.forceRDFAbout.add(item)
                    self.subject(item)
                    self.__serialized[item] = 1
            else:
                if depth <= self.max_depth:
                    self.subject(object, depth + 1)
                elif isinstance(object, BNode):
                    writer.attribute(RDF.nodeID, fix(object))
                else:
                    writer.attribute(RDF.resource, self.relativize(object))
        writer.pop(predicate)
Exemple #14
0
def GetTests():
    manifestGraph = Graph().parse(open('SPARQL/W3C/entailment/manifest.ttl'),
                                  format='n3')
    rt = manifestGraph.query(MANIFEST_QUERY, initNs=nsMap, DEBUG=False)
    for test, name, queryFile, rdfDoc, regime, result in rt:
        if isinstance(regime, BNode):
            regime = list(Collection(manifestGraph, regime))
        else:
            regime = [regime]
        named_graph_query = MANIFEST_NAMED_GRAPHS_QUERY % (test.n3())
        named_graphs = list(
            manifestGraph.query(named_graph_query, initNs=nsMap))
        yield test.split(TEST)[-1], \
              name, \
              queryFile, \
              rdfDoc, \
              regime, \
              result,\
              named_graphs
Exemple #15
0
    def extractPredication(self,predication,predType):
        if predType == RIF_NS.Frame:
            return self.extractFrame(predication)
        elif predType == RIF_NS.Atom:
            return [self.extractAtom(predication)]
        elif predType == RIF_NS.Exists:
            return [self.extractExists(predication)]
        elif predType == RIF_NS.Member:
            _cls,_inst = self.members[predication]
            return [Uniterm(
                RDF.type,
                [self.extractTerm(_inst),
                 self.extractTerm(_cls)],
                newNss=self.nsBindings)]
        elif predType == RIF_NS.External:
#            N3Builtin(self,uri,func,argument,result)
            args,op = self.externals[predication]
            args    = map(self.extractTerm,Collection(self.graph,args))
            op      = self.extractTerm(op)
            return [ExternalFunction(Uniterm(op,args))]
        else:
            raise SyntaxError("Unsupported RIF in RDF type: %s"%predType.n3())
Exemple #16
0
def IdentifyDerivedPredicates(ddlMetaGraph, tBox, ruleset=None):
    """
    See: http://code.google.com/p/fuxi/wiki/DataDescriptionLanguage#
    """
    dPreds = set()
    basePreds = set()
    DDL = Namespace(
        'http://code.google.com/p/fuxi/wiki/DataDescriptionLanguage#')

    if ruleset:
        for rule in ruleset:
            dPreds.add(GetOp(rule.formula.head))

    for derivedClassList in ddlMetaGraph.subjects(predicate=RDF.type,
                                                  object=DDL.DerivedClassList):
        dPreds.update(Collection(ddlMetaGraph, derivedClassList))
    for derivedClassList in ddlMetaGraph.subjects(
            predicate=RDF.type, object=DDL.DerivedPropertyList):
        dPreds.update(Collection(ddlMetaGraph, derivedClassList))
    derivedPropPrefixes = []
    basePropPrefixes = []
    for derivedPropPrefixList in ddlMetaGraph.subjects(
            predicate=RDF.type, object=DDL.DerivedPropertyPrefix):
        derivedPropPrefixes.extend(
            Collection(ddlMetaGraph, derivedPropPrefixList))
    for basePropPrefixList in ddlMetaGraph.subjects(
            predicate=RDF.type, object=DDL.BasePropertyPrefix):
        basePropPrefixes.extend(Collection(ddlMetaGraph, basePropPrefixList))

    for prop in tBox.query(OWL_PROPERTIES_QUERY):
        if first(itertools.ifilter(lambda prefix:prop.startswith(prefix),
                                   derivedPropPrefixes)) and \
                       (prop,RDF.type,OWL_NS.AnnotationProperty) not in tBox:
            dPreds.add(prop)
        if first(itertools.ifilter(lambda prefix:prop.startswith(prefix),
                                   basePropPrefixes)) and \
                       (prop,RDF.type,OWL_NS.AnnotationProperty) not in tBox and \
                       prop not in dPreds:
            basePreds.add(prop)

    derivedClassPrefixes = []
    for derivedClsPrefixList in ddlMetaGraph.subjects(
            predicate=RDF.type, object=DDL.DerivedClassPrefix):
        derivedClassPrefixes.extend(
            Collection(ddlMetaGraph, derivedClsPrefixList))
    baseClassPrefixes = []
    for baseClsPrefixList in ddlMetaGraph.subjects(predicate=RDF.type,
                                                   object=DDL.BaseClassPrefix):
        baseClassPrefixes.extend(Collection(ddlMetaGraph, baseClsPrefixList))
    for cls in tBox.subjects(predicate=RDF.type, object=OWL_NS.Class):
        if first(
                itertools.ifilter(lambda prefix: cls.startswith(prefix),
                                  baseClassPrefixes)):
            if cls not in dPreds:
                basePreds.add(cls)
        if first(
                itertools.ifilter(lambda prefix: cls.startswith(prefix),
                                  derivedClassPrefixes)):
            if cls not in basePreds:
                dPreds.add(cls)

    nsBindings = dict([(prefix, nsUri) for prefix, nsUri in itertools.chain(
        tBox.namespaces(), ddlMetaGraph.namespaces()) if prefix])
    for queryNode in ddlMetaGraph.subjects(predicate=RDF.type,
                                           object=DDL.DerivedClassQuery):
        query = first(ddlMetaGraph.objects(queryNode, RDF.value))
        for cls in tBox.query(query, initNs=nsBindings):
            dPreds.add(cls)

    for baseClsList in ddlMetaGraph.subjects(predicate=RDF.type,
                                             object=DDL.BaseClassList):
        basePreds.update(Collection(ddlMetaGraph, baseClsList))

    dPreds.difference_update(basePreds)
    return dPreds
def BuildNaturalSIP(clause,
                    derivedPreds,
                    adornedHead,
                    hybridPreds2Replace=None,
                    ignoreUnboundDPreds=False):
    """
    Natural SIP:
    
    Informally, for a rule of a program, a sip represents a
    decision about the order in which the predicates of the rule will be evaluated, and how values
    for variables are passed from predicates to other predicates during evaluation
    
    >>> ruleStore,ruleGraph=SetupRuleStore(StringIO(PROGRAM2))
    >>> ruleStore._finalize()
    >>> fg=Graph().parse(StringIO(PROGRAM2),format='n3')
    >>> rs=Ruleset(n3Rules=ruleGraph.store.rules,nsMapping=ruleGraph.store.nsMgr)
    >>> for rule in rs: print rule
    Forall ?Y ?X ( ex:sg(?X ?Y) :- ex:flat(?X ?Y) )
    Forall ?Y ?Z4 ?X ?Z1 ?Z2 ?Z3 ( ex:sg(?X ?Y) :- And( ex:up(?X ?Z1) ex:sg(?Z1 ?Z2) ex:flat(?Z2 ?Z3) ex:sg(?Z3 ?Z4) ex:down(?Z4 ?Y) ) )
    >>> sip=BuildNaturalSIP(list(rs)[-1])
    >>> for N,x in IncomingSIPArcs(sip,MAGIC.sg): print N.n3(),x.n3()
    ( <http://doi.acm.org/10.1145/28659.28689#up> <http://doi.acm.org/10.1145/28659.28689#sg> <http://doi.acm.org/10.1145/28659.28689#flat> ) ( ?Z3 )
    ( <http://doi.acm.org/10.1145/28659.28689#up> <http://doi.acm.org/10.1145/28659.28689#sg> ) ( ?Z1 )
    
    >>> sip=BuildNaturalSIP(list(rs)[-1],[MAGIC.sg])
    >>> list(sip.query('SELECT ?q {  ?prop a magic:SipArc . [] ?prop ?q . }',initNs={u'magic':MAGIC}))
    [rdflib.URIRef('http://doi.acm.org/10.1145/28659.28689#sg'), rdflib.URIRef('http://doi.acm.org/10.1145/28659.28689#sg')]
    """
    from FuXi.Rete.Magic import AdornedUniTerm
    occurLookup = {}
    boundHead = isinstance(adornedHead,
                           AdornedUniTerm) and 'b' in adornedHead.adornment
    phBoundVars = list(adornedHead.getDistinguishedVariables(varsOnly=True))

    #    assert isinstance(clause.head,Uniterm),"Only one literal in the head!"
    def collectSip(left, right):
        if isinstance(left, list):
            vars = CollectSIPArcVars(left, right, phBoundVars)
            if not vars and ignoreUnboundDPreds:
                raise InvalidSIPException("No bound variables for %s" % right)
            leftList = Collection(sipGraph, None)
            left = list(set(left))
            [leftList.append(i) for i in [GetOp(ii) for ii in left]]
            left.append(right)
            arc = SIPGraphArc(leftList.uri,
                              getOccurrenceId(right,
                                              occurLookup), vars, sipGraph)
            return left
        else:
            left.isHead = True
            vars = CollectSIPArcVars(left, right, phBoundVars)
            if not vars and ignoreUnboundDPreds:
                raise InvalidSIPException("No bound variables for %s" % right)
            ph = GetOp(left)
            q = getOccurrenceId(right, occurLookup)
            if boundHead:
                arc = SIPGraphArc(ph, q, vars, sipGraph, headPassing=boundHead)
                sipGraph.add((ph, RDF.type, MAGIC.BoundHeadPredicate))
                rt = [left, right]
            else:
                rt = [right]
        return rt

    sipGraph = Graph()
    if isinstance(clause.body, And):
        if ignoreUnboundDPreds:
            foundSip = False
            sips = findFullSip(([clause.head], None), clause.body)
            while not foundSip:
                try:
                    sip = sips.next()
                except StopIteration:
                    #Throw SIP exception if sip isn't found (probably means
                    #query + rules combination is 'malformed')
                    raise InvalidSIPException(
                        "Unable to find a sip for %s (%s)" %
                        (clause, adornedHead))
                try:
                    reduce(collectSip, iterCondition(And(sip)))
                    foundSip = True
                    bodyOrder = sip
                except InvalidSIPException:
                    foundSip = False
        else:
            if first(
                    itertools.ifilter(
                        lambda i: isinstance(i, Uniterm) and i.naf or False,
                        clause.body)):
                #There are negative literals in body, ensure
                #the given sip order puts negated literals at the end
                bodyOrder = first(
                    itertools.ifilter(
                        ProperSipOrderWithNegation,
                        findFullSip(([clause.head], None), clause.body)))
            else:
                bodyOrder = first(
                    findFullSip(([clause.head], None), clause.body))
            assert bodyOrder, "Couldn't find a valid SIP for %s" % clause
            reduce(collectSip, iterCondition(And(bodyOrder)))
        sipGraph.sipOrder = And(bodyOrder[1:])
        #assert validSip(sipGraph),sipGraph.serialize(format='n3')
    else:
        if boundHead:
            reduce(
                collectSip,
                itertools.chain(iterCondition(clause.head),
                                iterCondition(clause.body)))
        sipGraph.sipOrder = clause.body
    if derivedPreds:
        # We therefore generalize our notation to allow
        # more succint representation of sips, in which only arcs entering
        # derived predicates are represented.
        arcsToRemove = []
        collectionsToClear = []
        for N, prop, q in sipGraph.query(
                'SELECT ?N ?prop ?q {  ?prop a magic:SipArc . ?N ?prop ?q . }',
                initNs={u'magic': MAGIC}):
            if occurLookup[q] not in derivedPreds and (
                    occurLookup[q] not in hybridPreds2Replace
                    if hybridPreds2Replace else False):
                arcsToRemove.extend([(N, prop, q), (prop, None, None)])
                collectionsToClear.append(Collection(sipGraph, N))
                #clear bindings collection as well
                bindingsColBNode = first(sipGraph.objects(
                    prop, MAGIC.bindings))
                collectionsToClear.append(
                    Collection(sipGraph, bindingsColBNode))
        for removeSts in arcsToRemove:
            sipGraph.remove(removeSts)
        for col in collectionsToClear:
            col.clear()
    return sipGraph
Exemple #18
0
def T(owlGraph, complementExpansions=[], derivedPreds=[]):
    """
    #Subsumption (purely for TBOX classification)
    {?C rdfs:subClassOf ?SC. ?A rdfs:subClassOf ?C} => {?A rdfs:subClassOf ?SC}.
    {?C owl:equivalentClass ?A} => {?C rdfs:subClassOf ?A. ?A rdfs:subClassOf ?C}.
    {?C rdfs:subClassOf ?SC. ?SC rdfs:subClassOf ?C} => {?C owl:equivalentClass ?SC}.
    
    T(rdfs:subClassOf(C,D))       -> Th(D(y)) :- Tb(C(y))
    
    T(owl:equivalentClass(C,D)) -> { T(rdfs:subClassOf(C,D) 
                                     T(rdfs:subClassOf(D,C) }
    
    A generator over the Logic Programming rules which correspond
    to the DL  ( unary predicate logic ) subsumption axiom described via rdfs:subClassOf
    """
    for s, p, o in owlGraph.triples((None, OWL_NS.complementOf, None)):
        if isinstance(o, URIRef) and isinstance(s, URIRef):
            headLiteral = Uniterm(
                RDF.type,
                [Variable("X"), SkolemizeExistentialClasses(s)],
                newNss=owlGraph.namespaces())
            yield NormalizeClause(Clause(Tc(owlGraph, o), headLiteral))
    for c, p, d in owlGraph.triples((None, RDFS.subClassOf, None)):
        try:
            yield NormalizeClause(Clause(Tb(owlGraph, c), Th(owlGraph, d)))
        except UnsupportedNegation:
            import warnings
            warnings.warn(
                "Unable to handle negation in DL axiom (%s), skipping" %
                c,  #e.msg,
                SyntaxWarning,
                3)
        #assert isinstance(c,URIRef),"%s is a kind of %s"%(c,d)
    for c, p, d in owlGraph.triples((None, OWL_NS.equivalentClass, None)):
        if c not in derivedPreds:
            yield NormalizeClause(Clause(Tb(owlGraph, c), Th(owlGraph, d)))
        yield NormalizeClause(Clause(Tb(owlGraph, d), Th(owlGraph, c)))
    for s, p, o in owlGraph.triples((None, OWL_NS.intersectionOf, None)):
        try:
            if s not in complementExpansions:
                if s in derivedPreds:
                    import warnings
                    warnings.warn(
                        "Derived predicate (%s) is defined via a conjunction (consider using a complex GCI) "
                        % owlGraph.qname(s), SyntaxWarning, 3)
                elif isinstance(
                        s, BNode):  # and (None,None,s) not in owlGraph:# and \
                    #(s,RDFS.subClassOf,None) in owlGraph:
                    #complex GCI, pass over (handled) by Tb
                    continue
                conjunction = []
                handleConjunct(conjunction, owlGraph, o)
                body = And(conjunction)
                head = Uniterm(RDF.type,
                               [Variable("X"),
                                SkolemizeExistentialClasses(s)],
                               newNss=owlGraph.namespaces())
                #            O1 ^ O2 ^ ... ^ On => S(?X)
                yield Clause(body, head)
                if isinstance(s, URIRef):
                    #                S(?X) => O1 ^ O2 ^ ... ^ On
                    #            special case, owl:intersectionOf is a neccessary and sufficient
                    #            criteria and should thus work in *both* directions
                    #            This rule is not added for anonymous classes or derived predicates
                    if s not in derivedPreds:
                        yield Clause(head, body)
        except UnsupportedNegation:
            import warnings
            warnings.warn(
                "Unable to handle negation in DL axiom (%s), skipping" %
                s,  #e.msg,
                SyntaxWarning,
                3)

    for s, p, o in owlGraph.triples((None, OWL_NS.unionOf, None)):
        if isinstance(s, URIRef):
            #special case, owl:unionOf is a neccessary and sufficient
            #criteria and should thus work in *both* directions
            body = Or([Uniterm(RDF.type,[Variable("X"),
                                         NormalizeBooleanClassOperand(i,owlGraph)],
                                         newNss=owlGraph.namespaces()) \
                           for i in Collection(owlGraph,o)])
            head = Uniterm(RDF.type, [Variable("X"), s],
                           newNss=owlGraph.namespaces())
            yield Clause(body, head)
    for s, p, o in owlGraph.triples((None, OWL_NS.inverseOf, None)):
        #    T(owl:inverseOf(P,Q))          -> { Q(x,y) :- P(y,x)
        #                                        P(y,x) :- Q(x,y) }
        newVar = Variable(BNode())

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s
        o = SkolemizeExistentialClasses(o) if isinstance(o, BNode) else o

        body1 = Uniterm(s, [newVar, Variable("X")],
                        newNss=owlGraph.namespaces())
        head1 = Uniterm(o, [Variable("X"), newVar],
                        newNss=owlGraph.namespaces())
        yield Clause(body1, head1)
        newVar = Variable(BNode())
        body2 = Uniterm(o, [Variable("X"), newVar],
                        newNss=owlGraph.namespaces())
        head2 = Uniterm(s, [newVar, Variable("X")],
                        newNss=owlGraph.namespaces())
        yield Clause(body2, head2)
    for s, p, o in owlGraph.triples(
        (None, RDF.type, OWL_NS.TransitiveProperty)):
        #T(owl:TransitiveProperty(P))   -> P(x,z) :- P(x,y) ^ P(y,z)
        y = Variable(BNode())
        z = Variable(BNode())
        x = Variable("X")

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s

        body = And([Uniterm(s,[x,y],newNss=owlGraph.namespaces()),\
                    Uniterm(s,[y,z],newNss=owlGraph.namespaces())])
        head = Uniterm(s, [x, z], newNss=owlGraph.namespaces())
        yield Clause(body, head)
    for s, p, o in owlGraph.triples((None, RDFS.subPropertyOf, None)):
        # T(rdfs:subPropertyOf(P,Q))     -> Q(x,y) :- P(x,y)
        x = Variable("X")
        y = Variable("Y")

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s
        o = SkolemizeExistentialClasses(o) if isinstance(o, BNode) else o

        body = Uniterm(s, [x, y], newNss=owlGraph.namespaces())
        head = Uniterm(o, [x, y], newNss=owlGraph.namespaces())

        yield Clause(body, head)
    for s, p, o in owlGraph.triples((None, OWL_NS.equivalentProperty, None)):
        # T(owl:equivalentProperty(P,Q)) -> { Q(x,y) :- P(x,y)
        #                                     P(x,y) :- Q(x,y) }
        x = Variable("X")
        y = Variable("Y")

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s
        o = SkolemizeExistentialClasses(o) if isinstance(o, BNode) else o

        body = Uniterm(s, [x, y], newNss=owlGraph.namespaces())
        head = Uniterm(o, [x, y], newNss=owlGraph.namespaces())
        yield Clause(body, head)
        yield Clause(head, body)

    #Contribution (Symmetric DL roles)
    for s, p, o in owlGraph.triples(
        (None, RDF.type, OWL_NS.SymmetricProperty)):
        #T(owl:SymmetricProperty(P))   -> P(y,x) :- P(x,y)
        y = Variable("Y")
        x = Variable("X")

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s

        body = Uniterm(s, [x, y], newNss=owlGraph.namespaces())
        head = Uniterm(s, [y, x], newNss=owlGraph.namespaces())
        yield Clause(body, head)

    for s, p, o in owlGraph.triples_choices((None, [RDFS.range,
                                                    RDFS.domain], None)):

        s = SkolemizeExistentialClasses(s) if isinstance(s, BNode) else s

        if p == RDFS.range:
            #T(rdfs:range(P,D))  -> D(y) := P(x,y)
            x = Variable("X")
            y = Variable(BNode())
            body = Uniterm(s, [x, y], newNss=owlGraph.namespaces())
            head = Uniterm(RDF.type, [y, o], newNss=owlGraph.namespaces())
            yield Clause(body, head)
        else:
            #T(rdfs:domain(P,D)) -> D(x) := P(x,y)
            x = Variable("X")
            y = Variable(BNode())
            body = Uniterm(s, [x, y], newNss=owlGraph.namespaces())
            head = Uniterm(RDF.type, [x, o], newNss=owlGraph.namespaces())
            yield Clause(body, head)