def test__test(self): for i, (cond, obj, exp) in enumerate([ (Has('$x', 'color', 'red'), WME('B1', 'color', 'red'), True), (Has('$x', 'color', 'red'), WME('B1', 'color', 'blue'), False), ]): with self.subTest(i=i, cond=cond, obj=obj, exp=exp): result = cond.match(obj) assert_that(result, 'test').is_equal_to(exp)
def activation(self, wme: WME) -> None: """ :param wme: the activation WME """ if wme not in self.memory: self._memory.append(wme) wme.add_amem(self) for child in reversed(self._children): child.right_activation(wme)
def test__integration(self): for i, (rule, wmes, exp_len, var, exp_val) in enumerate([ (Rule(Has('spu:1', 'price', '$x'), Filter('$x>100'), Filter('$x<200')), [WME('spu:1', 'price', '100'), WME('spu:1', 'price', '150'), WME('spu:1', 'price', '300')], 1, '$x', '150'), (Rule(Has('spu:1', 'price', '$x'), Filter('$x>200 and $x<400')), [WME('spu:1', 'price', '100'), WME('spu:1', 'price', '150'), WME('spu:1', 'price', '300')], 1, '$x', '300'), (Rule(Has('spu:1', 'price', '$x'), Filter('$x>300')), [WME('spu:1', 'price', '100'), WME('spu:1', 'price', '150'), WME('spu:1', 'price', '300')], 0, None, None), ]): with self.subTest(i=i, exp_len=exp_len, var=var, exp_val=exp_val): network = Network() production = network.add_production(rule) for wme in wmes: network.add_wme(wme) assert_that(production.memory, 'filter').is_length(exp_len) if production.memory: token = production.memory[0] assert_that(token.get_binding(var), 'filter').is_equal_to(exp_val)
def test_ncc(): net = Network() c0 = Has('$x', 'on', '$y') c1 = Has('$y', 'left-of', '$z') c2 = Neg('$z', 'color', 'red') # YKY: allowed to have Neg inside Ncc c3 = Has('$z', 'on', '$w') p0 = net.add_production(Rule(c0, c1, Ncc(c2, c3))) save_Rete_graph(net, 'rete-0') wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), ] for wme in wmes: net.add_wme(wme) print("# of results [2] = ", len(p0.items)) # assert len(p0.items) == 2 net.add_wme(WME('B3', 'color', 'red')) print("# of results [1] = ", len(p0.items))
def test__case_1(self): for i, (rule, wmes, exp) in enumerate([(Rule( Has('$x', 'on', '$y'), Has('$y', 'left-of', '$z'), Has('$z', 'color', 'red'), ), [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), WME('B3', 'color', 'red') ], [])]): with self.subTest(i=i, rule=rule, wmes=wmes, exp=exp): network = Network() production = network.add_production(rule) am0 = network.build_or_share_alpha_memory(rule[0]) am1 = network.build_or_share_alpha_memory(rule[1]) am2 = network.build_or_share_alpha_memory(rule[2]) dummy_join = am0.children[0] join_on_value_y = am1.children[0] join_on_value_z = am2.children[0] match_c0 = dummy_join.children[0] match_c0c1 = join_on_value_y.children[0] match_c0c1c2 = join_on_value_z.children[0] for wme in wmes: network.add_wme(wme) assert am0.memory == [wmes[0], wmes[1], wmes[3], wmes[7]] assert am1.memory == [wmes[4], wmes[6]] assert am2.memory == [wmes[2], wmes[8]] assert len(match_c0.memory) == 4 assert len(match_c0c1.memory) == 2 assert len(match_c0c1c2.memory) == 1 t0 = Token(Token(None, None), wmes[0]) t1 = Token(t0, wmes[4]) t2 = Token(t1, wmes[8]) assert match_c0c1c2.memory[0] == t2 network.remove_wme(wmes[0]) assert am0.memory == [wmes[1], wmes[3], wmes[7]] assert len(match_c0.memory) == 3 assert len(match_c0c1.memory) == 1 assert len(match_c0c1c2.memory) == 0
def test_all_constants_the_same_should_not_match(): net = Network() c0 = Has('foo', 'foo', 'foo') p0 = net.add_production(Rule(c0)) net.add_wme(WME('bar', 'foo', 'foo')) assert len(p0.items) == 0
def test_add_wme(): root = ConstantTestNode('no-test') am1 = ConstantTestNode.build_or_share_alpha_memory(root, [('F2', 'on')]) am2 = ConstantTestNode.build_or_share_alpha_memory(root, [('F2', 'on'), ('F3', 'table')]) root.activation(WME('x', 'on', 'table')) assert len(am1.items) == 1 assert len(am2.items) == 1
def test_recurring_vars_should_not_match(): net = Network() c0 = Has('foo', '$x', '$x') p0 = net.add_production(Rule(c0)) net.add_wme(WME('foo', 'bar', 'baz')) assert len(p0.items) == 0
def test_network_case1(): # setup net = Network() c0 = Has('$x', 'on', '$y') c1 = Has('$y', 'left-of', '$z') c2 = Has('$z', 'color', 'red') net.add_production(Rule(c0, c1, c2)) # end am0 = net.build_or_share_alpha_memory(c0) am1 = net.build_or_share_alpha_memory(c1) am2 = net.build_or_share_alpha_memory(c2) dummy_join = am0.successors[0] join_on_value_y = am1.successors[0] join_on_value_z = am2.successors[0] match_c0 = dummy_join.children[0] match_c0c1 = join_on_value_y.children[0] match_c0c1c2 = join_on_value_z.children[0] wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), WME('B3', 'color', 'red') ] for wme in wmes: net.add_wme(wme) assert am0.items == [wmes[0], wmes[1], wmes[3], wmes[7]] assert am1.items == [wmes[4], wmes[6]] assert am2.items == [wmes[2], wmes[8]] assert len(match_c0.items) == 4 assert len(match_c0c1.items) == 2 assert len(match_c0c1c2.items) == 1 t0 = Token(Token(None, None), wmes[0]) t1 = Token(t0, wmes[4]) t2 = Token(t1, wmes[8]) assert match_c0c1c2.items[0] == t2 net.remove_wme(wmes[0]) assert am0.items == [wmes[1], wmes[3], wmes[7]] assert len(match_c0.items) == 3 assert len(match_c0c1.items) == 1 assert len(match_c0c1c2.items) == 0
def add_wmes(): net = init_network() wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), WME('B3', 'color', 'red') ] for wme in wmes: net.add_wme(wme)
def test__case_0(self): for i, (rule, wmes, exp) in enumerate([ (Rule(Has('x', 'id', '1'), Has('x', 'kind', '8')), [WME('x', 'id', '1')], 0), (Rule(Has('x', 'id', '1'), Has('x', 'kind', '8')), [WME('x', 'kind', '8')], 0), (Rule(Has('x', 'id', '1'), Has('x', 'kind', '8')), [WME('x', 'id', '1'), WME('x', 'kind', '8')], 1), ]): with self.subTest(i=i, rule=rule, wmes=wmes, exp=exp): network = Network() production = network.add_production(rule) for wme in wmes: network.add_wme(wme) result = len(production.memory) assert_that(result, 'case 0').is_equal_to(exp)
def test_network_case0(): net = Network() c0 = Has('x', 'id', '1') c1 = Has('x', 'kind', '8') p0 = net.add_production(Rule(c0, c1)) w0 = WME('x', 'id', '1') w1 = WME('x', 'kind', '8') net.add_wme(w0) assert not p0.items net.remove_wme(w0) net.add_wme(w1) assert not p0.items net.add_wme(w0) net.add_wme(w1) assert p0.items
def test_add_wme(self): root = ConstantTestNode('no-test') am1 = ConstantTestNode.build_or_share_alpha_memory( root, [('attribute', 'on')]) am2 = ConstantTestNode.build_or_share_alpha_memory( root, [('attribute', 'on'), ('value', 'table')]) root.activation(WME('x', 'on', 'table')) assert_that(len(am1.memory), 'add_wme').is_equal_to(1) assert_that(len(am2.memory), 'add_wme').is_equal_to(1)
def test_multiple_conditions_should_not_match(): net = Network() c0 = Has('foo', '$x', '$y') c1 = Has('foo', '$x', '$x') c2 = Has('$x', '$y', 'baz') p0 = net.add_production(Rule(c0, c1, c2)) net.add_wme(WME('foo', 'bar', 'baz')) assert len(p0.items) == 0
def test_dup(): # setup net = Network() c0 = Has('$x', 'self', '$y') c1 = Has('$x', 'color', 'red') c2 = Has('$y', 'color', 'red') net.add_production(Rule(c0, c1, c2)) wmes = [ WME('B1', 'self', 'B1'), WME('B1', 'color', 'red'), ] for wme in wmes: net.add_wme(wme) # end am = net.build_or_share_alpha_memory(c2) join_on_value_y = am.successors[1] match_for_all = join_on_value_y.children[0] assert len(match_for_all.items) == 1
def test_multiple_conditions_all_variables_should_match_one(): net = Network() c0 = Has('foo', 'foo', 'foo') c1 = Has('$x', '$x', '$x') c2 = Has('$x', 'foo', 'foo') c3 = Has('foo', '$x', 'foo') c4 = Has('$x', 'foo', '$x') p0 = net.add_production(Rule(c0, c1, c2, c3, c4)) net.add_wme(WME('foo', 'foo', 'foo')) assert len(p0.items) == 1
def test_filter_compare(): net = Network() c0 = Has('spu:1', 'price', '$x') f0 = Filter('$x>100') f1 = Filter('$x<200') f2 = Filter('$x>200 and $x<400') f3 = Filter('$x>300') p0 = net.add_production(Rule(c0, f0, f1)) p1 = net.add_production(Rule(c0, f2)) p2 = net.add_production(Rule(c0, f3)) net.add_wme(WME('spu:1', 'price', '100')) net.add_wme(WME('spu:1', 'price', '150')) net.add_wme(WME('spu:1', 'price', '300')) assert len(p0.items) == 1 token = p0.items.pop() assert token.get_binding('$x') == '150' assert len(p1.items) == 1 token = p1.items.pop() assert token.get_binding('$x') == '300' assert not p2.items
def test_black_white(): net = Network() c1 = Has('$item', 'cat', '$cid') c2 = Has('$item', 'shop', '$sid') white = Ncc( Has('$item', 'cat', '100'), Neg('$item', 'cat', '101'), Neg('$item', 'cat', '102'), ) n1 = Neg('$item', 'shop', '1') n2 = Neg('$item', 'shop', '2') n3 = Neg('$item', 'shop', '3') p0 = net.add_production(Rule(c1, c2, white, n1, n2, n3)) wmes = [ WME('item:1', 'cat', '101'), WME('item:1', 'shop', '4'), WME('item:2', 'cat', '100'), WME('item:2', 'shop', '1'), ] for wme in wmes: net.add_wme(wme) assert len(p0.items) == 1 assert p0.items[0].get_binding('$item') == 'item:1'
def test_ncc(): net = Network() c0 = Has('$x', 'on', '$y') c1 = Has('$y', 'left-of', '$z') c2 = Has('$z', 'color', 'red') c3 = Has('$z', 'on', '$w') p0 = net.add_production(Rule(c0, c1, Ncc(c2, c3))) wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), ] for wme in wmes: net.add_wme(wme) assert len(p0.items) == 2 net.add_wme(WME('B3', 'color', 'red')) assert len(p0.items) == 1
def test_multi_productions(): net = Network() c0 = Has('$x', 'on', '$y') c1 = Has('$y', 'left-of', '$z') c2 = Has('$z', 'color', 'red') c3 = Has('$z', 'on', 'table') c4 = Has('$z', 'left-of', 'B4') p0 = net.add_production(Rule(c0, c1, c2)) p1 = net.add_production(Rule(c0, c1, c3, c4)) wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), WME('B3', 'color', 'red'), ] for wme in wmes: net.add_wme(wme) # add product on the fly p2 = net.add_production(Rule(c0, c1, c3, c2)) assert len(p0.items) == 1 assert len(p1.items) == 1 assert len(p2.items) == 1 assert p0.items[0].wmes == [wmes[0], wmes[4], wmes[8]] assert p1.items[0].wmes == [wmes[0], wmes[4], wmes[7], wmes[6]] assert p2.items[0].wmes == [wmes[0], wmes[4], wmes[7], wmes[8]] net.remove_production(p2) assert len(p2.items) == 0
def test_bind(): net = Network() c0 = Has('spu:1', 'sales', '$x') b0 = Bind('len(set($x) & set(range(1, 100)))', '$num') f0 = Filter('$num > 0') p0 = net.add_production(Rule(c0, b0, f0)) b1 = Bind('len(set($x) & set(range(100, 200)))', '$num') p1 = net.add_production(Rule(c0, b1, f0)) b2 = Bind('len(set($x) & set(range(300, 400)))', '$num') p2 = net.add_production(Rule(c0, b2, f0)) net.add_wme(WME('spu:1', 'sales', 'range(50, 110)')) assert len(p0.items) == 1 assert len(p1.items) == 1 assert len(p2.items) == 0 t0 = p0.items[0] t1 = p1.items[0] assert t0.get_binding('$num') == 50 assert t1.get_binding('$num') == 10
net = Network() c1 = Has('male', '$a') c2 = Has('love', '$a', '$b') c3 = Has('female', '$b') # net.add_production(Rule(Ncc(c1, Ncc(c2, c3)))) # net.add_production(Rule(Ncc(c2, Ncc(c3)))) # net.add_production(Rule(c1, Ncc(c2))) # net.add_production(Rule(c1, Ncc(c2, c3))) # net.add_production(Rule(c2, c3)) p0 = net.add_production(Rule(c3, Ncc(c2, c1))) wmes = [ WME('female', 'Mary'), WME('female', 'Ann'), WME('love', 'John', 'Pete'), # 基 WME('love', 'John', 'John'), # 自恋 WME('love', 'Pete', 'Mary'), # 所谓正常 WME('love', 'Pete', 'John'), # 互基 WME('love', 'Mary', 'Ann'), # Lesbian WME('male', 'John'), WME('male', 'Pete'), ] for wme in wmes: net.add_wme(wme) print("# of results = ", len(p0.items)) print("Results:") for i in p0.items:
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
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: c = '❌' elif x == 1: c = '⭕'
def test_neg(): # setup net = Network() c0 = Has('$x', 'on', '$y') c1 = Has('$y', 'left-of', '$z') c2 = Neg('$z', 'color', 'red') p0 = net.add_production(Rule(c0, c1, c2)) # end wmes = [ WME('B1', 'on', 'B2'), WME('B1', 'on', 'B3'), WME('B1', 'color', 'red'), WME('B2', 'on', 'table'), WME('B2', 'left-of', 'B3'), WME('B2', 'color', 'blue'), WME('B3', 'left-of', 'B4'), WME('B3', 'on', 'table'), WME('B3', 'color', 'red'), # WME('B4', 'color', 'blue'), ] for wme in wmes: net.add_wme(wme) assert p0.items[0].wmes == [ WME('B1', 'on', 'B3'), WME('B3', 'left-of', 'B4'), None ]
def playGames(population): global board, moves, rete_net win = draw = stall = lose = 0 # Add rules to Rete rete_net = Network() # print("\x1b[43m-----------------------------------------------\x1b[0m") 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("\r\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': if play_1_move(population, CurrentPlayer): # Stalled? stall += 1 break # game-over, next game 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 # new_GUI.draw_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
def play_1_move(population, CurrentPlayer): global moves # **** Part A: pure INFERENCE step(s) **** i_infer = 0 max_infer = 3 while i_infer < max_infer: i_infer += 1 for candidate in population: p0 = candidate['p_node'] # a p-node seems to be the "results" node if not p0: continue if p0.items: DEBUG(len(p0.items), "instances") for item in p0.items: # **** Previously I assumed postcond = X = action # **** But now postcond can be a predicate P_i head = p0.postcondition.F0 DEBUG("the head=", head) if head[0] == 'P': DEBUG("production rule =", print_rule(candidate['rule'])) DEBUG("chosen item =", item) DEBUG("postcond =", p0.postcondition) # Question: are all instances the same? # apply binding to rule's action (ie, post-condition) if is_var(p0.postcondition.F1): p0.postcondition.F1 = item.get_binding( p0.postcondition.F1) if p0.postcondition.F1 is None: p0.postcondition.F1 = str(randint(0, 2)) 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(randint(0, 2)) DEBUG("postcond =", p0.postcondition, "<-- after binding") # **** Add to Working Memory: rete_net.add_wme( WME(head, p0.postcondition.F1, p0.postcondition.F2)) # input("added proposition to WM...") # pause continue # continue to next instantiation... # **** Part B: action step **** # 1) collect all playable rules playable = [] for candidate in population: p0 = candidate['p_node'] # a p-node seems to be the "results" node if not p0: continue if p0.items: DEBUG(len(p0.items), "instances") for item in p0.items: head = p0.postcondition.F0 if head[0] != 'P': # **** Here, the post-cond must be an ACTION **** DEBUG("production rule =", print_rule(candidate['rule'])) DEBUG("chosen item =", item) DEBUG("postcond =", p0.postcondition) # item = 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.F1): p0.postcondition.F1 = item.get_binding(p0.postcondition.F1) if p0.postcondition.F1 is None: p0.postcondition.F1 = str(randint(0, 2)) 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(randint(0, 2)) DEBUG("postcond =", p0.postcondition, "<-- after binding") # Check if the square is empty x = int(p0.postcondition.F1) y = int(p0.postcondition.F2) if board[x][y] == ' ': playable.append(candidate) # append to 'playable' list candidate['fitness'] += 1.0 else: candidate['fitness'] -= 1.0 # **** Randomly choose 1 playable move and play it **** # 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") return True # next game # 2) Choose a playable rule randomly candidate = choice(uniques) p0 = candidate['p_node'] x = int(p0.postcondition.F1) y = int(p0.postcondition.F2) board[x][y] = CurrentPlayer # print(" played move: X(%d,%d)" % (x,y)) # remove old WME rete_net.remove_wme(WME(' ', p0.postcondition.F1, p0.postcondition.F2)) # add new WME rete_net.add_wme( WME(CurrentPlayer, p0.postcondition.F1, p0.postcondition.F2)) # **** record move: record the rule that is fired moves.append(candidate) return False
def test__integration(self): for i, (rule, wmes, exp_len, var, exp_val) in enumerate([ (Rule(Has('spu:1', 'sales', '$x'), Bind('len(set($x) & set(range(1, 100)))', '$num'), Filter('$num > 0')),[WME('spu:1', 'sales', 'range(50, 110)')], 1, '$num', 50), (Rule(Has('spu:1', 'sales', '$x'), Bind('len(set($x) & set(range(100, 200)))', '$num'), Filter('$num > 0')),[WME('spu:1', 'sales', 'range(50, 110)')], 1, '$num', 10), (Rule(Has('spu:1', 'sales', '$x'), Bind('len(set($x) & set(range(300, 400)))', '$num'), Filter('$num > 0')),[WME('spu:1', 'sales', 'range(50, 110)')], 0, None, None), ]): with self.subTest(i=i, exp_len=exp_len, var=var, exp_val=exp_val): network = Network() production = network.add_production(rule) for wme in wmes: network.add_wme(wme) assert_that(production.memory, 'filter').is_length(exp_len) if production.memory: token = production.memory[0] assert_that(token.get_binding(var), 'filter').is_equal_to(exp_val)
def test_condition_test(): c0 = Has('$x', 'color', 'red') w0 = WME('B1', 'color', 'red') w1 = WME('B1', 'color', 'blue') assert c0.test(w0) assert not c0.test(w1)
if x == -1: c = '❌' elif x == 1: c = '⭕' else: c = ' ' print(c, end='') print(end='\n') board = 9 * [0] # ⭕ ❌ # ⭕❌⭕ # ❌⭕ wmes = [ WME('X', 0, 2), WME('X', 1, 1), WME('X', 2, 1), WME('O', 0, 0), WME('O', 1, 0), WME('O', 1, 2), WME('O', 2, 2), WME('□', 0, 1), WME('□', 2, 0), ] for wme in wmes: net.add_wme(wme) if wme.F0 == 'X': x = -1 elif wme.F0 == 'O': x = 1