def test_call_returns_empty_numdict_when_no_rules_exist(self): rules = Rules(max_conds=1) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } action_rules = ActionRules( source=chunks(1), rules=rules, temperature=1 # high temperature to ensure variety ) strengths = action_rules.call(inputs) self.assertEqual(len(strengths), 0, msg="Unexpected items in output.")
# We set up default action activations, as in `flow_control.py`. default_strengths = nd.MutableNumDict(default=0) default_strengths.extend(wm_interface.defaults, speech_interface.defaults, value=0.5) # As in `chunk_extraction.py`, we construct a chunk database to store chunks. nacs_cdb = Chunks() # We then manually populate the database with chunks representing the fruits # that alice discovered in `chunk_extraction.py`. nacs_cdb.define(chunk("APPLE"), feature("word", "/apple/"), feature("color", "red"), feature("shape", "round"), feature("size", "medium"), feature("texture", "smooth")) nacs_cdb.define(chunk("ORANGE"), feature("word", "/orange/"), feature("color", "orange"), feature("shape", "round"), feature("size", "medium"), feature("texture", "grainy")) nacs_cdb.define(chunk("BANANA"), feature("word", "/banana/"), feature("color", "yellow"), feature("shape", "oblong"), feature("size", "medium"), feature("texture", "spotty")) nacs_cdb.define(chunk("PLUM"), feature("word", "/plum/"), feature("color", "purple"), feature("shape", "round"), feature("size", "small"), feature("texture", "smooth"))
def test_goal_buffer_push(self): # TODO: Add assertions... interface = GoalStay.Interface(name="gctl", goals=(feature("goal", "select"), feature("goal", "analyze"), feature("goal", "evaluate"), feature("gobj", "attribute"), feature("gobj", "response"), feature("gobj", "pattern"))) chunks = Chunks() blas = BLAs(density=1.0) gb = GoalStay(controller=(subsystem("acs"), terminus("gb_actions")), source=(subsystem("ms"), terminus("goal_selection")), interface=interface, chunks=chunks, blas=blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".w"): 1.0, feature(("gctl", "goal"), "analyze"): 1.0, feature(("gctl", "gobj"), "pattern"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict(default=0) } output = gb.call(inputs) chunks.step() # pprint(output) # pprint(chunks) # pprint(blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".w"): 1.0, feature(("gctl", "goal"), "evaluate"): 1.0, feature(("gctl", "gobj"), "attribute"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict(default=0) } output = gb.call(inputs) chunks.step() # pprint(output) # pprint(chunks) # pprint(blas) input_ = nd.NumDict( { feature(("gctl", ".cmd"), ".f"): 1.0, feature(("gctl", "goal"), "analyze"): 1.0, feature(("gctl", "gobj"), "pattern"): 1.0 }, default=0) inputs = { (subsystem("acs"), terminus("gb_actions")): input_, (subsystem("ms"), terminus("goal_selection")): nd.NumDict({chunk(".goal_1"): 1.0}) } output = gb.call(inputs) chunks.step()
def test_rule_selection_follows_boltzmann_distribution(self): rules = Rules(max_conds=1) rules.define(rule("A"), chunk("Action 1"), chunk("Condition A")) rules.define(rule("B"), chunk("Action 1"), chunk("Condition B")) rules.define(rule("C"), chunk("Action 1"), chunk("Condition C")) rules.define(rule("D"), chunk("Action 2"), chunk("Condition D")) rules.define(rule("E"), chunk("Action 2"), chunk("Condition E")) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } get_rule = lambda c: rule(c.cid[-1]) action_rules = ActionRules( source=chunks(1), rules=rules, temperature=.1 # relatively high temperature to ensure variety ) expected = nd.transform_keys(inputs[chunks(1)], func=get_rule) expected = nd.boltzmann(expected, t=.1) expected = nd.with_default(expected, default=None) N = 100 selected = [] is_rule = lambda sym: sym.ctype in ConstructType.rule for _ in range(N): strengths = action_rules.call(inputs) s = nd.keep(strengths, func=is_rule) s = nd.threshold(s, th=0) s = s.constant(val=1) s = nd.with_default(s, default=0) selected.append(s) counts = nd.ew_sum(*selected) terms = ((counts - (N * expected))**2) / (N * expected) chi_square_stat = nd.val_sum(terms) critical_value = 9.488 # for chi square w/ 4 df @ alpha = .05 self.assertFalse(critical_value < chi_square_stat, msg="Chi square test significant at alpha = .05.")
def test_call_activates_unique_action_and_rule_pair(self): rules = Rules(max_conds=1) rules.define(rule("A"), chunk("Action 1"), chunk("Condition A")) rules.define(rule("B"), chunk("Action 1"), chunk("Condition B")) rules.define(rule("C"), chunk("Action 1"), chunk("Condition C")) rules.define(rule("D"), chunk("Action 2"), chunk("Condition D")) rules.define(rule("E"), chunk("Action 2"), chunk("Condition E")) inputs = { chunks(1): nd.NumDict( { chunk("Condition A"): .7, chunk("Condition B"): .2, chunk("Condition C"): .6, chunk("Condition D"): .5, chunk("Condition E"): .3 }, default=0) } action_rules = ActionRules( source=chunks(1), rules=rules, temperature=1 # high temperature to ensure variety ) strengths = action_rules.call(inputs) above_zero = nd.threshold(strengths, th=0.0) self.assertEqual( len(above_zero), 2, msg="Expected at most two items above zero activation.") if chunk("Action 1") in above_zero: self.assertTrue(rule("A") in above_zero or rule("B") in above_zero or rule("C") in above_zero, msg="Unexpected rule paired with Action 1.") if chunk("Action 2") in above_zero: self.assertTrue(rule("D") in above_zero or rule("E") in above_zero, msg="Unexpected rule paired with Action 2.")
# In this particular simulation, we set our default actions to have a constant # activation of 0.5. default_strengths = nd.MutableNumDict(default=0) default_strengths.extend(gate_interface.defaults, value=0.5) # Next, we initialize and populate chunk and rule databases as in the original # example. cdb = Chunks() rule_db = Rules() rule_db.define( rule("1"), cdb.define(chunk("FRUIT"), feature("tasty", True), feature("sweet", True)), cdb.define(chunk("APPLE"), feature("color", "#ff0000"), feature("color", "#008000"), feature("tasty", True))) cdb.define(chunk("JUICE"), feature("tasty", True), feature("state", "liquid")) ### Agent Assembly ### # The agent assembly process is very similar to `free_association.py`, but we # define some additional constructs and structures. alice = Structure(name=agent("Alice"), assets=Assets(gate_interface=gate_interface)) with alice:
feature("state", "liquid"), feature("sweet") ] # Feature values for red and green are given in hex code to emphasize the idea # that features in Clarion theory represent implicit knowledge. (It is better, # in practice, to label features in a way that is intelligible to readers.) # Moving on, let us consider chunk nodes. Chunk nodes correspond roughly to # the concepts known to Alice. Chunk nodes are simpler to identify than feature # nodes in that they are differentiated only by their names, which are taken to # be purely formal labels. # We can invoke chunk symbols using the `chunk()` constructor as follows. chunk("Chunk-1") # We will represent chunk nodes for the concepts FRUIT, APPLE, and JUICE. chunk_names = ["FRUIT", "APPLE", "JUICE"] # In this simulation, we specify the initial chunks and features explicitly # only for the sake of clarity. Strictly speaking, these specificaions are not # required. Only in more complex simulations, where constructs can pass around # commands for example, explicit specification of at least parts of the feature # domain becomes a necessity. # Now that we've defined the symbols we will be working with, we populate Alice # with some knowledge. # Setting up initial knowledge
# In this particular simulation, we set our default actions to have a constant # activation of 0.5. default_strengths = nd.MutableNumDict(default=0) default_strengths.extend(gate_interface.defaults, value=0.5) # Next, we initialize and populate chunk and rule databases as in the original # example. cdb = Chunks() rule_db = Rules() rule_db.define( rule("1"), cdb.define( chunk("FRUIT"), feature("tasty", True), feature("sweet", True) ), cdb.define( chunk("APPLE"), feature("color", "#ff0000"), feature("color", "#008000"), feature("tasty", True) ) ) cdb.define( chunk("JUICE"), feature("tasty", True), feature("state", "liquid")