def test_ac_lookfortup(self): class Looker(AcNode): acs = [ LookForTup([CTagged(Avail), CTagged(Avail)], tupcond=NotTheArgsOf(Plus, 'operands'), focal_point=InWorkspace), Raise(FoundTup, tup='nodes') ] g = NumboGraph(Numble([4, 5, 6], 15)) b4 = g.look_for(Brick(4)) b5 = g.look_for(Brick(5)) b6 = g.look_for(Brick(6)) plus = g.add_node(Plus, operands=[b4, b5]) looker = g.add_node(Looker, focal_point=g.ws) g.do_timestep(actor=looker) expect = [ (b4, b6), (b5, b6), # brick pairs that are not the operands (b6, b4), (b6, b5) # of plus. ] done = g.done() self.assertIsInstance(done, FoundTup) self.assertIn(done.tup, expect)
def test_override(self): g = NumboGraph(Numble([4, 5, 6], 15)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) noticer = g.add_node(NoticeAllBricksAreAvail, member_of=g.ws) self.assertIn(noticer.id, g.as_nodeids(g.active_nodes())) g.do_timestep(actor=noticer) # Since the NoticeAllBricksAreAvail can't run, it should get tagged # Blocked(NeedArg('focal_point')). tag = g.as_node(g.tag_of(noticer, Blocked)) self.assertTrue( tag, "Failed to create Blocked tag for missing 'focal_point' argument.") reason = g.getattr(tag, 'reason') self.assertTrue(isinstance(reason, NeedArg)) self.assertEqual(reason.name, 'focal_point') self.assertTrue(g.is_blocked(noticer)) # Now we manually override the 'focal_point' argument. g.add_override_node(noticer, 'focal_point', glom) g.remove_tag(noticer, Blocked) g.do_timestep(actor=noticer) bricks = g.find_all(OfClass(Brick)) self.assertTrue( g.has_tag(bricks, AllBricksAvail), "Did not tag the Bricks even when 'focal_point' was overridden.")
def test_ac_add_all_in_glom(self): g = NumboGraph(Numble([4, 5, 6], 15)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) proposer = g.add_node(AddAllInGlom, focal_point=glom) a_brick = g.look_for(OfClass(Brick), focal_point=g.ws) self.assertEqual(g.containers_of_recursive(a_brick), {glom.id, g.ws.id}) g.do_timestep(actor=proposer) proposal = g.as_node(g.neighbor(proposer, 'built')) self.assertEqual(g.class_of(proposal), Proposal) g.do_timestep(actor=proposal) new_plus = g.neighbor(proposal, 'built', neighbor_class=Plus) self.assertTrue(new_plus, 'Proposal did not build Plus.') self.assertTrue(g.is_member(new_plus, g.ws)) self.assertFalse(g.is_member(new_plus, glom)) self.assertTrue(g.is_dormant(proposal)) block = g.as_node(g.neighbor(proposal, 'built', neighbor_class=Block)) self.assertEqual(g.as_node(block), Block(15)) self.assertTrue(g.is_member(block, g.ws)) self.assertFalse(g.is_member(block, glom))
def test_ac_notice_same_value_fail_eq(self): g = NumboGraph(Numble([1, 1, 1], 4)) target = g.look_for(OfClass(Target)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) count = g.add_node(Count, taggees=glom, value=3) noticer = g.add_node(NoticeCountSameAsTarget, focal_point=InWorkspace) g.do_timestep(actor=noticer) self.assertTrue(g.is_failed(noticer))
def test_ac_has_value(self): g = NumboGraph(Numble([3, 3, 3], 15)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) noticer = g.add_node(NoticeAllHaveThisValue, member_of=g.ws, focal_point=glom) g.do_timestep(actor=noticer) self.assertTrue(g.has_tag(glom, AllMembersHaveThisValue))
def test_ac_already_built_fillparamscout(self): g = NumboGraph(Numble([4, 5, 6], 15)) noticer = g.add_node(NoticeAllBricksAreAvail, member_of=g.ws) tag = g.add_tag( Blocked(reason=NeedArg(ac=noticer.action, name='focal_point')), noticer) scout = g.add_node(FillParamScout, behalf_of=noticer, problem=tag) self.assertTrue( g.already_built(FillParamScout, behalf_of=noticer, problem=tag))
def test_ac_notice_same_value(self): g = NumboGraph(Numble([1, 1, 1], 3)) target = g.look_for(OfClass(Target)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) count = g.add_node(Count, taggees=glom, value=3) noticer = g.add_node(NoticeCountSameAsTarget, node1=target, node2=count, focal_point=g.ws) g.do_timestep(actor=noticer) self.assertTrue(g.has_tag([count, target], SameValue)) self.assertFalse(g.is_active(noticer))
def test_consume_result(self): # Tests that building a new Block that links to an existing Plus # makes a link to the Plus's 'result' port rather than creating # a 'consumer' port for the Plus, even though Block's definition # says that it links 'source -- consumer'. g = NumboGraph(Numble([4, 5, 6], 15)) (b4, b5) = g.look_for([Brick(4), Brick(5)], focal_point=g.ws) plus = g.add_node(Plus, operands=(b4, b5)) self.assertCountEqual(plus.defined_port_labels(), ['operands', 'result']) block = g.add_node(Block, value=9, source=plus) self.assertTrue(g.has_hop(plus, 'result', block, 'source'))
def test_ac_already_built_acnode_without_args(self): class MyScout(AcNode): # There are no NodeParams here. This exposed a bug once. acs = [FindParamName()] g = NumboGraph(Numble([4, 5, 6], 15)) noticer = g.add_node(NoticeAllBricksAreAvail, member_of=g.ws) tag = g.add_tag( Blocked(reason=NeedArg(ac=noticer.action, name='focal_point')), noticer) scout = g.add_node(MyScout, behalf_of=noticer, problem=tag) self.assertTrue( g.already_built(MyScout, behalf_of=noticer, problem=tag))
def test_ac_fillparamscout(self): g = NumboGraph(Numble([4, 5, 6], 15)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) noticer = g.add_node(NoticeAllBricksAreAvail, member_of=g.ws) tag = g.add_tag( Blocked(reason=NeedArg(ac=noticer.action, name='focal_point')), noticer) scout = g.add_node(FillParamScout, behalf_of=noticer, problem=tag) g.do_timestep(actor=scout) # The FillParamScout should do the override: self.assertTrue(g.has_hop(noticer, 'focal_point', glom, 'overriding')) # and remove the Blocked tag: self.assertFalse(g.has_node(tag))
def test_ac_count_members(self): class CountMembers(AcNode): acs = [ MembersOf('focal_point'), Len('nodes'), TagWith(Count, taggees='focal_point', value='value') ] g = NumboGraph(Numble([4, 5, 6], 15)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) self.assertFalse(g.has_tag(glom, Count(value=3))) counter = g.add_node(CountMembers, focal_point=glom) g.do_timestep(actor=counter) self.assertTrue(g.has_tag(glom, Count(value=3)))
def test_build_agent_for_needarg(self): # Here we test the entire sequence of becoming blocked for a missing # argument, posting a FillParamScout to fill it in, and running # successfully with the filled-in argument. g = NumboGraph(Numble([4, 5, 6], 15)) bricks = g.find_all(OfClass(Brick)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) noticer = g.add_node(NoticeAllBricksAreAvail, member_of=g.ws) assert len(bricks) == 3 # First, the Noticer tries to run, but can't, because it's missing # a 'focal_point' argument. So, it posts a Blocked tag about it: g.do_timestep(actor=noticer) problem_tag = g.neighbor(noticer, neighbor_class=Blocked) assert problem_tag, 'Noticer did not create problem tag.' # Next, the Noticer should build an agent to fix the problem. self.assertCountEqual(as_iter(g.actions(noticer)), [BuildAgent(noticer, problem_tag)]) g.do_timestep(actor=noticer) scout = g.neighbor(noticer, 'agents') self.assertTrue(g.is_of_class(scout, FillParamScout), 'Noticer did not build a FillParamScout') # Now the Noticer should be blocked: self.assertTrue(g.is_blocked(noticer)) ## and have nothing to do: #self.assertFalse(g.actions(noticer)) # and should only want to boost the scout: self.assertEqual(g.actions(noticer), BoostFromTo({scout})) # The Scout should find the Glom, override the Noticer's 'focal_point' # arg with it, and remove the Blocked tag. g.do_timestep(actor=scout) # Therefore the Noticer should no longer be blocked: self.assertFalse(g.is_blocked(noticer)) # and the Noticer should be able to act: self.assertTrue(g.actions(noticer)) # Finally, the Noticer notices what it's looking for: g.do_timestep(actor=noticer) self.assertTrue(g.has_tag(bricks, AllBricksAvail)) self.assertTrue(g.is_sleeping(noticer))
def test_ac_lookfor_not_there(self): # Tests that LookFor does not crash if no nodes meet the criterion. class Looker(AcNode): acs = [LookFor(OfClass(Count)), Raise(FoundNode, node='node')] g = NumboGraph(Numble([4, 5, 6, 15], 15)) looker = g.add_node(Looker, focal_point=g.ws) g.do_timestep(actor=looker) self.assertFalse(g.done())
def test_oom_and_gt(self): class ActivationTrap(Node): '''Does nothing but receive activation.''' pass g = NumboGraph(Numble([10, 5], 15)) b10 = g.look_for(Brick(10)) b5 = g.look_for(Brick(5)) t15 = g.look_for(Target(15)) assert b10, "Couldn't find Brick(10)" assert b5, "Couldn't find Brick(5)" assert t15, "Couldn't find Target(15)" atrap = g.add_node(ActivationTrap) oomtagger = g.add_node(OoMTagger, member_of=g.ws) oomgttagger = g.add_node(OoMGreaterThanTagger, member_of=g.ws) oom1btagger = g.add_node(OoMSmallGapToWantedTagger, member_of=g.ws) # Every OoM node should give activation to the ActivationTrap g.add_activation_autolinks((OoM, atrap)) g.do_timestep(actor=oomtagger) g.do_timestep(actor=oomtagger) g.do_timestep(actor=oomtagger) self.assertEqual(g.as_node(g.tag_of(b10, OoM)), OoM(value=1.0)) self.assertEqual(g.as_node(g.tag_of(b5, OoM)), OoM(value=log10(5))) self.assertEqual(g.as_node(g.tag_of(t15, OoM)), OoM(value=log10(15))) # This tests .do_activation_autolinks(). for oom in g.find_all(OoM): self.assertEqual(g.activation_from_to(oom, atrap), 1.0) # TODO Assert that this fizzles. g.do_timestep(actor=oomtagger) g.do_timestep(actor=oomgttagger, num=6) self.assertTrue(g.has_tag(t15, OoMGreaterThan, lesser=b5, greater=t15)) #ShowPrimitives.start_logging() g.do_timestep(actor=oom1btagger, num=6) self.assertTrue( g.has_tag(t15, OoMSmallGapToWanted, lesser=b5, wanted=t15))
def test_ac_notice_solved(self): class NoticeSolved(AcNode): acs = [ LookFor(CTagged(Avail), cond=EqualValue('node', 'target')), Raise(NumboSuccess, node='node', target='target') ] g = NumboGraph(Numble([4, 5, 6, 15], 15)) target = g.look_for(OfClass(Target)) glom = g.add_node(Glom, g.find_all(OfClass(Brick))) noticer = g.add_node(NoticeSolved, focal_point=glom, target=target) g.do_timestep(actor=noticer) got = g.done() self.assertEqual(got.__class__, NumboSuccess) self.assertEqual(g.as_node(got.node), Brick(15)) self.assertEqual(g.as_node(got.target), Target(15)) self.assertTrue(g.succeeded())
def test_ac_mycontext(self): class FindPlus(AcNode): acs = [ LookFor(Plus, focal_point=MyContext), Raise(FoundNode, node='node') ] g = NumboGraph(Numble([4, 5, 6], 15)) wrong_plus = g.look_for(OfClass(Plus), focal_point=g.ws) assert wrong_plus, 'No Plus in workspace' glom = g.add_node(Glom) right_plus = g.add_node(Plus, member_of=glom) finder = g.add_node(FindPlus, member_of=glom) self.assertEqual(as_nodeid(MyContext.focal_point(g, finder)), as_nodeid(glom.id)) g.do_timestep(actor=finder) self.assertEqual(g.done(), FoundNode(right_plus.id))
def test_ac_shadow_criterion_fields(self): # Tests that fields in Criterion objects can be overridden by the # same mechanisms as fields in Ac objects. g = NumboGraph(Numble([4, 5, 6], 15)) target = g.look_for(OfClass(Target), focal_point=g.ws) assert target, 'No Target node' seeker = g.add_node(SeekAndGlom(seekclass=Target, focal_point=g.ws)) g.do_timestep(actor=seeker) glom = g.look_for(OfClass(Glom), subset=g.neighbors(seeker, 'built')) self.assertTrue(glom, 'Did not build Glom') self.assertCountEqual(g.neighbors(glom, 'members'), [target])
def test_ac_add_node(self): g = NumboGraph(Numble([4, 5, 6], 15)) bricks = g.find_all(OfClass(Brick)) seek_and_glom = g.add_node(SeekAndGlom, member_of=g.ws, focal_point=g.ws) g.do_timestep(actor=seek_and_glom) glom = g.look_for(OfClass(Glom), subset=g.neighbors(seek_and_glom, 'built')) self.assertTrue(glom, 'Did not build Glom') self.assertCountEqual(g.neighbors(glom, 'members'), bricks)
def test_favor_closer_to_focal_point(self): g = NumboGraph(Numble([4, 5, 6], 15)) b4 = g.look_for(Brick(4), focal_point=g.ws) b5 = g.look_for(Brick(5), focal_point=g.ws) diff = g.add_node(Diff, lesser=b4, greater=b5, value=1) tups = [ g.look_for([CTagged(Avail), CTagged(Avail)], focal_point=diff) for _ in range(50) ] # All or nearly all of the tuples found should contain Brick(4) # and Brick(5), and not Brick(6), since Brick(4) and Brick(5) are # tagged directly by the focal point, i.e. the Diff tag. ct = Counter(tups) self.assertGreaterEqual(ct.get((b4, b5), 0) + ct.get((b5, b4), 0), 35)
def test_ac_inworkspace(self): class FindPlus(AcNode): acs = [ LookFor(OfClass(Plus), focal_point=InWorkspace), Raise(FoundNode, node='node') ] g = NumboGraph(Numble([4, 5, 6], 15)) plus = g.look_for(OfClass(Plus)) assert plus, 'No Plus in workspace' finder = g.add_node(FindPlus) self.assertEqual(as_nodeid(InWorkspace.focal_point(g, finder)), as_nodeid(g.ws)) g.do_timestep(actor=finder) self.assertEqual(g.done(), FoundNode(plus))
def test_noticer(self): g = NumboGraph(Numble([4, 5, 6], 15)) noticer = g.add_node(AdHocAcNode, [ All(OfClass(Brick), focal_point=g.ws), AllAre(CTagged(Avail)), TagWith(AllBricksAvail, taggees='nodes') ], member_of=g.ws) self.assertEqual(noticer.state, Start) self.assertTrue(noticer.can_go()) self.assertIn(noticer.id, g.as_nodeids(g.active_nodes())) g.do_timestep(actor=noticer) tag = g.as_node(first(g.new_nodes)) self.assertEqual(tag.__class__, AllBricksAvail) self.assertEqual(noticer.state, Completed) self.assertFalse(noticer.can_go()) self.assertNotIn(noticer.id, g.as_nodeids(g.active_nodes()))
def test_ac_build_op_result(self): class Builder(AcNode): acs = [ LookForTup([Brick(4), Brick(5)], focal_point=InWorkspace, asgn_to='operands'), BuildOpResult(operands='operands') ] g = NumboGraph(Numble([4, 5, 6], 15)) plus = g.look_for(Plus, focal_point=g.ws) b4 = g.look_for(Brick(4), focal_point=g.ws) b5 = g.look_for(Brick(5), focal_point=g.ws) builder = g.add_node(Builder, member_of=g.ws, opclass=plus) g.do_timestep(actor=builder) block = g.as_node(g.look_for(Block, focal_point=g.ws)) new_plus = g.neighbor(block, 'source') self.assertTrue(g.is_of_class(new_plus, Plus)) self.assertEqual(block, Block(9)) self.assertCountEqual(g.neighbors(new_plus, 'operands'), as_nodeids([b4, b5]))