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))
class NoticeCountSameAsTarget(AcNode): threshold = 1.0 acs = [ OrFail(LookFor(OfClass(Count), asgn_to='node1'), CantFind.from_env(criteria=OfClass(Count))), OrFail(LookFor(OfClass(Target), asgn_to='node2'), CantFind.from_env(criteria=OfClass(Target))), OrFail(EqualValue(), NotEqualValue.from_env(node1='node1', node2='node2')), Taggees('node1', 'node2'), TagWith(SameValue) ]
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_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)
class AddAllInGlom(AcNode): threshold = 1.0 acs = [ All(And(OfClass(Number), CTagged(Avail))), WithNameOverride(LookFor(And(OfClass(Plus), CTagged(Allowed)), focal_point=InWorkspace), focal_point='opwithin'), AddNode( Proposal, action=ConsumeOperands(), proposed_operands='nodes', proposed_operator='node', ) ]
def go(self, g, actor): if not self.focal_point: raise NeedArg(self, 'focal_point') g.add_node( Proposal, ConsumeOperands(), consume_operands=g.find_all(OfClass(Number), CTagged(Avail), focal_point=self.focal_point), proposed_operator=g.look_for( OfClass(Plus), CTagged(Allowed), # TODO 'and' these criteria focal_point=g.ws), member_of=g.ws) g.new_state(self.actor, Completed)
def go(self, g, actor): # Test that all members of 'focal_point' have value 'value'. # If so, tag 'focal_point' AllMembersSameValue # HACK Need to find 'focal_point' node left by SeekAndGlom or whatever # process set up the node in which we should NoticeAllSameValue. #focal_point = first(g.prev_new_nodes) # if not self.focal_point: # self.focal_point = g.look_for(OfClass(Glom)) # if not self.focal_point: # return # TODO FAIL if not self.focal_point: raise NeedArg(ac=self, name='focal_point') if self.value is None: raise NeedArg(ac=self, name='value') if all( g.value_of(memberid) == self.value #for memberid in g.members_of(self.focal_point) for memberid in g.find_all(OfClass(Number), focal_point=self.focal_point)): #g.do(Build.maybe_make(g, AllMembersSameValue, [self.focal_point], {})) g.do(Build.maybe_make(g, AllMembersSameValue, self.focal_point)) g.new_state(self.actor, Completed) else: raise NotAllSameValue(self, value=self.value, focal_point=self.focal_point)
def __init__(self, numble, *args, **kwargs): super().__init__(*args, **kwargs) self.nodeclasses.update(nodeclasses) for nc in [ Blocked, Slipnet, AssessorScout, FixerScout, Proposal, AllBricksAvail, NoticeAllBricksAvail, SameNumberGlommer, MemberCounter, SameValueTagger ]: self.nodeclasses[nc.__name__] = nc self.port_mates += port_mates # Make initial nodes ws = self.add_node(Workspace) slipnet = self.add_node(Slipnet) self.fill_slipnet(slipnet) numble.build(self, ws) #HACK #self.add_node(SameNumberGlommer) #self.add_node(MemberCounter) #self.add_node(SameValueTagger) #self.add_node(SameNumberTagger, member_of=ws) targetid = self.look_for(OfClass(Target)) #self.add_node(SuccessScout, target=targetid, min_support_for=1.0) self.add_node(NoticeAllBricksAvail, member_of=ws) self.add_node(FixerScout, member_of=ws)
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))
class AllBricksAvail(Tag, HasUpdate, ActiveNode): update_action: Actions = Ac.as_action([ All(OfClass(Brick), focal_point=MyContext), AcNot(AllAre(CTagged(Avail))), SelfDestruct() ]) def actions(self): pass
def go(self, g, actor): found_node = g.look_for(OfClass(self.nodeclass)) if found_node: g.add_override_node(self.for_node, self.port_label, found_node) g.boost_activation(self.for_node) g.new_state(self.actor, Completed) g.remove_node(g.neighbors(self.actor, 'rm_on_success')) else: raise CouldntFindArg(self)
def go(self, g, actor): if not self.focal_point: raise NeedArg(self, 'focal_point') operand = g.look_for(OfClass(Brick), focal_point=self.focal_point) if operand: g.add_node(Exclude, operand) g.new_state(self.actor, Completed) else: print('ExcludeOperand FAILED') #DEBUG
def actions(self): badnode = self.g.look_for( #TODO 'and' these criteria OfClass(Block), CTagged(Avail), CTagged(NotGoodEnough), focal_point=self.g.ws) if badnode: return FuncAction(start_fixer_seq, badnode)
class SeekAndGlom(AcNode): node_params = NodeParams( AttrParam('seekclass', Brick) # Specific to testNumboClasses: default ) # to seeking Brick nodes threshold = 1.0 acs = [ All(OfClass('seekclass'), focal_point=MyContext), AddNode(Glom, members='nodes') ]
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 go(self, g: 'G', actor: NRef, env: AcEnv) -> None: focal_point = self.get(g, actor, env, 'focal_point') #name = self.get(g, actor, env, 'name') # TODO Determine the class from 'name' criterion = OfClass('Glom') # HACK node = g.look_for(criterion, focal_point=focal_point) # HACK if not node: #print('LOOKCANT', criterion, node, focal_point) raise CantFind(criterion) env['node'] = node
def actions(self): actives = self.g.find_all(Activated(), OfClass(ActiveNode), subset=self.g.members_of(self) #TODO focal_point=self ? ) #print('ACTIVE SLIPNODES', actives) return [ ActivateSlipnode(slipnode) for slipnode in actives if not self.g.as_node(slipnode).dont_activate_slipnode ]
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 actions(self): group_node = self.g.look_for(OfClass(Group)) if group_node is None: return num_members = len(self.g.neighbors(group_node, port_label='members')) # TODO make_build3 -> Build.maybe_make return [ make_build3(g, Count, [], { 'taggees': [group_node], 'value': num_members }) ]
class NoticeAllHaveThisValue(AcNode): threshold = 1.0 acs = [ All(OfClass(Number)), OrFail( AllAre(HasThisValue(value=3)), NotAllThisValue.from_env(value=3) # TODO Get 'value' from env so search and exc are assuredly # consistent ), TagWith(AllMembersHaveThisValue, taggees='focal_point') ]
def make_slipnet(self): self.seqnode = make_action_sequence( self, SeekAndGlom(focal_point=self.ws, criteria=OfClass(Brick)), NoticeAllHaveThisValue(value=1, focal_point=None), CountMembers(focal_point=None), NoticeCountSameAsTarget(node1=None, node2=None, value=1, focal_point=InWorkspace), AddAllInGlom(), member_of=self.slipnet, )
def test_do_notice_and_tag(self): # Tests running Ac objects directly. Normally, though, you only run # Ac objects from inside an AcNode. g = NumboGraph(Numble([4, 5, 6], 15)) targetid = 1 # HACK env = Ac.run(g, All(OfClass(Brick), focal_point=g.ws), actor=targetid) nodes = map(g.as_node, env['nodes']) self.assertCountEqual(nodes, [Brick(4), Brick(5), Brick(6)]) # Should fail because All is missing a 'focal_point' arg. try: env = Ac.run(g, All(OfClass(Brick)), actor=targetid) except NeedArg as exc: self.assertEqual( exc, NeedArg(ac=All(OfClass(Brick)), name='focal_point')) else: self.fail("Missing 'focal_point' failed to raise AcNeedArg.") env = Ac.run( g, [All(OfClass(Brick), focal_point=g.ws), AllAre(CTagged(Avail))], actor=targetid) nodes = map(g.as_node, env['nodes']) self.assertCountEqual(nodes, [Brick(4), Brick(5), Brick(6)]) env = Ac.run(g, [ All(OfClass(Brick), focal_point=g.ws), AllAre(CTagged(Avail)), TagWith(AllBricksAvail, taggees='nodes') ], actor=targetid) result = list(g.as_nodes(env['result'])) self.assertEqual(len(result), 1) tag = result[0] self.assertEqual(tag.__class__, AllBricksAvail) self.assertTrue(g.has_tag(nodes, tag))
def fill_slipnet(self, slipnet: int): seqnode = make_action_sequence( self, SeekAndGlom(focal_point=ws, criteria=OfClass(Brick)), NoticeAllSameValue(value=1, focal_point=None), CountMembers(focal_point=None), NoticeSameValue(node1=None, node2=None), AddAllInGlom(), member_of=slipnet, ) aba = self.add_node(AllBricksAvail, member_of=slipnet) self.set_activation_from_to(aba, seqnode, weight=1.0) self.make_equation([4, 7], Plus, 11, '4+7=11')
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_copy_slipnode_to_ws(self): g = newg() old_node = g.look_for(OfClass(ActionSeqNode), focal_point=g.slipnet) assert old_node, "Couldn't find slipnode to copy" assert not g.getattr(old_node, 'is_duplicable'), \ "We're testing the ability to copy a non-duplicable node" new_node = g.copy_node(old_node, member_of=g.ws) self.assertTrue(g.is_of_class(new_node, ActionSeqNode)) self.assertTrue(g.has_hop(new_node, 'copy_of', old_node, 'copies')) self.assertTrue(g.is_member(new_node, g.ws)) self.assertFalse(g.is_member(new_node, g.slipnet)) new_node2 = g.copy_node(old_node, member_of=g.ws) self.assertTrue(g.is_of_class(new_node2, ActionSeqNode)) self.assertTrue(g.has_hop(new_node2, 'copy_of', old_node, 'copies')) self.assertTrue(g.is_member(new_node2, g.ws)) self.assertFalse(g.is_member(new_node2, g.slipnet))
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))