def test_NestedAndOrReversion(self): lhs = [ types.AndPatternCE([ types.OrPatternCE(["A", "B"]), types.OrPatternCE([ "C", "D", types.AndPatternCE(["Z", types.OrPatternCE(["W", "X"])]) ]) ]) ] lhs = analysis.normalizeLHS(lhs, self.MM) self.assertIsInstance(lhs, types.OrPatternCE) permutations = [] for i in range(0, 8): self.assertIsInstance(lhs.patterns[i], types.AndPatternCE) permutations.append(lhs.patterns[i].patterns) permutationExpected = [["A", "C"], ["B", "C"], ["A", "D"], ["B", "D"], ["A", "Z", "W"], ["A", "Z", "X"], ["B", "Z", "W"], ["B", "Z", "X"]] self.assertEqual(permutations, permutationExpected)
def normalizeLHS(lhs, MM): """ Change patterns orders (and nested patterns order) to normalize lhs in a Or (And ( normal form with all nested Or regrouped in a single top level Or """ if isinstance(lhs, list): # check if LHS has not pattern and handle this case as # (or (and (initial-fact))) if len(lhs) == 0: return types.OrPatternCE([types.AndPatternCE([_makeInitialFactPattern(MM)])]) # wrap the pattern list with an AndCE lhs = types.AndPatternCE(lhs) if isinstance(lhs, types.AndPatternCE): # wrap the AndCE with an OrCE lhs = types.OrPatternCE([lhs]) # then normalize lhs in a # form that has # all or inside the lhs reduced to # a single or at the top level of # the rule while _browseOr(lhs): continue # then compact all # (or (or # and # (and (and # as a single container while _compactPatterns(lhs): continue while _existsToNotNot(lhs): continue # then add a (initial-fact) # before (not or (test pattern # if they are first in the a group _initialFactNormalization(lhs, MM) return lhs
def test_NestedNotOrReversion(self): lhs = [ types.NotPatternCE( types.OrPatternCE([ "C", "D", types.AndPatternCE([ "Z", types.NotPatternCE(types.OrPatternCE(["W", "X"])) ]) ])) ] lhs = analysis.normalizeLHS(lhs, self.MM) self.assertIsInstance(lhs, types.OrPatternCE) permutations = [] for i in range(0, 4): self.assertIsInstance(lhs.patterns[i], types.AndPatternCE) self.assertIsInstance(lhs.patterns[i].patterns[1], types.NotPatternCE) if isinstance(lhs.patterns[i].patterns[1].pattern, types.AndPatternCE): permutations.append("~({0})".format(" ".join([ t if not isinstance(t, types.NotPatternCE) else "~" + t.pattern for t in lhs.patterns[i].patterns[1].pattern.patterns ]))) else: permutations.append("~" + lhs.patterns[i].patterns[1].pattern) permutationExpected = ["~C", "~D", "~(Z ~W)", "~(Z ~X)"] self.assertEqual(permutations, permutationExpected)
def _swapAndOr(And, AndParent, AndIndex): changed = False for index, inAndPattern in enumerate(And.patterns): if isinstance(inAndPattern, types.OrPatternCE): newOrPatterns = [] for orPattern in inAndPattern.patterns: #newOrPatterns = And.patterns[0:index] + [orPattern] + And.patterns[index+1:None] newOrPatterns.append(types.AndPatternCE(And.patterns[0:index] + [orPattern] + And.patterns[index+1:None])) newOr = types.OrPatternCE(newOrPatterns) if isinstance(AndParent, types.NotPatternCE): AndParent.pattern = newOr elif AndIndex is not None: AndParent[AndIndex] = newOr else: raise MyClipsBugException("Parent of And is not Not and no index is available") changed = True elif isinstance(inAndPattern, types.AndPatternCE): changed = _swapAndOr(inAndPattern, And.patterns, index) or changed elif isinstance(inAndPattern, types.NotPatternCE): changed = _swapNotOr(inAndPattern, And.patterns, index) or changed #if changed: # return changed return changed
def test_SimpleAndOrReversion(self): lhs = [types.AndPatternCE([types.OrPatternCE(["A", "B"]), "C"])] lhs = analysis.normalizeLHS(lhs, self.MM) self.assertIsInstance(lhs, types.OrPatternCE) self.assertIsInstance(lhs.patterns[0], types.AndPatternCE) self.assertIsInstance(lhs.patterns[1], types.AndPatternCE) self.assertEqual(lhs.patterns[0].patterns, ["A", "C"]) self.assertEqual(lhs.patterns[1].patterns, ["B", "C"])
def test_NccBetaCircuitNotPropagation(self): self.network.addRule(types.DefRuleConstruct("A", self.MM, lhs=[ types.OrderedPatternCE([ types.Symbol("A"), types.Symbol("B"), types.Symbol("C"), ], self.MM), types.NotPatternCE( types.AndPatternCE([ types.OrderedPatternCE([ types.Symbol("Z"), types.Symbol("Z"), types.Symbol("Z"), ], self.MM), types.OrderedPatternCE([ types.Symbol("W"), types.Symbol("W"), types.Symbol("W"), ], self.MM) ])) ])) trap = activationCatcher() (self.network._root.children[0] #MAIN .children[-1] #A .children[-1] #B .children[-1] #C .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #NCC ).prependChild(trap) self.network.assertFact(fact([types.Symbol("Z"), types.Symbol("Z"), types.Symbol("Z")])) self.network.assertFact(fact([types.Symbol("W"), types.Symbol("W"), types.Symbol("W")])) self.network.assertFact(fact([types.Symbol("A"), types.Symbol("B"), types.Symbol("C")])) self.assertFalse(trap.leftCatch)
def test_NccBetaCircuitCompilation(self): self.network.addRule(types.DefRuleConstruct("A", self.MM, lhs=[ types.OrderedPatternCE([ types.Symbol("A"), types.Symbol("B"), types.Symbol("C"), ], self.MM), types.NotPatternCE( types.AndPatternCE([ types.OrderedPatternCE([ types.Symbol("Z"), types.Symbol("Z"), types.Symbol("Z"), ], self.MM), types.OrderedPatternCE([ types.Symbol("W"), types.Symbol("W"), types.Symbol("W"), ], self.MM) ])) ])) # check main branch self.assertIsInstance(self.network._root .children[0] #MAIN .children[-1] #A .children[-1] #B .children[-1] #C .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #NCC , NccNode) # check partner branch self.assertIsInstance(self.network._root .children[0] #MAIN .children[-2] #Z .children[-1] #Z .children[-1] #Z .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #BETA .children[-1] #JOIN .children[-1] , NccPartnerNode) # check if nccPartner is linked to nccNode self.assertEqual(self.network._root .children[0] #MAIN .children[-2] #Z .children[-1] #Z .children[-1] #Z .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #BETA .children[-1] #JOIN .children[-1].nccNode , self.network._root .children[0] #MAIN .children[-1] #A .children[-1] #B .children[-1] #C .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #NCC ) # check if NccNode is linked to NccPartner self.assertEqual(self.network._root .children[0] #MAIN .children[-2] #Z .children[-1] #Z .children[-1] #Z .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1] #BETA .children[-1] #JOIN .children[-1] , self.network._root .children[0] #MAIN .children[-1] #A .children[-1] #B .children[-1] #C .children[-1] #LEN 3 .memory #AM .children[-1] #DUMMYJOIN .children[-1].partner )
@param declarations: list of rule properties parsed @type declasarions: list of RuleProperty @return: dict of (RuleProperty.name, RuleProperty.value) or None @rtype: dict|None """ return dict([(dec.propertyName, dec.propertyValue) for dec in declarations if isinstance(dec, types.RuleProperty)]) \ if len(declarations) > 0 \ else None if __name__ == '__main__': lhs = [types.OrPatternCE([ types.ExistsPatternCE(types.AndPatternCE(["A", "B"])), types.ExistsPatternCE("B") ])] import pprint from myclips.rete.Network import Network n = Network() lhs = normalizeLHS(lhs, n.modulesManager) pprint.pprint(lhs)