Esempio n. 1
0
def CreateHybridPredicateRule(hybridPred, program, nsMap=None):
    hPred = URIRef(hybridPred + u'_derived')
    literals = set(
        reduce(lambda l, r: l + r, [
            list(iterCondition(clause.formula.body)) +
            list(iterCondition(clause.formula.head)) for clause in program
        ]))
    for literal in literals:
        if GetOp(literal) == hybridPred:
            noArgs = len(GetArgs(literal))
            if noArgs == 1:
                # p_derived(X) :- p(X)
                body = BuildUnitermFromTuple(
                    (Variable('X'), RDF.type, hybridPred), newNss=nsMap)
                head = BuildUnitermFromTuple((Variable('X'), RDF.type, hPred),
                                             newNss=nsMap)
                vars = [Variable('X')]
            else:
                # p_derived(X,Y) :- p(X,Y)
                body = BuildUnitermFromTuple(
                    (Variable('X'), hybridPred, Variable('Y')), newNss=nsMap)
                head = BuildUnitermFromTuple(
                    (Variable('X'), hPred, Variable('Y')), newNss=nsMap)
                vars = [Variable('Y'), Variable('X')]
            return Rule(Clause(And([body]), head),
                        nsMapping=nsMap,
                        declare=vars)
Esempio n. 2
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
        )
Esempio n. 3
0
    def extractImp(self, impl):
        body, bodyType, head, headType = self.implications[impl]
        head = first(self.extractPredication(head, headType))
        if bodyType == RIF_NS.And:
            raise
        else:
            body = self.extractPredication(body, bodyType)

        body = And([first(body)]) if len(body) == 1 else And(body)
        return Rule(Clause(body, head), declare=[])
 def testSerializingEvalPred(self):
     nsBindings = {u'bfp': BFP_NS, u'rule': BFP_RULE}
     evaluateTerm = Uniterm(BFP_NS.evaluate,
                            [BFP_RULE[str(1)], Literal(1)],
                            newNss=nsBindings)
     self.failUnless(repr(evaluateTerm), "bfp:evaluate(rule:1 1)")
     xVar = Variable('X')
     yVar = Variable('Y')
     bodyTerm = Uniterm(RDF.rest, [xVar, yVar], newNss=nsBindings)
     rule = Rule(Clause(bodyTerm, evaluateTerm), declare=[xVar, yVar])
     self.assertEqual(
         repr(rule),
         "Forall ?X ?Y ( bfp:evaluate(rule:1 1) :- rdf:rest(?X ?Y) )")
Esempio n. 5
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 = [first(self.extractPredication(
                       i,
                       first(self.graph.objects(i, RDF.type)))
                   ) for i in Collection(self.graph,
                        first(self.graph.objects(body, RIF_NS.formulas)))]

        else:
            body = self.extractPredication(body, bodyType)

        body = And([first(body)]) if len(body) == 1 else And(body)
        return Rule(
            Clause(body, head),
            declare=allVars,
            nsMapping=dict(self.graph.namespaces())
        )
Esempio n. 6
0
def AdornRule(derivedPreds,
              clause,
              newHead,
              ignoreUnboundDPreds=False,
              hybridPreds2Replace=None):
    """
    Adorns a horn clause using the given new head and list of
    derived predicates
    """
    assert len(list(iterCondition(clause.head))) == 1
    hybridPreds2Replace = hybridPreds2Replace or []
    adornedHead = AdornedUniTerm(clause.head, newHead.adornment)
    sip = BuildNaturalSIP(clause,
                          derivedPreds,
                          adornedHead,
                          hybridPreds2Replace=hybridPreds2Replace,
                          ignoreUnboundDPreds=ignoreUnboundDPreds)
    bodyPredReplace = {}

    def adornment(arg, headArc, x):
        if headArc:
            #Sip arc from head
            #don't mark bound if query has no bound/distinguished terms
            return (arg in x and
                    arg in adornedHead.getDistinguishedVariables(True)) \
                        and 'b' or 'f'
        else:
            return arg in x and 'b' or 'f'

    for literal in iterCondition(sip.sipOrder):
        op = GetOp(literal)
        args = GetArgs(literal)
        if op in derivedPreds or (op in hybridPreds2Replace
                                  if hybridPreds2Replace else False):
            for N, x in IncomingSIPArcs(sip, getOccurrenceId(literal)):
                headArc = len(N) == 1 and N[0] == GetOp(newHead)
                if not set(x).difference(args):
                    # A binding
                    # for q is useful, however, only if it is a binding for an argument of q.
                    bodyPredReplace[literal] = AdornedUniTerm(
                        NormalizeUniterm(literal),
                        [adornment(arg, headArc, x) for arg in args],
                        literal.naf)


#                For a predicate occurrence with no incoming
#                arc, the adornment contains only f. For our purposes here,
#                we do not distinguish between a predicate with such an
#                adornment and an unadorned predicate (we do in order to support open queries)
            if literal not in bodyPredReplace and ignoreUnboundDPreds:
                bodyPredReplace[literal] = AdornedUniTerm(
                    NormalizeUniterm(literal),
                    ['f' for arg in GetArgs(literal)], literal.naf)
    if hybridPreds2Replace:
        atomPred = GetOp(adornedHead)
        if atomPred in hybridPreds2Replace:
            adornedHead.setOperator(URIRef(atomPred + u'_derived'))
        for bodAtom in [
                bodyPredReplace.get(p, p) for p in iterCondition(sip.sipOrder)
        ]:
            bodyPred = GetOp(bodAtom)
            if bodyPred in hybridPreds2Replace:
                bodAtom.setOperator(URIRef(bodyPred + u'_derived'))
    rule = AdornedRule(
        Clause(
            And([
                bodyPredReplace.get(p, p) for p in iterCondition(sip.sipOrder)
            ]), adornedHead))
    rule.sip = sip
    return rule
Esempio n. 7
0
def MagicSetTransformation(factGraph,
                           rules,
                           GOALS,
                           derivedPreds=None,
                           strictCheck=DDL_STRICTNESS_FALLBACK_DERIVED,
                           noMagic=None,
                           defaultPredicates=None):
    """
    Takes a goal and a ruleset and returns an iterator
    over the rulest that corresponds to the magic set
    transformation:
    """
    noMagic = noMagic and noMagic or []
    magicPredicates = set()
    replacement = {}
    adornedProgram = SetupDDLAndAdornProgram(
        factGraph,
        rules,
        GOALS,
        derivedPreds=derivedPreds,
        strictCheck=strictCheck,
        defaultPredicates=defaultPredicates)
    newRules = []
    for rule in adornedProgram:
        if rule.isSecondOrder():
            import warnings
            warnings.warn("Second order rule no supported by GMS: %s" % rule,
                          RuntimeWarning)

        magicPositions = {}
        #Generate magic rules
        for idx, pred in enumerate(iterCondition(rule.formula.body)):
            magicBody = []
            if isinstance(pred,
                          AdornedUniTerm):  # and pred not in magicPredicates:
                # For each rule r in Pad, and for each occurrence of an adorned
                # predicate p a in its body, we generate a magic rule defining magic_p a
                prevPreds = [
                    item for _idx, item in enumerate(rule.formula.body)
                    if _idx < idx
                ]
                if 'b' not in pred.adornment:
                    import warnings
                    warnings.warn(
                        "adorned predicate w/out any bound arguments(%s in %s) !"
                        % (pred, rule.formula), RuntimeWarning)
                if GetOp(pred) not in noMagic:
                    magicPred = pred.makeMagicPred()
                    magicPositions[idx] = (magicPred, pred)
                    inArcs = [(N, x) for (
                        N,
                        x) in IncomingSIPArcs(rule.sip, getOccurrenceId(pred))
                              if not set(x).difference(GetArgs(pred))]
                    if len(inArcs) > 1:
                        #                    If there are several arcs entering qi, we define the magic rule defining magic_qi
                        #                    in two steps. First, for each arc Nj --> qi with label cj , we define a rule with head label_qi_j(cj ). The body
                        #                    of the rule is the same as the body of the magic rule in the case where there is a single arc
                        #                    entering qi (described above). Then the magic rule is defined as follows. The head is
                        #                    magic_q(0). The body contains label_qi_j(cj) for all j (that is, for all arcs entering qi ).

                        #We combine all incoming arcs into a single list of (body) conditions for the magic set
                        PrettyPrintRule(rule)
                        SIPRepresentation(rule.sip)
                        print pred, magicPred
                        _body = []
                        additionalRules = []
                        for idxSip, (N, x) in enumerate(inArcs):
                            newPred = pred.clone()
                            SetOp(newPred,
                                  URIRef('%s_label_%s' % (newPred.op, idxSip)))
                            ruleBody = And(
                                buildMagicBody(N, prevPreds, rule.formula.head,
                                               derivedPreds))
                            additionalRules.append(
                                Rule(Clause(ruleBody, newPred)))
                            _body.extend(newPred)
    #                        _body.extend(ruleBody)
                        additionalRules.append(
                            Rule(Clause(And(_body), magicPred)))
                        newRules.extend(additionalRules)
                        for i in additionalRules:
                            print i
                        raise NotImplementedError()
                    else:
                        for idxSip, (N, x) in enumerate(inArcs):
                            ruleBody = And(
                                buildMagicBody(N, prevPreds, rule.formula.head,
                                               derivedPreds, noMagic))
                            newRule = Rule(Clause(ruleBody, magicPred))
                            newRules.append(newRule)
                    magicPredicates.add(magicPred)
        #Modify rules
        #we modify the original rule by inserting
        #occurrences of the magic predicates corresponding
        #to the derived predicates of the body and to the head
        #If there are no bound arguments in the head, we don't modify the rule
        idxIncrement = 0
        newRule = copy.deepcopy(rule)
        for idx, (magicPred, origPred) in magicPositions.items():
            newRule.formula.body.formulae.insert(idx + idxIncrement, magicPred)
            idxIncrement += 1
        if 'b' in rule.formula.head.adornment and GetOp(
                rule.formula.head) not in noMagic:
            headMagicPred = rule.formula.head.makeMagicPred()
            if isinstance(newRule.formula.body, Uniterm):
                newRule.formula.body = And(
                    [headMagicPred, newRule.formula.body])
            else:
                newRule.formula.body.formulae.insert(0, headMagicPred)
        newRules.append(newRule)

    if not newRules:
        newRules.extend(AdditionalRules(factGraph))
    for rule in newRules:
        if rule.formula.body:
            yield rule
Esempio n. 8
0
def SetupDDLAndAdornProgram(factGraph,
                            rules,
                            GOALS,
                            derivedPreds=None,
                            strictCheck=DDL_STRICTNESS_FALLBACK_DERIVED,
                            defaultPredicates=None,
                            ignoreUnboundDPreds=False,
                            hybridPreds2Replace=None):
    if not defaultPredicates:
        defaultPredicates = [], []
    # _dPredsProvided = bool(derivedPreds)
    if not derivedPreds:
        _derivedPreds = DerivedPredicateIterator(
            factGraph,
            rules,
            strict=strictCheck,
            defaultPredicates=defaultPredicates)
        if not isinstance(derivedPreds, (set, list)):
            derivedPreds = list(_derivedPreds)
        else:
            derivedPreds.extend(_derivedPreds)
    hybridPreds2Replace = hybridPreds2Replace or []
    adornedProgram = AdornProgram(factGraph,
                                  rules,
                                  GOALS,
                                  derivedPreds,
                                  ignoreUnboundDPreds,
                                  hybridPreds2Replace=hybridPreds2Replace)
    if adornedProgram != set([]):
        rt = reduce(lambda l, r: l + r, [
            list(iterCondition(clause.formula.body))
            for clause in adornedProgram
        ])
    else:
        rt = set()
    for hybridPred, adornment in [
        (t, a) for t, a in set([(URIRef(GetOp(term).split('_derived')[0]
                                        ) if GetOp(term).find('_derived') +
                                 1 else GetOp(term), ''.join(term.adornment))
                                for term in rt
                                if isinstance(term, AdornedUniTerm)])
            if t in hybridPreds2Replace
    ]:
        #If there are hybrid predicates, add rules that derived their IDB counterpart
        #using information from the adorned queries to determine appropriate arity
        #and adornment
        hybridPred = URIRef(hybridPred)
        hPred = URIRef(hybridPred + u'_derived')
        if len(adornment) == 1:
            # p_derived^{a}(X) :- p(X)
            body = BuildUnitermFromTuple((Variable('X'), RDF.type, hybridPred))
            head = BuildUnitermFromTuple((Variable('X'), RDF.type, hPred))
        else:
            # p_derived^{a}(X, Y) :- p(X, Y)
            body = BuildUnitermFromTuple(
                (Variable('X'), hybridPred, Variable('Y')))
            head = BuildUnitermFromTuple((Variable('X'), hPred, Variable('Y')))
        _head = AdornedUniTerm(head, list(adornment))
        rule = AdornedRule(Clause(And([body]), _head.clone()))
        rule.sip = Graph()
        adornedProgram.add(rule)

    if factGraph is not None:
        factGraph.adornedProgram = adornedProgram
    return adornedProgram