Exemplo n.º 1
0
    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.")
Exemplo n.º 2
0
    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.")
Exemplo n.º 3
0
# mathematical operations.

# 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:
Exemplo n.º 4
0
# To house chunk and rule definitions, we initialize a chunk database and a 
# rule database.

cdb = Chunks()
rdb = Rules()

# We can add rules to the rule database using the `define()` method of the rule 
# database. The argument signature for `define()` is a rule symbol, followed by 
# its conclusion chunk and then by one or more condition chunks. Thus, below, 
# `chunk("FRUIT")` is the conclusion and `chunk("APPLE")` is the only condition. 
# In other words, this rule establishes an association from the concept APPLE 
# to the concept FRUIT. In truth, we may also designate condition weights, but 
# this feature is not explored here.

rdb.define(rule(1), chunk("FRUIT"), chunk("APPLE"))

# We proceed in much the same way to link chunk and feature nodes in order to 
# define chunks. 

# The chunk database has a `define()` method, which can be used to link a chunk 
# node to feature nodes, creating a fully-formed chunk. The call signature 
# expects the chunk node first, followed by the feature nodes. By default, 
# feature notes have a dimensional weight of 1, dimensional weights may be set 
# explicitly through a keyword argument to `define()`.

# The first call to `define()` connects the 'APPLE' chunk node to the red and 
# green color feature nodes and the tasty feature node. 

cdb.define( 
    chunk("APPLE"),