def test_vma(self) -> None: # Regression test for a bug: When a canvas cell was painted over # after a VariantMakerFromAvails was created using it as a source, # the VariantMakerFromAvails would produce an invalid Consumer # (missing an operand). fm = FARGModel( slipnet=Slipnet(Graph.with_features([VariantMakerFromAvails()]))) ca = fm.build(StepCanvas([Step([4, 5, 6])])) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) cr1.paint(Step([5, 2], StepDelta([6, 4], [2], '-'))) # Consumer(12+5) will snag: 5 is avail but 12 is unavail co1 = fm.build(Consumer(operator=plus, operands=(12, 5), source=cr1)) fm.run_agent(co1, num=2) vma: VariantMakerFromAvails = fm.the( VariantMakerFromAvails) # type: ignore[assignment] assert vma, 'Consumer did not produce a VariantMakerFromAvails' self.assertEqual(vma.agent, co1) # Some other agent paints over cr1, removing the avail 5 cr1.paint(Step([4, 11], StepDelta([6, 5], [11], '+'))) #lenable(Agent, Codelet, Fizzle) fm.run_agent(vma) #ldisable_all() co2: Any = fm.built_by(vma)[0] assert isinstance(co2, Consumer), \ f'built by {short(co2)}, not a Consumer' self.assertEqual(len(as_list(co2.operands)), 2) fm.run_agent(co2) # Check for crash lp: Any = fm.built_by(co2)[0] self.assertIsInstance(lp, LitPainter)
def test_stepcanvas_basics(self) -> None: ca = StepCanvas([Step([4, 5, 6])]) self.assertEqual(ca[0], Step([4, 5, 6])) self.assertEqual(ca[1], None) self.assertEqual(ca[10], None) self.assertEqual(len(ca), 1) ca[1] = Step([6], StepDelta([4, 5], [9], '+')) self.assertEqual(ca[1], Step([6], StepDelta([4, 5], [9], '+'))) self.assertEqual(len(ca), 2)
class TestDetectors(unittest.TestCase): step0 = Step((4, 5, 6)) step1 = Step((6, 9), StepDelta((4, 5), 9, plus)) step2bad = Step((3, ), StepDelta((9, 6), 3, minus)) step2good = Step((15, ), StepDelta((9, 6), 3, plus)) def pons_start_canvas(self) -> StepCanvas: return StepCanvas([self.step0]) def test_dead_end_detector(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) cr2 = CellRef(ca, 2) det = fm.build( DeadEndDetector(target=15, startcell=cr0, on_success=RaiseException(UTDeadEndFound))) fm.run_detector(det) # no exception cr1.paint(self.step1) fm.run_detector(det) # no exception cr2.paint(self.step2good) fm.run_detector(det) # no exception cr2.paint(self.step2bad) with self.assertRaises(UTDeadEndFound) as cm: fm.run_detector(det) self.assertEqual(cm.exception, UTDeadEndFound(cr2)) def test_dead_end_detector_links_to_want(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) cr2 = CellRef(ca, 2) wa = fm.build(Want(startcell=cr0, target=15)) fm.run_agent(wa) det = fm.the(DeadEndDetector) assert det is not None fm.paint(cr1, self.step1) fm.paint(cr2, self.step2bad) fm.run_detector(det) dead_end: Any = fm.the(DeadEnd) self.assertIsNotNone(dead_end) self.assertEqual(dead_end.for_goal, wa) self.assertEqual(fm.builder_of(dead_end), det)
def test_cellref_basics(self) -> None: ca = StepCanvas([Step([4, 5, 6])]) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) # StepCanvas[0] self.assertEqual(cr0.value, Step([4, 5, 6])) self.assertCountEqual(as_iter(cr0.avails), [4, 5, 6]) taken, remaining = cr0.take_avails([4, 5]) self.assertCountEqual(taken, [4, 5]) self.assertCountEqual(remaining, [6]) self.assertEqual(cr0.value, Step([4, 5, 6])) self.assertTrue(cr0.has_a_value()) self.assertTrue(cr0.has_avail_value(4)) self.assertFalse(cr0.has_avail_value(7)) with self.assertRaises(ValuesNotAvail) as cm: taken, remaining = cr0.take_avails([4, 7]) self.assertEqual( cm.exception, ValuesNotAvail(cellref=cr0, avails=(4, None), unavails=(None, 7))) #StepCanvas[1] self.assertEqual(cr1.value, None) self.assertFalse(cr1.has_a_value()) self.assertCountEqual(as_iter(cr1.avails), []) with self.assertRaises(ValuesNotAvail) as cm: taken, remaining = cr1.take_avails([4, 7]) self.assertEqual( cm.exception, ValuesNotAvail(cellref=cr1, avails=(4, 7), unavails=())) # paint cr1.paint(Step([6], StepDelta([4, 5], [9], '+'))) self.assertEqual(ca[1], Step([6], StepDelta([4, 5], [9], '+')))
class TestQArgs(unittest.TestCase): step0 = Step((4, 5, 6)) step1 = Step((6, 9), StepDelta((4, 5), 9, plus)) def pons_start_canvas(self) -> StepCanvas: return StepCanvas([self.step0]) def test_before_from_avails(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) qarg = QBeforeFromAvails(source=cr0) self.assertCountEqual(as_iter(qarg.get_items( fm, [])), [Before(4), Before(5), Before(6)]) def test_qafter(self) -> None: fm = FARGModel() qarg = QAfter() self.assertCountEqual(as_iter(qarg.get_items(fm, {'features': 15})), [After(15)]) def test_slipnet_kwargs1(self) -> None: fm = FARGModel() qargs = (Before(4), After(11), SearchFor(Equation)) self.assertEqual( fm.mk_slipnet_args(qargs, []), dict(activations_in=dict(((Before(4), 1.0), (After(11), 1.0))), pred=(Equation, ), k=20, num_get=1)) def test_slipnet_kwargs2(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) qargs = (QBeforeFromAvails(), QAfter(), SearchFor()) sources = dict(source=cr0, features=15, type=Equation) self.assertEqual( fm.mk_slipnet_args(qargs, sources), dict(activations_in=dict(((Before(4), 1.0), (Before(5), 1.0), (Before(6), 1.0), (After(15), 1.0))), pred=(Equation, ), k=20, num_get=1))
def test_last_painted_cellref(self) -> None: ca = StepCanvas([Step([4, 5, 6])]) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) cr2 = CellRef(ca, 2) self.assertEqual(ca.last_painted_addr(), 0) self.assertEqual(ca.last_painted_cellref(), cr0) self.assertEqual(list(ca.cellrefs()), [cr0]) self.assertEqual(cr0.last_painted_cellref(), cr0) self.assertEqual(cr1.last_painted_cellref(), cr0) self.assertEqual(cr2.last_painted_cellref(), cr0) cr1.paint(Step([6, 9], StepDelta([4, 5], [9], '+'))) self.assertEqual(ca.last_painted_addr(), 1) self.assertEqual(ca.last_painted_cellref(), cr1) self.assertEqual(list(ca.cellrefs()), [cr0, cr1]) self.assertEqual(cr0.last_painted_cellref(), cr1) self.assertEqual(cr1.last_painted_cellref(), cr1) self.assertEqual(cr2.last_painted_cellref(), cr1)
class TestAgents(unittest.TestCase): maxDiff = None step0 = Step((4, 5, 6)) step1 = Step((6, 9), StepDelta((4, 5), 9, plus)) #step0 = Step((4, 5, 6)) #step1 = Step((6, 9), StepDelta((4, 5), 9, plus)) step2bad = Step((3,), StepDelta((9, 6), 3, minus)) #step2good = Step((15,), StepDelta((9, 6), 3, plus)) def pons_start_canvas(self) -> StepCanvas: return StepCanvas([self.step0]) def test_litpainter(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr1 = CellRef(ca, 1) lp = fm.build(LitPainter(dest=cr1, value=self.step1)) fm.run_agent(lp) self.assertEqual(ca[1], self.step1) self.assertEqual(fm.agent_state(lp), Succeeded) def test_consumer(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) ag = fm.build(Consumer( operator=plus, operands=(4, 5), source=cr0, #dest=cr1 )) fm.run_agent(ag) lp: Any = fm.the(LitPainter) fm.run_agent(lp) self.assertEqual(ca[1], self.step1) self.assertEqual(fm.agent_state(lp), Succeeded) self.assertEqual( fm.agent_state(ag), Delegate_succeeded, f"Consumer's state is {fm.agent_state(ag)}, not Delegate_succeeded." ) def test_want(self) -> None: #lenable(Want, FindLastPaintedCell) slipnet = Slipnet(Graph.with_features([ Consumer.make(plus, (4, 5)), #Consumer.make(plus, (6, 9)) ])) fm = FARGModel(slipnet=slipnet) ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) wa = fm.build(Want( startcell=cr0, target=9, on_success=RaiseException(SolvedPuzzle) )) self.assertEqual(wa.target, 9) self.assertEqual(fm.agent_state(wa), Born) fm.run_agent(wa) # first action: build AvailDetector det1: Any = fm.the(AvailDetector) self.assertIsInstance(det1, AvailDetector) self.assertEqual(det1.target, 9) self.assertEqual(det1.startcell, cr0) self.assertEqual(det1.on_success, RaiseException(SolvedPuzzle)) det2: Any = fm.the(DeadEndDetector) #lo(det2) self.assertEqual(det2.target, 9) self.assertEqual(det2.startcell, cr0) self.assertEqual(det2.behalf_of, wa) ''' # TODO Make match_wo_none skip attrs that are excluded from comparison # in __eq__. self.assertTrue(match_wo_none( det2, DeadEndDetector( target=9, startcell=cr0, behalf_of=wa ) )) ''' self.assertEqual(fm.agent_state(wa), Wake) fm.run_agent(wa) # second action: build Consumer self.assertEqual(fm.agent_state(wa), Sleeping) co: Any = fm.the(Consumer) self.assertIsInstance(co, Consumer) self.assertEqual(fm.builder_of(co), wa) self.assertEqual(co.source, cr0) # source came from wa.startcell because wa.startcell is declared # to be of type CellRef, and Consume.source needs a CellRef fm.run_agent(co) self.assertEqual(fm.agent_state(co), Sleeping) lp: Any = fm.the(LitPainter) fm.run_agent(lp) self.assertEqual(fm.agent_state(lp), Succeeded) self.assertEqual(ca[1], self.step1) # TODO UT co is Delegate_succeeded fm.run_agent(co) with self.assertRaises(SolvedPuzzle): fm.run_detector(det1) def test_timestep1(self) -> None: # Verifies that Want does something on its first two timesteps, # and then sleeps, and then another Agent gets called upon. slipnet = Slipnet(Graph.with_features([ Consumer.make(plus, (4, 5)) ])) for seed in range(1, 3): fm = FARGModel(slipnet=slipnet, seed=seed, paint_threshold=0.0) ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) wa = fm.build(Want( startcell=cr0, target=9, on_success=RaiseException(SolvedPuzzle) )) self.assertEqual(fm.agent_state(wa), Born) self.assertEqual(fm.t, 0) #lenable(Agent, Codelet) #pr(fm) #pr(wa.born) fm.do_timestep() # the Want should build a Detector self.assertEqual(fm.t, 1) #pr(fm.codelets_just_run) self.assertEqual(fm.agent_state(wa), Wake) fm.do_timestep() # the Want should build a Consumer self.assertEqual(fm.t, 2) self.assertEqual(fm.agent_state(wa), Sleeping) co: Any = fm.the(Consumer) self.assertIsInstance(co, Consumer) self.assertCountEqual(fm.nodes(Agent.CanRun), [co]) fm.do_timestep() # the Consumer should build a LitPainter self.assertEqual(fm.t, 3) self.assertTrue(fm.agent_just_ran(co)) self.assertEqual( fm.agent_state(co), Sleeping, f'{short(co)} is {fm.agent_state(co)}, not Sleeping' ) lp: Any = fm.the(LitPainter) self.assertIsInstance(lp, LitPainter) self.assertEqual(fm.builder_of(lp), co) fm.do_timestep() # the LitPainter should Paint self.assertEqual(fm.t, 4) self.assertTrue(fm.agent_just_ran(lp)) self.assertTrue(any(cr.clis(Paint) for cr in fm.codelets_just_run)) self.assertEqual(fm.agent_state(lp), Succeeded) def test_timestepper(self) -> None: slipnet = Slipnet(Graph.with_features([ Consumer.make(plus, (4, 5)) ])) for seed in range(1, 5): fm = FARGModel(slipnet=slipnet, seed=seed, paint_threshold=0.0) ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) wa = fm.build(Want( startcell=cr0, target=9, on_success=RaiseException(SolvedPuzzle) )) with self.assertRaises( SolvedPuzzle, msg=f'SolvedPuzzle not raised; seed={seed}' ): fm.do_timestep(num=6) #print() #print('WA', short(wa)) #print() #pr(fm, extra=True) self.assertEqual(ca[1], self.step1, f'seed={seed}') def test_snag_tag_and_no_result_from_slipnet(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) ag = fm.build(Consumer( operator=plus, operands=(3, 5), # 3 is not avail, so this Consumer must fail source=cr0, #dest=cr1 )) fm.run_agent(ag) snag_tag = fm.the(Fizzle) self.assertIsNotNone(snag_tag) self.assertEqual(fm.builder_of(snag_tag), ag) self.assertEqual(fm.agent_state(ag), Snag) def test_fail_after_no_result_from_slipnet(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) ag = fm.build(Consumer( operator=plus, operands=(3, 5), # 3 is not avail, so this Consumer must fail source=cr0, )) fm.add_tag(ag, ValuesNotAvail()) self.assertTrue(fm.has_tag(ag, ValuesNotAvail)) fm.set_state(ag, Snag) fm.run_agent(ag) self.assertTrue(fm.has_tag(ag, NoResultFromSlipnet)) self.assertEqual(fm.agent_state(ag), Failed) def test_variant_maker(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) ag1 = fm.build(Consumer( operator=plus, operands=(4, 4), source=cr0 )) ag2 = fm.build(VariantMakerFromAvails( agent=ag1, cellref=cr0, avails=(4, None), unavails=(None, 4) )) # The VariantMakerFromAvails should make a new Consumer, one whose # operands include 4 and another real avail, i.e. 5 or 6. #lenable(Agent, Codelet, Fizzle) #pr(fm) fm.run_agent(ag2) new_consumer = first(fm.nodes((Consumer, Exclude(ag1)))) #ldisable_all() self.assertTrue( match_wo_none(new_consumer, Consumer.make(plus, (4, 5))) or match_wo_none(new_consumer, Consumer.make(plus, (4, 6))) ) def test_snag_leads_to_variant_maker(self) -> None: #lenable(Codelet, Fizzle, LogPulse, Built) fm = FARGModel(seed=1, slipnet=Slipnet(desnag_graph)) ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) cr1 = fm.build(CellRef(ca, 1)) ag1 = fm.build(Consumer( operator=plus, operands=(4, 4), source=cr0 )) fm.run_agent(ag1, num=2) vm = fm.the(VariantMakerFromAvails) self.assertTrue(fm.the(VariantMakerFromAvails)) self.assertEqual( fm.the(VariantMakerFromAvails), VariantMakerFromAvails( agent=ag1, cellref=cr0, avails=(4, None), unavails=(None, 4) ) ) #lenable(Agent, Codelet, Fizzle, LogPulse, Built) fm.do_timestep(num=3) #pr(fm) #print() #print(short(cr1.value)) self.assertTrue( short(cr1.value) == '[4 + 5; 6 9]' or short(cr1.value) == '[4 + 6; 5 10]' ) def test_dead_end_extender(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = CellRef(ca, 0) cr1 = CellRef(ca, 1) cr2 = CellRef(ca, 2) wa = fm.build(Want(startcell=cr0, target=15)) fm.run_agent(wa) det = fm.the(DeadEndDetector) # Let's Consume and LitPainter our way to a dead end co1 = fm.build(Consumer( operator=times, operands=(6, 5), source=cr0 )) fm.run_agent(co1) lp1 = fm.the(LitPainter, es=fm.built_by(co1)) fm.run_agent(lp1) co2 = fm.build(Consumer( operator=times, operands=(4, 30), source=cr1 )) fm.run_agent(co2) lp2 = fm.the(LitPainter, es=fm.built_by(co2)) fm.run_agent(lp2) """ fm.paint(cr1, self.step1) fm.paint(cr2, self.step2bad) fm.run_detector(det) dead_end: Any = fm.the(DeadEnd) assert dead_end is not None self.assertIsNotNone(dead_end) self.assertEqual(dead_end.for_goal, wa) self.assertEqual(fm.builder_of(dead_end), det) """ fm.run_detector(det) dead_end: Any = fm.has_tag(cr2, DeadEnd) assert dead_end fm.add_tag(lp2, dead_end) self.assertCountEqual( fm.taggees_of(dead_end), [co2, lp2, cr2] ) self.assertEqual(fm.builder_of(dead_end), det)
class TestCodelets(unittest.TestCase): maxDiff = None step0 = Step((4, 5, 6)) step1 = Step((6, 9), StepDelta((4, 5), 9, plus)) def pons_start_canvas(self) -> StepCanvas: return StepCanvas([self.step0]) def test_build_codelet(self) -> None: fm = FARGModel() dag = fm.build(DummyAgent()) self.assertEqual(fm.agent_state(dag), Born) bc = Build(to_build=DummyCompanion()) sources = fm.run_codelet(bc, agent=dag) self.assertTrue(fm.has_node(DummyCompanion())) companion = fm.the(DummyCompanion) self.assertEqual(fm.ae_weight(dag, companion), 1.0) self.assertEqual(fm.builder_of(companion), dag) self.assertIn(companion, fm.look_up_by_name('built', sources)) # Verify that NewState updated dag's state #self.assertEqual(fm.agent_state(dag), Wake) def test_paint_codelet(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr1 = fm.build(CellRef(ca, 1)) fm.run_codelet(Paint(cr1, self.step1)) self.assertEqual(ca[1], self.step1) def test_paint_codelet_fail(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr1 = fm.build(CellRef(ca, 1)) ag = fm.build(DummyAgent(), init_a=0.2) # ag's activation is below the threshold: fail codelet = Paint(cr1, self.step1) with self.assertRaises(NeedMoreSupportToPaint) as cm: fm.run_codelet(codelet, ag) self.assertEqual(cm.exception.actor, ag) self.assertIsNone(ca[1]) self.assertEqual(fm.agent_state(ag), Snag) # with sufficient activation, succeed fm.set_a(ag, 1.0) fm.run_codelet(Paint(cr1, self.step1), agent=ag) self.assertEqual(ca[1], self.step1) self.assertEqual(fm.agent_state(ag), Succeeded) def test_consume(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) cr1 = fm.build(CellRef(ca, 1)) codelet = Consume(operator=plus, operands=(4, 5), source=cr0) sources = fm.run_codelet(codelet) self.assertEqual(fm.look_up_by_name('result', sources), self.step1) def test_buildlitpainter(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr1 = fm.build(CellRef(ca, 1)) codelet = BuildLitPainter(dest=cr1, value=self.step1) fm.run_codelet(codelet) lp: LitPainter = fm.the(LitPainter) # type: ignore[assignment] self.assertIsNotNone(lp) fm.run_agent(lp) self.assertEqual(ca[1], self.step1) self.assertEqual(fm.agent_state(lp), Succeeded) def test_query_slipnet_for_delegate(self) -> None: graph = Graph.with_features( Consumer.make_table(range(1, 20), range(1, 20), [plus, minus, times])) fm = FARGModel(slipnet=Slipnet(graph)) ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) # succeed codelet = QuerySlipnetForDelegate(qargs=(QBeforeFromAvails(), QAfter(15), SearchFor(Consumer))) #t0 = process_time() fm.run_codelet_and_follow_ups(codelet, {'source': cr0}) #print('RUN1', process_time() - t0) delegate = fm.the(Consumer) self.assertIsNotNone(delegate) # fail codelet = QuerySlipnetForDelegate(qargs=(QBeforeFromAvails(), QAfter(15), SearchFor(DummyAgent))) #t0 = process_time() with self.assertRaises(NoResultFromSlipnet): fm.run_codelet_and_follow_ups(codelet, {'source': cr0}) #print('RUN2', process_time() - t0) def test_sleep_codelet(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) cr1 = fm.build(CellRef(ca, 1)) lp = fm.build(LitPainter(dest=cr1, value=self.step1)) self.assertFalse(fm.is_sleeping(lp)) fm.run_codelet(Sleep(agent=lp, sleep_duration=10)) self.assertTrue(fm.is_sleeping(lp)) # TODO Wait 10 timesteps and test again def test_codelet_missing_argument(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) codelet = Consume(operator=plus, operands=(4, 5) # Missing 'source' and 'dest' ) with self.assertRaises(MissingArgument) as cm: fm.run_codelet(codelet) # No agent exc = cm.exception #self.assertEqual(exc.func, codelet.run) self.assertEqual(exc.param_name, 'source') self.assertEqual(exc.value, None) self.assertEqual(exc.type_needed, CellRef) self.assertEqual(exc.codelet, codelet) def test_make_variant_from_avails(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) ag = fm.build(Consumer(operator=plus, operands=(4, 4), source=cr0)) codelet = MakeVariantFromAvails(cellref=cr0, agent=ag, avails=(4, None), unavails=(None, 4)) fm.run_codelet(codelet) new_consumer = first(fm.nodes((Consumer, Exclude(ag)))) self.assertTrue( match_wo_none(new_consumer, Consumer.make(plus, (4, 5))) or match_wo_none(new_consumer, Consumer.make(plus, (4, 6)))) def test_add_tag(self) -> None: fm = FARGModel() ca = fm.build(self.pons_start_canvas()) cr0 = fm.build(CellRef(ca, 0)) self.assertFalse(fm.has_tag(cr0, UTTag)) #fm.add_tag(cr0, UTTag()) fm.run_codelet(AddTag(tag=UTTag, taggee=cr0)) self.assertTrue(fm.has_tag(cr0, UTTag)) self.assertTrue(match_wo_none(UTTag(), UTTag())) self.assertTrue(fm.has_node(UTTag()))