示例#1
0
文件: Magic.py 项目: Web5design/FuXi
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
示例#2
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
示例#3
0
文件: Magic.py 项目: Web5design/FuXi
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 list(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
示例#4
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 list(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