def perform_custom_join_test(self, token): # This is for CustomTestAtJoinNode: for this_test in self.custom_tests: DEBUG("custom test:", this_test) op = this_test.op wme1 = token.wmes[this_test.condition_number_of_arg1] arg1 = getattr(wme1, this_test.field_of_arg1) if hasattr(this_test, 'const'): arg2 = this_test.const else: DEBUG("token:", token) wme2 = token.wmes[this_test.condition_number_of_arg2] if wme2 is None: return True arg2 = getattr(wme2, this_test.field_of_arg2) if op == '!=': if arg1 == arg2: return False if op == '>': if arg1 <= arg2: return False if op == '<': if arg1 >= arg2: return False if op == 'π0': if arg1[0] != arg2: return False if op == 'π1': if arg1[1] != arg2: return False return True
def perform_join_test(self, token, wme): """ :type token: rete.Token :type wme: rete.WME """ DEBUG("join test, token=", token) for this_test in self.tests: DEBUG("test:", this_test) # This is for ordinary TestAtJoinNode: arg1 = getattr(wme, this_test.field_of_arg1) wme2 = token.wmes[this_test.condition_number_of_arg2] if wme2 is not None: arg2 = getattr(wme2, this_test.field_of_arg2) if arg1 != arg2: return False return True
def left_activation(self, token, wme, binding=None): """ :type wme: WME :type token: Token :type binding: dict """ new_token = Token(token, wme, node=self, binding=binding) self.items.append(new_token) DEBUG("**** firing %s\n" % new_token)
def left_activation(self, t, w, binding=None): """ :type w: rete.WME :type t: rete.Token :type binding: dict """ DEBUG("NCC left-activate, wme = ", w) new_token = Token(t, w, self, binding) self.items.append(new_token) new_token.ncc_results = [] DEBUG("NCC node.items add token = ", new_token) for result in self.partner.new_result_buffer: self.partner.new_result_buffer.remove(result) result.owner = new_token new_token.ncc_results.append(result) DEBUG(" add to ncc_results: ", result) if not new_token.ncc_results: # if results == [] for child in self.children: child.left_activation(new_token, None)
def left_activation(self, t, w, binding=None): """ :type w: rete.WME :type t: rete.Token :type binding: dict """ DEBUG("NCC partner left-activate, wme = ", w) new_result = Token(t, w, self, binding) owners_t = t owners_w = w for i in range(self.number_of_conditions): owners_w = owners_t.wme owners_t = owners_t.parent found = False for token in self.ncc_node.items: if token.parent == owners_t and token.wme == owners_w: DEBUG(" partner add to ncc_results: ", new_result) new_result.owner = token token.ncc_results.append(new_result) Token.delete_descendents_of_token(token) found = True if not found: # new_result.owner = 'buffed' self.new_result_buffer.append(new_result)
def activation(self, wme): """ :type wme: rete.WME """ DEBUG("⍺ activate: wme=%s" % wme) if self.field_to_test != 'no-test': v = getattr(wme, self.field_to_test) v2 = self.thing_the_field_must_equal # if v2 and v2[0] == 'F': # v2 = getattr(wme, v2) # print "%s =? %s" % (v, v2) if v != v2: return False # failed the test; don't propagate any further if self.amem: self.amem.activation(wme) for child in self.children: child.activation(wme)
def right_activation(self, wme): """ :type wme: rete.WME """ # The Join Nodes with CustomTests will never be right-activated # Because they have no proper "conditions" (Has). if hasattr(self, 'custom_tests'): DEBUG("This should be an error") # DEBUG(self, "right-activation:") # DEBUG("wme =", wme) for token in self.parent.items: # DEBUG("token=", token) if self.perform_join_test(token, wme): binding = self.make_binding(wme) for child in self.children: child.left_activation(token, wme, binding)
q = net.add_production(Rule(Has('□', '$x'))) q.postcondition = Has("random_play", '$x') q.truth = 0.4 p.append(q) # [note to myself: # Solved: The problem here is that the π1(x,1) proposition needs to # be checked for x != y, but it has no "Has" representation. # Now the problem is a "None" token passed down to the Join Node. # Why is it None?] f = open("rete.dot", "w+") f.write(net.dump()) f.close() os.system("dot -Tpng rete.dot -orete.png") DEBUG("\nRete graph saved as rete.png\n") # **** Background knowledge **** net.add_wme(WME('diag', (0, 0))) net.add_wme(WME('diag', (1, 1))) net.add_wme(WME('diag', (2, 2))) net.add_wme(WME('back_diag', (0, 2))) net.add_wme(WME('back_diag', (1, 1))) net.add_wme(WME('back_diag', (2, 0))) def show_board(board): for i in [0, 3, 6]: for j in range(3): x = board[i + j] if x == -1:
def playGames(population): from GUI import draw_board global board win = draw = stall = lose = 0 # Add rules to Rete rete_net = Network() for candidate in population: p = add_rule_to_Rete(rete_net, candidate['rule']) if p: print('●', print_rule(candidate['rule']), end='\n') # print(' (%d)' % length_of_rule(candidate['rule'])) candidate['p_node'] = p # save_Rete_graph(rete_net, 'rete_0') for n in range(1000): # play game N times print("\t\tGame ", n, end='\r') # Initialize board for i in [0, 1, 2]: for j in [0, 1, 2]: if board[i][j] != ' ': rete_net.remove_wme(WME(board[i][i], str(i), str(j))) rete_net.add_wme(WME(' ', str(i), str(j))) board[i][j] = ' ' CurrentPlayer = 'X' # In the future, may play against self moves = [] # for recording played moves for move in range(9): # Repeat playing moves in single game # print(" move", move, end='; ') if CurrentPlayer == 'X': # collect all playable rules playable = [] for candidate in population: p0 = candidate['p_node'] if not p0: continue if p0.items: DEBUG(len(p0.items), " instances") for item in p0.items: # item = random.choice(p0.items) # choose an instantiation randomly # Question: are all instances the same? # apply binding to rule's action (ie, post-condition) if is_var(p0.postcondition.F2): p0.postcondition.F2 = item.get_binding(p0.postcondition.F2) if p0.postcondition.F2 is None: p0.postcondition.F2 = str(random.randint(0,2)) if is_var(p0.postcondition.F3): p0.postcondition.F3 = item.get_binding(p0.postcondition.F3) if p0.postcondition.F3 is None: p0.postcondition.F3 = str(random.randint(0,2)) DEBUG("production rule = ", print_rule(candidate['rule'])) DEBUG("chosen item = ", item) DEBUG("postcond = ", p0.postcondition) # Check if the square is empty x = int(p0.postcondition.F2) y = int(p0.postcondition.F3) if board[x][y] == ' ': playable.append(candidate) candidate['fitness'] += 1.0 else: candidate['fitness'] -= 1.0 # print(len(playable), "playable rules ", end='') uniques = [] for candidate in playable: if not uniques: uniques.append(candidate) continue exists = False for u in uniques: if candidate['p_node'].postcondition == u['p_node'].postcondition: exists = True if not exists: uniques.append(candidate) # print("; unique moves =\x1b[31;1m", len(uniques), end='\x1b[0m\n') if not uniques: # print("No rules playable") stall += 1 break # next game # Choose a playable rule randomly candidate = random.choice(uniques) p0 = candidate['p_node'] x = int(p0.postcondition.F2) y = int(p0.postcondition.F3) board[x][y] = CurrentPlayer # print(" played move: X(%d,%d)" % (x,y)) # remove old WME rete_net.remove_wme(WME(' ', p0.postcondition.F2, p0.postcondition.F3)) # add new WME rete_net.add_wme(WME(CurrentPlayer, p0.postcondition.F2, p0.postcondition.F3)) # **** record move: record the rule that is fired moves.append(candidate) else: # Player = 'O' i,j = opponentPlay() board[i][j] = 'O' # print("Opponent move: O(%d,%d)" % (i,j)) # remove old WME rete_net.remove_wme(WME(' ', str(i), str(j))) # add new WME rete_net.add_wme(WME('O', str(i), str(j))) # printBoard() # this is text mode draw_board(board) # graphics mode # check if win / lose, assign rewards accordingly winner = hasWinner() if winner == ' ': # let the same set of rules play again # let opponent play (opponent = self? this may be implemented later) CurrentPlayer = 'O' if CurrentPlayer == 'X' else 'X' elif winner == '-': # increase the scores of all played moves by 3.0 for candidate in moves: candidate['fitness'] += 3.0 # print("Draw") draw += 1 break # next game elif winner == 'X': # increase the scores of all played moves by 10.0 for candidate in moves: candidate['fitness'] += 10.0 # print("X wins") win += 1 break # next game elif winner == 'O': # decrease the scores of all played moves by 8.0 for candidate in moves: candidate['fitness'] -= 8.0 # print("O wins") lose += 1 break # next game return win, draw, stall, lose