コード例 #1
0
ファイル: testCanvas.py プロジェクト: bkovitz/FARGish
    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)
コード例 #2
0
ファイル: testCanvas.py プロジェクト: bkovitz/FARGish
    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)
コード例 #3
0
ファイル: testDetectors.py プロジェクト: bkovitz/FARGish
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)
コード例 #4
0
ファイル: testCanvas.py プロジェクト: bkovitz/FARGish
    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], '+')))
コード例 #5
0
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))
コード例 #6
0
ファイル: testCanvas.py プロジェクト: bkovitz/FARGish
    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)
コード例 #7
0
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)
コード例 #8
0
ファイル: testCodelets.py プロジェクト: bkovitz/FARGish
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()))