def NormalizeDisjunctions(disj, clause, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus): """ Removes disjunctions from logic programs (if possible) """ from FuXi.DLP import breadth_first, breadth_first_replace # disj = [i for i in breadth_first(clause.body) if isinstance(i,Or)] while len(disj) > 1: ApplyDemorgans(clause) if HasBreadthFirstNestedConj(clause.body): FlattenConjunctions(clause.body) disj = [i for i in breadth_first(clause.body) if isinstance(i, Or)] assert len(disj) < 2, "Unable to effectively reduce disjunctions" if len(disj) == 1: # There is one disjunction in the body, we can reduce from: # H :- B1 V B2 to H : - B1 and H :- B2 origDisj = disj[0] for item in origDisj: # First we want to replace the entire disjunct with an item within # it list(breadth_first_replace( clause.body, candidate=origDisj, replacement=item)) clause_clone = copy.deepcopy(clause) disj = [i for i in breadth_first(clause_clone.body) if isinstance(i, Or)] if len(disj) > 0: # If the formula has disjunctions of it's own, we handle them # recursively NormalizeDisjunctions(disj, clause_clone, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus) else: if HasBreadthFirstNestedConj(clause_clone.body): FlattenConjunctions(clause_clone.body) # Otherwise handle normally HandleNonDisjunctiveClauses( ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus, clause_clone) # restore the replaced term (for the subsequent iteration) list(breadth_first_replace( clause.body, candidate=item, replacement=origDisj)) else: # The disjunction has been handled by normal form transformation, # we just need to handle normally if HasBreadthFirstNestedConj(clause_clone.body): FlattenConjunctions(clause_clone.body) HandleNonDisjunctiveClauses( ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus, clause)
def NormalizeDisjunctions(disj, clause, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus): """ Removes disjunctions from logic programs (if possible) """ from FuXi.DLP import breadth_first, breadth_first_replace # disj = [i for i in breadth_first(clause.body) if isinstance(i,Or)] while len(disj) > 1: ApplyDemorgans(clause) if HasBreadthFirstNestedConj(clause.body): FlattenConjunctions(clause.body) disj = [i for i in breadth_first(clause.body) if isinstance(i, Or)] assert len(disj) < 2, "Unable to effectively reduce disjunctions" if len(disj) == 1: # There is one disjunction in the body, we can reduce from: # H :- B1 V B2 to H : - B1 and H :- B2 origDisj = disj[0] for item in origDisj: # First we want to replace the entire disjunct with an item within # it list( breadth_first_replace(clause.body, candidate=origDisj, replacement=item)) clause_clone = copy.deepcopy(clause) disj = [ i for i in breadth_first(clause_clone.body) if isinstance(i, Or) ] if len(disj) > 0: # If the formula has disjunctions of it's own, we handle them # recursively NormalizeDisjunctions(disj, clause_clone, ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus) else: if HasBreadthFirstNestedConj(clause_clone.body): FlattenConjunctions(clause_clone.body) # Otherwise handle normally HandleNonDisjunctiveClauses(ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus, clause_clone) # restore the replaced term (for the subsequent iteration) list( breadth_first_replace(clause.body, candidate=item, replacement=origDisj)) else: # The disjunction has been handled by normal form transformation, we just need to # handle normally if HasBreadthFirstNestedConj(clause_clone.body): FlattenConjunctions(clause_clone.body) HandleNonDisjunctiveClauses(ruleset, network, constructNetwork, negativeStratus, ignoreNegativeStratus, clause)
def ApplyDemorgans(clause): """ >>> from FuXi.DLP import Clause >>> EX_NS = Namespace('http://example.com/') >>> ns = {'ex' : EX_NS} >>> pred1 = PredicateExtentFactory(EX_NS.somePredicate,newNss=ns) >>> pred2 = PredicateExtentFactory(EX_NS.somePredicate2,newNss=ns) >>> pred3 = PredicateExtentFactory(EX_NS.somePredicate3,binary=False,newNss=ns) >>> pred4 = PredicateExtentFactory(EX_NS.somePredicate4,binary=False,newNss=ns) >>> clause = Clause(And([pred1[(Variable('X'),Variable('Y'))], ... Or([pred2[(Variable('X'),EX_NS.individual1)], ... pred3[(Variable('Y'))]],naf=True)]), ... pred4[Variable('X')]) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) not Or( ex:somePredicate2(?X ex:individual1) ex:somePredicate3(?Y) ) ) >>> ApplyDemorgans(clause) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) And( not ex:somePredicate2(?X ex:individual1) not ex:somePredicate3(?Y) ) ) >>> FlattenConjunctions(clause.body) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) not ex:somePredicate2(?X ex:individual1) not ex:somePredicate3(?Y) ) """ from FuXi.DLP import breadth_first, breadth_first_replace replacementMap = {} for negDisj in [i for i in breadth_first(clause.body) if isinstance(i, Or) and i.naf]: replacementList = [] for innerTerm in negDisj: assert isinstance(negDisj, Uniterm), negDisj innerTerm.naf = not innerTerm.naf replacementList.append(innerTerm) replacementMap[negDisj] = And(replacementList) for old, new in list(replacementMap.items()): list(breadth_first_replace( clause.body, candidate=old, replacement=new))
def ApplyDemorgans(clause): """ >>> from FuXi.DLP import Clause >>> EX_NS = Namespace('http://example.com/') >>> ns = {'ex' : EX_NS} >>> pred1 = PredicateExtentFactory(EX_NS.somePredicate,newNss=ns) >>> pred2 = PredicateExtentFactory(EX_NS.somePredicate2,newNss=ns) >>> pred3 = PredicateExtentFactory(EX_NS.somePredicate3,binary=False,newNss=ns) >>> pred4 = PredicateExtentFactory(EX_NS.somePredicate4,binary=False,newNss=ns) >>> clause = Clause(And([pred1[(Variable('X'),Variable('Y'))], ... Or([pred2[(Variable('X'),EX_NS.individual1)], ... pred3[(Variable('Y'))]],naf=True)]), ... pred4[Variable('X')]) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) not Or( ex:somePredicate2(?X ex:individual1) ex:somePredicate3(?Y) ) ) >>> ApplyDemorgans(clause) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) And( not ex:somePredicate2(?X ex:individual1) not ex:somePredicate3(?Y) ) ) >>> FlattenConjunctions(clause.body) >>> clause ex:somePredicate4(?X) :- And( ex:somePredicate(?X ?Y) not ex:somePredicate2(?X ex:individual1) not ex:somePredicate3(?Y) ) """ from FuXi.DLP import breadth_first, breadth_first_replace replacementMap = {} for negDisj in [i for i in breadth_first(clause.body) if isinstance(i,Or) and i.naf]: replacementList = [] for innerTerm in negDisj: assert isinstance(i,Uniterm) innerTerm.naf = not innerTerm.naf replacementList.append(innerTerm) replacementMap[negDisj] = And(replacementList) for old,new in replacementMap.items(): list(breadth_first_replace(clause.body,candidate=old,replacement=new))