def DisjunctiveNormalForm(program, safety=DATALOG_SAFETY_NONE, network=None): for rule in program: tx_horn_clause = NormalizeClause(rule.formula) for tx_horn_clause in LloydToporTransformation(tx_horn_clause, True): if safety in [DATALOG_SAFETY_LOOSE, DATALOG_SAFETY_STRICT]: rule = Rule(tx_horn_clause, nsMapping=network and network.nsMap or {}) if not rule.isSafe(): if safety == DATALOG_SAFETY_LOOSE: warnings.warn("Ignoring unsafe rule (%s)" % rule, SyntaxWarning, 3) continue elif safety == DATALOG_SAFETY_STRICT: raise SyntaxError("Unsafe RIF Core rule: %s" % rule) disj = [ i for i in breadth_first(tx_horn_clause.body) if isinstance(i, Or) ] if len(disj) > 0: NormalizeDisjunctions(disj, tx_horn_clause, program, network) elif isinstance(tx_horn_clause.head, (And, Uniterm)): # print("No Disjunction in the body") for hc in ExtendN3Rules(network, NormalizeClause(tx_horn_clause)): yield makeRule(hc, network and network.nsMap or {})
def DisjunctiveNormalForm(program, safety=DATALOG_SAFETY_NONE, network=None): for rule in program: tx_horn_clause = NormalizeClause(rule.formula) for tx_horn_clause in LloydToporTransformation(tx_horn_clause, True): if safety in [DATALOG_SAFETY_LOOSE, DATALOG_SAFETY_STRICT]: rule = Rule( tx_horn_clause, nsMapping=network and network.nsMap or {}) if not rule.isSafe(): if safety == DATALOG_SAFETY_LOOSE: import warnings warnings.warn("Ignoring unsafe rule (%s)" % rule, SyntaxWarning, 3) continue elif safety == DATALOG_SAFETY_STRICT: raise SyntaxError("Unsafe RIF Core rule: %s" % rule) disj = [i for i in breadth_first( tx_horn_clause.body) if isinstance(i, Or)] if len(disj) > 0: NormalizeDisjunctions(disj, tx_horn_clause, program, network) elif isinstance(tx_horn_clause.head, (And, Uniterm)): # print("No Disjunction in the body") for hc in ExtendN3Rules( network, NormalizeClause(tx_horn_clause)): yield makeRule(hc, network and network.nsMap or {})
def MapDLPtoNetwork(network, factGraph, complementExpansions=[], constructNetwork=False, derivedPreds=[], ignoreNegativeStratus=False, safety=DATALOG_SAFETY_NONE): ruleset = set() negativeStratus = [] for horn_clause in T(factGraph, complementExpansions=complementExpansions, derivedPreds=derivedPreds): # print("## RIF BLD Horn Rules: Before LloydTopor: ##\n", horn_clause) # print("## RIF BLD Horn Rules: After LloydTopor: ##") fullReduce = True for tx_horn_clause in LloydToporTransformation(horn_clause, fullReduce): tx_horn_clause = NormalizeClause(tx_horn_clause) disj = [ i for i in breadth_first(tx_horn_clause.body) if isinstance(i, Or) ] if len(disj) > 0: NormalizeDisjunctions(disj, tx_horn_clause, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus) elif isinstance(tx_horn_clause.head, (And, Uniterm)): # print("No Disjunction in the body") for hc in ExtendN3Rules(network, NormalizeClause(tx_horn_clause), constructNetwork): if safety in [DATALOG_SAFETY_LOOSE, DATALOG_SAFETY_STRICT]: rule = Rule(hc, nsMapping=network.nsMap) if not rule.isSafe(): if safety == DATALOG_SAFETY_LOOSE: warnings.warn( "Ignoring unsafe rule (%s)" % rule, SyntaxWarning, 3) continue elif safety == DATALOG_SAFETY_STRICT: raise SyntaxError("Unsafe RIF Core rule: %s" % rule) _rule = makeRule(hc, network.nsMap) if _rule.negativeStratus: negativeStratus.append(_rule) if _rule is not None and (not _rule.negativeStratus or not ignoreNegativeStratus): ruleset.add(_rule) # Extract free variables anre add rule to ruleset # print("#######################") # print("########## Finished Building decision network from DLP ##########") # renderNetwork(network).write_graphviz('out.dot') if ignoreNegativeStratus: return ruleset, negativeStratus else: return iter(ruleset)
def MapDLPtoNetwork(network, factGraph, complementExpansions=[], constructNetwork=False, derivedPreds=[], ignoreNegativeStratus=False, safety = DATALOG_SAFETY_NONE): from FuXi.Rete.SidewaysInformationPassing import GetArgs, iterCondition, GetOp ruleset=set() negativeStratus=[] for horn_clause in T(factGraph,complementExpansions=complementExpansions,derivedPreds=derivedPreds): # print "## RIF BLD Horn Rules: Before LloydTopor: ##\n",horn_clause # print "## RIF BLD Horn Rules: After LloydTopor: ##" fullReduce=True for tx_horn_clause in LloydToporTransformation(horn_clause,fullReduce): tx_horn_clause = NormalizeClause(tx_horn_clause) disj = [i for i in breadth_first(tx_horn_clause.body) if isinstance(i,Or)] import warnings if len(disj)>0: NormalizeDisjunctions(disj, tx_horn_clause, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus) elif isinstance(tx_horn_clause.head,(And,Uniterm)): # print "No Disjunction in the body" for hc in ExtendN3Rules(network,NormalizeClause(tx_horn_clause),constructNetwork): if safety in [DATALOG_SAFETY_LOOSE, DATALOG_SAFETY_STRICT]: rule = Rule(hc,nsMapping=network.nsMap) if not rule.isSafe(): if safety == DATALOG_SAFETY_LOOSE: import warnings warnings.warn("Ignoring unsafe rule (%s)"%rule, SyntaxWarning, 3) continue elif safety == DATALOG_SAFETY_STRICT: raise SyntaxError("Unsafe RIF Core rule: %s"%rule) _rule=makeRule(hc,network.nsMap) if _rule.negativeStratus: negativeStratus.append(_rule) if _rule is not None and (not _rule.negativeStratus or not ignoreNegativeStratus): ruleset.add(_rule) #Extract free variables anre add rule to ruleset # print "#######################" # print "########## Finished Building decision network from DLP ##########" #renderNetwork(network).write_graphviz('out.dot') if ignoreNegativeStratus: return ruleset,negativeStratus else: return iter(ruleset)
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)
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 makeRule(clause, nsMap): vars = set() for child in clause.head: if isinstance(child, Or): # Disjunction in the head, skip this rule: # When a disjunction occurs on the r.h.s. of a subclass axiom it # becomes a disjunction in the head of the corresponding rule, and # this cannot be handled within the def-Horn framework. return None assert isinstance(child, Uniterm), repr(child) vars.update([ term for term in child.toRDFTuple() if isinstance(term, Variable) ]) negativeStratus = False for child in clause.body: if hasattr(child, 'naf') and child.naf: negativeStratus = True elif not hasattr(child, 'naf'): child.naf = False vars.update([ term for term in child.toRDFTuple() if isinstance(term, Variable) ]) return Rule(clause, declare=vars, nsMapping=nsMap, negativeStratus=negativeStratus)
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) )")
def ExtendN3Rules(network, horn_clause, constructNetwork=False): """ Extends the network with the given Horn clause (rule) """ from FuXi.Rete.RuleStore import Formula from FuXi.Rete.AlphaNode import AlphaNode rt = [] if constructNetwork: ruleStore = network.ruleStore lhs = BNode() rhs = BNode() assert isinstance(horn_clause.body, (And, Uniterm)), list(horn_clause.body) assert len(list(horn_clause.body)) # print(horn_clause) if constructNetwork: for term in horn_clause.body: ruleStore.formulae.setdefault(lhs, Formula(lhs)).append( term.toRDFTuple()) assert isinstance(horn_clause.head, (And, Uniterm)), repr(horn_clause.head) if IsaFactFormingConclusion(horn_clause.head): PrepareHornClauseForRETE(horn_clause) if constructNetwork: for term in horn_clause.head: assert not hasattr(term, 'next') if isinstance(term, Or): ruleStore.formulae.setdefault(rhs, Formula(rhs)).append(term) else: ruleStore.formulae.setdefault(rhs, Formula(rhs)).append( term.toRDFTuple()) ruleStore.rules.append( (ruleStore.formulae[lhs], ruleStore.formulae[rhs])) network.buildNetwork(iter(ruleStore.formulae[lhs]), iter(ruleStore.formulae[rhs]), Rule(horn_clause)) network.alphaNodes = [ node for node in list(network.nodes.values()) if isinstance(node, AlphaNode) ] rt.append(horn_clause) else: for hC in LloydToporTransformation(horn_clause, fullReduction=True): rt.append(hC) # print("normalized clause: ", hC) for i in ExtendN3Rules(network, hC, constructNetwork): rt.append(hC) return rt
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()) )
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