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 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 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 _swapNotOr(Not, NotParent, NotIndex): # not arg is a single subpattern # it could be another and/or/not or an # ordered/template # (not (or must be converted to (or (not (not # (not (and (or must be converted to (or (not (and changed = False if isinstance(Not.pattern, types.OrPatternCE): # need to start a new browseOr here # before make reversions while _browseOr(Not.pattern): changed = True # then reverse (not (or with (or (not reversedOrArguments = [] for inOrPattern in Not.pattern.patterns: reversedOrArguments.append(types.NotPatternCE(inOrPattern)) # then replace the main Not arg with the new Or ([Not, Not,..]) NotParent[NotIndex] = types.OrPatternCE(reversedOrArguments) changed = True elif isinstance(Not.pattern, types.AndPatternCE): # if found an (not (and (??? # status, i need to try to reverse # all (and (or in the changed = _swapAndOr(Not.pattern, Not, None) or changed return changed
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_NetworkPlotting_DefRuleWithOrClause(self): self.network.addRule( types.DefRuleConstruct( "A", self.MM, lhs=[ types.OrPatternCE([ types.OrderedPatternCE([ types.Symbol("A"), types.SingleFieldVariable(types.Symbol("varA")), types.Symbol("C"), ], self.MM), types.OrderedPatternCE([ types.SingleFieldVariable(types.Symbol("varA")), types.Symbol("A"), types.Symbol("C"), ], self.MM) ]) ])) # manually fire the network ready event self.network.eventsManager.fire(EventsManager.E_NETWORK_READY, self.network) self.network.eventsManager.fire(EventsManager.E_NETWORK_SHUTDOWN, self.network)
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_SimpleNotOrReversion(self): lhs = [types.NotPatternCE(types.OrPatternCE(["C", "D"]))] lhs = analysis.normalizeLHS(lhs, self.MM) self.assertIsInstance(lhs, types.OrPatternCE) permutations = [] for i in range(0, 2): self.assertIsInstance(lhs.patterns[i], types.AndPatternCE) self.assertIsInstance(lhs.patterns[i].patterns[1], types.NotPatternCE) permutations.append(lhs.patterns[i].patterns[1].pattern) permutationExpected = ["C", "D"] self.assertEqual(permutations, permutationExpected)
@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)