def leftActivation(self, token, wme): """ Get a token + wme that pass all binding tests from leftParent node (JoinNode), combine this values as a new Token, store it in the local storage and forward the activation to children Token could be None if the leftParent is a DummyNode. @param wme: a wme that activate this node @type wme: myclips.rete.WME @param token: a token @type token: myclips.Token | None """ if wme is not None and not isinstance(wme, WME): raise MyClipsBugException( "BetaMemory activated with a non-WME item: <%s:%s>" % (wme.__class__.__name__, wme)) if token is not None and not isinstance(token, Token): raise MyClipsBugException( "BetaMemory activated with a non-Token item: <%s:%s>" % (wme.__class__.__name__, wme)) # create a new token to combine the token + wme token = Token(self, token, wme) # store it in the local storage self.addItem(token) # then: propagate the new token to # all children (JoinNode/NegativeNode/etcetc...) for child in self.children: child.leftActivation(token, None)
def leftActivation(self, token, wme): """ Left activation for Negative join node: when a new token + wme come from a previous JoinNode, left activation try to combine the new token<token,wme> with all wme in right memory and if no match is found then token<token, wme> is propagated (tnx to no match) Otherwise for every match, a negative join result is created and linked to token and wme. no propagation will ever be place until all njr aren't gone """ # create a new token here # this is important because on future # negative join result creation # i will delete all children of # this new token to invalidate all # propagated match # i can reuse token variable, after this # old token is no usefull anymore token = Token(self, token, wme) # store the token inside the memory self.addItem(token) # now i need to check and combine # the newToken with all results # that comes from the alpha memory on the # right side of the node # i can reuse wme variable because old value # is useless after the newToken creation for wme in self.rightParent.items: if self.isValid(token, wme): # for each match i create a NegativeJoinResult # to store the info NegativeJoinResult(token, wme) # it's automatically linked inside token and wme # after i tried to combine the token with all wme # i check if negative join results has been created if not token.hasNegativeJoinResults(): # not negative join result: nice... i can propagate for child in self.children: child.leftActivation(token, None)
def leftActivation(self, token, wme): # combine match in new token token = Token(self, token, wme) # store it inside the local memory self.addItem(token) # get the token stored in the partner node # (getFlushBuffer automatically flush the buffer) for pToken in self.partner.getFlushResultsBuffer(): # and link them to this token as ncc result # (and link this token as their nccOnwer: # this is done automaticcaly inside the # linkNccResult method # ) token.linkNccResult(pToken) # i can propagate the token ONLY if # not ncc results are linked to this token if not token.hasNccResults(): for child in self.children: child.leftActivation(token, None)
def rightActivation(self, wme): """ Check new fact activation: if something is activated by the new wme, all activations from this node are retracted """ wme.linkExistsNode(self) self._existsCount += 1 if self._existsCount == 1: for token in self.leftParent.items: token = Token(self, token, None) self.addItem(token) for child in self.children: child.leftActivation(token, None)
def rightActivation(self, wme): leftItems = [] # check if this is not a dummy node if self.isLeftRoot(): # or not isinstance(self.leftParent, Memory): leftItems = [Token(None, None, None)] else: # left parent is a Memory or a subclass of Memory leftItems = self.leftParent.items #leftParent is a Memory or has Memory properties for token in leftItems: if self.isValid(token, wme): # join test is valid for token + wme # create new token and propagate for child in self.children: child.leftActivation(token, wme)
def leftActivation(self, token, _): """ Left activation for Negative join node: when a new token + wme come from a previous JoinNode, left activation try to combine the new token<token,wme> with all wme in right memory and if no match is found then token<token, wme> is propagated (tnx to no match) Otherwise for every match, a negative join result is created and linked to token and wme. no propagation will ever be place until all njr aren't gone """ if self._existsCount > 0: token = Token(self, token, None) # store the token inside the memory self.addItem(token) for child in self.children: child.leftActivation(token, None)
def leftActivation(self, token, wme): """ Left activation for ncc-parnet: create a new token and store it in the buffer (if no match with token in the ncc main node is found) or add a new nccresult and destroy propagated tokens if there is a match """ # basically ncc-partner does 3 things: # 1) build a new token and link it to this node # 2) check if the new token match with token in # main ncc node memory # 3a) store a new ncc result if match found and revoke # all activation from that token # 3b) store the new token in the buffer and wait # for ncc main node to be activated and # evaluate token in buffer # 1) nToken = Token(self, token, wme) # 2) problem 1: ncc and ncc-partner have a common # parent: the node who feed them both. # this means that i need to compare the new token # agains a token in the ncc main memory # that has same parent. To make this comparison # possible i have to get the token that # create the activation of the ncc circuit. # I can use the circuitLenght property for this parentToken = token parentWme = wme for _ in range(0, self._circuitLength): parentWme = parentToken.wme parentToken = parentToken.parent # 2) problem 2: new i need to scan all the ncc main memory # and find a token with the same parent token and wme for mToken in self.nccNode.items: # optimization: puth wme comparison first because is # faster then token comparison if mToken.wme == parentWme and mToken.parent == parentToken: # 3a) # I found a token who match both circuits # this is a new ncc result # so it's time to link it mToken.linkNccResult(nToken) # nToken owner is set by the linkNccResult automatically # i need to destroy all children of the # mToken because they are revocated now mToken.deleteChildren() # the function end on first match: # - there is no reason to keep scanning the main ncc memory # because only one match can be found # - there is no reason to stay in this method, no need to # to store the nToken in the buffer. It's has been just evaluated return # 3b) # if no match has been found in the for loop # means that: # - there is no match at all # OR # - there is a match, but it will in the future # when ncc main node will be left-activated. # Anyway, i need to store the partial match in the buffer # when main node will be activated, it will read and flush the buffer self._buffer.append(nToken)
def leftActivation(self, token, wme): #myclips.logger.debug("FIXME: PNode left activation NIY. token=%s, wme=%s", token, wme) newToken = Token(self, token, wme) self.addItem(newToken) self._network.agenda.insert(self, newToken)