From 42ed9a072e604e490b8d27ccc9852e6bb64c68b5 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 20 Sep 2024 16:07:56 -0300 Subject: [PATCH 01/59] Fix Memory/MO data types timestamp and id float->int --- src/cst_python/core/entities/memory.py | 8 ++++---- src/cst_python/core/entities/memory_object.py | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cst_python/core/entities/memory.py b/src/cst_python/core/entities/memory.py index 30e0160..bbaa0a6 100644 --- a/src/cst_python/core/entities/memory.py +++ b/src/cst_python/core/entities/memory.py @@ -38,7 +38,7 @@ def set_evaluation(self, evaluation:float) -> None: #@alias.alias("getTimestamp") @abc.abstractmethod - def get_timestamp(self) -> float: + def get_timestamp(self) -> int: ... #@alias.alias("addMemoryObserver") @@ -53,17 +53,17 @@ def remove_memory_observer(self, observer:MemoryObserver) -> None: #@alias.alias("getId") @abc.abstractmethod - def get_id(self) -> float: + def get_id(self) -> int: ... #@alias.alias("setId") @abc.abstractmethod - def set_id(self, memory_id:float) -> None: + def set_id(self, memory_id:int) -> None: ... #@alias.alias("getTimestamp") @abc.abstractmethod - def get_timestamp(self) -> float: + def get_timestamp(self) -> int: ... diff --git a/src/cst_python/core/entities/memory_object.py b/src/cst_python/core/entities/memory_object.py index 9ab855d..48a8160 100644 --- a/src/cst_python/core/entities/memory_object.py +++ b/src/cst_python/core/entities/memory_object.py @@ -10,8 +10,8 @@ class MemoryObject(Memory): def __init__(self) -> None: - self._id = 0.0 - self._timestamp = 0.0 + self._id = 0 + self._timestamp = 0 self._evaluation = 0.0 self._info : Any = None self._name = "" @@ -24,10 +24,10 @@ def __getstate__(self) -> object: return state - def get_id(self) -> float: + def get_id(self) -> int: return self._id - def set_id(self, memory_id: float) -> None: + def set_id(self, memory_id: int) -> None: self._id = memory_id def get_info(self) -> Any: @@ -35,7 +35,7 @@ def get_info(self) -> Any: def set_info(self, value: Any) -> int: self._info = value - self._timestamp = time.time() + self._timestamp = int(time.time()*1000) self._notify_memory_observers() return -1 @@ -47,16 +47,16 @@ def _notify_memory_observers(self) -> None: def update_info(self, info:Any) -> None: self.set_info(info) - def get_timestamp(self) -> float: + def get_timestamp(self) -> int: return self._timestamp @property - def timestamp(self) -> float: + def timestamp(self) -> int: return self._timestamp #@alias.alias("setTimestamp") @timestamp.setter - def timestamp(self, value:float) -> None: + def timestamp(self, value:int) -> None: self._timestamp = value def get_name(self) -> str: @@ -72,7 +72,7 @@ def get_evaluation(self) -> float: return self._evaluation def set_evaluation(self, evaluation: float) -> None: - return self._evaluation + self._evaluation = evaluation #@alias.alias("toString", "to_string") def __str__(self) -> str: From 8e4ca84e6c771a230e74aee97a5dfe7d7f6ded2d Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:32:29 -0300 Subject: [PATCH 02/59] "threshould" typo fix --- src/cst_python/core/entities/codelet.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index d0eaff2..27ef6ea 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -107,16 +107,16 @@ def outputs(self) -> List[Memory]: def outputs(self, value:List[Memory]): self._outputs = value - #@alias.alias("get_threshould", "getThreshould") + #@alias.alias("get_threshold", "getThreshold") @property - def threshould(self) -> float: + def threshold(self) -> float: return self._threshold - #@alias.alias("set_threshould", "setThreshould") - @threshould.setter - def threshould(self, value:float): + #@alias.alias("set_threshold", "setThreshold") + @threshold.setter + def threshold(self, value:float): if value > 1.0 or value < 1.0: - raise ValueError(f"Codelet threshould must be in (0.0 , 1.0) \ + raise ValueError(f"Codelet threshold must be in (0.0 , 1.0) \ (value {value} is not allowed).") self._threshold = value @@ -408,7 +408,7 @@ def notify_codelet(self) -> None: if self._enable_count == 0: self.calculate_activation() - if self.activation >= self.threshould: + if self.activation >= self.threshold: self.proc() else: self._raise_exception() From f1862014b2ec132fc4db1a6b8902b65a8dd16f55 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:36:21 -0300 Subject: [PATCH 03/59] Remove unused files --- src/cst_python/python/manager.py | 17 ---------- tests/common.py | 56 -------------------------------- tests/test_ms1.py | 40 ----------------------- tests/test_ms2_migration.py | 44 ------------------------- 4 files changed, 157 deletions(-) delete mode 100644 src/cst_python/python/manager.py delete mode 100644 tests/common.py delete mode 100644 tests/test_ms1.py delete mode 100644 tests/test_ms2_migration.py diff --git a/src/cst_python/python/manager.py b/src/cst_python/python/manager.py deleted file mode 100644 index a27ef53..0000000 --- a/src/cst_python/python/manager.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Any - -from cst_python.core.entities.codelet import Codelet -from cst_python.core.entities.memory_object import MemoryObject - - -def create_memory_object(name:str, info:Any) -> MemoryObject: - pass - -def use_memory_storage(enable:bool) -> None: - pass - -def insert_codelet(codelet:Codelet) -> None: - pass - -def start() -> None: - pass \ No newline at end of file diff --git a/tests/common.py b/tests/common.py deleted file mode 100644 index 26c373d..0000000 --- a/tests/common.py +++ /dev/null @@ -1,56 +0,0 @@ -from multiprocessing import Queue - -from cst_python import Codelet, MemoryObject - - -class PrintMessageCodelet(Codelet): - - def __init__(self, print_queue:Queue) -> None: - super().__init__() - - self._print_queue = print_queue - - self._trigger : MemoryObject = None - self._msg : MemoryObject = None - - - def proc(self) -> None: - if self._trigger.get_info(): - msg = self._msg.get_info() - print(msg) - self._print_queue.put(msg) - self._trigger.set_info(False) - - def access_memory_objects(self) -> None: - self._trigger = self.get_input("trigger") - self._msg = self.get_output("message") - - def calculate_activation(self) -> None: - pass - - -class ChangeMessageCodelet(Codelet): - - def __init__(self, new_msg:str) -> None: - super().__init__() - - self._new_msg = new_msg - - self._trigger : MemoryObject = None - self._msg : MemoryObject = None - - self._changed = False - - def proc(self) -> None: - if not self._changed: - self._trigger.set_info(True) - self._msg.set_info(self._new_msg) - - self._changed = True - - def access_memory_objects(self) -> None: - self._trigger = self.get_output("trigger") - self._msg = self.get_output("message") - - def calculate_activation(self) -> None: - pass diff --git a/tests/test_ms1.py b/tests/test_ms1.py deleted file mode 100644 index 63e003a..0000000 --- a/tests/test_ms1.py +++ /dev/null @@ -1,40 +0,0 @@ -from multiprocessing import Queue - -from cst_python import use_memory_storage, create_memory_object, insert_codelet, start - -from .common import PrintMessageCodelet, ChangeMessageCodelet - -use_memory_storage(True) - -msg = create_memory_object("message", "", ms=True) #Set the memory to use the MS -trigger = create_memory_object("trigger", False, ms=True) #Set the memory to use the MS - -msg_queue = Queue() - -codelet = PrintMessageCodelet(msg_queue) -codelet.add_input(msg) -codelet.add_input(trigger) -codelet.add_output(trigger) #Works in Java? - -codelet2 = ChangeMessageCodelet("Python message") -codelet2.add_output(msg) -codelet2.add_output(trigger) - -insert_codelet(codelet) -insert_codelet(codelet2) - -start() - -# Python print "Python message" - -msg = msg_queue.get() -assert msg == "Python message" - -# Start java code -... - -# Java changes message and trigger=True -# Python prints "Java message" - -msg = msg_queue.get() -assert msg == "Java message" \ No newline at end of file diff --git a/tests/test_ms2_migration.py b/tests/test_ms2_migration.py deleted file mode 100644 index c4fa0fa..0000000 --- a/tests/test_ms2_migration.py +++ /dev/null @@ -1,44 +0,0 @@ -import time -from multiprocessing import Queue - -from cst_python import use_memory_storage, create_memory_object, insert_codelet, start - -from .common import PrintMessageCodelet, ChangeMessageCodelet - -use_memory_storage(True) - -msg_memory = create_memory_object("message", "") #The memory location starts in the Python -trigger = create_memory_object("trigger", False, ms=True) #Starts the memory on the MS, for avoiding later copy - -msg_queue = Queue() - -codelet = PrintMessageCodelet(msg_queue) -codelet.add_input(msg_memory) -codelet.add_input(trigger) -codelet.add_output(trigger) #Works in Java? - -codelet2 = ChangeMessageCodelet("Python message") -codelet2.add_output(msg_memory) -codelet2.add_output(trigger) - -insert_codelet(codelet) -insert_codelet(codelet2) - -start() - -# Python print "Python message" -msg = msg_queue.get() -assert msg == "Python message" - -# Start java code -... - -# Java see message and trigger on the MS registry, migrate message to MS as it will be used in another node -# Python memories are migrated to the MS -# Codelets run "access_memory_objects" again as previous memories was invalidated? -# Java changes message and trigger=True - -# Python prints "Java message" - -msg = msg_queue.get() -assert msg == "Java message" \ No newline at end of file From 44ceb1b99c1cc1b5ed063c834ad496fc6e9c936b Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:29:26 -0300 Subject: [PATCH 04/59] Core tests implementation (partial) - MemoryObjectTest - MemoryTest - MindTest - RawMemoryTest - CodeletTest --- pytest.ini | 2 + src/cst_python/__init__.py | 3 +- src/cst_python/core/entities/__init__.py | 3 +- src/cst_python/core/entities/codelet.py | 40 ++- src/cst_python/core/entities/memory.py | 4 - tests/core/__init__.py | 0 tests/core/entities/CoalitionTest.py | 15 + tests/core/entities/CodeRackTest.py | 15 + tests/core/entities/CodeletContainerTest.py | 15 + tests/core/entities/CodeletTest.py | 313 ++++++++++++++++++ .../core/entities/DisconnectedCodeletTest.py | 15 + tests/core/entities/MemoryBufferTest.py | 15 + tests/core/entities/MemoryContainerTest.py | 15 + tests/core/entities/MemoryObjectTest.py | 150 +++++++++ tests/core/entities/MemoryTest.py | 82 +++++ tests/core/entities/MindTest.py | 55 +++ tests/core/entities/RawMemoryTest.py | 55 +++ tests/core/entities/__init__.py | 0 tests/core/entities/utils.py | 11 + 19 files changed, 787 insertions(+), 21 deletions(-) create mode 100644 pytest.ini create mode 100644 tests/core/__init__.py create mode 100644 tests/core/entities/CoalitionTest.py create mode 100644 tests/core/entities/CodeRackTest.py create mode 100644 tests/core/entities/CodeletContainerTest.py create mode 100644 tests/core/entities/CodeletTest.py create mode 100644 tests/core/entities/DisconnectedCodeletTest.py create mode 100644 tests/core/entities/MemoryBufferTest.py create mode 100644 tests/core/entities/MemoryContainerTest.py create mode 100644 tests/core/entities/MemoryObjectTest.py create mode 100644 tests/core/entities/MemoryTest.py create mode 100644 tests/core/entities/MindTest.py create mode 100644 tests/core/entities/RawMemoryTest.py create mode 100644 tests/core/entities/__init__.py create mode 100644 tests/core/entities/utils.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..fd17cc9 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --ignore=examples --ignore=docs --doctest-modules \ No newline at end of file diff --git a/src/cst_python/__init__.py b/src/cst_python/__init__.py index 0fa67dc..756ee08 100644 --- a/src/cst_python/__init__.py +++ b/src/cst_python/__init__.py @@ -1,5 +1,4 @@ from . import python from . import core -from .core.entities import Codelet, Mind, MemoryObject -from .python.manager import * \ No newline at end of file +from .core.entities import Codelet, Mind, MemoryObject \ No newline at end of file diff --git a/src/cst_python/core/entities/__init__.py b/src/cst_python/core/entities/__init__.py index fb71558..0a004b8 100644 --- a/src/cst_python/core/entities/__init__.py +++ b/src/cst_python/core/entities/__init__.py @@ -7,4 +7,5 @@ from .memory_container import MemoryContainer from .rest_memory_container import RESTMemoryContainer from .rest_memory_object import RESTMemoryObject -from .mind import Mind \ No newline at end of file +from .mind import Mind +from .raw_memory import RawMemory \ No newline at end of file diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index 27ef6ea..749097e 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -26,7 +26,7 @@ def __init__(self) -> None: self._time_step = 300 self._enabled = True self._enable_count = 0 - self._name = threading.currentThread().name+"|"+type(self).__name__+str(Codelet._last_id) + self._name = threading.current_thread().name+"|"+type(self).__name__+str(Codelet._last_id) self._last_start_time = 0.0 self._lock = threading.RLock() self._activation = 0.0 @@ -82,8 +82,13 @@ def activation(self) -> float: @activation.setter def activation(self, value:float): if value > 1.0 or value < 0.0: + if value > 1.0: + self._activation = 1.0 + else: + self._activation = 0.0 + raise ValueError(f"Codelet activation must be in (0.0 , 1.0) \ - (value {value} is not allowed).") +(value {value} is not allowed).") self._activation = value @@ -115,9 +120,14 @@ def threshold(self) -> float: #@alias.alias("set_threshold", "setThreshold") @threshold.setter def threshold(self, value:float): - if value > 1.0 or value < 1.0: + if value > 1.0 or value < 0.0: + if value > 1.0: + self._threshold = 1.0 + else: + self._threshold = 0.0 + raise ValueError(f"Codelet threshold must be in (0.0 , 1.0) \ - (value {value} is not allowed).") +(value {value} is not allowed).") self._threshold = value @@ -145,12 +155,12 @@ def broadcast(self, value:List[Memory]) -> None: #@alias.alias("IsProfiling") @property - def is_profiling(self) -> bool: + def profiling(self) -> bool: return self._is_profiling #@alias.alias("set_profiling", "setProfiling") - @is_profiling.setter - def is_profiling(self, value:bool): + @profiling.setter + def profiling(self, value:bool): if value is True: raise NotImplementedError("Profiling is not implemented") @@ -299,7 +309,7 @@ def add_broadcasts(self, memories:List[Memory]) -> None: #@alias.alias("getThreadName") def get_thread_name(self) -> str: - return threading.currentThread().name + return threading.current_thread().name #@alias.alias("to_string", "toString") def __str__(self) -> str: @@ -308,16 +318,18 @@ def __str__(self) -> str: result = f"Codelet [activation={self._activation}, name={self._name}, " if self._broadcast is not None: - result += self._broadcast[min(len(self._broadcast), max_len)] + result += "broadcast=" + result += str(self._broadcast[:min(len(self._broadcast), max_len)]) result += ", " - + if self._inputs is not None: - result += self._inputs[min(len(self._outputs), max_len)] + result += "inputs=" + result += str(self._inputs[:min(len(self.inputs), max_len)]) result += ", " if self._outputs is not None: - result += self._outputs[min(len(self._outputs), max_len)] - result += ", " + result += "outputs=" + result += str(self._outputs[:min(len(self._outputs), max_len)]) result += "]" @@ -414,7 +426,7 @@ def notify_codelet(self) -> None: self._raise_exception() except Exception as e: - #Logging + #TODO Logging pass finally: diff --git a/src/cst_python/core/entities/memory.py b/src/cst_python/core/entities/memory.py index bbaa0a6..15da8a9 100644 --- a/src/cst_python/core/entities/memory.py +++ b/src/cst_python/core/entities/memory.py @@ -61,10 +61,6 @@ def get_id(self) -> int: def set_id(self, memory_id:int) -> None: ... - #@alias.alias("getTimestamp") - @abc.abstractmethod - def get_timestamp(self) -> int: - ... def compare_name(self, other_name:str) -> bool: diff --git a/tests/core/__init__.py b/tests/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/core/entities/CoalitionTest.py b/tests/core/entities/CoalitionTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/CoalitionTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/CodeRackTest.py b/tests/core/entities/CodeRackTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/CodeRackTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/CodeletContainerTest.py b/tests/core/entities/CodeletContainerTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/CodeletContainerTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/CodeletTest.py b/tests/core/entities/CodeletTest.py new file mode 100644 index 0000000..4e7a6ee --- /dev/null +++ b/tests/core/entities/CodeletTest.py @@ -0,0 +1,313 @@ +from contextlib import redirect_stdout +import math +import unittest +import time +import threading +import io + +from cst_python import MemoryObject, Mind +from .utils import CodeletMock + +class TestCodelet(unittest.TestCase): + def setUp(self) -> None: + self.test_codelet = CodeletMock() + + + def test_get_is_loop_test(self) -> None: + # Any instantiated Codelet, if not changed, should be looping + assert self.test_codelet.loop == True + + + def test_upper_activation_bound_exception(self) -> None: + + with self.assertRaises(ValueError) as ve: + self.test_codelet.activation = 2.0 + + assert str(ve.exception) == "Codelet activation must be in (0.0 , 1.0) (value 2.0 is not allowed)." + + assert math.isclose(1.0, self.test_codelet.activation) + + + def test_lowerActivationBoundException(self) -> None: + with self.assertRaises(ValueError) as ve: + self.test_codelet.activation = -0.8 + + assert str(ve.exception) == "Codelet activation must be in (0.0 , 1.0) (value -0.8 is not allowed)." + + assert math.isclose(0.0, self.test_codelet.activation) + + + + def test_setInputs(self) -> None: + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.inputs = dummy_inputs + self.assertEqual(2, len(self.test_codelet.inputs)) + + + + def test_getInput(self) -> None: + + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + dummy_inputs[0].set_name("testName1") + self.test_codelet.inputs = dummy_inputs + + + self.assertEqual(dummy_inputs[0], self.test_codelet.get_input(name="testName1")) + + + + def test_getInputNull(self) -> None: + + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.inputs = dummy_inputs + + self.assertIsNone(self.test_codelet.get_input(name="testName2")) + + + + def test_add_inputs(self) -> None: + + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.add_inputs(dummy_inputs) + self.assertEqual(2, len(self.test_codelet.inputs)) + + + + + def test_removes_input(self) -> None: + + to_remove = MemoryObject() + + self.test_codelet.add_input(to_remove) + self.assertEqual(1, len(self.test_codelet.inputs)) + + self.test_codelet.removes_input(to_remove) + self.assertEqual(0, len(self.test_codelet.inputs)) + + + + def test_remove_from_input(self) -> None: + + to_remove = [MemoryObject(), MemoryObject()] + + self.test_codelet.add_inputs(to_remove) + self.assertEqual(2, len(self.test_codelet.inputs)) + + self.test_codelet.remove_from_input(to_remove) + self.assertEqual(0, len(self.test_codelet.inputs)) + + + + def test_remove_from_output(self) -> None: + + to_remove = [MemoryObject(), MemoryObject()] + + self.test_codelet.add_outputs(to_remove) + self.assertEqual(2, len(self.test_codelet.outputs)) + + self.test_codelet.remove_from_output(to_remove) + self.assertEqual(0, len(self.test_codelet.outputs)) + + + + def test_add_outputs(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.add_outputs(dummy_outputs) + self.assertEqual(2, len(self.test_codelet.outputs)) + + + + def test_get_outputs(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.add_outputs(dummy_outputs) + self.assertEqual(dummy_outputs, self.test_codelet.outputs) + + + + def test_get_output(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + dummy_outputs[0].set_name("testName3") + self.test_codelet.add_outputs(dummy_outputs) + self.assertEqual(dummy_outputs[0], self.test_codelet.get_output(name="testName3")) + + + + def test_get_outputNullReturn(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.add_outputs(dummy_outputs) + self.assertIsNone(self.test_codelet.get_output("testName4")) + + + + def test_get_outputEnableFalse(self) -> None: + self.test_codelet.time_step = 100 + #with self.assertRaises(Exception): #TODO Fix test after Java correction + with redirect_stdout(io.StringIO()): + self.test_codelet.name = "thisCodeletWillFail" + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.outputs = dummy_outputs + + + self.test_codelet.get_output("testType", 3) # This line will raise an exception + + + mind = Mind() + mind.insert_codelet(self.test_codelet) + mind.start() + time.sleep(0.1) + + mind.shutdown() + + + self.assertFalse(self.test_codelet.enabled) + self.test_codelet.enabled = True + self.assertTrue(self.test_codelet.enabled) + + + + def test_set_outputs(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.outputs = dummy_outputs + self.assertEqual(2, len(self.test_codelet.outputs)) + + + + def test_getInputsOfType(self) -> None: + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject(), MemoryObject(), MemoryObject()] + + dummy_inputs[0].set_name("toGet") + dummy_inputs[1].set_name("toGet") + + self.test_codelet.add_inputs(dummy_inputs) + self.assertEqual(2, len(self.test_codelet.get_inputs_of_type("toGet"))) + + + + def test_get_outputs_of_type(self) -> None: + + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject(), MemoryObject(), MemoryObject()] + + dummy_outputs[0].set_name("toGet") + dummy_outputs[1].set_name("toGet") + + self.test_codelet.add_outputs(dummy_outputs) + self.assertEqual(2, len(self.test_codelet.get_outputs_of_type("toGet"))) + + + + def test_get_broadcastNull(self) -> None: + + self.assertIsNone(self.test_codelet.get_broadcast("testName5")) + + + + def test_get_broadcastType(self) -> None: + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + dummy_outputs[0].set_name("testName6") + self.test_codelet.add_broadcasts(dummy_outputs) + self.assertEqual(dummy_outputs[0], self.test_codelet.get_broadcast("testName6", 0)) + + + + def test_get_broadcastTypeIndex(self) -> None: + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + dummy_outputs[0].set_name("testName") + dummy_outputs[1].set_name("testName") + self.test_codelet.add_broadcasts(dummy_outputs) + self.assertEqual(dummy_outputs[1], self.test_codelet.get_broadcast("testName", 1)) + + + + def test_addBroadcasts(self) -> None: + dummy_outputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + self.test_codelet.add_broadcasts(dummy_outputs) + self.assertEqual(2, len(self.test_codelet.broadcast)) + + + + def test_get_thread_name(self) -> None: + threading.current_thread().name = "newThreadName" + self.assertEqual("newThreadName", self.test_codelet.get_thread_name()) + + + + def test_toString(self) -> None: + + dummy_inputs : list[MemoryObject] = [MemoryObject(), MemoryObject()] + dummy_broadcasts : list[MemoryObject] = [MemoryObject(), MemoryObject()] + + expected_string = ("Codelet [activation=" + str(0.5) + ", " + "name=" + "testName" + ", " + + ("broadcast=" + str(dummy_broadcasts[0:min(len(dummy_broadcasts), 10)]) + ", ") + + ("inputs=" + str(dummy_inputs[0:min(len(dummy_inputs), 10)])) + ", " + + ("outputs=" + "[]") + "]") + + self.test_codelet.name = "testName" + + self.test_codelet.activation = 0.5 + + self.test_codelet.inputs = dummy_inputs + self.test_codelet.broadcast = dummy_broadcasts + + self.assertEqual(expected_string, str(self.test_codelet)) + + + + def test_setThreshold(self) -> None: + self.test_codelet.threshold = 0.5 + + + assert math.isclose(0.5, self.test_codelet.threshold) + + + + def test_upperThresholdBound(self) -> None: + + with self.assertRaises(ValueError) as ve: + self.test_codelet.threshold = 2.0 + + assert str(ve.exception) == "Codelet threshold must be in (0.0 , 1.0) (value 2.0 is not allowed)." + + assert math.isclose(1.0, self.test_codelet.threshold) + + + + + def test_lowerThresholdBound(self) -> None: + + with self.assertRaises(ValueError) as ve: + self.test_codelet.threshold = -1.0 + + assert str(ve.exception) == "Codelet threshold must be in (0.0 , 1.0) (value -1.0 is not allowed)." + + assert math.isclose(0.0, self.test_codelet.threshold) + + + + def test_getTimeStep(self) -> None: + + self.test_codelet.time_step = 222 + self.assertEqual(222, self.test_codelet.time_step) + + + + @unittest.skip("Codelet profiling not implemented") + def test_runProfiling(self) -> None: + + self.test_codelet.profiling = True + self.test_codelet.time_step = 100 + + with redirect_stdout(io.StringIO()): + mind = Mind() + mind.insert_codelet(self.test_codelet) + mind.start() + + time.sleep(0.1) + + + self.assertTrue(self.test_codelet.profiling) + diff --git a/tests/core/entities/DisconnectedCodeletTest.py b/tests/core/entities/DisconnectedCodeletTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/DisconnectedCodeletTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/MemoryBufferTest.py b/tests/core/entities/MemoryBufferTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/MemoryBufferTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/MemoryContainerTest.py b/tests/core/entities/MemoryContainerTest.py new file mode 100644 index 0000000..64459e5 --- /dev/null +++ b/tests/core/entities/MemoryContainerTest.py @@ -0,0 +1,15 @@ +import unittest + +class Test(unittest.TestCase): + def setUp(self) -> None: + super().setUp() + + def tearDown(self) -> None: + super().tearDown() + + @classmethod + def tearDownClass(cls): + ... + + def test_(self) -> None: + ... \ No newline at end of file diff --git a/tests/core/entities/MemoryObjectTest.py b/tests/core/entities/MemoryObjectTest.py new file mode 100644 index 0000000..18052cc --- /dev/null +++ b/tests/core/entities/MemoryObjectTest.py @@ -0,0 +1,150 @@ +import unittest + +from cst_python import MemoryObject, Mind + +class MemoryObjectTest(unittest.TestCase): + def setUp(self) -> None: + self.mo = MemoryObject() + + def test_id(self) -> None: + self.mo.set_id(2000) + + assert 2000 == self.mo.get_id() + + def test_to_string(self) -> None: + I = object() + + self.mo.set_id(2000) + self.mo.set_evaluation(0.8) + self.mo.set_info(I) + self.mo.set_type("testName") + + expected_string = f'''MemoryObject [idmemoryobject={2000}, timestamp={self.mo.get_timestamp()}, evaluation={0.8}, I={I}, name={"testName"}]''' + + assert expected_string == str(self.mo) + + def test_hash_code(self): + I = object() + self.mo_eval = 0.8 + self.mo_id = 2000 + name = "test_name" + + self.mo.set_id(self.mo_id) + self.mo.set_evaluation(self.mo_eval) + self.mo.set_info(I) + self.mo.set_type(name) + + prime = 31 + excepted_value = 1 + excepted_value = prime * excepted_value + (hash(I)) + excepted_value = prime * excepted_value + (hash(self.mo_eval)) + excepted_value = prime * excepted_value + (hash(self.mo_id)) + excepted_value = prime * excepted_value + (hash(name)) + excepted_value = prime * excepted_value + (0 if self.mo.get_timestamp() is None else hash(self.mo.get_timestamp())) + + #Python truncates the __hash__ return if is too long hashing it, so here we need hash(expected_value) + assert hash(excepted_value) == hash(self.mo) + + def test_equals(self): + other_mo = MemoryObject() + third_mo = MemoryObject() + fourth_mo = MemoryObject() + + self.mo.set_info(0.0) + other_mo.set_info(0.0) + third_mo.set_info(1.0) + + assert self.mo != fourth_mo + assert self.mo != third_mo + + self.mo.set_evaluation(0.0) + other_mo.set_evaluation(0.0) + third_mo.set_evaluation(1.0) + + fourth_mo.set_info(0.0) + fourth_mo.set_evaluation(None) + + assert self.mo != fourth_mo + assert self.mo != third_mo + + self.mo.set_id(1000) + other_mo.set_id(2000) + third_mo.set_id(2000) + + + fourth_mo.set_evaluation(0.0) + fourth_mo.set_id(None) + + assert fourth_mo != self.mo + assert self.mo != other_mo + + other_mo.set_id(1000) + fourth_mo.set_id(1000) + + self.mo.set_type("firstName") + other_mo.set_type("firstName") + third_mo.set_type("secondName") + + assert fourth_mo != self.mo + assert self.mo != third_mo + + fourth_mo.set_type("firstName") + + self.mo.timestamp = 100 + other_mo.timestamp = 100 + third_mo.timestamp = 200 + fourth_mo.timestamp = None + + assert fourth_mo != self.mo + assert self.mo != third_mo + + fourth_mo.timestamp = 200 + assert fourth_mo != self.mo + + assert self.mo == other_mo + + def test_equals_false_None(self) -> None: + other_mo = MemoryObject() + third_mo = MemoryObject() + fourth_mo = MemoryObject() + + self.mo.set_info(0.0) + other_mo.set_info(0.0) + third_mo.set_info(1.0) + + assert fourth_mo != self.mo + assert self.mo != third_mo + + self.mo.set_evaluation(0.0) + other_mo.set_evaluation(0.0) + third_mo.set_evaluation(1.0) + + assert fourth_mo != self.mo + assert self.mo != third_mo + + + self.mo.set_id(100) + other_mo.set_id(100) + third_mo.set_id(200) + + assert fourth_mo != self.mo + assert self.mo != third_mo + + + self.mo.set_type("firstName") + other_mo.set_type("firstName") + third_mo.set_type("secondName") + + assert fourth_mo != self.mo + assert self.mo != third_mo + + + self.mo.timestamp = 10 + other_mo.timestamp = 10 + third_mo.timestamp = 20 + fourth_mo.timestamp = None + + assert fourth_mo != self.mo + assert self.mo != third_mo + + assert self.mo == other_mo \ No newline at end of file diff --git a/tests/core/entities/MemoryTest.py b/tests/core/entities/MemoryTest.py new file mode 100644 index 0000000..4e68f76 --- /dev/null +++ b/tests/core/entities/MemoryTest.py @@ -0,0 +1,82 @@ +import math +import unittest +from typing import Any + +from cst_python.core.entities import Memory, MemoryObject, MemoryObserver + +class MemorySubclass(Memory): + def __init__(self) -> None: + super().__init__() + + self.I = None + self.evaluation = 0.0 + self.name = "" + self.timestamp = 10 + self.id = None + + def get_id(self) -> int: + return self.id + + def set_id(self, memory_id: int) -> None: + self.id = memory_id + + def get_info(self) -> Any: + return self.I + + def set_info(self, value: Any) -> int: + self.I = value + + def get_evaluation(self) -> float: + return self.evaluation + + def get_name(self) -> str: + return self.name + + def set_name(self, name: str) -> None: + self.name = name + + def set_evaluation(self, evaluation: float) -> None: + self.evaluation = evaluation + + def get_timestamp(self) -> int: + return self.timestamp + + def add_memory_observer(self, observer: MemoryObserver) -> None: + # TODO copy from CST when implemented + pass + + def remove_memory_observer(self, observer: MemoryObserver) -> None: + # TODO copy from CST when implemented + pass + +class MemoryTest(unittest.TestCase): + def setUp(self) -> None: + self.test_memory = MemorySubclass() + super().setUp() + + def test_get_set_info(self) -> None: + assert self.test_memory.get_info() is None + + test_value = 100.0 + self.test_memory.set_info(test_value) + + assert math.isclose(test_value, self.test_memory.get_info()) + + test_list : list[Memory] = [MemoryObject(), MemoryObject()] + self.test_memory.set_info(test_list) + + assert test_list == self.test_memory.get_info() + + + + def test_get_set_eval(self) -> None: + + test_value = 100.0 + self.test_memory.set_evaluation(test_value) + + assert math.isclose(test_value, self.test_memory.get_evaluation()) + + + def test_get_timestamp(self) -> None: + assert 10 == self.test_memory.get_timestamp() + \ No newline at end of file diff --git a/tests/core/entities/MindTest.py b/tests/core/entities/MindTest.py new file mode 100644 index 0000000..d23628d --- /dev/null +++ b/tests/core/entities/MindTest.py @@ -0,0 +1,55 @@ +import unittest + +from cst_python import Mind, MemoryObject +from .utils import CodeletMock + + +class MindTest(unittest.TestCase): + def setUp(self) -> None: + self.test_codelet = CodeletMock() + self.mind = Mind() + + def test_create_codelet_group(self) -> None: + self.mind.create_codelet_group("testGroup") + + assert "testGroup" in self.mind.codelet_groups + + + def test_create_memory_group(self) -> None: + self.mind.create_memory_group("testGroup") + + assert "testGroup" in self.mind.memory_groups + + + def test_insert_codelet_group(self) -> None: + self.mind.create_codelet_group("testGroup") + self.mind.insert_codelet(self.test_codelet, "testGroup") + + + assert 1 == len(self.mind.code_rack.all_codelets) + assert "testGroup" in self.mind.codelet_groups + assert self.test_codelet == self.mind.get_codelet_group_list("testGroup")[0] + + def test_register_memory_group(self) -> None: + mo = MemoryObject() + + self.mind.create_memory_group("testGroup") + self.mind.register_memory(mo, "testGroup") + + assert "testGroup" in self.mind.memory_groups + assert mo == self.mind.memory_groups["testGroup"][0] + assert 1 == len(self.mind.get_memory_group_list("testGroup")) + + + def test_register_memory_by_name(self) -> None: + mo = MemoryObject() + mo.set_name("testName") + + self.mind.create_memory_group("testGroup") + self.mind.raw_memory.add_memory(mo) + self.mind.register_memory("testName", "testGroup") + + assert "testGroup" in self.mind.memory_groups + assert mo == self.mind.memory_groups.get("testGroup")[0] + assert 1 == len(self.mind.memory_groups.get("testGroup")) + \ No newline at end of file diff --git a/tests/core/entities/RawMemoryTest.py b/tests/core/entities/RawMemoryTest.py new file mode 100644 index 0000000..52f55af --- /dev/null +++ b/tests/core/entities/RawMemoryTest.py @@ -0,0 +1,55 @@ +import unittest +import io +from contextlib import redirect_stdout + +from cst_python.core.entities import RawMemory, MemoryObject, Memory + +class TestRawMemory(unittest.TestCase): + def setUp(self) -> None: + self.raw_memory = RawMemory() + + + def test_getAllOfType(self) -> None: + test_list : list[Memory] = [MemoryObject(), MemoryObject(), MemoryObject(), MemoryObject()] + test_list[0].set_name("TYPE") + test_list[1].set_name("TYPE") + self.raw_memory.all_memories = test_list + + assert 2 == len(self.raw_memory.get_all_of_type("TYPE")) + assert test_list[0:2] == self.raw_memory.get_all_of_type("TYPE") + + + def test_printContent(self) -> None: + mem = MemoryObject() + mem.set_name("TYPE") + self.raw_memory.add_memory(mem) + expected_message = f'''MemoryObject [idmemoryobject={mem.get_id()}, timestamp={mem.get_timestamp()}, evaluation={0.0}, I={None}, name={"TYPE"}]''' + + with redirect_stdout(io.StringIO()) as f: + self.raw_memory.print_content() + + printed = f.getvalue().splitlines()[0] + + assert printed == expected_message + + + + def test_createAndDestroyMemoryObject(self) -> None: + self.raw_memory.create_memory_object("TYPE") + + assert 1 == len(self.raw_memory) + self.raw_memory.destroy_memory(self.raw_memory.all_memories[0]) + + assert 0 == len(self.raw_memory) + + + + def test_shutdown(self) -> None: + test_list : list[Memory] = [MemoryObject(), MemoryObject(), MemoryObject(), MemoryObject()] + self.raw_memory.all_memories = test_list + + assert 4 == len(self.raw_memory) + + self.raw_memory.shutdown() + assert 0 == len(self.raw_memory) + \ No newline at end of file diff --git a/tests/core/entities/__init__.py b/tests/core/entities/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/core/entities/utils.py b/tests/core/entities/utils.py new file mode 100644 index 0000000..6b229bb --- /dev/null +++ b/tests/core/entities/utils.py @@ -0,0 +1,11 @@ +from cst_python import Codelet + +class CodeletMock(Codelet): + def access_memory_objects(self) -> None: #NOSONAR + pass + + def calculate_activation(self) -> None: #NOSONAR + pass + + def proc(self) -> None: #NOSONAR + pass \ No newline at end of file From 45b79c64b49f9540720bf5f8b0aa15d28aaa6f48 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:59:43 -0300 Subject: [PATCH 05/59] Core tests --- src/cst_python/core/entities/__init__.py | 13 +- src/cst_python/core/entities/coalition.py | 4 + src/cst_python/core/entities/codelet.py | 10 +- .../core/entities/codelet_container.py | 7 + tests/core/entities/CoalitionTest.py | 15 - tests/core/entities/CodeRackTest.py | 15 - tests/core/entities/CodeletContainerTest.py | 15 - .../core/entities/DisconnectedCodeletTest.py | 15 - tests/core/entities/MemoryBufferTest.py | 15 - tests/core/entities/MemoryContainerTest.py | 15 - tests/core/entities/test_CoalitionTest.py | 53 ++ tests/core/entities/test_CodeRackTest.py | 62 ++ .../entities/test_CodeletContainerTest.py | 823 ++++++++++++++++++ .../{CodeletTest.py => test_CodeletTest.py} | 0 .../entities/test_DisconnectedCodeletTest.py | 27 + tests/core/entities/test_MemoryBufferTest.py | 109 +++ .../core/entities/test_MemoryContainerTest.py | 511 +++++++++++ ...ObjectTest.py => test_MemoryObjectTest.py} | 0 .../{MemoryTest.py => test_MemoryTest.py} | 0 ...RawMemoryTest.py => test_RawMemoryTest.py} | 0 .../entities/{MindTest.py => test_mind.py} | 2 +- 21 files changed, 1610 insertions(+), 101 deletions(-) create mode 100644 src/cst_python/core/entities/coalition.py create mode 100644 src/cst_python/core/entities/codelet_container.py delete mode 100644 tests/core/entities/CoalitionTest.py delete mode 100644 tests/core/entities/CodeRackTest.py delete mode 100644 tests/core/entities/CodeletContainerTest.py delete mode 100644 tests/core/entities/DisconnectedCodeletTest.py delete mode 100644 tests/core/entities/MemoryBufferTest.py delete mode 100644 tests/core/entities/MemoryContainerTest.py create mode 100644 tests/core/entities/test_CoalitionTest.py create mode 100644 tests/core/entities/test_CodeRackTest.py create mode 100644 tests/core/entities/test_CodeletContainerTest.py rename tests/core/entities/{CodeletTest.py => test_CodeletTest.py} (100%) create mode 100644 tests/core/entities/test_DisconnectedCodeletTest.py create mode 100644 tests/core/entities/test_MemoryBufferTest.py create mode 100644 tests/core/entities/test_MemoryContainerTest.py rename tests/core/entities/{MemoryObjectTest.py => test_MemoryObjectTest.py} (100%) rename tests/core/entities/{MemoryTest.py => test_MemoryTest.py} (100%) rename tests/core/entities/{RawMemoryTest.py => test_RawMemoryTest.py} (100%) rename tests/core/entities/{MindTest.py => test_mind.py} (98%) diff --git a/src/cst_python/core/entities/__init__.py b/src/cst_python/core/entities/__init__.py index 0a004b8..ed3a2ac 100644 --- a/src/cst_python/core/entities/__init__.py +++ b/src/cst_python/core/entities/__init__.py @@ -1,11 +1,14 @@ +from .coalition import Coalition +from .code_rack import CodeRack from .codelet import Codelet +from .codelet_container import CodeletContainer +from .memory import Memory from .memory import Memory from .memory_buffer import MemoryBuffer +from .memory_container import MemoryContainer from .memory_object import MemoryObject -from .memory import Memory from .memory_observer import MemoryObserver -from .memory_container import MemoryContainer -from .rest_memory_container import RESTMemoryContainer -from .rest_memory_object import RESTMemoryObject from .mind import Mind -from .raw_memory import RawMemory \ No newline at end of file +from .raw_memory import RawMemory +from .rest_memory_container import RESTMemoryContainer +from .rest_memory_object import RESTMemoryObject \ No newline at end of file diff --git a/src/cst_python/core/entities/coalition.py b/src/cst_python/core/entities/coalition.py new file mode 100644 index 0000000..f6b9733 --- /dev/null +++ b/src/cst_python/core/entities/coalition.py @@ -0,0 +1,4 @@ +class Coalition: + + def __init__(self) -> None: + raise NotImplementedError() \ No newline at end of file diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index 749097e..bead8ff 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -32,7 +32,7 @@ def __init__(self) -> None: self._activation = 0.0 #self._timer = self._is_profiling = False - self._thread : threading.Thread = None + self._thread : threading.Thread = threading.Thread(target=self.run, daemon=True) self._codelet_profiler = None self._additional_wait = 0.0 @@ -199,17 +199,17 @@ def run(self) -> None: traceback.print_exception(e) def start(self) -> None: - thread = threading.Thread(target=self.run, daemon=True) - self._thread = thread - thread.start() + self._thread.start() #thread.join(0.0) def stop(self): self.loop = False - self._thread.join(0.0) + + if self._thread.is_alive(): + self._thread.join(0.0) #@alias.alias("impendingAccess") def impending_acess(self, accessing:Codelet) -> bool: diff --git a/src/cst_python/core/entities/codelet_container.py b/src/cst_python/core/entities/codelet_container.py new file mode 100644 index 0000000..bcf29c4 --- /dev/null +++ b/src/cst_python/core/entities/codelet_container.py @@ -0,0 +1,7 @@ +from .memory import Memory + +class CodeletContainer(Memory): + + def __init__(self) -> None: + super().__init__() + raise NotImplementedError() \ No newline at end of file diff --git a/tests/core/entities/CoalitionTest.py b/tests/core/entities/CoalitionTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/CoalitionTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/CodeRackTest.py b/tests/core/entities/CodeRackTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/CodeRackTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/CodeletContainerTest.py b/tests/core/entities/CodeletContainerTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/CodeletContainerTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/DisconnectedCodeletTest.py b/tests/core/entities/DisconnectedCodeletTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/DisconnectedCodeletTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/MemoryBufferTest.py b/tests/core/entities/MemoryBufferTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/MemoryBufferTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/MemoryContainerTest.py b/tests/core/entities/MemoryContainerTest.py deleted file mode 100644 index 64459e5..0000000 --- a/tests/core/entities/MemoryContainerTest.py +++ /dev/null @@ -1,15 +0,0 @@ -import unittest - -class Test(unittest.TestCase): - def setUp(self) -> None: - super().setUp() - - def tearDown(self) -> None: - super().tearDown() - - @classmethod - def tearDownClass(cls): - ... - - def test_(self) -> None: - ... \ No newline at end of file diff --git a/tests/core/entities/test_CoalitionTest.py b/tests/core/entities/test_CoalitionTest.py new file mode 100644 index 0000000..e1b842b --- /dev/null +++ b/tests/core/entities/test_CoalitionTest.py @@ -0,0 +1,53 @@ +import unittest + +from cst_python.core.entities import Coalition +from .utils import CodeletMock + +@unittest.skip("Coalition not implemented") +class Test(unittest.TestCase): + def setUp(self) -> None: + self.test_codelet = CodeletMock() + self.other_codelet = CodeletMock() + + + def test_calculateActivationTest(self) -> None: + coalition = Coalition([self.test_codelet, self.other_codelet]) + try: + coalition.getCodeletsList().get(0).setActivation(1.0) + except CodeletActivationBoundsException as e: + e.printStackTrace() + + + self.assertEqual(0.5, coalition.calculateActivation(), 0) + + + + def test_setCodeletListTest(self) -> None: + coalition = Coalition([self.test_codelet]) + + list_test = [self.test_codelet, self.other_codelet] + coalition.setCodeletsList(list_test) + + self.assertEqual(list_test, coalition.getCodeletsList()) + + + + def test_activation_test(self) -> None: + coalition = Coalition([self.test_codelet]) + + activation_test = 0.8 + coalition.setActivation(activation_test) + + self.assertEqual(0.8, coalition.getActivation(), 0) + + + + def test_toStringTest(self) -> None: + list_test = [self.test_codelet, self.other_codelet] + coalition = Coalition([self.test_codelet, self.other_codelet]) + coalition.setActivation(0.8) + + expect_message = f"Coalition [activation={0.8}, codeletsList={list_test}]" + + self.assertIn(str(coalition), expect_message) + \ No newline at end of file diff --git a/tests/core/entities/test_CodeRackTest.py b/tests/core/entities/test_CodeRackTest.py new file mode 100644 index 0000000..ca8969b --- /dev/null +++ b/tests/core/entities/test_CodeRackTest.py @@ -0,0 +1,62 @@ +import unittest + +from cst_python.core.entities import CodeRack, MemoryObject, Codelet +from .utils import CodeletMock + +class Test(unittest.TestCase): + def setUp(self) -> None: + self.test_codelet = CodeletMock() + self.other_codelet = CodeletMock() + + + def test_setAllCodeletTest(self) -> None: + code_rack = CodeRack() + test_list : list[Codelet] = [self.test_codelet, self.other_codelet] + + code_rack.all_codelets = test_list + self.assertEqual(test_list, code_rack.all_codelets) + + + + def test_insertCodeletTest(self) -> None: + code_rack = CodeRack() + test_list : list[Codelet] = [self.test_codelet] + + code_rack.insert_codelet(self.test_codelet) + + self.assertEqual(test_list, code_rack.all_codelets) + + + + def test_createCodeletTest(self) -> None: + code_rack = CodeRack() + mem_input_test = [MemoryObject(), MemoryObject()] + mem_output_test = [MemoryObject()] + + code_rack.create_codelet(0.5, None, mem_input_test, mem_output_test, self.test_codelet) + + self.assertEqual(self.test_codelet, code_rack.all_codelets[0]) + + def test_destroyCodeletTest(self) -> None: + code_rack = CodeRack() + mem_input_test = [MemoryObject(), MemoryObject()] + mem_output_test = [MemoryObject()] + + code_rack.create_codelet(0.5, None, mem_input_test, mem_output_test, self.test_codelet) + + code_rack.destroy_codelet(self.test_codelet) + + self.assertEqual(0, len(code_rack.all_codelets)) + + + def test_startStopTest(self) -> None: + code_rack = CodeRack() + test_list : list[Codelet] = [self.test_codelet, self.other_codelet] + + code_rack.all_codelets = test_list + code_rack.start() + self.assertTrue(code_rack.all_codelets[0].loop) + + code_rack.stop() + self.assertFalse(code_rack.all_codelets[0].loop) + \ No newline at end of file diff --git a/tests/core/entities/test_CodeletContainerTest.py b/tests/core/entities/test_CodeletContainerTest.py new file mode 100644 index 0000000..076efec --- /dev/null +++ b/tests/core/entities/test_CodeletContainerTest.py @@ -0,0 +1,823 @@ +import unittest +import time + +from cst_python.core.entities import Codelet, CodeletContainer, Mind, MemoryObject, Memory + +class CodeletToTestOne(Codelet): + def __init__(self, name:str): + self.counter = 0 + + self.name = name + + def access_memory_objects(self): #NOSONAR + pass + + def calculate_activation(self): + self.activation = self.counter + + def proc(self): + self.counter += 1 + if (self.outputs is not None and len(self.outputs) != 0): + self.outputs[0].set_info("CODELET 1 OUTPUT") + +class CodeletToTestTwo(Codelet): + def __init__(self, name:str): + self.counter = 0 + + self.name = name + + def access_memory_objects(self): #NOSONAR + pass + + def calculate_activation(self): #NOSONAR + pass + + def proc(self): + self.counter += 2 + +class CodeletToTestThree(Codelet): + def __init__(self, name:str): + self.counter = 0 + + self.name = name + + def access_memory_objects(self): #NOSONAR + pass + + def calculate_activation(self): + self.activation = self.counter + + def proc(self): + self.counter += 3 + if (self.outputs is not None and len(self.outputs) != 0): + self.outputs[0].set_info("CODELET 3 OUTPUT") + +@unittest.skip("CodeletContainer not implemented") +class CodeletContainerTest (unittest.TestCase): + + def sleep(self, timestep:int) -> None: + time.sleep(timestep/1000) + + + def test_noMemoryChangeTest(self) -> None: + # no codelet runs + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + mind.start() + self.sleep(2000) + mind.shutdown() + + self.assertEqual(0, codelet_container.getOutputs().size()) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual(0, codelet_container.getEvaluation(), 0) + + + + + def test_noMemoryChangeButCodeletAddedIsStartedTest(self) -> None: + # no codelet runs + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, True) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + mind.start() + self.sleep(2000) + mind.shutdown() + + self.assertEqual(0, len(codelet_container.getOutputs())) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual( [], codelet_container.getOutputs()) + self.assertEqual(0, codelet_container.getEvaluation(), 0) + + + + + def test_runningCodeletChangingInputTest(self) -> None: + # changes the codelet container input + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory_input1 = mind.create_memory_object("MEMORY_INPUT_1", 0.12) + memory_input2 = mind.create_memory_object("MEMORY_INPUT_2", 0.32) + memory_input3 = mind.create_memory_object("MEMORY_INPUT_3", 0.32) + memory_input4 = mind.create_memory_object("MEMORY_INPUT_4", 0.32) + memory_output1 = mind.create_memory_object("MEMORY_OUTPUT_1", 0.22) + memory_output2 = mind.create_memory_object("MEMORY_OUTPUT_2", 0.22) + memory_output3 = mind.create_memory_object("MEMORY_OUTPUT_3", 0.22) + + codelet_one.add_input(memory_input1) + codelet_one.add_broadcast(memory_input2) + codelet_one.add_output(memory_output1) + + codelet_two.add_broadcast(memory_input3) + codelet_two.add_output(memory_output2) + + codelet_three.add_input(memory_input4) + codelet_three.add_output(memory_output3) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + codelet_container.set_info(10) + mind.start() + self.sleep(2000) + mind.shutdown() + + for codelet in codelet_container.getAll(): + for mem in codelet.inputs: + self.assertEqual(10, mem.get_info()) + + + + for codelet in codelet_container.getAll(): + for mem in codelet.broadcast: + self.assertEqual(0.32, mem.get_info()) + + + + self.assertEqual(3, codelet_container.getOutputs().size()) + expected_outputs = [] + expected_outputs.append(memory_output1) + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual(0.22, codelet_container.getOutputs()[1].get_info()) + self.assertEqual("MEMORY_OUTPUT_3", codelet_container.getOutputs()[2].name) + self.assertEqual(0, codelet_container.getEvaluation(), 0) + + + + + def test_runningCodeletChangingInputCodeletStartedWhenAddedTest(self) -> None: + # changes the codelet container input + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory_input1 = mind.create_memory_object("MEMORY_INPUT_1", 0.12) + memory_input2 = mind.create_memory_object("MEMORY_INPUT_2", 0.32) + memory_input3 = mind.create_memory_object("MEMORY_INPUT_3", 0.32) + memory_input4 = mind.create_memory_object("MEMORY_INPUT_4", 0.32) + memory_output1 = mind.create_memory_object("MEMORY_OUTPUT_1", 0.22) + memory_output2 = mind.create_memory_object("MEMORY_OUTPUT_2", 0.22) + memory_output3 = mind.create_memory_object("MEMORY_OUTPUT_3", 0.22) + + codelet_one.add_input(memory_input1) + codelet_one.add_broadcast(memory_input2) + codelet_one.add_output(memory_output1) + + codelet_two.add_broadcast(memory_input3) + codelet_two.add_output(memory_output2) + + codelet_three.add_input(memory_input4) + codelet_three.add_output(memory_output3) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, True) + + codelet_container.set_info(10) + self.sleep(2000) + + for codelet in codelet_container.getAll(): + for mem in codelet.inputs: + self.assertEqual(10, mem.get_info()) + + + + for codelet in codelet_container.getAll(): + for mem in codelet.broadcast: + self.assertEqual(0.32, mem.get_info()) + + + + codelet_to_test_one : CodeletToTestOne = codelet_container.getCodelet("Codelet 1") + self.assertEqual(7, codelet_to_test_one.counter) + self.assertEqual(3, codelet_container.getOutputs().size()) + expected_outputs : list[Memory] = [] + expected_outputs.append(memory_output1) + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual(0.22, codelet_container.getOutputs()[1].get_info()) + self.assertEqual("MEMORY_OUTPUT_3", codelet_container.getOutputs()[2].name) + self.assertEqual(0, codelet_container.getEvaluation(), 0) + + + + + def test_addCodeletsToCodeletContainerTest(self) -> None: + # changes the codelet container input + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory_input1 = mind.create_memory_object("MEMORY_INPUT_1", 0.12) + memory_input2 = mind.create_memory_object("MEMORY_INPUT_2", 0.32) + memory_input3 = mind.create_memory_object("MEMORY_INPUT_3", 0.32) + memory_input4 = mind.create_memory_object("MEMORY_INPUT_4", 0.32) + memory_output1 = mind.create_memory_object("MEMORY_OUTPUT_1", 0.22) + memory_output2 = mind.create_memory_object("MEMORY_OUTPUT_2", 0.22) + memory_output3 = mind.create_memory_object("MEMORY_OUTPUT_3", 0.22) + + codelet_one.add_input(memory_input1) + codelet_one.add_broadcast(memory_input2) + codelet_one.add_output(memory_output1) + + codelet_two.add_broadcast(memory_input3) + codelet_two.add_output(memory_output2) + + codelet_three.add_input(memory_input4) + codelet_three.add_output(memory_output3) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer() + codelet_container.addCodelet(codelet_one, False) + codelet_container.addCodelet(codelet_two, False) + codelet_container.addCodelet(codelet_three, False) + + + self.assertEqual(3, codelet_container.getOutputs().size()) + expected_outputs : list[Memory] = [] + expected_outputs.append(memory_output1) + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + + self.assertEqual("MEMORY_OUTPUT_1", codelet_container.getOutputs()[0].name) + self.assertEqual("MEMORY_OUTPUT_2", codelet_container.getOutputs()[1].name) + self.assertEqual("MEMORY_OUTPUT_3", codelet_container.getOutputs()[2].name) + self.assertEqual(3, codelet_container.getCodelet(codelet_one.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_two.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_three.name).outputs.size()) + + self.assertEqual(2, codelet_container.getInputs().size()) + expected_inputs : list[Memory] = [] + expected_inputs.append(memory_input1) + expected_inputs.append(memory_input4) + assert expected_inputs == list(codelet_container.getInputs()) + self.assertEqual("MEMORY_INPUT_1", codelet_container.getInputs()[0].name) + self.assertEqual("MEMORY_INPUT_4", codelet_container.getInputs()[1].name) + self.assertEqual(2, codelet_container.getCodelet(codelet_one.name).inputs.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_three.name).inputs.size()) + + self.assertEqual(2, codelet_container.getBroadcast().size()) + expected_broadcast : list[Memory] = [] + expected_broadcast.append(memory_input2) + expected_broadcast.append(memory_input3) + assert expected_broadcast == list(codelet_container.getBroadcast()) + self.assertEqual("MEMORY_INPUT_2", codelet_container.getBroadcast()[0].name) + self.assertEqual("MEMORY_INPUT_3", codelet_container.getBroadcast()[1].name) + self.assertEqual(2, codelet_container.getCodelet(codelet_one.name).broadcast.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_two.name).broadcast.size()) + + + + def test_addCodeletsToCodeletContainerWhichHasInputsAndOuputsTest(self) -> None: + # changes the codelet container input + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory_input1 = mind.create_memory_object("MEMORY_INPUT_1", 0.12) + # 2 and 3 is not used + memory_input4 = mind.create_memory_object("MEMORY_INPUT_4", 0.32) + memory_output1 = mind.create_memory_object("MEMORY_OUTPUT_1", 0.22) + memory_output2 = mind.create_memory_object("MEMORY_OUTPUT_2", 0.22) + memory_output3 = mind.create_memory_object("MEMORY_OUTPUT_3", 0.22) + + codelet_container = CodeletContainer() + + new_inputs : list[Memory] = [] + new_inputs.append(memory_input1) + new_inputs.append(memory_input4) + codelet_container.set_infonputs(new_inputs) + + new_outputs: list[Memory] = [] + new_outputs.append(memory_output1) + new_outputs.append(memory_output2) + new_outputs.append(memory_output3) + codelet_container.setOutputs(new_outputs) + + codelet_container.addCodelet(codelet_one, False) + codelet_container.addCodelet(codelet_two, False) + codelet_container.addCodelet(codelet_three, False) + + + self.assertEqual(3, codelet_container.getOutputs().size()) + expected_outputs : list[Memory] = [] + expected_outputs.append(memory_output1) + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual("MEMORY_OUTPUT_1", codelet_container.getOutputs()[0].name) + self.assertEqual("MEMORY_OUTPUT_2", codelet_container.getOutputs()[1].name) + self.assertEqual("MEMORY_OUTPUT_3", codelet_container.getOutputs()[2].name) + self.assertEqual(3, codelet_container.getCodelet(codelet_one.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_two.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_three.name).outputs.size()) + + self.assertEqual(2, codelet_container.getInputs().size()) + expected_inputs : list[Memory] = [] + expected_inputs.append(memory_input1) + expected_inputs.append(memory_input4) + assert expected_inputs == list(codelet_container.getInputs()) + self.assertEqual("MEMORY_INPUT_1", codelet_container.getInputs()[0].name) + self.assertEqual("MEMORY_INPUT_4", codelet_container.getInputs()[1].name) + self.assertEqual(2, codelet_container.getCodelet(codelet_one.name).inputs.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_three.name).inputs.size()) + + + + + def test_removeCodeletsFromCodeletContainerTest(self) -> None: + # changes the codelet container input + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory_input1 = mind.create_memory_object("MEMORY_INPUT_1", 0.12) + memory_input2 = mind.create_memory_object("MEMORY_INPUT_2", 0.32) + memory_input3 = mind.create_memory_object("MEMORY_INPUT_3", 0.32) + memory_input4 = mind.create_memory_object("MEMORY_INPUT_4", 0.32) + memory_output1 = mind.create_memory_object("MEMORY_OUTPUT_1", 0.22) + memory_output2 = mind.create_memory_object("MEMORY_OUTPUT_2", 0.22) + memory_output3 = mind.create_memory_object("MEMORY_OUTPUT_3", 0.22) + + codelet_one.add_input(memory_input1) + codelet_one.add_broadcast(memory_input2) + codelet_one.add_output(memory_output1) + + codelet_two.add_broadcast(memory_input3) + codelet_two.add_output(memory_output2) + + codelet_three.add_input(memory_input4) + codelet_three.add_output(memory_output3) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + + self.assertEqual(3, codelet_container.getOutputs().size()) + expected_outputs : list[Memory] = [] + expected_outputs.append(memory_output1) + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual("MEMORY_OUTPUT_1", codelet_container.getOutputs()[0].name) + self.assertEqual("MEMORY_OUTPUT_2", codelet_container.getOutputs()[1].name) + self.assertEqual("MEMORY_OUTPUT_3", codelet_container.getOutputs()[2].name) + self.assertEqual(3, codelet_container.getCodelet(codelet_one.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_two.name).outputs.size()) + self.assertEqual(3, codelet_container.getCodelet(codelet_three.name).outputs.size()) + + self.assertEqual(2, codelet_container.getInputs().size()) + expected_inputs : list[Memory] = [] + expected_inputs.append(memory_input1) + expected_inputs.append(memory_input4) + assert expected_inputs == list(codelet_container.getInputs()) + self.assertEqual("MEMORY_INPUT_1", codelet_container.getInputs()[0].name) + self.assertEqual("MEMORY_INPUT_4", codelet_container.getInputs()[1].name) + self.assertEqual(2, codelet_container.getCodelet(codelet_one.name).inputs.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_three.name).inputs.size()) + + self.assertEqual(2, codelet_container.getBroadcast().size()) + expected_broadcast : list[Memory] = [] + expected_broadcast.append(memory_input2) + expected_broadcast.append(memory_input3) + assert expected_broadcast == list(codelet_container.getBroadcast()) + self.assertEqual("MEMORY_INPUT_2", codelet_container.getBroadcast()[0].name) + self.assertEqual("MEMORY_INPUT_3", codelet_container.getBroadcast()[1].name) + self.assertEqual(2, codelet_container.getCodelet(codelet_one.name).broadcast.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_two.name).broadcast.size()) + + codelet_container.removeCodelet(codelet_one) + + self.assertEqual(2, codelet_container.getOutputs().size()) + expected_outputs = [] + expected_outputs.append(memory_output2) + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual(2, codelet_container.getCodelet(codelet_two.name).outputs.size()) + self.assertEqual(2, codelet_container.getCodelet(codelet_three.name).outputs.size()) + + self.assertEqual(1, codelet_container.getInputs().size()) + expected_inputs = [] + expected_inputs.append(memory_input4) + assert expected_inputs == list(codelet_container.getInputs()) + self.assertEqual("MEMORY_INPUT_4", codelet_container.getInputs()[0].name) + self.assertEqual(1, codelet_container.getCodelet(codelet_three.name).inputs.size()) + + self.assertEqual(1, codelet_container.getBroadcast().size()) + expected_broadcast = [] + expected_broadcast.append(memory_input3) + assert expected_broadcast == list(codelet_container.getBroadcast()) + self.assertEqual("MEMORY_INPUT_3", codelet_container.getBroadcast()[0].name) + self.assertEqual(1, codelet_container.getCodelet(codelet_two.name).broadcast.size()) + + codelet_container.removeCodelet(codelet_two) + + self.assertEqual(1, codelet_container.getOutputs().size()) + expected_outputs = [] + expected_outputs.append(memory_output3) + assert expected_outputs == list(codelet_container.getOutputs()) + self.assertEqual(1, codelet_container.getCodelet(codelet_three.name).outputs.size()) + + self.assertEqual(1, codelet_container.getInputs().size()) + expected_inputs = [] + expected_inputs.append(memory_input4) + assert expected_inputs == list(codelet_container.getInputs()) + self.assertEqual("MEMORY_INPUT_4", codelet_container.getInputs()[0].name) + self.assertEqual(1, codelet_container.getCodelet(codelet_three.name).inputs.size()) + + self.assertEqual(0, codelet_container.getBroadcast().size()) + self.assertEqual(0, codelet_container.getCodelet(codelet_three.name).broadcast.size()) + + + + + + def test_getEvaluationTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + test_value = 100.0 + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + memory1.setEvaluation(test_value) + codelet_container.set_info(10) + mind.start() + self.sleep(2000) + mind.shutdown() + + + + self.assertEqual(test_value, codelet_container.getEvaluation()) + + + + + + def test_getActivationTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + test_value = 6.0 + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + memory1.setEvaluation(test_value) + codelet_container.set_info(10) + mind.start() + self.sleep(2000) + mind.shutdown() + + + + self.assertEqual(test_value, codelet_container.getActivation(), 0) + + + + + def test_set_infonputsTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + + new_inputs : list[Memory] = [] + new_inputs.append(memory1) + codelet_container.set_infonputs(new_inputs) + + + + self.assertEqual(new_inputs, codelet_container.getInputs()) + + + + + def test_setOutputsTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + + new_outputs: list[Memory] = [] + new_outputs.append(memory1) + codelet_container.setOutputs(new_outputs) + + + + self.assertEqual(new_outputs, codelet_container.getOutputs()) + + + + + def test_setBroadcastTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + + new_broadcast : list[Memory] = [] + new_broadcast.append(memory1) + codelet_container.setBroadcast(new_broadcast) + + + + self.assertEqual(new_broadcast, codelet_container.getBroadcast()) + + + + + def test_setNameTest(self) -> None: + codelet_container = CodeletContainer() + codelet_container.setName("Container") + self.assertEqual("Container", codelet_container.name) + + + + def test_setTypeTest(self) -> None: + codelet_container = CodeletContainer() + codelet_container.setType("Container") + self.assertEqual("Container", codelet_container.name) + + + + def test_setEvaluationTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + codelet_one.add_input(memory1) + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container = CodeletContainer(codelet_container_array, False) + codelet_container.setEvaluation(5.0) + self.assertEqual(5.0, codelet_container.getCodelet("Codelet 1").getInputs()[0].getEvaluation(),0) + + + + def test_addMemoryObserverTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.set_infosMemoryObserver(True) + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + codelet_container.addMemoryObserver(codelet_one) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + codelet_container.set_info(10) + mind.start() + self.sleep(2000) + mind.shutdown() + + + codelet_to_test_one : CodeletToTestOne = codelet_container.getCodelet("Codelet 1") + self.assertEqual(6, codelet_to_test_one.counter) + + + + def test_getTimestampTest(self) -> None: + codelet_one = CodeletToTestOne("Codelet 1") + codelet_two = CodeletToTestTwo("Codelet 2") + codelet_three = CodeletToTestThree("Codelet 3") + + mind = Mind() + memory1 = mind.create_memory_object("MEMORY1", 0.12) + memory2 = mind.create_memory_object("MEMORY2", 0.32) + memory3 = mind.create_memory_object("MEMORY3", 0.32) + memory4 = mind.create_memory_object("MEMORY4", 0.32) + + codelet_one.add_input(memory1) + codelet_one.add_broadcast(memory2) + + codelet_two.add_broadcast(memory3) + + codelet_three.add_input(memory4) + + codelet_container_array : list[Codelet] = [] + codelet_container_array.append(codelet_one) + codelet_container_array.append(codelet_two) + codelet_container_array.append(codelet_three) + + codelet_container = CodeletContainer(codelet_container_array, False) + + mind.insert_codelet(codelet_one) + mind.insert_codelet(codelet_two) + mind.insert_codelet(codelet_three) + codelet_container.set_info(10) + mind.start() + self.sleep(2000) + mind.shutdown() + + self.assertGreater(codelet_container.getTimestamp().doubleValue(), 1) + + \ No newline at end of file diff --git a/tests/core/entities/CodeletTest.py b/tests/core/entities/test_CodeletTest.py similarity index 100% rename from tests/core/entities/CodeletTest.py rename to tests/core/entities/test_CodeletTest.py diff --git a/tests/core/entities/test_DisconnectedCodeletTest.py b/tests/core/entities/test_DisconnectedCodeletTest.py new file mode 100644 index 0000000..5896a6c --- /dev/null +++ b/tests/core/entities/test_DisconnectedCodeletTest.py @@ -0,0 +1,27 @@ +import unittest + +from .utils import CodeletMock + +class disconnected_codeletTest (unittest.TestCase): + def setUp(self) -> None: + self.message = "" + + def tearDown(self) -> None: + super().tearDown() + + + def test_disconnected_codelet(self) -> None: + + disconnected_codelet = CodeletMock() + + disconnected_codelet.name = "Disconnected Codelet" + try: + disconnected_codelet.start() + disconnected_codelet.getInput("TYPE", 0) + disconnected_codelet.stop() + except Exception as e: + message = repr(e) + #print("Testing disconnected_codelet:"+e.getMessage()) + + disconnected_codelet.stop() + #print("Codelet stopped !") \ No newline at end of file diff --git a/tests/core/entities/test_MemoryBufferTest.py b/tests/core/entities/test_MemoryBufferTest.py new file mode 100644 index 0000000..f5d913a --- /dev/null +++ b/tests/core/entities/test_MemoryBufferTest.py @@ -0,0 +1,109 @@ +from contextlib import redirect_stdout +import io +import unittest + +from cst_python.core.entities import RawMemory, MemoryBuffer, MemoryObject + +@unittest.skip("MemoryBuffer not implemented") +class MemoryBufferTest(unittest.TestCase): + + @unittest.skip("'setType' is not implemented in Python as is deprecated") + def test_basic_call(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + testList : list[MemoryObject] = [MemoryObject(), MemoryObject(), MemoryObject()] + testList[0].setType("memory_0") + testList[1].setType("memory_1") + testList[2].setType("memory_2") + + memoryBuffer.putList(testList) + + self.assertEqual(3, len(memoryBuffer)) + self.assertEqual(memoryBuffer.get(), memoryBuffer.getAll()) + self.assertEqual(testList[2], memoryBuffer.getMostRecent()) + self.assertEqual(testList[0], memoryBuffer.getOldest()) + + + @unittest.skip("'setType' is not implemented in Python as is deprecated") + def test_puts_more_than_max(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + testList : list[MemoryObject] = [MemoryObject(), MemoryObject(), MemoryObject(), MemoryObject()] + testList[0].setType("memory_0") + testList[1].setType("memory_1") + testList[2].setType("memory_2") + testList[3].setType("memory_3") + memoryBuffer.putList(testList) + + self.assertEqual(3, len(memoryBuffer)) + self.assertEqual(memoryBuffer.get(), memoryBuffer.getAll()) + self.assertEqual(testList[1], memoryBuffer.get()[0]) + + memoryBuffer.put(MemoryObject()) + self.assertEqual(testList[2], memoryBuffer.get()[0]) + + + @unittest.skip("'setType' is not implemented in Python as is deprecated") + def test_put_pop(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + testMemory = MemoryObject() + testMemory.setType("memory_0") + memoryBuffer.put(testMemory) + + self.assertEqual(testMemory, memoryBuffer.pop()) + self.assertEqual(0, len(memoryBuffer)) + + + + def test_null_oldest_and_newest(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + self.assertIsNone(memoryBuffer.getOldest()) + self.assertIsNone(memoryBuffer.getMostRecent()) + + + @unittest.skip("'setType' is not implemented in Python as is deprecated") + def test_remove_and_clear(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + testList : list[MemoryObject] = [MemoryObject(), MemoryObject(), MemoryObject()] + testList[0].setType("memory_0") + testList[1].setType("memory_1") + testList[2].setType("memory_2") + + memoryBuffer.putList(testList) + memoryBuffer.remove(testList[1]) + + self.assertEqual(2, len(memoryBuffer)) + self.assertEqual(testList[2], memoryBuffer.get()[1]) + + memoryBuffer.clear() + self.assertEqual(0, len(memoryBuffer)) + + + @unittest.skip("'setType' is not implemented in Python as is deprecated") + def test_pint_status(self) -> None: + rawMemory = RawMemory() + memoryBuffer = MemoryBuffer(3, rawMemory) + + testList : list[MemoryObject] = [MemoryObject()] + testList[0].setType("memory_0") + memoryBuffer.putList(testList) + + expectedMessage ='''"###### Memory Buffer ########\n# Content: [MemoryObject [idmemoryobject=null, timestamp=null, evaluation=0.0, I=null, name=memory_0]]" + + "\n# Size: 1\n###############################''' + + with redirect_stdout(io.StringIO()) as f: + memoryBuffer.printStatus() + + printed = f.getvalue().replace("\r\n", "\n") + expectedMessage = expectedMessage.replace("\r\n", "\n") + + self.assertTrue(expectedMessage in printed) + \ No newline at end of file diff --git a/tests/core/entities/test_MemoryContainerTest.py b/tests/core/entities/test_MemoryContainerTest.py new file mode 100644 index 0000000..8128013 --- /dev/null +++ b/tests/core/entities/test_MemoryContainerTest.py @@ -0,0 +1,511 @@ +import unittest +from typing import Callable + +from cst_python.core.entities import MemoryContainer, Memory, MemoryObject + +@unittest.skip("Memory Container not implemented") +class MemoryContainerTest (unittest.TestCase): + + def test_memory_container_content(self) -> None: + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(71, 0.1, "TYPE") + memoryContainer.set_info(75, 0.2, "TYPE") + + self.assertEqual(75, memoryContainer.get_info()) + + def test_memory_container_size(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(71, 0.1, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE3") + + self.assertEqual(2, memoryContainer.getAllMemories().size()) + + def test_set_type(self) -> None: + # memoryContainer = MemoryContainer() + # memoryContainer.setType("TYPE") + # self.assertEqual("TYPE", memoryContainer.get_name()) + + memoryContainer = MemoryContainer() + memoryContainer.set_name("TYPE2") + self.assertEqual("TYPE2", memoryContainer.get_name()) + + memoryContainer = MemoryContainer("TYPE3") + self.assertEqual("TYPE3", memoryContainer.get_name()) + + def test_get_type(self) -> None: + memoryContainer = MemoryContainer("TYPE-Container") + memoryContainer.set_info("value", 1.0, "TYPE") + self.assertEqual(memoryContainer.get_info("TYPE"), "value") + print("-- This test will raise a warning ...") + self.assertIsNone(memoryContainer.get_info("TYPE2")) + + def test_get_i(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(71, 0.1, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + + self.assertEqual(70, memoryContainer.get_info()) + self.assertEqual(75, memoryContainer.get_info(0)) + print("-- This test will raise a warning ...") + # This test will raise a warning for index greater than the number of stored memories + self.assertIsNone(memoryContainer.get_info(2)) + self.assertEqual(70, memoryContainer.get_info("TYPE3")) + + def test_get_i_predicate(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(71, 0.1, "TYPE2") + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + memoryContainer.set_info(70, 0.25) + + pred: Callable[[Memory], bool] = lambda m: m.get_name() == "TYPE2" + + self.assertEqual(75, memoryContainer.get_info(pred)) + + def test_get_i_accumulator(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + memoryContainer.set_info(80) + + binaryOperator: Callable[[Memory, Memory], Memory] = lambda mem1, mem2: mem1 if mem1.get_evaluation( + ) <= mem2.get_evaluation() else mem2 + + self.assertEqual(80, memoryContainer.get_info(binaryOperator)) + + def test_set_i_specific(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + memoryContainer.set_info(80) + + memoryContainer.set_info(60, 1) + memoryContainer.set_info(90, 0.5, 2) + + self.assertEqual(60, memoryContainer.get_info(1)) + self.assertEqual(90, memoryContainer.get_info()) + self.assertEqual(0.5, memoryContainer.get_evaluation(), 0) + + def test_set_evaluation(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + + memoryContainer.set_info(90, 0.5, 2) + + self.assertEqual(70, memoryContainer.get_info()) + memoryContainer.set_evaluation(0.5, 0) + self.assertEqual(75, memoryContainer.get_info()) + + def test_set_evaluation_last(self) -> None: + memoryContainer = MemoryContainer("TYPE") + print("-- This test will raise a warning ...") + memoryContainer.set_evaluation(2.0) + self.assertEqual(memoryContainer.get_evaluation(), None) + memoryContainer.set_info("message") + memoryContainer.set_evaluation(2.0) + self.assertEqual(memoryContainer.get_evaluation(), 2.0) + + def test_get_timestamp_not_valid(self) -> None: + memoryContainer = MemoryContainer("TYPE") + print("-- This test will raise a warning ...") + ts: int = memoryContainer.get_timestamp() + self.assertEqual(ts, None) + memoryContainer.set_info("message") + ts = memoryContainer.get_timestamp() + self.assertTrue(ts != None) + + def test_add(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + memoryContainer.add(MemoryObject()) + + self.assertEqual(3, memoryContainer.getAllMemories().size()) + + def test_get_internal(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + + self.assertEqual( + 75, memoryContainer.getInternalMemory("TYPE2").get_info()) + self.assertIsNone(memoryContainer.getInternalMemory("TYPE4")) + + def test_get_timestamp(self) -> None: + + memoryContainer = MemoryContainer("TYPE") + + memoryContainer.set_info(75, 0.2, "TYPE2") + memoryContainer.set_info(70, 0.3, "TYPE3") + + self.assertEqual(memoryContainer.getInternalMemory("TYPE3").get_timestamp(), + memoryContainer.get_timestamp()) + + def test_max_policy(self) -> None: + memoryContainer = MemoryContainer("MAX") + memoryContainer.setPolicy(Policy.MAX) + m1 = memoryContainer.set_info(1, 0.2) + m2 = memoryContainer.set_info(2, 0.4) + m3 = memoryContainer.set_info(3, 0.8) + i: int = memoryContainer.get_info() + self.assertEqual(i, 3) + memoryContainer.set_evaluation(0.1) + i: int = memoryContainer.get_info() + self.assertEqual(i, 2) + memoryContainer.set_evaluation(0.1) + i: int = memoryContainer.get_info() + self.assertEqual(i, 1) + memoryContainer.set_evaluation(0.1, m1) + memoryContainer.set_evaluation(0.1, m2) + memoryContainer.set_evaluation(0.1, m3) + + for j in range(20): + m: int = memoryContainer.get_info() + ver: bool = (m == 1 or m == 2 or m == 3) + self.assertEqual(ver, True) + # print("max: "+m) + + memoryContainer.set_evaluation(0.05, m1) + for j in range(20): + m: int = memoryContainer.get_info() + ver: bool = (m == 2 or m == 3) + self.assertEqual(ver, True) + # print("max2: "+m) + + def test_max_policy_with_same_eval(self) -> None: + memoryContainer = MemoryContainer("MAX") + memoryContainer.setPolicy(Policy.MAX) + m1 = memoryContainer.set_info(1, 0.2) + m2 = memoryContainer.set_info(2, 0.2) + m3 = memoryContainer.set_info(3, 0.2) + i = -1 + oldi = 0 + for j in range(10): + oldi = i + # Despite the choice is random, if no chance in I happens, it stays the same + i: int = memoryContainer.get_info() + if (j > 0): + self.assertEqual(oldi, i) + + i2: int = 0 + k = 0 + + while True: + memoryContainer.set_info(1, m1) + memoryContainer.set_info(2, m2) + memoryContainer.set_info(3, m3) + i2: int = memoryContainer.get_info() + + k += 1 + + if not (i2 == i and k < 100): + break + + self.assertTrue(k != 100) + + def test_min_policy_with_same_eval(self) -> None: + memoryContainer = MemoryContainer("MIN") + memoryContainer.setPolicy(Policy.MIN) + m1: int = memoryContainer.set_info(1, 0.2) + m2: int = memoryContainer.set_info(2, 0.2) + m3: int = memoryContainer.set_info(3, 0.2) + i = -1 + oldi = 0 + for j in range(10): + oldi = i + # Despite the choice is random, if no chance in I happens, it stays the same + i: int = memoryContainer.get_info() + if (j > 0): + self.assertEqual(oldi, i) + + i2 = 0 + k = 0 + while True: + # Changing I will trigger a different choice, though ! + memoryContainer.set_info(1, m1) + memoryContainer.set_info(2, m2) + memoryContainer.set_info(3, m3) + i2: int = memoryContainer.get_info() + k += 1 + if not (i2 == i and k < 100): + break + self.assertTrue(k != 100) + + def test_max_unique_policy(self) -> None: + memoryContainer = MemoryContainer("MAX") + memoryContainer.setPolicy(Policy.MAX) + memoryContainer.set_info(1) + i: int = memoryContainer.get_info() + self.assertEqual(i, 1) + + def test_min_policy(self) -> None: + memoryContainer = MemoryContainer("MIN") + memoryContainer.setPolicy(Policy.MIN) + m1: int = memoryContainer.set_info(1, 0.2) + m2: int = memoryContainer.set_info(2, 0.4) + m3: int = memoryContainer.set_info(3, 0.8) + i: int = memoryContainer.get_info() + self.assertEqual(i, 1) + memoryContainer.set_evaluation(0.9) + i: int = memoryContainer.get_info() + self.assertEqual(i, 2) + memoryContainer.set_evaluation(0.9) + i: int = memoryContainer.get_info() + self.assertEqual(i, 3) + memoryContainer.set_evaluation(0.1, m1) + memoryContainer.set_evaluation(0.1, m2) + memoryContainer.set_evaluation(0.1, m3) + for k in range(20): + m: int = memoryContainer.get_info() + ver: bool = (m == 1 or m == 2 or m == 3) + self.assertEqual(ver, True) + # print("min: "+m) + + memoryContainer.set_evaluation(0.2, m1) + for k in range(20): + m: int = memoryContainer.get_info() + ver: bool = (m == 2 or m == 3) + self.assertEqual(ver, True) + # print("min2: "+m) + + def test_random_proportional_policy(self) -> None: + memoryContainer = MemoryContainer("RANDOMPROPORTIONAL") + memoryContainer.setPolicy(Policy.RANDOM_PROPORTIONA) + memoryContainer.set_info(1, 0.2) # 14 % + memoryContainer.set_info(2, 0.4) # 28 % + memoryContainer.set_info(3, 0.8) # 57 % + count = [0, 0, 0] + for i in range(1000): + j: int = memoryContainer.get_info() + count[j-1] += 1 + + # print("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]) + self.assertEqual(count[0] < count[1], True) + self.assertEqual(count[1] < count[2], True) + memoryContainer.set_evaluation(0.8, 0) + memoryContainer.set_evaluation(0.4, 1) + memoryContainer.set_evaluation(0.2, 2) + count = int[3] + for i in range(1000): + j: int = memoryContainer.get_info() + count[j-1] += 1 + + # print("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]) + self.assertEqual(count[0] > count[1], True) + self.assertEqual(count[1] > count[2], True) + memoryContainer.set_info(1, 0.5, 0) + memoryContainer.set_info(2, 0.0, 1) + memoryContainer.set_info(3, 0.0, 2) + for i in range(5): + j: int = memoryContainer.get_info() + self.assertEqual(j, 1) + + memoryContainer.set_info(1, 0.0, 0) + memoryContainer.set_info(2, 0.5, 1) + memoryContainer.set_info(3, 0.0, 2) + for i in range(5): + j: int = memoryContainer.get_info() + self.assertEqual(j, 2) + + memoryContainer.set_info(1, 0.0, 0) + memoryContainer.set_info(2, 0.0, 1) + memoryContainer.set_info(3, 0.5, 2) + for i in range(5): + j: int = memoryContainer.get_info() + self.assertEqual(j, 3) + + memoryContainer.set_info(1, 0.0, 0) + memoryContainer.set_info(2, 0.0, 1) + memoryContainer.set_info(3, 0.0, 2) + count = int[3] + for i in range(30): + j: int = memoryContainer.get_info() + count[j-1] += 1 + + # print("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]) + self.assertEqual(count[0] > 0, True) + self.assertEqual(count[1] > 0, True) + self.assertEqual(count[2] > 0, True) + + def test_random_proportional_stable_policy(self) -> None: + memoryContainer = MemoryContainer("RANDOMPROPORTIONALSTABLE") + memoryContainer.setPolicy(Policy.RANDOM_PROPORTIONAL_STABLE) + n = memoryContainer.set_info(1, 0.2) # 14 % + memoryContainer.set_info(2, 0.4) # 28 % + memoryContainer.set_info(3, 0.8) # 57 % + count = [0, 0, 0] + first = 0 + for i in range(1000): + j: int = memoryContainer.get_info() + if (i == 0): + first = j-1 + count[j-1] += 1 + + # print("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]+" first:"+first) + for i in range(3): + if (i == first): + self.assertEqual(count[i] > 0, True) + else: + self.assertEqual(count[i] > 0, False) + + count[0] = 0 + count[1] = 0 + count[2] = 0 + for i in range(1000): + memoryContainer.set_info(1, 0.2, n) + j: int = memoryContainer.get_info() + count[j-1] += 1 + + # print("[0]: "+count[0]+" [1]: "+count[1]+" [2]: "+count[2]) + self.assertEqual(count[0] < count[1], True) + self.assertEqual(count[1] < count[2], True) + + def test_random_flat(self) -> None: + memoryContainer = MemoryContainer("RANDOMFLAT") + memoryContainer.setPolicy(Policy.RANDOM_FLAT) + memoryContainer.set_info(1, 0.2) # 14 % + memoryContainer.set_info(2, 0.4) # 28 % + memoryContainer.set_info(3, 0.8) # 57 % + count = [0, 0, 0] + for i in range(1000): + j: int = memoryContainer.get_info() + count[j-1] += 1 + + self.assertEqual(count[0] > 0, True) + self.assertEqual(count[1] > 0, True) + self.assertEqual(count[2] > 0, True) + + def test_random_flat_stable(self) -> None: + memoryContainer = MemoryContainer("RANDOMFLATSTABLE") + memoryContainer.setPolicy(Policy.RANDOM_FLAT_STABLE) + n1 = memoryContainer.set_info(1, 0.2) # 14 % + memoryContainer.set_info(2, 0.4) # 28 % + memoryContainer.set_info(3, 0.8) # 57 % + count = [0, 0, 0] + first = 0 + for i in range(1000): + j: int = memoryContainer.get_info() + if (i == 0): + first = j-1 + count[j-1] += 1 + + for i in range(3): + if (i == first): + self.assertEqual(count[i] > 0, True) + else: + self.assertEqual(count[i] > 0, False) + + count[0] = 0 + count[1] = 0 + count[2] = 0 + for i in range(1000): + memoryContainer.set_info(1, 0.2, n1) + j: int = memoryContainer.get_info() + if (i == 0): + first = j-1 + count[j-1] += 1 + + self.assertEqual(count[0] > 0, True) + self.assertEqual(count[1] > 0, True) + self.assertEqual(count[2] > 0, True) + + def test_iterate_policy(self) -> None: + memoryContainer = MemoryContainer("ITERATE") + memoryContainer.setPolicy(Policy.ITERATE) + print("-- This test will raise a warning ...") + k: int = memoryContainer.get_info() + self.assertIsNone(k) + memoryContainer.set_info(1) + memoryContainer.set_info(2) + memoryContainer.set_info(3) + for i in range(9): + j: int = memoryContainer.get_info() + self.assertEqual(j, i % 3+1) + + def test_get_evaluation(self) -> None: + memoryContainer = MemoryContainer("TEST") + self.assertEqual(memoryContainer.get(-1), None) + self.assertEqual(memoryContainer.get(0), None) + self.assertEqual(memoryContainer.get(10), None) + self.assertEqual(memoryContainer.get_name(), "TEST") + memoryContainer.set_name("TEST-NEW") + self.assertEqual(memoryContainer.get_name(), "TEST-NEW") + memoryContainer.setType("TEST-NEW") + self.assertEqual(memoryContainer.get_name(), "TEST-NEW") + # Testing the getEvaluation without any included MemoryObject + self.assertEqual(memoryContainer.get_evaluation(), None) + self.assertEqual(memoryContainer.get_evaluation(0), None) + self.assertEqual(memoryContainer.get_evaluation(1), None) + self.assertEqual(memoryContainer.getPolicy(), Policy.MAX) + res: float = memoryContainer.get_evaluation() + self.assertEqual(res, None) + memoryContainer.set_info(1) + memoryContainer.set_evaluation(0.5) + self.assertEqual(memoryContainer.get_evaluation(), 0.5) + self.assertEqual(memoryContainer.get_evaluation(0), 0.5) + memoryContainer.setPolicy(Policy.ITERATE) + self.assertEqual(memoryContainer.getPolicy(), Policy.ITERATE) + i: int = memoryContainer.get_info() + self.assertEqual(i, 1) + i: int = memoryContainer.getLastI() + self.assertEqual(i, 1) + mo: MemoryObject = memoryContainer.getLast() + i: int = mo.get_info() + self.assertEqual(i, 1) + memoryContainer.set_evaluation(0.6, 0) + self.assertEqual(memoryContainer.get_evaluation(), 0.6) + self.assertEqual(memoryContainer.get_evaluation(0), 0.6) + + def test_get_timestamp(self) -> None: + memoryContainer = MemoryContainer("TEST") + # Without any initialization, the timestamp must be None + self.assertEqual(memoryContainer.get_timestamp(), None) + print("This test will raise a warning...") + self.assertEqual(memoryContainer.get_timestamp(0), None) + print("This test will raise a warning...") + self.assertEqual(memoryContainer.get_timestamp(1), None) + # after we initialize the container, the timestamp must be something different from None + memoryContainer.set_info(1) + self.assertEqual(memoryContainer.get_timestamp() != None, True) + self.assertEqual(memoryContainer.get_timestamp(0) != None, True) + # nevertheless, if we go further, it should remain None + print("This test will raise a warning...") + self.assertEqual(memoryContainer.get_timestamp(1), None) + self.assertEqual(memoryContainer.get( + 0).get_info(), memoryContainer.get_info()) + + def test_double_indirection(self) -> None: + mc1: MemoryContainer = MemoryContainer("TEST1") + mc2: MemoryContainer = MemoryContainer("TEST2") + mc2.set_info(0) + mc1.add(mc2) + self.assertEqual(mc1.get_info(), 0) + mc1.set_info(1, 0.5, 0) + self.assertEqual(mc1.get_info(), 1) + mc1.set_evaluation(0.6, 0) + self.assertEqual(mc1.get_evaluation(), 0.6) diff --git a/tests/core/entities/MemoryObjectTest.py b/tests/core/entities/test_MemoryObjectTest.py similarity index 100% rename from tests/core/entities/MemoryObjectTest.py rename to tests/core/entities/test_MemoryObjectTest.py diff --git a/tests/core/entities/MemoryTest.py b/tests/core/entities/test_MemoryTest.py similarity index 100% rename from tests/core/entities/MemoryTest.py rename to tests/core/entities/test_MemoryTest.py diff --git a/tests/core/entities/RawMemoryTest.py b/tests/core/entities/test_RawMemoryTest.py similarity index 100% rename from tests/core/entities/RawMemoryTest.py rename to tests/core/entities/test_RawMemoryTest.py diff --git a/tests/core/entities/MindTest.py b/tests/core/entities/test_mind.py similarity index 98% rename from tests/core/entities/MindTest.py rename to tests/core/entities/test_mind.py index d23628d..3a44d81 100644 --- a/tests/core/entities/MindTest.py +++ b/tests/core/entities/test_mind.py @@ -4,7 +4,7 @@ from .utils import CodeletMock -class MindTest(unittest.TestCase): +class TestMind(unittest.TestCase): def setUp(self) -> None: self.test_codelet = CodeletMock() self.mind = Mind() From a61f87e8a0282bb2e0d8050ba6b699bec89693e7 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:02:15 -0300 Subject: [PATCH 06/59] Test pipeline configuration --- .github/workflows/pipeline-windows.yml | 33 ------------------- .../{pipeline-ubuntu.yml => test.yml} | 13 ++++---- 2 files changed, 6 insertions(+), 40 deletions(-) delete mode 100644 .github/workflows/pipeline-windows.yml rename .github/workflows/{pipeline-ubuntu.yml => test.yml} (72%) diff --git a/.github/workflows/pipeline-windows.yml b/.github/workflows/pipeline-windows.yml deleted file mode 100644 index 253feaa..0000000 --- a/.github/workflows/pipeline-windows.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: evolvepy CI/CD -on: - push: - branches: [ develop, main ] - pull_request: - branches: [ develop, main ] - -jobs: - build: - - runs-on: windows-latest - strategy: - fail-fast: false - matrix: - python-version: ["3.7","3.8", "3.9", "3.10"] - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - python3 -m pip install pytest - if [ -f setup.cfg ]; then python3 -m pip install . ; fi - - - name: Test with pytest - run: | - cd ./test - pytest - shell: bash \ No newline at end of file diff --git a/.github/workflows/pipeline-ubuntu.yml b/.github/workflows/test.yml similarity index 72% rename from .github/workflows/pipeline-ubuntu.yml rename to .github/workflows/test.yml index c353c6a..6821505 100644 --- a/.github/workflows/pipeline-ubuntu.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: evolvepy CI/CD +name: Test on: push: branches: [ develop, main ] @@ -8,27 +8,26 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - python-version: ["3.7","3.8", "3.9"] + os: [ubuntu-latest, windows-latest] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies run: | python3 -m pip install --upgrade pip python3 -m pip install pytest - if [ -f setup.cfg ]; then python3 -m pip install . ; fi + python3 -m pip install .[tests] - - name: Test with pytest + - name: Tests run: | pytest shell: bash \ No newline at end of file From 6de63473836cfca63c7441fdff6bb244902b5721 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:09:56 -0300 Subject: [PATCH 07/59] Update .gitignore --- .gitignore | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 159 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 895864c..efa407c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,162 @@ +# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] -*.pyc -*.whl -*.gz -*.egg-info/ +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ dist/ -build/ \ No newline at end of file +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file From 01d714e88bf5ee68a1ea81e642dad43d650628a3 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:30:06 -0300 Subject: [PATCH 08/59] Coverage check --- .github/workflows/test.yml | 13 +++++++++---- .gitignore | 2 ++ tests/check_coverage.py | 8 ++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 tests/check_coverage.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6821505..b497ad2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,9 +1,9 @@ name: Test on: push: - branches: [ develop, main ] + branches: [ dev, main ] pull_request: - branches: [ develop, main ] + branches: [ dev, main ] jobs: build: @@ -25,9 +25,14 @@ jobs: run: | python3 -m pip install --upgrade pip python3 -m pip install pytest + python3 -m pip install pytest-cov python3 -m pip install .[tests] - name: Tests run: | - pytest - shell: bash \ No newline at end of file + pytest --cov=cst_python --cov-report json + shell: bash + + - name: Coverage Check + run: | + python3 tests/check_coverage.py \ No newline at end of file diff --git a/.gitignore b/.gitignore index efa407c..d5e6f4c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +coverage.json + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/tests/check_coverage.py b/tests/check_coverage.py new file mode 100644 index 0000000..044a576 --- /dev/null +++ b/tests/check_coverage.py @@ -0,0 +1,8 @@ +import json + +if __name__ == "__main__": + + with open("coverage.json") as file: + coverage_info = json.load(file) + + assert coverage_info["totals"]["percent_covered"] > 78 \ No newline at end of file From 3e6c803e6978ac9af0e742b98eaf2aa235b74b3c Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:36:28 -0300 Subject: [PATCH 09/59] Set coverage minimum to 75% --- tests/check_coverage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/check_coverage.py b/tests/check_coverage.py index 044a576..7b59da5 100644 --- a/tests/check_coverage.py +++ b/tests/check_coverage.py @@ -5,4 +5,4 @@ with open("coverage.json") as file: coverage_info = json.load(file) - assert coverage_info["totals"]["percent_covered"] > 78 \ No newline at end of file + assert coverage_info["totals"]["percent_covered"] > 75 \ No newline at end of file From d73f62b0cabe6fd464c1b67e57f21528ad9198d6 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:39:14 -0300 Subject: [PATCH 10/59] Introduction to CST --- examples/Introduction to CST-Python.ipynb | 571 ++++++++++++++++++ setup.cfg | 3 + tests/{core => cst_python}/__init__.py | 0 .../entities => cst_python/core}/__init__.py | 0 tests/cst_python/core/entities/__init__.py | 0 .../core/entities/test_CoalitionTest.py | 0 .../core/entities/test_CodeRackTest.py | 0 .../entities/test_CodeletContainerTest.py | 0 .../core/entities/test_CodeletTest.py | 0 .../entities/test_DisconnectedCodeletTest.py | 0 .../core/entities/test_MemoryBufferTest.py | 0 .../core/entities/test_MemoryContainerTest.py | 0 .../core/entities/test_MemoryObjectTest.py | 0 .../core/entities/test_MemoryTest.py | 0 .../core/entities/test_RawMemoryTest.py | 0 .../core/entities/test_mind.py | 0 tests/{ => cst_python}/core/entities/utils.py | 0 tests/examples/__init__.py | 0 .../test_introduction_to_cst_python.py | 38 ++ tests/utils.py | 11 + 20 files changed, 623 insertions(+) create mode 100644 examples/Introduction to CST-Python.ipynb rename tests/{core => cst_python}/__init__.py (100%) rename tests/{core/entities => cst_python/core}/__init__.py (100%) create mode 100644 tests/cst_python/core/entities/__init__.py rename tests/{ => cst_python}/core/entities/test_CoalitionTest.py (100%) rename tests/{ => cst_python}/core/entities/test_CodeRackTest.py (100%) rename tests/{ => cst_python}/core/entities/test_CodeletContainerTest.py (100%) rename tests/{ => cst_python}/core/entities/test_CodeletTest.py (100%) rename tests/{ => cst_python}/core/entities/test_DisconnectedCodeletTest.py (100%) rename tests/{ => cst_python}/core/entities/test_MemoryBufferTest.py (100%) rename tests/{ => cst_python}/core/entities/test_MemoryContainerTest.py (100%) rename tests/{ => cst_python}/core/entities/test_MemoryObjectTest.py (100%) rename tests/{ => cst_python}/core/entities/test_MemoryTest.py (100%) rename tests/{ => cst_python}/core/entities/test_RawMemoryTest.py (100%) rename tests/{ => cst_python}/core/entities/test_mind.py (100%) rename tests/{ => cst_python}/core/entities/utils.py (100%) create mode 100644 tests/examples/__init__.py create mode 100644 tests/examples/test_introduction_to_cst_python.py create mode 100644 tests/utils.py diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb new file mode 100644 index 0000000..6c7439e --- /dev/null +++ b/examples/Introduction to CST-Python.ipynb @@ -0,0 +1,571 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to CST-Python\n", + "\n", + "The CST (Cognitive Systems Toolkit) is a code toolkit for creating agents that implements Cognitive Architectures, that is, computational models of cognitive process in the mind of living beings. The core toolkit is the [Java CST](https://cst.fee.unicamp.br/), and CST-Python is a compatible implementation in Python.\n", + "\n", + "For building architectures, the CST defines three basic elements: Memory, Codelet and Mind, that will be presented in this tutorial." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets start by importing the CST-Python and other required modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "\n", + "import cst_python as cst" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Memories: storing data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first element is the `Memory`. Memories are used to store data that are processed by the agent. That are many classes that implements the basic `Memory` class, but the most simple and used is the `MemoryObject`.\n", + "\n", + "Lets create one, and set it's name:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "memory = cst.MemoryObject()\n", + "\n", + "memory.set_name(\"My Memory\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can check that the MemoryObject is a type of Memory:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [ + "check_interface" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "isinstance(memory, cst.core.entities.Memory)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each Memory has a integer id, a unique identifier (that are some details about when the 'id' is really unique), and a name:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [ + "basic_memory_members" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 'My Memory')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.get_id(), memory.get_name()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And a `info`, the information that memory is actually storing. Because we didn't set any info, the current is `None`:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "check_empty_memory" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.get_info() is None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's set a info. They can be any variable of any type:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "set_info" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.set_info(\"My Memory's data\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now see that the stored info changed. Also, each Memory has a `timestamp`, they store the time when the memory's info have changed:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "check_info_change" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(\"My Memory's data\", 1729269027698)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.get_info(), memory.get_timestamp()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Codelets: cognitive processes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But, a agent can't do nothing with only data. `Codelets` are elements of the architecture that process data, executing the agent's cognitive processes.\n", + "\n", + "Each Codelet can have some input and output memories. They can also be local or global, we will only use local inputs/outputs in this example." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For creating a codelet, we need to define the methods:\n", + "- `access_memory_objects`: gets all the memories the codelet is going to use, localizable by name.\n", + "- `calculate_activation`: computes the codelet's activation. We are not going to use this now.\n", + "- `proc`: the actual function that the codelet performs, reading from the inputs, processing and setting the outputs." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our first codelet is going to read a input value, adding one and sending this value to other memory:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "class MyFirstCodelet(cst.Codelet):\n", + "\n", + " def __init__(self):\n", + " super().__init__()\n", + "\n", + " self._input_mo : cst.MemoryObject | None = None\n", + " self._output_mo : cst.MemoryObject | None = None\n", + "\n", + "\n", + " def access_memory_objects(self):\n", + " self._input_mo = self.get_input(name=\"InputMemory\")\n", + " self._output_mo = self.get_output(name=\"OutputMemory\")\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " read_value : float = self._input_mo.get_info()\n", + " \n", + " output_value = read_value + 1\n", + "\n", + " self._output_mo.set_info(output_value)\n", + "\n", + "my_first_codelet = MyFirstCodelet()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before we can use the codelet, we need to create and add it's input and output, and execute `access_memory_objects`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "input_memory = cst.MemoryObject()\n", + "input_memory.set_name(\"InputMemory\")\n", + "\n", + "output_memory = cst.MemoryObject()\n", + "output_memory.set_name(\"OutputMemory\")\n", + "\n", + "my_first_codelet.add_input(input_memory)\n", + "my_first_codelet.add_output(output_memory)\n", + "\n", + "my_first_codelet.access_memory_objects()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets test it by setting the info, running the `proc` and checking if the output value is correct:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [ + "check_codelet_working" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_memory.set_info(0)\n", + "\n", + "my_first_codelet.proc()\n", + "\n", + "output_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mind: organizing everything" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can create all the data and cognitive process of the agent, but they need to be manually managed.\n", + "\n", + "The `Mind` element contains all the memories in its `RawMemory` and all the codelets in its `Coderack`. It also manage the execution of all the codelets and is the expected way to create an agent with CST." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets create a Mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "mind = cst.Mind()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using a Mind, all the MemoryObjects need to be create by it (now each memory is guaranteed to have a unique id). We can also pass a default value, in this case `0` to the \"InputMemory\":" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "input_memory = mind.create_memory_object(\"InputMemory\", 0)\n", + "output_memory = mind.create_memory_object(\"OutputMemory\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create the codelet and add it's inputs and outputs as before:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "my_first_codelet = MyFirstCodelet()\n", + "my_first_codelet.add_input(input_memory)\n", + "my_first_codelet.add_output(output_memory)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But now insert it into the Mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.MyFirstCodelet at 0x1a3cef18f10>" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mind.insert_codelet(my_first_codelet)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When running using a Mind, it will run each codelet in a separated thread at a fixed rate. The default `time step` is 300 ms. Lets change it to 100 ms for a faster execution:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "my_first_codelet.time_step = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `start` method start the Mind and the execution of all the codelets:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "mind.start()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After waiting our codelet run by 110 ms, we can check the added value in the ouput memory: " + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "check_mind_scheduling" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time.sleep(0.110)\n", + "\n", + "output_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also change the input memory, wait and check the modified value in the output:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "tags": [ + "example_change_memory" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "124" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_memory.set_info(123)\n", + "\n", + "time.sleep(0.110)\n", + "\n", + "output_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `shutdown` method stops the execution of the Mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "mind.shutdown()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/setup.cfg b/setup.cfg index 50a2a2d..c2b9063 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,3 +28,6 @@ packages = find: [options.packages.find] where = src + +[options.extras_require] +tests = mypy; testbook; ipython; ipykernel \ No newline at end of file diff --git a/tests/core/__init__.py b/tests/cst_python/__init__.py similarity index 100% rename from tests/core/__init__.py rename to tests/cst_python/__init__.py diff --git a/tests/core/entities/__init__.py b/tests/cst_python/core/__init__.py similarity index 100% rename from tests/core/entities/__init__.py rename to tests/cst_python/core/__init__.py diff --git a/tests/cst_python/core/entities/__init__.py b/tests/cst_python/core/entities/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/core/entities/test_CoalitionTest.py b/tests/cst_python/core/entities/test_CoalitionTest.py similarity index 100% rename from tests/core/entities/test_CoalitionTest.py rename to tests/cst_python/core/entities/test_CoalitionTest.py diff --git a/tests/core/entities/test_CodeRackTest.py b/tests/cst_python/core/entities/test_CodeRackTest.py similarity index 100% rename from tests/core/entities/test_CodeRackTest.py rename to tests/cst_python/core/entities/test_CodeRackTest.py diff --git a/tests/core/entities/test_CodeletContainerTest.py b/tests/cst_python/core/entities/test_CodeletContainerTest.py similarity index 100% rename from tests/core/entities/test_CodeletContainerTest.py rename to tests/cst_python/core/entities/test_CodeletContainerTest.py diff --git a/tests/core/entities/test_CodeletTest.py b/tests/cst_python/core/entities/test_CodeletTest.py similarity index 100% rename from tests/core/entities/test_CodeletTest.py rename to tests/cst_python/core/entities/test_CodeletTest.py diff --git a/tests/core/entities/test_DisconnectedCodeletTest.py b/tests/cst_python/core/entities/test_DisconnectedCodeletTest.py similarity index 100% rename from tests/core/entities/test_DisconnectedCodeletTest.py rename to tests/cst_python/core/entities/test_DisconnectedCodeletTest.py diff --git a/tests/core/entities/test_MemoryBufferTest.py b/tests/cst_python/core/entities/test_MemoryBufferTest.py similarity index 100% rename from tests/core/entities/test_MemoryBufferTest.py rename to tests/cst_python/core/entities/test_MemoryBufferTest.py diff --git a/tests/core/entities/test_MemoryContainerTest.py b/tests/cst_python/core/entities/test_MemoryContainerTest.py similarity index 100% rename from tests/core/entities/test_MemoryContainerTest.py rename to tests/cst_python/core/entities/test_MemoryContainerTest.py diff --git a/tests/core/entities/test_MemoryObjectTest.py b/tests/cst_python/core/entities/test_MemoryObjectTest.py similarity index 100% rename from tests/core/entities/test_MemoryObjectTest.py rename to tests/cst_python/core/entities/test_MemoryObjectTest.py diff --git a/tests/core/entities/test_MemoryTest.py b/tests/cst_python/core/entities/test_MemoryTest.py similarity index 100% rename from tests/core/entities/test_MemoryTest.py rename to tests/cst_python/core/entities/test_MemoryTest.py diff --git a/tests/core/entities/test_RawMemoryTest.py b/tests/cst_python/core/entities/test_RawMemoryTest.py similarity index 100% rename from tests/core/entities/test_RawMemoryTest.py rename to tests/cst_python/core/entities/test_RawMemoryTest.py diff --git a/tests/core/entities/test_mind.py b/tests/cst_python/core/entities/test_mind.py similarity index 100% rename from tests/core/entities/test_mind.py rename to tests/cst_python/core/entities/test_mind.py diff --git a/tests/core/entities/utils.py b/tests/cst_python/core/entities/utils.py similarity index 100% rename from tests/core/entities/utils.py rename to tests/cst_python/core/entities/utils.py diff --git a/tests/examples/__init__.py b/tests/examples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/examples/test_introduction_to_cst_python.py b/tests/examples/test_introduction_to_cst_python.py new file mode 100644 index 0000000..782db9c --- /dev/null +++ b/tests/examples/test_introduction_to_cst_python.py @@ -0,0 +1,38 @@ +import os +import json + +from testbook import testbook +from testbook.client import TestbookNotebookClient + +from ..utils import get_examples_path + +examples_path = get_examples_path() + +@testbook(os.path.join(examples_path, "Introduction to CST-Python.ipynb"), execute=True) +def test_introduction(tb :TestbookNotebookClient): + result = tb.cell_output_text("check_interface") + assert result == "True" + + result = tb.cell_output_text("basic_memory_members") + assert result == "(0, 'My Memory')" + + result = tb.cell_output_text("check_empty_memory") + assert result == "True" + + result = tb.cell_output_text("set_info") + assert result == "-1" + + result = tb.cell_output_text("check_info_change") + result = eval(result) + assert result[0] == "My Memory's data" + + result = tb.cell_output_text("check_codelet_working") + assert result == "1" + + result = tb.cell_output_text("check_mind_scheduling") + assert result == "1" + + result = tb.cell_output_text("example_change_memory") + assert result == "124" + + diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..600c85f --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,11 @@ +import os +import pathlib + + +def get_repository_path(): + repository_path = pathlib.Path(__file__).parent.parent.resolve() + return repository_path + +def get_examples_path(): + examples_path = os.path.join(get_repository_path(), "examples") + return examples_path \ No newline at end of file From dc2b288103b388855aca624f02765cbe2663acad Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:47:59 -0300 Subject: [PATCH 11/59] Fix questions about introduction --- examples/Introduction to CST-Python.ipynb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb index 6c7439e..857941c 100644 --- a/examples/Introduction to CST-Python.ipynb +++ b/examples/Introduction to CST-Python.ipynb @@ -224,7 +224,7 @@ "source": [ "But, a agent can't do nothing with only data. `Codelets` are elements of the architecture that process data, executing the agent's cognitive processes.\n", "\n", - "Each Codelet can have some input and output memories. They can also be local or global, we will only use local inputs/outputs in this example." + "Each Codelet can have any number of inputs and outputs memories. They can also be local or global, we will only use local inputs/outputs in this example." ] }, { @@ -234,7 +234,9 @@ "For creating a codelet, we need to define the methods:\n", "- `access_memory_objects`: gets all the memories the codelet is going to use, localizable by name.\n", "- `calculate_activation`: computes the codelet's activation. We are not going to use this now.\n", - "- `proc`: the actual function that the codelet performs, reading from the inputs, processing and setting the outputs." + "- `proc`: the actual function that the codelet performs, reading from the inputs, processing and setting the outputs.\n", + "\n", + "It is important to note that the codelet should only get inputs in the `access_memory_objects`, not in `proc`. The content of the memories (info) can be accessed everywhere." ] }, { From 2065cb3f29931867de37ec39b40839d82c1331fc Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:05:03 -0300 Subject: [PATCH 12/59] Add shape library --- resources/CST-Library.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 resources/CST-Library.xml diff --git a/resources/CST-Library.xml b/resources/CST-Library.xml new file mode 100644 index 0000000..cbcc92b --- /dev/null +++ b/resources/CST-Library.xml @@ -0,0 +1,22 @@ +[ + { + "xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><mxCell id=\"2\" value=\"\" style=\"group\" vertex=\"1\" connectable=\"0\" parent=\"1\"><mxGeometry width=\"163\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"3\" value=\"&lt;font style=&quot;font-size: 12px&quot;&gt;Behavioral&lt;br&gt;Codelet&lt;/font&gt;\" style=\"rounded=1;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#ffcc99;strokeColor=#36393d;\" vertex=\"1\" parent=\"2\"><mxGeometry x=\"15.49647887323944\" width=\"132.00704225352115\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;O&lt;/font&gt;\" style=\"whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcccc;strokeColor=#36393d;fontSize=8;\" vertex=\"1\" parent=\"2\"><mxGeometry x=\"147.50352112676057\" y=\"9.999999999999998\" width=\"15.49647887323944\" height=\"15\" as=\"geometry\"/></mxCell><mxCell id=\"5\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;A&lt;/font&gt;\" style=\"whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcccc;strokeColor=#36393d;fontSize=8;\" vertex=\"1\" parent=\"2\"><mxGeometry x=\"147.50352112676057\" y=\"34.99999999999999\" width=\"15.49647887323944\" height=\"15\" as=\"geometry\"/></mxCell><mxCell id=\"6\" value=\"&lt;font style=&quot;font-size: 8px; line-height: 120%;&quot;&gt;LI&lt;/font&gt;\" style=\"whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcccc;strokeColor=#36393d;verticalAlign=middle;spacing=0;fontSize=8;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"9.999999999999998\" width=\"15.49647887323944\" height=\"15\" as=\"geometry\"/></mxCell><mxCell id=\"7\" value=\"&lt;font style=&quot;font-size: 8px;&quot;&gt;GI&lt;/font&gt;\" style=\"whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcccc;strokeColor=#36393d;fontSize=8;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"34.99999999999999\" width=\"15.49647887323944\" height=\"15\" as=\"geometry\"/></mxCell></root></mxGraphModel>", + "w": 163, + "h": 60 + }, + { + "xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><mxCell id=\"2\" value=\"&lt;font style=&quot;font-size: 11px&quot;&gt;Memory Object&lt;br&gt;&lt;/font&gt;\" style=\"ellipse;whiteSpace=wrap;html=1;strokeColor=#36393d;strokeWidth=2;fillColor=#ffff88;fontSize=8;align=center;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"57\" height=\"60\" as=\"geometry\"/></mxCell></root></mxGraphModel>", + "w": 57, + "h": 60 + }, + { + "xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><mxCell id=\"2\" value=\"&lt;font style=&quot;font-size: 11px&quot;&gt;Memory Object&lt;/font&gt;&lt;br&gt;\" style=\"ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;strokeColor=#36393d;strokeWidth=2;fillColor=#ffff88;fontSize=10;align=center;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"70\" height=\"75\" as=\"geometry\"/></mxCell></root></mxGraphModel>", + "w": 70, + "h": 75 + }, + { + "xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><mxCell id=\"2\" value=\"&lt;div align=&quot;center&quot;&gt;&lt;font style=&quot;font-size: 18px&quot;&gt;Working Memory&lt;/font&gt;&lt;br&gt;&lt;/div&gt;\" style=\"rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#CFE7F5;dashed=1;strokeColor=#3465A4;verticalAlign=top;align=center;spacingLeft=0;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"331\" height=\"290\" as=\"geometry\"/></mxCell></root></mxGraphModel>", + "w": 331, + "h": 290 + } +] \ No newline at end of file From 321b63b853e75cbf24dd866de277e63ddc500cdd Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:30:58 -0300 Subject: [PATCH 13/59] Example: Implementing a Architecture --- examples/Implementing a Architecture.ipynb | 513 ++++++++++++++++++ .../.$diagram.drawio.bkp | 10 + .../Implementing a Architecture/Codelet.png | Bin 0 -> 10321 bytes .../MemoryGroup.png | Bin 0 -> 55033 bytes .../MemoryObject.png | Bin 0 -> 12687 bytes .../SimpleDiagram.png | Bin 0 -> 32581 bytes .../diagram.drawio | 213 ++++++++ .../Implementing a Architecture/diagram.png | Bin 0 -> 198751 bytes .../test_implementing_a_architecture.py | 37 ++ 9 files changed, 773 insertions(+) create mode 100644 examples/Implementing a Architecture.ipynb create mode 100644 examples/Implementing a Architecture/.$diagram.drawio.bkp create mode 100644 examples/Implementing a Architecture/Codelet.png create mode 100644 examples/Implementing a Architecture/MemoryGroup.png create mode 100644 examples/Implementing a Architecture/MemoryObject.png create mode 100644 examples/Implementing a Architecture/SimpleDiagram.png create mode 100644 examples/Implementing a Architecture/diagram.drawio create mode 100644 examples/Implementing a Architecture/diagram.png create mode 100644 tests/examples/test_implementing_a_architecture.py diff --git a/examples/Implementing a Architecture.ipynb b/examples/Implementing a Architecture.ipynb new file mode 100644 index 0000000..6767f18 --- /dev/null +++ b/examples/Implementing a Architecture.ipynb @@ -0,0 +1,513 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementing a Architecture\n", + "\n", + "A cognitive architecture in the CST is implemented using a combination of Codelets and Memories inside a Mind. Each Codelet will communicate with the others using only the Memories." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Diagrams\n", + "\n", + "Before implementing the code, it is common to prepare a diagram describing all the elements of the architecture.\n", + "\n", + "For that, it is defined a visual language:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The **Codelet** symbol:\n", + "\n", + "![](./Implementing%20a%20Architecture/Codelet.png)\n", + "\n", + "The string inside the symbol is the Codelet name. The left ports are its inputs, the _local input (LI)_ and the _global input (GI)_, and the right ports its outputs, the _standard output (O)_ and the _activation level (A)_. The LI and A ports will be discussed in later examples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Memory Object symbol:\n", + "\n", + "![](./Implementing%20a%20Architecture/MemoryObject.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So, if we have a Codelet \"My Codelet\", that reads from \"Input Memory\" and writes to \"Output Memory\", the diagram is going to be:\n", + "\n", + "![](./Implementing%20a%20Architecture/SimpleDiagram.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Its also possible to group memories in a _Memory Group_:\n", + "\n", + "![](./Implementing%20a%20Architecture/MemoryGroup.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For creating a diagram, a [draw.io](https://www.drawio.com/) shape library is provided: [shape library](https://github.com/H-IAAC/CST-Python/blob/2065cb3f29931867de37ec39b40839d82c1331fc/resources/CST-Library.xml)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example architecture" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our example architecture is going to solve a simple quadratic equation in the form $ax^2+bx+c=0$.\n", + "\n", + "For that, the equation parameters $a$, $b$ and $c$ will be stored in Memory Objects, two \"SolveEquation\" will solve the equation computing the two different solutions, and a final \"JoinResults\" codelet will join each result to a final memory:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](./Implementing%20a%20Architecture/diagram.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For that, we start importing the necessary modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "import math # Math operations\n", + "import time # Sleep\n", + "\n", + "import cst_python as cst # CST-Python module" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can implement the `SolveEquationCodelet` using the quadratic formula. Note that the codelet can receive two parameters: if should compute the second solution (`negative`), and the output memory name `output_name`:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "class SolveEquationCodelet(cst.Codelet):\n", + "\n", + " def __init__(self, negative:bool=False, output_name:str=\"x\"):\n", + " super().__init__()\n", + "\n", + " self._negative = negative\n", + " self._output_name = output_name\n", + "\n", + " self._a_mo : None | cst.MemoryObject = None\n", + " self._b_mo : None | cst.MemoryObject = None\n", + " self._c_mo : None | cst.MemoryObject = None\n", + " self._x_mo : None | cst.MemoryObject = None\n", + "\n", + " def access_memory_objects(self):\n", + " self._a_mo = self.get_input(name=\"a\")\n", + " self._b_mo = self.get_input(name=\"b\")\n", + " self._c_mo = self.get_input(name=\"c\")\n", + "\n", + " self._x_mo = self.get_output(name=self._output_name)\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " a = self._a_mo.get_info()\n", + " b = self._b_mo.get_info()\n", + " c = self._c_mo.get_info()\n", + "\n", + " delta = math.pow(b, 2) - (4*a*c)\n", + " delta_sqrt = math.sqrt(delta)\n", + "\n", + " if self._negative:\n", + " delta_sqrt *= -1\n", + " \n", + " if a == 0:\n", + " if b == 0:\n", + " x = float(\"nan\")\n", + " else:\n", + " x = -c/b\n", + " else: \n", + " x = (-b + delta_sqrt)/(2*a)\n", + "\n", + " self._x_mo.set_info(x)\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `JoinResultsCodelet` is going to get all its inputs and send to a unified result:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "class JoinResultsCodelet(cst.Codelet):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self._result_mo : None | cst.MemoryObject = None\n", + "\n", + " def access_memory_objects(self):\n", + " self._result_mo = self.get_output(name=\"result\")\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " result = []\n", + "\n", + " for input_mo in self.inputs:\n", + " result.append(input_mo.get_info())\n", + "\n", + " self._result_mo.set_info(result)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we have all the codelets defined, we can start creating the agent mind:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mind = cst.Mind()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Starting with the memories, observe that the Memory Groups defined in the diagram is created using a `mind.create_memory_group`, and each memory is assigned to the group using `register_memory`, and that each memory starting info is defined (instead of `None`) to avoid exceptions inside the codelets:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "# Input\n", + "\n", + "mind.create_memory_group(\"Input\")\n", + "\n", + "a_mo = mind.create_memory_object(\"a\", 0)\n", + "b_mo = mind.create_memory_object(\"b\", 0)\n", + "c_mo = mind.create_memory_object(\"c\", 0)\n", + "\n", + "mind.register_memory(a_mo, \"Input\")\n", + "mind.register_memory(b_mo, \"Input\")\n", + "mind.register_memory(c_mo, \"Input\")\n", + "\n", + "# Working Memory\n", + "\n", + "mind.create_memory_group(\"Working Memory\")\n", + "\n", + "x1_mo = mind.create_memory_object(\"x1\", 0)\n", + "x2_mo = mind.create_memory_object(\"x2\", 0)\n", + "\n", + "mind.register_memory(x1_mo, \"Working Memory\")\n", + "mind.register_memory(x2_mo, \"Working Memory\")\n", + "\n", + "# Output\n", + "\n", + "mind.create_memory_group(\"Output\")\n", + "\n", + "result_mo = mind.create_memory_object(\"result\")\n", + "\n", + "mind.register_memory(result_mo, \"Output\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We than create the SolveEquationCodelets:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solve_equation1 = SolveEquationCodelet(output_name=\"x1\")\n", + "solve_equation2 = SolveEquationCodelet(output_name=\"x2\", negative=True)\n", + "\n", + "solve_equation1.add_inputs([a_mo, b_mo, c_mo])\n", + "solve_equation2.add_inputs([a_mo, b_mo, c_mo])\n", + "\n", + "solve_equation1.add_output(x1_mo)\n", + "solve_equation2.add_output(x2_mo)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the JoinResultsCodelet:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "join_results = JoinResultsCodelet()\n", + "\n", + "join_results.add_inputs([x1_mo, x2_mo])\n", + "join_results.add_output(result_mo)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, we can add the codelets to the mind and start it. Before that, we change the time step of each codelet to 10 ms:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "solve_equation1.time_step = 10\n", + "solve_equation2.time_step = 10\n", + "join_results.time_step = 10\n", + "\n", + "mind.insert_codelet(solve_equation1)\n", + "mind.insert_codelet(solve_equation2)\n", + "mind.insert_codelet(join_results)\n", + "\n", + "mind.start()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can check the initial result for the equation $0x^2+0x+c = 0$, that is unsovable equation: " + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "tags": [ + "equation1" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[nan, nan]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_mo.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can than change the input values to solve different equations:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$1x^2 = 0$" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "tags": [ + "equation2" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[0.0, 0.0]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_mo.set_info(1)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "result_mo.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$-4x^2+8x+0=0$" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "tags": [ + "equation3" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[-0.0, 2.0]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_mo.set_info(-4)\n", + "b_mo.set_info(8)\n", + "c_mo.set_info(0)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "result_mo.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$5x^2-6x+9=0$" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "tags": [ + "equation4" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[3.0, 3.0]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a_mo.set_info(1)\n", + "b_mo.set_info(-6)\n", + "c_mo.set_info(9)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "result_mo.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the end, we stop the agent mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "mind.shutdown()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/Implementing a Architecture/.$diagram.drawio.bkp b/examples/Implementing a Architecture/.$diagram.drawio.bkp new file mode 100644 index 0000000..d5b56be --- /dev/null +++ b/examples/Implementing a Architecture/.$diagram.drawio.bkp @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/examples/Implementing a Architecture/Codelet.png b/examples/Implementing a Architecture/Codelet.png new file mode 100644 index 0000000000000000000000000000000000000000..58e8abada5532afac5ae7a55e7ec9d25d3009216 GIT binary patch literal 10321 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 literal 0 HcmV?d00001 diff --git a/examples/Implementing a Architecture/MemoryObject.png b/examples/Implementing a Architecture/MemoryObject.png new file mode 100644 index 0000000000000000000000000000000000000000..56165133df09ccd57470d729e3b958a91f16b82f GIT binary patch literal 12687 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 literal 0 HcmV?d00001 diff --git a/examples/Implementing a Architecture/SimpleDiagram.png b/examples/Implementing a Architecture/SimpleDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..ebf5e3a05691e15c7a6fb3593197aa1d349d0857 GIT binary patch literal 32581 zcmZ_01z43`(>5%K2m+GQ-HoImDV=WV?uJcEr-&fk4I2arK^it)(%r~r6H0eU=XW9Z z^S<}<{r`8kJw!RYuC><8oO7Ntvj~0nRtDo4@v}#d9%0DIN~%11^ceo=5dtv^GVm`5 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%0DA`2a7RJFQA_6GY ziNuwJ%0D#fB?HyEvd2#5k<9A!WCQ(cqcXs|W!pR={q5Zt!L2`Lek%q4osynyBX}=V zz8l5`1J(QU5v}q-I)sZ##23i-EQD*iF5m*OFlJzO8AHfg-5Hf=Up~JM!~dD@$=VIe z>uH_;Js?zQ3>V{GolOuB_29|kru@>`csbys>mMsN%Nd9}iQUbfdQI|D_9O z!-%fprl_i{W=6nqf3DpB%mD_$ZY*>t${z|oO@5h({9T&=0yK_-?QSb0<}Fa>b1>M# zV|NZfBxF-Z@2_8oegqh#Cfh*0f+Pg|bSjT5gAsEQd@55f{gv59`gZ^rhfn8GkP_BC zMX;39-dIkZ00a>37Z(5P7q3_WjFO|1;t}l+13#_QekiAeRfdN<>DIoqwDjixP_Fy& zcg9qUC)4c~(k8?JjvJ_8Fv7vJQrMPx)Ogpwv_+g6n5U z=Fh-5eZWQwH@}O{(Z8=z>~eF@ZdK`zc;`K3lbxyPXRyO4S*$-~NwH72H9_?6C;+-y z$JTrdtSUVo6w!D`Iw&mq~={|}v(f{4` zZx1U)T-I$qJP9J6eMVvs{h!PKrRRd3t$gB#n!!5@8*A+RnaVOg!NsUb&KboWBV`e8 z#{8nA$-}K{&SgD4)1_sMFH@P0ock8h(!(w2mBDN z<%g5t@8xd2QG@Dn@rnoBbE`7>@=y<{hiqERW$k^f*g5k$n}N_7v&F4f0*loj1B)}j zd8PlGb6?6W+_IMjwlxCsaQ`J{@C7by;~^TR|FL*o1GrKqIF8Uh`rEwB5eDlXDrFTzB!kN?j#CHZm?c?}1LMH34XZzduJn zRjeNi8_aK|s=)que=|k_RwPe{zPSe0Yt)l(PKMZoxC$m0EwbFMQ#YDcmV0Am`OhsW zhkO)-2qiHvv4`U%GlSGf+CSjN&Uee%^NYVP>gXU?~ zx@?gUK9+~MzD~UItNrJ=-X~*t9(EV~{sg`b9a_0h8x5MBh|#yDXOWx;&*U7J!w87P z)~`a+&iVOGZPjGabTRB+267lmVJ+WBw^9|yQ(5^#Q;Oh9)xjYdJF~6M!-x@54LfYY zC-=cCp!Z3rzzM)6`o!fN3qTZF6WhBpH=oG-db%k#zqhND+~nP{&B#&JDC5<*N2qK% zTw1~=(DS47jW0r2cx;aAr(0Pnb>WzZxXam%GH^^H_Leo`W3~nf3vlH*$j>qxYvO`BR~!_4L#&UWVBHEq)(Kz{*ugCt#a>U2CD4w zU$L@9U%Q`PWSY~ z#e-yHXl43~-~;Z@mo#=Cvk0+1kPgm$^*dU)rdMU344o+Xy7&PQQsWWg7e_xd(xh;# zr>jf9G1oY+guA$I*80|4fZd=?;87uq>tp%D71kqP>fSg>x41FeymVBxvB`T+BVm-S zlK9|Z<5Bv1Dk1KhHYy}U+nj@imNY^xt0i_RDPi3T#T_KjxE$JFtI8RBIh!hm9C>r1 zXiz#!@!LNh&cD9*59|_QidGeZy@Y7szCx~wTz#yMx z8!?-%_8fIjP22@kVjonCYTWnfvnoYO3xUCDw#Jh8t7g_5_vScBaeLIcahR=CQxt6YQI2(`>jJ?gM*adLtrNK1mGEm#YvyKwZ(=F!I z%vSyYG%jjr)f$uMN zKYdOt&W~Xl<6yW&+(oiill0355_(|Hh62{xaEHAB2S;1)+EWLX{~4?Yy%cb9CA z@V|-zF`p99U0B*#>WO00OBx|Dx^Pot+b8ah-f~zE&FaXaZV2K@;sne=tReSmX`wx_&7hAVrO!Q>UnK>CwI?HK zGG1kQ-+T*ia(nDuWYKJfm+sn3G@rFp%a6>G>l>5h^7@rF=5iIGq#Uewm{em(IrN_d z-5@`kU74!1U9KD$H}dL>v4t1J_a+HxUMFS03qR3&C^r#)w{RSvCrq?&V>%^Bux4=J!`Ao!v){paB;_2LdgjoEQi`3^`0!uPz zBbR)A6?b+&v1+Mh$<}H4j6}%of%b*x_xg?FP5By^eYq}H1r(wi2#QIIr`{pLjcd+Q ziZg5W$Fz8@FJEEV`-u*WV%51w`$sn2#jH3ZZY28}mqqX0-MM%m_M}TPV!&j?gT;U# zTDzHM%sbcx6IY-ReO2P&IhvzJ6VGcMwR+thbdGC8(hW7mSnKa!ba$f6Txo5(rkt2X zqs{h>0Zn5Od$r4&#;$6|a$jO!oXVwcPV{OWg-QbNhs@0TELvY8$C1xO{64!AdAkZC zQ@!dGJ|lxT`{QwC)MzJ2x-)cnHedfTg4O}5)X|G?e0>;vD2pQeIWW%+jpa-C4}JRZ zx9WFQ2ie~H?e+-_7a58Oc^{Rmx;XXGgDK)ZCox6-Rbg^DOkg%r*Vt!l#j^B8=glGa z*<{a5#0R^9lEN+R)x4QnlYlB|GQq(^W)~5z0Tw#=O(DyED!meufcooKFSM z^(nF=jM9P^LZ-0mmTYB-&16p50+ViH{Q4d`UI-a~Z{vV~so1~^th0TAkh7f2I}a3; zg@q;iBSnmE!81BF@nf?DojPH&T#c+u5Y?9fV)l?@QRw~ATupi3i(|{(*EYvHOUt6k z&v$0Mw&Izd!5OHG@B8S=kQodzy*R;m9AVVp8BgRYw#O0=3%n8_LpV``e8}xK4RP8$ zJC?D!X@~Z!gxhqHEACBq3~v;=6(-!Jo4*^dyE32z#9MlerV_63GQ~VJ7SB8>G^~Ty zmlp>2H&P4OCrvvKh%Gl|BoigY*zt~>9sP(Xb4BWue@?nrTbW?NF4hf_k>lN!Ti-+} zn7GQsoU>oTF$y%lxhfnN=#|%^_7$QzogO`J!`-z!*;AA-L3$CVXjZwNbb^J|7rZ6R z+gofnEfmR0?2_4}Stgi53A1WM^+gttVYJw7y8(J||rGqXC(o zh}*^|;C7mC94+-6A`h~L`f*iz`RmK=a>!&$l^-!6^a~dk&B`f0^I6s9xOc8Z_@LR_6VJm%!ma{_#qAni@lkag`4btv15G;y$?g9T^YV4TbMlun( z6JIZ28-6wr&+`uPL_Y{j?M#M%Q+(2x*#^(9@-WKm44skDSGP-o=2OJH62_l^eYkrX zcfx5T>@6CA0LVD>veN9^Z5F*Uv))#iW*LF0NTxkWP4qtmh?63>^OOAsohM|Xt8-0F zc#|n=347Sc;NmSv{qb^Ql#sJU@p#!)_hh&9tpMZ~PxcgjS=CfF20{@`!(8v7?^#Zu zTzW$L9}xz$34YBUDdKLgU^53K|JRwxc`R-m3n#sm%)}`$MO4l^!Jv~;wJ5M>mI?gO z^1k+XdJixy;RQca2A;khyXr7&Kn=Y`fKn&CF1lm+3A{%VP$`c3t`gV5VGbJdY zrB`*-d|T%4s?Otp z6vok{X5x%o&V))&+{_k`O=CCp${GEl-ufisp4e1DdVc`gZ2t15;GYGe68m$K)yh#x z_xF2n0BuQqXb29KIBtjSj{l+AElKV`5(X^WrvG!^VA^jX=8<|eR}lx>aBb1C*e_5t+o4cE2Nn4hr^$^UYG%# z%cz)WbuG@)(UQW0Sma(6Iw1Ys(I)~}@XF+hA%L#Lg0-Kj*L-KW`y*RA4;_vxDl3!xj;OWZqCKFgI_jl8^u1XcHH!1mh&!9`)ABTZ^ zbQhXwYgCASu>9>)Q^QF?fT7v}zxkUFcEPSs^3XxY??H=<#1f{TY4q_zN5rf4(iBOq z=07D*+iahLQ@!fz52kE8WXbeKPyt&_mlwRMz+k~mkTGB~xJ~FX>6k*ugL9j3J z32#17i(8J^56uf@7d@PIwm{tQv6Kp|^nK?lV-UCpoPB*b6mqye;@;w_SUambcj?%` zaF0wZMv?wsYXg^d-VyU$Oq`KX_9_9z{RHW~u0(-i@_4Hdr=58P&p&)<6ZA~}aR2M;eqwk)A5hLv1jmw4BSdf!JeG>p2a|9$ zkFh-MozB9!~`9GRq`d*^b+!8RJkH zBToAZTeEzAA`z^W3g*5sVJcVdN(_efEYgAHEpEXIxX-oTNfv$IrFh{NZtfK{!%TjEEOASJWhT-!3- zwsIBT{Ljqwm!!u(+fBXXg`C+>ReU?Uw@HEWJ^R_&7xPo6P+tM4A2PacPQ%F4KcXA0 zF!_LwZ;V~C3OdPMl{0ef_8opGVzbhed3BObEGIa4fz$x&UrX|rS$JEGG5Nr|?KSGr zvthbc|1QRV*(LO^XqU0f61RP@|9|~z<}bIUQ{14PBnEW<+EU6DM95f!dVsz^(${vFU?lkl9`H(&Nh4e z-9Hn!-}*#p#s}J*K{_cCN974XHm}{7ZGea$&0i@Mk!=-z;|(v+D|_C4T|q$s1VvMn zg17#j$-}ShoUT*TYhiZ2Mn_WJ`^fPu%YhVFPE=iXcGbT-RfWIrO#iKwfKD=SI>1LafR91fy!luk{Q?X}(}X-{K_<4KJP@@0z1C15Y%X z;JLr901R#xs0NGTv(<4f1S8rN#i(QkqP{YZU5oOQ+M@a*JKxQkmFXpKpHFd|hEX8( zkO529ykAX4#dRD)^OVrD}ZfYZ&0Y>XF0{~By6Iuq*22RV_NQmB~l>xc-kgHILq zGgEM_okRhLZlDip1~~fM-baq)yjGDeo6|xj6Bi(<@6#eANNv11Be#L7nu`sl@jWV{ zhnJj#ZID zkaalgRXpytX62%x5#=EdxdH`RqB9KrjigV27*ZlQgtPs<88U6jCFbPoHJTWp(ia*u z=!%5Lr>-#{0!Ntz)UB*H9S9HqKE*hJmr2m^#anC{3(GtzYk;78Pg9T647-pfN4BZ15sOHt>ddG#mGO zKGO~GH6S1p;vj0!Ta=W}QJsSmy(E|gi{8!HSU%D<;m{xRiZTZLsR*zLyogA>R#?iH zg#)z9s&z%y%KKOTuucY1&tfAi)(cr!wRpUe8VB_JYA>fxFeH1_l7+`c2V6mF*(v(U z5zOaQ0h>|gK0f=IT5~Merdm;e0S&R$6HaiRrHq|i^$ep>KOQ6XwvqAFa+R?J1e zM%DGu?V0XB#x+h^6<~TeMr2_B)!mz9={CFaD{u{mP5Yzm9@? zN}TVFSPbzeb8muvFZ-(+11YMy@e6doS3Vd&Y}VZROKG0ZZ6g&fxrwiLGTxXA~@EQwgPizt@w-FJp1xCZbkFcO+Zoiq4#F zXH}5h4BOMW^8JuSsdWLf_5w*JyM-sh?+sx>0O!g;$tmk+WlECLIA zrK@aHppebeEBs3bJ=Cjlz|K7Uu*B~ChGpq-kkFQF4K)gea}FPJLbp?C14@dV6X-Q4neWm9p+zWC4$gqvJO}MVQSe`)+E8I#z9$1`2 zRM|Bd_)!}+`OZKc`0b{6%dgiI;|y;5*>&z-7WFEc-$eHs;Nm2xw%RFJm2Az~8vq77B>EJ%%0ME% zMKdXZSZF}~JK!Qb0qW;{q$VKP_z0Sz3jzS5{SrHBJ$T~7XC=+-&}BOpNRE4c4{+GZ zVq&_4x6CPOj5;ZfK<6Hw&`Ra_zp8EfHkYV%=dS_x#|miS7g`EB9n)|M+1gwLn0f#>?)hLJWv@|R&O9WkV)hE-w~feF(A zPLpgoi(lb=BWVf=1S<0RefLHw4EDe1m1lcgKFg6ozAaP@H3Az=crl*uDFyoLuh
N3 zIpN{n02|VGp+N!kHJgPDRf5W^3SUNkx386|F3tc*ibaSw@Ge^kHW$UO?R?w~EpgDB zWYhZcgZq!$#15zLR0pg7m5l`m-YL0*w!q75U=aI%KYgL51y-r&)&k3~H`3Hyhkvk7 z)+u6`sm1uTNp{}LGw=lDx|yIH)oAQF5zLUJ#$_#v{3~4DJb5!EA;Ctj3^|(100L%< zOmPSdYJ@xoEjhovR<|SEUEB$P^eo@=la~j&55{Ewof=Cvr}!s>1%2EXmGr&AxSbb@ zK(5DxRQmHl>tGlo*J!BzT8ChlwE#OQMH3fMx=#Mm#Td!!G@#x8;|sYK$$zFN*c5%z zye9OfBv~?@^U*^ zLNKRn6#MVi48M^ST_$dEt6fd_%BP`wZ~VNgFt|#rGq8>|i|DVWU<3@}eCNm^gh^i( z+&Soti6Jh}Ic)Sf%>+9D!^OrD)>9R^W}qLY2<6uQ>cS+}&sgwE`Zv`^|3doEO`yFA n6494OY3kkhsc;E#f=s!WlT$v^)K#3~KI literal 0 HcmV?d00001 diff --git a/examples/Implementing a Architecture/diagram.drawio b/examples/Implementing a Architecture/diagram.drawio new file mode 100644 index 0000000..fe0cd88 --- /dev/null +++ b/examples/Implementing a Architecture/diagram.drawio @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Implementing a Architecture/diagram.png b/examples/Implementing a Architecture/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..e97d782f2039e4b77d67a0dfe7d0f45847482e4b GIT binary patch literal 198751 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%0AtTRYY2F5jY29a7DofFe<;4s&NGd3*`ej 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
5z}T7Q?mwLW`TI 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 literal 0 HcmV?d00001 diff --git a/tests/examples/test_implementing_a_architecture.py b/tests/examples/test_implementing_a_architecture.py new file mode 100644 index 0000000..581f14d --- /dev/null +++ b/tests/examples/test_implementing_a_architecture.py @@ -0,0 +1,37 @@ +import os +import math + +from testbook import testbook +from testbook.client import TestbookNotebookClient + +from ..utils import get_examples_path + +examples_path = get_examples_path() + +@testbook(os.path.join(examples_path, "Implementing a Architecture.ipynb"), execute=True) +def test_implementing_architecture(tb :TestbookNotebookClient): + expected_results : list[list] = [["nan", "nan"], + [0, 0], + [-0, 2], + [3,3]] + + for i, excepted_result in enumerate(expected_results): + result = tb.cell_output_text(f"equation{i+1}") + result = result.replace("nan", "'nan'") + result = eval(result) + + for x in result: + for y in excepted_result: + if isinstance(x, str) or isinstance(y,str): + if isinstance(x, str) and isinstance(y,str) and x == y: + excepted_result.remove(y) + break + + elif math.isclose(x, y): + excepted_result.remove(y) + break + + assert len(excepted_result) == 0 + + + From 3108287c8fce5a6e427ca56267a927270c271239 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:31:16 -0300 Subject: [PATCH 14/59] Example Introduction: stateless codelet --- examples/Introduction to CST-Python.ipynb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb index 857941c..b52cad5 100644 --- a/examples/Introduction to CST-Python.ipynb +++ b/examples/Introduction to CST-Python.ipynb @@ -236,7 +236,9 @@ "- `calculate_activation`: computes the codelet's activation. We are not going to use this now.\n", "- `proc`: the actual function that the codelet performs, reading from the inputs, processing and setting the outputs.\n", "\n", - "It is important to note that the codelet should only get inputs in the `access_memory_objects`, not in `proc`. The content of the memories (info) can be accessed everywhere." + "It is important to note that the codelet should only get inputs in the `access_memory_objects`, not in `proc`. The content of the memories (info) can be accessed everywhere.\n", + "\n", + "Also, the Codelet should be stateless. Any data necessary for its operation should be in the inputs." ] }, { From e60d45a5ca2f24c617cff936eaf8401647b72282 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:32:05 -0300 Subject: [PATCH 15/59] Publisher Subscriber example --- examples/Publisher-Subscriber.ipynb | 502 ++++++++++++++++++ .../Publisher-Subscriber/.$diagram.drawio.bkp | 34 ++ examples/Publisher-Subscriber/diagram.drawio | 66 +++ examples/Publisher-Subscriber/diagram.png | Bin 0 -> 70838 bytes src/cst_python/core/entities/codelet.py | 3 +- .../core/entities/memory_observer.py | 7 +- src/cst_python/core/entities/raw_memory.py | 1 - tests/examples/test_publisher_subscriber.py | 19 + 8 files changed, 625 insertions(+), 7 deletions(-) create mode 100644 examples/Publisher-Subscriber.ipynb create mode 100644 examples/Publisher-Subscriber/.$diagram.drawio.bkp create mode 100644 examples/Publisher-Subscriber/diagram.drawio create mode 100644 examples/Publisher-Subscriber/diagram.png create mode 100644 tests/examples/test_publisher_subscriber.py diff --git a/examples/Publisher-Subscriber.ipynb b/examples/Publisher-Subscriber.ipynb new file mode 100644 index 0000000..d820837 --- /dev/null +++ b/examples/Publisher-Subscriber.ipynb @@ -0,0 +1,502 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Publish-Subscribe\n", + "\n", + "Sometimes we wish that a codelet is only executed when its input value is changed. For that, we can use the publish-subscribe mechanism." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For exemplify that, we are going to implement a agent that computes the average of its input values:\n", + "\n", + "![](./Publisher-Subscriber/diagram.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets start by importing the necessary modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time # Sleep\n", + "\n", + "import cst_python as cst # CST-Python Module" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Naive" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The first implementation is going to be a naive aproach: we are going to store the last timestamp the input value was changed, and only compute the average when the timestamp increases:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class NaiveAverageCodelet(cst.Codelet):\n", + " def __init__(self):\n", + " super().__init__()\n", + "\n", + " self._value_mo : cst.Codelet | None = None\n", + "\n", + " self._counter_mo : cst.Codelet | None = None\n", + " self._avg_mo : cst.Codelet | None = None\n", + "\n", + " self.last_timestamp = 0\n", + "\n", + " def access_memory_objects(self):\n", + " self._value_mo = self.get_input(name=\"Value\")\n", + "\n", + " self._counter_mo = self.get_output(name=\"Counter\")\n", + " self._avg_mo = self.get_output(name=\"Average\")\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " \n", + " # Check if have a new value\n", + " if self._value_mo.get_timestamp() != 0 and self._value_mo.get_timestamp() <= self.last_timestamp:\n", + " return\n", + " self.last_timestamp = self._value_mo.get_timestamp()\n", + "\n", + " counter : int = self._counter_mo.get_info()\n", + " avg : float = self._avg_mo.get_info()\n", + "\n", + " # Retrieve the previous sum\n", + " avg *= counter\n", + "\n", + " # Update the values\n", + " avg += self._value_mo.get_info()\n", + " counter += 1\n", + " avg /= counter\n", + " \n", + " self._avg_mo.set_info(avg)\n", + " self._counter_mo.set_info(counter)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `prepare_mind` function creates a new mind with all the necessary memories:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def prepare_mind(average_codelet:cst.Codelet):\n", + " mind = cst.Mind()\n", + "\n", + " avg_mo = mind.create_memory_object(\"Average\", 0.0)\n", + " counter_mo = mind.create_memory_object(\"Counter\", 0)\n", + " value_mo = mind.create_memory_object(\"Value\", 0.0)\n", + " \n", + " average_codelet.add_input(value_mo)\n", + "\n", + " average_codelet.add_output(avg_mo)\n", + " average_codelet.add_output(counter_mo)\n", + "\n", + " # Avoid the naive codelet using the first value in the computation\n", + " average_codelet.last_timestamp = value_mo.get_timestamp() \n", + " \n", + " average_codelet.time_step = 10\n", + " mind.insert_codelet(average_codelet)\n", + "\n", + " return mind, value_mo, avg_mo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We than create the codelet, prepare and start the mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "naive_codelet = NaiveAverageCodelet()\n", + "\n", + "mind, value_mo, avg_mo = prepare_mind(naive_codelet)\n", + "\n", + "mind.start()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For testing, we can set the \"Value\" memory info and check the current average:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [ + "check_average0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.0" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(10)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [ + "check_average1" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "15.0" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(20)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We then stops the executing mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "mind.shutdown()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Memory Observer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, the codelet are not going to check if the input value changed, the `proc` method is more clean and really peforms only the codelet operation. Also, the codelet becomes stateless:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "class PubSubAverageCodelet(cst.Codelet):\n", + " def __init__(self):\n", + " super().__init__()\n", + "\n", + " self._value_mo : cst.Codelet | None = None\n", + "\n", + " self._counter_mo : cst.Codelet | None = None\n", + " self._avg_mo : cst.Codelet | None = None\n", + " \n", + "\n", + " def access_memory_objects(self):\n", + " self._value_mo = self.get_input(name=\"Value\")\n", + "\n", + " self._counter_mo = self.get_output(name=\"Counter\")\n", + " self._avg_mo = self.get_output(name=\"Average\")\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " counter : int = self._counter_mo.get_info()\n", + " avg : float = self._avg_mo.get_info()\n", + "\n", + " # Retrieve the previous sum\n", + " avg *= counter\n", + "\n", + " # Update the values\n", + " avg += self._value_mo.get_info()\n", + " counter += 1\n", + " avg /= counter\n", + " \n", + " self._avg_mo.set_info(avg)\n", + " self._counter_mo.set_info(counter)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We than create the codelet and mind as before:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "average_codelet = PubSubAverageCodelet()\n", + "\n", + "mind, value_mo, avg_mo = prepare_mind(average_codelet)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this case, we configure the codelet as a \"memory observer\": it is going to execute the `proc` method only when the observed memory is changed. Than we set the codelet as a observer of the \"Value\" memory and starts the mind:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "average_codelet.is_memory_observer = True\n", + "value_mo.add_memory_observer(average_codelet)\n", + "\n", + "mind.start()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We test the codelet with the same example as before:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "tags": [ + "check_average2" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.0" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(10)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [ + "check_average3" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "15.0" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(20)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "mind.shutdown()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Publisher-Subscriber\n", + "\n", + "The previous example shows how to create a codelet that that selectively waits for some input to change.\n", + "\n", + "Sometimes, we wanna the codelet to run when any input (or the only input) changes. In this case, we can use a \"publish-subscriber\" codelet:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "average_codelet = PubSubAverageCodelet()\n", + "\n", + "mind, value_mo, avg_mo = prepare_mind(average_codelet)\n", + "\n", + "average_codelet.set_publish_subscribe(True)\n", + "\n", + "mind.start()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "check_average4" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.0" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(10)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "tags": [ + "check_average5" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "15.0" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "value_mo.set_info(20)\n", + "\n", + "time.sleep(0.020)\n", + "\n", + "avg_mo.get_info()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/Publisher-Subscriber/.$diagram.drawio.bkp b/examples/Publisher-Subscriber/.$diagram.drawio.bkp new file mode 100644 index 0000000..3c614fe --- /dev/null +++ b/examples/Publisher-Subscriber/.$diagram.drawio.bkp @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Publisher-Subscriber/diagram.drawio b/examples/Publisher-Subscriber/diagram.drawio new file mode 100644 index 0000000..788d5d4 --- /dev/null +++ b/examples/Publisher-Subscriber/diagram.drawio @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Publisher-Subscriber/diagram.png b/examples/Publisher-Subscriber/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..ea875c87815d70657d91f86bfacbdc492798d4a9 GIT binary patch literal 70838 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 literal 0 HcmV?d00001 diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index bead8ff..ada9aa0 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -9,11 +9,12 @@ from cst_python.python import alias from .memory import Memory from .memory_buffer import MemoryBuffer +from .memory_observer import MemoryObserver #TODO: Profile, Broadcast, impending access, correct exception types #@alias.aliased -class Codelet(abc.ABC): +class Codelet(MemoryObserver): #(abc.ABC) is not necessary _last_id = 0 def __init__(self) -> None: diff --git a/src/cst_python/core/entities/memory_observer.py b/src/cst_python/core/entities/memory_observer.py index 6980135..66a8ef4 100644 --- a/src/cst_python/core/entities/memory_observer.py +++ b/src/cst_python/core/entities/memory_observer.py @@ -2,11 +2,8 @@ from cst_python.python import alias -class MemoryObserver(abc.ABC): - def __init__(self) -> None: - raise NotImplementedError() - +class MemoryObserver(abc.ABC): #@alias.alias("notifyCodelet") @abc.abstractmethod def notify_codelet(self): - raise NotImplementedError() \ No newline at end of file + ... \ No newline at end of file diff --git a/src/cst_python/core/entities/raw_memory.py b/src/cst_python/core/entities/raw_memory.py index 99359bb..c270498 100644 --- a/src/cst_python/core/entities/raw_memory.py +++ b/src/cst_python/core/entities/raw_memory.py @@ -72,7 +72,6 @@ def create_memory_object(self, name:str, info:Optional[Any]=None) -> MemoryObjec mo = MemoryObject() mo.set_info(info) - mo.timestamp = time.time() mo.set_evaluation(0.0) mo.set_name(name) diff --git a/tests/examples/test_publisher_subscriber.py b/tests/examples/test_publisher_subscriber.py new file mode 100644 index 0000000..ca75b15 --- /dev/null +++ b/tests/examples/test_publisher_subscriber.py @@ -0,0 +1,19 @@ +import os +import math + +from testbook import testbook +from testbook.client import TestbookNotebookClient + +from ..utils import get_examples_path + +examples_path = get_examples_path() + +@testbook(os.path.join(examples_path, "Publisher-Subscriber.ipynb"), execute=True) +def test_publisher_subscriber(tb :TestbookNotebookClient): + expected_results : list[list] = [10, 15, 10, 15, 10, 15] + + for i, excepted_result in enumerate(expected_results): + result = tb.cell_output_text(f"check_average{i}") + result = eval(result) + + assert math.isclose(result, excepted_result) \ No newline at end of file From f064510fd1da0fd5ae69e24e76c5dd6a0a62e35b Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:28:44 -0300 Subject: [PATCH 16/59] Activationa and Monitoring example --- dev/simple_test.ipynb | 371 ---------------- examples/Activation and Monitoring.ipynb | 405 ++++++++++++++++++ setup.cfg | 2 +- .../test_activation_and_monitoring.py | 36 ++ 4 files changed, 442 insertions(+), 372 deletions(-) delete mode 100644 dev/simple_test.ipynb create mode 100644 examples/Activation and Monitoring.ipynb create mode 100644 tests/examples/test_activation_and_monitoring.py diff --git a/dev/simple_test.ipynb b/dev/simple_test.ipynb deleted file mode 100644 index f089685..0000000 --- a/dev/simple_test.ipynb +++ /dev/null @@ -1,371 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import time\n", - "import random\n", - "import threading\n", - "\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import cst_python as cst" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "class OscillatorCodelet(cst.Codelet):\n", - " def __init__(self, name:str) -> None:\n", - " super().__init__()\n", - "\n", - " self.name = name\n", - " self._ascending = True\n", - "\n", - " def access_memory_objects(self) -> None:\n", - " pass\n", - "\n", - " def calculate_activation(self) -> None:\n", - " if self._ascending:\n", - " step = 0.1\n", - " else:\n", - " step = -0.1\n", - "\n", - " try:\n", - " self.activation += step\n", - " except ValueError:\n", - " self._ascending = not self._ascending\n", - "\n", - " def proc(self) -> None:\n", - " pass\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "class SensorCodelet(cst.Codelet):\n", - " def __init__(self, name:str) -> None:\n", - " super().__init__()\n", - "\n", - " self.name = name\n", - " self._ascending = True\n", - "\n", - " self._input_mo : cst.MemoryObject = None\n", - " self._output_mo : cst.MemoryObject = None\n", - " self._n_run = 0\n", - "\n", - " def access_memory_objects(self) -> None:\n", - " self._input_mo = self.get_input(name=\"SensoryInput\")\n", - " self._output_mo = self.get_output(name=\"SensoryOutput\")\n", - "\n", - " def calculate_activation(self) -> None:\n", - " pass\n", - "\n", - " def proc(self) -> None:\n", - " #print(\"RUN\", end=\" \")\n", - " read_value : float = self._input_mo.get_info()\n", - " #print(read_value, read_value is None)\n", - " read_value *= 10\n", - "\n", - " self._output_mo.set_info(read_value)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "class MotorCodelet(cst.Codelet):\n", - " def __init__(self, name:str) -> None:\n", - " super().__init__()\n", - "\n", - " self.name = name\n", - " self._ascending = True\n", - "\n", - " self._minput_mo : cst.MemoryObject = None\n", - " self._output_mo : cst.MemoryObject = None\n", - "\n", - " def access_memory_objects(self) -> None:\n", - " self._minput_mo = self.get_input(name=\"SensoryOutput\")\n", - " self._output_mo = self.get_output(name=\"Action\")\n", - "\n", - " def calculate_activation(self) -> None:\n", - " pass\n", - "\n", - " def proc(self) -> None:\n", - " read_value : float = self._minput_mo.get_info()\n", - " \n", - " action = read_value > 5 \n", - "\n", - " self._output_mo.set_info(action)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "def prepare_mind() -> cst.Mind:\n", - " mind = cst.Mind()\n", - "\n", - " mind.create_codelet_group(\"Sensory\")\n", - " mind.create_codelet_group(\"Perception\")\n", - " mind.create_codelet_group(\"Behavioral\")\n", - " mind.create_codelet_group(\"Motivational\")\n", - " mind.create_codelet_group(\"Motor\")\n", - " mind.create_codelet_group(\"StandardMemories\")\n", - " mind.create_codelet_group(\"Containers\")\n", - "\n", - " m1 = mind.create_memory_object(\"SensoryInput\", 1.12)\n", - " mind.register_memory(m1,\"StandardMemories\")\n", - "\n", - " m3 = mind.create_memory_object(\"SensoryOutput\", 3.44)\n", - " mind.register_memory(m3,\"StandardMemories\")\n", - " m5 = mind.create_memory_object(\"Action\", False)\n", - " mind.register_memory(m5,\"StandardMemories\")\n", - " \n", - "\n", - " c = SensorCodelet(\"Sensor1\")\n", - " c.add_input(m1)\n", - " c.add_output(m3)\n", - " mind.insert_codelet(c,\"Sensory\")\n", - "\n", - " c2 = MotorCodelet(\"Motor1\")\n", - " c2.add_input(m3)\n", - " c2.add_output(m5)\n", - " mind.insert_codelet(c2,\"Motor\")\n", - "\n", - " c3 = OscillatorCodelet(\"Curiosity\")\n", - " mind.insert_codelet(c3, \"Motivational\")\n", - "\n", - " c.time_step = 100\n", - " c2.time_step = 100\n", - " c3.time_step = 100\n", - "\n", - " mind.start()\n", - " \n", - " return mind" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "mind = prepare_mind()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "input_memory = mind.raw_memory.get_all_of_type(\"SensoryInput\")[0]\n", - "sensory_output_memory = mind.raw_memory.get_all_of_type(\"SensoryOutput\")[0]\n", - "action_memory = mind.raw_memory.get_all_of_type(\"Action\")[0]\n", - "\n", - "for codelet in mind.code_rack.all_codelets:\n", - " if isinstance(codelet, OscillatorCodelet):\n", - " oscillator_codelet = codelet\n", - " break" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "sleep_time = (oscillator_codelet.time_step/2)/1000" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "threading.active_count()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "n_step = 100\n", - "\n", - "activation_hist = np.empty(n_step, dtype=np.float64)\n", - "input_hist = np.empty(n_step, dtype=np.float64)\n", - "sensory_output_hist = np.empty(n_step, dtype=np.float64)\n", - "action_hist = np.empty(n_step, dtype=bool)\n", - "\n", - "for i in range(n_step):\n", - " input_value = random.random()\n", - " \n", - " input_memory.set_info(input_value)\n", - "\n", - " input_hist[i] = input_memory.get_info()\n", - " sensory_output_hist[i] = sensory_output_memory.get_info()\n", - " action_hist[i] = action_memory.get_info()\n", - " activation_hist[i] = oscillator_codelet.activation\n", - " \n", - " time.sleep(sleep_time)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mind.shutdown()\n", - "time.sleep(1)\n", - "threading.active_count()" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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//4XgwYNwuGHHy79+xFHHIFBgwbh3Xff1bddeumlmDJlCq688koMHz4cW7duxZdffomff/4Z++67LwDgo48+wm9+8xv07dsXY8eORZ8+ffDzzz/jnXfewdixYzMa8xtvvIHW1lZcdtll6N69O7755hs8/PDDWLNmDd544w0AwCWXXIJ169bho48+wosvvsjtTwjBb3/7W3z66ae44IILsPfee+PDDz/Etddei7Vr1+Kf//wn1/6TTz7B66+/jiuvvBI9evTAoEGDlGN77rnnUFlZiXHjxqGyshKffPIJbrnlFjQ2NuK+++7T26W6PlbjF3HCCSegsrISr7/+Oo488kjub5MnT8Zuu+2G3XffXe932bJlGDNmDPr06YMFCxbgySefxIIFC/D1119D0zScfPLJWLx4MV599VX885//RI8ePQCAUzFZbNy4EYceeihaW1tx1VVXoXv37nj++efx29/+FlOmTMFJJ53Etf/73/8On8+Hv/zlL2hoaMC9996Ls88+G7NmzbI8z2LHwIEDMXPmTPz444/656XCXXfdhZtvvhmnnXYaLrzwQmzevBkPP/wwjjjiCMydO5db2a+rq8Nxxx2Hk08+GaeddhqmTJmC66+/HnvssQdGjRoFAHjqqadw1VVX4ZRTTsHYsWPR3t6OH374AbNmzcJZZ50FIJF3efjhh6O6uhrXXXcdgsEgnnjiCRx11FH47LPPcNBBB3FjvPzyy9GzZ0/ccsstaGlpwVFHHYUBAwbg5ZdfNn0nXn75ZQwZMgSHHHKI4+tm5/zY66ZpGq6//nps2rQJEydOxMiRI/H999+jrKzMdp+77ror7rjjDtxyyy24+OKL9efnoYce6nj8HuTw7gfr+8HpczcVbrzxRjQ0NGDNmjX6O7CystJ0nb37pzgwaNAgHHLIIXj11Vf17/3777+PhoYGnHHGGXjooYe49nbnTS+++CIuvPBCHHjggbj44osBAEOGDAGQ+T2jQmNjI/71r3/hzDPPxEUXXYSmpiY8/fTTOPbYY/HNN99g77331ttecMEFeO655zBq1ChceOGFiEaj+OKLL/D1119j//33txy/DLfddhtuv/12jBw5EpdddhkWLVqExx9/HLNnz8ZXX32FYDCot3XyripYdDar60zU19cTAOR3v/udZbvf/va3BABpbGwkhBBSU1NDrrjiCmX7aDRKBg8eTAYOHGhi6+yKRrpKFatIUUyYMIFomkZWrlypb7viiitMxyckoSYBIHfeeSe3/ZRTTiGappElS5bo2wAQn89HFixYoDxfFrKxXXLJJaS8vJy0t7cTQuxfH9X46bioUkUIIWeeeSbp1asXp4itX7+e+Hw+cscdd1iO79VXXzWplffdd590RYYQ82d09dVXEwDkiy++0Lc1NTWRwYMHk0GDBpFYLEYIMT7LXXfdlYTDYb3tgw8+yKlpXRX/+9//iN/vJ36/nxxyyCHkuuuuIx9++CGJRCJcuxUrVhC/30/uuusubvv8+fNJIBDgttPV5xdeeEHfFg6HSZ8+fcjvf/97fdvvfvc7sttuu1mO78QTTyShUIgsXbpU37Zu3TpSVVVFjjjiCH0bXc0bMWKESaEdP348KSkpIfX19fq2TZs2kUAgwH2fZVApVXbOj+7bv39//TlGCCGvv/46AUAefPBBfZudlXZCCJk9e7a3up5FePfDrZb9233u2lWqCCHkhBNO0NUpWVvv/il80O/D7NmzySOPPEKqqqr0ecGpp55Kjj76aEIIMSlVTuZNFRUV0u+AG/eMDNFolJtTEEJIXV0d6d27N/njH/+ob6Pq8FVXXWU6Bjv3Uo1fvJc2bdpEQqEQ+fWvf63fb4QQ8sgjjxAA5JlnntG32X32FDq6tFFFU1MTAKCqqsqyHf17Y2MjAKC2thazZs3CunXrpO3nzp2L5cuX4+qrrzbFwosW6umAXRFraWnBli1bcOihh4IQgrlz56bc/7333oPf78dVV13Fbf/zn/8MQgjef/99bvuRRx6J4cOHOx5bU1MTtmzZgsMPPxytra1YuHAhgOxcn9NPPx2bNm3i7KanTJmCeDyO008/XTq+9vZ2bNmyBQcffDAAYM6cOWn1/d577+HAAw/EiBEj9G2VlZW4+OKLsWLFCvz0009c+zFjxiAUCum/01XKZcuWpdV/seCYY47BzJkz8dvf/hbz5s3Dvffei2OPPRb9+/fHf/7zH73d1KlTEY/Hcdppp2HLli36f3369MHOO++MTz/9lDtuZWUl/vCHP+i/h0IhHHjggdz1rq2txZo1azB79mzp2GKxGP73v//hxBNP5HIr+/bti7POOgtffvml/nyguOiii0zx5+eeey7C4TCmTJmib5s8eTKi0Sg3Riewc35s/+zz7pRTTkHfvn3x3nvvpdW3h+zBux+s7wenz1034N0/xYXTTjsNbW1teOedd9DU1IR33nlHV2JFOJ03iXDrnpHB7/frc4p4PI5t27YhGo1i//335+Y1b775JjRNw6233mo6Rjpzr48//hiRSARXX301fD6DTlx00UWorq7mIrwAZ++qQkWXJlX04UjJlQoi+br33nvx448/YsCAATjwwANx2223cV+KpUuXAkDKkI10sWrVKpx//vnYbrvtUFlZiZ49e+phbw0NDSn3X7lyJfr162cik7vuuqv+dxaDBw+2PbYFCxbgpJNOQk1NDaqrq9GzZ0/9JqJjy8b1Oe6441BTU4PJkyfr2yZPnoy9994bQ4cO1bdt27YNY8eORe/evVFWVoaePXvq52fn2smwcuVK7LLLLqbtquu5ww47cL9369YNQEIa7+o44IADMHXqVNTV1eGbb77B+PHj0dTUhFNOOUWfJP3yyy8ghGDnnXdGz549uf9+/vlnUxL/9ttvb3phdOvWjbve119/PSorK3HggQdi5513xhVXXIGvvvpK//vmzZvR2tqq/Jzj8ThWr17NbZfdN8OGDcMBBxyAl19+Wd/28ssv4+CDD8ZOO+3k4Eo5Oz+KnXfemftd0zTstNNOXt2RPIV3P6jh9LnrBrz7p7jQs2dPjBw5Eq+88gqmTp2KWCyGU045RdrW6bxJhFv3jArPP/889txzT5SWlqJ79+7o2bMn3n33XW5es3TpUvTr1w/bbbed7eNagZ6zeE6hUAg77rij6Zo4eVcVKrp0TlVNTQ369u2LH374wbLdDz/8gP79+6O6uhpAYnXj8MMPx1tvvYX//e9/uO+++3DPPfdg6tSpWY8LjcViOOaYY7Bt2zZcf/31GDZsGCoqKrB27Vqcf/75iMfjrvdpN1a8vr4eRx55JKqrq3HHHXdgyJAhKC0txZw5c3D99ddnZWwUJSUlOPHEE/HWW2/hsccew8aNG/HVV1/h7rvv5tqddtppmDFjBq699lrsvffeqKysRDwex3HHHZfV8bFQrTwRQnLSfyEgFArhgAMOwAEHHIChQ4dizJgxeOONN3DrrbciHo9D0zS8//770msp5kHYud677rorFi1ahHfeeQcffPAB3nzzTTz22GO45ZZb0i5LoLpvzj33XIwdOxZr1qxBOBzG119/jUceeSStPgD3v0+qFctYLOY5P3USvPshfVh9n7MB7/4pLJx11lm46KKLsGHDBowaNcoUPdOZsDv3eumll3D++efjxBNPxLXXXotevXrB7/djwoQJ+iJ2PqArzH26NKkCgN/85jd46qmn8OWXX3JhBBRffPEFVqxYgUsuuYTb3rdvX1x++eW4/PLLsWnTJuy777646667MGrUKD2p78cff8TIkSNdHe/8+fOxePFiPP/88zj33HP17R999JGprerhPnDgQHz88cdoamriVl1oeF66NQimT5+OrVu3YurUqVwtneXLl3Pt7F4fp3L06aefjueffx7Tpk3Dzz//DEIIF/pXV1eHadOm4fbbb8ctt9yib//ll18y6nvgwIFYtGiRaXum19NDAvvvvz8AYP369QAS3x9CCAYPHsypkJmioqICp59+Ok4//XREIhGcfPLJuOuuuzB+/Hj07NkT5eXlys/Z5/NhwIABtvo544wzMG7cOLz66qtoa2tDMBjkvqfZhPhdJ4RgyZIl2HPPPfVt3bp1k9ZnW7lyJRe24kYoswfn8O6HBOw+d2kkgPidlikLqb7T3v1TfDjppJNwySWX4Ouvv+YiXUQ4mTfJPls37xkRU6ZMwY477oipU6dyfYthfkOGDMGHH36Ibdu2WapVdr+b9JwXLVrEfbcjkQiWL1/u+vy3ENClw/8A4Nprr0VZWRkuueQSbN26lfvbtm3bcOmll6K8vBzXXnstgMRqkxgm1qtXL/Tr1w/hcBgAsO+++2Lw4MGYOHGi6eGaKSOnTJ89DiFEWgyS1jQQx3D88ccjFouZVgP/+c9/QtO0tNU22dgikQgee+wxrp3d66MavwojR47Edttth8mTJ2Py5Mk48MADOflcNj4A0mKPTvo+/vjj8c0332DmzJn6tpaWFjz55JMYNGiQ7Xy0ro5PP/1Uen/QfAUaYnDyySfD7/fj9ttvN7UnhJjuYzsQ9wmFQhg+fDgIIejo6IDf78evf/1r/Pvf/+ZCfTZu3IhXXnkFI0aM0JXsVOjRowdGjRqFl156CS+//DKOO+443WEy23jhhRe4cOcpU6Zg/fr13D0/ZMgQfP3114hEIvq2d955xxSa4vT+9OAM3v1gDbvPXbqI9/nnn+vtYrEYnnzySdMxKyoqLMPAvfun+FBZWYnHH38ct912G0aPHq1s52TeVFFRYfpc3bxnRMjmNrNmzeLuDQD4/e9/D0KIVG0W5152vpcjR45EKBTCQw89xO3/9NNPo6GhASeccILTUyl4dHmlauedd8bzzz+Ps88+G3vssQcuuOACDB48GCtWrMDTTz+NLVu24NVXX9UfzE1NTdh+++1xyimnYK+99kJlZSU+/vhjzJ49G/fffz+ARJHOxx9/HKNHj8bee++NMWPGoG/fvli4cCEWLFiADz/8MO3xDhs2DEOGDMFf/vIXrF27FtXV1XjzzTelMan77bcfAOCqq67CscceC7/fjzPOOAOjR4/G0UcfjRtvvBErVqzAXnvthf/973/497//jauvvtrSPtMKhx56KLp164bzzjsPV111FTRNw4svvmh60du9PqrxqxAMBnHyySfjtddeQ0tLC/7xj39wf6+ursYRRxyBe++9Fx0dHejfvz/+97//mZQ0tu8bb7wRZ5xxBoLBIEaPHi0tvnfDDTfotqxXXXUVtttuOzz//PNYvnw53nzzTS6B04Maf/rTn9Da2oqTTjoJw4YNQyQSwYwZMzB58mQMGjQIY8aMAZCYtNx5550YP348VqxYgRNPPBFVVVVYvnw53nrrLVx88cX4y1/+4qjvX//61+jTpw8OO+ww9O7dGz///DMeeeQRnHDCCfqq5J133omPPvoII0aMwOWXX45AIIAnnngC4XAY9957r6P+zj33XD12/29/+5ujfTPBdttthxEjRmDMmDHYuHEjJk6ciJ122gkXXXSR3ubCCy/ElClTcNxxx+G0007D0qVL8dJLL5meC0OGDEFtbS0mTZqEqqoqVFRU4KCDDnKUB+BBDe9+sIbd5+5uu+2Ggw8+GOPHj9dX6F977TVEo1HTMffbbz9MnjwZ48aNwwEHHIDKykpuou3dP8WJ8847L2UbJ/Om/fbbDx9//DEeeOAB9OvXD4MHD8ZBBx3k6j3D4je/+Q2mTp2Kk046CSeccAKWL1+OSZMmYfjw4WhubtbbHX300TjnnHPw0EMP4ZdfftHTHr744gscffTRuPLKKy3HL6Jnz54YP348br/9dhx33HH47W9/i0WLFuGxxx7DAQcckLb5UkEj2/aChYIffviBnHnmmaRv374kGAySPn36kDPPPNNkcx0Oh8m1115L9tprL71421577UUee+wx0zG//PJLcswxx+jt9txzT/Lwww/rf0/XUv2nn34iI0eOJJWVlaRHjx7koosuIvPmzTPZs0ajUfKnP/2J9OzZk2iaxvXV1NRErrnmGtKvXz8SDAbJzjvvbFn81y6++uorcvDBB+uF3agNsHgOdq6P1fghWKpTfPTRRwQA0TSNrF692vT3NWvWkJNOOonU1taSmpoacuqpp5J169ZJj/e3v/2N9O/fn/h8Ps5G1Kr4b21tLSktLSUHHnigsvjvG2+8wW1fvny5Z61LCHn//ffJH//4RzJs2DBSWVlJQqEQ2Wmnncif/vQnsnHjRlP7N998k4wYMYJUVFSQiooKMmzYMHLFFVeQRYsW6W1owUER5513Hmed/MQTT5AjjjiCdO/enZSUlJAhQ4aQa6+9ljQ0NHD7zZkzhxx77LGksrKSlJeXk6OPPtpUoJS17FWBFpmsqakhbW1ttq6PVfHfVOdH93311VfJ+PHjSa9evUhZWRk54YQTuDIMFPfff79enPqwww4j3377rckSmhBC/v3vf+tFwb3vsLvw7ofUsPPcpe1GjhypF3z/61//qr8r2PupubmZnHXWWaS2tlZa/Ne7fwofdr6PhJgt1QmxP29auHAhOeKII0hZWZm0+K8b9wyLeDxO7r77bjJw4EBSUlJC9tlnH/LOO++Y7mtCEvOq++67jwwbNoyEQiHSs2dPMmrUKPLdd9+lHL+qPMEjjzxChg0bRoLBIOnduze57LLLlMV/RcjGWMjQCCmiDDEPHjx4KABEo1H069cPo0ePxtNPP531/qZPn46jjz4ab7zxhtLdyoOHzkKu7wen8O4fDx482IEXl+TBgwcPOcbbb7+NzZs3c2YzHjx0VXj3gwcPHooBXT6nyoMHDx5yhVmzZuGHH37A3/72N+yzzz56fTkPHroivPvBgwcPxQRPqfLgwYOHHOHxxx/HZZddhl69euGFF17o7OF48NCp8O4HDx48FBO8nCoPHjx48ODBgwcPHjx4yACeUuXBgwcPHjx48ODBgwcPGcAjVR48ePDgwYMHDx48ePCQAbqcUUU8Hse6detQVVUFTdM6ezgePJhACEFTUxP69evXaYWDvfvEQ74jH+4TwLtXPOQ3vPvEg4fUcOs+6XKkat26dRgwYEBnD8ODh5RYvXo1tt9++07p27tPPBQKOvM+Abx7xUNhwLtPPHhIjUzvky5HqqqqqgAkLlx1dXUnj8aDBzMaGxsxYMAA/bvaGfDuEw/5jny4TwDvXvGQ3/DuEw8eUsOt+6TLkSoqO1dXV3s3toe8RmeGSHj3iYdCQWeHEnn3iodCgHefePCQGpneJ55RhQcPeY7PP/8co0ePRr9+/aBpGt5+++2U+0yfPh377rsvSkpKsNNOO+G5557L+jg9ePDgwYMHDx66KjxS5cFDnqOlpQV77bUXHn30UVvtly9fjhNOOAFHH300vv/+e1x99dW48MIL8eGHH2Z5pB48ePDgwYMHD10TXS78z4OHQsOoUaMwatQo2+0nTZqEwYMH4/777wcA7Lrrrvjyyy/xz3/+E8cee2y2hunBgwcPHjx48NBl0alKlRfW5MGD+5g5cyZGjhzJbTv22GMxc+ZM5T7hcBiNjY3cfx48ePDgofjgzb08eMgOOpVUeWFNHjy4jw0bNqB3797ctt69e6OxsRFtbW3SfSZMmICamhr9P8/61oMHDx6KE97cy4OH7KBTw/+8sCYPHvID48ePx7hx4/Tfqb2oBw8ePHgoLnhzLw8esoOCyqlShTVdffXVyn3C4TDC4bD+e76ENU35bg2e/nI5CCHc9pP26Y9LjhzSSaPqPHzw43o8/MkSxOL89Ri5a2/85dhdOmlUhYk+ffpg48aN3LaNGzeiuroaZWVl0n1KSkpQUlKSi+F1SXy6aBO2Kw9hrwG1GR3nhzX1+Mf/FmP8qGHYta9nS5zv+PPr87BgXQMA4KyDdsC5hwzq3AF58JAGsj33enjaL3h3/nr999KgHzf/Zjj2G9jN1Pa9+evx6KeJuYLqnlq2uRk3TJ2PxrYObvv23crxyFn7oDToRzQWx9jJ32PppmauTUVJAH/73e4Y3s/6+frRTxvx4LTFiMYITtlve1x4+I6mNqu3teLaKfNQ39qBIb0q8eDpeyPg5wPE4nGCv7wxDz+tb0R1aRB///0e2LFnpelYL85cgZdnrbIckx0M7F6Oh8/cF6GADx2xOMa+NhfLNregW3kI/zhtL/SvTcwR/v7+QkxftAklQT9uPmFX7D9ou4z7ZtEWieFPr87Bmro29KwqwT9P3xs9KhNzkJvf/hGzV2zj2pcEfLh+1DAcOqQHAGDqnDX41xfLERfm0CrsPaAWE07eI+ulBQqKVKUKa5JNGCdMmIDbb789V0O0jSc/X4rFG5tN2x/5ZEmXJFXPfLkCC9aZH7oLNzRh7MidEfR7RpV2ccghh+C9997jtn300Uc45JBDOmlEXRtbm8O44LnZ6FlVgll/HZl6Bwv8+/t1+HzxZuzer9ojVQWA1dtasXBDEwDgqS+WeaTKQ0Ei23OvjU3t+n1C8dbcNVJS9fwMY66guqc+WLAB3yzfZtq+cEMTvl9dj4N37I7FG5vx7g/rTW0A4L8/rEtJql76eiV+XJsYxxOfL5OSqo9+2oivl23T+778qCHYrV8N12bF1hZMnbuWG/vlR+1kOtaTXyzD6m3y8H0nWLihCfPXNmC/gd3w07pGvDd/g/63TxZuwjkHD0QkGsekz5bq29+cs9Z1UvXdyjp8/PMmfUxfLdmC3+3dH9taInjx65XSfd74do1Oqp6bsQI/rbcvkizc0ISrRw5Fn5rSzAdvgYIiVekgX8OatrUkVlDuPmkP7LBdOZrDUVz60ndoCkfREYt3ORKxrTUCALjx+F2xa99qEBCc8/Q3AID61g70rOq6KkpzczOWLFmi/758+XJ8//332G677bDDDjtg/PjxWLt2LV544QUAwKWXXopHHnkE1113Hf74xz/ik08+weuvv4533323s06hS6OutQNxAmxtjmR8LKrkRqLxjI/lIfu46Te7Yt6aBtz89o+IxuytqHrwUAxwMvc6/9DBOG63vgCAf3+/Fm98t8YUtULBbo8p7im6/ahdeuLCEQmyc8PUH7Cmrk3fn/7sXhHCg2fsAwB4dfYqvPvDemXfynHYGKuqnalNinP62+92w+AeZiXLDq6dMg/rG9r1PqOmvhPvFVH9icXdf99EhWPS5yO7/aULDgIAfLBgPV76ehU3Xtr+uuN2wZ79ay37+uNzsxGJxU19ZgMFRaqKJayJEIKGtsQE66hdeqJfbRlicQJNAwjpmiSivjVBMg/dqbu+klNdGkBjexQNbZEudz1YfPvttzj66KP13+mL6rzzzsNzzz2H9evXY9UqIyxg8ODBePfdd3HNNdfgwQcfxPbbb49//etfXux7J4ESoGicIB4n8PnSDz+gLzvxZeghP7Hn9rXwJz9vOxM1Dx7yEdmee+3UqxI79UoQhXlr6gEAqvkvO+FX3VJ0e7/aMozYOaFsVJYEuP3pz9KgX2/z5ZItyb5T36v8OOTtxe2yw4rbUp3TPjt0w+79a+SNUqBCuAZi+gntw864M4V4yYwxJX73+zT9c1myqck0LvrvPfvX6u1UCPg1RGLmPrOBgiJVxRLW1BKJoSPJsruVhwAkvkDVpUE0tHWgvrVrkQhCCOqTShW9HgDQrSKExvYo6lo7VLt2CRx11FGmhx8LmbXtUUcdhblz52ZxVPkJQgj+M28ddutXjZ16VaEtEkMo4NMntm71sWRTM4b0rLRFkMLRmP7vjngcJT5/2n3TF0lHrPCUqjV1ragIBdCtIpS6cRGBfvfsxv578JBvyOXcy6dZ3y/sBD8VmWEfz8ZxhTY+to25DxW4Cb5iBzNhMrczE5hU55T+u8w4P0os5X3YGXemEI9JxM+F/eySv7DzIPpPO6/2VN8pN9GpMWbNzc34/vvv8f333wMwwproqvv48eNx7rnn6u0vvfRSLFu2DNdddx0WLlyIxx57DK+//jquueaazhh+2qhrSRCIkoAPZSFjgtWtPJj4excjEc3hqL7yzpKq2uS/6fXy4CEVPl20CWNf+x4jH/gcDa0d2PWWD3Dy4zNc7eON79bgmH9+jqe+WGarPRuq15FhCBh92RVaKFldSwS/uv8znPrETMsFgmKEX/OUKg/5hXyee6UiNoRTK6zbsASEkieROHBtHEy+2b5Vzc3EITWpUj0f9fFmMGun5ycSGKNv6+1uIhWhYw0l6L9Z9ZK2t2M8oTkgy5miU0nVt99+i3322Qf77JOIZx03bhz22Wcf3HLLLQCgDGv66KOPsNdee+H+++8vyLAmGurGEgiAIRGtXYtE0OuhIpn1XYxkekgfNHEYAD77ZTMAYN7qelf7WLOtFQCwKvkzFcIMqco0F4q+cDtyEBvuJpZtaUY4GseSTc1Y19De2cPJKXxe+J+HPEM+z73oBDgVubDThp1ua+DVDvqTa5OibxY8uZO3V4XX8W2Qsg17LA3pK1VGH3wIpLidxOXt3YQqxJCqfvxnZ97HIFWp+5Ltny10avhfVw1roqSpNkkaKCiJaOhiJKJOEvrH/t7VSKaH9FESMNaJ2jtiFi3ThyruXAVeqcqMDFEuVWhK1cZGw1r5+1X1um1vV4BfCDvy4KGzkc9zL11NUfydMH9J1UbjVKjk3wi/r0+iiNi5VdnLpxwHsf5d2kZxNGO8NgangKhUiV0Zm7OvVKU6b5mCSLj25nYqGOGDjofpGF3LYi5P4JEIHjTcUSSZtV00HNJD+mBJVThLDnn6Kp/Nw0di7ilVhlFFYSlVGxsNder71XWdOJLcwzOq8ODBPrQUIXiyEDBTG0lonyYsbuiKCJd3ZX1cvo/USlV6OVXW/WVSZ0kVAin2kYucqlQmGT7J55JpTlUuQs89UtUJ0MP/KkQSQUlV1yIRMpMK9vf6LkYyPaSPkqARPtoeya5SFbP5gOaMKjJVqgg9TmFN0DdwpKq+8wbSCdDD/7pYLpkHD+kgVU6VPYMI9cTcXk5V6nHyhhmpxyr73W4bwDhXN5WqfMqpIg4/Fyck04kBSabwSFUngJKqmjIxp4rmEHUtElGfQqnycqo82EWIqe9W35ad+0h/+Nt8QrPqVCRDUqXnVBWY+98mJvxv/tqGght/JtDD/zylyoOHlEhlFsGF3Snzj5LH8klCyIScKp80RNBZTpWqvbhd1sxMLlT90TGmz6pEFdBE6OLWuVZuIlXf7GlqEgVRRpxVSKV+ugmPVHUCjPA/eU5V1wv/ozlmnnGHh8wQ8BtP2GwpvqoXkgpsGGJHNLOHOt278HKqDKWqvSOORRuaOnE0uQUNufGUKg8eUiMVsbEVdicN7RMt1WFqI3OZU8GeUiX+bm5oCoNLqb65YalO+xb7UG3PAanS+06ep4QQc9c8zv/NCk7COjOFR6o6Aapwt64b/kfdEOUk01OqPNgF+8xkrfjdjKU2wv/stXdTqSrUOlWUVJUn3T27Ugignwm56Wp28h48OEUqYuOk+C+fU8XvLyMpzizV7eRUpc6Xclr8NwNOZTo/lSLVmcV/peF/PrqPWR20R6o8o4qihsqYgZIsz/0P3O+eUuXBLlgzAJaMu2kSYBhVpKFUuZRTFXVwPttaIllzQrQLGv63R/8aAIkxdRWwhac9swoPHqzhJPyvc4v/8mOS16CSj8tqW8pzyiCpSlQBU+U1idvdhKPiv5LvhBOS2WWK/3ZVqJWqrhr+lzqnylvh9WAH7KSVvY/cDL1SJfOq4GadKt39zyY5q2uJ4NC/T8N5z3yTUb+ZoCUcRVM4CgDol7RSz8XLLV/AToK8EEAPHqzhxKhCnX8kUaEEtUOWo+TEJc5OvpS5TWpSpc7PomNMOTQlTA6IKge+uHy7m1A6DyZfbXaL/9pRqrpM8d+uijqF+1+3Cup217VIRCr3v0gsjtYsObl5KC6wk1ZWDXHTgZw+zEXVQaVcuVmnyjCqsPd8WFvfhvaOOJZubs6o30ywqSmhUlWE/KgqTZRG7EqmDX7mpV9gTvgePOQcxu2iIBfcv63byIv/Jn7XDREkfdt5OtnJOxK3SKd1oiqk6o/W3sqg+C/dk45DHI/qeubCUp3oPyWfi/C3xJiSf7NlVCHvMxvwSFUnQGXMQHOIuhqJ0MP/BJJZHvLrbm5dTb3zkB6iqvA/V3OqzHHnN741H4f+/RM0tJlDd1lL9Ug0jvOe+QZn/+vrtB7wevFfm7NzFQHMJWg+Ve/qUkeWxcUCv6dUefBgG6KaIsJeThXhjpX4N/83ok/KZbWsUt+nJoVJ1saG4mO3JpSRa5RyaEqIYXCpakVRZOOxpSKlVgoif63sK1W5fO94pCrHiMbiaGpPhMKIykxZ0I9QoOuRiPoWGv7HXw9N0zxbdQ+OwL7EWFOITEjFF79sxk/rGpljmY/52eLN2NDYjiWbzK52rFJV39aBzxZvxldLtqKxLep4LEb4n73zoWN0koPlNiip6lVdktPY9nwB+9L3cqo8eLBGqmdEusV/lTlV0lpWqcdprwaV9T7y41j3VyzFf53lVNE2ZkLtFf/t4mBXsquToTAUmqahtqxrkYiOWFzPt6DnzsIjVR6cQEUe0g0329TUjnOf+QYXPD9b3yZL5jVqbJiPwZKqpnbje9yRRiwYPb5dF0FVjHwuwStViW1dSbHxjCo8eLCPVMSGd4CTT5SJJWHin9Xpuv+ZQuekKpRIHFKTKtX5uJFTlc/Ff8V3qFxBZPe3TzK9nKoiBs2nqi4NIOA3X36qXnUVEsGSzBopqfIcAD3YR0xBVNKdxG9qDIMQYH1Du+6gJwv/o2RORl5Yo4rmdkOdSqfWFH3h2t1XV7bSeJss2tAkDWd0io1J57/e1aW6aUMX4lTcJMgjVR48WCOVqmCnWK5ewyiLxX/tKFWq8Dq+jXzsqja5KP5rHnf2lSp7royMUhU3E2cVPPe/IoZuylARkv69qzkA0uuhJplBrp0HD1ZQCTjpKjVNDAnamjS+0OtUMceM2VWqwsbx0jGtMEiSvX2NcTk7/7mr6nDsxM9x1H2fWrb7Zvk2fPTTRss2evhfFRP+lyNy8fnnn2P06NHo168fNE3D22+/zf2dEIJbbrkFffv2RVlZGUaOHIlffvnF1TFompbT4pMePBQyxNwnEfbC7qiKwR43e8V/Zb/L29gJ/7Nuk4viv7kI/1MRNznZNStVstwrFbziv0WKf32xDNe8/j0Ac/4QBVWq7nr3Z/z9/YW5Glqn4LVvVuHiF74DoCaZ9Ho8OG0JbnxrfpdyRfTgHG4rVc0MCdqcdLGTrfLFhBcCC9aoglOq0iAWdBe77n/pGlV8unATAOtC5LE4wWlPzMRFL3yrXxsZqOlOdWnQUc6CG2hpacFee+2FRx99VPr3e++9Fw899BAmTZqEWbNmoaKiAsceeyza29tdHQcNAfSUKg8erOFLQWyckBmZCpWN4r+qfdwq/stu0zKYtedT8d9UNbJSFf91YqnuFf8tUjzy6RKs3tYGANild6W0zS59qgAAGxrbMemzpWgrYhfAJz5fhmVbWgAAQ3tXSdvQ67GlOYyXZ63SQ4k8eJBBJf6kO5ltDhukYkuSOOhx50xfsZiFUhVjc6rY8L8MlCq7OVVxup+zJF2ZaixiU5NBPKyKC7Orxrk2qhg1ahTuvPNOnHTSSaa/EUIwceJE3HTTTfjd736HPffcEy+88ALWrVtnUrQyBT1vj1R58GCN1MV/7YfdZbP4rymnSvJItlNE12nelRtKVcriv3H5djeRqkaWXGUkpvb2LNW98L+iQyxO9PyEJ8/ZD387cXdpu6t+tTOmXHoIAslvfzGHAdI6Qv84dS88dMY+0jbnHTIIUy8/VM+3YmsPefAgQqVUpVsfiFWWtjTzShWrfuk5VZKHNh/+Z5A0u2YTLOjhO2xOzjk1zcGEPmiDVK2pa9P/bfVio/368iwMbvny5diwYQNGjhypb6upqcFBBx2EmTNnKvcLh8NobGzk/ksF+jzPh/P24CGfYdQUkv/djomCTMUQaxXR/di6T07qGaWXU5VuG+PfGfhU6HunLP7bCUqVlYEI/ZfM+dEWqVL0mQ14pCpHaGzr0G+Mo3bphZKAX9rO79Ow/6Dtit71LhYnaEw6oR0xtAfKQvLr4fNp2HeHbuhRmTTwaPNIlQc1VGF+dnOQRDRJw/+Q/GkmLLIXoptGFU6VKvZ6OAmBDPpTv6lWb2vV/211aPo3v0/TE8fzgVxs2LABANC7d29ue+/evfW/yTBhwgTU1NTo/w0YMCBlXz4v/M+DB1vQ1RQbxX9V7WR7qpzvZIqInbvUnI9kTYZkv0vbyPpitrqjVMk7y9fivz7J5+Iop0oSPpgteKQqR6CKU2VJQK9FZYVa3QWwOEkESzJry+T5VCy6miuiBzM2N4Xx2PQlXNiZCKWlero5VRZKFWu2YORUmY/BW6qzOVXph//FiXqC3hyO4pynZ+G1b1bxY3QwoQ/YsFRilSqr6xtjwjmMMDjbQ8k7jB8/Hg0NDfp/q1evTrmPP4/IpAcP+YyUxX8dFNSVKVX2isw6V6pke2Qlp8rF4r92lapsPLZUpNTqc+Hs9NMo/uvlVBURaMI3VaBSoZvuAlicJCJdklnM4ZAerPHS1ytx7weL8NLMlco2Kle5dCfxTRypSnz36IOdNaewq1Tx7n/pKFXGv1Xugd+trMMXv2zBi1+v5No7IlVM+J9qdW9NnaFUWR2aDcVxYlmcbfTp0wcAsHEj7164ceNG/W8ylJSUoLq6mvsvFfxFQCY9eMgFUudU8b9bGUTYyqlKu/ivnXHYH6vdNhkpVYJik8osQtzuJlLVyNKkn4uxj5Piv15OVRFCt1JXuP6JKHYSkS7J9JSqrgt6LzQyREeESqlK36hCEv4Xp8c0H9tR8d+0cqqMDtTnGtfHxY3NQXds+J8q94ua7tC+VMjX8L/BgwejT58+mDZtmr6tsbERs2bNwiGHHOJqX174nwcP9pCK2Jgm49K6TknCxNWp4v9mVxFRwRS+Jg3tE9ukJlXS4r/MOWZS/NdsKy8QurhiexYeW6mK//IqY2bFf3PpOhvIfhceAIMMOCcRxUmqnJJMarle5xlVdFlQhzmrsDnVpDXdSXyTRfifXoiXI1XWSlV7h/Hv9Ir/Gv9W5VXFGbLHkzD7rCrAWGKFo3FpDuiaejanyiL8j1kRznX4X3NzM5YsWaL/vnz5cnz//ffYbrvtsMMOO+Dqq6/GnXfeiZ133hmDBw/GzTffjH79+uHEE090dRz+HK6UevBQyHBa/Feq7CSfL5pFaJ9sUp6qRpZVv+laqpuUN6mLoEtKlXANUtWKkvXvFjIp/ksIYUhx6r5y6Trrkaococ4pidCVquJUZpwqVbVFHg7pITUoIbEiIypS5Yal+uZm3qhCFvKXqk4Vi0yK/yb2tyaQcULSNqrwM2+qcEccKOX/Ho3Fsb7eyG3L1/C/b7/9FkcffbT++7hx4wAA5513Hp577jlcd911aGlpwcUXX4z6+nqMGDECH3zwAUpLS1WHTAtenSoPHuzBzeK/7IRbVfxXGiKYx8V/M8up4selOgc755YpHBX/9fE5UeyuTor/5uK945GqHIEqVd1sk4jiDv9zrFQVuXGHh9SgSpVVLpKSVKVrVMGE/zW1R9HeETPlVPFKlfkYbPgfi0yK/yb2VyhVzIuRvR5OJvTsS1wW/rehsT2lQieOJ0GqcqvYHHXUUZYvUk3TcMcdd+COO+7I6jjoqmu630MPHroKUhEbc06VuU2nFP+VDMRtowpNsxfupoKoAqpCD8VzyU5OFf+7WCNLs/HZJf6W+nqkMj9xE15OVY5AyVGN7ZyqBPlqKFJlxmk4ZG2yTlV9W3FeDw+p0Z4kJ2mF/6WrVAn5W1uawyaXohhD8mQvqbCCVFkpVZ8u3ISxr83Vyw6wx6NQKXZ6Ha044SYgzkiV8e+wpLAv6/zH9ik9Fq1T5WPC/7oYt9DD/zylyoMHS6QiNrZykCyMKgy1Qx1mZodDiG3kOVXycbFwdj4ZVqkykRP5WOwobJkiZfifRfFfzg3RBovJZX1ET6nKEZwqVYb7X3EqM/S8aj3jDg820R5J5lTlNPxPJFURU/gfqz6I3VipalZ/G/PcbABATVkQd/zOKBRux/2PJVXpGlWwk38ZKWRrVAHWkxBZ+F9Xyy3yjCo8eLAHp8V/5coOSR5Lki8lGCLIiv9mLadKMlg7+UvGWDODJhT/Nfdtvd1NZFL8lwuHtNGXeN7ZhKdU5QhOc6pqi7wuk2OSWeG5/3V1tEdp+J+FUqV4GaYbdkWNKronjVI2N4U50sL+BMwvI5VzHmCvgO/ijU3c7+zLRF2Ty2jLt7fPqtjrZYdUWZEF+jefpum5RflgqZ5L6JbqXey8PXhwCp1UuVD8l51wi4V9O6X4r43jSNs4qMlkBVGJU/UtjiEri2CiQif8S1b8V7arV/y3i8K5+19xKzPpGnfUt0a8EJouCsP9T/35u2mpHonGdUIxuEcFgET4nxg+YpVbJAudo+iwMabGNl4ps6NUEYb08XU9nIT/GW1lOWE/rW9UtjePJ/HTp2n6pKWrKTZ68V+vTpUHD5YQ60mxYF3fKNLNqSLSNvld/DdDTmWj+K98uy2W6RCpamRZfS4skfaK/3ZRODdmSOZUtXUUJYlI1/0vTnibaw9dB9T9z1KpUoTUpTOJb2FC/3boXg4A2NYSMZQq+pPNqRKGlqlSZZVTpQofNFwJeetyJ2aDfPgfTwwJIZi3poFvbyf8z2c9YSpm+DylyoMHW7AiNrLbxyqkjs+Xcrf4r718KTttSOo2jNqfCdIt/puTnCohtI9XEPm/cTlVXvHfrok6PdzNWfhfnJgnVsUApySzJOBHeShRK6dY1TsP1tCVKqucKpvJzXZA86nKgn6UBRPfvY5YnAn/M/dpVqqsSJUdpYq/97lwPmVOldE23fA/3qiC329jYxibm8LwaUCf6oT1uL06VRr8OQzDyCcYSlXXOm8PmSEeJ9jQ0I5NTe2pGxcJrMwibBMtibGD28V/7dWgkitBztvQ8aUcliXyuvivLaXKPD4nlupeTlWRoL0jhrbkhLC2wp4yEwr4UKGTiOIjVU7D/9i2XZVUPfrooxg0aBBKS0tx0EEH4ZtvvrFsP3HiROyyyy4oKyvDgAEDcM0116C9vXBfzpkU/02n2CxVRCtLA8akmJgf7DFmPOL70EqpsvobRWO7VfifNYE0hf85uAbsdRTHOW9NPQBgaO8qlJf4TeMSQYfg93Xd8D/PqMJDOrj4xW9x8IRpOPCuabj7vZ87ezg5gZWqYGVKwW2T2HKbHeSIpI36mKn6Tbf4r4lcWBT/dSunKh+K/6YyyeBURmExjjDXKN+K/3qkKgeg+VR+n4aqEvuGi8XqeNfeEdNDueySTMAIAeyKZhWTJ0/GuHHjcOutt2LOnDnYa6+9cOyxx2LTpk3S9q+88gpuuOEG3Hrrrfj555/x9NNPY/LkyfjrX/+a45G7ByP8z0IVcTGniipVVSUBpnYKMdX4YHOqRKVMVaMKsKdUibCjPLG1RuIWY7Pbjxj+Nz8Z+rfn9jW2XlZsmI2d8L/61gjOfeYbvDV3je3x5jv8yRe/F/7nwS5awlF8stB4vn+7YlsnjiZ3sHIIZbcZC13qdtLCvvqiGNRtHBT/tcqXFPuwGqud83Evp4ofH7toCBjnYhgLZdavDOJ5i+/VbChVXcKooiusvte3Je3Dy4KOCrcVa62q9EkmrVVVXCTTDh544AFcdNFFGDNmDIYPH45JkyahvLwczzzzjLT9jBkzcNhhh+Gss87CoEGD8Otf/xpnnnlmyvsrXxGLE10xSatOVVrhf4nvaWVpgCMPoqV61KJOlUhIWDgJx6NgD6+uU5UcHyFcPaiYo/A/hlR1yJWqPbavtWWRTq+TxoT/WbV/bsYKfL54M66ZPM/2ePMdXvifB6f4YU0Dt/jQZhFKnA7yde5lRWzYx4ZIBGTtslX8lzgkd4Gk1CIPVeSPY9XGl2H8n6r4r4rYWJ1bpjATOroYmNhut/ivs5yqTEZsD51KqrrK6ntdizNTBopiDXfTa1Q5JpnJ69FSXCQzFSKRCL777juMHDlS3+bz+TBy5EjMnDlTus+hhx6K7777Tn9RLlu2DO+99x6OP/54aftwOIzGxkbuv3wCS05yVadKD/8rCegP9Rgxaj8Z9U5YUiWOWz0RslLcVLcF25fKsIO1eueUKkfhf8a/2XMghGD+2oRStRerVFkcWw//0zRbk5ZiFHM8owoeb81dg7ve/QkPTful6BYN3cLc1XUAgN7VJQCM8Gc3kM9zL6u8Jva5EbAozyBVqgTSkknxX/Y5H7AgQ0QkDhamGgELApPt4r9i36rtbiJuOm9+u7T4r1hjTIOtOWQu6yN2KqnqKqvvTk0ZKGr1AsDF9dIxCv86JZk0/K+4SGYqbNmyBbFYDL179+a29+7dGxs2bJDuc9ZZZ+GOO+7AiBEjEAwGMWTIEBx11FHKl+CECRNQU1Oj/zdgwADXzyMTtDOrtJbuf8mn7cE7boc+1aW6kUI6D1OOVDEvTtEhiQ3/E1/wlJBQowsWVudRXWrcG1wBXy78T35O7Gpj+kYVxn5sCGNDW4euNA/tXWWLJLF1qjQbJKxvTSnXXzGATqq6Qk5VfWsEq7e1ojUid2nd2NiOaybPw1NfLMcDHy3G69+uzvEICwNzV9UDAA4d0gMA0BZxj1Tl89zLmPib/8aF/1moD9J8Kfo3YWLOVUSyOfmWj8NOaJ/6WNbHMY00LaiK/4rXUrXdTbCLbYk+CLddVvxXJMR2r0eXKP6bi9V3oPNX4P/x4SLc8c5PAAylxS4oCXt8+hLc8OYPReGYNemzpbhuyg8AnJNM2v7Fr1fiylfm2LKk7qqYPn067r77bjz22GOYM2cOpk6dinfffRd/+9vfpO3Hjx+PhoYG/b/Vq/NrosOu0lrXqUp8J8YcNhhf//VX2Ll3JYDMcqq48L84E/7HGEJQiCuRlJBUlprDXK2+v1VM+ybG/ZMlIypSxsbLc86ELliqs+paadCvr/LayqnyWU8c2ONSrK1rsz/oPEY2w2jyCbOWbcV+d36Mw+/9FAfdPQ11LeYFMLEkRrFFYrgBQohOqg4Z0h0AdLOrTJHvcy+r4r/sFn2hK8Piv7KcqlR3KXsb+ywVJnpcOi6LNj5133Q/J5E9MqiK/4p9058+CzUwUxhKodi3mTCJn4vMIdAKuhqZg+ev/YQWl2G1+r5w4ULpPmeddRa2bNmCESNGgBCCaDSKSy+91FKCnjBhAm6//XZXx24XkWgcj3y6RP99lz6VjvbfpU8VAGBLcwSvzV6NK47eCQO2K3d1jLnGI58s0SerQ5PnZxf0etS1duCdH9bjkiOGYI/ta1wfY76hR48e8Pv92LhxI7d948aN6NOnj3Sfm2++Geeccw4uvPBCAMAee+yBlpYWXHzxxbjxxhvh8/HrKSUlJSgpKcnOCbgAjlRZWqonftKQgkwUgubk5K+6NMiF/xmx3xJSJXSjk6qSADY3hbm/WRX/9TNv+vrWDn1Bxk6dKtb9j32HOAk9Y9uy4X/0XOn1tVNUkX0B2gmvYa/nmrpWDO9XbXvc+Qo9/K/I14EWrGvUP7+m9ihWbmtFtwp+8Uy8F9tdzhXqDBBC8PP6JrREotixRwW6V6b/LCWE4JdNzdjSHEbQr+GAQdsBcE+pyve5l2XxX+arooeNWRpEqPNy5HlX9hY/pGGIFu0CyWRSK/c/MQyOaxPnzyFdiCRJDMFTb8+sXxnE8xYjQDSLz4USL7ukqsvkVDmF09V3oHNX4KmhgqYBb1x6CK4ZOdTR/mcduAPeuvxQ9KhMvJS2SVb9CgmRaFwnVM+efwBuG72bo/1P2KMv/nvlCAyihVi7yApnKBTCfvvth2nTpunb4vE4pk2bhkMOOUS6T2trq4k4+f0JBaAQFU92ldY6/C/xN/rysKOMqKArVSUBLonYUqlShP9VSgxZrJQq9jjsSj77UlDtz46HJaCOjCo4pYohVcLqosr++OOfNuK6KfPQFolxCeG6pbpVuCDztzVFplQ5+QwKESJhki1miNuszFwKBa98swrHP/QFTp00E7964DNp/hMhBK/MWoV7P1iIZ75crjzv856djV//83MAwPB+NagtS4QCR2LxTovOyOXcy25OlZX6a1X815RTxSlV4NqowP5dNHmQtbNqozKLkLXJVk6VySxCsd1NmEIjhRpZfE6VfNx2L0cuLdU7TanKxeo70Lkr8DT3oKYsqK82OYHPp2GfHbqhR2UJtjRHUF/g+QWUZPo04MihPR072Wiahj22r0HfmjKs2NrapXKrxo0bh/POOw/7778/DjzwQEycOBEtLS0YM2YMAODcc89F//79MWHCBADA6NGj8cADD2CfffbBQQcdhCVLluDmm2/G6NGjdXJVSGBXs63C/+icQ1SqrPZRga1T1ZpcJY4xluo0v4rPqeKPEbEkVRYhc8zcib3v2fARldLFjoEloE7mY+yh2ZyqWExUqsztAeDR6Uswd1U9jt+jL/PytJcwHOeUquIgVV1FqRLvs1QTY8DazKVQsHxzi/7v+tYONLR1cGGsADBnVT3++tZ8/fe+NaUYtUdfrk1HLI7PF28GkHh2/X7f/igLGcdpj8ZR6c9sLTzf515WhVplpEr2KJHlVJkd5GBqY1UjSzUOS4XJgQmFdRv+HNKFqAKa+o6rxpRZvzKkMsngFEST5bszkpnL4r+dRqrY1fcTTzwRgLH6fuWVV0r3KbTVdxpP7jR3SATdv9BJBEsyM7EG7VbR9epVnX766di8eTNuueUWbNiwAXvvvTc++OADPYRj1apV3L1x0003QdM03HTTTVi7di169uyJ0aNH46677uqsU8gIYYdKFVWoMrGyppbqFSUBfeVZNH+IE159UFmqy3KqrIr/ssepd6hUcQ6BcXPonh3w4X8x03Z6fQ2ywB+bErFINK5f+4SleuqXNK9Utdoecz6DzoOL3f1PVOLsKVWFT6pEMilbxBG/y43t5vcXa8yy4PZjURr0gxACTUtMrNsiMekCjRPk+9zLTvFfTbNWH4xwOTVhkluqg/ubChy586vfMfaMKsTjqPtzK6dKvAZ63ym2uwli6oPfLndlNBY02e2pYKV+uo1OI1VA8a++U9c+py53IiiJkCX9FhLcIpnFWhQ5Fa688krlS2/69Onc74FAALfeeituvfXWHIws+2h3aKlOX2KUvKeTU0WJQUnAx7kgsYeKxQmnPljlVImwaw3PLh6wL4VUdaoAoCNq/OLkGnDhfx0sMUuSVj8fXim+rHTbeWIYe/hYS3WLsbB/W1tfHEpVV6lTJeb5yU5XJBxuWoV3FsRJp+xz3tLMv69kayL0Xq8uDehKl6ZpKAv60RqJuXat8nnupU/8LezHfZpmaZKT7eK/vKW6k3wp9ViN41icT4YJO2IIpDE+vo5WPC7f7ibMNbyS7wxmEU4ct9l23W5OFb9fNtGppKrYV9/TtVIXYZCIwlZmXCOZ5V1Pqerq4MP/Uluq00ksnfRb8Bcl6OQv6NeM8IO4qFQRS6WKkqrSoA9+n8bnO1mcB/uCZr/nHGFS7K+yUXeiknDFf6PmEEI6SVDZHxtmGcyqp6bZernxRhXFQapUil42EY8TrNyWUEcGbleeceFQOxDPz2qCSFGMSpXsc97azBvVyO5Hfc4gmHtQUuWWA2A+z72szG9YImRpaCELITOpHZSomCfvqRQNWfFfeU4VEdqoz8lW8d+Mc6oUipQpBE++3U2kyufiVUYIbQi3PRWsvituo1NJFVDcq+80F8I9ElHYyoxbJLNYiyJ7UKO9g7f1ToTEmJ+oUZFUZaAQ0DDDgM/HhZqw75e4KadKPmEsCfgR9POkyqr4rzr8z4ZSpejDyTVQFf+lJI1eD1UIDmvmEYsbL0A74X/s3xraOtDY3sHV7SpEZLOIpgrjXv8eb3+/DgBw8r798cBpe2e9T5FcyM7XFP5XDEqVjfC/LQKpkt2PdAGFmlNQUNXKzVpV+Tr3sgzrY8Lg7BhasK8IY2FM3caqRhZ/fOPf1jlVtE1ShbJQ33JR/FflgCj2rdruJpwU/1UpbHYXirpM8d9iR53rJKKwlRk6/poMSWZNWXEWRfZgIB4nuPntH/HaN6sAmGu0qFb84wKp0hWCNB6mUcaUQWapTsdhaameZCehgA8hIcHcKjeMI1VtbJ0qllRZ16kS+3Bi1sErVUxOVZx/EapCcOg4CUNC/T6b4X/CsYqhVlUmYajp4vvV9fq/f1qXm/qMYk6V7HS7Qk6VbPJmDv+TkKo2+o4UlKqkWUWri6QqX2HUqTKDbtPAFIS1aCcjIdTsR8/PYioiWdXI4o7BfL5WOWC69bdVDSpBmUl13pmAnivtUyRrtB/Rsjwrj60U5y0r/gvQdwoxbbeCeN7ZhEeqsoj6lsQDsluGJKJYcojcVqoKXbnzoMZ3q+rw4tcrccPU+YjHiamWjYogmJWqxPZ0JrPUXS/g9wmW6jyJsrRUT5LBkoAPoQD/uLWbU1XH5VQZbSIp6lQl+mBCE9MmVWazC59AWsWXFWs3z1uqm48vQvysiiEE0J8BuU8XzWFjAp4rhcxELmwYVRRFTpWD8L+qZH6l7DMx3pH8nKEsqVQVw7VKBatnBOv6prezMIiQ16AS20DZRgXeMMNqvImfdnKqrELtjDwj63GlguiCZw7Bk2/PhsGDykpeqjIyv7B5zU6L/+bCqMIjVVkEJUHiqpNT0FCAhkK3VG91h2R2Rfe/YsTMpVsxefYq6d8CzJtuTV2baTKhUnnE5NdMwv8oIQn4NW41kl2Mj8f58D+lUuX3ISgqVRY5Veyzv0EZ/mfD/Y8hXk6UKnZSGLEo/qvXnVKs1MfixKhtpdmrG8YSj5P37Y/ulZk9P/MBnWFU0ZKsswbkTiGzk1MlEstIESpVsutNlaqe1SXKNqrwP0qq3MqpymfYy5Wy146fmCPZnnBtZMTLbk4Va74j28MwmMiPnCpV8V8VsbEaU6ZIlVPFKog8qSK6kmbXDTGXxX87PaeqmOE2iSh0pYqOv9Zz//MA4Nop87Cmrg2HDumBAduVc39jH5Y/b2g05V2oVB5DqUr87kb4X9DnM8L/4oR74bI5Q4AkpyqpsJUEzaQqHaWKfSmoSBI7kWVt250ZVRj/lilVhhGIuU+Az1vQJy8+zVRvRNp38o9nHDAAf//9nrbHnM8wwv9y0180Fucm4LkSyOyQC1rrjNqEF0P4n3hviedNCNFzqnpXlWLZ5hbp/ahaiKXhf27mVOUr7ORKcWTGsp3suOD2kxX/tatU+Rilyqr4b+Z1qszKWzpQFdFV1YrKaU6VVfFfH7+fYZlvry8vp6pI4FZOFSURNJywUGGQTHfC/5rao51WYd5D5qDFdWX1WtjcjEUbmtAuTLxUKo8x6c9cqaJ9BPyaEP5ntImbcqoEUsUpVfwbwG5OFas48CpU6pyqtMP/mLaynCoxZ80U/pdsxypliYkQHaMVoUy2z4FbXa6Q6/C/FmHynat+YzYs1elYKkKJNd1iCGkTz1u83s3hqE4eeyWVKqlRRZt8IbZrKVWJn3LjB4OQW5lKyOo6qQhFJsV/NY2JYrCoL2UZ2merDX8O6UJV/NcvEBvT9iw8Pthc20QfqRVE+nenluq5dP/zSFUW4Z77X5JEhKOWE7F8R50iXtwpapjQiPoCD4nsypBNvI2/Gf9etKHJNPFSqTz6pF8o/usk9E08VpAJ/2NzhABZThV/DCOE0IdQgK/nYpdUscnp7PtWXafK2M6et6PwPzanirOz50mrahJC92dJnZ+tU2Uj/M+f6Qwij5Dr8D+WiAO5y6kSFzus8kOo+tIVlCoa+lce8qMimVMlu/0bFGVH6LUqBgKaCnaK//p81s8SWfFfO7WOrGpk8eMw1BTLnCqTCiU7VuJnwEbxX7fd//TxicV/4/x2wP18JLFveng9b05S/Jfux4aB2kEui/96pCpLIIS4ZsxQUxbUVygKOY/ILfc/v09DdWnixeSZVXQOLnhuNk55fAY2NLSnfQxqzy1TG9lJycINjaawl5Thf0Jx2szc/3xcLhD7YowRMadKnFwlfvp9GkKCUmVFctg/tXXE9BcNp1Sp6lQxO3e4YFQhCyE0wivN4wWMlxd7jpqPL645Y+kWHHDXx/hwwQbpvkUkVGUUhpoOTKQqR7zFSU5VuU6qCp8oiOct/k5NKnpUllg+k/QQ+TJ+zpANS/V8hRFOZ54E2y3+ax3axytVViGCKrBqip3cLivDB0Op8qVsk63iv36x+K+wnd3mFsTztlIQzUYVZiXSCrks/uuRqiyhJRLTV+AzJVUJElHYtarcJJmAURzRs1XvHHy7sg7frqxDszB5cwI60ZMrVca2FVtbTSYtqQiFqFRlVKfKr3HkgX3pJcL/jLGIz2y28C3NqaKTSaucKvHh356ceNqqU8VsZq+to5wqNvyPWR2nYU70RahaLVaH/xntxzw7G5ubwrjkxe+k+xZV+B+dAOZIqWoS7stcGVXYyqmKU1KVWBjriJGcjS9bMJFJk1JFSVXI8plUr1KqkqSqtQsoVWKoFws+l8mZsYNo0mBV/Ndu+J/d3C4xb4iFOe9K3SZbxX/NOVX8dnabW1Dnc5kJMXvaiYVNZyTTC/8rAtS1JAhEScCnS/eZgIbMFSqJaA5H9ReuG6RKN6toKUySWeig9uCZhKPqSpXkTcMSgFicYIFQZye1UUUy5ycDgwB6rKCfL/7Lh/8R7tgqa2WfzyBVNPxHde3Y2k4UNASQN6qw4/5nNpmwA/byckYVOklM/K5aLTZIlRD+x7RXjacYw/9yXaeqs8L/xNwiWbf0GlQw78VCV6vEz1Ukl5uT4X/dK0ssVct6hZlTWShx43QFpUqcQLMwfje84azC7rjCvvRvgiGCrG+7RhUac2Cr0D47OVW2ih5bDysljGuW+CmSNau8JrefIaL5hpjnxdepYoh2nL3+NpWq5E9PqSpguGXKQFHojnf0erhNMgs5HLKQQQvZpmuHTJgwOhm5EMnJ2nq+VlGqfejqlx0LbxV0pYpzrRPC/wSlSpwoGSEOBhGtTJIqtXufeVtbJGZaCY1E5fuzzTilKs3wv3A0rvdtWKoLSpXJ7Szxkwv/Y1aXY3GY6nbpfQvEOJuIxWK4+eabMXjwYJSVlWHIkCH429/+5nrsfc6NKpKkyqomUjbgRKli3wPhjhzFJ2YJpvA/4Xpz4X8K1TISjesGIypL9a6UUwWYbcrZXBrNQqmim7iJuW59ThURWRtwbVQgDGmzyqmix9HD/6THQrINUraxG+6mguhUSJj3E9u3MW7zGNyC6rxlnx37KiAgcBoirquROXgMepbqWUJ9G11xyix/iIIep6FASYTbJFMvANxWmCSz0JGpUsVOQmThf6lMFWR/Z7f5TEqV86epbqnu5y3VRaWK7Vd88ehKFRP+R0lVh4KQsmMN+jV0xAhaIzGzCUYKB0QgfaVKnPB1xAhCAU3p/iceWmZUIYbKhAI+zoTDGGeyfQ5I1T333IPHH38czz//PHbbbTd8++23GDNmDGpqanDVVVe51k+ujSpo4d/qsiCawtGchL0AvGsnoMipSg4m5Pch4NMQjZOCN6swkSrhmUbD/3pWhnRHUHEfGuKsaYnPjUWphfvfPR8sxL/nrsWFh++IP44YnMFZ5AdEUwIWfNidvA0gVzuyUfzXrmFGQMgbkp1TwE5OVYaPRLFelhGCJ8+pCnA5Ve4+RFTnLVMZMy3+m8ucKo9UZQl1itjodNGtwJUqo0aVO9eDOgAWajhkoYPag6erVHGudClyqqT7y5Qq5oEpKlVpGVUoLNXZQ8UJP1FWhcH5fRpCgcQxdFJlI3yvoiSA+tYOtEaippetLfe/dMP/hLbhaAyhgE9Cqsx9svtz4X8+zVilJ8RUt0scfy7C/2bMmIHf/e53OOGEEwAAgwYNwquvvopvvvnG1X5ybVTRnCxTUFVKneas+11X34Z5q+tREvTh0CE99Em8U4iLHVZGFX6fhtKgP2k3XtgKjMn9z6RUGeF/GxrbpW1o6F91adCk0tL8M1n4X31rBOsa2tEaST+/NZ9glVPFKlVWBMgwO2CPS49BVRpzfxkV/5UpZkLellX+l5V9uVMSoYIqp8pcgJffrhpXJlCFRspC+1Q5VXYvh5dTVQRw05QBMMhIoZIIt0mVrlQVKMksdNAJccQVpcqaIMmQSt3Si9OmaRBACNH7CPh83MuIHXssbu3+JzOqoDlVdkgRJWAypcpOnaq0jSqEplRJMOWsKSYU9Bx4owpw1vQhBanKpVHFoYceimnTpmHx4sUAgHnz5uHLL7/EqFGjlPuEw2E0NjZy/6WCX1dM3Rl3KtAwMqp4pPr+//7xGbjs5Tn443Pf4oGPFqfdr/idlk4Qme9QSVLxbi/w8D8TmUz+vnJrC/a/82O8/2PC4ZJ1/xM/E6sSLHpOlUSpigrmMYUOqzwe1vUt3eK/Yu6OjHjZVqo065BBlRkDi1wW/xUXwYhifOJ2dgxuQWXiITeq0Di1SUaIrZDL4r+eUuUyCCG48e0f8b8FGwGYE07TBSURr81ehVXbWvDgGfsoV3rzDRPe/xn/nrsOgIvhfxWJF887P6zHxsYwHjlrH301L99x0mNfIRojePjMfTCoR0VnDyct0PC/dJUqdoIvIwd0kjKkZwWWbm6R/N3aht1sVOHsYSqG4KnC/xI5VSypkh+HNaqoLEm6/8UTseFinDx7DJ5UCUqV4pyI4trG4gQvzFyBqtIATtpne+m+xhj4Y9PPWcx3UtWUoUOjn5OmiRMh6BNqVd+5MP+74YYb0NjYiGHDhsHv9yMWi+Guu+7C2WefrdxnwoQJuP322x31k/vwv4RqQV1jrSYT8TjBeqY0gpi/6ASprMXZbT6GVBW6UiV+rvTenLuqXg/9qyoJYO8darFoYxMA8yIHNV2SzRnKLCzVjTzHHNwwOQCvSvB/Y13frEwl6Odhp/ivLO/Krvsf+0yzV/zXRhtJI5nylg5UIZBi8V9ZXqvbjy4jp0pO6MRFNZ+mIZYkVE5Jpl2rfDdQGLPyAsL6hna8MmuV/iDdpXelK8fdpU8VgERu0nvzN+CHNQ2uHDfbaIvE8MRny/SQh6G9q1w57i7J4zS1R/HJwk34etlWV46bbRCScLKbv7YhJ4n42QIlCDLFyA7YnAMZOaAP9T41pXpNMsCYOKQKGdQt1dMMu2LHFPAbdarM4X9iTpUwqaQvDk0zjCqY8/l00SZMnr1KeR4GqYqaXgiyEEhxf3ZsW5sjuOXfC3D9m/NTrjqKkwq1UpXsUxH+Rz8nn/B55Ev43+uvv46XX34Zr7zyCubMmYPnn38e//jHP/D8888r9xk/fjwaGhr0/1avXp2yn9yH/yVJVVkgZb9iGKrqe2UHesisRV2eKEMCaJhhoedUqcIe6fZDh3TH7JtGon9tmfFMEk5ZV6rKzEqVVU6VeE8WOqyVKqONVS6TVWifdU6Vsb/VM5Ld17r4b+KnlQqlt/GrJ/6iQ2C6EEMgdbXIrwnb+TGxf3ML5r6T23VCLB87axZl93LYJctuwCNVLmNbixHmNvXyQ3HuIYNcOe6vh/fGO38agR17JpSNQrES35YMzwv6NUy59BBc9audXTnuQTt2xwdXH469tq9J9NNSGGGRbR0xfdWf1toqRNAV5kgsvRVmPqdKrTr5fT7s1MtYmKCERK5uGaoIXeVKVyFgjx/waUbYGhGNKngSI65Wsit++wyoRcCn4YBB2+l/v+rV73H9m/M5dYB9edHzbZMoVSpCy4X/MZPVpmSeTSQaT6ncyXKqAGNyHhCuL0c0udBOfuJCX4IxQpTuf7kM/7v22mtxww034IwzzsAee+yBc845B9dccw0mTJig3KekpATV1dXcf6mQ6zpVLSalSt1W/B5lYvuum1AEaGK+uQ1LmkN6+F9xKFX0vqDXgRp3lIf8OjGSfRe+WrIF789fD0AR/mdBqnSlyl8spMr4NxGep3aL/0oJE3WZs1BErPK5+HEY7e3kVNkr/mtFvAyFLhNoJmIJoW/5mNi/uQV1Plfi7yKBZMfulGTmMvzPI1Uugzr49Kwswb47dHNtYqBpGnbvX4P+tWUAjFWtfAdbd2P/Qdu5upo2rE81Bnav4PrJd9CcuKBf4+q0FBp0pUph650K7MMtYqE6+TVg516GukkT7+XqVuInGwZDv2+p3ARFsEpYwKdxD37r8D/5BNXn03Dq/gPw4+3HYtTuffW/0zCtbc0R0z6AkX8lD/9T17miYFUIdkKW6nqYlKpkzkssSTbpc01/0SmuASWn9OXnY17eQcUkkPLZXKy8t7a2wifMVPx+P+KKa5sucq5U6aQqaalu8XmLLpTpqs+A8b2iZEke/pf46fNpKKFKVcHnVCXGT5+L9DrIVCSfMIlsi8Qw5rnZ+HTRZgBAr6oS0/Gp/Xy7JPyP9t2VlCq2PINc2TEfS1S22BA+O33zxzcm9VYqiCpviIWRv6ReiHCaQ6SCuR4VHZ9Put1v83qkg7jpvPnPRfw668Qont/FfwsjCaWAUOeyQYWIQjNoMKzU3TGoEFFo9arYuPlMa050JkIZGlWkVKqYVSyqzgJAZUkQQJulUsW+eKxW/6zAkhG/j7Xv5R/MYvifKgeAvpxKg37pamUzU6yVPQYl3m0dMqMKlVJlVooAfuKaSo0QX/70c2ZDtwB5YjdLHMTPhA0/yYfwv9GjR+Ouu+7CDjvsgN122w1z587FAw88gD/+8Y+u9mMYVeRIqYrQ8L/E89Ey/E+4l1Rk3Q7o+dHPVm6pboQIGjlVhU2q6McaCvgS96quVPGTVsAcktwaierRC388bDDGHDbYdHxbSlWRkCrR6Y2FrAiuFZmRPUJEQwSuiUU+F39883jlqmzip0ikZWO1U/w3U9DTE5Uqc2hksn3SIIIQ98ZAIeZF0cOr8qWoGyAbgu+0+K/bIYwyeKTKZbhtpS6im+4CWBikqk5RId4tFFpR5GyTzFwhmKlRRYqcKta6e/tu5fr2KgvnPJlSZRSbTU+pCvo1LhnZVIcnzhf/NeVU6UqVsU3TEsoXO6YWjlQZ507NV2SW6nbc/9g+2hkzAJXzoL6fQqkSCY9sIsBeIjH8z8+8vNnwv1icmIhHLsL/Hn74Ydx88824/PLLsWnTJvTr1w+XXHIJbrnlFlf7SZfcpws9pyoZ/kdzRGQLOeLCiCtKlSWpSvz0cTlVhR3+R4mortDRnKqYcS9TiCHJ9PuuacAto4dLj28vp6o4Ao/sFf9NEXYHox2Ef1sV/+VCDy0qxRpW6dahZaKzn+yIdDc7xX8zVqpMIZD0u6P3lPx/4zvJGkS4CdV505/is0pfkAOjVNm8HFaW9m7DI1Uuo74lu0qVQSIKRJnxlCoO2SaZuUJIN6rIjvsfS6qGMmYvFbpznoVSJZnAOB1mlLFTZ48pkpEYIdyx9QT1WBwBv89Q3IQXRNAvkKqImVT5NCPsR1r8VzH5VakS7Vz4n/UFEcPF6KRXZVTBEj5OqVKEC8bihHP/a++I6aGOxjWzHKIrqKqqwsSJEzFx4sSs9pMuuU8XevhfmfGKjxP5NRVJVCZGFXZyqth7olgs1entRJ+LMYEwSRd6ktdGzFOUoZyG/3XEEY8T7hlXbEoVkHiusLkzFHx9qMQ2uxbkKkt1me164u/q8ckMM2QqiEEcUhf2tdMm049YJKJxYXwyBcunATG4vyAknnfq8D82pyqxzW60j+j8mE0Ux9JGHkFXqiqyTSIKRJnJMsmkZg+Fo1TR61HYShUtZJu2UsVM6jticcxZVYenPl9mWr31aRp27l2F647bBXf8bjd9siZbTRfj1wHebc4JaPgfTf6mhzTXo+HPJU6Aez5YiH3u+Agrt7ZIrWkBICisKrPhf+y56+F/aeZUsWAnro5zqlJYqrNEit03ypxL4qdxTPaasCvwYsHMYkDOw//CyTpVpcZzRnUPiIsamYyRHkskF/zxjRygYrFUp/diiZBLJsupEpUqmZoloozJv20XrpWd/QsN6vp3iZ92c6o0jjAh2d5KqbKXQyQr/mtpyqKbasiOlfhpOASq22Sr+K/oTsgSG9Hcwi3ETefNfy5iaB9LjBwrVV5OVeHC7aK/InQSUSBud5Rk1mSJRBSacmeE/xW2UhXMUKnic6oIbv/vT5i3uh77DuyG/QZ2Mz3sLz9qJwDArOXbkvuoa1vJksLTrVNFz9OvUBrMOVUEs5ZtRVM4ip/WNepkQyQIolMXG/7HvkDLQmqjCmVOleIjaXdgVCEeWqVUyeqv8O5/cWl7gL+WbP2dmEDEigGq70+2YChVxnM3FicISrxxxIWRTML/9PsmoF69Z41IisVSnZ6TaNARExZnAPMzyU4OYWnA+ODaIjGuJmNxKlUaAGJ65jk1iGAvqUgOZMV/+Xwu9fhY0kb3kStMiZ+iGiMbqx33v0zzsEV1z1DSeKLPh1kiuc3dZ5fojEjfWzIFEWBD+Lziv10KdVlWIgovhyjbxh2Fpdxlm2TmCnQlOpxu+B838SZoTLpZUttvXeEwKTwa93cW8vyFxE/HSlWMr7dDX2aiOiRarBPCh/XQ5uKEKeAXlSozqUjkVNHwP/t1qlTnyqpBsRQTZ7ZWCCGGy6NoHS17WYmfLduOnRRwJhpR9vwTP4tq5Z1OpDN4p69vaMPqbW2oKQtiaO9K5QSLEGIYVaShVGViVCHmVMm+ouwkUleqCjz8LybmVFkpVYK6a6fOFC2UHI7GTXlVxeb+B6jNH1jXN5lJDqCedIvPqkyUKpbc2VGqrFQosY0s/9EYq3JItqCq1cX2DbDPf+vctUwgKlW6gsjkXKrGns/Ffz1S5TKo1XlNWZZyqpIrjw2FYqnelt2cqtoy6oZYINcjyyQzV6BGFelaqvMT77i+Wk6JkWGpLicjVuF/fslLMn2jimROlcZv1/uME25bnBAuhDGmmDCFBFIlM6rQNDCkSqJUKc5JNRlgJ64d8TgmvPcztrVEcO8pe5om6PQYIX9iIkfDIUWyK3tZscOixI8en70M7GS+LcKGUKZeuS80ZFqnanNTGEfeO103lZj0h/1w3O59pG1bIzH98xBzqmQw51S5oFRZGlUYE6KSpAIjhrSlgx/XNuCqV+eisb0Du/atxnNjDswZ0YiJZJLwzzHO/U/4LqhChEWUhfwIR+Omml7FVqcKYCbQwpeWV1Dkyg77q63ivz62PXMcC57Php9Z53YlflrXqUq24Qrtyl0Qs1X8l/ZtJpzWroSZwNw3v108VfY6y8I7reAV/y1gZN9CvLCUqqy7/yVz19o6YgVRQDLbSmauYFiqu1D8Nx7Xw3/oqmtcMVGgtY0sw/+YfdLNZYkKYTuqeleyOlVsknpM8TK0Cv9jV/KplbLcqCK1+x8L1uUtGiN48otleOO7NdjSbH6W0HMQc0TEUKPUdap4gsROHDlS1SEJ/yuilfdMjSrW1LVyn9+CdQ3KtvS75NMgDRMTISpVHZkoVTFesbEiVQGfhpIgr1Td9+FCHHXfpzjmgc/w4YINjvr+dOEmLNvSgi3NEXzxyxYs39KS9nk4hYlMWihVYs0yu+59uq16RFQW7e1fSDAm//x2NgxOdLIT27DHAWTOd7SNc6VKRu7kuV2iUiUjXnwbWTvWbTATqIr/ikoaH2bJt3ULqXKqlMV/485JpkrVzAaK5y7ME+iT5orskoj2DvOKVT4i2zlEVSUB/aYsBLXKsNwvbKUqlKFSxefdEESSK9V0Ei4aHFDQFV+ZSmOEpplrwjgP/5OTB5HIxAkg1qmifcXiRLkKLeY/yOpU+TTDUr0tEjOt2saJfKJs51zbOww1Q3YM+rdQUknoEBREQ6nixywez6hTZZwTBauQsM8yMbm7GEC/k+kW/xVzjjY1hpVtm5LfpYqSAPe9U+VEmML/XFCqSmyQKp9P03OFwtEYYnGCSZ8tw4qtrfhlUzOe+XK5o75NJjK5iPUR+qbPRfq7LN9JXOgx1GzrPiip2tTUzrttKlT9QoZKHWEVFJWBAvs7q8CrTBr4Nuxx1N8fdl87uV1i3pBsvCwpVp1T5jlV/FiNvCZ58d9sKlXmvvntZvc/6ONIv/ivp1QVFGJxooflZatOFUsiCkGtyrYyo2mafq0L4XoUS/hfppbqYvFfo7isUA9JYfBgpVTJHOZSGTOYjiWE/6mOwz7ggcQLQaZUiRMmsfBti8L9T7dU7zDnVAHy62/nVFPZq9Nx08lxNMaH/xk5VeaXFUeqaE6VTk7lY5cqVUU0Scw0/E80k9jcrCZV9LtUVRLg7gW1UpXYXhrkCUE6oPsGLXKqOEt1qlRF49jcFObGuHhjk6PkePH8cmUKAjDhsgFBqbKqU2URIigDNfW44Plvcd2UH/TtdnKyCg6KkDq2YK8G6zYA/y7Q21sU/5XlMcmgkxzYK/5rx4SCDV6wOu9MYFwzYXyCMqifC6NUuW1UIZ63GJLoavHfLJ2DDB6pchGNbR36h12bpZwqjkTkuQMgSzKzacxQSOYd2a7blSvQMLxwLI4p363BVa/OdWSLLJoZ0EmjqIiYrMj96omfVKkSXI1S4fPFm3Hz2z/qypFoqS6buPE5VcxkiSFYqcP/zEpNInzLbKnOrnpbXQcrsCRGunpKFQdhoi3WFvFJJgvse4uSZXr+7Gp6NIVSVUykSgz5cgqTUtXUrmzbzChVGjMpUvVNyS1VQtysUyV1/9OJBpg6VTGsb2gDAGxXEYJPSzwrNzepyaPpuMR8b+YKaqWKN7wBzKGgRp6idR/H7d5Hf559s2Kbvr2Yc6rET9Bu2J14HNkxVWFmeuhhhsV/2e++veK/6s9PFqqYDvTvmEmpouMj3E9eqcqoaxNM+WZ0e/KnneK/TnOqciFee6TKRdBJfWVJQH+4ZgOUROS7410uSCZQOAWAY3GCxvZiCf9LhoVF43h8+hL8Z946fL+q3vb+7IQnHDXyhVIaVSSfrDKFRuYYaLiu2XuaPjjtF7z49Up88cvmZH/UqIIqZOYVRDGniv5qFf5nUqrY4r+M+x1rVEF7YZ8tHRIranvhf8Z+smvDGlUAxvWOCp+L1P1PolpJw/8YNtcuIXnFtPLulNyLoAsWtG6ZKvxv5dYWfPhjIheJFlP2p5hQ0M+WhpqmG/5HCJEoVRJSxRBz1lJ9Q0OCKA7qXo5BPSoAAAs3NNnu3xwemxtSFY8bbnMlglGFLN9JDAUzFkus5wxX/WpnvHnZoYnjMp9RMbr/qWy87RT/5ZUqCamShLjxfaeegMvJnThW499Oiv9anVOmH7EqpypV8V/ZmDKFeN4ykwzV2FWEWIVcWqp7pMpFGPky2VUhuunhbvlNInJNMvNdqWpgSWaRKFWRWBytyRpDotWvFdjJFqvS0AmCSqmi7n+yiZ80f0FfFbY3Ljq5p66VQV2pouF/Yk4VEQrf8rkSKqMKsfivzKiCy6nqiHHJ8PS6yOr72M2porCa+Brhf8lzorlmwnVR5VR12A3/Y+tUFaNS5ZDci6BK7oDtygEAW5rD0s/tohe+xfMzVwIwnjGpTDLosWmoabpGFezxDaMKcztjoQFM8d841idJVd+aMuzSuwpAIgQwnf5lv2cL7Gcqhv/JVCSTUYVQdsAK9NnGPodiMfNzr9ChUkeM3CI1+eFzqthj0r/zk3ezIqIO1TP6oEqJZpHbZWxwUvxX1s41pUqRUyWaRbCEkzWIcBPieetumIpQR59+DfO7+K9HqlxErvJlCoVE5Jpk5rtSRb8fVSUBk1JhB48++igGDRqE0tJSHHTQQfjmm2+s+6uvxxVXXIG+ffuipKQEQ4cOxXvvvZfW2EXoRhUxo26KmPdhBTZsrZVRafTwP0VOVVAyqaCQucY5VQjoMSjJ0ZUqxUsxFufPRcypUqkuYqgOV6eKCS2hShUhBvHwaUApEzYlwmlOldTsIjluanmthzMJhEe2osy7//Hhfxqz8smF/zHfHRWhLmQ4JfciKHnuV1sGTUt8xltbzGrVpmS43JFDe+JP/5comM1ORmSg9xz9rqWrVLH3QcjCUp01odEt1Tti2NCYIFV9akqxS58EqXKiVImENVdKFXv/iOHJ0jpVglGFXaUKYHNKWaWq+O4XlfkD70pn3SZxHNkxE7+rlCo7bnesmqJ2KjT+7aT4r6ydzFQjHYjGQmLOVyJfyXhvsc9rq3DIdCCeNxE/F0WdKkKIHiPoVKnqEjlV+TRRzBT1OSIRhVKrqqEttyQz38MhMyn8O3nyZIwbNw633nor5syZg7322gvHHnssNm3aJG0fiURwzDHHYMWKFZgyZQoWLVqEp556Cv3798/oHCh0S/VoXJ/sRxzMGDmlilUpbCpVsjpVookC4DyXhT7oW4ScKpWzViL8jycEbAK6ihyKxX9ZpYoNcaF5LoCRK+PTND1sSlbfxw6BTEmqaPifYFShtlQ378vux1kba+YQTlapKkb3v4zD/5KfV1nIj+4VJQDkIYBUtbj9t7thv4HbJfpOsdJMPwf6nYrGSVqTD7lSpVZBAz5NoVSVYliSVC1yQqpMSpWDwWcA6XmLShVHqhI/6bVRFTqXgRIvlsDaNboQkc9zL33yL3yGrOubyiabrS/ltPgv+7vVvcqSO7VTofG7reK/bJ0q03nz55AuxFBFad9Efn5u8xF6TgGxRhZD6GRjZ/OW7ZJMlZqYDXRq8V86UZw0aRIOOuggTJw4EcceeywWLVqEXr16mdrTiWKvXr0wZcoU9O/fHytXrkRtbW3uBy9BtmsyUVC79rqWPCcRLTkimQUSDpmJkvnAAw/goosuwpgxYwAAkyZNwrvvvotnnnkGN9xwg6n9M888g23btmHGjBkIBhPXZ9CgQekPXgBdkQ1HjRpTTpQqdiLSGpYoVQqDB6s6VbIVv3SVqqZ2qlTx5MHUp8mogiFVRG1UERKUKhre5/dp+mTQr2kJ2+mgD+0dcZ1UaZrGJPinF/7XxuxnZXtdorCIFov/yvKoAMP63pzbQLjvi4zkFVX4X4ZGFXTBosTvQ6+qEmxpDksdAO3URRJh5FQZBD4WJ46ND+wqVWyeoZ5T1RHDhqRRRd+aMgxNhv/9sqlJvy9SIZ/C/8w5VZLPgypVEuKlgh7+x9acS0Opyve5V6rCvnbJDPfcUSoiYt98XzLwluP8NnGsgM3ivzaUqkyfiYYKxxNLsW9eiUsdDpkOTHbzhN+uVBDjxDHJ7DKW6uxEcfjw4Zg0aRLKy8vxzDPPSNvTieLbb7+Nww47DIMGDcKRRx6JvfbaK8cjlyPbhX8pCoVE5IxkFphS5ZRkRiIRfPfddxg5cqS+zefzYeTIkZg5c6Z0n//85z845JBDcMUVV6B3797YfffdcffddyOmKNYbDofR2NjI/WcFOnmg5ANwGv5ntGVrNFGCInO6Y3+X1akSTRQAY1XYvlKV+EmNIwKCpbqIGOEt1RM5Vfy5yPaXrSrTPkVnI5pXxRZ1NYqmZh7+J3UQpDlVQd6oQlx5F1fdAX51OSqE/wHGJIbtV0aqiimcKXOlKkmqgj70qk4oVZtlSpUsh8fCzhkwCBuriqZjqy4Lg5NaqjPEnH6/IoxS1aemFAO7V+iLCcNv+QCPT1+asn+ryXU2EWPu85Bg0CFz/xPD/5yQIvq5ss8/mRqWCvk+91KH1BkKhePivwpCkV5OlbGvnZwqO8V/2feWykkw0+K/Ym6RvPAwHy1hJxwyHZhyquwqiIKSZgcqVTMb6DRSlYuJIuB8spgOorE4rnxlDl6etRJA7kjE/xZswPnPfoOm9vwiV4QQXD/lB0z6LPEizDbJpMefsXQrzv7X145seHOFv73zE+77cCEA50rVli1bEIvF0Lt3b2577969sWHDBuk+y5Ytw5QpUxCLxfDee+/h5ptvxv33348777xT2n7ChAmoqanR/xswYIDlmOikqZEJQXVSs4p9abRGzEYVYn0jCsOoQqLQWCWFO86pSowpKFiqy/oUc6roubHXw+RiKFEBKGkSHQPpZJcL/6O5KBIiayd0K3X4X+JnSDAGEQmPLDREJJlse3YflnSyJiduJWXnE5ySexG6UhXwo2dlMvxPYqsuc4IzQqkUSlWygHcZo1SlU3+OLfRMv99SS3WGBFAltK0jho2NRvif36fhV8MSz7twNI53fliXsv+8UqooYdLt49UFyZ0sIgQlzz+n7n+FMPdS50sl/878v5nMmI8Drj2/cGe6agL5koGrl6Voz5E7wfFRNl6rGlnG7xkqVcLYZOSEjbbQNPX5ZQqxb5OCKCpVMP5OmPHZgcqhMRvoNFKVi4ki4HyymA4WrGvEOz+s15UI6lyULdAk3qZwFNMXbcZXS7ZmtT+nWL2tDZO/XY0tzQnlaGiWr8fOyeO3RmL4aslWTPt5Y1b7c4qGtg48/eVybEyuLNPPL5uIx+Po1asXnnzySey33344/fTTceONN2LSpEnS9uPHj0dDQ4P+3+rVqy2PTycPjQyhlznRqSBLtAZsGFVIErXF4/g4pSq98L9m0ahCmVPFT97Y31nlTlxhZI1Kqkp5JUpcqaNhWS16+J9RqFVmVGFn4i6rC8UdIzkI3ZCEkl1hAiib/Mj6l+VUsTl4bRKL92IiVU7JvQh6b4UChlK1SVg8YsNiZLXanIT/pWNWweb2WJ0v+/nS8L/1De3oiBH4NKBnVeL8HjlrH/zr3P0B8M8ZFUR1LV0C6xRs2QBDheL/xuV5CkqVE1LF5uZYOQxaoRDmXvTWFz9Bedid0IapscRCbJ9KEbH69sjDEMVxGLCuUyU5J6Gl0Z/FoGzA5+MvLD2u+N2jvWua2jI+U4h9GzWyjL5ZsJ+L6rNTIVvEUIaCSgV2OlEEnE8W08G2ZNjZoO7leOdPI3D8Hn1c74PFvjt0w/+uOQL77lALIP9cAOn16FFZgrevOAxnHbhDVvsb0rMSn/z5SBwxtCeA/AuLpLlvpUEf3rzsEFx65BBH+/fo0QN+vx8bN/JkcePGjejTR/5d69u3L4YOHQq/35go7brrrtiwYQMiEfP3paSkBNXV1dx/VghJDCPSNapgQVdgVXkGdLIoC/+zLLRpO/yPJ0S6dbgq/E+WU0VJFatUKchheciP6tKE0kodAGP6KpycVHFGFbLwPxsfA5uLJZtAxwVSJYYzGUpVsj0x78uCfUHKLiVfp8r+JLNQ4JZRRUnAh15VpQDMRhUsqZApgymNKgKZhf8Zqowm/V5QsCSiRCi10bOqRF9w0DQNg3okLOQb26JIBVOdqlwpVQyZDOiESb4Iwf6bDk9fQLIxQWTJspXDoNvI9dwrk5wqldKtVkTEdvzfZZAZZphyqpj7zU5OlZUphFs5VeYQSPN3R51TlVHXJqTOqeLPlSVGXvFfCXIxUQScTxbTQUNyEt+vtgy796/J2PbSDob2rtILJOablTjNbepVVYK9B9TacjXKFDv2rMTOvSq5/vMFtObRduUh7DdwO8cvv1AohP322w/Tpk3Tt8XjcUybNg2HHHKIdJ/DDjsMS5YsQZyZSS1evBh9+/ZFKJR5eKqs7hirzKSa0KhIjjhREB+sAcGoYtGGJl2ZpByG/b7R9jISF43F8enCTZyLptguqCtV8vNgH/CJ383ETH4eieNWlgRQWSIqVfRlk2hLc6oo6UooVTTBP12jCmulSs+pCvA225R/GcV/JUqV5Fpzk3zJxeTCEYXzLwa4ZVQRShpVAObwP/a6yxYWUuVUhQI+QwlOoygN675p1SdPqvzc3/rUlHG/0wWHpvYOG88U/vcccSomR4z9nPm/WYUk64tBNpQmtk00HucKD9t1/yuEuZeKqHA5VSnaqHNyiNBO7Ds1ibBD7vicKrVxC5svpSaK8rE6hdlWnh8f/RtvXZ/c7vINJarq5pwqvj2fU8VvSwWRTGYTnfbayseJYrqoy1F9KhH5atCgG3ZU5LbArVEUOb+uhxuGHePGjcNTTz2F559/Hj///DMuu+wytLS06G6A5557LsaPH6+3v+yyy7Bt2zaMHTsWixcvxrvvvou7774bV1xxRWYnk0RQMgGgJKKpvQOH3fMJxr3+vXJ/lVJFV81lK2iJfvkcnytfmYMLnv8Wq7e1ypPCLcKQHpu+FGOem42LX/hW3yY+dO1YqpvqVMlyqsTzSP5eVRpARQmfMxUXCKVcqUqG/0ks1e28N5wW/zWMKgQFT/LClX20svA/FlzxXwWhLmSIYWFOITOqWF3Xhi9/2aIvMLBESK6MWN9zbFHp9ML/kiqmX7M0x2BJFf0eU/StLuV+r06WD4kTw8hFBXHSl7OcKkapEhVJWb6TaFShLwbZUao4UkWU6qQVCmHular4r09T22TrvwuXQ+V8Jy6Cq/K5+D4McmfHqEJV51Ach8oUQjVWp1ARS1Gp4kMSs6NUEaFvQqzzpdh6e05JZpcp/ptvE8V0kasityKKmUSkA6Mocn4qd5mQzNNPPx3/+Mc/cMstt2DvvffG999/jw8++ECPi1+1ahXWr1+vtx8wYAA+/PBDzJ49G3vuuSeuuuoqjB07Vmq/ng6slKqlm1uwvqEdXy3ZIv07oJ600e1sKBELw/0vcSz6XdvSHJbmJoj5CyxemLkCADBr+TZ9m0mpYkKRZIjFxZwqo3AiGxppNqpIHLeqNIgKk1KVHHtyn1JKqiKM+19AHf5nRw1pkyhDLHSjCoWluh7+J5k8yyYjsnoxLFhyWNThf2mulNKcqpKAH72TxGNzUxh/eHoWXvp6JQC1UkUvvTrkNrE9FPDpymx6RhWsUqXuU5/IaRoqSgLce3NYXz7ftCTg00ONU9VlFNW1XLn/Gaq68TnTsUjrVJmMKsyLQSpw4X8xovzMUyHf514qdcRWfSjm82Chcr5T5V5ZibV8eBw9nrwNYP7MU56TxXlnAlVemVgjK5fFf61qZPFjp+SLKEM8VbAT0ukW0qpTFY1GMX36dCxduhRnnXUWqqqqsG7dOlRXV6OystL2cU4//XRs3rwZt9xyCzZs2IC9997bNFH0MQ8ROlG85pprsOeee6J///4YO3Ysrr/++nROwzVkUn8oE+QriajLkbW8iHxT7uh98taHsxCPDkVted+07hOKK6+8EldeeaX0b9OnTzdtO+SQQ/D111877scOQpLYLBpGZKgaxt/+M28drpn8PSaevjdG79VPvWoed6ZU0QlNOBqX5y9YrFDJ8jTESSCdqFiF/3GkKm6QFN6oQn4eVaXm8L+YMCmgqha9rpxSlWb4Hxs2GLORUyVaqpvD/4x9ZRNpc50qHnzxX4DEY5j15WeY2bAho3dMvsBNo4r+tWW4cMRgvPPDemxobMe6pBW5SrVIRegiulKlGeG1GeRUsYqNrEu22G3Q78O/rzgMC9Y1oizox6E7defaapqG6rIgtjSHE/drN3X/Ig/MlVJlTA59JkVSFsZMpzSipbqdMHkSj6F95ffoqFuP+voDEexei2jTVvhKyh0tQuT73Etp/iDJZTK34Y+hH1OwYNfb+eSTdztKlXVuF6P2WNwPTghaxkYVNpUq2fm5zUfoOZn6VhT/ZQvNs0qhHeR18d+VK1fiuOOOw6pVqxAOh3HMMcegqqoK99xzD8LhsGXiogz5NFFMF52nVOUXiaDoLJJJSVw+5Jix90l7exh9LnoC3cqDad8n+YagjFQlJ34dUT5UDACuenUuAOBPr87F6L36KSdtJutuRU6VOMmPROPSF4QYasONV1pAmP89VZ2qeJyYlCp9TDG11TENn6wqDZhypsSwCJ9OqoywCCulylb4X9RaqTLC//icKpG4ylYApUoV83WRkSqWHLZu24B1z96AsY9sQySS+TsmH5CxUUXUMKrQNA03/WY4QgEfHpu+VFpDjJ1sWC0sAMb3Kuj36d/3dJQqVsXULEikaEIzsHsFBnavUB63uiyQIFUpHAA7q06VXv5B05hwY+Ez8ZufSfrEVqJmyUDfKZuWLgeJdmDD5svRvVstGmdNAYl1IOA72dG483nupXKcY8PgDKJiT9URiZo6pwrJ46rHZ6f4L29AwfcpP5YNgpYhqxJDIGk3Yo0seZhllpQqjlSl/lzE8dlBXhf/HTt2LPbff3/U1dWhrMxIKj3ppJO4GN2uhM4mEfmqVHXl8D/2PgmEEjkQ3cpDRXOfWIX/dQgrsDIoQ5EsXLMAI/xFDEfjlCpuVTg5ybH5MDWH/yX2V4b/EcKFHbEPbXo9ZPlY1GiipiwoMaoA1yfdn1eqKKlKT6mSue1RsOEVovufGJonWwFMK/yPGc+qdx9FSd+dMWvhqqJ5x+iT7TRf6hFGqaIICAsGqnsmVfhfh+506dNV0XRUnihDIKzCnWIOJ4jUrKIxRfhfZ9WpYieHhn194m9WdaqcKlX0nbLLtW9AC5YgHks8e8qHHoL2lfOKKlxWnVtkEBCRIIhtTDk5QvvMcqqMtqlyqnxcG8kiAzNep+fkFCpimVgIgf43nuiB28ct6ITOlM/Fj1U2dqfhkNk6BxkcK1VffPEFZsyYYUpOHDRoENauXevawAoJdS7kzKSD2rxXqnKs3FVQpSoCQkhOXBhVYO8Teh/XlocwaPviuE9kSlU4JipVxhMs5PdxypDaqEIdlpDoNxmeJKzOh6MxPYyNWxVWxKirIE56KYmzq1SxuWI6CZIsXf12r35YsqkZfzh4IN79IZELR40qRItlUZ1LZVRhZzLJWaqb4veNf5ekqFMld/8z98eHP0nC/xhS1bzyR/Q++z6UlRbPO0YM+XIKNqeKIiCUNdC//8L1tWtUEfJrpmM6AatUWa3M0++HHQtxwDCraGxPYVQh9JUrUsXeE6Ii6aROVSqlir5TTnl1BYDEPRmLEwRqeiPWtK1T33duw07xXy1F8V/zhJv/bHSiYuob3N9lYPdNRYSgMc9Jq+K/sCJoRptMQMdKCH8NksMEAV/AHhZEL1PI3vF8TpUwdr2N8+K/4nlnE46Vqng8Lq2ivWbNGlRVZb+oaT6ChpvVlOVamTHC3XLxZbGL+k4Kh6xNXv9onOgT1M4Ce5/Qj6a2LFg094mV+19HjJ+AA0BlKb9+ow7/48mSOAE3TSSZ8D9Z0Vh9Mmtxf7Cr/yL5El3uRMSEnKoO5q1Jr4Ns8jhgu3L88/S9sVu/GpNRBZs3wJ4P7UfTYFmnylb4n4WlOns+lFSZwjKF8D92H3lOFftvOakych0ICImb2hXyveOeUYW5qK/o/icuAKSqUxVh3P8CwjGdgO4T8LHuf+Z2TowZAKA6+exIpVSJ5jfstY7G4miNRNM6r1TgyKRgVCF1/xMmznaL/9J3Cl3QisUT7n/Rpi3wlZRZ7ltoMMwReNgp/otUxX/1Y9Ht8vvF6k5l91Xnfxn9Wn20snMSe2ePlQnMtbqM7ex5E0i2uzzHlIUeEsYOw07xX6c5VbmYJjsmVb/+9a8xceJE/XdN09Dc3Ixbb70Vxx9/vJtjKxjUd7IxQz6QCBad5f5XFvLrk47Ozqti7xP6mChFpGjuE03TTGYVlFTRSRpLUGiIG0VMMcMTw/rMxX/FSQtVquKWTluE8C8F1hihmiF8IvkK6qRK/vCOxgn3MmUndhGaa5HiTUivTbPJqELjzqeDyd0oTX7P3ahTJZIgdn+zpTo/AZQZEshevnwxWvN4CDG+N5U77oumb//NhRgW+jvGytrfDiJJRZJdAAgKNdiM/B3+vkxVI4u1VM/IqEL/bvgsjTlUCyYq1CSVqlTuf+L5Uf60oaEdB909DcNv+RD73fkxlm9psdWvXbD3BL1X6eNN+kwSlSpBmVaBvlP0sE9C0NjYhIYvX0blTge4dDb5gUyK/6qUKpFQqHOvaF/qe0BmmGEq/mtjrFw7n5qgue3+Z6oJJdTIkuZUubweITfJUJ8rq5ip1CwV8jqn6v7778dXX32F4cOHo729HWeddZYelnHPPfdkY4x5jUg0rk+Gcp1TlU8kgoVBMnNfO6ybnlfVuSGR7H0S74hgy3/vw9nHHFBU94mYV2UoVYkHVzRuyPRVpSKpkh9TVETEByvr/seStnBHjJncmFfz2WMCCQt2ChpSxeYSUQT04r/yp3dHlN+BDZuiYZCpVqAHJ4t4z1q+LWm4Aa5Pw6jCCCfUi/9Kwv+cuv+Zw/+M302W6nr+CG81z4X/SfpnVxRVk+n2SGJMPUZeiPCanzHy0P2L5h3DKjfprPjKlSoammncb4ntwiSRqe8iA2dUkYGlOksg/BZ90q+b3RwgI/wvhVGFmFOV7Hv+2gZsbUm8DxraOvDDmnpb/doFH/bIE1jZZyLmecrClmWg75QfH7wAJBrBdVdchEP32RXRpm3oe8wFLp5R50Nt/pD43U7xX5XSITrfmXOv1Cqr0Qf0PtShisY7zCqEjiUIqmNlr/ivbIyqnKrsKFV84WG1CYU7xX/THq5tOM6p2n777TFv3jy89tpr+OGHH9Dc3IwLLrgAZ599NpdU3FVQ35Z4WGua8fDPJbqVh7ChsR11rREM2K485/2L4Elm7q9HbXkQGxrbO51ksvfJ1Y/9G+H2Vtxwzp8w9tI/Fs19IoYAipbqQOIh5td4pSoai1soVUlFRDHxYvOLWDLAKlXsQj27fzROQFNS6CSL7gvIV9VThf+Jk0/WtCJiEf7H4tAh3dGrqgSbmsL4ZOEmkxkE3Z91GbMyqrAzH2bz26yKphruf6JSheRYksfgcqokShVnVCG/Hm0dMdQgCH9VD/T948O4asgWrF66MOvvmLVr1+L666/H+++/j9bWVuy000549tlnsf/++7vWB3v+sThJOYEWITOqMJQqdU0ktm9VXqGeUxXQTOqXE7BGFVY2zPQesTshMowqrKMxKEmh+ZtiXhNFOvlilv1yZJJX+tjCwBTi5yELW5aBvlN2/8MtWL98EYYOrcHpZ5+LSWv7obSq8MoMWEGljkgVFFHV0S25xWPSYwgqjUoRsbgH5Jbq8jaaps7/YrexRFF13tkq/psIPTS+l+zYs1U4V1eqhBpZqYr/sjlVTpWqvK1TFQgE8Ic//MHtsRQkjHyqYKe471ASkQ+Od4BBMn2a8TLMJfJFqQIS98lpZ5yFm37shkoAl15yDMpynHeXTaiVKlYFicPv83NKVWN7VBleZORKyfMugoz7n+i0l0qpYttvaQoz+ybUHpnCksqoQiRVMalRhfVzIeD34aR9++OJz5ZhynerMXLXRK0YuptfMKrQWKMKaU6VsxeHeN7sRyMqVaKbmeyFK+uet1SXj4OeSzxOoPn8OPWMs9CnptT2eaSDuro6HHbYYTj66KPx/vvvo2fPnvjll1/QrVs3V/thvwMxQhy/eGVGFfQ7ySrD7Haxb9WkiN63vKW688kHe89ahf/RCaPtnKqyZE5VCqWK9hX0a4jEzGGRFOmocJb9MhNsI/zPSqni97NrVAEk3in9Dvg12gcdhj9ffDBqy4N4cuIX3DOvGKBSR2wV/1VMuMX7wAi7E/u2r1RZ5XaxpE2skZX+ObkT/meEQCZ+8sqfcY+ySpV1lplzyC3VWUKnVhoJM247yJbZhgyOSdULL7xg+fdzzz037cEUIupaOsdOnSLfalWxJDPTmgrpwHAA7FySSe+TxrYONP+4ABqAt1/fol+TYrhPRAdAPaeKKXpLJwzss6yuNaJcBdSVKvpQVyhV0RgxKVXGBMZoz76E2MnV1haGVOk5YObxBFJYqrPnCvBGFVaW6iJO3W97PPHZMny6aDP23L6WG7tuqa6v8AMlVKlKM/yPhSmnysKoQl9dpKGJkhAc2USaC/8zhXRq6IgR/XNo+OFjEABTXtsgVf/dvHfuueceDBgwAM8++6y+bfDgwa4dn4Ij92nM6dk6VRR0gUG35o7JFyJSFR7mcqqEnEUnYAmEVQ6DXWMGCqeW6qGADy2RmN63uGjgOqmiZNKvmZz99BpUEkdSmudpN8eMvlM2f7cQzY3teOfNFSgP+dH842L4y4IARrp3Up2MrBT/FZ5VREFU7KgastpS5pwqiQokOSRrQpGaoCmHZAtqpYq/Z+V28Jn1LUKmFLLFf80KoqFeOrdUz845yOCYVI0dO5b7vaOjA62trQiFQigvLy+KyaITdFbhXwpKIupa8oNUdTbJrM0TpYreJ3ECNLd3ACSGP74XLqr7RDSq6NDD/8wTbJYA1bd2pCz+qyqIqYf/xeOcKhSOGpMopVLFzKW2NPPhf4QQqVIVFIp2ihNTsYCwzFLdzuRxp15VGNi9HCu3tmLxxiYAEqOKqPEiKQ1Y1alK2R0HU30faU6V3FJdVuRVdh2twv/Kgn50xKKIJD+HbR8/CQC46asgNGT3HfOf//wHxx57LE499VR89tln6N+/Py6//HJcdNFFyn3C4TDCYYOUNzY2puyHC/9zSHoJITpBZ0mVaLWvUqqsakYl9qcKj49btHAKNtTNKg9Dr8tkN/zPrlFF3DgP9ncx1FhcCMkUMWYSaKd2mJjnaVepou+U5nAU8TjB/Z8ShNvaQHwBNIRKARRmvqEMnVn8l80tUsFebSmjX6v7wU49q2wX//UJ5yEjem6qPOxnRmtkESIaVfD7sONwSjLz2qiirq6O+6+5uRmLFi3CiBEj8Oqrr2ZjjHmNzir8S5FPBW+BPCCZ5fmhVNH748M5SzDg6sk48q73i+4+EcP/aIgSa1ssC8Gpb42kXDVX5V3Q1XlCeEITURT/VU1mWaMKQhKTH2lOFUPQZA9wcYLGkkX6N7uROZQoRQSDC9Gm2afBMvwvY6WKmTAYxgXylXfRHpptw4K9duL1KAtR041ECOeAqydjwNWTsWLtxqy/Y5YtW4bHH38cO++8Mz788ENcdtlluOqqq/D8888r95kwYQJqamr0/wYMGJCyH5Vhih2wDpOy8D9zvSP+AqcKfTHqVGVmVNGhh4ZaW6rrYT8288qo+1+TzTpVOqnSw+v4duk4G1pBGvZoEdonhoLaLf5L3ynH3/s+Blw9Gf+dvQxvfvINSrcfjmFn3eTeCeUBVMSGN3Xgt4lt7OZUpTK0kIEnTPLvOhvGZqgsalKlaWpTmWwX//Vp/D3LG4K4r/Kwx2KVPEJSF/+lCi9gn2SqFMBswJVA3J133hl///vfTSpWV0B9cvWsthNMKth+U63i5QoNbZ1jp05Ba1XlXThkebDo7hNT+J/EqELPxWFWi+tbO5QTS9qe/lllVAHwznfhaFzqouVTTGZZpQpIEBnZC49VqmQhgFaTT7tGFRR03BE9dyq5Xcid0aDpk2upUuXw7Wd6gTPFWcViy6LKIMsVkHXvUxBdIKFUAckCzsxx2M8uW/dOPB7Hvvvui7vvvhv77LMPLr74Ylx00UWYNGmScp/x48ejoaFB/2/16tUp++EVU2efT5gh7rxRBR+aqVSqBPIlQg//Y4wq0iEednOqVM6eKtitU8WG/wGMEYSgVHVkS6nymYv/WtWpSrRzllMFGJb50ThB/4E7ovbI87HsP49kdhJ5hlTqj5b8H7tNbGMKH4MxKWePLV51O/k3Tor/smYPskM6OadsF/+lf5MpcW6aPPD9GmfFEzph7My+qs9OhVzmVLmW3RgIBLBu3Tq3Dlcw6KyaTBT5ZMwAdL5SRfvNF+VOVDKL6T5RGVVEJOF/7OSqzkKpUhWZpWCJHEsoworiv+wx2AfqVkapomO3MqoA5ORIDP9jodeVsjtZSrZTKVUdDNmiSlVYqlTZ6k6HylKdnSR2CJ8jHass3l52HdlrIJLTslBi0pwgtsZ28Xpn497p27cvhg8fzm3bddddsWrVKuU+JSUlqK6u5v5LBfYr4DT8L6IgVYbTHM1DNHJ7WMhqibGg39OAz1CqVKSqriWCTU3t0gkWS+r8ErJNIbpbpgIN/2sKRy1VPp1U6eF/4H5SuJ1TFWXIpC33P0Gp0p91Nkkm+7lH43FoPj/CjVszPIv8grIAL5enxG1iG+lt+GOyh7GhiFiMj91XRZikuVJWx/KxYyTyNi4pVfR4Rt+pi/+6G/5n/FvzsdeccH2z0JjxqVRGFXJZ/NdxTtV//vMf7ndCCNavX49HHnkEhx12mGsDKxTUt3RO4V+KfCMRdZ0cDpkvxh30Pvls/nq0/rIWW2PdMGnSd0V1n5gs1aXufyS5zXiaNbSpc6pURWYp2NVcNvQtEo3rE06ZpXQMRFCqeFIVjsalLyxO9ZL8XaxTxSLdyZLuGigYVUgt1W0YVfi0FPkBYk5V3JiUmPNT+M9F9sJNGf4nXA6dIEbjiBOC1l9mAQDef7cDoYAvq++Yww47DIsWLeK2LV68GAMHDnS1H+quFSfm67N8Swtuens+Gtui2LVvFe75/Z7cZIEqskG/xt0PoqoU1cmRfDKSSqkKcTlVZuLxyCe/4B//WwwA+NWwXnj6fL7grFF82Ah3khHIaFw+ThVY59Dm9ihqFO9a2lcwwPdtyqly2VKdLWIqqoIy9ZB9HMTiRi5nKgc/+k7ZOH8RWtc34atpG9HRtBVb3nkE3Qbv4c7J5Als5VSlaKMiS7SN28V/0ylUzB3LItROZarhFNY5VcYY47LtLq5FsNdBrJGV6nPJ9+K/jknViSeeyP2uaRp69uyJ//u//8P999/v1rjyHi3hKP706lzMXrENAFBb0bkk4pvlW3HWU1/jgdP2zroNsQwdsTiuenUuZi7bmhxX5xp3/Ly+CadNmol7TtlTL66aS5x44onGWhMB/uvTMKvI7pMQk98BKOpUqZQqxcNNXOEVCQk7OeHD/2JGXSfR/cwHIMaPYask/I9OxliwyphMcbJSqmRjtgIN69FzsTT+fGhfbPHfjliCLLJ9iJfWn5zNq4iVeAqswx+beM86lRmkiu5j3t80Bsm/fZphvkDVws1T7wQAnPZWok023zHXXHMNDj30UNx999047bTT8M033+DJJ5/Ek08+6Wo/QOK84zGzIcq7P6zDV0sSz835axtwyZFDMKSnUXdIr1ElhNv6hXw3VU4VXRdQ3XN8+B8fUshi9oo65t/bTH+PMoqX32IipivKNu+LkoAfpUEf2jviaGzvUJIqw6pdDP/jz0VGGDNBlMklY01B4nFDDWEJJB/+R/SwZX+KuCE69yLJ/7vnbQ2123VHsOdw7H3W1W6cSt4gVUidVUFd+rmL/MPkMqfMvUpNIlhy527xX/4cxDZZzanS+85+8V/2UGxOFXvPmJVGY+wqlVGFXOZUOSZVcTfpagFj5tKt+GThJv33XXpXdco4du5dCU1LhELNWLoVH/28Eecc7O4qqx3MW12P93/coP8+tJOux6DuFXrxx29WbMM789bhT7/aOefjWLyhESMf+Ez//d7f74nTDkid0F5ICAlKFXWykudUGU+z+tYOzrmPha5UMau/LLRknk9HjHC5JuFoHCUB+T4y9zMxBzESi8Hn40kiICSYy8L/bORn2H3w077COqlKbDeRRM2oUwUkFLsKpriyOHn2aRrgA+KKay6u5OurlD5NJ3pAksAJnwv7MjSOZ+6HVV7Yf/t9mk7OaV7bwOv/CwBYctcorv9s4IADDsBbb72F8ePH44477sDgwYMxceJEnH322a73lbhWZkOUlgivNorfKb1GVZD/fgZ1wmvt/mdlEU0I4dz/jHBP8/eaHbeMoLOhoVYrw3HFgokVqkuDaO8Io6GtA6qnqCn8j5ifPYD74X/sIgQb/sf26xdcRPUxE/tKFZ17Xfj8bHz88yb8/eQ90KOyBBe+8C0qutW6ci75Ap+C2LAKitogIvFTDA3TfGwbwj3n+L6NNipIi+aaxmEQIStbcpn6ZjdPzCnY/cXcKZmleqp8sHQhKlUs6VERSDZ/N5+VquKqGJdDbEuGl+01oBYfXn0EDhy8XaeMY2D3Cnzy56Pwf8N6Aeg8a3UafjikZwXe+dMIHDO8d6eMo3tlCab9+UiM3qsfN65cg4ZB9q4uwb+vOAyn7r99p4wjmxBzqoDEhDDChMTFhHwPwJ6lulUtG79APgAg3BFX7iPWjiGEmCagYSGfh4Kd1EvD/1xUqkyKVPJFIAvnKmVUQtEBUHxxsHWDZBBJGGskwIZ4RuPmaywN/5PlVGnyf/t9mj4Jpu5/7N9ygd/85jeYP38+2tvb8fPPP1vaqWcCw8SA394mkCqRdIU7VEpVcgIvKlV+1fffPCY2LDfo9zHGJObPUCzqLYKrU6VwMWPbOalXSx0An/lqOeauqpO2ocelirNYi4fC7fA/PpfMWGRgP0f2HtZY5SJu31Kdgs1zVBHpQoc6pM5QOVO2sVCqCIGeOGSliKjAkhyVCiJvY6VUWYU0OiMRKrD7J0LtZGM0nlHcdheL/3JGFUpCZ37vAbyaVbDFf8eNG2f7gA888EDagykkNCQn64O6l2OXPp2jylAM7lGBob2r8MnCTZ1mJU5JxPbdyrF7/5pOGQPFgO3KsVu/avx33rqc5lax98nKra3Y9tMG+KtK8PyW90xti+E+Ed3/gASpSqVU1bVG0LtaHqJqzt0xt0mE98T1ySYAhGNx5QRDrB3DTnbKQ340tUcRjsZRHjI/cMU6VSLskCq7YU70euo5VZS4SFZSfUkyEonF0c6QSzYB22ivQfMBfBaZAWX4n0/jQsnY602vqWxiI7sknM29EApVEvRh27Sn8PyK7vi8RwW2zVoFTQP+/Odp0vEW6r1Dr4FIYsNCXpz4nYrEkoV/g/zNwLrAsT+d1Kli+2It1WWLHlwtMunfmSK4ijyuOEc07LOqnlUl+GVTM6bOWYtpP2/C59cdrRMt/diEV6rikmcPkAWlSmLQkVCqjH5kn0k0qVJZFf+Vzb1mLdyEbZub8dKK7igLBrBt4UbMrykFLjvUrVPqdKjUEd5+XNWGP4ZxTP44qepZdUbxXza3SNomQ1bFkhD23hRrZGW7+C97LDE8UlX8l72GBV/8d+7cubYOZpc1FgM625BBhFGfqXOUKsPlrnNyqUR00w08cnc92PtkU1MYkc3NaGkKYi7ZxLUrlvtERqrCsRhPqqjdM7M6XN/age6VJdJj0rAjY6Ji7sNQl5icqo6YPqlTWkpLwoEoqYpE46YwOICf+Mk+NzvhfzbL8RhKlRj+p3i5lAQTpIp1AJTNA3waQKyUKlP4n/HC4oxBmOstEj62X9nknb127IvQ59NQ4vchsmkZVkQ3oHltCSKb6qABmDu3wfI4hQZRMaUQlSqRBFAyWyIow6LdPWtpzveb+JmKVAX9mqVRBTsuGeli61SpHAdZQukk/O+mE4bjzTlr8OGCDVhT14anv1iGcb/ehT82VaoE9z8xP8V99z/2vA1CF7MgkD4mz9FKqZLNvbZuakakOYyVsQ0I+n2IbGpGQ1N+zEPcgjpPKfHTqlCuSulQGVWYc6r4vmRwWvzXXk6VOmxWdU5OwX7FeFLFPydYopednCqe0LE1stRKozEONgzUDuwQZbdgi1R9+umn2R5HwaGzrcNFdLa1unE98uPh3hlFkdn75MnPl+Lu9xbixL37YeIZ++RsDLkEG/4X8GmIxolJqaIPYnPxX/nEhiQnGbJCvhR0MsmG/yVMDiDdR1w1ZyeEFaEAgHCSVJnHwylVMlIVMyayqpBGpzlVoqW6OUcm8bM0mCCErLV8KjtzGcTzZt3/aJhNnNhXqmTuf7z7Ga9alQR96HPmBFx5zFCcvN/2OOzvnyAU8OHTO0dZjrvQILP2B4A2IXxTDL0LU3e+gCL8L4VSZVUziq2J5vcxRhUplKpEiBCR1oEL+Hz690IVWgo4C/8b3q8aw/sNxwGDuuHSl+bg6S+XozUSw1G79MKInXsAML53QVqnSpFTJQttzARsSCyrRkaFSSsLw8jDWqmSzb3+/Po8vDlnDcYeNwy9q0sw7vV5ODx5DYoFxnOF387nMvHbZG1YsI9hfmKuUkTU3xM+bE6ugtivU8Wqb87OySnYc2XvTTGfqzOL/6b6XAjhw0DtQPV9yga8nKo0IdYf6mx0trV6vl2PzrZWzzeSmQ3QMJugX9MLuCZIlXlFmw2FaYnEpEVrKTpiTM0pyRNKVHQAmo9jXaeHDoFdhS8vMcYtm3SmyqmiY5Cpdvp+TnOqFO5/FJSUULMKVkGSOu8JipMIZfHf5D4BJueJgo7Ndp0qpns/928jpyoSi6dlYlAoUJEb8V4Q85UMpUowqhAIkMr9z2pSxJpUaBpTlyyFUgWYP2cup0oxMbVSb+zg2N36YI/+NWiJxPCvL5fjqtcMJYf2b9SpSvyuky2huLZbYEmVjwn/YxUoUWFgrdedWsyzCqXTfQsF9HKJeTx6Lg1TMlZ83NBfVcV/AYDE2e2qvtUwxqFWqti8H9EgQtVOPydlf5l9zuwlYe9FTWOvg3HVWSXOTZWHCISO9k2Y3k0KIjM6p6pZ3uVUifj222/x+uuvY9WqVYhE+Enr1KlTXRlYvsMo+psnSlVF55IImstFLc07G3o4ZFvnkczw+l/wxctv44xXmoryPqEr56VBf2IiE05MWNgJmSyPCbBWVKNxok+EZBMvuk10/1MaVSSfqM3hKNo7Ynz4XzBZeDYWlz5wxQRzEcakVIPqq2aXIBg5VUY4iPx8Ej+pWUV7qvA/n/WrWJzEi/HqQZ+GCPhwS0OpMhMF2eSdC/kTwv9CjKU67Tu8fjGuu+6TonrHUN5tCv9LpVQlr7vaqIKWMpB//1nzBBEdgl17UD+mua0YEhiLE7CGhGz4ocq9jSViaXAqaJqGh8/cB8/PXIFnv1qBRuamo8dWuf+VBv3oiEVdD//T3fs0IwcxnsJEglXyWPfAVPj222/x2UuPYvPCpXjqy1KUBn3YtK4Rn1aVAGOKJ6Iodb0mtfqQKnwM4J95GeVU+ayK/5rHSsfLLizJQu3UtbeUQ7IFTqkScqpUOUusQYRboIeiw5HXyJIvJibGJ2+jQi6L/zp+rL322ms49NBD8fPPP+Ott95CR0cHFixYgE8++QQ1NTXZGGNeQicReaJE1JZ1rlJlkMw8uR7JcTS0dSiLXmYTs6e9gw0vXYtta5cV7X1CV0zLgn5uYizLqeoQJmmt4cREUfZMZFdgrZQqsU5VqtpWZz71NUbc8wlXJJWOm92fRSCFUUVEEZol6z8VzO5/8v3pi4TWqmLD8lTOe1Yr2abwP0ElpEoVq6jooYmSCYi0+K8q/E/TdAWGEuOWnz7Dimf/XHTvGJVhhOjeKCpCEd1SXcip8olKlSKnyiKcSa9R5edVyVThf7I2umrit8gNYfZJV40c1KMCVxy9k94n/e4Z4X/8JJB+n43abi6Tqhhz3pQ4E6P+lOzeY4muXQc/OvfatnY5Wn+ZiWi0A6uX/YL2lT+gpLxzzbLcRkbFf+NGG9kxATOhYGFH1XCeU6WZ9hV/5wkM35/bxX8BkVjyNbJ4oqdWutOFeD46QY6rz5XPqZITZxXy2lL97rvvxj//+U/897//RSgUwoMPPoiFCxfitNNOww477JCNMeYl8s2ogpKIxvbOIREGycwPpYoqiISAW83MFb799zPY7lcX4vZHXyza+yTkT0xSykI8qWIti2U5VQDQGokCAGcNTsGG58gmXpTocO5/FkoV+/uW5ojet19QSWRha6xSJnuAi8nxMtgN/xMnX3r4nWKSTI0L2Em57N73M4nAMogkiL7U6LWnE27aT+IFnNgmS+pOFf7HhQJyxDahVDV8/Qb6HXdJ0b1jVEYVJlIlTPr1OlViThUNA0uZU5X4KftcIjqpShzbrlGF7DyM+8+nzA3hajdlsOzO3hMxgTwFhfA/Sm5ouKy4wJMpYswk0FhkMK6tVVmIhPufuh0LOvc655bHoPmDOOGi8bj75Y9QMWwEqnv0ce188gHsBJ+FreK/NnKq2O+hJjy6VSor34fR1o65BK9UqdqlzhPLNCraqVLFjt1NQiIqb7ylOv83ceyJnCp+WyoYCmDaQ7YNx6Rq6dKlOOGEEwAAoVAILS0t0DQN11xzTVaq0Ocr6vPMqKKzSYSuVJXlB8kM+n2oTBZE7QzzjubNa1E25ADUlgWL9j6hK8KlAT+XF9PBhOXJcqoAoDXpeFYaND+CeEMEWfgfVap4o4pUk0oKqrgE/T5j3NG4VGFhjSqsiIkVqbLr/ifmgmn6Kp58JZWuvPM5VebjsrkyMpjNBMD1K4Zb8kTTPKGQKlWsOuXj/82rhUC0fj1qdzkIQHG9Y1IZVVDS1CFcP3rdQ2JOlRD+xyom0n5l4X9MTlXimPaVKpVyxYb/mez6qQKtycNp7YLNdaThwvSyiuF/ulIVyJJSxZw3e29QhVFWwJoNm7WqyceCzr0Cfh80XwCtra2IEaB6/xPx06dvuXIu+YLURXBTt5HVOaKbrJQqOyTCSfFf8bsuHtae6YV8rE7B7s+G+GoaS1qI9PzcJCSimyFLelIV/43HiWOSmddKVbdu3dDU1AQA6N+/P3788UcAQH19PVpbW90dXZ6iLRLTX3T5QqqCfh+qOolEEELyzg0R6FzzDl9pJeKRNnQrDxXtfUInL6UhdfifUfyXnziweQ4iwpx1t7lfv89nagcYRM1KqQIMEkKd5xLHsmNUYUWq1H+zuyIvEkjatTr8zxyWJ8sDYC2uZVBNlimJFMMt2WEaioSxTR6CqEn/7fdpOpmgZiG+kkqQjnYAxfWO8SuIBv38qkoDyb8LdapUSpXPmIBZhZFZ1Zkxh/9p3HZZWwpxoSQmtVQXvltEPkanYJWqaJxwCwP0WaSH/yV/loWyS6p8jFEFYE+pisetC52zoHOvoF+Dv6o7NqxYjFicIB5uRjTc7sap5A1UxIbLZVKooaqcqsQ2s1pspYiowCol+v7ERhthvCZrcWXYIz1v9ZjsgB2HuU4V7ctQ6djt2Sj+S8fD5VTFecJFwT7HnCpVdkI63YLtj4i+2I444gh89NFHAIBTTz0VY8eOxUUXXYQzzzwTv/rVr7IzyjwDJS0Bn6arIfmA2orOIRFtHTH9xU8NM/IBneEA+OOPP4IQgpIBu6F9+VzUlgeL9j6hk5eyoC9lThWd8JWHeBLFkir6N1nuDguZUgUAW5oT5W2rSnliLz5425PkK+g3nOfCyvA/lgyY/qzDMvzP5oNfRZ5UyltJ0GxUIZs4s1bPZRISK5IqVfgfVRBlShU7CZDNWdlrwF4On2Z8jzasWIw4ISgZsDual84BUFzvGGX4X/L7SN8lYniablQhkCpRrVG5/6kMMhJ9CeF/FkYV5kK+wrE4o4rkPmL4n2DCki44UhXjF0T08D/Cj1tXqqIuh/8plCpaP06WU6VP7klqpUqce/l9Gsp3OQwf/OvveOHev2Lzf+7DwD0OdO+E8gC2iv8q2yDZRnbdEz+jAqFgoap/JR9H6npZrNrDjk/8N5fXZEHQMgF7TcRrwKo5suLG7uZUGf0C4Aiy6lzdyalKf8x2YZsR7LnnnjjggANw4okn4tRTTwUA3HjjjQgGg5gxYwZ+//vf46abbsraQPMJrClDPhWj7FYewuptbTl3AKShkEG/hoqQedLWWajVCyLnjmTuueee2G///RHovivKh41At4pQ0d4ndJJSEQqAkESeUsL9j51gJyYN9EFZEQqgqT2q/52uvmtagmC1RmKcAiUlVdQaWSBV9HOuKQtK21OwShXnPCetU2VXqcrcqEIcp5pUJZWqgJmEyibOmmYcozzkN7nNmcL/hNAK3agiauRUGWMxH0Nq6+5j/80rVZTYvnnTWVj0xr4I9dwNPfc8EkBxvWNURhX086CLAeJnqFKqWHU0Glfba8vMRCjE8D/DqCJ1TpVJqWLIgZGXIp9oZmoBzn6HOmIEoYCZVIlKFVWlO6ySZdJAJkpVLM5br8sgzr3+sySMmkNPx6AdumPb8h9RvsuhOOGKv7h5Sp0ON4r/yi5nYh++MLMpzExBbFR9qPOgjD7ZPuKKZ6WmZb/4Lx1znFgX/zXGbi8c0ilEh1m586A4buM5phMvm8+RvCv+CwCfffYZnn32WUyYMAF33XUXfv/73+PCCy/EDTfckM3x5SXyzZSBoqaTHADzmWQCuQ2H/Oyzz/DoE0/huzfeQMPM13FFy6dFe58cPawXRu3eB2cdtAOe/HwZAGpUwRejZSdftC4UBVWqQn6foUCxSpXk+6RSqihEUiUeoy1iKC46qYqZlSqWjAA8qRKL/VqF/6VrVGG7ThVnqS4hNExOlSzckoZtEUKgaZpp5Vz8XGQhkezkWfbyZZ8LYiggVdz+78+PoXLlF1jw7zcw9+vXcd7694vq3pEpVR2M0yVVqtRGFfxnx34vEkpVchKvyM2TKbE0/5EWzNWVKpdyqsTDWBW6dQJN0xD0a+iIEY6YAMa9KBb7zpb7H3ve7LNGz6myCv8jhHHblF8Tce61x4hfI9z9IOz32zHYfrtyPDTtF1RW17h6Tp0NlWKjkwsYdYus3PRMx03+ZN9JYsEJO6FiOukAS+4UYxWUKrZGFk+qrJwEjfPOFJqmAUQklnzdL87dUFEPLBMY14//aVX81/i8nV8PO0TZLdgO/zv88MPxzDPPYP369Xj44YexYsUKHHnkkRg6dCjuuecebNiwIZvjzCvkm/MfRWcVvM1XktmtE5Sqww8/HDfd8zC2v+JFDPzNFUV9n/SsKsHjf9gPh+/ck8uLEetUsQ/vihC/jkP340hV1Dr8T8/xERQXCpFUiZMVSkICflGp4p+4QVMYFUOqhImrtVGFvUe/X5VTZQpPSfy0a1TB5riUSZTkGCG49o15OPof09EaieovT7pPUFCqZESTfeHK1DJV+B+rVNXuuCduuS9x7+z0uz8V3b2jh+ExF4slxJWlzsL/2O9nNKYuImuoIuYx0Xs15Oc/a1n4nzmnSiBZNKfK71OactjNH7IDtlAx+52jzxR6nel9TUNf3Q7/Y+tMsedFn2OWdarihCvxIIM499q2YS02vjIez179O3z82hOINde5cj3zCbpxgSlRif5dXR/KOIbsutNFIHNfYhurb4kRosaaLBBFG6H4L3NkdhexnepYmUJUnugh2WtO9LYaZxDhFoipb+OaK4v/6m2Ic+UuC2qbCo7T3ioqKjBmzBh89tlnWLx4MU499VQ8+uij2GGHHfDb3/42G2PMO+SjKQNgkIhcG1XkW40qitpOUKqABInzhUqx8+Gju8x9wio+7ISMnewBQIWgVNFJfijg0xWQcNRs3c0iyORBiWBrZlGYlCom14Gu/kckRhXmcDxmDD4xFCvz8L+g0I6eu7L4LzXZSFGninX/k+VUxeMEnyzchBVbW7F4Y7N+HWj/Ad1SPTlJlKhOqpAWCi78j9mfNwtJuP/5QqXof+DxRXfv6OF/zPeMfhc1DXrotN3wP5/PCCuKxtmSAkI7xaQPUFuqy9Qcc06VXKkK+uQua4BBdDIN/0v0YzgVsv0EhPA/Q6milurZUar8Ph9nQR2RuGVSsI6Mdov/0rnXXx+bjH4XP4EdD/wVZvz3Fax5fAxeu+tKt04nL2Avpwop25iPm/iZjeK/5jwoc4ig2I4nVWqliiVxmYI+1/VakMnf2RpZbE6VldFNutDVKB/tO7k9rlaq+BBBeRsVsuFgqOwrk5132mkn/PWvf8VNN92EqqoqvPvuu26NK69R35KfSpVBInId/ucpVSxEktkV7hM6KTOF/8WNIpiAWamieUEJUsUrVSoyIiv+SyGqVICFUuXz6RPVcDRmCo8SJ34swTMrVeqHu22jCoUVduqcqhR1qnywNKqIxok+0WxujxoObcluA8L1ZscjC9NJpVSZwv+Y744YHlZM9w49J3aRgRLi0oBfJwNizo+qThXAEAsLpUplkAFIcqoUluqEGMc3iJyoQhn3reH+B6GNOjTLKfx6mF+cywNka0CxP7MV/hfXSVVyXMn+I5ZKlTFGu8V/KQJ+DcFu/bDHb8bgyNMugS9UhsXffp7ROeQbjAm+GAaX+GmZUyWUhGAhc/8zKyL0OFbhf0x4nIII8TlVmmlf8d+cKYRYisDlnCrAuF/p77wRhLEtGzlV5uK/BmGyU/zXyuFRBk4pzDKzSptUff755zj//PPRp08fXHvttTj55JPx1VdfpXWsRx99FIMGDUJpaSkOOuggfPPNN7b2e+2116BpGk488cS0+k0X9W35rVQ15JhENORZjSoKSmrq23KsVNHvR1nQ1fskn8G66HHuf3GiTxI1LWG/zoKqFKGAT58g0ommauJllVMlI1XiCjAX/mdRp0pUn3iDBf5vojrG76f8EwdzTpW5X8B4sVKVr43LqTIfNxHCwe/DIs5M7JraOwz3Pz2niv9cuPA/SZiXbC7CESnBtIILwWRW7Yvt3rFSqspCfp2Yi6F3KqUKEAwPYvLJuZ+ZsIhQu//x9xa7LyXzypwqv8aRBu44cX7cmYB+LztixDiupjHW9UlSpRf/9evt3QSrVCV+8osQ4gIM2yYWJwwps3dNfvl+Nra8+0+8fNVx+PDZ+1E+9BBcfv/Ljsedz/MuVQ6MPYMI9YRbXBBIkCK1IqICS+7s1Kniz0lOqrQ0z8kp6Hjpc0ash8jlLGlqm/dMwJI2tm9CLIr/Mgs1zpUqc9/ZgiNStW7dOtx9990YOnQojjrqKCxZsgQPPfQQ1q1bh6eeegoHH3yw4wFMnjwZ48aNw6233oo5c+Zgr732wrHHHotNmzZZ7rdixQr85S9/weGHH+64z0zhhbvx0MMhK/KLZOp1qlpySzJXrlyNhpmvY8oNv3ftPgHy+yVIJ8ZtkRifX0N4dytxYljGGlXQMLOo2ooYYHOqbJIqk1JlJJBbGVVYhv8Jf6suVX/37U6WzGFbKqUq8bMiaWzQEmZzquQqEb2WKkt1Orluao/quTdi+F9YkngvnShIlSrzedFzoyGY4WgcG9evR8PM1/HlhLNdvXfyAbpixFyrNloEO+CTqkR1LRFsS0ZGiEYVAB+up1SqFCv6dD8ACAX4z1pUodiFEnrPmJUqg1yo+ozGrVVoJ2BJKFv/SsznyrlSpfH3i2WdKptKFTv3uuOy0xCtW48DzhiHsU9PQ/dRV2HH3fZ1NOZ8n3epvj+s65s67I4/BndcQbWVq1mQ9s1CXhxXRYR40sI2Y8dulSfmlERYQVTrpMQmbj4/d8P/eELHRjyoVDk+RJBXzVNBpRRmA7ZJ1ahRozBw4EA8/PDDOOmkk/Dzzz/jyy+/xJgxY1BRUZH2AB544AFcdNFFGDNmDIYPH45JkyahvLwczzzzjHKfWCyGs88+G7fffjt23HHHtPtOF/lqzNBZxW494w4Do0aNwq1nH42m7/6LPQ47xrX7JN9fgnSi1RyOcttjTI4VO4Gm0N3/2JwqqlQpJhli7hWLahvhf3pOlZ+vr2XKqVKQnMS+/DGpyYAMdl+EIlFLZalO63q1RoxrLs9nsjaqSIT/JZWqMBv+pyXHRT8Xc/ifTAWRucz5OCLG708/g5+euQGn/d++aPruv+iz5+Gu3Tv5AlFBAQzVtDTkNwpjJyf9K7e24MC7P8as5dsAyNXQADNJVBEWq/A/qoLRz1hlVCE1ghCVKsZwgc13YSebcYb8ZAqjkHicU+nE89XrVAUNMujmqruoVNH+ZYsQFMbENrV5hzj3emTqdPT5w70YeMgJ8IXKlH1YId/nXao8QE5B8aVqIzuunFDI2lh9RXgTCkjbi+ROFiYoFv9VhTQaOVzqMdmFqNaZx8ePnW7PZvFfVtmmfYufHx8iyG9LBV6pyhNSFQwGMWXKFKxZswb33HMPdtlll4w7j0Qi+O677zBy5EhjQD4fRo4ciZkzZyr3u+OOO9CrVy9ccMEFKfsIh8NobGzk/ksXm5racfa/vsbMpVsB5J9SRUnEkk1NOHXSDCzZ1JTV/praO3D+s9/gowUbk/3nF8mk12NDYztOeuwr/LCmPqv9haMx/LSxBQNOvRH9L38OZ1453pX7BMj/lyCd8LUIpIpNIg/6fPrEhkJ3/wv4dKMGWe4OCzqBiEhWnGVKVbvgEtjOkAMjpypumvCpSE5iDPx5VJUElKEZ9pUqTfq7KiywPJmf1hKJYU1dK37z8Bd4c84a03HZ1UYZqWLrfbHhf/QUxXBLPqfKPAlIGf7HnA4b/kd8ftw68V/of/lz2O3Ey127d/IFMkc8PfwvyIT/JS/g4o3N6IgR+H0aduldhYN37G46pp6HZZVTZbHy3qETIT78T8zrYlUpGrJrDv8zvh+qYqcxJkwvU+gEME64hQD9fOO0zySpYhZ03AwBVOUgWuVUyepUqZ4T4txr0JCdAVBzEufKXy7mXUBmc69UNuU+zaoNfwwWRj6RXA3h+06tVNkp/ku7kI2XV6qswh7V5+QUZmLJK2l8cd0cF/9lOrFV/Ncmg+FzqtIYsAPYJlX/+c9/8Lvf/Q5+v3vFXbds2YJYLIbevXtz23v37q20z/3yyy/x9NNP46mnnrLVx4QJE1BTU6P/N2DAgLTHO+3nTfhqyVb9RTi0d2Xax8oGBnYvR2nQh44YwewVdfjPvPVZ7e/LX7Zg+qLNaEpOpIf2rspqf07Rq7oEteVBxAkwd1U9pnxnnnC6iTkr66H9+npg4AHQfH7s4tL1KITFB2o20BIRlKo4E97iNytVJbLwvw71Ci/gPPyvsY1Xbun9G2Qs1cPRuD7h26N/DbbvVoZf7co/lzhLdWFslaUB5aqZ3dU01WTYVK8j+Tt1i2sNR/HFL1vw49pGTJ2zVto/PXapJISMJZ2J8D/+ZatbqkuUKpkiIQ//Y/YRcrIose1zyq04+OjjoPn8roS55Btk1ub0u14aNIwqqOJDw9T226EbPrzmCPSpKTUdk1WqWEtzrl9H4X92lKrEd0hV/DfAqEViv3SfTOtU0X7oObAGJ+L50r+xCwpuhgCK1103qohZuP8xY0xFqsS5F1tLTEWkrZCLeReQ2dxLXQTX+HuqQrnynCp+4UKuVPF9yWDHyEEM2TPIvlm5pWNLfU5ukKrET9F4Jh+K/0Y5UiWOmyqIJA2lSv48ygZcEBNzh6amJpxzzjl46qmn0KNHD1v7jB8/Hg0NDfp/q1evTrt/Gtt+xNCe+OTPR2LHnvlFqmrLQ5j256Nw8j79ASTi8bMJGma438Bu+N81R2CfHbpltT+nKA368b+rj8A5Bw8EYHx+2QINgxzWpwrvXXU4jtqlpyvHLYTFByP8j1eFokxYkiynioawlQb9jFU6tVS3VqrsGlU0CKTKMFzwSY0qupUH8cV1R+Pm3wzn9mOHExAmrhUlalJl29VLmHypLdUTv5cnc6paIzE0t0f18xDBGlWEAj7T8djr2Nwe1V+oovugTKmSrQDK3f/M4wcSq/tcXpuLOTf5BtZGm6KdUaqMyXLiGugmEgH1tdBzquIWOVV6v/y+izY04ce1DYk+9PC/5BjEmlQxwyksoDgemxvEDoH9PtB93LBU58weiJnQxQRSxarkrpIqIVyWfr9lxi4U9FaPMSqb3WsSYHPJHJpcpIN05l1AZnMvNhSNhV7fCHwxWFkbq+K/9DkjFv7l+7ahVIGpn6RQ1XTSIs2pEtUs/hyMdvz4M4FeDDxunEPipzE+3t1Qfn6ZQPzMjM+FJ5myNmzelV2wh8q2UYU6ESAH6NGjB/x+PzZu3Mht37hxI/r06WNqv3TpUqxYsQKjR4/Wt8XphC0QwKJFizBkyBBun5KSEpSUlLgyXjo5G9qrMu8IFUX/2jLs1r8GU+eu1V3osgVKIgb3qMg7lYqiV3Up9h5Qixe/XmmaXLsNmmu3fbdyDO9XndW+rJDu4sO4ceP03xsbGx0RK1X4XzxO+JwqIfzvV8N6YfbybTjzwB3w8qyVAFJbqlvlVNWUmR9polJFJ7JBH+88ZyS7+xShIxZKVUlAmTTrxCpZtp/SqCJJSFsiUV0tlhFNP7N6H/In8qtkeT0A0BTuYJKUqXpBSZW6+C+QeNH5oNnIqeLHxuYKyWphFQtkjnhUNS0NGkYVNDRNzHeSgbVUVxFSWb8t4ShOeuwrtEYMUsfuK5pQGITNx5hZyJWqoJ8n7qJxDTumTMDmf9FnDKdUCTlVIb8fmpYYjyx0OF3EBDJrhCerw5jZUFCqdNlXtI16W+koVbmYdwGZzb10BVzI4+FzmQzlgmsDo435uJRQ8P3I2liCjoNZQDBN9E1KVXK87Dkp2wiHyoJSZYTQJTawuVPsNdRJpotsRAwxl4VQip+NrPiv3evBNsu2pXqnkqpQKIT99tsP06ZN053J4vE4pk2bhiuvNBezGzZsGObPn89tu+mmm9DU1IQHH3wwo9A+O6DKT7eK/MqlEmHUZ8quMlOvG1TkVy6ViG4VuSmKXJel61EIiw9U8bHKqUrUheLDz3pVl+Lp8w8AAEz+NrGSKQszY2GpVEmufUtEyKmKsjlVyeK/MbZ4qrRbPvxPIEBVLoT/qciTyniAVarodZcqVT5Nr+kT9PsQ8Glg74Qwl1MVNU186cRdRng05lrFCEEA8peWMvxP49VLSjLcSMjON9Dv1Re/bMYe/Wuwe/8aw6gi6Ne/UzFdqTJIivqYBsHRi++ayHniJzsp2tjYjtZIDEG/hv8b1gunHTCA60vt7KfphgwqS3Uxp4olc24qkaxTIWvFr6pT5fdpCPp9iETjpvDGTKCHkiX7pT9t1anilCp7X3rje6IO+bRCIcy71C54hoLChh5zbYSwNv64iZ96GKpVTpUFiZDnVMnb0D5l6hsbRsi1EQ5GhHaZQFX8l62RxZK47Lj/Qegb3JjYv4m/J5QqeRsVVDme2UCnkioAGDduHM477zzsv//+OPDAAzFx4kS0tLRgzJgxAIBzzz0X/fv3x4QJE1BaWordd9+d27+2thYATNuzAd06PN9JRI6s1Y3rkd8kU7eaz7K1uk4yXSbdhfASDAWoEx1PYNicqoDfHP7HTjiCgnV3quK/sgUnWfifCGpjHWTc/8LRWEpnMnazONGtCFkZVaQcEgC126C5ThXtM0kIo3FdJZWtwPs0xskv4DOtaos5VcZ1SI7LQqliCZZV+B97DURL9RDzR/r9KcbwP2os8t78DZi1bBu+vWkkZ1Rh1IhKXD8j30n9BWJzoFhLcxayPA367O5TU4onztnfOB6Tp8SCvYf9kgkQIORUKXIYdKMKF3OqotyCCOv+J4zdpyGYXFBwM/wvzhyf/Wnl/seGLrI5p3bAWu+no1QB+T/vyqj4r8WE2xT6ZkG8rHOqDMKUKqfKXAeKMG2Ioo28v2Iv/htj1G+VUUUip4onrKnAh6kXsVIFAKeffjo2b96MW265BRs2bMDee++NDz74QM8fWbVqFXx5smxZn6fW4SJyVZ+pUK5HrqzVs0m68/0laMf9j3Xbo2AnA35dEUlOrFPkVMlgh1S1M7kOJRJLdTuKk6gGWBlV2A1lU9UXEvc3LNWNx/empnbTsfTJmqZhrwG1eHf+euzer8aUD8aTKnP4n2FUkZwkMucumzzLRAAr9z9NS4QARqJxfSzFaFRx6ZFDEPL7MPnb1djaEkFjWxTtEVap4lUinVRZsPKAZHKu+h6xn4vq2a22VDcIAp3UixNeOl4xp4pt52YOkB4GFxfqVAkTcra4bjDgAyIxV0mVaL5hR6lijSrizH1qB2xtsnSVv3yfd6mIDev6piYz6gk3PSVRXeT7lpM1vg+jbSpVTSQtshIDMmJj95ycQjeFUBT/5XOqslv8V8w3Y5874u3A5oY6dUPknkfFrlQBwJVXXildcQeA6dOnW+773HPPuT8gBYyiv4WhVGU//C8/63WJoONricQQicYtV34zQTZJZr6/BJV1quJxPck94NN0tz8KTqkSVnhT5VTJYI9U0TpVmrROlVqpMhNACqucKrtOZ+JKdaqcqlDAh6BfQ0eMYFNjmGsT8BukStM0XDBiMM48cADKQwHT8diXDOf+J6y8ywiPLAFY9vJlX35+7jom/l2SDMuiKmIxkqpd+lThnlP2xIc/bUB9awc2NLajPfldLwuxluqJbVR1FAk8C36CLf/+yqzcVVEGqnypDj0v0siXUitVfE4VH+7kjEBYgQ2XZImTbgKR7IsNSwzqxjQuThAF8w16bhELpYpV0+wU/2XB5tGlq1QB+T3vUhEbLqdKEbFg5QynshPn29DjqL8jrFKiHqsivI6wbSBtozwnF1iVqlaXruJx7npq6/pMIOZE0Y+BjXIwu94a+zolmbks/psXpKpQYJCI/FZmanNEIgySmd/Xo7o0CJ+WeCjUt0bQq9psTewG9ImKjYl9Osjnl2BIN48Qk9f54pim8D/mYaeHmVm4ZgHWEwhZ8d8X/nggHvhoMRrbOrBsS4tBqpjQswhbp0qlVDFDDwpjqCwJKF94dieQQZP7X3J/hfIAJNSqhrYOk1IV9PnQDnodjbaysbNoDjPuf1QpE8Iy2esvVapk4X8cETMTrFDAB4SNnKpiDP+j6FNdqpOqNkapoufsxKjCnlKV+MkqRnp+sLAgxo6BEGIKlwr4NC6nhwVLDtjPmG3nlEBYIcCMlbXItlKqQroamAWlSgjXNRaH1Jbq7DicGtqIUQDFBBWx4RUUfpvYRmaVpyIULOyQCFYp0fSxytuIxEEW/me0kRM0N5UqOg5zTlViu0hs9M8iB8V/2YUak1LFfC5OLdVpX+k4BzpFfsTVFQAIIbqbXr6TKkoigOyqVTrJrMhvpcrn03QFgxKfbKBQSGY2IBb1pYjFjRX0oJBTpWn8ypvo6peORblMqTpiaE+8fcVhuiNjm65U+XQ3QrZOlYocce5/DsL/bCtVCoXBnFNl/E7zqsTvNTs+03EtlI9WJjSK7kbJntz9z9iXCMVWWbDtZKYV9HvRVsThfxS9k4s6GxvaGaMKn36d6fXTLdUtSRUTAqdy/2OIF0WdKvyPIQDsxygzoRA/Z514+fnvLRfu5CapYkIV2eOKRhVsUWJW2XMLNGIpINyvVkqV2Ibdlgqs9T7rylhMcKP4rzynKvHTqvivvfA/g5Ckqi1FuzDyxMxjNcLg+O3mdtlQqjTpdrotG0YVJoWOKTEgjtP4ne7L5FQ5+NqrVEC3UVx3YhbRFDbCYvI9/I8lEdmyVWdJZm1Z/pOI2hyERDYUCMnMBlRhd2wyNeu2B5gnG2L4n0hcVPvRCXlp0OwuyB1fzA3iVq6JHqaoVKpYUsU8zYPJosaqOVG6luoqowr2V+oAaD4WS17F62z92KelB/TwPwsDEZnLm2wywo6BHT+nVMEwEXFgZuYq/v73v0PTNFx99dVZ66NPklRtaGznjSqECT9VrKyNKuhEyHC0UxmesJOiOkXUBfsdZIkHJWxBv8apYyzYMN9Ev8l9OaMKPrQ0EwSZc2fLIYgkUldesxT+J5JZXamizxPJc0zPu4qlo1TJzEmKaxFCTVSMv6ciM9KcKkERkbfh+5KBM3LwyduL5E6mrKmK4HZm8V9OLfLxZMYtqAw67BT/5YsTO1GqUpNlN+CRKpuoT5o+lAZ9KA2qJ275At0BMEsFbxvbC4dkAox5R5aUqkJSMrMB1TnHmBX0RE6V8cgRXxABIYRQ9QIRc6poAeFU+VR6blCUhv/5+BpJVCFThfFxqprx78oksVE94N02qmALVlKlSgQb4ifun2oCRkmV7hiYvN70XcRO2tlrFSf8JFbVp0/ybzOpyv0kcfbs2XjiiSew5557ZrWf3jUGqWKL/+q5SqbwP/W1YEPglDlVksmE4VTK3zOsKsZOcDqYWnOynKoNDe16G/r9kJE5fYwufLw0rI4/d3P4H6tU0fNzVakSHA11UsWEGZvGntzEKlW2i/9KlariIlVGqBy/XVb815x/pCYgdIud4r92cqo0jS2aS5Rt2PGwzcQ2qr4tIhodQ3RW1PsGv532J1PYMkVccT5c34r3JhvC5+h62CDLbsAjVTahCpfIV2SbRNCXclnQX1AkM1tKVaGRTLehspGPxgk3IWPD/8SJACUqdutUUdBcoZSkSiQHfr7wbGsKlYR9xrPEorI00b9qXmN3Vd6sMCA5HrVSVaYgVSzxFLu3S6roJMBE9lQ5OxY5VarwPzpMqjB2Vvhfc3Mzzj77bDz11FPo1q2bZdtwOIzGxkbuPyfow4X/JWYqpUG/PuF3FP7H7MPanrPQXbM4owp5qDL7WUc5pcogTIYdeOLv/523DgdPmGbkw/mFVXfW/Y9RlDJFkCEXBlkzh//RyaBf0xDKRvifqFRpvAolrVPlM4/D7ndez6liCz67wVLzCMYlU5ALzaL4r4WK4aT4r9XcmzPMkChQYhv+uETZRpMQr8Tv7ilVegikyiyC6dzH5IxlxVLdZ/TDj8m8D/u5WIV4qpANxU3aT1aPXkQotHyZbJOIQnH+o8gVySwP+S1D0IoV1aVmVzkgMaFSFf8V2xu5O/bqVFHYVarEFX82/A9gVBJb4X+sWhQw/Z0br83nviqnik3KBnhSUxGSh/+x5yqSIDpJVykg5vA/tQ0+YF6Blb18+YK/xnZT+F8nGVVcccUVOOGEEzBy5MiUbSdMmICamhr9P6d13/rUJIpsb2wywv84owq9+K+NOlW6uhXnFBkWehgeQ25Uz2923w7G3pgN4WVrLAHAgnWN+jiPHNoTfZOkUTbZTFVg2wlYxYwNKxQnznKlys3wP14hFC3V5UoV30bVTgauTpWuDhYXqVKpI3xOFd0mtoHexnzcxE9dqZLmXZkXA0Q4Kf4rqlC8GyY/1tQ5Vcoh2UZe5lQJzygrV8Y4V6fKCamSE1a34ZEqmyg0ElGTZRLhkUwe2Xb+y3domiY992hcXfxXnPwZ7n8p6lQJM7LDduqBXXpX4aR9trcco6gEBXxGjSSAUUlUZI4lVZLwv3SMNbjxKHKqxGOw3ahyqlh1QxX+V6og/4ZSlRyXgkSJv1srVfJzoYpFSM93y71S9dprr2HOnDmYMGGCrfbjx49HQ0OD/t/q1asd9derKhn+1xDWiTxnqa4X/038tKxTxeQExhQTbJml+rYWeeSFpslzpmQ5VWI9rTGHDcLzfzzQVK+JP448RDEdcEYVjHOneL5seF5WjCqEcwoIpErq/seEbVLYVbTZxRC9jxwru9mGOzlVaqXKqFMl65vvSwYnxX+t8qXUxX/tn5NT6DlVep0q+Xb6t5zmVMUsPjsfJUXOLdXZY3qW6nmCQgv/y5lSVSCmDN10kpktUlVYJDMbqC0PYquQw2eVUyVONnQjiVR1qoTt23crw4fXHJFyfCalKtmfWCPJlqU6M9GlIXiqiCb74X8CWeHIh6ZPwNgXjiqnSmUmARjXgdqYi9BzqnSlSrhuwjjFFVjZZITdhbNUp+F/QT6nKlekavXq1Rg7diw++ugjlJbaK7VQUlKCkpKStPvsk8yp2toS1lXW0oAPtMQbnfA5sVRnaxap3CLpqj8hhHl+m59XtMYZSzz4nCo+TJGGCYrkzzKnyo3wP52ExjniRIdB+2KfP1nJqSL8dded/WJqpYre27IyBanALiqlUvULFSpiw4aNqQwiiMWEW3SZsyJenVn812wlz48/ExiKFJ+7LG6n27JBRkSFThP6lj3+2edYOkYVKmXTbXikyiaMYokeiWCPWygkgo4z2+F/hUIys4EEkW/htrHJ1Knc/8wrvPaUH9thM4riunZrJKnC/+jEWB3+Z5dUyXOqxGOw28sV4X9cLSmFciHWDKOgE256PqJboDmnir7sCPdT04yJhmr8ulFFcqKYKq/NbXz33XfYtGkT9t13X31bLBbD559/jkceeQThcBh+v7vhvNuVh/Sizau2tQJIEHORpERsWaonFQ8mr0j8HtFrTyf/rZGYfmxZ5AWtcRaVKEyJnKrENp38KVwHZQqZoSgpT8k22PA/NsRP/D4aqoQR7puKVH3800a89+N6BH0+nHPIQOzev0bZliqEfmFyalVvj7btsMi7UoG9t9lC5sUEVb4UO5m200Z1XLFGE98G0uOyyFbxX1Uoobs5VeI1kG+nf8tF8V9dJbMZ/ucpVUWA+gJTqrJNIuoKLBwy6+F/LZR0F8b3IxuQnXuMi/v3WYb/pfqdQhXelAripI9TbMCoJDZIFZsYXp4ip8p2nSqR9ClC5jilqkQ+4U/kliRehGL39DqoDGZMRhUplCpTuFXyZzCpAAKiOsX8O7m9JDmWVCYlbuNXv/oV5s+fz20bM2YMhg0bhuuvv951QgUkPpteVaVYW9+mbysL+nXTCjGsztL9j9qKxyyMKoRJIl0QCwV8KJN8B+j+iWdlBTcmVqmKCyQwGJD3K8upcsdS3Qh9jBN2fDyJjOuE0H5O1V/fmo9NTQkZd3NzGM+cf4CyrahU6YtDFkqVWKcqU1LlhvKXT1CZI/D1oazbWKkdsXjqNnYs1dniv6rwP/3ZR9sxB3Zuqa4ek12o8pfE7fRvquucCUQ1Ucznkn0uLCnVyaiDC5KNMEYZPFJlE/UFp1QlJrgNWSJVDVSpKoAaVYDxudVnS6lqKyySmQ2w5+73acnQP7FOlZpUiSvySlJlamdvQiFOTvV8ngANO0xlVMEci+mThv+pFhHtKlVB4XxVRITdrlKqaG5JPEaUuWtWBgiJPml768/FHP6XJFU+DRHJPrLzEpWqXIX/VVVVYffdd+e2VVRUoHv37qbtbqJPDU+qSoN+BPyJ+L+oI6MKtvivQR5YiLlNbH6wbDWfft4nPTYDY3+1M645ZqgRQmeRU2VSNIWwQ3YfN4wVDDt5pnC3Zi5OzK5+282pYiM8NjW1W7ZVGVXo22V1qjJQqti26YQPFgJU5ghs2Fg6xX9VhELet1X4H0Pu9FwfVRv1OYkGFKqwx3TC3VQQ1TqrWlGJnKrk+WXcswHxfMQaWakURKsQTxWyYbgh7Se7hy8eFF64W7bD/wqLZObK/a9QSGY2wOZn0BXwKJtT5U8YQ1BipbJUp1AaVZiUEnvjE8kBJVliUWClUsVsZ8daHkwR/mdXqbJQ4HilymijVKqYyaWpHhgN/0tRCoGer0j2zO5y/CREVwYUtu78v3mC11nuf7kGtVWnKA36ufwoAOiIGoqfCqy9ucr9zwj/S/yeKj/418N76/+euWxrYiyMCYbo/tcRp+O0/l4AxnfDFaMKZhysGiUqp/RnwG8v/C8cjXFK1rZm63eoSGbF55ZcqUr8TEepYs1EVHl0hQ6VOkI4pUpOfixzqgTCLW9D+1aPjyV3xmRf1YZXguQ5VTwhN4c0uhf+ZyaWye1Cvpmm8c6z2TCqEEMP7SmI6RX/1RTfF7fhkSqbKDT3v2yTiEI27siG/FtoJDMbYM+dhpZx9XOEXB6T1bciJ0OEmXzYe4ypwtYMUpWepbqRUyXvN9M6VexYxXGolCpNY1bOTZO8ZPhfCqVKLz4skl8TqUr8pPcVG/5njIchiBKlSszvynWdKhbTp0/HxIkTs9rH0N5V+r8rSwKoLgsYqhMt/qswgGDBOgaqcqror/TzUTn/Udx10h548pz9EmNITvpZgwkxvK6DqiUKRZML/3NxchhgQvn04/rUSpVfsxf+1xKOcb9vS7EwyeZsAZIwXsnzSbddtwgRtEKqkNxCh16vSdjOFsHVz1hoRH+VfcfoFn3yblH811KbYUIM9aK55uJS3PFkio9RU4sfn6lnwv89IwjkwjhfYbvY3sXiv8bnqHF9WZFH9tqkU/xXj6hw8Txk8ML/UmDZ5mbc8OZ8LNrQBKBwlCr6wtzaEsaJj36FW0cPxz47dMv4uBsa2jHu9e8xZ1Vdop8CMWag1yMaJ/jtI1/hhlHDcNhOPTI+bkNrB/702lzMWVnH9dMVwZ57Wchs9UwnFyVBP9AeTa1UqcL/UkzyVRBX/CmJowVB2/XEcvn+7HjYCWRZyjpVNkmVomireAxOqVK4/7ErueL50ElfKqWK9ileN6VRBQ3/S760WOVCRQr/v703j7ajKvP+v1VnuPOU8WYkgQTCmBBCYoKiNoGgokQGkZf3FVGxReIS469VfCUJbXfHAVkoHeEF24ZlS4vxXaCy7LxqMNBAAAmDIhABgTDkJoHkZrjTOfec+v1xzq7atWvvql3nVJ3x+ax11723zq6qXXVqV+2nnuf5PrVoVFWCv3/v0Th2aieGMzmcPLMHLUlHUj0nhP+l/ML/uLwilddCNDJ0lFvZtcHCy/gXI6LkOvtMNP7YVxifpDozKPMuw4lXhcvnLUcsxTTsvC8/T9UQk2EsMpotKIOqCm3nS/FUFdswozXs9c7EROztNZhRpfKO8FLcyvwjIazNvV23h8/XI+Iz+XYLZrj7JrbxilA47UQBClWNrFgk1RU5Varl0ar/sRcRrE/u78XPy+jKqQpxPuxrKtJARsl+Yt16A3Dfn3bj8Vf3I5PLI500MWdie7W7pMWkzhZM7EjDsoCnXx/Ez594I5Lt/va5ATzy8jsYzeZhGMC8yV3BK9UAbekEZk8ofHd/fvMg/uPR1yLZ7gMv7sODf92HI8UH8XH99XE+4oD34rIaSLm8ZYcHiZ4qb65PaTlV2p4ghdHGjIaxgDpV/P1b5qlShSLohieqJsOA++23K6dKUaeqoILm3Q7g/R4YopfVKf7rP0kUQzfyEk8VvwrfHZcCo6v/koNqIFpTCXzg5Gm48LSZttfKVrNjnipbUl19ffOKmWyioaorxuZpOqHs7NrIFPMMczknhFfsZ5b7jMfxVDnLIjWqJOF/CdNwGTV8fkjCNDhvoHrGzO7lkzrTtqHo560SJ6E6QjqsbXSeqsYaMJUq/htFTpVu8V9ZWGH4nCpll7SxX7LYdaoM6XI/1cJyURb/9a1Txda1SjIyVdL3UdNYIzEGWKjE+YumY+va92JiZ+n1SSpJOmniv655Dz65Yg4A4MBQNLlV7HyctWAK/vDl92F2nRiZAPDLq8/AF/5uHgDnOMqFndelcyfg92vP9JXebXR6XZ4qx6jKCbkeKqNKzN1R3TBL9VSpPGNOfSz/8D9+OW/YtAWF/+l6qhRhdeK+3eF/8rfnrvA/z/mSq/9NEu5tbDWVVLbYTiz+y0/8ZN4pgFP/Ez1VDfbmXQdezQ7ghCp8JdWLLwTGnZA1b/iZ++23Tig7M3Jlnio+j4vvp8ejKZmc2kp5UYT/SUQ6ePU/wDFa2GfsuPzD/wpGVUdLEhOKeaJ+eVV8zhYgG2+yCaJR7Id/HqcKMaRQJoZRz6jzpYqfm45ARHWK/zpt+a/OnS/l3qc0xzCs+l8E90WvR0q+XDT0KlL8V8PLyEuqh7mNVEpSnYyqAJi88InTuzFrQv0YEAAwpasVi4/qAwAMjkRjRLAH8rH9XZgzqSOSbVaKvo40Tp8zAYDzvZYLOx/HTO7EvCnN66UC3OF/spwq9sad1aoK8lSpjCU/j44fonHA/k8JEy2dOlV8k8A6VZoPQl9Plem/b1lf7WKkmp6qSZ1uz4UT/mdIl4t9Y88q9tBKuzxVcgPLrlMleqoaPPxPhh3OZhsrXo+fah0WugqoPVXMoDlUvPf1tPkYVQnmqXIbVbKcqvGce3w7+y385kOZcgFjLAx88V9eUp2feLJ8L/YZWyczHuyp6kgnbfEdHU8Vu2ZV48O1TAj/C+up8hQyb7CXEGqPjWMIOJN9d5uoiv/q1akyXNvg++uVDXcvF49H1abwv/vzchAL7Yqhh6rllSz+K/cyspdD/gqPKlSezaihnKoA6k31T6QvYilxp15XfeRSifTZ9bsi8lTV+fmIEv4csAm7PKdKT/1P9VauZE+VOBFh0uIK1TIRfjd8m7ZUNEIVTNVLJiurrFOlEKooTDoM+28e9lZbNGQ8nio7/E83p4qF/6G4Hm88Oe1d4X/Fv/mi0EDj5YjowI45mytIBocp/stEVvjtMERPIvM+qeqUFT4rGlU5t1CFLKcqyFOV4yZjYk2ncmD3Ez6fzDTc4X+ip8rxBvrlVBXOZWdL0s7BUkV6iDlbgNdrJCvMy04VM5zDeiB080/rFZVh485lUnl1nDaq7fp5RAxhvMjgPSVuo8pCQhB88OZLOdsRw+CCQgnjyaly90G1PEpjpNziv7bBGsItRJ6qGsEpcluvRlXURkR9F7nlVRGjcGfXW1HoOOGviaw9Gcu7QocATv1PuHF2CflBqrmkJ/dKM/RFnPSx/ujWxzJdho2zfMG0bgA+OVUhHoRqGXXnb35z7QpJdT4MyquyaNi/+X14w/+KRpWw/tK5E1z/i28Ac7ZnkqtJpgr/K/4tetwaXahCBq9+mbf4OlXqc8HO3+g476lSqPDlmVFVMBr8wgrTxaLHY6wgMXsxknCK/zo5VSz8TW5U8bfZSCXVOU+VE/7n3nZGOC+2+t+4Tvhfwr6vq8LFeYORnXevp8pH/a9ET5XX695Y40Vl2LhzmfzbyG4htkck5zYceHSMCN5TYpj8cm/4n2EbTLI28jC4MMcUFlG4xhAMG1VR4Fop/mtZpXmq4ghjlEGeqgDq3TMjGhHlFo+rdyOChXNkxvMYyeaUktS6kJS6A+/5YOFIhbfIYk5VYcImvm0V8xVVydeeRPASc5bYJFD02CjrVAk5Vdv+v/fh4EgWM3rbip/L9xtmApk0DYzZ++P7Gs5Txb/JFR88bJKXTJhIGAZyRTWknraUXbS50K7QnjeOvnjWfDuEVuyPWKeKNxL4+44s/K+r1T1+Gu3Nuw78y4FsLm+HrjEDR4ZYDgDwXofi22/mqWIeYxktHk8VK/Br2NeF11MleMgEjxYQraS6Hf4nCFXw2+Y9VabhrKMjVNHRksTEjgCjijs2drkHlSAAuPC/nDvUShcdMYx6RmXY8GFwqjZ+E27bcPDNu2LbCfZUieF/rhcICsNBJlQhhv+FOaawKD1Spnu5IfQ7SkSDM0zxX5enKkTX4vC4ySCjKgDm9q9XzwwzfqI2IurVyOxIF6SLszkLB4azZZ+Pejcy44JN8vJ5yxU6BPBCFf45Pbo5SqVKqis9VRr7NQ3Dk1OoDhsMYVQlTABeFUKXUAXX3TZFCJdpqCd586Z0AijkAZrO7pBOmuhpS9kTSNbvYyZ34H3HTcZRE9rxxbPmS/cFOMYUm7C4DUFve/64ulvd47DB5oha8EboeN5ycqo0PFVjnMdDfHEmFuu1jaqk2lhjXqxc3sJ4Lm8reBZyqoqfsZwqiWcSkE9OxXtBOfAeMz6skL/emfGUKJ4X1seMhqR6Z0twThVvVNmeKg2Dxwn1lCsnBuHNP22soKNAL5RQYYp/Yew34WaLnDpVsn17PawifH0pQ7JcbMP3R5ZTxdoYkjb831HcFg3hfu2pFSV4sHTCIcPirTNlCPuWreW8vHOGnf4ZEY87Lsio8mE8l8eh0cINtl49Ee3pBNIJE5lcPhIjot5zzAzDQG97GvsOj+HAUMb2MpQKearkMKNqPG/ZYUJsIsBq4IjziM6WJNJJ0w6JUYb/iTkjpeZUKcP/5OvzN3q/sBGRsJ4q2fb4bfDTCdM00J5OYDiTg2m432gyg0Xs16VLZ+G9x03G9J5W/MtvngfgeBp6JUZVMmHijiuWKvvsqVMlkVRXhTKqPFXNqP7HX5/jubxWThXzvLByAH6iCGJOlV/4H+/FynDhdcmEk1PFjClH+l0RdigxqqL4flN2P/KOp8owXGPTvpcY7rE+7qP+dyTjVf9T5VTx4X9hPFVsDGTte104o8gjHtNg40V1L+UNFdFD5BgkrI36vPsLVRS341PPiDfcxJwqbxtmnBSNNdeGIG8jMc5U/Q2LHQIp5CV5lhvu5XEU//VIqmt4EC14vYA6qPLVoqaxXm9EDK8Q1+ujlFTLFIyIYghgmTLi47k8DheNzHr1VAHRinfUu5EZNR86eRoA4NPvORoAk1TX81QZhoFJHc55VE00dFUCPeuJeQgKoQrVfmXGAI/qeRem5pJMblxcLu7nuP4utKUSmMt5znjJYVk42IzeNlfhSqAw4ezm7nO6EzVR2tgp/hus/se+u+42IZ+uCXOq+OuYV/PzF6pwS5/L2opvmjMa4X+8wZUZzzs5Vdx1xfJSWHivqn4ZPxljDqJocqoc1c5xzljjr2veU8Ufl07x346WpB2B8I7k2bn30Ch+9ODfnP6Y8lxRP08VM5zDKqKX6q2vF3RyqlTGjJ+og1hTzy/vSrf4L78Nv5wqmedWJ6eK/ztKoQpV7lRFc6pM1ifR2JX12zGKRKNMBx1jOQrIqPJhsGhUdbUmPRO5eoIZVeXKiPPr+8nx1jq9bYUHZbky841iZEbJzZeeiievOxtLilL+43mLCx1yG1WyiQCfV6XrqdKdoHlliIuS6pqeKlWtKNkylWcmuI98HpJ82+L2/vPKd+Ghr77fde54T5Xf+eE/SyZMl8dVd54mPnRztqdKboTyNivbP+VUFSZW7LiHit4SIKBOlS2p7uOpssP/Cv8zoQq/8L9kwrS/17HxvCunylb/s1hOVeG3VxYfrnaFPrg9R+XAqxCK9a/EsEj2Pztf/uF/TP0vYedUyV5I3nz/S/jB/S8BKIThsvPlVSdVC1XYIh9hPVWm+z7RaJ5dU2HY2J54E4JAhKSNdGJe+D0eYfFflaR6VDlV/N9GBNNQO6dKUfxXtTxKfQeVwTneAMV/KfzPh0bJl+mNSAGQhbo1ipF5oExPVaMYmVFimgYmdKTx9pGC3EKeK/7LJjSqOlUAMJHLq9LJbVJtR4ZHNZCF/4lCFYr9Bob/cZtJJ0yM5NUTXRUq9T+VUAVQkMZuTSXcRozhrO8nTsN75dIJw3Ud607UxIeVUwyV91Q57WWiFV2enKrGmiTqkjQLQiEjGUd4QnwZ4G7v9lT5hZpZgqdKNIJEWpIJjGRzyIyLOVXut8p2XpAYlivsFwBY1F2U6n/ZHBf+xwrwGgYAy1N7LqXhqeKFKlhOlezZye5xS+dOwGfePZdLutfwVAnXd9iUKP5+0GheKkBt2KjrQ6nD7mTbdcJQZftm21T3zy2Y4e0fv74oGCSvUxXcRnVMYfF6pPSWx5FTJYY9ankQrdKK/8ZRb0tG/c6MK8CBofoWZWD0RWRENIqRyfo/WGY4JDuf3XVuZMYBm0jwOVW2pyolT+gGgIkdvKdKFf5XolEltGMTLF1J9SDvE78s5WME6fZR5Z1SHa4YbsceIn6hRfyhJ03TZVTpehP4h5VlOXV7VOdAFtaYSph2bSR+ebPBvv+RoufJMPzPhS2p7uupKvxm3hxHqML/nsWMrrHxvB3qJ8upUtapssNCnWVRSqrz9xg7rFDwVGUET5VOThUvVGHnVA1nPQnu7Du66LSZOOfEfqdfwrjxq1NltwlpVfHPm0YcK3aolvA1yYr/iu38Jtx6KnNew0ZEx1MlCmbIQhr12vB9U3ZJG3a/Fr11QcvjLP5rKvbNw3svHY9lGE+Ve99xQTNBHxolXyZqI6LejczejoiNzI76vj7iwBWaI0hs+4X/8QqA6vA/PSNIRGU8eXKqFMaEqlaUs8xZyHsBQglVKArm8udK5Xniz4tpONLXvpNy3hBMmq7cUV1jkH/DyauhpQUjL+jv7tbwXrJGg02Wh4ueqlTC9PU02kIVGp4qW/2vaAwEe6qYUZWzJ6G8uh7zQDMDRaX+x66Lf/z1c3j81f2FzyL4ftn+cpw33C7AazheLH45q/mllVOVdnKqcnkLh0bdzwvmTRQVOHVe+ohjK+z5SHHtG035D1BP5GXFf8V2fvLjXo+IrI13myK84abOqVLkS+X59pC3kRiJqmMKi9ojZfguj9IYEb2JqnwuWb/Ll1QnT1XVGGwQZTcn/K88I6LhjMyIwiHrVcQkTpy3yHnXhAyAnafQLTlvfPifaqJRapK2ONlhE1LVG3YRfrHfTV/cZrjwP7kh4vaSydf1hP8Jbxql++PWSZmG6zspJfzPVQxVR1Kd+4cPAWxSm8r+DtmEvSXAAy6G4skKYYvhmSyfSNdTleFyqpIuo6owuXEk1eXGRN6y8PTrg/jxw69g3+FCyNyULndNulJg4z6by3tUw8TiuqL6X8ZP/Y8L/0snTbso+RsHRlztmHdQNKrEe4O0TlWJ9zDGhxdOx+SuFvS2p3Dxkpmh1q0HVCFnsuK/YjtfT5WQNyTPuwo2IlzFfw15IWLRuJO3CQ614/+OIiparFPlyWtSLI+yaK74HalqZMn6bVlU/LduOdAw4W5M7a48I6LeCyEznHDIco2qxjAy44CfeI0LOVUfXTwTeQs496R+z3p8+J9qouEVqtB7N6QSuNCtU+USWwgM/5MbR2H6qFL/U20vKeyT9VfXU1UQqgj2FIrw6n/880r0nIntxX3wYhXNqP4HON/VSLYwsRfz/US8tde87UUjSKdOFeAO/2M5VUnTcHmhszneiJbnJuYtyzZUZvS2Yf2HT8BZx0/13bcO7FjHc074X1K45jOCp4qt4++pYkIVhelRX0cah8fGcd7ND+GTK+Zgw0dOBOAoNLal3edRNFZl51kck2E9EKtPnYHVp84ItU49oTJs3LlMvKdK1sbf26FsY7rbyPB6WoyCYS/xMIkeH3eoovszdm+UtVH1NyxKj5TwgkZU5ovSFFEZnLoeRMvHcFYRhzS8DPJU+dAoNYj6IhaqqHcjIirPXaMYmXHgMqqEnKrOliQuXzEHU7tbPetN6nIr2MnwhNdo3lnFSZ+dUyWqlik9Vf7eIn5ZJOF/KqNKcddOCW3s/BKf88MbOClRqCJk+F/echdD5c+ByiDl/3Z5qprUVcUm/U74n/950BFt4Scj2Zxj+OoIVQBFTxUbwwmn+O8498JE1lc+3Il5dfp7WnHOif2RClWM5y0738kpIyB4qoTwv0MjWTzx6n5pIVBHUr1w/B/gXv48/NLb9t8sp6pV8FR98ORp+NDJ03DGvIn45Io5mF8sts2j481qZtjpEb0KfsV/xTayU8oW2R4R2b7hNWxEnLA993Zlxp3tjZF4oUTjwNmOt42qv6ERDRhhq57lkn6Xi1j8l+3LT1LdkBT/Ffvuh05YZxSQp8qHRhFmiErtrlHOR+Thf3V+PuKATQ7zllodTMZEV50qladKMII0i7ykFBNQMcRKGXboyqmSTV7lnqowXpekwngyA/Yt7tPgPFV+u0+a7j53tIT3sPEeCT78TwxHlP3Nf8fd5KnyhP/51aji2zP8Qs3yluWSEg8T/jfOeapYl/J5C9lx/vtW5FRZlm1UtfrUxgpLyjaqvCHGrCsZIdeMGYp7D4/holu345bLFuMDxdp6QGECy+Tsmafq2g8ej1Un9eOCHz5iG7sAb1S5j6m/pxWbLlvs2/dSFUybBZV3hDdU+PuTJTVmZJ4qZugHe0R0i/8627WkxpAo+MBvVfSqVaL4r+2pUtWKUknB10rxX8u7TIc4PG7S/cS8fS02bdqEOXPmoLW1FcuWLcPjjz+ubHv77bfjPe95D/r6+tDX14eVK1f6ti+HRsupKrdOVeOcj2I4ZETno96NzDjgJwkZ26gKvt1M6gz2VIk30pI9VaxOVVLP88UvDvRUKQQnglCF+alUAXl4L1fCcAqg+k3YxJDFcjxVlmXB4h68/Pft9rTJPXB8AeBmnWSy42aTd78aVYCeaAu7nnN5yxapAIKNqhZe/c+VU+V4qrLcTMtPUt02qgJCDsOQ4ML/2GRW9M6yFzrsmjt+WjcuOm2m/fLmtf3Drm2OZHP2W/COFud6ZHlVw1z9sFGFUIUO4tiqxvVeq/MuQKP4rxmcU+UnVDHu4xHRMSJEgQm/nKooi/9Gk1NV+C2G2onLRYOn6sV/hbwrfj0dKpVTVXWj6u6778batWuxfv16PPnkk1i4cCFWrVqFvXv3Sttv27YNl156Kf7whz9g+/btmDVrFs455xy8+eabkfetUXJmos8hagyj6uBI1hWuFJbBBjkfccBPsMaKuQc6HqUJnKeK5WGIGIbhzj3SnJB4wgaVQhXy9VVha7JlpQpVqNZzh88Fr2sajrHvd32KtbDc6n96fXYUteDjqZL/zRuwXaT+Z3+HzAsS5KnSETxwlNScFxzpAFVBwDGqMjlH/Y+XVC/kVDE5dcOzPSdHw/G8taajM6ocafe8I9Rhe2cLv0VPVcI0cMPFC+18Tr4eGODccwwDaOf6yvKmeE/VaLGIsphTpUO5QhXlUsvzLkBt2PA5VW6BCKeNTvFff5U5r2Ejoq4vJWsjblfdV9PneAzDX3RIF69YhyFdbgj9jtIWCSr+K/cyFn7nSjSqDMn5j4OqG1U33ngjrrzySlxxxRU44YQTcOutt6K9vR0//vGPpe1/+tOf4vOf/zwWLVqEBQsW4Ec/+hHy+Ty2bt0aed8GG0VCnPNUlWdENIZnpret0H/LKsTWl0qljcxafrMowk8a/OSeRfg8jwM+JQBcXhnNCUlKsJZYf3SFKoLympRGVYgbP78PfjUtT5VrXQP/+0PH48aPLcSZ8ycr98evk06YLvW/YWHCqYJ/k8nfX5KucERve0BQ/+M8A80a/mcLVbDwv6T/edCpscYvs1UFA7xUgOMlG8vmubxI06UexpbLvND8dTFavAdE6ania04xYz7BGU8A56kSrifmXRrNuq9xJlLRkU66Jnbt6cK1WfDaFYxJJtJRiqdKtJUr/RKhluddgNqw0SmWq1P8166H5FP818+IsJTGkCVpo+5rucdTCmwzolfIu1zthSsX0eAUpe6lOVXCdwcARggLJg6Pm3Q/sW49gEwmgx07dmDlypX2MtM0sXLlSmzfvl1rG8PDw8hms5gwYYL087GxMRw6dMj1E8Sf3hjER3/4MPYeHgXQAEZEcdJvWcBH/vUhPPDXfaHWf2nvYVx86yN4ed8RAPV/PtJJ046X//htj+I3f94dav03B0fw8du246ldgwAqcz5q/c2iiNuoUhcm9cMvPFMVWuaH6KliBoUYYqXaHv9M84vFB9QiDYF95D1wvEdHYWzx8IIbpmFgZl87Llg807cwNd+3ZMJwJd0fHtV74cDn7PAPS1f/FZ4qfv8kqc7XqSp4TILC/7weD7VxAzgesCCRCsAp0p3JOZ6gpGnY4yifd3K0ZIIa/HVhy4+no5tyuIr/srfuglGV4YoW87QqjSq3SAWD91oNZ8Zd64lCFTpUU6iiEvMuoLS5l90fhWHjkeKWenbcbVzbLV5+/ipzpXuqZP0QjRZeHEWn+K+f560UREl1j6dKsTye4r/++5b1u1RPVRz1tqT7iXfz/rz99tvI5XKYOtUtrzp16lQMDAxobeOrX/0qpk+f7rpB8GzcuBE9PT32z6xZswK3ufmJN/DUrkHkrYJBMjmCmhrVJJUwcczkDgDAX946hJ9sfzXU+r98+i388dUDyOYstKZMzJ7QHkMvK8tx/V0AgJ17DuPHD70Sat0tzw7g0b/tx9h4HgnTwDESdaeoqfU3iyL8JNrxVIW73fiFPrnC1nSNKkVyuG6dqiBZc/7zKDxVqpA51YOEF+LQlUN3Ff8VVjo8Kg+/FHHXD3EeijqKfxT+54Z9hyNZZqyEE6qQFprlljFjIIynqiBU4a1TxXuqZP10JIwtR9QhUk+Vc1y2dLoQTqT0VBWNpJGsPPyPz6cCCueLbXMkk3Otp3MuRTyS6hW83isx7wJKm3sxgor/isIOYYv/+k/e2XaCjSq2utwYUuVLeY9Hp/hvFKF/hX0UfrM8SdFA9S537u9RoS7+Kx+vfBt3TpX+PmVewDioevhfOXzrW9/Cz372M9xzzz1obfXKMwPAtddei4MHD9o/r7/+euB29xfDuj6x/Cj89pozS3oTVWv836tW4EsrjwUQXgVwfzEM64JTZ2Drl9+HnjoPhwSAO644HdeddwIA5/vWhYWlnXPCVNz/5fdiRm9b5P3jqVWPrh+m6QglsJwq8W2xiu9/fBGWzp2Aa1bOV7YpJaeKz8VKmk4OiGdiqnh4BUuqOwvTXNhWKE+VImROT6givHKfyxAUjF7dcc7O46HRLF59u5D4b5oG+NPqCv/jduMWqiD1Pyf8r+ipCpiwezxVMo8Rdy5ZSGeLxjONKeWN8ep/ypwqSX0s9mbZcu4BUT5L+evdkU4v7pt5qhShx46nyp20wzxVnYJRZRiGHQI4nMnZx9OWSpQ02RWv73qSVNeZdwGlzb0Y8nA6r4dC1s6/+G/hdy7C4r+Ac4+3fIw7P8PLDiOU1Mjyk4gvBaVHylQs1zAywxJU/FemlG57qnLe60CHOMIYZVRVUn3SpElIJBLYs2ePa/mePXvQ3+8tDMpzww034Fvf+hZ+//vf45RTTlG2a2lpQUtLOE/TwaLRcersXkyR1NKpR3rb01g6tzChDitYwcKwTprRE7sBUSm6WlNYccxEAM73rcvgSOH8LZjWjaMmdkTeNxG/N4svvPCC1jZ0PLrXX3992X3lSZomMrm8Hf6nO3E4f9EMnL/Iv7BlKTlVbL3xvOVav7Q6VbK3oM7f6RKFKtg5YonY9v5cRpViXe6YdCd6olAFANz+iSW4/4W9uOR0vTfLbBPrfvkXZ7uG49EQj0UVCsiH/zWr+h8zTlhuT7CnSp4nyMOf4xFNVUHAXfxXnlOVd8olSIw5J4SLD/+LXqii0EcWYmwW9134TFT/YzAZdKWnKu2dGrWlEzgyNo6hzLh93ks9HrE/UeXL6FCJeRdQ2tyLEVwEl/32tvMv/ssMfR9Plcm2o558y4r/evshF6rwLf4b8nhKQZW/5FluupdHaYoEFf+V51QV25SohhiHNLx0P/Fu3p90Oo3TTjvNFZLEQpSWL1+uXO873/kOvvnNb2LLli1YsmRJ5P1qFNU/kb6OopR4WCOC1afqqH8PFY9dr2okG8olfKDOBEzi8ugG4bx1K/yOcqLsyqkKcWdl3hh+fXGCqSPlLn8LyhlqZYb/+eVcqDaXdnmqwu0PcPp89glTsfGCk21PRRCqUEgxpIXhMrBUOVVNalQx48RR//M/D956R5KcKm4R226LRr0oR1I9J82pyuVhizXIjDRH/c8J/yslVE6F26gK56mSCVUcGRvHX/ccBuAN/wOADhYymMnZxmkpIhV8/2THEje1Ou/iYWdDKS1ebOHXTnafZIt0iv/qeKrs8D9hubSNj/dN7Kv0eNTdCYVowIjn0rM8Tk8V65On+K/kpSUEbxa3TIem8FQBwNq1a3H55ZdjyZIlWLp0KW666SYMDQ3hiiuuAAB84hOfwIwZM7Bx40YAwLe//W2sW7cOd911F+bMmWPHAHd2dqKzM5rclkZRuRPhi97m85b2xOXAUGMWuWUCHrm8hUOj464aPX5UughyrXp0gygYLnnh/2hwpJPDhtcZrt+AnoIaEOyp4ldziUaEOGxm9HneZLuMKnn/SgmJdBtVpT22VW8VbQPR81Zevn8q/ut8h9rFfxWKljz8tcqMiDCeKj6nKmHy4X95jPt6qpzJqVP8N8o6VZxRlXXnYjhCFXlPW8BrVFmWhQ/94L/x2juF8NXOFm8/27jwv3SyMDHTMU5lVLtOVS3Ou3j8CuUCjupbWM8On+fH/+9uU9yORvFfx2Bi17rMYBK8UJJj8rSJ0VMlhvOJtaKUUvBRenjYMXHRDO59qz2I+XJzqkJ2NSxVz6m65JJLcMMNN2DdunVYtGgRnn76aWzZssUOddq1axd273bU2W655RZkMhlcdNFFmDZtmv1zww03RNanA/akuT48EbowIyJv6SehA5U3IipFayphP1wHQ4REOkZmZa6PenizKMP7Fj1CTxUzjkJuk+VhJH2MCdV8M0iowpVTVaqnKuF+yDDC5lRph/8pvGthUHmqRNEA/jPZ37xRlYv5bSJj48aNOP3009HV1YUpU6Zg9erV2LlzZ0X2LYO9eBjO6qn/qWqvuZZJwv90jAHeqGJvkFMJd/HfjEZOVd6ybOGNUj07MvgcSVFhlF2TTq6V+7ww44550EayOdugOnpyBy5YPNOzv3auVhVbLypPVaWNqlqcd/H45UoVPld7UXwn5p58Itm+g40Ib9ierB86bYKV9vw8b6UgngNPrSjF8igFHrwqjmKfgvvNL9MhjuOQUXVPFQCsWbMGa9askX62bds21/+vvvpqrH0ZG8/ZybyN5plpSSbQnk5gOJPD4EhGOxG93sLdwtDXnsLIwRwODGdx1ES9daphZNb6m0UZosFTqifEb9th394xdTXea+ZR/1Nsk18s987IDbVScqpEQ8ydhyRf111sV29/oqR6KUiNKsPg3kKKnirD1Y7RyYX/DSkKP0fNAw88gKuvvhqnn346xsfH8fWvfx3nnHMOnnvuOXR0xJ8vKWKH/2WKRXrDClXIPFXcsmE7DC+cUEWWy6myjSW+TpU0/A92uzg8VYX9FnIkZUV+ASenKkiogi/6+/svvVfq/XaMqnEAhb9LNqqq7KkCamveJSIzbPi5sCPs4HhDxXZyg0m+H+m+FZNvuWCG18Ok8vjIc6rcv6VtIrpGxH6o+ufxVEVoi6hyqvzz4bzbCfP4r1Tx35owqmoJFvqXMA10tzbe6elrT2M4M6JtRIxmnbdyjWZkAoVjeuvgaCjxjgNVCA+95JJLsG/fPqxbtw4DAwNYtGiR582iyRkK/JtFnvXr12PDhg0V6XOcb2MTptfjpLVewj3pArx5Hqp+umtF+d/02WTYMMJJ4SaFRHt72zqeKu771zU2XR67EsMzpQU0TUf9UZxAuoxThRJgpYyqLVu2uP6/4447MGXKFOzYsQNnnnlmRfrA44T/FY4/rFCFOnS1GIZXglAF76lKmoY9hsY59b90QPjfWAx1qgr9KYQYs5wqO/yPeaoUkuq2UEXxfAwXhUHaUwnl5JX3VLHNlS5U4f6/WYVZVMjkr2WeKr920nu0J6xatm8Utynvm1www9tH0UAQQw/5fvtJxMdV/JchGjaq5XEW//W+ePOuI36fYZ+tsu8oDhrPaigTNrnuaUtFVhegluhtT+HNwRFtI6LhjUxbvEPvfLiMzAoLd9Tym0UZOoVJS8X2VIWcjDDDIeWTU6UWqvD3BMmEKsLmBjFPhXhcOkIVfB6X7iSNL5Za6ptQlYHJ573xqML/3OtX59578OBBAAgsajo2Nmb/X275AR67+G9WL6cqYRr45Io5+N1ze9CaMrFaoZqZMA3kc1bJQhUs5MadU2UhaxtbsqLDxXZWPHWqAGe8jAlhfqw72XHL1Y7BjCEWNjiUkden4mGS6iOZnH1sumIuIp4XTg041ygHZyLvLHMJVXiMGW87Hc9GKcV/3f0QjSFvO52+etvIwgil3QmNKnIgaHmUHh7R4AzjQfRr40ccxyGj8WbJZVLpfJlKw45L14hg8uENa2S2MfEOPUXEgyOOkdnl8wAmajWnyuup0pVUd4f/+Xuq2GQ4rKHCy5C7tq3hqUppGF6e/RUblhOaqQz/M7znWmwvTia//sEFeOild3Dewmkl96dU8vk8rrnmGpxxxhk46aSTlO3iKD/AYN8Dm3SkksHfy4aPnIgNHznRt03h3m05dap0iv+6PFUsd8r5XsfzFrJFY0YcQ4A7h4GF2enUxwoDM+aYccS/JACAMVXx35Sj5Ac4EvZ+RhUzxIYy4/Z+SvVUiZLtfvttRuS5Rd7Pwxb/1fGIBHk03B6z4m/f+lKiceKXd+VnnEXz/BSP2RCOwbNc4g0sF09hZKFTQZEgsv+DiOM4ZNBIFjg40piiDAwWwseMxyCaxcjULYhsy+03qJEZJaLBE6VssJM7Ec77lbQ9VXxOlZ7xp6qvxOCvBxZeFfaQU8KkkBF38d9SQ/8K+5IsM/k6VeID092O57NnHoPPnnlMyX0ph6uvvhrPPvssHnroId921157LdauXWv/f+jQIcyapVfTKwjxe9cJ09PabvGkM49RUK4W4BhemZy7ThV/LdpCFT65XDkupypKoQrAGRcs50vMtcwGFP8dyeZgWZbtqWr3MZLaOUPMrlNVovrfrAntuP4jJ+KFgUPobkvho6f61+VrNsRyHIB+8V+VTDnfXtyOe9/uFxsilsS4k4chuts4eUMyw4vtO7hNuYT3VLn7EQXiMclC+0T8SnPoYHs/Y3ZVkVEl0MiiDIBzXNqeqgZV/mPwMvM6NLqRGSUewyBCoYqEbXyEWy8l81QJBoUy/I83bKSx+Nw22X5C3viZkSg+MIJCDwH3+dV9ALPzUM53IztG0zCUD0w/T1W1WLNmDe677z48+OCDmDnTq/zGE0f5AYYYRleqIqMI+55HQwlVFL1A2bwd/sfnVPHbk/WTf+tuh/+VaISo8KgfCt7RjLL4b8LuWzZn2TlVvuF/LbykOjOqSjcSL18xp+R1Gx0/I6XwudgOnnalhpCF81SJRpXTTlX8Vy6qIXre1G3KxXs/ViyvYPFfHS+UN+cr3D4p/K9KNGrhXwZf8FaHRjcyw3qqGt3IjJJ4c6q8RXy11mOS6rxXp5gnwueNyHAbNv7hCenipDVs+F9SYYwFiWQAYvFfTU+VHf5X+nejCtVwwv/k+wTkEuCVxLIsfOELX8A999yDbdu2Ye7cuVXtj+g1jcqoYqechbvpeKrSnKcqJ8mpAhxjSWaUs2s2b1l2Hamo1f88+ZCme/yo1f+c9UayOVsYpcPPU8UJVTCDs7XE8D/CH/Zt8fNf3sCyc5nsz7h2UHuq9O42/kaEq14WM0iK/8uMIbsN81RxW/bUu4KsTZi+B6PKKxO37yn+G6E1Ih6TWMQ3KBJEtk4QTp4eeaoqymDDGxHF8L+w4W4NakSE9lQNN2Yh5DgQQ/PiyKkKa6exyZVX7t3EeN5d60aEX+wXNlLYntcjpoMqp8od/idfVydEUIT1uZzJu6w/Q5mcMvyvljxVV199Ne666y788pe/RFdXl116oKenB21tbRXvjzhmoipDwL4LW6hCK/yvYDDwxX+TXE4V4EiSy8IUWbNsLm97jKIO/1PlbbLrWlWnKp0wYRqOMqEd/ucrVOFIqjOjLGrhDaKAX64Uf8uQtivKsOtMzMv1VIkGk7y+lPs+6M6XgrxNnm9ToZwqRQiezAtXLrYXT5VDHGNOVdxUvfhvrXFgqNGNiFLD/xrTyGTqf7pqiI1aGDoOKpFTFdZTxYwHvxpaep4q7+f8PZu95Q+t/idMCu39hc6pCre/qIUqDg5n1XWqFDLq1eCWW27BwYMH8b73vc9V1PTuu++uSn/E70HH+NGBfQd28V8NY4BdwyPZnD35Swo5VWN+niphn0AMdaoURpXoqRKvM8MwHLGKrFObsjPtI1SRcjxVzJgsVaiC8Mc2bHzkxwE9gQj3dkWjSrZvr2HDIxPM0BOh8OursG9Zm4hm60G5U6rlceRUBRl0sv6o/g+CPFVVwvFENOakuc/2VJFnBggv3GEbmR2NeT6ixB2yFj4UTmfbYSfltmqgMAnkw6FUhlBwnSreU1Wa+p+qqLGOF8pV/Fdzv05OVRmeKsmqmVzePo/i550tSXzo5GlIJYzIJ9lhiVsJKizi9RxV+J9tVIUQqmDep2HOKEpwAiSAXk7VELd+VEYiw1OnS8ipsqXWJWOmNZXAUNFAYsV/21vU1yPLtxrJ5GIT3iAK+OdKeduVXPxXJrAiyefi0S3+q8qp8sv/Ym11c8RKQTunymPoRbJ717aCamTxeMMWw+2TcqqqRKPnzNg5RGGNiAY9H6WH/zWm0R0lvCEQtfw881CF9wTJc7FSrhwr+bqG62Hu/ZxfVmqdqgRbT/RUcdtRbTJVQk4Vaxd1ThW/bZlq06bLFpe8v0ZG/B6iE6oo/A4V/lcMcRvmCjEnTQOGUTCsCqp+TGpdYlQVr2G2fkvSjPTFChAc/ud4qrz94xUAh+2cqmBJ9eHsOEayhXZkVMWDn8eGv9/IBS3U4XJe6W7vvh2PhrxvMsEMefifu4+1Uvw3yCMlLo/Dw1NK8V9vxEO48xGHx026n1i3Xoc4OUSNOWlmnpmDmkIVgw1uRPS2FY5rKJOz4+/9sM9HW2MamVHC3/SOn9Yd6bZl9aZ0SCnqW/GTQh1PVVBoiR3+F7Z/pvzNXVLDC+XyVGk+gNl2ywn/U50vNo+tdt5UPeG5LiMP/yvWiwrjqco6niZRSGV0nHmqZOOh8JvlK8XhlRT3a4ujFBc7OVXedVle1EgmZ3vT/DxVTFJ9eCxnhzSSUEU8yAwbmbS4bjuxPcPvPh6m+K9/fSm2XXVfvW38c8nKQSVNHrQ82pwqd1/Edx6lKjf6EcdxSPcT7+brD2ZsNK5npmBEHBkb1zIiGt3I7G5L2TcrVujYj0bPMYsSfoJ44vSeSLddevgfU/9zr+cK/ytR/Y9/M8reYOuEWfGIOSHyfcvX5b1vuqclCk+Val+z+tphGoWaPIQeXkGFqN5OF42gMHWqitcwPwmxPcRM+CLDcqq822PXMAsfjMOrI3qcRXEUNiGVeaqY52l03FH/6/QVqnAk1Zkx2RpxOCNRgL04cntsip9J7sPSdj6hfc7/sn2juE1532RGmzy3y71Prbwr0zvx98sRKwWV4IPXsHH3LZ6cKn+DTtYf1f9ByDyFcUDhfxyWZXHqf41pVHW3psBUjwZHMpjS1erbvtHPR8I00NOWwuBwFoPD2cDz0ehqiFHCTxBPmB6xp6pEo4p5glThf4bhF87m/C1PpHX+PmVmDy5bNhtL504I1T9b1VDYQZCXjF/Xr40ImwuXIyKiOl+zJrTjwa+8HxM74qnp1IjEFf7HLvfhDAvF0xCqkOZJFX6z62V0PDj8jxksUdeoAiR1qhRCL7LTyIy8Ud5T5RP+x7xYw5lx25gkoYp4kOcWSYQqpJ6d4oTdZ7vO/2rDS51T5V1Xto43tA+eNt4wOPXxRBU5q1JAVC2PR6iC7UPeJ3lYZrDh5YfMUxgH9JqF4/DYuF2rplE9M2bRiACAy25/DL965i1puyd3HcDqTQ9jf4PnVAHOsf39T3bgrsd2Sdu8MHAIF93yCF57Z7iwTkdjXh9Rwj90TozYqErYuVFhPVWG6zcjLYQ1yXCrTvm/BU0nTPzzR0/G+YtmhOufKRe44I9T1UVXnSptoYrCOuV5qtT7mtnXThPPEIjXZWQ5VYLnJkxOld23Yj4V4FxftlCFz3iwQ+Vi8VTJjSpvnTd1TtXoOJ9TpVenioQq4oXVIJKGwUnayYQdZJNusbaR7M7FlgWF//GbZ3/KjEDWzq+wr9NXnzYRVaryCD4Ivz3tmDEYyd4LiIavuG+d0M2wZyMOj5t0P7Fuvc4YLIo3tKbMqqtSxclx/V0AgBf3HsG//fffpG1+/sfX8fTrg7AsYGJHGhM7G9eoOm5q4Xy88vYQ/s+DL0vb3PPUm3jitQMYz1toTycwo7fyNWzqjYGDo/bf86Z0RrrtVMI9udMlIYQvOdsLVusLCsEL8mTp4Kj/qfeteriWIqnuFP8t/YEdsfZAUyO+vJoQkcqoaPiGyali8AYfu06ZpLos98vJqYrRqFKo/3k8VZIBaQtVZPJ2Hzv8wv9Shc/G8xYOj8aXJ0ZwnipumVgol/9bVvxXa2LutThwMwAAIS9JREFUE8atmnp7DaEggwmu/vgV/5W3kfe9VFSCD2qpdcdwjUwtVQjR1MmXikpSPW7FVwr/45jS3YLNn1vukpBtRH50+en4vzvewPpf/UVZBHh/sV7XFWfMwVXvOyayN6a1yE0fX4Tf/Hk31v78Gfu4RZjB/bElM3HNymPR1UqeqiB27jls/x319WNLgZcoVJFShP/5eaqCQvCc+PDSCzWqcsXcoX3ydcsK/ytLUt3Z1//+4PH45988j78/8+iSt9fMrDx+Kv75oyfh7cMZzJrQFpmHVzQyRC+UDI9RxY0ZsZiwbByya3A4E2P4n6iSycRRhF3J6mjx6n8sRLHDR6iC97i+U3xOkFEVD37Ff2U1+3SL/+pN3tl2/D1Vrpwqw/2Zu53bcJAV//W0kRT/jSunyjHojMDllhWNcefNqRL7pP5eVP8HYRuH4VYLDRlVHK2pBE6fEy4Hoh7pbEnijHmTAKjrVQ0WBTsWz+4LzDOqd1pTCZx57GQAwOHRcYzn8p5JJjtPJ8/sxXTyUlWdUnOq7ER7McxKQ61P9oaUx1YeK8N1M2dSBwBgtiDuECSSAbgNRd0HH/PcyfJndOH7c9qcPrzwzXNpslki6aSJy5YdFfl2xZcF6UTw92OaBtIJExlJAV07p0pDUj2bK0xjYhGqUBh+fkIvjLaikTeazdmGn19OVTppIpUw7OMBKKcqLvicKsuyYBiGdvFfPwlynYl5kEqcfk6V+zPnmPxyqrzbqZXiv6wvZgRhiOJxq2pkyfrDCPvikjWn8D8iFph6HTMiRBq9PpUIk1YH5HLzjmAHeah0+dDJ0wAA16ycH/m22WSqVEl1MQcknZA/WHiCDBvxwVgKx07twkNffT9u/Ngi1/KwQhW654VNjqMK/+tsSZJBVYOIl4yOpwpwqwS6ClCLOVU+ohaMSuRUsYmnX04iwxaqyOYwNFY4Dj/1P34d1f9ENIjeEcC/+K88p0qyXc/1ovZmBeVUyVUIZe1Yf7xeKNHwcib+6jblErb4L788KpEHVdFjZ9/eYxUXhTUyK1X8l4yqJqWHMyIGJUZEsxW5TSZMdLUWHqiykMgDTWZkRsG3LzoFd35qKb7wdzEYVYqE9CBmFj1AM/rc3saUhpGmW6eqHE8VUBB3ECWv+W0airt2UsPwEnn/gsk4dXYvzj81nKAGD7+vdnpzX5OI16ROTpXYTu6pYpLq3utN3GdFhCoM+X1BNnlm/Rkay9lhjEHXr+jJIqMqHkzXRN5y/ZbnMqnD7nj0VObYduR9kxltMi+IKJihU9BYt+hxOeh4pFTLo/LyWAoPnaqP8jbhzkccKoYyKPyvSUkmTHS3JnFodByDwxlM6nRkjwvS8kUjIqJE6Xqgrz2Nw8XzIdJsRmYUdLYk8d5iWGXUlFqn6n8snY1FM3tx/LQu13Ido4q/h/slQcdR7JbfpuphYhiGHZ6ke1rmTenCPZ8/o6y+8Q+pDp/wKaJ6iNeMbv00vp2rQLYgqS4LHxUngRURqlDlJPoYVfuHxuxlfkIVgNfo0jVOiXDwL47ytqfKL5fJ217mydCSVDfj8VTJ+yq0kdTIknnoykFZ5NdULJd4DcvFY3AK35U8p6pco8rr1YwDuiM0McxgGhQ8M0OZnB033kzhbuxYRU+VZVk4OEKeqlqCTZJkb8j9SJgGTp7Z45mM2ep/fkIVkjekPGIIR5ToCFUATk5JVG81dWB5NYBTy4eoLTxCFRp1qgB1UWz2NysgL/VUeYyq6KcbvKfIMJz+6oR5MaOKiU4kTCPQSOKv75akGVp9lNBD5qnSL/7rl1Ol4xFh25H3TfSyAI5R4J9TZXjaqIQq5HlXcXmqgpZ7v4tyEY9JVSNL1h9G2NNBxX+J2OltT+O1d4Y9RsSB4kMmnTSbKryBFfQVxTvcRiYZVbVAUsMICkM6Gez5CpJUL9V7poOOUAVQnNxm4/GWqWChU0B5ghdEfIg2j66nqkWRUyXWfdLJqYrjWXLZu2bjnaExDGdyeNfRE+3wPPH6l+dUFfr89pHC/b49nQh8GcFk1QESqYgT/uuyPJ4q731YZoTIvkktT1VgTpV3Xb+wPW++lMwAdPfPr025hC3+yy+Ozqhi+3Dvy+mjdx0dw8sPmacwDsioamIcz4zbiOBFGSr5xrvasPMhhv8xI7MladKDtEZgYThR5fDoeKpkUr6uz1n4XwxGVVJT2S9t19uKvAtKxjijqpnuF/VEKXWqAHedrB4uakE0UmRCJ6IXJ47wv2Mmd+L7Hz81cN+yMcnu5e8cKYT/6YSunjq7F4+/uh8AsHBmb9juEprwtficnCp1O1m4nE7xX/m+3fsVkRX/ZYQt/stEK/yK/zpFj6O5t4r9tvunaMe3j8oeEetziftWPUINgy+GHA6ZURsHZFQ1MUzxTjQiBouhbr1tzeWVYZ4qMRxykPKpao7zTpmONw6M4OLTZkayvbRGTpVMdYpHFoMeFbyRFOipQmWNm0av69cIuF8I6Nd3++b5J+G+P+2GBeCDJ/fby1XFs137rED4nwrRU+VX/JfVJvSrUcX42gcW4H8tPwq5vIWZfe2B7YnSkE3kbY+N6W3nKv7r49nxKMj53MdVU29Z8V9ZTpW6+C/XBpa8jSSMMKpbujKnSmO55RWKLglVaKSqj/zyXInhkHE8l2WQUdXEOOFuQvhfkxoRvYqcKlL+qz0mdKTx9Q8eH9n2dOpUdaSTWNDfBdMwpBPEqNT/ZOhIqgOOR6tSDxDAHf5H1Cb8JZlOmtpG9/ypXfjS2V2e5V4hCO94EO2sSoaShyn+O16cCQeJVACFiSYZU/EjV//zfibPqfK2k2238L9s3852WI0sHv3iv+59ykME5W1kHq/4c6rk5ybOnKowxX9Zu5zdJtw+ZUqRcUBGVRPTZ3tmxPC/5jQiVOeDGVXNZmQ2E074n7qNaRq47wvvhmEYvhXf4zBokoKnQUVKo95W1JBRVfvwRpCuSIXu9gAnJ5HHE3JYQaPKI1QhGZOikUflAGoHV05V0TuiW/zXzwgRbX+/OlWFfXon7/rFf9398Mv/Ep8d0uOJyNGrkzsl67fYr3Iopfiv065UT5V733FBRlUT09fBwv9EoYqs6/NmoVeRY8aKATebkdlMsOK/QV4mUTWQx34IxRDlxD9A/LwMbMIs8xzExSgZVTXP1O5W++9pPa0+LfUQwwdl15s3/K+CnioNoQqxP1QOoHbw81TxX23o4r+KEDe/fZtC9o7MaJPmS9Vo8V8djxS/vFaK/4rtarX4L91FmhiV2p3jmWkuI6JPkVPFjMxmOx/NhI5QRRBs1TiU95ywPv92n373XPzu+T04dXZv5H1QMUI5VTXP+g+fiPcfNwXj+TyWzZ1Y9vZ0cqpET1B3a+WmG2L/ZB4JsX864X9EZZApzvkbMzLPjvc71/GIyGpk8ciNO/e+3e38wv+EMDhJjay4i//q1IoyjcLxWBF5eTyqhx7Psnw9XRVc+brufccF3UWaGEftThRmyLg+bxb6AozMZjsfzYRO8d8gTOHBGCXsgRf0IPnY6bPwsdNnRb5/P849qR8v3v8SjpncUdH9Evr0tKXw4YXTI9ue16jyXpfvnj8Jnz3zaOw5NIr+7lasOGZSZPsPQhwnck+VexapI1RBVIZCiHXBSxO2+K/j2fFuN4ykOr9PnmiL/0LaRuZ5i6v4r45YhGkYyFtW5J6q8DlVehEbMmSewjggo6qJURsRzemZ4YUq+ATVZs0xayZ0hCqCYIZPHJ6qrtYUkqZRk3l9a/5uHo6d2oUVx5TvASHqA6+kutdT1ZpKRComEwYdT5UY/tdO4X81BVN6Y54F3eK/vjlVIYQq+H3yRFv8V8y7Cnc8peDNnXL/Fpc7+7aqWvy30E7ePx2C6o9FBd1FmhgyItz0FWuyZMbzGMnm7Idss6ohNhPphPuhVgpxqv/1tKVwxxVL0VXBECpdWpKJSL0gRO3jUf+TeKqqiWhEyTxV/T2tmD+lEy/uPYJ0wsTyo+mlQC3BlN5ET5UYlgYoiv9qeKp0cqpEZCqEjhdEbQw5+VIyMQtotykXlUfKY9iY/PF5+1UOQcV/4wz/izunqoIlItVs2rQJc+bMQWtrK5YtW4bHH3/ct/3mzZuxYMECtLa24uSTT8ZvfvObCvW0sWCeqMx4HqNZxyc6ONKcRkRHOmE/fPmQSOd8NJeR2UxEEf4XZ50qoBBOtXBWbyzbJogweNT/fARcqoE4jGXe41TCxP+75kz8ecM5+NOGc7DyhKkV6l1tUOvzLqewryBUIbTiP3O3k92HZWurkRpVko6wP/nWYYr/skZ+xYzDl7uVIw4Fu39iO0mbqJw8QcV/VY9QQ3LOdXGOIV6rqup3wrvvvhtr167F+vXr8eSTT2LhwoVYtWoV9u7dK23/yCOP4NJLL8WnP/1pPPXUU1i9ejVWr16NZ599tsI9r3860gk7Fp4PATww1Jw5RIZhSMU7mjXHrJlgcsrlFCh1km6j6BFB1C4J4SL3U8WsBlO63AqHk7tapO1M00BXa6qiyoS1QD3Mu+xJcPF/WfFfMQeJnzBHkVMlm35bknblFv+VheB5wx4lnSmBsMV/+c+iM6r0981TnqeqeAyh1gpP1e+EN954I6688kpcccUVOOGEE3Drrbeivb0dP/7xj6Xtv//97+Pcc8/FP/zDP+D444/HN7/5TSxevBj/+q//WuGe1z8yI2I8l8eh0XEAzemZkYl3MCOzGc9Hs/Ce+ZPxP981G1e/f17J27DD/2LyVBFEreDNqaqta/7vFkzBbf/rNGy84GT89DPLMH+qt4BxM1MP8y7bUMnr51Txk36tnCrJDFhWI4vHTzAjfE6VvA2/frWL//KfxZdTJfZJZVQ5f4c9HU1R/DeTyWDHjh249tpr7WWmaWLlypXYvn27dJ3t27dj7dq1rmWrVq3CvffeK20/NjaGsbEx+/9Dhw6V3/EGoq89hX2Hx3DVfzyJ9nQCOe5VS29b83lmWB7ZV37xJzt/hRmZ1fZUbdq0Cd/97ncxMDCAhQsX4uabb8bSpUuV7Tdv3ozrrrsOr776KubPn49vf/vb+OAHP1jBHtcPHS1J/NPqk8vahkoeliAaDR1J9WqSMA2cc2J/tbtRk1Ri3gWUP/dil9jlP34c6aSJw8XnsMuDUrzsbr7/RfzHo68FG1Vi8d8Aw+vCWx/xvEAYyox72rG//8+Df8MvdrwBAMjk8q7PWPMdrx3AuTc9CAB448CI61j5bX7g+/8Nw3BeeFer+C//2afu+CPSyfI78re3h4r78O6LXy4i857pUqmcqqoaVW+//TZyuRymTnXHMk+dOhUvvPCCdJ2BgQFp+4GBAWn7jRs34vrrr4+mww3Icf3d+OueI9i1f9i1/JjJHTUX0lEJjuvvwuOv7sebgyOu5VO6WqrqqWLhGrfeeiuWLVuGm266CatWrcLOnTsxZcoUT3sWrrFx40acd955uOuuu7B69Wo8+eSTOOmkk6pwBI3PzL52AMDsCe1V7glBxAt/jfd3t9ZcThWhphLzLqD8udesCe14YeCwPQG3l/e1udoAwJ5DY9hzyDHg+tpTaJdI5M/qc9+bZ/Z579WGAczobcObgyN4ae8RZf/4dVk/9h0ew77DTj+6WpLoKb6cZm2GMzm8MHBY2q/2lgQmdKSxfyiDnXvkbcpF3A77f0JHGh3pBIaKdQdnTXDO8+wJ7fjLW4c830W5sHPY31O4hzBDdJbiGTp7Qrt9fvn+6VAp9T/Dijtry4e33noLM2bMwCOPPILly5fby7/yla/ggQcewGOPPeZZJ51O484778Sll15qL/vhD3+I66+/Hnv27PG0l70tmTVrFg4ePIju7u6Ij6j+GM3m8OSuAx7t/pNmdDdluFtmPI+ndh1ANuceFgumdWFSpzwuP2oOHTqEnp4e1zW6bNkynH766Xa4RT6fx6xZs/CFL3wBX/va1zzbuOSSSzA0NIT77rvPXvaud70LixYtwq233lpSH4hgXnl7CNN6WpsuR6MaRHmNhvUCx9WPeiGXt/DUrgMYzeZx/LQuTKzQvZEIj3h9VmLeBZQ/9zo4ksWf3zjoWmaawOLZffb9dTyXx5O7BpEZd09gju3v9OTVMV7edwS7B0cxpbsFxyrCQg8MZfCXt9SeNdMATp3dh7ZiLi4/HnjmT+3E1G6nH3/dcxh7OeMPACZ1pbGg3zkf+w6PYadgdKWTJhbP7o3sRfdLe49g4OAo+ntaMG+Kcw4GDo7ipb1H0NWaxCkze2zP0KHRLP70+kHV5kpiem8rjp7caf//xoFhvPr2MHrbUzhxerc0r+rI2DieeX0QCdPA4tl9obxmbw2O4G/7hjznmxHVfbyqnqpJkyYhkUh4BuWePXvQ3y933ff394dq39LSgpYWuuGraE0lKlqUsdZJJ00sqzFpXQqTrR/mTqICuPVGWC8wUQivWzJnQrW7QZRAJeZdQPlzr562FN49339ukkyYWDo33HV4zOROHMNN5mX0daQD982jOx6OndqlNOQYk7talMIqUTFvSifmTfGeg/6eVvT3eI3R7tbg76JcZva1Sz2HPJ0tSZwxr7R+TO9tw/TecN6tUqiqzz6dTuO0007D1q1b7WX5fB5bt251vUHhWb58uas9APzud79TtieIescvXEMVflFKmGxPT4/9M2vWrGg6TxA1TtikfYKoZ2jeRRDxUfVA6LVr1+L222/HnXfeieeffx5XXXUVhoaGcMUVVwAAPvGJT7je0H/xi1/Eli1b8L3vfQ8vvPACNmzYgCeeeAJr1qyp1iEQRN1z7bXX4uDBg/bP66+/Xu0uEUTsMC/wypUr7WVBXuCxsTEcOnTI9UMQ9QTNuwgiHqoa/gcUcj/27duHdevWYWBgAIsWLcKWLVvst+y7du2CycmerFixAnfddRe+8Y1v4Otf/zrmz5+Pe++9l5LviYaFwmQJIh5KSdon8SOi3qF5F0HEQ1WFKqpBMyYVE/WFSqhi6dKluPnmmwEUwjVmz56NNWvWKIUqhoeH8etf/9petmLFCpxyyikkVEE0BFFco6Uk7ZP4EVFP1Mq9vFb6QRAyGkKogiAIPdauXYvLL78cS5YswdKlS3HTTTd5wjVmzJiBjRs3AiiEa7z3ve/F9773PXzoQx/Cz372MzzxxBO47bbbqnkYBFFTlOIFJq8uQRAEIaPqOVUEQQRzySWX4IYbbsC6deuwaNEiPP30055wjd27d9vtWbjGbbfdhoULF+IXv/gFhWsQhEApSfsEQRAEIYM8VQRRJ6xZs0aZGLxt2zbPsosvvhgXX3xxzL0iiPomyAtMEARBEDo0nVHFUshIsYmoVdi1Wc10RxonRK0T1TgJStoPgsYKUcvUwvOE3z+NE6IWiWqcNJ1QxRtvvEE1eIi64PXXX8fMmTOrsm8aJ0S9UM1xAtBYIeoDGicEEUy546TpjKp8Po+33noLXV1dMAzD8zlTcnr99ddJoUYTOmeloTpvlmXh8OHDmD59ukvWtpLQOIkeOmelUcvjBPAfK/Sdlwadt/DQOGk+6LyFJ+5x0nThf6Zpalmh3d3ddJGGhM5ZacjOW09PT5V6U4DGSXzQOSuNWhwngN5Yoe+8NOi8hYfGSfNB5y08cY0TUv8jCIIgCIIgCIIoAzKqCIIgCIIgCIIgyoCMKoGWlhasX7+eijuGgM5ZadTzeavnvlcLOmelUc/nrZ77Xk3ovIWnns9ZPfe9mtB5C0/c56zphCoIgiAIgiAIgiCihDxVBEEQBEEQBEEQZUBGFUEQBEEQBEEQRBmQUUUQBEEQBEEQBFEGZFQRBEEQBEEQBEGUARlVHJs2bcKcOXPQ2tqKZcuW4fHHH692l2qKDRs2wDAM18+CBQvsz0dHR3H11Vdj4sSJ6OzsxIUXXog9e/ZUsceV58EHH8SHP/xhTJ8+HYZh4N5773V9blkW1q1bh2nTpqGtrQ0rV67Eiy++6Gqzf/9+XHbZZeju7kZvby8+/elP48iRIxU8imBorKihcRIMjROCxkkwNE4IGid61MpYIaOqyN133421a9di/fr1ePLJJ7Fw4UKsWrUKe/furXbXaooTTzwRu3fvtn8eeugh+7MvfelL+PWvf43NmzfjgQcewFtvvYULLrigir2tPENDQ1i4cCE2bdok/fw73/kOfvCDH+DWW2/FY489ho6ODqxatQqjo6N2m8suuwx/+ctf8Lvf/Q733XcfHnzwQXz2s5+t1CEEQmMlGBon/tA4IQAaJ0HQOCEAGic61MxYsQjLsixr6dKl1tVXX23/n8vlrOnTp1sbN26sYq9qi/Xr11sLFy6UfjY4OGilUilr8+bN9rLnn3/eAmBt3769Qj2sLQBY99xzj/1/Pp+3+vv7re9+97v2ssHBQaulpcX6z//8T8uyLOu5556zAFh//OMf7Tb/9V//ZRmGYb355psV67sfNFb8oXESDhonzQmNk3DQOGlOaJyEp5pjhTxVADKZDHbs2IGVK1fay0zTxMqVK7F9+/Yq9qz2ePHFFzF9+nQcffTRuOyyy7Br1y4AwI4dO5DNZl3ncMGCBZg9ezadwyKvvPIKBgYGXOeop6cHy5Yts8/R9u3b0dvbiyVLlthtVq5cCdM08dhjj1W8zyI0VvSgcVI6NE6aBxonpUPjpHmgcVIelRwrZFQBePvtt5HL5TB16lTX8qlTp2JgYKBKvao9li1bhjvuuANbtmzBLbfcgldeeQXvec97cPjwYQwMDCCdTqO3t9e1Dp1DB3Ye/K6zgYEBTJkyxfV5MpnEhAkTauI80lgJhsZJedA4aQ5onJQHjZPmgMZJ+VRyrCTL7CvRRHzgAx+w/z7llFOwbNkyHHXUUfj5z3+Otra2KvaMIGoHGicEEQyNE4IIhsZJfUGeKgCTJk1CIpHwKKbs2bMH/f39VepV7dPb24tjjz0WL730Evr7+5HJZDA4OOhqQ+fQgZ0Hv+usv7/fk6A7Pj6O/fv318R5pLESHhon4aBx0pzQOAkHjZPmhMZJeCo5VsioApBOp3Haaadh69at9rJ8Po+tW7di+fLlVexZbXPkyBG8/PLLmDZtGk477TSkUinXOdy5cyd27dpF57DI3Llz0d/f7zpHhw4dwmOPPWafo+XLl2NwcBA7duyw29x///3I5/NYtmxZxfssQmMlPDROwkHjpDmhcRIOGifNCY2T8FR0rJSvs9EY/OxnP7NaWlqsO+64w3ruueesz372s1Zvb681MDBQ7a7VDF/+8petbdu2Wa+88or18MMPWytXrrQmTZpk7d2717Isy/rc5z5nzZ4927r//vutJ554wlq+fLm1fPnyKve6shw+fNh66qmnrKeeesoCYN14443WU089Zb322muWZVnWt771Lau3t9f65S9/af3pT3+yzj//fGvu3LnWyMiIvY1zzz3XOvXUU63HHnvMeuihh6z58+dbl156abUOyQONFX9onARD44SgcRIMjROCxoketTJWyKjiuPnmm63Zs2db6XTaWrp0qfXoo49Wu0s1xSWXXGJNmzbNSqfT1owZM6xLLrnEeumll+zPR0ZGrM9//vNWX1+f1d7ebn30ox+1du/eXcUeV54//OEPFgDPz+WXX25ZVkHa87rrrrOmTp1qtbS0WGeddZa1c+dO1zbeeecd69JLL7U6Ozut7u5u64orrrAOHz5chaNRQ2NFDY2TYGicEDROgqFxQtA40aNWxophWZYV2pdGEARBEARBEARBAKCcKoIgCIIgCIIgiLIgo4ogCIIgCIIgCKIMyKgiCIIgCIIgCIIoAzKqCIIgCIIgCIIgyoCMKoIgCIIgCIIgiDIgo4ogCIIgCIIgCKIMyKgiCIIgCIIgCIIoAzKqCIIgCIIgCIIgyoCMKoIgCIIgCIIgiDIgo4pwsW/fPlx11VWYPXs2Wlpa0N/fj1WrVuHhhx8GABiGgXvvvbe6nSSIKkPjhCCCoXFCEMHQOGkcktXuAFFbXHjhhchkMrjzzjtx9NFHY8+ePdi6dSveeeedaneNIGoGGicEEQyNE4IIhsZJA2ERRJEDBw5YAKxt27ZJPz/qqKMsAPbPUUcdZX927733WqeeeqrV0tJizZ0719qwYYOVzWbtzwFYP/zhD61zzz3Xam1ttebOnWtt3rw57kMiiMihcUIQwdA4IYhgaJw0FmRUETbZbNbq7Oy0rrnmGmt0dNTz+d69ey0A1r//+79bu3fvtvbu3WtZlmU9+OCDVnd3t3XHHXdYL7/8svXb3/7WmjNnjrVhwwZ7XQDWxIkTrdtvv93auXOn9Y1vfMNKJBLWc889V7HjI4gooHFCEMHQOCGIYGicNBZkVBEufvGLX1h9fX1Wa2urtWLFCuvaa6+1nnnmGftzANY999zjWuess86y/uVf/sW17Cc/+Yk1bdo013qf+9znXG2WLVtmXXXVVdEfBEHEDI0TggiGxglBBEPjpHEgoQrCxYUXXoi33noLv/rVr3Duuedi27ZtWLx4Me644w7lOs888wz+8R//EZ2dnfbPlVdeid27d2N4eNhut3z5ctd6y5cvx/PPPx/XoRBEbNA4IYhgaJwQRDA0ThoHEqogPLS2tuLss8/G2Wefjeuuuw6f+cxnsH79enzyk5+Utj9y5Aiuv/56XHDBBdJtEUQjQuOEIIKhcUIQwdA4aQzIU0UEcsIJJ2BoaAgAkEqlkMvlXJ8vXrwYO3fuxLx58zw/pulcYo8++qhrvUcffRTHH398/AdAEBWAxglBBEPjhCCCoXFSn5CnirB55513cPHFF+NTn/oUTjnlFHR1deGJJ57Ad77zHZx//vkAgDlz5mDr1q0444wz0NLSgr6+Pqxbtw7nnXceZs+ejYsuugimaeKZZ57Bs88+i3/6p3+yt79582YsWbIE7373u/HTn/4Ujz/+OP7t3/6tWodLECVB44QggqFxQhDB0DhpMKqd1EXUDqOjo9bXvvY1a/HixVZPT4/V3t5uHXfccdY3vvENa3h42LIsy/rVr35lzZs3z0omky5pzy1btlgrVqyw2trarO7ubmvp0qXWbbfdZn8OwNq0aZN19tlnWy0tLdacOXOsu+++u9KHSBBlQ+OEIIKhcUIQwdA4aSwMy7Ks6pp1RDNgGAbuuecerF69utpdIYiahcYJQQRD44QggqFxUnkop4ogCIIgCIIgCKIMyKgiCIIgCIIgCIIoAwr/IwiCIAiCIAiCKAPyVBEEQRAEQRAEQZQBGVUEQRAEQRAEQRBlQEYVQRAEQRAEQRBEGZBRRRAEQRAEQRAEUQZkVBEEQRAEQRAEQZQBGVUEQRAEQRAEQRBlQEYVQRAEQRAEQRBEGZBRRRAEQRAEQRAEUQb/P5ztLU3lbp7oAAAAAElFTkSuQmCC", - "text/plain": [ - "

" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, axs = plt.subplots(1, 4, figsize=(10, 3))\n", - "\n", - "axs : list[plt.Axes]\n", - "\n", - "axs[0].plot(activation_hist)\n", - "axs[0].set_title(\"Oscillator activation\")\n", - "\n", - "axs[1].plot(input_hist)\n", - "axs[1].set_title(\"Sensory input\")\n", - "\n", - "axs[2].plot(sensory_output_hist)\n", - "axs[2].set_title(\"Sensory output\")\n", - "\n", - "axs[3].plot(action_hist)\n", - "axs[3].set_title(\"Motor action\")\n", - "\n", - "for ax in axs:\n", - " ax.set_xlabel(\"Step\")\n", - " ax.set_ylabel(\"Value\")\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9edwlRXU+/nTf+76zsw4MiwODLCIRAeELYjQsQScu8FMTRTSyKoogu0ZUQFzAhc0YlIgKRqOixmgURJSAREFBEMUoIjthGZZhmIWZ953bt39/3NvV1VWnTp/q7ru+/Xw+MDP39u2qru6uOvWc55wTxHEco0aNGjVq1KhRY0wQDroDNWrUqFGjRo0aVaI2bmrUqFGjRo0aY4XauKlRo0aNGjVqjBVq46ZGjRo1atSoMVaojZsaNWrUqFGjxlihNm5q1KhRo0aNGmOF2ripUaNGjRo1aowVauOmRo0aNWrUqDFWqI2bGjVq1KhRo8ZYoTZuatSo0Xfsv//+2H///QfdjbHERz7yEQRBMOhu1KgxUNTGTY0aQ4wrrrgCQRCo/2bPno2ddtoJJ5xwApYtWzbo7rH44x//iI985CN44IEHBt2VGjVqzDA0B92BGjVq5OOjH/0otttuO6xbtw6/+MUv8IUvfAFXX301/vCHP2Du3LmD7h6JP/7xjzjnnHOw//77Y8mSJZnvrr322sF0qkaNGjMCtXFTo8YI4NWvfjX22msvAMA73vEObLrpprjwwgvxgx/8AIcddhj5mzVr1mDevHn97KYYk5OTg+5CjRo1xhi1W6pGjRHEgQceCAC4//77AQBHHnkk5s+fj3vvvRevec1rsGDBArztbW8D0DFyTjvtNCxevBizZs3CC17wApx//vmI4zhzzrVr1+LEE0/EwoULsWDBAhxyyCF45JFHEAQBPvKRj6jjHnzwQbznPe/BC17wAsyZMwebbrop3vSmN2XcT1dccQXe9KY3AQAOOOAA5Va74YYbANCamyeeeALHHHMMFi1ahNmzZ2O33XbDV7/61cwxDzzwAIIgwPnnn48vfvGL2H777TFr1iz8v//3/3DrrbeKxm7FihU4+eST1XjssMMO+NSnPoV2uw0AiOMYBxxwADbbbDM88cQT6nfT09PYddddsf3222PNmjXisUjGIwgC/OIXv8CJJ56IzTbbDBtttBHe9a53YXp6GitWrMDhhx+OjTfeGBtvvDHe//73Z+6Pft0XXXQRtt12W8yZMwf77bcf/vCHP4iu++tf/zr23HNPzJkzB5tssgne8pa34OGHHxb9tkaNUUPN3NSoMYK49957AQCbbrqp+qzVamHp0qV4+ctfjvPPPx9z585FHMc45JBDcP311+OYY47B7rvvjp/85Cd43/veh0ceeQQXXXSR+v2RRx6Jb3/723j729+Ol770pfj5z3+O1772tVbbt956K2666Sa85S1vwfOe9zw88MAD+MIXvoD9998ff/zjHzF37lz8zd/8DU488UT88z//Mz74wQ/ihS98IQCoP02sXbsW+++/P+655x6ccMIJ2G677fCd73wHRx55JFasWIGTTjopc/w3vvENrFq1Cu9617sQBAE+/elP441vfCPuu+8+TExMOMftueeew3777YdHHnkE73rXu7DNNtvgpptuwhlnnIHHHnsMF198MYIgwFe+8hW8+MUvxrvf/W5873vfAwCcffbZ+N///V/ccMMNihGTjIWO9773vdhiiy1wzjnn4Fe/+hW++MUvYqONNsJNN92EbbbZBueeey6uvvpqfOYzn8GLXvQiHH744Znf/9u//RtWrVqF448/HuvWrcNnP/tZHHjggbjzzjuxaNEi53V/4hOfwJlnnok3v/nNeMc73oEnn3wSn/vc5/A3f/M3+O1vf4uNNtrI+dsaNUYScY0aNYYWl19+eQwg/tnPfhY/+eST8cMPPxx/61vfijfddNN4zpw58f/93//FcRzHRxxxRAwg/sAHPpD5/fe///0YQPzxj3888/k//MM/xEEQxPfcc08cx3F82223xQDik08+OXPckUceGQOIzz77bPXZc889Z/Xz5ptvjgHE//Zv/6Y++853vhMDiK+//nrr+P322y/eb7/91L8vvvjiGED89a9/XX02PT0d77vvvvH8+fPjlStXxnEcx/fff38MIN50003j5cuXq2N/8IMfxADiH/7wh9QwKnzsYx+L582bF999992Zzz/wgQ/EjUYjfuihh9Rn//qv/6r69Ktf/SpuNBrW+EjHIrmPS5cujdvttvp83333jYMgiN/97nerz1qtVvy85z0vMz7Jdev3PI7j+Ne//nUMID7llFPUZ2effXasT+0PPPBA3Gg04k984hOZft55551xs9m0Pq9RYxxQu6Vq1BgBHHTQQdhss82wePFivOUtb8H8+fPxn//5n9h6660zxx133HGZf1999dVoNBo48cQTM5+fdtppiOMYP/7xjwEA11xzDQDgPe95T+a49773vVZf5syZo/6+fv16PP3009hhhx2w0UYb4fbbby90fVdffTW22GKLjH5oYmICJ554IlavXo2f//znmeMPPfRQbLzxxurfr3jFKwAA9913H9vOd77zHbziFa/AxhtvjKeeekr9d9BBByGKItx4443q2GOPPRZLly7Fe9/7Xrz97W/H9ttvj3PPPTdzPt+xOOaYYzJh2vvssw/iOMYxxxyjPms0Gthrr73Ia3n961+fued777039tlnH1x99dXOa/7e976HdruNN7/5zZlr3mKLLbDjjjvi+uuvZ8esRo1RRO2WqlFjBHDJJZdgp512QrPZxKJFi/CCF7wAYZjdmzSbTTzvec/LfPbggw9iq622woIFCzKfJ+6hBx98UP0ZhiG22267zHE77LCD1Ze1a9fivPPOw+WXX45HHnkkow159tlnC13fgw8+iB133NG6JrOfCbbZZpvMvxND55lnnmHb+ctf/oLf//732GyzzcjvdY0NAHz5y1/G9ttvj7/85S+46aabMsYM4D8WZr833HBDAMDixYutz6lr2XHHHa3PdtppJ3z7298mrwfoXHMcx+RvAbBuvBo1RhW1cVOjxghg7733VtFSLsyaNcsyDnqB9773vbj88stx8sknY99998WGG26IIAjwlre8RYlye41Go0F+HhsiaRPtdhuvfOUr8f73v5/8fqeddsr8+4YbbsDU1BQA4M4778S+++6b+d53LFz9pj7PuxYp2u02giDAj3/8Y7Kd+fPnV9JOjRrDhNq4qVFjjLHtttviZz/7GVatWpVhb+666y71ffJnu93G/fffn9nh33PPPdY5v/vd7+KII47ABRdcoD5bt24dVqxYkTnOJ0vutttui9///vdot9sZA83sZ1lsv/32WL16NQ466KDcYx977DG8973vxate9SpMTk7i9NNPx9KlSzN9kY5FVfjLX/5ifXb33XdbeYR0bL/99ojjGNttt51lvNWoMa6oNTc1aowxXvOa1yCKIvzLv/xL5vOLLroIQRDg1a9+NQBg6dKlAIDPf/7zmeM+97nPWedsNBoWq/C5z30OURRlPksiiiQL/Wte8xo8/vjjuPLKK9VnrVYLn/vc5zB//nzst99+ueeQ4M1vfjNuvvlm/OQnP7G+W7FiBVqtlvr3O9/5TrTbbXz5y1/GF7/4RTSbTRxzzDGZa5eORVX4/ve/j0ceeUT9+5ZbbsGvf/1rdR8pvPGNb0Sj0cA555xj9TWOYzz99NM96WuNGoNEzdzUqDHGOPjgg3HAAQfgQx/6EB544AHstttuuPbaa/GDH/wAJ598MrbffnsAwJ577om///u/x8UXX4ynn35ahYLffffdALIszOte9zp87Wtfw4YbbohddtkFN998M372s59lwtIBYPfdd0ej0cCnPvUpPPvss5g1axYOPPBAbL755lY/jz32WPzrv/4rjjzySNx2221YsmQJvvvd7+KXv/wlLr74YkszVBTve9/78F//9V943etehyOPPBJ77rkn1qxZgzvvvBPf/e538cADD2DhwoW4/PLLcdVVV+GKK65QOqbPfe5z+Md//Ed84QtfUMJr6VhUhR122AEvf/nLcdxxx2FqagoXX3wxNt10U6ebDegwNx//+Mdxxhln4IEHHsDrX/96LFiwAPfffz/+8z//E8ceeyxOP/30nvS3Ro2BYSAxWjVq1BAhCSG+9dZb2eOOOOKIeN68eeR3q1atik855ZR4q622iicmJuIdd9wx/sxnPpMJSY7jOF6zZk18/PHHx5tsskk8f/78+PWvf3385z//OQYQf/KTn1THPfPMM/FRRx0VL1y4MJ4/f368dOnS+K677oq33Xbb+Igjjsic87LLLouf//znx41GIxMWboaCx3EcL1u2TJ13cnIy3nXXXePLL788c0wSEv2Zz3zGuk4YIesurFq1Kj7jjDPiHXbYIZ6cnIwXLlwYv+xlL4vPP//8eHp6On744YfjDTfcMD744IOt377hDW+I582bF993331eY+G6j0nY9pNPPpn53Lyf+nVfcMEF8eLFi+NZs2bFr3jFK+Lf/e535DlN/Md//Ef88pe/PJ43b148b968eOedd46PP/74+M9//nPumNWoMWoI4rgi1VqNGjXGDnfccQf22GMPfP3rX1cZj2v0Hw888AC22247fOYzn6lZlho1BKg1NzVq1ADQCWs2cfHFFyMMQ/zN3/zNAHpUo0aNGsVQa25q1KgBAPj0pz+N2267DQcccACazSZ+/OMf48c//jGOPfZYKw9LjRo1agwzauOmRo0aAICXvexl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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.title(\"Progation example\")\n", - "plt.xlabel(\"Step\")\n", - "plt.ylabel(\"Motor action\")\n", - "\n", - "plt.plot(sensory_output_hist>5, label=\"Expected\")\n", - "plt.plot(action_hist, label=\"True\")\n", - "\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/Activation and Monitoring.ipynb b/examples/Activation and Monitoring.ipynb new file mode 100644 index 0000000..37d64d1 --- /dev/null +++ b/examples/Activation and Monitoring.ipynb @@ -0,0 +1,405 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Activation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Each codelet has two outputs: the \"standard output\", which corresponds to the memories that the codelet writes, and the \"activation\". The \"activation\" level ranges from 0.0 to 1.0, and can tell different things, like the relevance of the codelet output for attention mechanisms.\n", + "\n", + "In this example, we are going to see how to change the codelet activation level, and execute it's `proc` only when the activation is above the codelet threshould. The default threshould is 0.0.\n", + "\n", + "We are also going to see how to retrieve a mind element and monitor the mind state. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets start by importing the necessary modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import time # Sleep\n", + "import math # Math operations\n", + "\n", + "import numpy as np # Arrays operation\n", + "import matplotlib.pyplot as plt # Plot data\n", + "\n", + "import cst_python as cst # CST-Python module" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Codelet definition" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are going to implement a architecture with two codelets: a `SensorCodelet` that reads a input value, multiplies by 10 and send to the output. Also, it's activation level is setted to the input value clipped in [0.0, 1.0] in the `calculate_activation`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "class SensorCodelet(cst.Codelet):\n", + " def __init__(self, name:str) -> None:\n", + " super().__init__()\n", + "\n", + " self.name = name\n", + " self._ascending = True\n", + "\n", + " self._input_mo : cst.MemoryObject = None\n", + " self._output_mo : cst.MemoryObject = None\n", + " self._n_run = 0\n", + "\n", + " def access_memory_objects(self) -> None:\n", + " self._input_mo = self.get_input(name=\"SensoryInput\")\n", + " self._output_mo = self.get_output(name=\"SensoryOutput\")\n", + "\n", + " def calculate_activation(self) -> None:\n", + " read_value : float = self._input_mo.get_info()\n", + " read_value = np.clip(read_value, 0.0, 1.0)\n", + "\n", + " self.activation = read_value\n", + "\n", + " def proc(self) -> None:\n", + " read_value : float = self._input_mo.get_info()\n", + " read_value *= 10\n", + "\n", + " self._output_mo.set_info(read_value)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The other codelet, the `MotorCodelet`, set it's action as `True` if the input ceil is divisible by 2:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "class MotorCodelet(cst.Codelet):\n", + " def __init__(self, name:str) -> None:\n", + " super().__init__()\n", + "\n", + " self.name = name\n", + " self._ascending = True\n", + "\n", + " self._minput_mo : cst.MemoryObject = None\n", + " self._output_mo : cst.MemoryObject = None\n", + "\n", + " def access_memory_objects(self) -> None:\n", + " self._minput_mo = self.get_input(name=\"SensoryOutput\")\n", + " self._output_mo = self.get_output(name=\"Action\")\n", + "\n", + " def calculate_activation(self) -> None:\n", + " pass\n", + "\n", + " def proc(self) -> None:\n", + " read_value : float = self._minput_mo.get_info()\n", + " \n", + " action = math.ceil(read_value) % 2 == 0 \n", + "\n", + " self._output_mo.set_info(action)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mind creation\n", + "\n", + "We than create the mind with all the codelets and memories:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def prepare_mind() -> cst.Mind:\n", + " mind = cst.Mind()\n", + "\n", + "\n", + " m1 = mind.create_memory_object(\"SensoryInput\", 0.0)\n", + " m2 = mind.create_memory_object(\"SensoryOutput\", 0.0)\n", + " m3 = mind.create_memory_object(\"Action\", False)\n", + "\n", + "\n", + " c = SensorCodelet(\"Sensor1\")\n", + " c.add_input(m1)\n", + " c.add_output(m2)\n", + " mind.insert_codelet(c,\"Sensory\")\n", + "\n", + " c2 = MotorCodelet(\"Motor1\")\n", + " c2.add_input(m2)\n", + " c2.add_output(m3)\n", + " mind.insert_codelet(c2,\"Motor\")\n", + "\n", + " c.time_step = 10\n", + " c2.time_step = 10\n", + " \n", + " mind.start()\n", + " \n", + " return mind" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "mind = prepare_mind()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting mind elements\n", + "\n", + "Sometimes, we also need the retrieve a mind element after it's creation. In this case, we can manually inspect the `Raw Memory` and the `Code Rack`:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "for codelet in mind.code_rack.all_codelets:\n", + " if isinstance(codelet, SensorCodelet):\n", + " sensor_codelet = codelet\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "input_memory = mind.raw_memory.get_all_of_type(\"SensoryInput\")[0]\n", + "sensory_output_memory = mind.raw_memory.get_all_of_type(\"SensoryOutput\")[0]\n", + "action_memory = mind.raw_memory.get_all_of_type(\"Action\")[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Execution\n", + "\n", + "With all the elements, we can execute the mind for 100 time steps and store desired values from the mind, in this case the `SensoryCodelet` activation, the input, sensory otput and action memories values.\n", + "\n", + "The input value is going to be manually setted as value from 0 to 1. The `SensoryCodelet` threshould will be changed to 0.7 in the middle of the execution.\n", + "\n", + "Because we wanna monitor the mind, we are to step the sample time step as half the codelet time step. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "sleep_time = (10/2)/1000 #Half codelet execution time in seconds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Store the value history:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "n_step = 100\n", + "\n", + "activation_hist = np.empty(n_step, dtype=np.float64)\n", + "input_hist = np.empty(n_step, dtype=np.float64)\n", + "sensory_output_hist = np.empty(n_step, dtype=np.float64)\n", + "action_hist = np.empty(n_step, dtype=bool)\n", + "\n", + "for i in range(n_step):\n", + " input_value = i / n_step\n", + " \n", + " input_memory.set_info(input_value)\n", + "\n", + " input_hist[i] = input_memory.get_info()\n", + " sensory_output_hist[i] = sensory_output_memory.get_info()\n", + " action_hist[i] = action_memory.get_info()\n", + " activation_hist[i] = sensor_codelet.activation\n", + " \n", + " # Change threshould\n", + " if i == 50:\n", + " sensor_codelet.threshold = 0.7\n", + "\n", + " time.sleep(sleep_time)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "mind.shutdown()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see the stored values:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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BVOnTsXkyZP1z58+fdpgO39/f3h7e1eabt7UYe+4uDj873//008BPHXqFOLj4w22WblyJXr06IFvvvnG4Pm0tDSDzpcpxzb2Z1vd2Fubt6Z724gQAmfOnDG4MVKjRg2kpaWVeu3FixcNpq2YM12ELMf2UKRu3brlHl/3faDo9xlAqd/pskYWKvudZvupfgYOHIj//e9/2LVrl8G0/nuZcv4t62crZZu518qVK1GvXj2sWrXK4Nj3TvOrX78+Nm3ahFu3blU4WmXs76buPScmJhr8bufn5+P8+fMmXzNWB4qd/rd169Yye6+6ucu6jsCgQYPg6OiIqVOnltpeCIGbN2+afOx7X+Pi4oKoqCgIIVBQUABHR0c8+OCDWLt2rcGwf3JyMhYvXowuXbrop+1Vxs/PD3369MFPP/2En3/+Gb179za46AaKGoYQAiNHjkRWVlapfezfvx/ff/89gKLaCxqNptSdvk8//RQqlQp9+vQBAP2/c+fONdju3sKHjo6OGDx4MH755ZcyOyepqanlvreAgAB0794dX375pf4CoLzX6uovlHUyupfubse9P+97Y3dwcEBcXBx+/fVX7Nu3r9R+dK835dhA0XqD2NhYLF++HEuXLoWLiwvi4uJKxXhvfCtWrCi1hsyUYxv7s7VVbPPW98MPPxhMJV65ciWuX79u8LtTv3597Nq1C/n5+frnfvvtt1JTU0xtN2QatoeKPfTQQ9izZw927typfy47OxtfffUVwsPDERUVBQD6Ke7//POPfjuNRoOvvvqq1D49PDwqnJ7N9lP9eHp64osvvsC7776L/v37l7udKedfDw+PUj9XKdvMvcq6Jtq9e7dB2wCAwYMHQwhR5mhzydeWFX9ZYmJi4OLigrlz5xq8/ptvvkF6ejr69u1r6luxeYodqXrxxReRk5ODgQMHIjIyEvn5+dixYweWLVuG8PBw/Xqe+vXr47333kN8fDwuXLiAuLg4eHl54fz581i9ejWeffZZvPrqqyYd+8EHH0RQUBA6d+6MwMBAnDhxAvPnz0ffvn31dyjee+89bN68GV26dMELL7wAJycnfPnll8jLy8OsWbNMOt6oUaP083inT59e6vudOnXCggUL8MILLyAyMhIjR45Ew4YNkZmZiW3btmHdunV47733AAD9+/dHjx498Pbbb+PChQto2bIl/vjjD6xduxYTJkzQn2BatWqF4cOH4/PPP0d6ejo6deqELVu24MyZM6WO/8EHH2Dr1q3o0KEDxowZg6ioKNy6dQsHDhzAn3/+iVu3bpX73hYsWIAuXbqgefPmGDNmDOrVq4fk5GTs3LkTV65cwaFDh/TxODo64sMPP0R6ejrUajV69uyJgICAUvv09vZG165dMWvWLBQUFCA0NBR//PEHzp8/X2rbGTNm4I8//kC3bt3w7LPPokmTJrh+/TpWrFiB//77D76+viYdW2fo0KF4/PHH8fnnnyM2NrbUlIF+/fph2rRpGD16NDp16oQjR47g559/NribAxT9/vr6+mLhwoXw8vKCh4cHOnToUOZcamN/traKbd76atasiS5dumD06NFITk7GnDlz0KBBA4wZM0a/zTPPPIOVK1eid+/eePTRR3H27Fn89NNPpX6/TPndJdOxPVTszTffxJIlS9CnTx+89NJLqFmzJr7//nucP38ev/zyi37hfNOmTXHfffchPj5ef4d+6dKlKCwsLLXPNm3aYNmyZZg4cSLatWsHT09Pgwtttp/qqbylDSWZcv5t06YN/vzzT8yePRshISGIiIhAhw4dJG0zJfXr1w+rVq3CwIED0bdvX5w/fx4LFy5EVFSUwY34Hj16YOTIkZg7dy5Onz6tXy7x77//okePHhg3blyF8d/L398f8fHxmDp1Knr37o2HH34YiYmJ+Pzzz9GuXTuzky/ZNOslFrTM77//Lp566ikRGRkpPD09hYuLi2jQoIF48cUXRXJycqntf/nlF9GlSxfh4eEhPDw8RGRkpBg7dqxITEzUb6MrPnave1NXf/nll6Jr166iVq1aQq1Wi/r164vXXntNpKenG7zuwIEDIjY2Vnh6egp3d3fRo0ePUsUKS6bvLI+u4JyPj4+4c+dOudvt379fjBgxQoSEhAhnZ2dRo0YN0atXL/H9998bpLPMzMwUL7/8sn67hg0bllkg9s6dO+Kll14StWrVEh4eHhUW/01OThZjx44VYWFhwtnZWQQFBYlevXqJr776Sr9NecV/z549K0aNGiWCgoKEs7OzCA0NFf369RMrV6402O7rr78W9erVE46OjpWmV79y5YoYOHCg8PX1FT4+PuKRRx4R165dKzP2ixcvilGjRgl/f3+hVqtFvXr1xNixYw1SkJZ37HvT4OpkZGQINzc3AUD89NNPpb6f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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(1, 4, figsize=(10, 3))\n", + "\n", + "axs : list[plt.Axes]\n", + "\n", + "axs[0].plot(activation_hist)\n", + "axs[0].set_title(\"SensoryCodelet activation\")\n", + "\n", + "axs[1].plot(input_hist)\n", + "axs[1].set_title(\"Sensory input\")\n", + "\n", + "axs[2].plot(sensory_output_hist)\n", + "axs[2].set_title(\"Sensory output\")\n", + "\n", + "axs[3].plot(action_hist)\n", + "axs[3].set_title(\"Motor action\")\n", + "\n", + "for ax in axs:\n", + " ax.set_xlabel(\"Step\")\n", + " ax.set_ylabel(\"Value\")\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Observe that, because whe changed the threshould to 0.7 in the middle of the execution, the `SensoryCodelet` stops executing to when its activation is above that." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One insteresting detail is that, because the codelet is executed in _time step_ intervals, there is a delay between its input change to the `proc` execution with the output change:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACRhUlEQVR4nO2dd3wVVfr/PzNzU4DQSwIYihTLCkhZMZYFMS42/NqVRSkirigCYkUFxIYNhHVV1gK6awF1FVfFyoqIojRBWUSU/kMSmiGhJWTm/P7InbltMpy5uXPnnMnzfr3ygtzMTc49d+6ZZz7n8zyPwhhjIAiCIAiCCAiq3wMgCIIgCIJIJRTcEARBEAQRKCi4IQiCIAgiUFBwQxAEQRBEoKDghiAIgiCIQEHBDUEQBEEQgYKCG4IgCIIgAgUFNwRBEARBBAoKbgiCIAiCCBQU3BAEkXb69u2Lvn37+j2MQHL//fdDURS/h0EQvkLBDUEIzMsvvwxFUayv7OxsdO7cGaNGjUJxcbHfw3Nk7dq1uP/++7F582a/h0IQRC0j5PcACII4Og888ADat2+Pw4cPY/HixXjuuecwf/58rFmzBnXr1vV7eLasXbsWkydPRt++fdGuXbuYn3366af+DIogiFoBBTcEIQHnnXceevXqBQC4/vrr0bRpU0ybNg3vvfceBg4caPucAwcOoF69eukcJjeZmZl+D4EgiABD21IEISH9+vUDAGzatAkAMHToUOTk5GDDhg04//zzUb9+fQwaNAhAVZBz2223IT8/H1lZWTjuuOPw5JNPgjEW8zsPHTqE0aNHo1mzZqhfvz4uuugibN++HYqi4P7777eO27JlC2666SYcd9xxqFOnDpo2bYorrrgiZvvp5ZdfxhVXXAEAOOuss6xttYULFwKw99zs3LkTw4cPR25uLrKzs9GtWze88sorMcds3rwZiqLgySefxPPPP48OHTogKysLf/zjH7Fs2TKuuSspKcHYsWOt+ejYsSMee+wxGIYBAGCM4ayzzkLz5s2xc+dO63kVFRXo0qULOnTogAMHDnDPhTkfiqJg8eLFGD16NJo3b45GjRrhr3/9KyoqKlBSUoLBgwejcePGaNy4Me68886Y9yf6dT/11FNo27Yt6tSpgz59+mDNmjVcr/vVV19Fz549UadOHTRp0gRXX301tm3bxvVcgpANUm4IQkI2bNgAAGjatKn1WGVlJfr3748zzjgDTz75JOrWrQvGGC666CJ88cUXGD58OE4++WR88sknuOOOO7B9+3Y89dRT1vOHDh2KN998E9deey1OPfVUfPnll7jgggsS/vayZcvwzTff4Oqrr8YxxxyDzZs347nnnkPfvn2xdu1a1K1bF3/6058wevRo/O1vf8M999yDE044AQCsf+M5dOgQ+vbti19//RWjRo1C+/bt8dZbb2Ho0KEoKSnBmDFjYo5//fXXUVZWhr/+9a9QFAWPP/44Lr30UmzcuBEZGRnVztvBgwfRp08fbN++HX/961/Rpk0bfPPNNxg/fjx27NiB6dOnQ1EUzJo1C127dsWNN96Id955BwAwadIk/O9//8PChQstRYxnLqK55ZZbkJeXh8mTJ+Pbb7/F888/j0aNGuGbb75BmzZt8Mgjj2D+/Pl44okncNJJJ2Hw4MExz//nP/+JsrIy3HzzzTh8+DBmzJiBfv364ccff0Rubm61r/vhhx/GhAkTcOWVV+L666/Hrl278PTTT+NPf/oTvv/+ezRq1Kja5xKElDCCIIRl9uzZDAD7/PPP2a5du9i2bdvYnDlzWNOmTVmdOnXY//t//48xxtiQIUMYAHb33XfHPH/evHkMAHvooYdiHr/88suZoijs119/ZYwxtmLFCgaAjR07Nua4oUOHMgBs0qRJ1mMHDx5MGOeSJUsYAPbPf/7Teuytt95iANgXX3yRcHyfPn1Ynz59rO+nT5/OALBXX33VeqyiooIVFBSwnJwcVlpayhhjbNOmTQwAa9q0Kdu7d6917HvvvccAsPfff99uGi0efPBBVq9ePbZ+/fqYx++++26maRrbunWr9dg//vEPa0zffvst0zQtYX5458J8H/v3788Mw7AeLygoYIqisBtvvNF6rLKykh1zzDEx82O+7uj3nDHGvvvuOwaA3XrrrdZjkyZNYtFL++bNm5mmaezhhx+OGeePP/7IQqFQwuMEEQRoW4ogJKCwsBDNmzdHfn4+rr76auTk5ODdd99F69atY44bOXJkzPfz58+HpmkYPXp0zOO33XYbGGP46KOPAAAff/wxAOCmm26KOe6WW25JGEudOnWs/x85cgR79uxBx44d0ahRI6xcuTKp1zd//nzk5eXF+IcyMjIwevRo7N+/H19++WXM8VdddRUaN25sfX/mmWcC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ch7ufPhvGDh8CTZu3Iirr77aOv7rr7/Gaaedhptuuilmjpxo3rw5duzYYX1fWloa0wG+R48eKCoqQigUQrt27Rx/VyqRu4CJJHAZWgVc8C3lRqJUZDuSUm583iY0wueBzhSp6gzJugVLeAPjSYv2MFuqvLwcRUVFMV9mxpGu67jmmmvQv39/DBs2DLNnz8YPP/yQkHW0detWTL73Lmze8AvefXsunn76aYwZMwZAlUl30KBBGDx4MN75z3xs2rodS1eswpQpU/Dhhx8CAMaPH49ly5bhpptuwg8//IB169bhueees8bRrl07fPfdd9i8eTN2794NwzBw8803Y+/evRg4cCCWLVuGDRs24JNPPsGwYcOg6zpycnIwfPhw3HHHHfjvf/+LNWvWYOjQoTFBGWCflH7p+f1QduAARo4cibPOOgutWrWyftapUycsX74cn3zyCdavX48JEyZg2bJljnPcr18//Otf/8JXX32FH3/8EUOGDInpYFBYWIiCggJcfPHF+PTTT7F582Z88803uPfee7F8+XK+NzIJXK+auq7jySefxCmnnIK8vDw0adIk5otIxDJZOkn1Ai74ilkhtzYrN36lgoc9N7pk9x+meZ4rW0qgLVjCI7jKqnhTxA8APv74Y7Rs2TLm64wzzgAAPPzww9iyZQv+8Y9/AKja7nn++edx3333xaQpDx48GIcPHcKgAWfjnttvxZgxY2JMsLNnz8bgwYNx273347g/XYKLr70By5YtsxSVzp0749NPP8Xq1atxyimnoKCgAO+9956lyNx+++3QNA0nnngimjdvXmVObtUKX3/9NXRdx5///Gd06dIFY8eORaNGjawA5oknnsCZZ56JAQMGoLCwEGeccQZ69uzpPLWMoX5OPQw4py9Wr16NQYMGxRz+17/+FZdeeimuuuoq9O7dG3v27IlRcewYP348+vTpgwsvvBAXXHABLr74Yiu1HKhS+ubPn48//elPGDZsGDp37oyrr74aW7ZsiclKSznMJRMmTGAtW7ZkTz75JMvOzmYPPvggGz58OGvatCmbMWOG21+Xdvbt28cAsH379qXtbz638FfW9q4P2G1vrqr+oNVvMjapAWOvXJS2cR2Nnx46lbFJDdiKj//p91BqRP+nvmRt7/qALVq/k/9Ju9ZXvR9T8r0bmAO/bV7H2KQG7ODEZr78/WS55sVv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CIIgAoXv7RfSjVmQubS01OeREARBEATBi3nd5mmsUOuCm7KyMgBAfn6+zyMhCIIgCMItZWVlaNiwoeMxta63lGEY+O2331C/fn0oipLS311aWor8/Hxs27aN+lZ5DM11+qC5Th801+mD5jp9pGquGWMoKytDq1atYhpq21HrlBtVVXHMMcd4+jcaNGhAH5Y0QXOdPmiu0wfNdfqguU4fqZjroyk2JmQoJgiCIAgiUFBwQxAEQRBEoKDgJoVkZWVh0qRJyMrK8nsogYfmOn3QXKcPmuv0QXOdPvyY61pnKCYIgiAIItiQckMQBEEQRKCg4IYgCIIgiEBBwQ1BEARBEIGCghuCIAiCIAIFBTcp4plnnkG7du2QnZ2N3r17Y+nSpX4PSXqmTJmCP/7xj6hfvz5atGiBiy++GD///HPMMYcPH8bNN9+Mpk2bIicnB5dddhmKi4t9GnFwePTRR6EoCsaOHWs9RnOdOrZv345rrrkGTZs2RZ06ddClSxcsX77c+jljDBMnTkTLli1Rp04dFBYW4pdffvFxxHKi6zomTJiA9u3bo06dOujQoQMefPDBmN5ENNfJs2jRIgwYMACtWrWCoiiYN29ezM955nbv3r0YNGgQGjRogEaNGmH48OHYv39/zQfHiBozZ84clpmZyWbNmsX+97//sREjRrBGjRqx4uJiv4cmNf3792ezZ89ma9asYatWrWLnn38+a9OmDdu/f791zI033sjy8/PZggUL2PLly9mpp57KTjvtNB9HLT9Lly5l7dq1Y127dmVjxoyxHqe5Tg179+5lbdu2ZUOHDmXfffcd27hxI/vkk0/Yr7/+ah3z6KOPsoYNG7J58+ax1atXs4suuoi1b9+eHTp0yMeRy8fDDz/MmjZtyj744AO2adMm9tZbb7GcnBw2Y8YM6xia6+SZP38+u/fee9k777zDALB333035uc8c3vuueeybt26sW+//ZZ99dVXrGPHjmzgwIE1HhsFNynglFNOYTfffLP1va7rrFWrVmzKlCk+jip47Ny5kwFgX375JWOMsZKSEpaRkcHeeust65iffvqJAWBLlizxa5hSU1ZWxjp16sQ+++wz1qdPHyu4oblOHXfddRc744wzqv25YRgsLy+PPfHEE9ZjJSUlLCsri73xxhvpGGJguOCCC9h1110X89ill17KBg0axBijuU4l8cEN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igmCEJbs7Gycc845OOecczBhwgRcf/31mDRpEoYOHWp7/P79+zF58mRceumltr+LIIjaASk3BEFIw4knnogDBw4AADIyMqDreszPe/TogZ9//hkdO3ZM+FLVyHL37bffxjzv22+/xQknnOD9CyAIIi2QckMQhHDs2bMHV1xxBa677jp07doV9evXx/Lly/H444/j//7v/wBUZUwtWLAAp59+OrKystC4cWNMnDgRF154Idq0aYPLL78cqqpi9erVWLNmDR566CHr97/11lvo1asXzjjjDLz22mtYunQpXnrpJb9eLkEQKYYMxQRBCEd5eTnuv/9+fPrpp9iwYQOOHDmC/Px8XHHFFbjnnntQp04dvP/++xg3bhw2b96M1q1bW6ngn3zyCR544AF8//33yMjIwPHHH4/rr78eI0aMAFBlKH7mmWcwb948LFq0CC1btsRjjz2GK6+80sdXTBBEKqHghiCIWoVdlhVBEMGCPDcEQRAEQQQKCm4IgiAIgggUZCgmCKJWQTvxBBF8SLkhCIIgCCJQUHBDEARBEESgoOCGIAiCIIhAQcENQRAEQRCBgoIbgiAIgiACBQU3BEEQBEEECgpuCIIgCIIIFBTcEARBEAQRKCi4IQiCIAgiUPx/F5kLR15srJYAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.title(\"Progation example\")\n", + "plt.xlabel(\"Step\")\n", + "plt.ylabel(\"Motor action\")\n", + "\n", + "plt.plot(np.ceil(sensory_output_hist) % 2 == 0, label=\"Expected value\")\n", + "plt.plot(action_hist, label=\"True value\")\n", + "\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/setup.cfg b/setup.cfg index c2b9063..d997eed 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,4 +30,4 @@ packages = find: where = src [options.extras_require] -tests = mypy; testbook; ipython; ipykernel \ No newline at end of file +tests = mypy; testbook; ipython; ipykernel; numpy; matplotlib \ No newline at end of file diff --git a/tests/examples/test_activation_and_monitoring.py b/tests/examples/test_activation_and_monitoring.py new file mode 100644 index 0000000..1f0fca2 --- /dev/null +++ b/tests/examples/test_activation_and_monitoring.py @@ -0,0 +1,36 @@ +import os +import math + +import numpy as np +from testbook import testbook +from testbook.client import TestbookNotebookClient + +from ..utils import get_examples_path + +examples_path = get_examples_path() + +@testbook(os.path.join(examples_path, "Activation and Monitoring.ipynb"), execute=True) +def test_activation(tb :TestbookNotebookClient): + activation_hist = tb.ref("activation_hist.tolist()") + input_hist = tb.ref("input_hist.tolist()") + sensory_output_hist = tb.ref("sensory_output_hist.tolist()") + action_hist = tb.ref("action_hist.tolist()") + + last_sensory_output = sensory_output_hist[0] + for i, (activation, input_value, sensory_output, action) in enumerate(zip(activation_hist, input_hist, sensory_output_hist, action_hist)): + assert math.isclose(input_value, i/100) + + assert math.isclose(activation, np.clip(input_value, 0.0, 1.0), abs_tol=0.021) + + if i >= 50 and activation < 0.7: + expected_sensory = last_sensory_output + else: + expected_sensory = input_value * 10 + + assert math.isclose(sensory_output, expected_sensory, abs_tol=0.21) + + last_sensory_output = sensory_output + + assert math.isclose(action_hist[0], True ) + assert math.isclose(action_hist[55], False ) + assert math.isclose(action_hist[-1], True ) \ No newline at end of file From 959231224e2f022e7ccd52d33e8297f0e4da64c6 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:34:20 -0300 Subject: [PATCH 17/59] Add install cst_python to examples --- examples/Activation and Monitoring.ipynb | 40 ++++++++++++++-------- examples/Implementing a Architecture.ipynb | 12 +++++++ examples/Introduction to CST-Python.ipynb | 12 +++++++ examples/Publisher-Subscriber.ipynb | 12 +++++++ 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/examples/Activation and Monitoring.ipynb b/examples/Activation and Monitoring.ipynb index 37d64d1..6578a31 100644 --- a/examples/Activation and Monitoring.ipynb +++ b/examples/Activation and Monitoring.ipynb @@ -27,7 +27,19 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import cst_python\n", + "except:\n", + " !python3 -m pip install cst_python" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -97,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -137,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -170,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -188,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -200,7 +212,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -224,7 +236,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -240,7 +252,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -270,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -293,12 +305,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { - "image/png": "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BVOnTsXkyZP1z58+fdpgO39/f3h7e1eabt7UYe+4uDj873//008BPHXqFOLj4w22WblyJXr06IFvvvnG4Pm0tDSDzpcpxzb2Z1vd2Fubt6Z724gQAmfOnDG4MVKjRg2kpaWVeu3FixcNpq2YM12ELMf2UKRu3brlHl/3faDo9xlAqd/pskYWKvudZvupfgYOHIj//e9/2LVrl8G0/nuZcv4t62crZZu518qVK1GvXj2sWrXK4Nj3TvOrX78+Nm3ahFu3blU4WmXs76buPScmJhr8bufn5+P8+fMmXzNWB4qd/rd169Yye6+6ucu6jsCgQYPg6OiIqVOnltpeCIGbN2+afOx7X+Pi4oKoqCgIIVBQUABHR0c8+OCDWLt2rcGwf3JyMhYvXowuXbrop+1Vxs/PD3369MFPP/2En3/+Gb179za46AaKGoYQAiNHjkRWVlapfezfvx/ff/89gKLaCxqNptSdvk8//RQqlQp9+vQBAP2/c+fONdju3sKHjo6OGDx4MH755ZcyOyepqanlvreAgAB0794dX375pf4CoLzX6uovlHUyupfubse9P+97Y3dwcEBcXBx+/fVX7Nu3r9R+dK835dhA0XqD2NhYLF++HEuXLoWLiwvi4uJKxXhvfCtWrCi1hsyUYxv7s7VVbPPW98MPPxhMJV65ciWuX79u8LtTv3597Nq1C/n5+frnfvvtt1JTU0xtN2QatoeKPfTQQ9izZw927typfy47OxtfffUVwsPDERUVBQD6Ke7//POPfjuNRoOvvvqq1D49PDwqnJ7N9lP9eHp64osvvsC7776L/v37l7udKedfDw+PUj9XKdvMvcq6Jtq9e7dB2wCAwYMHQwhR5mhzydeWFX9ZYmJi4OLigrlz5xq8/ptvvkF6ejr69u1r6luxeYodqXrxxReRk5ODgQMHIjIyEvn5+dixYweWLVuG8PBw/Xqe+vXr47333kN8fDwuXLiAuLg4eHl54fz581i9ejWeffZZvPrqqyYd+8EHH0RQUBA6d+6MwMBAnDhxAvPnz0ffvn31dyjee+89bN68GV26dMELL7wAJycnfPnll8jLy8OsWbNMOt6oUaP083inT59e6vudOnXCggUL8MILLyAyMhIjR45Ew4YNkZmZiW3btmHdunV47733AAD9+/dHjx498Pbbb+PChQto2bIl/vjjD6xduxYTJkzQn2BatWqF4cOH4/PPP0d6ejo6deqELVu24MyZM6WO/8EHH2Dr1q3o0KEDxowZg6ioKNy6dQsHDhzAn3/+iVu3bpX73hYsWIAuXbqgefPmGDNmDOrVq4fk5GTs3LkTV65cwaFDh/TxODo64sMPP0R6ejrUajV69uyJgICAUvv09vZG165dMWvWLBQUFCA0NBR//PEHzp8/X2rbGTNm4I8//kC3bt3w7LPPokmTJrh+/TpWrFiB//77D76+viYdW2fo0KF4/PHH8fnnnyM2NrbUlIF+/fph2rRpGD16NDp16oQjR47g559/NribAxT9/vr6+mLhwoXw8vKCh4cHOnToUOZcamN/traKbd76atasiS5dumD06NFITk7GnDlz0KBBA4wZM0a/zTPPPIOVK1eid+/eePTRR3H27Fn89NNPpX6/TPndJdOxPVTszTffxJIlS9CnTx+89NJLqFmzJr7//nucP38ev/zyi37hfNOmTXHfffchPj5ef4d+6dKlKCwsLLXPNm3aYNmyZZg4cSLatWsHT09Pgwtttp/qqbylDSWZcv5t06YN/vzzT8yePRshISGIiIhAhw4dJG0zJfXr1w+rVq3CwIED0bdvX5w/fx4LFy5EVFSUwY34Hj16YOTIkZg7dy5Onz6tXy7x77//okePHhg3blyF8d/L398f8fHxmDp1Knr37o2HH34YiYmJ+Pzzz9GuXTuzky/ZNOslFrTM77//Lp566ikRGRkpPD09hYuLi2jQoIF48cUXRXJycqntf/nlF9GlSxfh4eEhPDw8RGRkpBg7dqxITEzUb6MrPnave1NXf/nll6Jr166iVq1aQq1Wi/r164vXXntNpKenG7zuwIEDIjY2Vnh6egp3d3fRo0ePUsUKS6bvLI+u4JyPj4+4c+dOudvt379fjBgxQoSEhAhnZ2dRo0YN0atXL/H9998bpLPMzMwUL7/8sn67hg0bllkg9s6dO+Kll14StWrVEh4eHhUW/01OThZjx44VYWFhwtnZWQQFBYlevXqJr776Sr9NecV/z549K0aNGiWCgoKEs7OzCA0NFf369RMrV6402O7rr78W9erVE46OjpWmV79y5YoYOHCg8PX1FT4+PuKRRx4R165dKzP2ixcvilGjRgl/f3+hVqtFvXr1xNixYw1SkJZ37HvT4OpkZGQINzc3AUD89NNPpb6f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", + "image/png": "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yIYMGVLp9TzzzDOscePGjDHG8vLymK2tLevVq5dB75tGo2G9evViCoWCvfrqq2zx4sVswIABDACbPHmy3rYvvvgiA8BGjhzJFi9ezAYPHszCw8MrJVXJycmsQYMGLDAwkM2aNYt9//337Nlnn2UA2DfffKPbrqqk6sKFC8zNzY2FhYWxL7/8ki1evJh169aNKRQK3cn0xo0b7O2332YA2EcffcR+/fVX9uuvv7Lk5ORqX+dXX33FnnzySTZr1iz2448/skmTJjEHBwfWoUMHvT9w9+/fZ/7+/szR0ZFNnjyZLV26lE2bNo21aNGCPXr0qNZjlz8RMsZYr169WFhYWKV4Zs6cyaytrXX7nThxgjVu3JhNnTqV/fDDD2zWrFksICCAubm5sfv37+ve11mzZjEA7LXXXtMd+8aNG4yxykkVl98tABYREaH7fC5YsICFhIQwR0fHKhNPOaA237jG11xdUmXI69Pu27p1axYeHs7mz5/Ppk6dyuzt7VmzZs1Yfn6+bltDLgpr++wS4ag91NwekpOTmY+PD3NxcWEff/wxmz9/PouIiGBWVlZ6iZqhSdWuXbtYZGQk8/T01H2eN23apLcttR/zp/08nDhxgnXu3Jm99NJLup9t3ryZWVlZsfv371dKqgw9//76669MqVSyJ598Uvd71d4cENpmqpOWlsb8/PzYlClT2Pfff8/mzZvHmjdvzmxtbVl8fLzeti+//DIDwPr27csWLFjAvvrqKzZw4EDdDeGa4q+qLc2YMYMBYNHR0WzRokVswoQJzNramrVv354VFRXptjP0b4+5k21StWvXLmZtbc2sra1Zp06d2AcffMB27typ90tijLHbt28za2tr9vnnn+s9fv78eWZjY6P3uPZO1C+//KJ7TKVSMV9fX70/7AMHDmQtW7asMb7Y2FhmZ2en90cwKSmJubi4sG7duuke034Iu3btykpKSvSeIy4ujimVSpaZmal7LDU1ldnY2OiSmrNnzzIAbNKkSTXGo7V582YGgH322Wd6jw8dOpQpFAp2/fp1xhhjZ86cYQDYW2+9pbfdyJEjKyVVr7zyCvPz86t0MT58+HDm5uamO6FUlVT17t2btW7dmhUWFuoe02g0rHPnzqxp06a6x9avX19r71R55U9iWqtXr2YA2MGDB3WPjRo1illZWenuwpSnTb5qOnbFpOqHH35g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", "text/plain": [ "
" ] @@ -347,12 +359,12 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 28, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACRhUlEQVR4nO2dd3wVVfr/PzNzU4DQSwIYihTLCkhZMZYFMS42/NqVRSkirigCYkUFxIYNhHVV1gK6awF1FVfFyoqIojRBWUSU/kMSmiGhJWTm/P7InbltMpy5uXPnnMnzfr3ygtzMTc49d+6ZZz7n8zyPwhhjIAiCIAiCCAiq3wMgCIIgCIJIJRTcEARBEAQRKCi4IQiCIAgiUFBwQxAEQRBEoKDghiAIgiCIQEHBDUEQBEEQgYKCG4IgCIIgAgUFNwRBEARBBAoKbgiCIAiCCBQU3BAEkXb69u2Lvn37+j2MQHL//fdDURS/h0EQvkLBDUEIzMsvvwxFUayv7OxsdO7cGaNGjUJxcbHfw3Nk7dq1uP/++7F582a/h0IQRC0j5PcACII4Og888ADat2+Pw4cPY/HixXjuuecwf/58rFmzBnXr1vV7eLasXbsWkydPRt++fdGuXbuYn3366af+DIogiFoBBTcEIQHnnXceevXqBQC4/vrr0bRpU0ybNg3vvfceBg4caPucAwcOoF69eukcJjeZmZl+D4EgiABD21IEISH9+vUDAGzatAkAMHToUOTk5GDDhg04//zzUb9+fQwaNAhAVZBz2223IT8/H1lZWTjuuOPw5JNPgjEW8zsPHTqE0aNHo1mzZqhfvz4uuugibN++HYqi4P7777eO27JlC2666SYcd9xxqFOnDpo2bYorrrgiZvvp5ZdfxhVXXAEAOOuss6xttYULFwKw99zs3LkTw4cPR25uLrKzs9GtWze88sorMcds3rwZiqLgySefxPPPP48OHTogKysLf/zjH7Fs2TKuuSspKcHYsWOt+ejYsSMee+wxGIYBAGCM4ayzzkLz5s2xc+dO63kVFRXo0qULOnTogAMHDnDPhTkfiqJg8eLFGD16NJo3b45GjRrhr3/9KyoqKlBSUoLBgwejcePGaNy4Me68886Y9yf6dT/11FNo27Yt6tSpgz59+mDNmjVcr/vVV19Fz549UadOHTRp0gRXX301tm3bxvVcgpANUm4IQkI2bNgAAGjatKn1WGVlJfr3748zzjgDTz75JOrWrQvGGC666CJ88cUXGD58OE4++WR88sknuOOOO7B9+3Y89dRT1vOHDh2KN998E9deey1OPfVUfPnll7jgggsS/vayZcvwzTff4Oqrr8YxxxyDzZs347nnnkPfvn2xdu1a1K1bF3/6058wevRo/O1vf8M999yDE044AQCsf+M5dOgQ+vbti19//RWjRo1C+/bt8dZbb2Ho0KEoKSnBmDFjYo5//fXXUVZWhr/+9a9QFAWPP/44Lr30UmzcuBEZGRnVztvBgwfRp08fbN++HX/961/Rpk0bfPPNNxg/fjx27NiB6dOnQ1EUzJo1C127dsWNN96Id955BwAwadIk/O9//8PChQstRYxnLqK55ZZbkJeXh8mTJ+Pbb7/F888/j0aNGuGbb75BmzZt8Mgjj2D+/Pl44okncNJJJ2Hw4MExz//nP/+JsrIy3HzzzTh8+DBmzJiBfv364ccff0Rubm61r/vhhx/GhAkTcOWVV+L666/Hrl278PTTT+NPf/oTvv/+ezRq1Kja5xKElDCCIIRl9uzZDAD7/PPP2a5du9i2bdvYnDlzWNOmTVmdOnXY//t//48xxtiQIUMYAHb33XfHPH/evHkMAHvooYdiHr/88suZoijs119/ZYwxtmLFCgaAjR07Nua4oUOHMgBs0qRJ1mMHDx5MGOeSJUsYAPbPf/7Teuytt95iANgXX3yRcHyfPn1Ynz59rO+nT5/OALBXX33VeqyiooIVFBSwnJwcVlpayhhjbNOmTQwAa9q0Kdu7d6917HvvvccAsPfff99uGi0efPBBVq9ePbZ+/fqYx++++26maRrbunWr9dg//vEPa0zffvst0zQtYX5458J8H/v3788Mw7AeLygoYIqisBtvvNF6rLKykh1zzDEx82O+7uj3nDHGvvvuOwaA3XrrrdZjkyZNYtFL++bNm5mmaezhhx+OGeePP/7IQqFQwuMEEQRoW4ogJKCwsBDNmzdHfn4+rr76auTk5ODdd99F69atY44bOXJkzPfz58+HpmkYPXp0zOO33XYbGGP46KOPAAAff/wxAOCmm26KOe6WW25JGEudOnWs/x85cgR79uxBx44d0ahRI6xcuTKp1zd//nzk5eXF+IcyMjIwevRo7N+/H19++WXM8VdddRUaN25sfX/mmWcC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ch7ufPhvGDh8CTZu3Iirr77aOv7rr7/Gaaedhptuuilmjpxo3rw5duzYYX1fWloa0wG+R48eKCoqQigUQrt27Rx/VyqRu4CJJHAZWgVc8C3lRqJUZDuSUm583iY0wueBzhSp6gzJugVLeAPjSYv2MFuqvLwcRUVFMV9mxpGu67jmmmvQv39/DBs2DLNnz8YPP/yQkHW0detWTL73Lmze8AvefXsunn76aYwZMwZAlUl30KBBGDx4MN75z3xs2rodS1eswpQpU/Dhhx8CAMaPH49ly5bhpptuwg8//IB169bhueees8bRrl07fPfdd9i8eTN2794NwzBw8803Y+/evRg4cCCWLVuGDRs24JNPPsGwYcOg6zpycnIwfPhw3HHHHfjvf/+LNWvWYOjQoTFBGWCflH7p+f1QduAARo4cibPOOgutWrWyftapUycsX74cn3zyCdavX48JEyZg2bJljnPcr18//Otf/8JXX32FH3/8EUOGDInpYFBYWIiCggJcfPHF+PTTT7F582Z88803uPfee7F8+XK+NzIJXK+auq7jySefxCmnnIK8vDw0adIk5otIxDJZOkn1Ai74ilkhtzYrN36lgoc9N7pk9x+meZ4rW0qgLVjCI7jKqnhTxA8APv74Y7Rs2TLm64wzzgAAPPzww9iyZQv+8Y9/AKja7nn++edx3333xaQpDx48GIcPHcKgAWfjnttvxZgxY2JMsLNnz8bgwYNx273347g/XYKLr70By5YtsxSVzp0749NPP8Xq1atxyimnoKCgAO+9956lyNx+++3QNA0nnngimjdvXmVObtUKX3/9NXRdx5///Gd06dIFY8eORaNGjawA5oknnsCZZ56JAQMGoLCwEGeccQZ69uzpPLWMoX5OPQw4py9Wr16NQYMGxRz+17/+FZdeeimuuuoq9O7dG3v27IlRcewYP348+vTpgwsvvBAXXHABLr74Yiu1HKhS+ubPn48//elPGDZsGDp37oyrr74aW7ZsiclKSznMJRMmTGAtW7ZkTz75JMvOzmYPPvggGz58OGvatCmbMWOG21+Xdvbt28cAsH379qXtbz638FfW9q4P2G1vrqr+oNVvMjapAWOvXJS2cR2Nnx46lbFJDdiKj//p91BqRP+nvmRt7/qALVq/k/9Ju9ZXvR9T8r0bmAO/bV7H2KQG7ODEZr78/WS55sVvWdu7PmD/XrGt+oPm3VQ1t4ueTN/AiKQ4dOgQW7t2LTt06FBSzy/ad4it3vY727b3QPUH7d/N2PaVjO3+NclRekefPn3YmDFj2G8lB9nqbb+z334/WP3BZTurXseejekb4FFYt6OUrd72Oys7fKTqgUMlVWPc+ZO/A3PA6Zxzc/12fVv42muv4YUXXsBtt92GUCiEgQMH4sUXX8TEiRPx7bffpj76CgAaTyqyzwZWO0zPjUzZOnaYaoLjVkk8lgfKny7tRrjOjSGbcuOqzo0/c0ukj0hvKcfmUuZRHo8mebhqD8f3bxIAFmcopvYLDhQVFaFLly4AgJycHOzbtw8AcOGFF1p7jEQs7gqbiRPcqJahWG7PjRlcOtYZisdvz004uNElqzHkrs6NOFuwhEdwdQX3blsqdYQNxRzHCAV1BefnmGOOwY4dO9CmTRt06NABn376KXr06IFly5ZZBXqIWGRd8NWw50b24MZKT5ao/YJRGQ5uJFNuZK3GTXgD1ydOYDXBTF8uLj1c9QBPleQUV1KuCYlTK0MgmRpcr5yXXHIJFixYAAC45ZZbMGHCBHTq1AmDBw/Gddddl/IBBgFXqeACLfhqULal1CSUG59bBBiGpNtSbgzFAgXyhEe4MRRLcMV13pYSd/zRhuK4RwKL66vWo48+av3/qquuQtu2bfHNN9+gU6dOGDBgQEoHFxRCPMqBgAt+RLmRO7jhSk+Ox1TSmGFVHU0nuqXcyKWacbW6UMTzlxHewPeJE19NMD/+zqIM10FpJRLLxE+uwJOdImp81Tr11FNx6qmnpmIsgcXyfDid9NaCL47J0lJuJOptZIfV28tV48yooMLQgTSrVyx84ZdOuZHUX0Z4Q0QncLiYCrwtZeJuZAIFN/GGYgkCyVQh18opKZq0yk0wDMWWcuNUZyjhSVGv2YetQl2vqnNjSGYolnULlvAI01DMVedG5Csuh6FYxPHb1LmJeySwUHCTBjQez4eAC75mNc6Up7eRHVwVouOJ3orzI+DU5VZuZAvkCW9wtS0lMFbc4riGCLgtZf4nIZah4IZIARHlxmHLScAF31RuVMnbL3Blq8WjxG1LpRld8lRwx0BeEa+PGuERPLsgEm1L8aWCixfc0LbUUdB1HYsWLUJJSYlHwwkmkQXf4SABF3zTUCy7cpNUcBOt3PigprFwkMsku//QuPqoiadSEt5QrZ/V7igRt3Xi4BFuvEBRFMybN8/9E61YRon5vjZEN65WTk3T8Oc//xm///67V+MJJO4WfHEMxZoV3MilHsSj8XSqjifeUJxmTEOxdMoNVzVu8QJ5whsiZwFPheLUoSiK49f999/v8vdxHVX1j1DbUgmmG8Q9EFhcp4CcdNJJ2LhxI9q3b+/FeAKJxpOKrIpYxC8YdW60cGsLV4ZiRanKYGOGLxdhs0KxfMpN1XgpW4oAwCfKeKAm7Nixw/r/3LlzMXHiRPz888/WYzk5OZE/zxh0XbcaWdrDU6HY+o3uBusRjNmFlvKoZDXF9cr50EMP4fbbb8cHH3yAHTt2oLS0NOaLSETTOHwIAi74lqFY8jo34el3p9wAvlaNtlLBZVNuwiuKbNW4CW9gXBf61F9w8/LyrK+GDRtCURTr+3Xr1qF+/fr46KOP0LNnT2RlZWHx4sUYOnQoLr744pjfM3bsWPTt29camq7rmDJlCtq3b486deqgW7duePvtt6sd/z333IPevXsnPN6tWzc88MADAIBly5bhnHPOQbNmzdCwYUP06dMHK1eurPa1LVy4EIqixNhDVq1aBUVRsHnzZuuxrxYvxtBLz8MpHVuifbu2GD16NA7sP8A3gQHA9VXr/PPPBwBcdNFFMc3QGGNQFAW6Ls7FWRS4lBsBF3zLcxOS3XMTVm7ceG6AqoDTOOKP58ZqnClbcONCuSHPjZwwBhw5yHWocuQglCNHoFQYQEU1a9uRg8CRQ1X/VjhcfDPqpjQAuvvuu/Hkk0/i2GOPRePGjR2PNf/qczOmYv67b2LmzJno1KkTFi1ahGuuuQbNmzdHn1N7Vh0UdRM1aNAgTJkyBRs2bECHDh0AAP/73//www8/4N///jcAoKysDEOGDMHTTz8NxhimTp2K888/H7/88gvq16+f1GvbsGEDzj/vPNx0+72YPPXvaKQcxpjRt2DU7Tsx+/G7aoVy4zq4+eKLL7wYR6DhKv8v4IIfCky2VNW/rgzFgK9bhaahWFblxnkL1ixYKU4gT7jgyEHgkVZch7ZJ5d+95zcgs17Kft0DDzyAc845h/v4ivJyPDfjSSz4/HMUFBQAAI499lgsXrwY//jHP9Cn4IXwkZFz/w9/+AO6deuG119/HRMmTAAAvPbaa+jduzc6duwIAOjXr1/M33n++efRqFEjfPnll7jwwguTem1TpkzBX/7yF1xz/UgAwEmtGuJvf/sb+vTpg+ceGIvsukn9WqlwHdz06dPHi3EEGpUrFVy8kvSmchOSPluKQ02wwwpu0m/yNpUbpsjpuXHcArS2YMUxzxO1j169enEfqyjA1s0bcejgwYSAqKKiAt27d6/2uYMGDcKsWbMwYcIEMMbwxhtvYNy4cdbPi4uLcd9992HhwoXYuXMndF3HwYMHsXXrVvcvKszq1avxww8/4NXXXgcAqErV7ophGNi0bTtOaNI66d8tC0mZKUpKSvDSSy/hp59+AlAVnV533XVo2LBhSgcXFCzlxunaKpjnhhkGQkq4t1RtVW7Ic+MaWbdgCRdk1K1SUTjYtPsA9pdX4phGddC4Xqb9Qfu2Agd/B+rnATm5zn83hdSrF6sCqaoaY8IFgCNHqiqFK1Bw8GDVltmHH36I1q1jg4OsrCxUly01cOBA3HXXXVi5ciUOHTqEbdu24aqrrrJ+PmTIEOzZswczZsxA27ZtkZWVhYKCAlRUVNiOWw3fQESP1Rynyf79+zHihhtw7pXDAADH5dWvspGUFaNN4wzalrJj+fLl6N+/P+rUqYNTTjkFADBt2jQ8/PDD+PTTT9GjR4+UD1J2uJQbwRZ8w4i4PUKSe25CSSs3/m0VRpQbuYKbkBvzvEBbsIQLFIV7e4hlMDCjEkpWXSCzmuAmVBfIOFz1O1O47eSW5s2bY82aNTGPrVq1ChkZVetfh07HITMrC1u3brXfwbB8SLHn/jHHHIM+ffrgtddew6FDh3DOOeegRYsW1s+//vprPPvss5afddu2bdi9e7fjOIGqjDDTK7Rq1aqYY3r06IGf1v6EG9ofCwDo2LrKVI3SOsD+nagNqeCuNe9bb70VF110ETZv3ox33nkH77zzDjZt2oQLL7wQY8eO9WCI8hPiKeIn2IJfWRm5a1AkTwW3OlW7zZby03MTPg9kC264OrALWPaA8AZ3qdP+XnD79euH5cuX45///Cd++eUXTJo0yQp2FAWol1Mfw0fegltvvRWvvPIKNmzYgJUrV+Lpp5/GK6+84jj+QYMGYc6cOXjrrbcwaNCgmJ916tQJ//rXv/DTTz/hu+++w6BBg1CnTp1qf1fHjh2Rn5+P+++/H7/88gs+/PBDTJ06NeaYu+66C0uWfINH7rsDP//vR/z666947733MOr2e5OfIMlwHdwsX74cd911V0xNgFAohDvvvBPLly9P6eCCQmTBd/LcRBXxE6AIlBGV9eZc/0F8TDUhaeXGj61CXU5DMZ95nor41Rpc1bnxl/79+2PChAm488478cc//hFlZWUYPHhwzDFj7pqACRMmYMqUKTjhhBNw7rnn4sMPPwzXfau+iN/ll1+OPXv24ODBgwnp5i+99BJ+//139OjRA9deey1Gjx4do+zEk5GRgTfeeAPr1q1D165d8dhjj+Ghhx6KOaZr1674fMEX2LJxA4Zedj66d++OiRMnolVeeNuPtqUSadCgAbZu3Yrjjz8+5vFt27YlnbYWdCLl/x0OijaOGjrgs1pSWRnZw5W9iJ+l3Lj23Phn8jY9N5DMUKzyNM4UsNUI4Q2uKhR7dMEdOnQohg4dan3ft2/fBG+NyeTJkzF58uSEx/cfjnhvxowZgzFjxiQ+ufJwtWNo1KgRDh+2/3n37t2xbNmymMcuv/zymO/jx3v66afjhx9+cDym1x974R+vvwNVUXBS67Afdt824ED1W15BwvXKedVVV2H48OGYO3cutm3bhm3btmHOnDm4/vrrMXDgQC/GKD1WV2qexpmAEHJ9tHKjSR7c1DgV3I+tQkNOz41ZMJF6SxFVVJ0HzmGLINKNA2ZNN5kaZ5ofwZi5r0W9pVxftZ588kkoioLBgwejsrJqAc7IyMDIkSPx6KOPpnyAQUDladwY3ctIgEVfj/LcyB/c1NBQ7GO2lHTBTTiS1J1aXfg4r0R6YVzbUmJ4bnhwrrgsVm8p+zim9rRfcH3VyszMxIwZM6yqiwDQoUMH1K1bC6oCJUmIK7gRTLkxU5GZIn8RPx6Tqx1+bp9Iq9xwmLdpW6rW4OoTJ/AFV+ERZRKaU4qBEh3dCBJ4pQPX21LXXXcdysrKULduXXTp0gVdunRB3bp1ceDAAVx33XVejFF6uLJ1oi9iAiz6ethzUylZ40Y7uNKT7fBTYZBUueEL5Cm4qTXYbY1Ud5AUyo0TYgURjoKYwIFkqnB95XrllVdw6NChhMcPHTqEf/7znykZVNDgytZRxQpuDKu3kfzBDVd6su0Tw6+d+VBJ1wxuVLmCG1dbsAJsvxJ8VGfAPerzzP84XUwFCASOhsLVFVysgIHZ+p3EDySTPdfi4d6WKi0tBWMMjDGUlZUhOzvb+pmu65g/f75j+lptRuPJ1lGUqswYZgix6Bvh1C5dssaNdkQqRMuTCi5rnRuuuRasGjdRPWYBu4MHDzrWXqkeHkNxGIHVBHfbUuaBYrye2GGJH0ialZm1GtohuIObRo0aQVEUKIqCzp07J/xcURTbFDoikgpusEj3dFvUEKBXCLHoG3rVCaZLlopsB5eaYIefVaPNc0CVy8xtpYI7GYoFq8ZNVI+maWjUqBF27twJAKhbt27165cNekUFmGGgovwwNFbNuXykEqhkQPkRQKk+ndpPyo/oYJUV0FWl2pRuGHrV6wCAQ4cjyq9PHK6oBKusgMHUyJgrwmOsqASqex0+YhgGdu3ahbp169a4vhr3s7/44gswxtCvXz/8+9//RpMmTayfZWZmom3btmjViq9TbG3DDG6AqgusuU2VgECLvpkKHiTlRqb2C9Y5IFlwac01j3IjgEJJHJ28vDwAsAIcNxTvO1y1HVyWhcxQNedyWTGglwMlADKSUYe8p1I3sLO0HKoChA5UM0bGgH27qv6/P8v3z255pYFdZeXI0BQo+8M7LQd2V7WJqKMDWft8HV91qKqKNm3auAqi7eAObsxeGps2bUJ+fr7VvIs4OjHBDWPVT7pAi76hVxmKA+G5STq48THYNLelZFNueLZgVf+KIxLuURQFLVu2RIsWLRIaNB6NO2d+g70HKjDz2p5o36KaIq9zJwG71gIXPAW0PzMFI049O0oO4f73vkN2hoYPR1czRv0I8NyVVf+//r9AdoP0DdCG77f+jvv/sxptmtTF7GEnVD34wdPA5kXAWfcC7S/xdXzVkZmZmZL4wvXK2bZtW+oK7pJ45aZaBFr0g6jcuDcUm8FN+g3FilWhWK75d1X2QIDznOBH0zTXPogd+3Xs3q8jMzM7xqcZw+EiYP82IKQA1R3jM5nZDNvLdGSGWPWvw8iseh0AkKH5/lp0JQPby3TUr4fImA/vrBqjavg+Pq9JqrdUhw4d8NRTT2Hv3r3Yu3cvpk2bhg4dOmDlypVejFF6+IMbcRb9IGVLmYZu14ZiP7cJmZzZUhpPcCPQ9ivhLeYNhea0jFj+MnHXGr6eaSoihfz8X8PNrWE1envHHJdk60oyuFZuzK7gL7zwgmX4qaysxPXXX4+xY8di0aJFKR+k7GgKZ3Aj0KJvSNq40Q4taeXGv21CxfLcyDX/XMGNQNuvhLfoVnDjELhIYJ7nLiehalXrtwBruNnuJ8bjaY5L4LlOFa5f4fLly2MCGyDSFbxXr14pHVxQcK3cCLDosyApNzx3XXb46rkJb4VJtgjxBTfiBPGEt1jBjZM5VIJAPhS1hhsGs3x8CaihcHDj/xpuNmqOUW7MLXbJEhWSwfUrNLuCx1OTruDPPPMM2rVrh+zsbPTu3RtLly7let6cOXOgKEpCC3nRUBQF5mdBlkXfbL+gC7zg8BJRblx6Z/yspGvdYck1/xpXtpR/XiYivVjBTXUZokDUVom4gXx0MMPX8d7/NdxSbtTaqdz43hV87ty5GDduHCZNmoSVK1eiW7du6N+//1HTDjdv3ozbb78dZ54pprs+Hq5F34ymBVj0zWwpFijlxuUTfeyBpIQXfEWy4JI8N0Q0rpQbgQP5aPXduUClWX3b/zXcUm5U8txwkequ4NOmTcOIESMwbNgwAMDMmTPx4YcfYtasWbj77rttn6PrOgYNGoTJkyfjq6++QklJieu/m240VcERnTkXNxOoWzIj5cZnz42cixB5bohozJs5rbptHCBy1yHwuR7iVW4EUt8rSblxh9kV/Pfff8eqVauwatUq7N27F0899RSysrJc/a6KigqsWLEChYWFkQGpKgoLC7FkyZJqn/fAAw+gRYsWGD58uNvh+wZXxo5APXdMQ3EglBurcanLJ/q4UCmS3mFxtRoR6AJAeIdhMKvav3NwI77nRnWdFCLAGm4XWEpaYiIZkg7fzK7gNWH37t3QdR25ubkxj+fm5mLdunW2z1m8eDFeeuklrFq1iutvlJeXo7y83Pq+tLQ06fHWBK6MHQGVmyBlS+lulRsBtqVku8NytS3FjKqqrgL3FCKSJ3oL3nFbSoJAPuS6nIf/a7i5SxBrKBY/7T5VcK+c1113Hddxs2bNSnowR6OsrAzXXnstXnjhBTRr1ozrOVOmTBGi5xVXxo5AUX8kW0rcBYeXyAXX5RMFUG4UgRd8O/iC+KjXZOiAJlcAR/ARHQQ4Gool2CpRuYMbgdT3cHAZsvXciDvXqYL7Fb788sto27YtunfvnrKW5M2aNYOmaSguLo55vLi42OpnEs2GDRuwefNmDBgwwHrMMPcVQyH8/PPP6NChQ8xzxo8fj3Hjxlnfl5aWIj8/PyXjd4NZ54Fvv9b/DwYLLzgsACmDSSs3PpoDZVduuLZfgfBiK9drJPiICW4cDcVmerLYgXxIVVBpMM4tV//XcPNao9p5bgSf61TAvaqMHDkSb7zxBjZt2oRhw4bhmmuuiWmemQyZmZno2bMnFixYYKVzG4aBBQsWYNSoUQnHH3/88fjxxx9jHrvvvvtQVlaGGTNm2AYtWVlZrr1AXmBW6JQl6g/mtlSSRfz8WKjCAZWsyg2XdA8IcREgvCFmW8rJcyPBthQQDhIMdpSMV3GCG3OXIGTnuZHspikZuG/Ln3nmGezYsQN33nkn3n//feTn5+PKK6/EJ598UiMlZ9y4cXjhhRfwyiuv4KeffsLIkSNx4MABK3tq8ODBGD9+PICq/hgnnXRSzFejRo1Qv359nHTSScjMzEx6HF4TCis3suzXmttSwVJu5Gm/oLLw35Rsy4bLUBwdMAtwrhPeoOucwY0EqeBAVN80STJe7ZUbOQLJVOBq5czKysLAgQMxcOBAbNmyBS+//DJuuukmVFZW4n//+x9ycnJcD+Cqq67Crl27MHHiRBQVFeHkk0/Gxx9/bJmMt27dGogO5OZLkCXqjyg3cl1c7eCqMWSHn6ngpnIjmXLmWrkRQKUkvCH68+YU28iiJkSyLuVQ33U75UYSlSwVJH02qaoKRVHAGIOu1+yNHDVqlO02FAAsXLjQ8bkvv/xyjf52uuBTbsRJkQ2U50bhuOOyw+rS7p9yo8im3LhpvwAIEcgT3hDpK6VAkbz9AhAxRTt69wRSbmwLKEoy16nA1ZWrvLwcb7zxBs455xx07twZP/74I/7+979j69atSak2tQlX7RcEqG4JUm6iFio/DMVyem5CPHOtKFHVuCm4CSrRwU21GAaA8Lkii3LjtBwIVGXetoCiJCpZKuB+hTfddBPmzJmD/Px8XHfddXjjjTe407GJiHLjmArup4E1DtNzE4QGa0mngvvoubGCG8mUGzVKuWGMVX/HrmhVQbwAd7iEN3C1XojevhHcfiBb9W3DLrikbalEZs6ciTZt2uDYY4/Fl19+iS+//NL2uHfeeSdlgwsS5qIvS9M180PAAiBfhpJOBfdvoVKtOjdyBTcx3ZMZUG15EzUEGEeEuAgQ3mDr+Ygn+kZO8HNdto73lXbBDSk3iQwePNh535RwhEuuFyjqj2RLyR/cqMlmS/m4UKkIBzeSKjdAVW8brbo7RIEuAoQ32GbrxBP9/gu+1vB1vBdHfbdVbqz2C2KrZKnAVRE/InlUrjRC/wysCQRSuUk2uPFTuZFr/mOUGyehzJpb/70JhDfYVsiNh8mo3DicswKp7/bKjfjVoFNF8MM3QXCl3Iiw4AdJueFJ4bTDz95SqDoHVNmUGyVWuakWgS4ChDdYvY24t6XEXmu4vHsCJYVYhmKldnpuKLhJE66Kmwmw4DNTuQnAhyCkJavc+LdNqAVeuRFnC5bwBi7lJjq4EXyrxFzDHYN2gbZbzV2CmL5epNwQqUaVrP2CuegEQbnhCizt8LNxJsxUcLkWIU3lVG4EuggQ3mB5bnhr3Aju6Yw0P3Y4SKBCrAnKTfTAA7CuHw0KbtKEbO0XguSqjzRzhLtWIT6aA03lRpNsW0pRlEhNJ0mMl4Q3WNlSTh3BJWoQG+l4L1cRP0s5ix6TZIpwMlBwkya4MnZEKmxmBK/ODeBSvVF8rFAcVm6gybcIcaXMinSuE57AVedGkr5SgMuO9wKo73p8thqTx9+UCuS/ckkCV8aOSHezludG/DuqoxG7VZKEcuODOVC1lJuMtP/tmiJbsTPCG/gqFEuo3DhmvAq0LeWo3Ig/3zWFgps0wZWxI1DUr1j1EOSP8KMXV8e7rnh8rXMjZ/sFgNPjRJ6bwOMquJFAITbPa8c1RCTPTbxyE2Pelm9dcYv4Z1RACFn7tZJ4bgJU5yY2PdnNtpR/C5UWLuKnheS7w+LbghXnIkB4g3kj52golig1WZNsDU/YFpQo7T4VUHCTJiJOe0kWfEOeRedoxKYnJ7Mt5UMRP7POjYTycYjLm0DbUkHH4DEUS7gtJUvGa0LjzOgxSaCU1ZTgv0JB4Iv6xZHqFYnuqI5G8p4b/0yvpnKjSqjc8J3rZCgOOq5TwQVH+t5SEqXdpwIKbtIEl3IjUHVLmVI0j0Z0enJSyo0vqeByVigGXBqKKbgJLFyNMyVaZ/iyAMVpK2IkGIrlmetUQMFNmpBtv1YJj0GR4I6KB675j8fHitGWciNjcCNZNW7CGxIMrXZYF1zxL0XuMl79P68TGpdKlHafCsQ/owKCbE57xVSPAvJB4LrrikcEz42MwQ1Puwvy3AQe3U37BQnUBNkyXhOUG2tNF3+uUwEFN2lCtgVfCViUzxVcxuPj/rkWDm60kIR1bigVnECke7ZzKrg8nhvTGO1sLRBnuzUhW02itPtUUDtepQBEmq7xmCwFWPADFuUntS2l+rN/zgwDmmJKyuIv+vG4M176700gvMHsnu0Y3EjkuVF51nAfq5rHk9D+ohY1zQQouEkbfIZiM+r3f8FXWdhzI+HF1Q6u+Y/HJ1+Irkf+nhbKTOvfTgXujJf+XwQIb7CUG672C+Jfilx5bgRICtHjs9UClAHLg/hnVEDgUg5EWvADp9xUnerJtV9Ir8RcWXkkMgQpe0uFm8RSnZtaDZdyY8izznAVpxRou7XS8tzEqUkSzHUqoOAmTcjWdM2scxMc5abqX3eGYn8WKiNauZEyuKn6V5aaToQ3BM1zo/EYigVKCjFVavPzaAWSEsx1KqDgJk3wNV0TJ43QbNwICbN17DDvXpLKlkrzQlVZGb0tJaGhODzXXDWdBLgIEN7A1VtKIs+N6V3RJVnDI0X84pUbCm6IFMKXCi5O1VZLuQlIlG9+vh3vuuLx6f1gMcqN+It+PKZ/kW8L1v9znfCGhAq5dkh0weVLBQ+vGQKo7waLU27Ic0N4QcRz42A0EyiN0ApuJLy42lEj5cZHz42MwU2IS7khz03QMeJ7G9keJM8F110RP//Pa3OXIFG5kW9NSQYKbtJEJIPE4SCBPDdqwDw35voqg+eG6VVzrzMFigRZJPGo5LkhEKXcOGZLmbVXxF9nZOt2bwWXCXVuxJ/rVCDfyikpkeCGR7nxf8E3KxSTcoP0e270KuVGh5yLkKXc8GRLCXARILyBqyu4TJ4bSdsvRBpnyqOSpQIKbtIEl3IjUNRvlv9XJFh0eOC664pH8UdJM0zlRtKPJ98drjjeBMIbzLXOuSu4PBdcV6ngApzXRnxwQ54bwgtCXMqNQMFN4Ir4Vf3rTrnxx1BsVMqt3HAZigU61wlvCFoqeIinVplA262VCang8sx1KqDgJk1EnPZOB4kT9QdtW0qTaFvKCC9ChqQ9YPhSwWlbKujoPIZiidQEd82PxalQrMXfpAVEjT8acq6eEmLVSJDEc6Oi6oMgY28jO7jUhHh8qhhtFvGTVrnhMRSLVI2b8ARXhmIJ1hmuKucCreF6/PxLlHafCii4SRMqT6dkkTw3AVNuuEyu8fiUriy758aVoVgAlZLwBsvz4WQolkhNMIN2ruKUApzXCcqZ1VKHghsihcjmtDeVm+AYiqv+TaorODMAN0FRDTHC2VKGpB9Plasatzjdkwlv4FNu5PGBSKvcqHHKjQRznQrkXD0lhM9pb2aQ+L9fayo3MhaRs4OrsFw80Xc4aVTTTOXGkHRbKsTVR828CPh/rhPeYKWCB6T9ApdyI1CV+cTgRp65TgUU3KQJPqe9OFG/BrO3lJwX2HhUnvmPJ/oOJ43vianc6JIais0tWPLc1G7M91/lar8g/rnuTrkRMbghzw3hAVxdwQX03GiafI0b7bDUhGSypYC07qEzIxjKDdcWrADeBMIbzLXOUbkxlTsJ1ATTOuTcW0ogz028ciaRSpYKKLhJE5pkC37EcyPnBTYerqZ3CU/yS7kJBzeS7o27KnZGyk1gMT1XXMqNBOe6pslV4sBc69T4bSlJFWG31I5XKQAaT7aUQAu+WaFYCwUjyufaFown+g4njYsVk9xQzKfciKNSEt6g8yg3EqkJmmTbrQnKDXluCC9wVZJeAJOlZtW5CcYHQUtmWyr6DiedwY25LSXpHRaXSinQFizhDeb779x+QR4fCF8quBhtRRhjifMvUcHEVCDn6ikhsqWCa2HlRg2IcqMlZShWfOkvZRbxk9VzYwU3VOemVpOgHNgR2CJ+/p7X0UMMJRiKg7GmHw0KbtKEyrXgi2NG08JjUAOSCp6UcgP4slVoKjcsyMqNQFuwhDckZOvYYflAZAhuqv6VISkk+rOX6LkRf65TgZyrp4RYng/HwmbiKDem5yZowY0r5Qbw5U7MUm4UOefelXmetqUCS0JvIztk8tyYyo0Ea3j0Zy/Rc0PBDZFCZGu6ZnlughLc8My/HX4YBM3GmZJ+PLnM85a/zP9AnvCGSHDjcJBMnhuejEtB1PfoMWoJqeDiz3UqkHP1lBAu5UAgqV6zsqWCUefG7G/jeNdlR3QLhjRhdgVnksrH7soe+B/IE94Q6W3kcJmRSE1wt93qc3Cj2wQ35LkhvIDL8yFI1M8MA5pi1kgQf9Hhgeuuyw4/Fis9INlSPHe4tC0VWLiUGyaPD0SmLMAY5UYhzw3hIXzKjSD7tXrk7welt1RkYXKpFPiwLcUs5UbOubfm2kklE6geCOENfKng8ig3MmW8Vkatc2qCciP+XKcCCm7SBJdyI0rUHxXcqEHZlrIWJpdP9CNlOSjZUpQKXquJpILzbEuJH8i7qrzt83ltxjYxafjmFjAFN0QqcaXcgPlqKtYrj1j/1wLSODNp5cYHH1QkW0rOueerxi1O92TCG1wZiiU412VUbmJaX0g016mAgps0wdU4M/oOx8fIX9cjfzswhuKklRsfMtiYqdzIuQhRKjgBcBqKJcrg4epPJ0iVeVvlRiKVLBVQcJMmuHobxfQy8i/yN2KUm2B8ECJqggSeG70WZEuR5ybw8Ck38gQ3IU0+5UZTbJQbCeY6FVBwkyZUrtof0V2o/VRuAmwodp0t5YM3pDYpN+S5CSxcRfwkUhO41nBRPDemaqZFe27kCSRTAQU3acI01XEt+IDPyk3V39aZAsVpYZIIrguuHX7UHjKzpSRdhGSr6UR4gxXc8DTOlCCQl8tzYzP3lApOeIEZI3BF/YCvxc308AdTl7Rxox01D27S2RU8/N5Lugjx+cvEqcZNeANXbymp2i+4UN+ZAbhViVOI7dxLpJKlAgpu0gTXgh+d+uvntpSp3ATo9EjaUOxDer4ieyq4wqHckOcm8PA1zpTHB8JlKBbkBtW8Z4iZe9qWIryAS6pXFCEWfRZA5SaUdCp4+r0hVhE/Se+wTOOlczVu8twEnUi2lFNwI0/tFT5DcbRv0r813DIU26WCS7quuEWI4OaZZ55Bu3btkJ2djd69e2Pp0qXVHvvCCy/gzDPPROPGjdG4cWMUFhY6Hi8K5t0sY+K3YDDr3Mha/t+OyF2X2yf6EGxKVJLeDtVSbhwCSfLcBB6zjxuXciPBuS5TUohhF1hanpvgrOtO+P4q586di3HjxmHSpElYuXIlunXrhv79+2Pnzp22xy9cuBADBw7EF198gSVLliA/Px9//vOfsX379jSP3B3RVTq5Krf6qdyE69wESrnRaqjcpHOhkrxxpqmSOU411bkJPOYFNhQQz40rQzHgr3JjF1iS5ya9TJs2DSNGjMCwYcNw4oknYubMmahbty5mzZple/xrr72Gm266CSeffDKOP/54vPjiizAMAwsWLEjzyN0RnXQkeuM1MxU8SJ4brrsuO6yiXOnMlpJHqrdDVTmUG4UqFAcdcwveubeUPJ4bV13BAX/Vd2aTLUWem/RRUVGBFStWoLCw0HpMVVUUFhZiyZIlXL/j4MGDOHLkCJo0aeLVMFNCjHLDlSLro6Rplv8PUHDDdddlh+UNSZ85UDHCRRQlV24ctwDJcxN4zO33kOYU3MhzwXWVLQX4e4Nqmy1Vuzw3vr7K3bt3Q9d15Obmxjyem5uLdevWcf2Ou+66C61atYoJkKIpLy9HeXm59X1paWnyA64BMcoNj9vex0U/EtyIv+DwwtX0zvaJfnhuqgIpWevcqDzmbfLcBB4+5UYefxlfQ1gVgIKq/oCiBTfyzHUqkPrW/NFHH8WcOXPw7rvvIjs72/aYKVOmoGHDhtZXfn5+mkdZRYxy43RLK4DnxjCzpQJkPONqf2GHD94QRfI7rBBP2j15bgKPpdwExHMTrdwwwX2Tut3cS7QFmAp8vXo1a9YMmqahuLg45vHi4mLk5eU5PvfJJ5/Eo48+ik8//RRdu3at9rjx48dj37591te2bdtSMna3RJ9jzo3X/N+WQthQHCTlhqvOkB2KD0qa5NlS5j6/Y1agH/NKpBW+VHCJtqWiFCjHeyQB1HczuInpCs7k9vK5xdfgJjMzEz179owxA5vm4IKCgmqf9/jjj+PBBx/Exx9/jF69ejn+jaysLDRo0CDmyw8URZGmW7JpKDYkvbjaYdUZcpsL7sP2iSK58U/jMRQL4C0jvKXSVRE/CZSbKO+Q87ktunIj/lynAt9f5bhx4zBkyBD06tULp5xyCqZPn44DBw5g2LBhAIDBgwejdevWmDJlCgDgsccew8SJE/H666+jXbt2KCoqAgDk5OQgJyfHt9fBg6Yo0MGOEtyE400fo36ziFyQDMWWmuC6caYPbQIkupu1I6KSORxEwU3gMXiCG4lUyhjlxmk5UHxYM+IwVTO1FveW8j24ueqqq7Br1y5MnDgRRUVFOPnkk/Hxxx9bJuOtW7dCjfKrPPfcc6ioqMDll18e83smTZqE+++/P51Dd42mKoAufuM1Zik3wQlu1GQ9Nz5UjDaVG0XSOyy+VHAyFAcdV4ZiCRr0RgdpVed2NUGCAGZ552wpCm7SxqhRozBq1Cjbny1cuDDm+82bN3s/II9wlUroZyq4ETzPTaSwXLKp4Gk0FEu+LeWqiB95bgJJ9OfM0VAsUWG56EDB+dwWx3NDvaWItMDVX0og5UbWxo12JK3c+Oq5EX/Bt8NV+wWfuycT3hD9OVN5PDcSbJVEb0uJ7rmx9TvVsm2p4Fy9JIArY0cIz01YuVHkvLjakXwRPx+6glvbUnIuQpFWFw4HxTQYJPUmaESvcUFJBVdVBWZ8I3rGq20avkQqWSqg4CaNcGXsCJAtxfRw48wAnR5a0u0XfAhuJF+EInPN4bkByHcTQKKVm6CkggO8/aX8D25s/U61zHMTnKuXBHBl7AgQ9ZvKjayNG+3gqi5qhx+eG1QFBbIqN65KHgDkuwkgekCDG64edQJ4bqympZqd50bOmya3UHCTRlw1XvNzWyqA2VJa0oZiqnPjFtcNBkm5CRwxwQ1P40xJbqQ0HrO8ADeouq1yEx60JHNdU4Jz9ZIAaQzFlnITnAifa+7t8KP9guSp4Hw9eKJeG3luAod5cVWUoxiKJVMT+ApU+r+GU/sFCm7SCpeh2FRL/FzwjeBlSyWt3FjvR/oWKlVyQzFfyYOoc4uCm8BhpSI7qTaAdBdcvqQQ/9V3+/YLcivCbgnO1UsCpDEUW9lSwfkQ1Fi5YemrNmopN5ocd7Px8AU3CvWXCjB8faWiPlOSKDdcDXgFMhTX5vYLFNykES5DsQBRP7OUm+AFN8m3X0inciO5odg6z3GU7sn+V3IlvEHXXfSVAmKVPIHhMhQL4LmxbX1BdW4Ir5DFc4MAZktx3XHZ4YOSpkruuQlFldIXvUks4Q1cyk30DZwk5zpfKrj/a7hjET9Jb5rcQsFNGuHyfQgQ9QcxFZzrjssOH7ZOrFRwSbelotsEcRU7o22pwGFb/j+e6DVOkguuKknGq6lQx3ieyHNDeAWfciOAVG9uSwXoQ2CqCclXKE6/oViV5G42Hn7lxv9AnvAG22ydeKI/U5Kc6/IpN9HGffLcEB7hrs5N+gysCQRwb9b8jCcf3KTv/bC2pTQ55z9GuaHgplZiW2clnug1TpK1hku5sTIs/VvDI56b6AeDt647QcFNGnFVuZU8NykleeUm/e+HCrmzpdx7bshQHDTcKTdKbEQsMNIqN4xJV1OopshxRgUEq+eO6O0Xwh+CIG1LWcqN22wpH3whathzI+u2VPT1jCurhDw3gcP8nDl3BJfPA6LyrOECeG70eOUmWiWTaL5rAgU3aSTSLVns6paylUTnwQwsGXNZyM9Pz42kyo2iKFaAw7ctRcpN0DDXOK5UcInWGXMNFz3jNaGIooRp9zWldrxKQYhk7DgdZMqIflYoDu62FOBSvfHBF6JK3jgTiNoG5Kpz46O/jPAEc43jSgWXSKG0ajhxeW58VG5Y3LaUIV/afU2h4CaNRPZreZQb/4ObIMmX3CbXeHzYJtRM5SaUkba/mWrM+Xasxq2QchNUzN5Lzk0z5Vtn3NUq8zG40eO2pWIy0+SZ75pAwU0aiTjtHQ4SwHNjdaUOqnLjalvKbL/gh+dG3vk359u5Gnf655ZIDwaPciNxcOOo3IjguYlXbiQsmFhTKLhJI5ah2FG5EeBuNoB1bqKVG1dVin14PzSYnht559+8pglf04nwhMqAem5Ma4HjeS2AIplgKI6+WZZovmsCBTdpRNNcpBH6GPUrEu6FH41o5cadodiH9gumcqPJuy0VCq+qXHe4VOcmcJiKnWMquITrjGko5lIk/dyWik8Ft8YiT9p9Takdr1IQNK6o338zmox3VEcjeo11pdz48H5YnhuplRs3d7gU3AQN02vlnApuVsyV5zy3zmsnL5kVUAig3JjTL+Fc1xQKbtKIeRcjetRv1UQI0AdBUZTkOoP7oKRplnKTmba/mWpcFTsjz03g4FJuDPnWGeu85vKS+ZcFaAU3WpznRiKVrKZQcJNGuAzFApjRlIBG+VoyzTP9qHNjBTfyfjxdtRohz03gMBU7x/YLEirEsjQ/1uMbZ9ay1gsABTdpxV0quH8LvsLMOivBivK5Lrjx+KCkmcqNFpJXudHc3OHStlTgsNovaMHy3LhLBfd/W8pSzgz55rqmUHCTRuRJBQ+ocpNMcOND5kNkW0re+eeaa8V/bwLhDVyNMyVUiLm2tgVQ3635N4MbK5CsPZf82vNKBYBPuREhuDH3woMV5XPddcWT5i7thq5DVcz9cnmzpVw1ifXRm0B4A1/jTPnUBDP7yNlQ7P92a6JyYwaS8sx1TaHgJo3I0nTNTAWXufy/HckZitMbbOp6ZEGUtbcUwFmmXoBAnvAGwyoix7EtJVGvI3OXzXENsdRe/w3Favy2FHluCC8ISbJfG8Q6N0CUcuN01xVPmt8PvfKI9X8tJO/8y+JNILyh0uAIbmRWbgQ/r0m5oeAmrcjitAeTv3GjHZaa4Ea5UdKrpEUrN5rMyg2PoTjNc0ukD8NVcCPPOmMmMHJlAQrQfsHyPFlWg9pzya89r1QA+O5m/d+vVVkwo/zkPDfpvQurrIwKbiRunGkFN4J7EwhviCg3DpcYCdUE8/Vwecl8PK8rSbmh4CaduGu65t9+rRJU5SapVHAzoyc97werTcqN6r83gfCGhAq5dkjYoJdLuRGgynyCckaeG8JLZPEhmMqNIvHF1Q6uqrnxpF25iXhuVIklZFfZUqTcBI6E3kZ2SLgtFXKl3PgX3CR4nki5IbyEy/MhgOcmqMqNWpM6N2naP2fh972SqVBkDm54qkGT5yawWBVynU5hCYMbWTJeE5QbJt9c1xR5V08JMbuCO9dI8P9uVg1qKrgE7RfMbCkdcs89tV+o3ZheK2dDsXztF8yKy6IrkpXhrV41of1C7bnk155XKgCaJFF/4NsvJNM4M02+EEOvet91yT+a7oIbUm6Chu6mzo1E64zqRpH003MTHp7V/kLCtPuaIvcKKhnuStL798FQEVZuAua5icy/i0AlzS0CdL1KuTEk/2jynev+XwQIb4gYioPWfqHqX+eg3f+2IonKjXxzXVPkXkElw53J0sfgJnxHpQYsyo/Mv4snWS0C0vN+WMqN5PKxq8aZ5LkJHEE1FLtKBfcx49W8fwsleG6CtaY7IfcKKhmy+BAsz43EjRvtSEq5SfP7YVjKjdxzb96xi17TifCGSHDjcJCE6clc57UPzXbjMZWbhGwpiea6plBwk0bcNRP0c1sq7LkJ7LaUiyelWUkLjOdG46np5L9KSXgDl3IjoZoQkuS8Nte4SHBjViim4IbwAFlSwU3PTeC2pXgM3fFYdzosLaZiFr7Dkt5zw3WH6783gfCGSi7lRj4fiDSp4PGGbkoFJ7zEXfsFPz03YTNawJSbSBpnEttSQFoWKyNcoVj2VPAQVzVu/70JhDdELq7B8txwFQIVYA2v1KvZlgrYDasTFNykEVeeGxG2pSRadHiIpHG6eVLUHKRhsTKDG0NyQ7Hqqv0CbUsFDa5sKQnbL3AVAhVAfTeHpyXUuZFnrmuK3CuoZMhSkt7KlpK4caMdoaQMxVF3Oml4T6zgJiDKjejnOuEN5vsecmouJWHtFVnO62oNxQG7YXWCgps0IkvtD1O5UQP2QVCTMRQr6d2WYmFDsSH5HZarO1xKBQ8c5vuuOta5kW9biuu8FkB9N+INxYwMxYSHuIv6/ftgaCDlxiJGuUnjtlRAlBtKBa+dWMoNT/sFCZUb0Zsfm8pNiDw3RDrgc9qH3xIBPDfBVW7ctF+I+oikIbixsqVk99woPIZiM7ghQ3HQMNc41Sm4sTw38pzrfBmvZhagP+c1Y8zy3FjzT54bwktkaboWdOXG8a7LjjS+J8wIF/GTfBGS5Q6X8IZKLuVGPs8NX8arv+d19PWFlBsiLcjSdE0zU8ED9kHguuuyI43eEBY2BElf50blucP135tAeIOp2DkqNxJ6bjSuEgf+ntfROwPW/Ft1buReV9xQe16pAITc9CURQLnRQgELbki5SRvWXOvkuamN8Ck38qkJkTXEYctJSOVGPpWsplBwk0bMoJnPae+fD8Hy3ASsiB/XXZcdaazHYoSVGxaQ4MZRuaE6N4HF/IwFrc5NZA1xOMhn9T36+qJSnRsiHWhc21L+l6QPWcFNsD4IarLKjfWepMNQXKXcMMk/mqrCcYcrwBYs4Q2VXNtSpnIjz7nOdV6r6Vsv7Ii+vlCdGyItWIZix7tZf1PBDV2HqoTvurRgGordKzdpbGZqBKPOTSTt3uEgAZrEEt5gKnbO21Jm7RV5FGLrvHZaQnw+r2OCGyXecyPPXNcUCm7SiBX1C+xD0PXI3w3atpTK08zR9onpe0/MOjeyb0upPDWFyHMTWMw1jku5kehc13jOa8XnNTy8vilKdCq4Ode155Jfe16pAJiGYmcfQlTU7zarJwVEBzdBMxRH7rqSNRSTcsOLK+WGtqUCh86j3EioJmgSnNe2cy+hSlZTKLhJI+ZWrKNyEFPuP/2mYr3yiPV/LWDKjbUwOWrKNqTRG2IW8WOS32Hx3eH6600gvIOv/YJ8PhCu89pno7ylmkXPvYRzXVPkXkElw1JueLKlAF8+HLoe+ZtawIr4aUkrN2msWxF+z5kid2CpSeBNILyDr/2CvHVuRO4tZet3klAlqylCBDfPPPMM2rVrh+zsbPTu3RtLly51PP6tt97C8ccfj+zsbHTp0gXz589P00hrhsaj3MQEN+nfszVqg3IjsOemVik35LkJLOZnTOMJbiTagnXX/Nif89o2U01Cf1NN8X0FnTt3LsaNG4dJkyZh5cqV6NatG/r374+dO3faHv/NN99g4MCBGD58OL7//ntcfPHFuPjii7FmzZo0j9w9GpdyExVQ+BD5xxiKJUrR5CH54Cb9nhsm+R0W3x0ueW6CCldwI6GawKX++p3xaqeaSaiS1RTfz6pp06ZhxIgRGDZsGABg5syZ+PDDDzFr1izcfffdCcfPmDED5557Lu644w4AwIMPPojPPvsMf//73zFz5sy0jt0tZlreEcPA//v9oP1BegWOCf+3eMvPMLLqp2dwYcr2FKEpgEqmWttoQcGc/9LDldXPvw0tDAWZAPYUbUGF2sKj0VXBDu6p+ld25SY81wfK9WrnOuvAETQHcKT8AHZv+TmNoyO8pmHFDrTGQdQ9+BtQcsj+oIoDVf9KdME1z+uKyurXcPVABVqhSoUt8uG83rP3EFpjFxormUDJ1qoHy0vDg5NnrmuKr8FNRUUFVqxYgfHjx1uPqaqKwsJCLFmyxPY5S5Yswbhx42Ie69+/P+bNm2d7fHl5OcrLy63vS0tLaz7wJNHCdW4OHzFwxmNf2B6jwMCm7Kr/575+drqGZtEy/K/svY3sMOf//dW/4f3Vv3E/74PMQzhJBZp+crNXQ7Mw5192+di8w1386+5qz/XT1TV4LRPI2PMzWs4+JZ3DIzzmDQDIBjCP42CJznXzvC4uLa/2vG6CUqzMBhQwX87rlgC+zgagA5ge90OJ5rqm+Brc7N69G7quIzc3N+bx3NxcrFu3zvY5RUVFtscXFRXZHj9lyhRMnjw5NQOuIXkNstG7fROs2lbicJSKD4zTUKgsS9ewbPmxcSH+6OsIUs8ZHZvh5fqbse/QkaMfHMXHrADt2Q5oSE/2WrmSCe2EC9Lyt7zilPZN0LpRHezeX17tMevRARtYK7TGrjSOjEgXiqIgM6TCYWMKyMkF2pyariHVmI4tcnBS6wb4pXh/tcccQEN8ZXTFH5Wf0jiyRDRVQYYWdZNapzFwbB//BpRmfN+W8prx48fHKD2lpaXIz8/3ZSyaqmDuXws4jjzP87EcjaAFNgDQ9ZhGWHpvYRLPPA9A+rY8swH0SNtf84a2Tevh67v7cRx5hedjIYhUkZ2h4YNbzuQ48nzPx0I442tw06xZM2iahuLi4pjHi4uLkZeXZ/ucvLw8V8dnZWUhKysrNQMmCIIgCEJ4fDVWZGZmomfPnliwYIH1mGEYWLBgAQoK7BWOgoKCmOMB4LPPPqv2eIIgCIIgahe+b0uNGzcOQ4YMQa9evXDKKadg+vTpOHDggJU9NXjwYLRu3RpTpkwBAIwZMwZ9+vTB1KlTccEFF2DOnDlYvnw5nn/+eT9fBkEQBEEQguB7cHPVVVdh165dmDhxIoqKinDyySfj448/tkzDW7dujam3ctppp+H111/Hfffdh3vuuQedOnXCvHnzcNJJJ/n1EgiCIAiCEAiFMR+6M/pIaWkpGjZsiH379qFBgwZ+D4cgCIIgCA7cXL+DV8yEIAiCIIhaDQU3BEEQBEEECgpuCIIgCIIIFBTcEARBEAQRKCi4IQiCIAgiUFBwQxAEQRBEoKDghiAIgiCIQEHBDUEQBEEQgYKCG4IgCIIgAoXv7RfSjVmQubS01OeREARBEATBi3nd5mmsUOuCm7KyMgBAfn6+zyMhCIIgCMItZWVlaNiwoeMxta63lGEY+O2331C/fn0oipLS311aWor8/Hxs27aN+lZ5DM11+qC5Th801+mD5jp9pGquGWMoKytDq1atYhpq21HrlBtVVXHMMcd4+jcaNGhAH5Y0QXOdPmiu0wfNdfqguU4fqZjroyk2JmQoJgiCIAgiUFBwQxAEQRBEoKDgJoVkZWVh0qRJyMrK8nsogYfmOn3QXKcPmuv0QXOdPvyY61pnKCYIgiAIItiQckMQBEEQRKCg4IYgCIIgiEBBwQ1BEARBEIGCghuCIAiCIAIFBTcp4plnnkG7du2QnZ2N3r17Y+nSpX4PSXqmTJmCP/7xj6hfvz5atGiBiy++GD///HPMMYcPH8bNN9+Mpk2bIicnB5dddhmKi4t9GnFwePTRR6EoCsaOHWs9RnOdOrZv345rrrkGTZs2RZ06ddClSxcsX77c+jljDBMnTkTLli1Rp04dFBYW4pdffvFxxHKi6zomTJiA9u3bo06dOujQoQMefPDBmN5ENNfJs2jRIgwYMACtWrWCoiiYN29ezM955nbv3r0YNGgQGjRogEaNGmH48OHYv39/zQfHiBozZ84clpmZyWbNmsX+97//sREjRrBGjRqx4uJiv4cmNf3792ezZ89ma9asYatWrWLnn38+a9OmDdu/f791zI033sjy8/PZggUL2PLly9mpp57KTjvtNB9HLT9Lly5l7dq1Y127dmVjxoyxHqe5Tg179+5lbdu2ZUOHDmXfffcd27hxI/vkk0/Yr7/+ah3z6KOPsoYNG7J58+ax1atXs4suuoi1b9+eHTp0yMeRy8fDDz/MmjZtyj744AO2adMm9tZbb7GcnBw2Y8YM6xia6+SZP38+u/fee9k777zDALB333035uc8c3vuueeybt26sW+//ZZ99dVXrGPHjmzgwIE1HhsFNynglFNOYTfffLP1va7rrFWrVmzKlCk+jip47Ny5kwFgX375JWOMsZKSEpaRkcHeeust65iffvqJAWBLlizxa5hSU1ZWxjp16sQ+++wz1qdPHyu4oblOHXfddRc744wzqv25YRgsLy+PPfHEE9ZjJSUlLCsri73xxhvpGGJguOCCC9h1110X89ill17KBg0axBijuU4l8cEN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igmCEJbs7Gycc845OOecczBhwgRcf/31mDRpEoYOHWp7/P79+zF58mRceumltr+LIIjaASk3BEFIw4knnogDBw4AADIyMqDreszPe/TogZ9//hkdO3ZM+FLVyHL37bffxjzv22+/xQknnOD9CyAIIi2QckMQhHDs2bMHV1xxBa677jp07doV9evXx/Lly/H444/j//7v/wBUZUwtWLAAp59+OrKystC4cWNMnDgRF154Idq0aYPLL78cqqpi9erVWLNmDR566CHr97/11lvo1asXzjjjDLz22mtYunQpXnrpJb9eLkEQKYYMxQRBCEd5eTnuv/9+fPrpp9iwYQOOHDmC/Px8XHHFFbjnnntQp04dvP/++xg3bhw2b96M1q1bW6ngn3zyCR544AF8//33yMjIwPHHH4/rr78eI0aMAFBlKH7mmWcwb948LFq0CC1btsRjjz2GK6+80sdXTBBEKqHghiCIWoVdlhVBEMGCPDcEQRAEQQQKCm4IgiAIgggUZCgmCKJWQTvxBBF8SLkhCIIgCCJQUHBDEARBEESgoOCGIAiCIIhAQcENQRAEQRCBgoIbgiAIgiACBQU3BEEQBEEECgpuCIIgCIIIFBTcEARBEAQRKCi4IQiCIAgiUPx/F5kLR15srJYAAAAASUVORK5CYII=", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACVQUlEQVR4nO2dd3hUVfrHv3dmUoDQpCSAoSzFsgJSVoxlUcTFhsvakGWliKgoImJFBcSGDcR1VdYCuCsK6iKuK1ZWUBSlKCiriNJ/CKEZElpCZu7vj+TeuXPPmZszkJnz3sn7eZ48wM2d5Mzhzjnv+z1vMUzTNMEwDMMwDJMmBHQPgGEYhmEYpjph44ZhGIZhmLSCjRuGYRiGYdIKNm4YhmEYhkkr2LhhGIZhGCatYOOGYRiGYZi0go0bhmEYhmHSCjZuGIZhGIZJK9i4YRiGYRgmrWDjhmGYlHPWWWfhrLPO0j2MtOS+++6DYRi6h8EwWmHjhmEIM3PmTBiGYX9lZ2ejQ4cOGDlyJAoLC3UPz5Pvv/8e9913HzZu3Kh7KAzD1DBCugfAMEzV3H///WjTpg0OHTqExYsX47nnnsP8+fOxevVq1K5dW/fwpHz//feYOHEizjrrLLRu3Trmex9++KGeQTEMUyNg44ZhfMD555+P7t27AwCuueYaNGrUCFOmTMHbb7+NAQMGSF+zf/9+1KlTJ5XDVCYzM1P3EBiGSWP4WIphfEivXr0AABs2bAAADBkyBDk5OVi3bh0uuOAC1K1bFwMHDgRQYeTceuutyM/PR1ZWFo477jg88cQTME0z5mcePHgQo0aNQuPGjVG3bl1cfPHF2Lp1KwzDwH333Wfft2nTJtxwww047rjjUKtWLTRq1AiXX355zPHTzJkzcfnllwMAzj77bPtYbeHChQDkMTc7duzAsGHDkJubi+zsbHTu3Bkvv/xyzD0bN26EYRh44okn8Pzzz6Nt27bIysrC7373Oyxbtkxp7oqKijB69Gh7Ptq1a4dHH30UkUgEAGCaJs4++2w0adIEO3bssF9XVlaGjh07om3btti/f7/yXFjzYRgGFi9ejFGjRqFJkyZo0KABrrvuOpSVlaGoqAiDBg1Cw4YN0bBhQ9xxxx0x/z/O9/3kk0+iVatWqFWrFnr27InVq1crve9XXnkF3bp1Q61atXDMMcfgyiuvxJYtW5ReyzB+g5UbhvEh69atAwA0atTIvlZeXo4+ffrgjDPOwBNPPIHatWvDNE1cfPHF+OSTTzBs2DCcfPLJ+OCDD3D77bdj69atePLJJ+3XDxkyBK+//jquuuoqnHrqqVi0aBEuvPBC4XcvW7YMX3zxBa688koce+yx2LhxI5577jmcddZZ+P7771G7dm38/ve/x6hRo/DXv/4Vd999N0444QQAsP90c/DgQZx11ln4+eefMXLkSLRp0wZvvPEGhgwZgqKiItx8880x97/66qsoKSnBddddB8Mw8Nhjj+GSSy7B+vXrkZGREXfeDhw4gJ49e2Lr1q247rrr0LJlS3zxxRcYO3Ystm3bhqlTp8IwDEyfPh2dOnXC9ddfj7lz5wIAJkyYgP/9739YuHChrYipzIWTm266CXl5eZg4cSK+/PJLPP/882jQoAG++OILtGzZEg8//DDmz5+Pxx9/HCeddBIGDRoU8/p//OMfKCkpwY033ohDhw7hqaeeQq9evfDdd98hNzc37vt+6KGHMG7cOFxxxRW45pprsHPnTjz99NP4/e9/j2+++QYNGjSI+1qG8SUmwzBkmTFjhgnA/Pjjj82dO3eaW7ZsMWfPnm02atTIrFWrlvl///d/pmma5uDBg00A5l133RXz+nnz5pkAzAcffDDm+mWXXWYahmH+/PPPpmma5ooVK0wA5ujRo2PuGzJkiAnAnDBhgn3twIEDwjiXLFliAjD/8Y9/2NfeeOMNE4D5ySefCPf37NnT7Nmzp/3vqVOnmgDMV155xb5WVlZmFhQUmDk5OWZxcbFpmqa5YcMGE4DZqFEjc8+ePfa9b7/9tgnAfOedd2TTaPPAAw+YderUMdeuXRtz/a677jKDwaC5efNm+9rf//53e0xffvmlGQwGhflRnQvr/7FPnz5mJBKxrxcUFJiGYZjXX3+9fa28vNw89thjY+bHet/O/3PTNM2vvvrKBGDecsst9rUJEyaYzqV948aNZjAYNB966KGYcX733XdmKBQSrjNMOsDHUgzjA3r37o0mTZogPz8fV155JXJycvDWW2+hRYsWMfeNGDEi5t/z589HMBjEqFGjYq7feuutME0T7733HgDg/fffBwDccMMNMffddNNNwlhq1apl//3w4cPYvXs32rVrhwYNGuDrr78+ovc3f/585OXlxcQPZWRkYNSoUdi3bx8WLVoUc3//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", "text/plain": [ "
" ] diff --git a/examples/Implementing a Architecture.ipynb b/examples/Implementing a Architecture.ipynb index 6767f18..d02fe10 100644 --- a/examples/Implementing a Architecture.ipynb +++ b/examples/Implementing a Architecture.ipynb @@ -95,6 +95,18 @@ "For that, we start importing the necessary modules:" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import cst_python\n", + "except:\n", + " !python3 -m pip install cst_python" + ] + }, { "cell_type": "code", "execution_count": 19, diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb index b52cad5..573655e 100644 --- a/examples/Introduction to CST-Python.ipynb +++ b/examples/Introduction to CST-Python.ipynb @@ -18,6 +18,18 @@ "Lets start by importing the CST-Python and other required modules:" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import cst_python\n", + "except:\n", + " !python3 -m pip install cst_python" + ] + }, { "cell_type": "code", "execution_count": 1, diff --git a/examples/Publisher-Subscriber.ipynb b/examples/Publisher-Subscriber.ipynb index d820837..b91e83a 100644 --- a/examples/Publisher-Subscriber.ipynb +++ b/examples/Publisher-Subscriber.ipynb @@ -25,6 +25,18 @@ "Lets start by importing the necessary modules:" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import cst_python\n", + "except:\n", + " !python3 -m pip install cst_python" + ] + }, { "cell_type": "code", "execution_count": 1, From e3eff24e763ad5d806f9aeb58966677dbce8cfe0 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:11:47 -0300 Subject: [PATCH 18/59] "Open in" badges --- examples/Activation and Monitoring.ipynb | 6 +++++- examples/Implementing a Architecture.ipynb | 4 ++++ examples/Introduction to CST-Python.ipynb | 4 ++++ examples/Publisher-Subscriber.ipynb | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/examples/Activation and Monitoring.ipynb b/examples/Activation and Monitoring.ipynb index 6578a31..a30dcee 100644 --- a/examples/Activation and Monitoring.ipynb +++ b/examples/Activation and Monitoring.ipynb @@ -4,7 +4,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Activation" + "# Activation\n", + "\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Activation.ipynb)\n", + ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Activation.ipynb)\n", + ")" ] }, { diff --git a/examples/Implementing a Architecture.ipynb b/examples/Implementing a Architecture.ipynb index d02fe10..c40d68e 100644 --- a/examples/Implementing a Architecture.ipynb +++ b/examples/Implementing a Architecture.ipynb @@ -6,6 +6,10 @@ "source": [ "# Implementing a Architecture\n", "\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb)\n", + ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb)\n", + ")\n", + "\n", "A cognitive architecture in the CST is implemented using a combination of Codelets and Memories inside a Mind. Each Codelet will communicate with the others using only the Memories." ] }, diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb index 573655e..b731895 100644 --- a/examples/Introduction to CST-Python.ipynb +++ b/examples/Introduction to CST-Python.ipynb @@ -6,6 +6,10 @@ "source": [ "# Introduction to CST-Python\n", "\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb)\n", + ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb)\n", + ")\n", + "\n", "The CST (Cognitive Systems Toolkit) is a code toolkit for creating agents that implements Cognitive Architectures, that is, computational models of cognitive process in the mind of living beings. The core toolkit is the [Java CST](https://cst.fee.unicamp.br/), and CST-Python is a compatible implementation in Python.\n", "\n", "For building architectures, the CST defines three basic elements: Memory, Codelet and Mind, that will be presented in this tutorial." diff --git a/examples/Publisher-Subscriber.ipynb b/examples/Publisher-Subscriber.ipynb index b91e83a..8a376be 100644 --- a/examples/Publisher-Subscriber.ipynb +++ b/examples/Publisher-Subscriber.ipynb @@ -6,6 +6,10 @@ "source": [ "# Publish-Subscribe\n", "\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb)\n", + ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb)\n", + ")\n", + "\n", "Sometimes we wish that a codelet is only executed when its input value is changed. For that, we can use the publish-subscribe mechanism." ] }, From f67ba27f1bdf9f99fa065ff4a9fe55aa75ec08cc Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:29:59 -0300 Subject: [PATCH 19/59] Separate coverage check workflow --- .github/workflows/test.yml | 19 ++++++++++++++++++- tests/check_coverage.py | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b497ad2..772b740 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ on: branches: [ dev, main ] jobs: - build: + test: runs-on: ${{ matrix.os }} strategy: @@ -33,6 +33,23 @@ jobs: pytest --cov=cst_python --cov-report json shell: bash + - if: ${{matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'}} + name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: coverage_report + path: coverage.json + + coverage-check: + runs-on: ubuntu-latest + needs: + - test + + steps: + - name: Retrieve coverage report + uses: actions/download-artifact@v4 + with: + name: coverage_report - name: Coverage Check run: | python3 tests/check_coverage.py \ No newline at end of file diff --git a/tests/check_coverage.py b/tests/check_coverage.py index 7b59da5..8486a79 100644 --- a/tests/check_coverage.py +++ b/tests/check_coverage.py @@ -5,4 +5,6 @@ with open("coverage.json") as file: coverage_info = json.load(file) + print("Coverage:", coverage_info["totals"]["percent_covered"], "%") + assert coverage_info["totals"]["percent_covered"] > 75 \ No newline at end of file From b0e84e8f18c56fac22088ffd87d0c9a8b98e5e52 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:39:51 -0300 Subject: [PATCH 20/59] Change examples to fix tests --- .github/workflows/test.yml | 3 ++ examples/Activation and Monitoring.ipynb | 4 ++- examples/Implementing a Architecture.ipynb | 42 +++++++++++----------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 772b740..e2b7537 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,10 +17,13 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + cache: 'pip' + - name: Install dependencies run: | python3 -m pip install --upgrade pip diff --git a/examples/Activation and Monitoring.ipynb b/examples/Activation and Monitoring.ipynb index a30dcee..7ac2581 100644 --- a/examples/Activation and Monitoring.ipynb +++ b/examples/Activation and Monitoring.ipynb @@ -43,10 +43,12 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ + "from __future__ import annotations\n", + "\n", "import time # Sleep\n", "import math # Math operations\n", "\n", diff --git a/examples/Implementing a Architecture.ipynb b/examples/Implementing a Architecture.ipynb index c40d68e..2058243 100644 --- a/examples/Implementing a Architecture.ipynb +++ b/examples/Implementing a Architecture.ipynb @@ -101,7 +101,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -113,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -132,7 +132,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -191,7 +191,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -224,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -240,7 +240,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -284,7 +284,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -307,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -326,7 +326,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -350,7 +350,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 10, "metadata": { "tags": [ "equation1" @@ -363,7 +363,7 @@ "[nan, nan]" ] }, - "execution_count": 23, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 11, "metadata": { "tags": [ "equation2" @@ -401,7 +401,7 @@ "[0.0, 0.0]" ] }, - "execution_count": 24, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -409,7 +409,7 @@ "source": [ "a_mo.set_info(1)\n", "\n", - "time.sleep(0.020)\n", + "time.sleep(0.1)\n", "\n", "result_mo.get_info()" ] @@ -423,7 +423,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 12, "metadata": { "tags": [ "equation3" @@ -436,7 +436,7 @@ "[-0.0, 2.0]" ] }, - "execution_count": 25, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -446,7 +446,7 @@ "b_mo.set_info(8)\n", "c_mo.set_info(0)\n", "\n", - "time.sleep(0.020)\n", + "time.sleep(0.1)\n", "\n", "result_mo.get_info()" ] @@ -460,7 +460,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 13, "metadata": { "tags": [ "equation4" @@ -473,7 +473,7 @@ "[3.0, 3.0]" ] }, - "execution_count": 26, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -483,7 +483,7 @@ "b_mo.set_info(-6)\n", "c_mo.set_info(9)\n", "\n", - "time.sleep(0.020)\n", + "time.sleep(0.1)\n", "\n", "result_mo.get_info()" ] @@ -497,7 +497,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ From 90c4bf1cc5a75e1e5c40f29185ac00ac79bc844a Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:42:18 -0300 Subject: [PATCH 21/59] Remove pip cache from CI --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e2b7537..d3ee44a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,6 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - cache: 'pip' - name: Install dependencies run: | From 376e41141e5723614f0508e3cef9da6f9d104efd Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:47:20 -0300 Subject: [PATCH 22/59] Fix coverage pipeline --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d3ee44a..21608cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: python3 -m pip install --upgrade pip python3 -m pip install pytest python3 -m pip install pytest-cov - python3 -m pip install .[tests] + python3 -m pip install -e .[tests] - name: Tests run: | @@ -48,6 +48,8 @@ jobs: - test steps: + - uses: actions/checkout@v2 + - name: Retrieve coverage report uses: actions/download-artifact@v4 with: From e73489a7bd9abb72cb4f9aa2267023ec3b6b7d89 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:51:10 -0300 Subject: [PATCH 23/59] Update test_activation_and_monitoring.py --- tests/examples/test_activation_and_monitoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/test_activation_and_monitoring.py b/tests/examples/test_activation_and_monitoring.py index 1f0fca2..d311bb1 100644 --- a/tests/examples/test_activation_and_monitoring.py +++ b/tests/examples/test_activation_and_monitoring.py @@ -20,7 +20,7 @@ def test_activation(tb :TestbookNotebookClient): for i, (activation, input_value, sensory_output, action) in enumerate(zip(activation_hist, input_hist, sensory_output_hist, action_hist)): assert math.isclose(input_value, i/100) - assert math.isclose(activation, np.clip(input_value, 0.0, 1.0), abs_tol=0.021) + assert math.isclose(activation, np.clip(input_value, 0.0, 1.0), abs_tol=0.031) if i >= 50 and activation < 0.7: expected_sensory = last_sensory_output From ddfbc1b72a706297ef36427bdddeb7f26890d356 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:55:12 -0300 Subject: [PATCH 24/59] Change setup.cfg to pyproject.toml --- pyproject.toml | 41 +++++++++++++++++++++++++++++++++++++---- setup.cfg | 33 --------------------------------- 2 files changed, 37 insertions(+), 37 deletions(-) delete mode 100644 setup.cfg diff --git a/pyproject.toml b/pyproject.toml index b5a3c46..0931aee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,39 @@ [build-system] -requires = [ - "setuptools>=42", - "wheel" +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "cst_python" +version = "0.1.0" +authors = [{name = "H.IAAC", email = "hiaac@unicamp.br"}] +description = "Python module of the CST, the Cognitive Systems Toolkit, a toolkit for the construction of cognitive systems and cognitive architectures." +classifiers = [ + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", ] -build-backend = "setuptools.build_meta" \ No newline at end of file + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[project.urls] +Homepage = "https://hiaac.unicamp.br" +"Bug Tracker" = "https://github.com/H-IAAC/CST-Python/issues" +# Documentation = + +[project.optional-dependencies] +tests = ["mypy", "testbook", "ipython", "ipykernel", "numpy", "matplotlib"] + +[tool.setuptools] +include-package-data = true +package-dir = {"" = "src"} +# install_requires = +# numpy + +[tool.setuptools.packages.find] +where = ["src"] +namespaces = false diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index d997eed..0000000 --- a/setup.cfg +++ /dev/null @@ -1,33 +0,0 @@ -[metadata] -name = cst_python -version = 0.1.0 -author = H.IAAC -author_email = hiaac@unicamp.br -description = Python module of the CST, the Cognitive Systems Toolkit, a toolkit for the construction of cognitive systems and cognitive architectures. -long_description = file: README.md -long_description_content_type = text/markdown -url = https://hiaac.unicamp.br -project_urls = - Bug Tracker = https://github.com/H-IAAC/CST-Python/issues -# Documentation = -classifiers = - Programming Language :: Python :: 3 - Operating System :: OS Independent - Topic :: Scientific/Engineering - Topic :: Scientific/Engineering :: Artificial Intelligence - Intended Audience :: Science/Research - License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) - -[options] -include_package_data = True -package_dir = - = src -packages = find: -#install_requires = -# numpy - -[options.packages.find] -where = src - -[options.extras_require] -tests = mypy; testbook; ipython; ipykernel; numpy; matplotlib \ No newline at end of file From 80cc6528343b1d6251b90f57e98ae4b3a787d0a7 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:58:44 -0300 Subject: [PATCH 25/59] Auto package version --- pyproject.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0931aee..7711651 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,9 @@ [build-system] -requires = ["setuptools>=61.2"] +requires = ["setuptools>=61.2", "setuptools_scm>=8"] build-backend = "setuptools.build_meta" [project] name = "cst_python" -version = "0.1.0" authors = [{name = "H.IAAC", email = "hiaac@unicamp.br"}] description = "Python module of the CST, the Cognitive Systems Toolkit, a toolkit for the construction of cognitive systems and cognitive architectures." classifiers = [ @@ -15,6 +14,7 @@ classifiers = [ "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", ] +dynamic = ["version"] [project.readme] file = "README.md" @@ -37,3 +37,5 @@ package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] namespaces = false + +[tool.setuptools_scm] \ No newline at end of file From c6aaa0cd7d943be6dc7a782f5076712edfd4ea34 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 20:12:15 -0300 Subject: [PATCH 26/59] Fix examples badges --- examples/Activation and Monitoring.ipynb | 4 +--- examples/Implementing a Architecture.ipynb | 4 +--- examples/Introduction to CST-Python.ipynb | 4 +--- examples/Publisher-Subscriber.ipynb | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/examples/Activation and Monitoring.ipynb b/examples/Activation and Monitoring.ipynb index 7ac2581..46a6a96 100644 --- a/examples/Activation and Monitoring.ipynb +++ b/examples/Activation and Monitoring.ipynb @@ -6,9 +6,7 @@ "source": [ "# Activation\n", "\n", - "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Activation.ipynb)\n", - ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Activation.ipynb)\n", - ")" + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)](https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Activation%20and%20Monitoring.ipynb) [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python/blob/main/examples/Activation%20and%20Monitoring.ipynb)" ] }, { diff --git a/examples/Implementing a Architecture.ipynb b/examples/Implementing a Architecture.ipynb index 2058243..8c4d48f 100644 --- a/examples/Implementing a Architecture.ipynb +++ b/examples/Implementing a Architecture.ipynb @@ -6,9 +6,7 @@ "source": [ "# Implementing a Architecture\n", "\n", - "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb)\n", - ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb)\n", - ")\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)](https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb) [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python/blob/main/examples/Implementing%20a%20Architecture.ipynb)\n", "\n", "A cognitive architecture in the CST is implemented using a combination of Codelets and Memories inside a Mind. Each Codelet will communicate with the others using only the Memories." ] diff --git a/examples/Introduction to CST-Python.ipynb b/examples/Introduction to CST-Python.ipynb index b731895..13f4fe7 100644 --- a/examples/Introduction to CST-Python.ipynb +++ b/examples/Introduction to CST-Python.ipynb @@ -6,9 +6,7 @@ "source": [ "# Introduction to CST-Python\n", "\n", - "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb)\n", - ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb)\n", - ")\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)](https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb) [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python/blob/main/examples/Introduction%20to%20CST-Python.ipynb)\n", "\n", "The CST (Cognitive Systems Toolkit) is a code toolkit for creating agents that implements Cognitive Architectures, that is, computational models of cognitive process in the mind of living beings. The core toolkit is the [Java CST](https://cst.fee.unicamp.br/), and CST-Python is a compatible implementation in Python.\n", "\n", diff --git a/examples/Publisher-Subscriber.ipynb b/examples/Publisher-Subscriber.ipynb index 8a376be..09788fe 100644 --- a/examples/Publisher-Subscriber.ipynb +++ b/examples/Publisher-Subscriber.ipynb @@ -6,9 +6,7 @@ "source": [ "# Publish-Subscribe\n", "\n", - "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)]((https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb)\n", - ") [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)]((https://github.com/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb)\n", - ")\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)](https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb) [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python/blob/main/examples/Publisher-Subscriber.ipynb)\n", "\n", "Sometimes we wish that a codelet is only executed when its input value is changed. For that, we can use the publish-subscribe mechanism." ] From 3c5bcb38862c4fd74b3ddcfee05452d51c55c12e Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 18 Oct 2024 20:20:11 -0300 Subject: [PATCH 27/59] PyPI publish workflow --- .github/workflows/python-publish.yml | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/python-publish.yml diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..8fdbd62 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,66 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +name: Upload Python Package + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + release-build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Build release distributions + run: | + # NOTE: put your own distribution build steps here. + python -m pip install build + python -m build + + - name: Upload distributions + uses: actions/upload-artifact@v4 + with: + name: release-dists + path: dist/ + + pypi-publish: + runs-on: ubuntu-latest + + needs: + - release-build + + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + + # Dedicated environments with protections for publishing are strongly recommended. + environment: + name: pypi + # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status: + url: https://pypi.org/project/cst-python/ + + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 \ No newline at end of file From 5062c830ad95bf1090388a04d482a981016059b9 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:22:07 -0300 Subject: [PATCH 28/59] Create CITATION.cff --- CITATION.cff | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..08d5bfd --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,58 @@ +# This CITATION.cff file was generated with cffinit. +# Visit https://bit.ly/cffinit to generate yours today! + +cff-version: 1.2.0 +title: CST-Python +message: >- + If you use this software, please cite it using the + metadata from this file. +type: software +authors: + - given-names: Elton + family-names: Cardoso do Nascimento + email: e233840@dac.unicamp.br + affiliation: H.IAAC-UNICAMP + orcid: 'https://orcid.org/0009-0005-0480-6970' + - given-names: Paula + family-names: Dornhofer Paro Costa + email: paulad@unicamp.br + affiliation: H.IAAC-UNICAMP + orcid: 'https://orcid.org/0000-0002-1534-5744' +identifiers: + - type: doi + value: 10.5281/zenodo.14057065 +repository-code: 'https://github.com/H-IAAC/CST-Python' +repository-artifact: 'https://pypi.org/project/cst-python/' +abstract: >- + CST-Python is a Python module of the CST, the Cognitive + Systems Toolkit, a toolkit for the construction of + cognitive systems and cognitive architectures. +keywords: + - cognitive architecture + - cst + - toolkit + - python +license: LGPL-3.0 +references: + - title: "CST" + type: 'software' + repository-code: 'https://github.com/CST-Group/cst' + authors: + - given-names: Ricardo + family-names: Ribeiro Gudwin + - given-names: Klaus + family-names: Raizer + - given-names: André + family-names: Luís Ogando Paraense + - given-names: Suelen + family-names: Mapa de Paula + - given-names: Vera + family-names: Aparecida de Figueiredo + - given-names: Elisa + family-names: Calhau de Castro + - given-names: Eduardo + family-names: Fróes + - given-names: Wandemberg + family-names: Santana Pharaoh Gibaut + + \ No newline at end of file From f40dd07bdb6dadc8e3ab121ebe7012cace9a501a Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:25:18 -0300 Subject: [PATCH 29/59] Fix CITATION.cff DOI and URL --- CITATION.cff | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 08d5bfd..612ccab 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -18,9 +18,8 @@ authors: email: paulad@unicamp.br affiliation: H.IAAC-UNICAMP orcid: 'https://orcid.org/0000-0002-1534-5744' -identifiers: - - type: doi - value: 10.5281/zenodo.14057065 +doi: 10.5281/zenodo.14057065 +url: https://github.com/H-IAAC/CST-Python' repository-code: 'https://github.com/H-IAAC/CST-Python' repository-artifact: 'https://pypi.org/project/cst-python/' abstract: >- From 6359f80b8965bea7f338e3a4452eb0e4d7b0ff5f Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:32:30 -0300 Subject: [PATCH 30/59] README authors and acknowledgements --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e78cb65..eca6c10 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,12 @@ This project was developed as part of the Cognitive Architectures research line ## Authors -- (2023-) Elton Cardoso do Nascimento: M. Eng. student, FEEC-Unicamp +- (2023-) Elton Cardoso do Nascimento: M. Eng. student, FEEC-UNICAMP +- (Advisor, 2023-) Paula Dornhofer Paro Costa: Professor, FEEC-UNICAMP ## Acknowledgements -This project is part of the Hub for Artificial Intelligence and Cognitive Architectures -(H.IAAC- Hub de Inteligência Artificial e Arquiteturas Cognitivas). We acknowledge the -support of PPI-Softex/MCTI by grant 01245.013778/2020-21 through the Brazilian Federal Government. +Project supported by the brazilian Ministry of Science, Technology and Innovations, with resources from Law No. 8,248, of October 23, 1991 ## License From 9e2c1be54101d1212e1fecf8df969424a86ad65c Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 14:39:43 -0300 Subject: [PATCH 31/59] README DOI --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eca6c10..0b9b2cb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://img.shields.io/pypi/v/cst_python?style=for-the-badge)](https://pypi.org/project/cst_python) [![](https://img.shields.io/pypi/l/cst_python?style=for-the-badge)](https://github.com/H-IAAC/CST-Python/blob/main/LICENSE) [![](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python) +[![](https://img.shields.io/pypi/v/cst_python?style=for-the-badge)](https://pypi.org/project/cst_python) [![](https://img.shields.io/pypi/l/cst_python?style=for-the-badge)](https://github.com/H-IAAC/CST-Python/blob/main/LICENSE) [![](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python) [![](https://img.shields.io/badge/DOI-10.5281/zenodo.14057065-1082c3?style=for-the-badge)](https://doi.org/10.5281/zenodo.14057065) # CST-Python From e7ce34f78f7c1bb4839f366b996bf2c77c340e94 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:54:54 -0300 Subject: [PATCH 32/59] Configure documentation --- docs/.nojekyll | 0 docs/Makefile | 22 ++++++ docs/_static/index.css | 7 ++ docs/_templates/layout.html | 21 ++++++ docs/_templates/package.rst.jinja | 52 ++++++++++++++ docs/conf.py | 112 ++++++++++++++++++++++++++++++ docs/index.html | 5 ++ docs/index.rst | 27 +++++++ docs/install_doc_requirements.py | 10 +++ docs/make.bat | 42 +++++++++++ docs/readme_link.rst | 1 + docs/tear_down.py | 15 ++++ examples/README.md | 8 +++ 13 files changed, 322 insertions(+) create mode 100644 docs/.nojekyll create mode 100644 docs/Makefile create mode 100644 docs/_static/index.css create mode 100644 docs/_templates/layout.html create mode 100644 docs/_templates/package.rst.jinja create mode 100644 docs/conf.py create mode 100644 docs/index.html create mode 100644 docs/index.rst create mode 100644 docs/install_doc_requirements.py create mode 100644 docs/make.bat create mode 100644 docs/readme_link.rst create mode 100644 docs/tear_down.py create mode 100644 examples/README.md diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..4199b8b --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,22 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -j 4 +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @sphinx-apidoc --force -e -E -M --templatedir=_templates ../src -o auto_doc + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @python tear_down.py \ No newline at end of file diff --git a/docs/_static/index.css b/docs/_static/index.css new file mode 100644 index 0000000..5540163 --- /dev/null +++ b/docs/_static/index.css @@ -0,0 +1,7 @@ +/* necessary to remove the duplicated toctree entries created by referencing index in the sphinx index.rst */ +.wy-menu-vertical > ul > li:nth-child(1), +.wy-menu-vertical > ul > li:nth-child(2), +.wy-nav-content .toctree-wrapper > ul > li:nth-child(1), +.wy-nav-content .toctree-wrapper > ul > li:nth-child(2) { + display: none; +} \ No newline at end of file diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 0000000..39e0a58 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,21 @@ +{% extends "!layout.html" %} + {% block footer %} {{ super() }} + + +{% endblock %} diff --git a/docs/_templates/package.rst.jinja b/docs/_templates/package.rst.jinja new file mode 100644 index 0000000..2563f72 --- /dev/null +++ b/docs/_templates/package.rst.jinja @@ -0,0 +1,52 @@ +{%- macro automodule(modname, options) -%} +.. automodule:: {{ modname }} +{%- for option in options %} + :{{ option }}: +{%- endfor %} +{%- endmacro %} + +{%- macro toctree(docnames) -%} +.. toctree:: + :maxdepth: {{ maxdepth }} +{% for docname in docnames %} + {{ docname }} +{%- endfor %} +{%- endmacro %} + +{%- if is_namespace %} +{{- [pkgname, "namespace"] | join(" ") | e | heading }} +{% else %} +{{- [pkgname, "package"] | join(" ") | e | heading }} +{% endif %} + +{%- if is_namespace %} +.. py:module:: {{ pkgname }} +{% endif %} + +{%- if modulefirst and not is_namespace %} +{{ automodule(pkgname, automodule_options) }} +{% endif %} + +{%- if subpackages %} +{{ toctree(subpackages) }} +{% endif %} + +{%- if submodules %} +{% if separatemodules %} +{{ toctree(submodules) }} +{% else %} +{%- for submodule in submodules %} +{% if show_headings %} +{{- [submodule, "module"] | join(" ") | e | heading(2) }} +{% endif %} +{{ automodule(submodule, automodule_options) }} +{% endfor %} +{%- endif %} +{%- endif %} + +{%- if not modulefirst and not is_namespace %} +Module contents +--------------- + +{{ automodule(pkgname, automodule_options) }} +{% endif %} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..ca99f78 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,112 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +from importlib.metadata import version as get_version +sys.path.insert(0, os.path.abspath('../src')) + +# -- Project information ----------------------------------------------------- + +project = 'CST-Python' +copyright = '2024, H.IAAC' +author = 'EltonCN, pdpcosta' + +# The full version, including alpha/beta/rc tags +release: str = get_version("cst_python") +# for example take major/minor +version: str = release + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', #Docs modules + 'sphinx_mdinclude', #Markdown + 'sphinx.ext.napoleon', #NumPy/Google Docs Styles + 'sphinx.ext.viewcode', #Source code + "nbsphinx", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', "README.md"] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_theme_options = { + "collapse_navigation" : False +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +source_suffix = ['.rst', '.md'] + +def skip(app, what, name, obj, would_skip, options): + if name == "__init__": + return False + return would_skip + +def setup(app): + + app.config.m2r_parse_relative_links = True + app.connect("autodoc-skip-member", skip) + + +sys.path.insert(0, os.path.abspath('.')) + +nbsphinx_execute = 'never' + +# Parse Markdown files, creating copys with corrected links +#from markdown_parser import parse_files +#parse_files() + +import shutil + +print("Coping examples into docs/_examples") + +def all_but_ipynb(dir, contents): + result = [] + for c in contents: + if os.path.isfile(os.path.join(dir,c)) and (not (c.endswith(".ipynb") or c.endswith(".png"))): + result += [c] + return result + +project_root = "../" + +shutil.rmtree(os.path.join(project_root, "docs/_examples"), ignore_errors=True) +shutil.copytree(os.path.join(project_root, "examples"), + os.path.join(project_root, "docs/_examples"), + ignore=all_but_ipynb) + +try: + os.remove("README.md") +except: + pass + +shutil.copyfile(os.path.join(project_root, "README.md"), os.path.join(project_root, "docs/README.md")) +shutil.copyfile(os.path.join(project_root,"examples", "README.md"), os.path.join(project_root, "docs/Examples.md")) diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..dad15b1 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..63c77b1 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,27 @@ +.. include:: readme_link.rst + +.. toctree:: + :maxdepth: 4 + :caption: Getting started + :hidden: + + readme_link + self + +.. toctree:: + :maxdepth: 1 + :caption: Examples + :hidden: + + Examples.md + _examples/Introduction to CST-Python + _examples/Implementing a Architecture + _examples/Publisher-Subscriber + _examples/Activation and Monitoring + +.. toctree:: + :maxdepth: 4 + :caption: Reference + :hidden: + + auto_doc/cst_python diff --git a/docs/install_doc_requirements.py b/docs/install_doc_requirements.py new file mode 100644 index 0000000..9bdd4c7 --- /dev/null +++ b/docs/install_doc_requirements.py @@ -0,0 +1,10 @@ +import subprocess +import sys +import configparser +import os + +config = configparser.ConfigParser() +config.read(os.path.join("..", "setup.cfg")) +packages = config["options.extras_require"]["doc_generation"] + +subprocess.check_call([sys.executable, "-m", "pip", "install"]+packages.split(";")) \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..6d81678 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,42 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=python3.11 -m sphinx build +) +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + set SPHINXBUILD=python -m sphinx build +) + +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +sphinx-apidoc --force -e -E -M --templatedir=_templates ../src -o auto_doc +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -j 4 +python3.11 tear_down.py +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd \ No newline at end of file diff --git a/docs/readme_link.rst b/docs/readme_link.rst new file mode 100644 index 0000000..e1c8d01 --- /dev/null +++ b/docs/readme_link.rst @@ -0,0 +1 @@ +.. mdinclude:: README.md \ No newline at end of file diff --git a/docs/tear_down.py b/docs/tear_down.py new file mode 100644 index 0000000..83e95da --- /dev/null +++ b/docs/tear_down.py @@ -0,0 +1,15 @@ +import shutil +import os + + +for path in ["_examples", "auto_doc"]: + try: + shutil.rmtree(path) + except Exception: + pass + +for path in ["README.md", "Examples.md"]: + try: + os.remove(path) + except Exception: + pass \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..2116e3e --- /dev/null +++ b/examples/README.md @@ -0,0 +1,8 @@ +# Examples + +Here we have some examples of how to use the CST-Python: + +- [Introduction to CST-Python](https://h-iaac.github.io/CST-Python/_build/html/_examples/Introduction%20to%20CST-Python.html): what is CST-Python, and basics about how to use it. +- [Implementing a Architecture](https://h-iaac.github.io/CST-Python/_build/html/_examples/Implementing%20a%20Architecture.html): how to implement a cognitive architecture using CST-Python. +- [Publisher-Subscriber](https://h-iaac.github.io/CST-Python/_build/html/_examples/Publisher-Subscriber.html): using the publisher-subscriber mechanism for synchronous codelets. +- [Activation and Monitoring](https://h-iaac.github.io/CST-Python/_build/html/_examples/Activation%20and%20Monitoring.html): using codelet's activation value and monitoring the agent. \ No newline at end of file From c3317d225d55e7179ae80028925fdbfe9d85878e Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Fri, 8 Nov 2024 15:54:59 -0300 Subject: [PATCH 33/59] Codelet doc --- src/cst_python/core/entities/codelet.py | 292 +++++++++++++++++++++++- 1 file changed, 288 insertions(+), 4 deletions(-) diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index ada9aa0..a47d5ba 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -15,9 +15,32 @@ #@alias.aliased class Codelet(MemoryObserver): #(abc.ABC) is not necessary + ''' + The **Codelet** class, together with the **MemoryObject** + class and the **Mind** class is one of the most important classes + in the CST toolkit. According to the Baars-Franklin architecture, + consciousness is the emergence of a serial stream on top of a parallel set of + interacting devices. In the Baars-Franklin architectures, such devices are + called "codelets", which are small pieces of code specialized in performing + simple tasks. In a CST-built cognitive architecture, everything is either a + **Codelet** or a **MemoryObject**. Codelets are used to + implement every kind of processing in the architecture. + + Codelets have two kinds of inputs: standard inputs and broadcast inputs. + Standard inputs are used to convey access to MemoryObjects. Broadcast inputs + come from consciousness, and can also be used. Nevertheless, Standard inputs + are usually fixed (but can be changed through learning mechanisms), and + Broadcast inputs change all the time, due to the consciousness mechanism. + Codelets also have outputs. Outputs are used for the Codelets to write or + generate new MemoryObjects. Codelets also have an Activation level, which can + be used in some situations. + ''' _last_id = 0 def __init__(self) -> None: + ''' + Codelet's init. + ''' self._threshold = 0.0 self._inputs : List[Memory] = [] self._outputs : List[Memory] = [] @@ -44,16 +67,25 @@ def __init__(self) -> None: #@alias.alias("should_loop", "shouldLoop", "is_loop", "isLoop") @property def loop(self) -> bool: + ''' + Defines if proc() should be automatically called in a loop + ''' + return self._loop #@alias.alias("set_loop", "setLoop") @loop.setter - def loop(self, value) -> None: + def loop(self, value:bool) -> None: self._loop = value #@alias.alias("get_enabled", "getEnabled") @property def enabled(self) -> bool: + ''' + A codelet is a priori enabled to run its proc(). However, if it tries to + read from a given output and fails, it becomes not able to do so. + ''' + return self._enabled #@alias.alias("set_enabled", "setEnabled") @@ -67,6 +99,10 @@ def enabled(self, value:bool) -> None: #@alias.alias("get_name", "getName") @property def name(self) -> str: + ''' + Gives this codelet a name, mainly for debugging purposes + ''' + return self._name #@alias.alias("set_name", "setName") @@ -77,6 +113,10 @@ def name(self, value:str) -> None: #@alias.alias("get_activation", "getActivation") @property def activation(self) -> float: + ''' + Activation level of the Codelet. Ranges from 0.0 to 1.0. + ''' + return self._activation #@alias.alias("set_activation", "setActivation") @@ -96,6 +136,10 @@ def activation(self, value:float): #@alias.alias("get_inputs", "getInputs") @property def inputs(self) -> List[Memory]: + ''' + Input memories, the ones that are read. + ''' + return self._inputs #@alias.alias("set_inputs", "setInputs") @@ -106,6 +150,10 @@ def inputs(self, value:List[Memory]): #@alias.alias("get_outputs", "getOutputs") @property def outputs(self) -> List[Memory]: + ''' + Output memories, the ones that are written. + ''' + return self._outputs #@alias.alias("set_outputs", "setOutputs") @@ -116,6 +164,12 @@ def outputs(self, value:List[Memory]): #@alias.alias("get_threshold", "getThreshold") @property def threshold(self) -> float: + ''' + Threshold of the codelet, which is used to decide if it runs or not. If + activation is equal or greater than activation, codelet runs + proc(). Ranges from 0.0 to 1.0. + ''' + return self._threshold #@alias.alias("set_threshold", "setThreshold") @@ -135,6 +189,13 @@ def threshold(self, value:float): #@alias.alias("get_time_step", "getTime_step") @property def time_step(self) -> float: + ''' + If the proc() method is set to be called automatically in a loop, this + variable stores the time step for such a loop. A timeStep of value 0 + means that the proc() method should be called continuously, without + interval. + ''' + return self._time_step #@alias.alias("set_time_step", "setTime_step") @@ -147,6 +208,10 @@ def time_step(self, value:float): #Problem: get_broadcast method overload @property def broadcast(self) -> List[Memory]: + ''' + Input memories, the ones that were broadcasted. + ''' + return self._broadcast #@alias.alias("set_broadcast", "setBroadcast") @@ -157,6 +222,10 @@ def broadcast(self, value:List[Memory]) -> None: #@alias.alias("IsProfiling") @property def profiling(self) -> bool: + ''' + Option for profiling execution times. + ''' + return self._is_profiling #@alias.alias("set_profiling", "setProfiling") @@ -169,6 +238,10 @@ def profiling(self, value:bool): @property def is_memory_observer(self) -> bool: + ''' + Defines if codelet is a memory observer (runs when memory input changes). + ''' + return self._is_memory_observer @is_memory_observer.setter @@ -181,18 +254,36 @@ def is_memory_observer(self, value) -> None: #@alias.alias("accessMemoryObjects") @abc.abstractmethod def access_memory_objects(self) -> None: + ''' + This method is used in every Codelet to capture input, broadcast and + output MemoryObjects which shall be used in the proc() method. This + abstract method must be implemented by the user. Here, the user must get + the inputs and outputs it needs to perform proc. + ''' ... #@alias.alias("calculateActivation") @abc.abstractmethod def calculate_activation(self) -> None: + ''' + This abstract method must be implemented by the user. Here, the user must + calculate the activation of the codelet before it does what it is + supposed to do in proc(). + ''' ... @abc.abstractmethod def proc(self) -> None: + ''' + Main Codelet function, to be implemented in each subclass. + ''' ... def run(self) -> None: + ''' + When first activated, the thread containing this codelet runs the proc() + method. + ''' try: self._scheduled_run() @@ -200,13 +291,18 @@ def run(self) -> None: traceback.print_exception(e) def start(self) -> None: - + ''' + Starts this codelet execution. + ''' self._thread.start() #thread.join(0.0) def stop(self): + ''' + Tells this codelet to stop looping (stops running). + ''' self.loop = False if self._thread.is_alive(): @@ -214,14 +310,44 @@ def stop(self): #@alias.alias("impendingAccess") def impending_acess(self, accessing:Codelet) -> bool: + ''' + Safe access to other Codelets through reentrant locks. + + Args: + accessing (Codelet): the Codelet accessing. + + Raises: + NotImplementedError: this method is not implemented yet. + + Returns: + bool: True if is impeding access. + ''' raise NotImplementedError() #@alias.alias("impendingAccessBuffer") def impending_access_buffer(self, accessing:MemoryBuffer) -> bool: + ''' + Safe access to MemoryBuffers through reentrant locks. + + Args: + accessing (MemoryBuffer): the Memory Buffer accessing. + + Raises: + NotImplementedError: this method is not implemented yet. + + Returns: + bool: True if is impending access. + ''' raise NotImplementedError() #@alias.alias("addInput") def add_input(self, memory:Memory) -> None: + ''' + Add one memory to the input list. + + Args: + memory (Memory): one input to set. + ''' if self._is_memory_observer: memory.add_memory_observer(self) @@ -229,6 +355,12 @@ def add_input(self, memory:Memory) -> None: #@alias.alias("addInputs") def add_inputs(self, memories:List[Memory]) -> None: + ''' + Add a list of memories to the input list. + + Args: + memories (List[Memory]): a list of inputs. + ''' if self._is_memory_observer: for memory in memories: memory.add_memory_observer(self) @@ -237,26 +369,62 @@ def add_inputs(self, memories:List[Memory]) -> None: #@alias.alias("addOutput") def add_output(self, memory:Memory) -> None: + ''' + Add a memory to the output list. + + Args: + memory (Memory): one output to set. + ''' self._outputs.append(memory) #@alias.alias("removesOutput") def removes_output(self, memory:Memory) -> None: + ''' + Removes a given memory from the output list. + + Args: + memory (Memory): the memory to be removed from output. + ''' self._outputs.remove(memory) #@alias.alias("removesInput") def removes_input(self, memory:Memory) -> None: + ''' + Removes a given memory from the input list. + + Args: + memory (Memory): the memory to be removed from input. + ''' self._inputs.remove(memory) #@alias.alias("removeFromOutput") def remove_from_output(self, memories:List[Memory]) -> None: + ''' + Removes a given memory list from the output list. + + Args: + memories (List[Memory]): the list of memories to be removed from output. + ''' self._outputs = [m for m in self._outputs if m not in memories] #@alias.alias("removeFromInput") def remove_from_input(self, memories:List[Memory]) -> None: + ''' + Removes a given list of memories from the input list. + + Args: + memories (List[Memory]): the list of memories to be removed from input. + ''' self._inputs = [m for m in self._inputs if m not in memories] #@alias.alias("addOutputs") def add_outputs(self, memories:List[Memory]) -> None: + ''' + Adds a list of memories to the output list. + + Args: + memories (List[Memory]): the list of memories to be added to the output. + ''' if self._is_memory_observer: for memory in memories: memory.add_memory_observer(self) @@ -265,6 +433,15 @@ def add_outputs(self, memories:List[Memory]) -> None: #@alias.alias("getOutputsOfType") def get_outputs_of_type(self, type:str) -> List[Memory]: + ''' + Gets a list of output memories of a certain type. + + Args: + type (str): the type of memories to be fetched from the output. + + Returns: + List[Memory]: the list of all memory objects in output of a given type. + ''' outputs_of_type = [] if self._outputs is not None: @@ -276,6 +453,15 @@ def get_outputs_of_type(self, type:str) -> List[Memory]: #@alias.alias("getInputsOfType") def get_inputs_of_type(self, type:str) -> List[Memory]: + ''' + Gets a list of input memories of a certain type. + + Args: + type (str): the type of memories to be retrieved. + + Returns: + List[Memory]: the list of memory objects in input of a given type. + ''' inputs_of_type = [] if self._inputs is not None: @@ -287,6 +473,16 @@ def get_inputs_of_type(self, type:str) -> List[Memory]: #@alias.alias("getBroadcast") def get_broadcast(self, name:str) -> Memory: + ''' + Returns a specific memory (with the given name) from the broadcast list + of the Codelet. + + Args: + name (str): the name of a memory to be retrieved at the broadcast list. + + Returns: + Memory: the memory. + ''' if self._broadcast is not None: for m in self._broadcast: if m.compare_name(name): @@ -294,6 +490,12 @@ def get_broadcast(self, name:str) -> Memory: #@alias.alias("addBroadcast") def add_broadcast(self, memory:Memory) -> None: + ''' + Adds a memory to the broadcast list. + + Args: + memory (Memory): one broadcast input to set. + ''' if self._is_memory_observer: memory.add_memory_observer(self) @@ -301,6 +503,12 @@ def add_broadcast(self, memory:Memory) -> None: #@alias.alias("addBroadcasts") def add_broadcasts(self, memories:List[Memory]) -> None: + ''' + Adds a list of memories to the broadcast input list. + + Args: + memories (List[Memory]): one input to set. + ''' if self._is_memory_observer: for memory in memories: memory.add_memory_observer(self) @@ -310,6 +518,12 @@ def add_broadcasts(self, memories:List[Memory]) -> None: #@alias.alias("getThreadName") def get_thread_name(self) -> str: + ''' + Gets the codelet's thread name, for debugging purposes. + + Returns: + str: The name of the thread running this Codelet. + ''' return threading.current_thread().name #@alias.alias("to_string", "toString") @@ -338,6 +552,22 @@ def __str__(self) -> str: def _get_memory(self, search_list:List[Memory], type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory: + ''' + This method returns an memory from a list. If it couldn't + find the given M, it sets this codelet as not able to perform proc(), and + keeps trying to find it. + + Can search by the memory's name, or type and index. + + Args: + search_list (List[Memory]): list to search memories. + type (Optional[str], optional): type of memory it needs. If None, searches by the name. Defaults to None. + index (Optional[int], optional): position of memory in the sublist. If None, searches by the name. Defaults to None. + name (Optional[str], optional): the name of the memory being searched. If None, searches by the type and index. Defaults to None. + + Returns: + Memory|None: the memory searched or None if not found. + ''' found_MO = None @@ -368,19 +598,64 @@ def _get_memory(self, search_list:List[Memory], type:Optional[str]=None, #@alias.alias("getInput") def get_input(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory: + ''' + This method returns an input memory from its input list. If it couldn't + find the given M, it sets this codelet as not able to perform proc(), and + keeps trying to find it. + + Args: + type (Optional[str], optional): type of memory it needs. If None, searches by the name. Defaults to None. + index (Optional[int], optional): position of memory in the sublist. If None, searches by the name. Defaults to None. + name (Optional[str], optional): the name of the memory being searched. If None, searches by the type and index. Defaults to None. + + Returns: + Memory|None: the memory searched or None if not found. + ''' return self._get_memory(self._inputs, type, index, name) #@alias.alias("getOutput") - def get_output(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory: + def get_output(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory|None: + ''' + This method returns an output memory from its output list. If it couldn't + find the given M, it sets this codelet as not able to perform proc(), and + keeps trying to find it. + + Args: + type (Optional[str], optional): type of memory it needs. If None, searches by the name. Defaults to None. + index (Optional[int], optional): position of memory in the sublist. If None, searches by the name. Defaults to None. + name (Optional[str], optional): the name of the memory being searched. If None, searches by the type and index. Defaults to None. + + Returns: + Memory|None: the memory searched or None if not found. + ''' return self._get_memory(self._outputs, type, index, name) #@alias.alias("getBroadcast") - def get_broadcast(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory: + def get_broadcast(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory|None: + ''' + This method returns an broadcast memory from its broadcast list. If it couldn't + find the given M, it sets this codelet as not able to perform proc(), and + keeps trying to find it. + + Args: + type (Optional[str], optional): type of memory it needs. If None, searches by the name. Defaults to None. + index (Optional[int], optional): position of memory in the sublist. If None, searches by the name. Defaults to None. + name (Optional[str], optional): the name of the memory being searched. If None, searches by the type and index. Defaults to None. + + Returns: + Memory|None: the memory searched or None if not found. + ''' return self._get_memory(self._broadcast, type, index, name) #@alias.alias("setPublishSubscribe") def set_publish_subscribe(self, enable:bool) -> None: + ''' + Defines if codelet runs in publish-subscribe mode, executing when any input changes. + + Args: + enable (bool): True if should run in publish-subscribe mode. + ''' if enable: self.is_memory_observer = True @@ -403,6 +678,12 @@ def set_publish_subscribe(self, enable:bool) -> None: #@alias.alias("setCodeletProfiler") def set_codelet_profiler(self, *args, **kargs) -> None: + ''' + Sets Codelet Profiler + + Raises: + NotImplementedError: this method is not implemented yet. + ''' raise NotImplementedError() @@ -412,6 +693,9 @@ def _raise_exception(self) -> None: #@alias.alias("notifyCodelet") def notify_codelet(self) -> None: + ''' + Runs when codelet is a memory observer and memory input changes + ''' try: if self._is_profiling: start_time = time.time() From 1d4b893bb8fdf0c4de2b33b0f0021bf839887875 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:00:55 -0300 Subject: [PATCH 34/59] Core code documentation --- src/cst_python/core/entities/coalition.py | 7 + src/cst_python/core/entities/code_rack.py | 55 ++++++++ src/cst_python/core/entities/memory.py | 88 ++++++++++++ src/cst_python/core/entities/memory_buffer.py | 5 + .../core/entities/memory_container.py | 12 ++ src/cst_python/core/entities/memory_object.py | 34 +++++ src/cst_python/core/entities/mind.py | 127 ++++++++++++++++++ src/cst_python/core/entities/raw_memory.py | 93 +++++++++++++ 8 files changed, 421 insertions(+) diff --git a/src/cst_python/core/entities/coalition.py b/src/cst_python/core/entities/coalition.py index f6b9733..47022af 100644 --- a/src/cst_python/core/entities/coalition.py +++ b/src/cst_python/core/entities/coalition.py @@ -1,4 +1,11 @@ class Coalition: + ''' + A Coalition is a group of Codelets which are gathered in order to perform a + task by summing up their abilities or to form a specific context. + + In CST, two codelets belong to the same coalition when they share information + - pragmatically, when they write in and read from the same memory object. + ''' def __init__(self) -> None: raise NotImplementedError() \ No newline at end of file diff --git a/src/cst_python/core/entities/code_rack.py b/src/cst_python/core/entities/code_rack.py index 93de444..e609e44 100644 --- a/src/cst_python/core/entities/code_rack.py +++ b/src/cst_python/core/entities/code_rack.py @@ -7,12 +7,22 @@ class CodeRack: + ''' + Following Hofstadter and Mitchell + "The copycat project: A model of mental fluidity and analogy-making". Pool of + all alive codelets in the system. The whole arena in the Baars-Franklin + metaphor. + ''' + def __init__(self) -> None: self._all_codelets :List[Codelet] = [] #@alias.alias("getAllCodelets", "get_all_codelets") @property def all_codelets(self) -> List[Codelet]: + ''' + List of all alive codelets in the system + ''' return self._all_codelets #@alias.alias("setAllCodelets", "set_all_codelets") @@ -22,10 +32,26 @@ def all_codelets(self, value:List[Codelet]) -> None: #@alias.alias("add_codelet") def add_codelet(self, codelet:Codelet) -> None: + ''' + Adds a new Codelet to the Coderack + + Args: + codelet (Codelet): codelet to be added. + ''' self._all_codelets.append(codelet) #@alias.alias("insertCodelet") def insert_codelet(self, codelet:Codelet) -> Codelet: + ''' + Creates a codelet and adds it to this coderack. + + Args: + codelet (Codelet): codelet to be created. + + Returns: + Codelet: the own codelet inserted, if it is needed to concatenate to + further methods calls. + ''' self.add_codelet(codelet) return codelet @@ -34,6 +60,20 @@ def insert_codelet(self, codelet:Codelet) -> Codelet: def create_codelet(self, activation:float, broadcast:List[Memory], inputs:List[Memory], outputs:List[Memory], codelet:Codelet) -> Codelet: + ''' + Creates a codelet and adds it to this coderack. + + Args: + activation (float): codelet's activation. + broadcast (List[Memory]): list of memory objects which were broadcast lately (treated as + input memories). + inputs (List[Memory]): list of input memories. + outputs (List[Memory]): list o output memories. + codelet (Codelet): codelet to be created. + + Returns: + Codelet: the codelet created. + ''' try: codelet.activation = activation @@ -50,18 +90,33 @@ def create_codelet(self, activation:float, broadcast:List[Memory], #@alias.alias("destroyCodelet") def destroy_codelet(self, codelet:Codelet) -> None: + ''' + Removes a codelet from coderack. + + Args: + codelet (Codelet): the codelet to be destroyed. + ''' codelet.stop() self._all_codelets.remove(codelet) #@alias.alias("shutDown", "shut_down") def shutdow(self): + ''' + Destroys all codelets. Stops CodeRack's thread. + ''' self.stop() self._all_codelets.clear() def start(self) -> None: + ''' + Starts all codelets in coderack. + ''' for codelet in self._all_codelets: codelet.start() def stop(self) -> None: + ''' + Stops all codelets within CodeRack. + ''' for codelet in self._all_codelets: codelet.stop() diff --git a/src/cst_python/core/entities/memory.py b/src/cst_python/core/entities/memory.py index 15da8a9..f12b58c 100644 --- a/src/cst_python/core/entities/memory.py +++ b/src/cst_python/core/entities/memory.py @@ -5,65 +5,153 @@ from.memory_observer import MemoryObserver class Memory(abc.ABC): + ''' + This class represents the interface for all kinds of memories that exist in + CST. In order to be recognized as a Memory, an entity must implement this + interface. Currently, there are to kinds of Memory: MemoryObject and + MemoryContainer. However, other forms of Memory might come up as CST + develops. + ''' #@alias.alias("getI", "get_I") @abc.abstractmethod def get_info(self) -> Any: + ''' + Gets the info inside this memory. + + Returns: + Any: the info in memory. + ''' ... #@alias.alias("setT", "set_I") @abc.abstractmethod def set_info(self, value:Any) -> int: + ''' + Sets the info inside this Memory. + + Args: + value (Any): the updated info to set in memory. + + Returns: + int: index of the memory inside the container or -1 if not a + container. + ''' ... #@alias.alias("getEvaluation") @abc.abstractmethod def get_evaluation(self) -> float: + ''' + Gets the evaluation of this memory. + + Returns: + float: the evaluation of this memory. + ''' ... #@alias.alias("getName") @abc.abstractmethod def get_name(self) -> str: + ''' + Gets the type of this memory. + + Returns: + str: the type of the memory. + ''' ... #@alias.alias("setName") @abc.abstractmethod def set_name(self, name:str) -> None: + ''' + Sets the name of this memory. + + Args: + name (str): the value to be set as name. + ''' ... #@alias.alias("setEvaluation") @abc.abstractmethod def set_evaluation(self, evaluation:float) -> None: + ''' + Sets the evaluation of this memory. + + Args: + evaluation (float): the value to be set as evaluation. + ''' ... #@alias.alias("getTimestamp") @abc.abstractmethod def get_timestamp(self) -> int: + ''' + Gets the timestamp of this Memory. + + Returns: + int: the timestamp of this Memory. + ''' ... #@alias.alias("addMemoryObserver") @abc.abstractmethod def add_memory_observer(self, observer:MemoryObserver) -> None: + ''' + Add a memory observer to its list. + + Args: + observer (MemoryObserver): MemoryObserver to be added. + ''' ... #@alias.alias("removeMemoryObserver") @abc.abstractmethod def remove_memory_observer(self, observer:MemoryObserver) -> None: + ''' + Remove a memory observer from its list. + + Args: + observer (MemoryObserver): MemoryObserver to be removed. + ''' ... #@alias.alias("getId") @abc.abstractmethod def get_id(self) -> int: + ''' + Gets the id of the Memory. + + Returns: + int: the id of the Memory. + ''' ... #@alias.alias("setId") @abc.abstractmethod def set_id(self, memory_id:int) -> None: + ''' + Sets the id of the Memory. + + Args: + memory_id (int): the id of the Memory to set. + ''' ... def compare_name(self, other_name:str) -> bool: + ''' + Compares tha name of this memory with another. + + Comparation is case insensitive. + + Args: + other_name (str): name of the other memory. + + Returns: + bool: True if is the same name. + ''' if self._name is None: return False diff --git a/src/cst_python/core/entities/memory_buffer.py b/src/cst_python/core/entities/memory_buffer.py index d60b418..1ed1687 100644 --- a/src/cst_python/core/entities/memory_buffer.py +++ b/src/cst_python/core/entities/memory_buffer.py @@ -1,3 +1,8 @@ class MemoryBuffer: + ''' + MemoryBuffer is a generic holder for memory objects. It may be used to + produce sensory buffers, action buffers or other very short term memory + structures. + ''' def __init__(self) -> None: raise NotImplementedError() \ No newline at end of file diff --git a/src/cst_python/core/entities/memory_container.py b/src/cst_python/core/entities/memory_container.py index fe7bbc5..235fd76 100644 --- a/src/cst_python/core/entities/memory_container.py +++ b/src/cst_python/core/entities/memory_container.py @@ -1,6 +1,18 @@ from .memory import Memory class MemoryContainer(Memory): + ''' + This class represents a Memory Container. The Memory Container is responsible + for implementing an important element in the Dynamic Subsumption mechanism + used in CST. All the Memory Objects in a Container are of the same type, and + hold the same parameters. The only differences among them are that they were + generated by a different codelet, and they might have different evaluations. + An evaluation is an inner parameter from any Memory Object, which holds a + value (usually a real value between 0 and 1) that measures a relative + importance given by the codelet, and which is used by the Evaluation codelet + within the Container to decide which from all input Memory Objects will be + sent to the output. + ''' def __init__(self) -> None: super().__init__() diff --git a/src/cst_python/core/entities/memory_object.py b/src/cst_python/core/entities/memory_object.py index 48a8160..cf12eab 100644 --- a/src/cst_python/core/entities/memory_object.py +++ b/src/cst_python/core/entities/memory_object.py @@ -8,8 +8,31 @@ from .memory_observer import MemoryObserver class MemoryObject(Memory): + ''' + A Memory Object is a generic information holder, acting as a sign or an + internal representation, which is responsible to store any auxiliary or + perennial information necessary for the cognitive architecture to perform its + behavior. Codelets and Memory Objects are intrinsically coupled to each + other, in the sense that Memory Objects hold the information necessary for + the Codelets to run, and are also the placeholders of any new information + generated by the codelet. The main property being hold by a Memory Object is + its Information (I). This information can be simply a number, or hold complex + structures like lists, trees, graphs or whole networks. In our computational + implementation, the information I is a generic Java Object, which can be used + to represent virtually anything. A Memory Object also has two extra kinds of + meta-information: a time stamp (T), which tags the Memory Object with a + marker indicating its last update, and an evaluation (E), which has many + different uses within CST. This evaluation is simply a number, which can be + used, e.g. as an appraisal factor in an emotional module, or simply as a + discriminator to differentiate among two or more Memory Objects of the same + type. These meta-information can be simply ignored by simpler codelets, or be + useful while implementing more sophisticated cognitive models. + ''' def __init__(self) -> None: + ''' + Creates a MemoryObject. + ''' self._id = 0 self._timestamp = 0 self._evaluation = 0.0 @@ -44,7 +67,15 @@ def _notify_memory_observers(self) -> None: for observer in self._memory_observers: observer.notify_codelet() + def update_info(self, info:Any) -> None: + ''' + Args: + info (Any): the info in memory object to set. + + .. deprecated:: + Use set_info() instead + ''' self.set_info(info) def get_timestamp(self) -> int: @@ -52,6 +83,9 @@ def get_timestamp(self) -> int: @property def timestamp(self) -> int: + ''' + Date when the data was "created" in milliseconds. + ''' return self._timestamp #@alias.alias("setTimestamp") diff --git a/src/cst_python/core/entities/mind.py b/src/cst_python/core/entities/mind.py index 4900171..6b2d3e2 100644 --- a/src/cst_python/core/entities/mind.py +++ b/src/cst_python/core/entities/mind.py @@ -11,7 +11,14 @@ from .memory_container import MemoryContainer class Mind: + ''' + This class represents the Mind of the agent, wrapping all the CST's core + entities. + ''' def __init__(self) -> None: + ''' + Creates the Mind. + ''' self._code_rack = CodeRack() self._raw_memory = RawMemory() self._codelet_groups : Dict[str, List[Codelet]] = dict() @@ -39,22 +46,57 @@ def memory_groups(self) -> Dict[str, List[Memory]]: #@alias.alias("createCodeletGroup") def create_codelet_group(self, group_name:str) -> None: + ''' + Creates a Codelet Group. + + Args: + group_name (str): The Group name. + ''' self._codelet_groups[group_name] = [] #@alias.alias("createMemoryGroup") def create_memory_group(self, group_name:str) -> None: + ''' + Creates a Memory Group. + + Args: + group_name (str): The Group name. + ''' self._memory_groups[group_name] = [] #@alias.alias("getCodeletGroupsNumber") def get_codelet_groups_number(self) -> int: + ''' + Returns the number of registered codelet groups + + Returns: + int: the number of registered groups + ''' return len(self._memory_groups) #@alias.alias("getMemoryGroupsNumber") def get_memory_groups_number(self) -> int: + ''' + Returns the number of registered memory groups + + Returns: + int: the number of registered groups + ''' + return len(self._memory_groups) #@alias.alias("createMemoryContainer") def create_memory_container(self, name:str) -> Optional[MemoryContainer]: + ''' + Creates a Memory Container inside the Mind of a given type. + + Args: + name (str): the type of the Memory Container to be created inside the + Mind. + + Returns: + Optional[MemoryContainer]: the Memory Container created. + ''' mc = None if self._raw is not None: @@ -66,6 +108,19 @@ def create_memory_container(self, name:str) -> Optional[MemoryContainer]: def create_rest_memory_object(self, name:str, port:int, hostname:Optional[str]=None) -> Optional[RESTMemoryObject]: + ''' + Creates a new MemoryObject and adds it to the Raw Memory, using provided + info and type. + + Args: + name (str): memory object name. + port (int): port of the REST server + hostname (Optional[str], optional): hostname of the REST server. If is None, + uses 'localhost'. Defaults to None. + + Returns: + Optional[RESTMemoryObject]: created MemoryObject + ''' if hostname is None: hostname = "localhost" @@ -81,6 +136,19 @@ def create_rest_memory_object(self, name:str, def create_rest_memory_container(self, name:str, port:int, hostname:Optional[str]=None) -> Optional[RESTMemoryContainer]: + ''' + Creates a new MemoryObject and adds it to the Raw Memory, using provided + info and type. + + Args: + name (str): memory object name. + port (int): port of the REST server + hostname (Optional[str], optional): hostname of the REST server. If is None, + uses 'localhost'. Defaults to None. + + Returns: + Optional[RESTMemoryContainer]: created MemoryObject + ''' if hostname is None: hostname = "localhost" @@ -94,6 +162,17 @@ def create_rest_memory_container(self, name:str, #@alias.alias("createMemoryObject") def create_memory_object(self, name:str, info:Optional[Any]=None) -> Optional[MemoryObject]: + ''' + Creates a new MemoryObject and adds it to the Raw Memory, using provided + type. + + Args: + name (str): memory object type. + info (Optional[Any], optional): memory object info. Defaults to None. + + Returns: + Optional[MemoryObject]: created MemoryObject. + ''' mo = None if self._raw_memory is not None: @@ -103,6 +182,16 @@ def create_memory_object(self, name:str, info:Optional[Any]=None) -> Optional[Me #@alias.alias("insertCodelet") def insert_codelet(self, co:Codelet, group_name:Optional[str]=None) -> Codelet: + ''' + Inserts the Codelet passed in the Mind's CodeRack. + + Args: + co (Codelet): the Codelet passed + group_name (Optional[str], optional): the Codelet group name. Defaults to None. + + Returns: + Codelet: the Codelet. + ''' if self._code_rack is not None: self._code_rack.add_codelet(co) @@ -112,12 +201,26 @@ def insert_codelet(self, co:Codelet, group_name:Optional[str]=None) -> Codelet: #@alias.alias("registerCodelet") def register_codelet(self, co:Codelet, group_name:str) -> None: + ''' + Register a Codelet within a group. + + Args: + co (Codelet): the Codelet. + group_name (str): the group name. + ''' if group_name in self._codelet_groups: group_list = self._codelet_groups[group_name] group_list.append(co) #@alias.alias("registerMemory") def register_memory(self, memory:Union[Memory,str], group_name:str) -> None: + ''' + Register a Memory within a group + + Args: + memory (Union[Memory,str]): the Memory or the memory name. + group_name (str): the group name + ''' if group_name in self._memory_groups: to_register = [] @@ -131,17 +234,41 @@ def register_memory(self, memory:Union[Memory,str], group_name:str) -> None: #@alias.alias("getCodeletGroupList") def get_codelet_group_list(self, group_name:str) -> List[Codelet]: + ''' + Get a list of all Codelets belonging to a group + + Args: + group_name (str): the group name to which the Codelets belong + + Returns: + List[Codelet]: A list of all codeletGroups belonging to the group indicated by groupName + ''' return self._codelet_groups[group_name] #@alias.alias("getMemoryGroupList") def get_memory_group_list(self, group_name:str) -> List[Memory]: + ''' + Get a list of all Memories belonging to a group + + Args: + group_name (str): the group name to which the Memory belong + + Returns: + List[Memory]: A list of all memoryGroups belonging to the group indicated by groupName + ''' return self._memory_groups[group_name] def start(self) -> None: + ''' + Starts all codeletGroups in coderack. + ''' if self._code_rack is not None: self._code_rack.start() #@alias.alias("shutDown", "shut_down") def shutdown(self) -> None: + ''' + Stops codeletGroups thread. + ''' if self._code_rack is not None: self._code_rack.shutdow() \ No newline at end of file diff --git a/src/cst_python/core/entities/raw_memory.py b/src/cst_python/core/entities/raw_memory.py index c270498..6f7fabf 100644 --- a/src/cst_python/core/entities/raw_memory.py +++ b/src/cst_python/core/entities/raw_memory.py @@ -14,11 +14,17 @@ class RawMemory: _last_id = 0 def __init__(self) -> None: + ''' + Creates a Raw Memory. + ''' self._all_memories : List[Memory] = [] #Should be a set? #@alias.alias("getAllMemoryObjects", "get_all_memory_objects") @property def all_memories(self) -> List[Memory]: + ''' + List of all memories in the system. + ''' return self._all_memories #@alias.alias("setAllMemoryObjects", "set_all_memory_objects") @@ -33,6 +39,15 @@ def all_memories(self, value:List[Memory]) -> None: #@alias.alias("getAllOfType") def get_all_of_type(self, type:str) -> List[Memory]: + ''' + Returns a list of all memories in raw memory of a given type + + Args: + type (str): type of memory + + Returns: + List[Memory]: list of Ms of a given type + ''' list_of_type = [] for m in self._all_memories: @@ -43,29 +58,92 @@ def get_all_of_type(self, type:str) -> List[Memory]: #@alias.alias("printContent") def print_content(self) -> None: + ''' + Print Raw Memory contents. + ''' for m in self._all_memories: print(m) #@alias.alias("addMemoryObject", "add_memory_object", "addMemory") def add_memory(self, m:Memory) -> None: + ''' + Adds a new Memory to the Raw Memory. + + Args: + m (Memory): memory to be added. + ''' self._all_memories.append(m) m.set_id(self._last_id) self._last_id += 1 #@alias.alias("createMemoryContainer") def create_memory_container(self, name:str) -> MemoryContainer: + ''' + Creates a memory container of the type passed. + + Args: + name (str): the type of the memory container passed. + + Raises: + NotImplementedError: method is not implemented. + + Returns: + MemoryContainer: the memory container created. + ''' raise NotImplementedError() #@alias.alias("createRESTMemoryObject") def create_rest_memory_object(self, name:str, port:int, hostname:Optional[str]=None) -> RESTMemoryObject: + ''' + Creates a new RestMemory and adds it to the Raw Memory, using provided + name, hostname and port . + + Args: + name (str): memory object type. + port (int): the port of the REST server + hostname (Optional[str], optional): the hostname of the REST server. If None, + uses 'localhost'. Defaults to None. + + Raises: + NotImplementedError: method is not implemented. + + Returns: + RESTMemoryObject: created MemoryObject. + ''' raise NotImplementedError() #@alias.alias("createRESTMemoryContainer") def create_rest_memory_container(self, name:str, port:int, hostname:Optional[str]=None) -> RESTMemoryContainer: + ''' + Creates a new RestMemory and adds it to the Raw Memory, using provided + name, hostname and port . + + Args: + name (str): memory object type. + port (int): the port of the REST server + hostname (Optional[str], optional): the hostname of the REST server. If None, + uses 'localhost'. Defaults to None. + + Raises: + NotImplementedError: method is not implemented. + + Returns: + RESTMemoryContainer: created MemoryObject. + ''' raise NotImplementedError() #@alias.alias("createMemoryObject") def create_memory_object(self, name:str, info:Optional[Any]=None) -> MemoryObject: + ''' + Creates a new MemoryObject and adds it to the Raw Memory. + + Args: + name (str): memory object type. + info (Optional[Any], optional): memory object info. Defaults to None. + + Returns: + MemoryObject: created MemoryObject. + ''' if info is None: info = "" @@ -80,12 +158,27 @@ def create_memory_object(self, name:str, info:Optional[Any]=None) -> MemoryObjec #@alias.alias("destroyMemoryObject", "destroy_memory_object") def destroy_memory(self, m:Memory): + ''' + Destroys a given memory from raw memory + + Args: + m (Memory): the memory to destroy. + ''' self._all_memories.remove(m) #@alias.alias("size") def __len__(self) -> int: + ''' + Gets the size of the raw memory. + + Returns: + int: size of Raw Memory. + ''' return len(self._all_memories) #@alias.alias("shutDown", "shut_down") def shutdown(self) -> None: + ''' + Removes all memory objects from RawMemory. + ''' self._all_memories = [] \ No newline at end of file From 6c264a6845df79da42eb8e3d4e2233a4f7dda131 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:12:42 -0300 Subject: [PATCH 35/59] Fix examples figures --- docs/conf.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index ca99f78..2b7edb2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -110,3 +110,16 @@ def all_but_ipynb(dir, contents): shutil.copyfile(os.path.join(project_root, "README.md"), os.path.join(project_root, "docs/README.md")) shutil.copyfile(os.path.join(project_root,"examples", "README.md"), os.path.join(project_root, "docs/Examples.md")) + +#Copy examples images +shutil.rmtree("_build/html/_examples/_examples", ignore_errors=True ) +def ignore_ipynb(dir, contents): + result = [] + for c in contents: + if os.path.isfile(os.path.join(dir,c)) and c.endswith(".ipynb"): + result += [c] + return result + +shutil.copytree(os.path.join(project_root, "docs", "_examples"), + os.path.join(project_root, "docs", "_build", "html", "_examples", "_examples"), + ignore=ignore_ipynb) From a9d6ae2d2452b959e45e6574cafb624c428db805 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:23:07 -0300 Subject: [PATCH 36/59] Documentation workflow --- .github/workflows/documentation.yml | 56 +++++++++++++++++++++++++++++ docs/install_doc_requirements.py | 11 +++--- pyproject.toml | 1 + 3 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/documentation.yml diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..3b9e7ff --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,56 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Build and deploy documentation + +on: + # Runs on pushes targeting the default branch + release: + types: [published] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + cd docs + python3 install_doc_requirements.py + cd .. + - name: Install pandoc + uses: pandoc/actions/setup@v1 + - name: Build documentation + run: | + cd docs + make html + cd .. + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload docs dir + path: './docs' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/docs/install_doc_requirements.py b/docs/install_doc_requirements.py index 9bdd4c7..ab8f4fc 100644 --- a/docs/install_doc_requirements.py +++ b/docs/install_doc_requirements.py @@ -1,10 +1,11 @@ import subprocess import sys -import configparser +import tomllib import os -config = configparser.ConfigParser() -config.read(os.path.join("..", "setup.cfg")) -packages = config["options.extras_require"]["doc_generation"] +with open("../pyproject.toml", "rb") as file: + data = tomllib.load(file) -subprocess.check_call([sys.executable, "-m", "pip", "install"]+packages.split(";")) \ No newline at end of file +packages = data["project"]["optional-dependencies"]["doc_generation"] + +subprocess.check_call([sys.executable, "-m", "pip", "install"]+packages) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 7711651..8079f50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ Homepage = "https://hiaac.unicamp.br" [project.optional-dependencies] tests = ["mypy", "testbook", "ipython", "ipykernel", "numpy", "matplotlib"] +doc_generation = ["sphinx", "sphinx_rtd_theme", "nbsphinx", "sphinx-mdinclude==0.5.4"] [tool.setuptools] include-package-data = true From c27d7dfc66e557b1c14767c55c21ffad51b6bd05 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:38:07 -0300 Subject: [PATCH 37/59] Type check --- src/cst_python/core/entities/codelet.py | 25 +++---------- src/cst_python/core/entities/memory.py | 4 +-- src/cst_python/core/entities/memory_object.py | 8 +++-- src/cst_python/core/entities/mind.py | 9 ++--- src/cst_python/python/alias.py | 2 ++ tests/test_typecheck.py | 36 +++++++++++++++++++ 6 files changed, 55 insertions(+), 29 deletions(-) create mode 100644 tests/test_typecheck.py diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index a47d5ba..eed248e 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -188,7 +188,7 @@ def threshold(self, value:float): #@alias.alias("get_time_step", "getTime_step") @property - def time_step(self) -> float: + def time_step(self) -> int: ''' If the proc() method is set to be called automatically in a loop, this variable stores the time step for such a loop. A timeStep of value 0 @@ -200,7 +200,7 @@ def time_step(self) -> float: #@alias.alias("set_time_step", "setTime_step") @time_step.setter - def time_step(self, value:float): + def time_step(self, value:int): self._time_step = value @@ -471,23 +471,6 @@ def get_inputs_of_type(self, type:str) -> List[Memory]: return inputs_of_type - #@alias.alias("getBroadcast") - def get_broadcast(self, name:str) -> Memory: - ''' - Returns a specific memory (with the given name) from the broadcast list - of the Codelet. - - Args: - name (str): the name of a memory to be retrieved at the broadcast list. - - Returns: - Memory: the memory. - ''' - if self._broadcast is not None: - for m in self._broadcast: - if m.compare_name(name): - return m - #@alias.alias("addBroadcast") def add_broadcast(self, memory:Memory) -> None: ''' @@ -551,7 +534,7 @@ def __str__(self) -> str: return result def _get_memory(self, search_list:List[Memory], type:Optional[str]=None, - index:Optional[int]=None, name:Optional[str]=None) -> Memory: + index:Optional[int]=None, name:Optional[str]=None) -> Memory|None: ''' This method returns an memory from a list. If it couldn't find the given M, it sets this codelet as not able to perform proc(), and @@ -597,7 +580,7 @@ def _get_memory(self, search_list:List[Memory], type:Optional[str]=None, return found_MO #@alias.alias("getInput") - def get_input(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory: + def get_input(self, type:Optional[str]=None, index:Optional[int]=None, name:Optional[str]=None) -> Memory|None: ''' This method returns an input memory from its input list. If it couldn't find the given M, it sets this codelet as not able to perform proc(), and diff --git a/src/cst_python/core/entities/memory.py b/src/cst_python/core/entities/memory.py index f12b58c..eab496a 100644 --- a/src/cst_python/core/entities/memory.py +++ b/src/cst_python/core/entities/memory.py @@ -152,8 +152,8 @@ def compare_name(self, other_name:str) -> bool: Returns: bool: True if is the same name. ''' - if self._name is None: + if self.get_name() is None: return False - return self._name.lower() == other_name.lower() + return self.get_name().lower() == other_name.lower() \ No newline at end of file diff --git a/src/cst_python/core/entities/memory_object.py b/src/cst_python/core/entities/memory_object.py index cf12eab..199bc83 100644 --- a/src/cst_python/core/entities/memory_object.py +++ b/src/cst_python/core/entities/memory_object.py @@ -1,7 +1,7 @@ from __future__ import annotations import time -from typing import Any, Set +from typing import Any, Set, cast from cst_python.python import alias from .memory import Memory @@ -131,7 +131,11 @@ def __hash__(self) -> int: return result #@alias.alias("equals") - def __eq__(self, value: MemoryObject) -> bool: + def __eq__(self, value: object) -> bool: + if not isinstance(value, MemoryObject): + return False + value = cast(MemoryObject, value) + if id(self) == id(value): return True if value is None: diff --git a/src/cst_python/core/entities/mind.py b/src/cst_python/core/entities/mind.py index 6b2d3e2..e52b364 100644 --- a/src/cst_python/core/entities/mind.py +++ b/src/cst_python/core/entities/mind.py @@ -99,7 +99,7 @@ def create_memory_container(self, name:str) -> Optional[MemoryContainer]: ''' mc = None - if self._raw is not None: + if self._raw_memory is not None: mc = self._raw_memory.create_memory_container(name) return mc @@ -128,7 +128,7 @@ def create_rest_memory_object(self, name:str, mo = None if self._raw_memory is not None: - mo = self._raw_memory.create_rest_memory_object(name, hostname, port) + mo = self._raw_memory.create_rest_memory_object(name, port, hostname) return mo @@ -155,7 +155,7 @@ def create_rest_memory_container(self, name:str, mc = None if self._raw_memory is not None: - mc = self._raw_memory.create_rest_memory_container(name, hostname, port) + mc = self._raw_memory.create_rest_memory_container(name, port, hostname) return mc @@ -195,7 +195,8 @@ def insert_codelet(self, co:Codelet, group_name:Optional[str]=None) -> Codelet: if self._code_rack is not None: self._code_rack.add_codelet(co) - self.register_codelet(co, group_name) + if group_name is not None: + self.register_codelet(co, group_name) return co diff --git a/src/cst_python/python/alias.py b/src/cst_python/python/alias.py index acd74cf..8c63dda 100644 --- a/src/cst_python/python/alias.py +++ b/src/cst_python/python/alias.py @@ -1,5 +1,6 @@ import warnings import functools +import typing from typing import Any, Callable, Type class aliased: @@ -26,6 +27,7 @@ class alias: def __init__(self, *aliases:str) -> None: self._aliases = set(aliases) + @typing.no_type_check def __call__(self, method:Callable) -> Callable: method._aliases = self._aliases diff --git a/tests/test_typecheck.py b/tests/test_typecheck.py new file mode 100644 index 0000000..60cb081 --- /dev/null +++ b/tests/test_typecheck.py @@ -0,0 +1,36 @@ +import os +import glob +import subprocess +import unittest +import pathlib +import sys +from typing import List + + + + +class TestTypeCheck(unittest.TestCase): + + def test_run_mypy_module(self): + """Run mypy on all module sources""" + mypy_call: List[str] = self.base_call + [self.pkg_path] + subprocess.check_call(mypy_call) + + #def test_run_mypy_tests(self): + # """Run mypy on all tests in module under the tests directory""" + # mypy_call: List[str] = self.base_call + [self.tests_path] + # subprocess.check_call(mypy_call) + + def __init__(self, *args, **kwargs) -> None: + super(TestTypeCheck, self).__init__(*args, **kwargs) + + self.tests_path = pathlib.Path(__file__).parent.resolve() + + + self.pkg_path = os.path.join(self.tests_path, "../src/cst_python") + + self.mypy_opts: List[str] = ['--ignore-missing-imports'] + + self.base_call : List[str] = [sys.executable, "-m", "mypy"] + self.mypy_opts + + \ No newline at end of file From 794f9da97f67f3b6b849c3764e2126a1d5840d3c Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:49:44 -0300 Subject: [PATCH 38/59] Fix Activation and Monitoring test --- tests/examples/test_activation_and_monitoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/test_activation_and_monitoring.py b/tests/examples/test_activation_and_monitoring.py index d311bb1..7006577 100644 --- a/tests/examples/test_activation_and_monitoring.py +++ b/tests/examples/test_activation_and_monitoring.py @@ -20,7 +20,7 @@ def test_activation(tb :TestbookNotebookClient): for i, (activation, input_value, sensory_output, action) in enumerate(zip(activation_hist, input_hist, sensory_output_hist, action_hist)): assert math.isclose(input_value, i/100) - assert math.isclose(activation, np.clip(input_value, 0.0, 1.0), abs_tol=0.031) + assert math.isclose(activation, np.clip(input_value, 0.0, 1.0), abs_tol=0.04) if i >= 50 and activation < 0.7: expected_sensory = last_sensory_output From a9816eb39e45d9fabeb8551d266c45d357e95329 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:00:56 -0300 Subject: [PATCH 39/59] Update minimum Python Version to 3.10 --- .github/workflows/test.yml | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 21608cd..a01d4e4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v2 diff --git a/pyproject.toml b/pyproject.toml index 8079f50..bd5c27e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ classifiers = [ "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", ] +requires-python = ">= 3.10" dynamic = ["version"] [project.readme] From 7a65ae156b49a8a0e33b55b01bc66e26929a15cb Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:02:51 -0300 Subject: [PATCH 40/59] Doc differences from CST-Java --- docs/index.rst | 1 + docs/src/Differences from CST-Java.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 docs/src/Differences from CST-Java.md diff --git a/docs/index.rst b/docs/index.rst index 63c77b1..06ffaa8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,6 +7,7 @@ readme_link self + src/Differences from CST-Java.md .. toctree:: :maxdepth: 1 diff --git a/docs/src/Differences from CST-Java.md b/docs/src/Differences from CST-Java.md new file mode 100644 index 0000000..a1427a5 --- /dev/null +++ b/docs/src/Differences from CST-Java.md @@ -0,0 +1,17 @@ +# Differences from CST-JAVA + +CST-Python is a port of the CST-Java to Python. However, the intention is only to port the existing elements in cst.core and the Ideas functionalities, to enable the creation of basic CST applications and interaction with other architectures in Java. + +At this time, the following elements are not implemented: +- Coalition +- CodeRack +- CodeletContainer +- MemoryBuffer +- MemoryContainer +- REST functionalities +- Ideas functionalities + +Other differences between the versions: +- All get and set methods have been replaced by properties with the name of the attribute you want to access, except in the case of methods coming from interfaces and abstract classes and their implementations. +- Interfaces have been converted to abstract classes. +- Synchronization features have not been implemented, as the GIL prevents most of these issues from occurring. \ No newline at end of file From 2d3e4fe4266ed358df2ebba5b17bc4f7f465050c Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:03:10 -0300 Subject: [PATCH 41/59] Update Differences from CST-Java.md --- docs/src/Differences from CST-Java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/Differences from CST-Java.md b/docs/src/Differences from CST-Java.md index a1427a5..ac6a125 100644 --- a/docs/src/Differences from CST-Java.md +++ b/docs/src/Differences from CST-Java.md @@ -1,6 +1,6 @@ # Differences from CST-JAVA -CST-Python is a port of the CST-Java to Python. However, the intention is only to port the existing elements in cst.core and the Ideas functionalities, to enable the creation of basic CST applications and interaction with other architectures in Java. +CST-Python is a port of the CST-Java to Python. However, the intention is only to port the existing elements in cst.core and the Ideas functionalities, to enable the creation of basic CST applications for prototyping and interaction with other architectures in Java. At this time, the following elements are not implemented: - Coalition From a39b12f22dd115478f87d57f1ce44ca205a65350 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:09:02 -0300 Subject: [PATCH 42/59] Update test_activation_and_monitoring.py --- tests/examples/test_activation_and_monitoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/examples/test_activation_and_monitoring.py b/tests/examples/test_activation_and_monitoring.py index 7006577..0fc199b 100644 --- a/tests/examples/test_activation_and_monitoring.py +++ b/tests/examples/test_activation_and_monitoring.py @@ -27,7 +27,7 @@ def test_activation(tb :TestbookNotebookClient): else: expected_sensory = input_value * 10 - assert math.isclose(sensory_output, expected_sensory, abs_tol=0.21) + assert math.isclose(sensory_output, expected_sensory, abs_tol=0.3) last_sensory_output = sensory_output From 26b59d88bc49964a7d4a634f5af94285357b3fa4 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:30:09 -0300 Subject: [PATCH 43/59] Generate citation code --- .vscode/settings.json | 5 +++++ README.md | 6 ++++++ generate_citation.py | 24 ++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 generate_citation.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..82cf781 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.exclude": { + "**/.git": false + } +} \ No newline at end of file diff --git a/README.md b/README.md index 0b9b2cb..14e762e 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ This project was developed as part of the Cognitive Architectures research line pip install . ``` +## Citation + + + + + ## Authors - (2023-) Elton Cardoso do Nascimento: M. Eng. student, FEEC-UNICAMP diff --git a/generate_citation.py b/generate_citation.py new file mode 100644 index 0000000..a6cd1e8 --- /dev/null +++ b/generate_citation.py @@ -0,0 +1,24 @@ +import re + +import cffconvert + +with open("CITATION.CFF", "r") as file: + cff_content = file.read() + citation = cffconvert.Citation(cff_content) + +citation_str = citation.as_bibtex(reference="Cardoso_do_Nascimento_CST-Python") +citation_str = citation_str.replace("@misc", "@software") + +citation_str = ("\n"+ + "```bibtext\n"+ + citation_str+ + "```\n"+ + "") + +with open("README.md", "r") as file: + readme_text = file.read() + +readme_text = re.sub(r"((.|\n)*)", citation_str, readme_text) + +with open("README.md", "w") as file: + file.write(readme_text) \ No newline at end of file From a6d50f68f3cc648de1c0ac47bc13710f2fd0a7ef Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:31:21 -0300 Subject: [PATCH 44/59] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 14e762e..260fd5c 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,14 @@ This project was developed as part of the Cognitive Architectures research line +```bibtext +@software{Cardoso_do_Nascimento_CST-Python, +author = {Cardoso do Nascimento, Elton and Dornhofer Paro Costa, Paula}, +doi = {10.5281/zenodo.14057065}, +title = {CST-Python}, +url = {https://github.com/H-IAAC/CST-Python'} +} +``` ## Authors From 607db9a8bca7f557ab7bbb97a90f476f3eee02e2 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:32:55 -0300 Subject: [PATCH 45/59] Documentation Badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 260fd5c..8cd92d3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://img.shields.io/pypi/v/cst_python?style=for-the-badge)](https://pypi.org/project/cst_python) [![](https://img.shields.io/pypi/l/cst_python?style=for-the-badge)](https://github.com/H-IAAC/CST-Python/blob/main/LICENSE) [![](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python) [![](https://img.shields.io/badge/DOI-10.5281/zenodo.14057065-1082c3?style=for-the-badge)](https://doi.org/10.5281/zenodo.14057065) +[![](https://img.shields.io/pypi/v/cst_python?style=for-the-badge)](https://pypi.org/project/cst_python) [![](https://img.shields.io/pypi/l/cst_python?style=for-the-badge)](https://github.com/H-IAAC/CST-Python/blob/main/LICENSE) [![](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python) [![](https://img.shields.io/badge/-Documentation-fe9c22?style=for-the-badge&link=https%3A%2F%2Fh-iaac.github.io%CST-Python%2F)](https://h-iaac.github.io/CST-Python) [![](https://img.shields.io/badge/DOI-10.5281/zenodo.14057065-1082c3?style=for-the-badge)](https://doi.org/10.5281/zenodo.14057065) # CST-Python From 31637f45222b023ce37268063f1895c544a437b4 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:39:39 -0300 Subject: [PATCH 46/59] Fix test --- generate_citation.py | 7 ++++++- pyproject.toml | 1 + pytest.ini | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/generate_citation.py b/generate_citation.py index a6cd1e8..3b59561 100644 --- a/generate_citation.py +++ b/generate_citation.py @@ -1,6 +1,11 @@ import re +try: + import cffconvert +except: + import warnings + warnings.warn("cffconvert not installed. Not updating README citation.") -import cffconvert + exit() with open("CITATION.CFF", "r") as file: cff_content = file.read() diff --git a/pyproject.toml b/pyproject.toml index bd5c27e..0cfb8e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ Homepage = "https://hiaac.unicamp.br" [project.optional-dependencies] tests = ["mypy", "testbook", "ipython", "ipykernel", "numpy", "matplotlib"] doc_generation = ["sphinx", "sphinx_rtd_theme", "nbsphinx", "sphinx-mdinclude==0.5.4"] +dev = ["cffconvert"] [tool.setuptools] include-package-data = true diff --git a/pytest.ini b/pytest.ini index fd17cc9..da0d4c7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts = --ignore=examples --ignore=docs --doctest-modules \ No newline at end of file +addopts = --ignore=examples --ignore=docs --doctest-modules --ignore=generate_citation.py \ No newline at end of file From 045c0f1454742ad11f29d07fd2d13f13b155a608 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:58:02 -0300 Subject: [PATCH 47/59] Update Copyright and license --- README.md | 3 +++ pyproject.toml | 1 + 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 8cd92d3..a7f3c38 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,11 @@ Project supported by the brazilian Ministry of Science, Technology and Innovatio ## License +CST-Python is a code derived from [main cst code](https://github.com/CST-Group/cst). + ``` Copyright 2024 H.IAAC +Copyright 2016 CST-Group Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (the "License"); you may not use this file except in compliance with the License. diff --git a/pyproject.toml b/pyproject.toml index 0cfb8e2..0f8634c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dev = ["cffconvert"] [tool.setuptools] include-package-data = true package-dir = {"" = "src"} +license-files = ["LICENSE"] # install_requires = # numpy From 9d90459f2ab866a1e84be24d0f78764434f9b089 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:14:48 -0300 Subject: [PATCH 48/59] HOTFIX: Documentation pipeline Python version --- .github/workflows/documentation.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 3b9e7ff..6aa252e 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -31,6 +31,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.11 - name: Setup Pages uses: actions/configure-pages@v5 - name: Install dependencies From c74f8b43bc85f5e831b4f80ce18856afb83a06e1 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:17:11 -0300 Subject: [PATCH 49/59] HOTFIX: documentation pipeline package install --- .github/workflows/documentation.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 6aa252e..8154a40 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -40,9 +40,7 @@ jobs: - name: Install dependencies run: | python3 -m pip install --upgrade pip - cd docs - python3 install_doc_requirements.py - cd .. + python3 -m pip install .[doc_generation] - name: Install pandoc uses: pandoc/actions/setup@v1 - name: Build documentation From 25868a51d0bc2e3904553de502034ece430e8135 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:29:36 -0300 Subject: [PATCH 50/59] Codelet: print exception in proc --- src/cst_python/core/entities/codelet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cst_python/core/entities/codelet.py b/src/cst_python/core/entities/codelet.py index eed248e..3139ecf 100644 --- a/src/cst_python/core/entities/codelet.py +++ b/src/cst_python/core/entities/codelet.py @@ -694,8 +694,8 @@ def notify_codelet(self) -> None: self._raise_exception() except Exception as e: + traceback.print_exception(e) #TODO Logging - pass finally: if self._codelet_profiler is not None: From da47ccbe81dcd345d47a29cfc9f25f78c62698b4 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:30:08 -0300 Subject: [PATCH 51/59] Gym experiment --- dev/Gym codelet.ipynb | 548 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 dev/Gym codelet.ipynb diff --git a/dev/Gym codelet.ipynb b/dev/Gym codelet.ipynb new file mode 100644 index 0000000..8ec8e5e --- /dev/null +++ b/dev/Gym codelet.ipynb @@ -0,0 +1,548 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Optional, Any\n", + "\n", + "import gymnasium as gym\n", + "from gymnasium.wrappers import TransformAction, TransformObservation\n", + "\n", + "import cst_python as cst\n", + "from cst_python.core.entities import Memory, MemoryObject" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class GymCodelet(cst.Codelet):\n", + " _last_indexes = {\"reward\":-1, \"reset\":-1, \"terminated\":-1, \"truncated\":-1, \"info\":-1, \"seed\":-1}\n", + "\n", + " def __init__(self, mind:cst.Mind, env:gym.Env):\n", + " super().__init__()\n", + " \n", + " self.env = env\n", + " \n", + " self.observation_memories = self.space_to_memories(mind, env.observation_space)\n", + " self.action_memories = self.space_to_memories(mind, env.action_space, action=True)\n", + "\n", + " self._common_memories : dict[str, MemoryObject] = {}\n", + " for name in [\"reward\", \"reset\", \"terminated\", \"truncated\", \"info\", \"seed\"]:\n", + " self._last_indexes[name] += 1\n", + "\n", + " memory_name = name\n", + " if self._last_indexes[name] != 0:\n", + " memory_name += str(self._last_indexes[name])\n", + " \n", + " self._common_memories[name] = mind.create_memory_object(memory_name)\n", + "\n", + " self._common_memories[\"reward\"].set_info(0.0)\n", + " self._common_memories[\"reset\"].set_info(False)\n", + " self._common_memories[\"terminated\"].set_info(False)\n", + " self._common_memories[\"truncated\"].set_info(False)\n", + " self._common_memories[\"info\"].set_info({})\n", + " self._common_memories[\"seed\"].set_info(None)\n", + "\n", + "\n", + " self.is_memory_observer = True\n", + " for memory_name in self.action_memories:\n", + " memory = self.action_memories[memory_name]\n", + " memory.add_memory_observer(self)\n", + " self._common_memories[\"reset\"].add_memory_observer(self)\n", + "\n", + " self._last_reset = self._common_memories[\"reset\"].get_timestamp()\n", + "\n", + " @property\n", + " def reward_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"reward\"]\n", + " \n", + " @property\n", + " def reset_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"reset\"]\n", + " \n", + " @property\n", + " def terminated_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"terminated\"]\n", + " \n", + " @property\n", + " def truncated_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"truncated\"]\n", + " \n", + " @property\n", + " def info_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"info\"]\n", + " \n", + " @property\n", + " def seed_memory(self) -> MemoryObject:\n", + " return self._common_memories[\"seed\"]\n", + "\n", + " def access_memory_objects(self):\n", + " pass\n", + "\n", + " def calculate_activation(self):\n", + " pass\n", + "\n", + " def proc(self):\n", + " if self._last_reset < self.reset_memory.get_timestamp():\n", + " self._last_reset = self.reset_memory.get_timestamp()\n", + "\n", + " observation, info = self.env.reset(seed=self.seed_memory.get_info())\n", + " reward = 0\n", + " terminated = False\n", + " truncated = False\n", + "\n", + " else:\n", + " action = self.memories_to_space(self.action_memories, self.env.action_space)\n", + " observation, reward, terminated, truncated, info = self.env.step(action)\n", + "\n", + " print(\"Observation\", observation)\n", + " \n", + " self.reward_memory.set_info(reward)\n", + " self.terminated_memory.set_info(terminated)\n", + " self.truncated_memory.set_info(truncated)\n", + " self.info_memory.set_info(info)\n", + "\n", + " self.sample_to_memories(observation, self.observation_memories)\n", + "\n", + " @classmethod\n", + " def space_to_memories(cls, mind:cst.Mind, \n", + " space:gym.Space,\n", + " action:bool=False) -> dict[str, cst.MemoryObject]:\n", + " memories = {}\n", + "\n", + " if isinstance(space, gym.spaces.Dict):\n", + " for space_name in space:\n", + " subspace = space[space_name]\n", + "\n", + " name = space_name\n", + " if space_name in cls._last_indexes:\n", + " cls._last_indexes[space_name] += 1\n", + " name += str(cls._last_indexes[space_name])\n", + " else:\n", + " cls._last_indexes[space_name] = 0\n", + "\n", + " info = subspace.sample()\n", + " memory = mind.create_memory_object(name, info)\n", + " memories[space_name] = memory\n", + " \n", + " else:\n", + " if action:\n", + " space_name = \"action\"\n", + " else:\n", + " space_name = \"observation\"\n", + "\n", + " name = space_name\n", + " if space_name in cls._last_indexes:\n", + " cls._last_indexes[space_name] += 1\n", + " name += str(cls._last_indexes[space_name])\n", + " else:\n", + " cls._last_indexes[space_name] = 0\n", + "\n", + " info = space.sample()\n", + " memory = mind.create_memory_object(name, info)\n", + " memories[space_name] = memory\n", + " \n", + "\n", + " return memories\n", + " \n", + " @classmethod\n", + " def sample_to_memories(cls, sample:dict[str, Any]|Any, memories:dict[str, Memory]) -> None:\n", + " if isinstance(sample, dict):\n", + " for name in sample:\n", + " element = sample[name]\n", + " memory = memories[name]\n", + " \n", + " memory.set_info(element)\n", + " else:\n", + " memory = memories[next(iter(memories))]\n", + " memory.set_info(sample)\n", + " \n", + "\n", + " @classmethod\n", + " def memories_to_space(cls, memories:dict[str, Memory], space:gym.spaces.Dict) -> dict[str, Any]|Any:\n", + " if isinstance(space, gym.spaces.Dict):\n", + " sample = {}\n", + " for memory_name in memories:\n", + " sample[memory_name] = memories[memory_name].get_info()\n", + " else:\n", + " sample = memories[next(iter(memories))].get_info()\n", + "\n", + " if not space.contains(sample):\n", + " raise ValueError(\"Memories do not correspond to an element of the Space.\")\n", + " \n", + " return sample" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "env = gym.make(\"Blackjack-v1\")\n", + "\n", + "env = TransformObservation(env, \n", + " lambda obs:{\"player_sum\":obs[0], \"dealer_card\":obs[1], \"usable_ace\":obs[2]}, \n", + " gym.spaces.Dict({\"player_sum\":env.observation_space[0], \"dealer_card\":env.observation_space[1], \"usable_ace\":env.observation_space[2]}))\n", + "\n", + "env = TransformAction(env, \n", + " lambda action:action[\"hit\"], \n", + " gym.spaces.Dict({\"hit\":env.action_space}))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mind = cst.Mind()\n", + "gym_codelet = GymCodelet(mind, env)\n", + "mind.insert_codelet(gym_codelet)\n", + "\n", + "mind.start()\n", + "gym_codelet.seed_memory.set_info(42)\n", + "gym_codelet.reset_memory.set_info(not gym_codelet.reset_memory.get_info())" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816658, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816658, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816658, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732659816658, evaluation=0.0, I=False, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816658, evaluation=0.0, I=0, name=reward])" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Observation {'player_sum': 25, 'dealer_card': 2, 'usable_ace': 0}\n", + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"hit\"].set_info(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816687, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816687, evaluation=0.0, I=25, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816687, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732659816687, evaluation=0.0, I=True, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816687, evaluation=0.0, I=-1.0, name=reward])" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.reset_memory.set_info(True)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816736, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816736, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816736, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732659816736, evaluation=0.0, I=False, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816736, evaluation=0.0, I=0, name=reward])" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Observation {'player_sum': 15, 'dealer_card': 2, 'usable_ace': 0}\n", + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"hit\"].set_info(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816814, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816814, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816814, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732659816814, evaluation=0.0, I=True, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816814, evaluation=0.0, I=1.0, name=reward])" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "env = gym.make(\"Blackjack-v1\")\n", + "mind = cst.Mind()\n", + "\n", + "gym_codelet = GymCodelet(mind, env)\n", + "mind.insert_codelet(gym_codelet)\n", + "\n", + "mind.start()\n", + "gym_codelet.seed_memory.set_info(42)\n", + "gym_codelet.reset_memory.set_info(not gym_codelet.reset_memory.get_info())" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732659816913, evaluation=0.0, I=(15, 2, 0), name=observation]},\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816913, evaluation=0.0, I=False, name=terminated1],\n", + " MemoryObject [idmemoryobject=2, timestamp=1732659816913, evaluation=0.0, I=0, name=reward1])" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Observation (25, 2, 0)\n", + "GymCodelet execution\n" + ] + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"action\"].set_info(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732659816947, evaluation=0.0, I=(25, 2, 0), name=observation]},\n", + " MemoryObject [idmemoryobject=4, timestamp=1732659816947, evaluation=0.0, I=True, name=terminated1],\n", + " MemoryObject [idmemoryobject=2, timestamp=1732659816947, evaluation=0.0, I=-1.0, name=reward1])" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories, gym_codelet.terminated_memory, gym_codelet.reward_memory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 6826ea4bd5e561d587fa3cea565e151a3800adbc Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:59:41 -0300 Subject: [PATCH 52/59] GymCodelet integrated --- dev/Gym codelet.ipynb | 300 +++++------------------ src/cst_python/python/gym/__init__.py | 1 + src/cst_python/python/gym/gym_codelet.py | 255 +++++++++++++++++++ 3 files changed, 312 insertions(+), 244 deletions(-) create mode 100644 src/cst_python/python/gym/__init__.py create mode 100644 src/cst_python/python/gym/gym_codelet.py diff --git a/dev/Gym codelet.ipynb b/dev/Gym codelet.ipynb index 8ec8e5e..aab533e 100644 --- a/dev/Gym codelet.ipynb +++ b/dev/Gym codelet.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 56, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -12,176 +12,12 @@ "from gymnasium.wrappers import TransformAction, TransformObservation\n", "\n", "import cst_python as cst\n", - "from cst_python.core.entities import Memory, MemoryObject" + "from cst_python.python.gym import GymCodelet" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class GymCodelet(cst.Codelet):\n", - " _last_indexes = {\"reward\":-1, \"reset\":-1, \"terminated\":-1, \"truncated\":-1, \"info\":-1, \"seed\":-1}\n", - "\n", - " def __init__(self, mind:cst.Mind, env:gym.Env):\n", - " super().__init__()\n", - " \n", - " self.env = env\n", - " \n", - " self.observation_memories = self.space_to_memories(mind, env.observation_space)\n", - " self.action_memories = self.space_to_memories(mind, env.action_space, action=True)\n", - "\n", - " self._common_memories : dict[str, MemoryObject] = {}\n", - " for name in [\"reward\", \"reset\", \"terminated\", \"truncated\", \"info\", \"seed\"]:\n", - " self._last_indexes[name] += 1\n", - "\n", - " memory_name = name\n", - " if self._last_indexes[name] != 0:\n", - " memory_name += str(self._last_indexes[name])\n", - " \n", - " self._common_memories[name] = mind.create_memory_object(memory_name)\n", - "\n", - " self._common_memories[\"reward\"].set_info(0.0)\n", - " self._common_memories[\"reset\"].set_info(False)\n", - " self._common_memories[\"terminated\"].set_info(False)\n", - " self._common_memories[\"truncated\"].set_info(False)\n", - " self._common_memories[\"info\"].set_info({})\n", - " self._common_memories[\"seed\"].set_info(None)\n", - "\n", - "\n", - " self.is_memory_observer = True\n", - " for memory_name in self.action_memories:\n", - " memory = self.action_memories[memory_name]\n", - " memory.add_memory_observer(self)\n", - " self._common_memories[\"reset\"].add_memory_observer(self)\n", - "\n", - " self._last_reset = self._common_memories[\"reset\"].get_timestamp()\n", - "\n", - " @property\n", - " def reward_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"reward\"]\n", - " \n", - " @property\n", - " def reset_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"reset\"]\n", - " \n", - " @property\n", - " def terminated_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"terminated\"]\n", - " \n", - " @property\n", - " def truncated_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"truncated\"]\n", - " \n", - " @property\n", - " def info_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"info\"]\n", - " \n", - " @property\n", - " def seed_memory(self) -> MemoryObject:\n", - " return self._common_memories[\"seed\"]\n", - "\n", - " def access_memory_objects(self):\n", - " pass\n", - "\n", - " def calculate_activation(self):\n", - " pass\n", - "\n", - " def proc(self):\n", - " if self._last_reset < self.reset_memory.get_timestamp():\n", - " self._last_reset = self.reset_memory.get_timestamp()\n", - "\n", - " observation, info = self.env.reset(seed=self.seed_memory.get_info())\n", - " reward = 0\n", - " terminated = False\n", - " truncated = False\n", - "\n", - " else:\n", - " action = self.memories_to_space(self.action_memories, self.env.action_space)\n", - " observation, reward, terminated, truncated, info = self.env.step(action)\n", - "\n", - " print(\"Observation\", observation)\n", - " \n", - " self.reward_memory.set_info(reward)\n", - " self.terminated_memory.set_info(terminated)\n", - " self.truncated_memory.set_info(truncated)\n", - " self.info_memory.set_info(info)\n", - "\n", - " self.sample_to_memories(observation, self.observation_memories)\n", - "\n", - " @classmethod\n", - " def space_to_memories(cls, mind:cst.Mind, \n", - " space:gym.Space,\n", - " action:bool=False) -> dict[str, cst.MemoryObject]:\n", - " memories = {}\n", - "\n", - " if isinstance(space, gym.spaces.Dict):\n", - " for space_name in space:\n", - " subspace = space[space_name]\n", - "\n", - " name = space_name\n", - " if space_name in cls._last_indexes:\n", - " cls._last_indexes[space_name] += 1\n", - " name += str(cls._last_indexes[space_name])\n", - " else:\n", - " cls._last_indexes[space_name] = 0\n", - "\n", - " info = subspace.sample()\n", - " memory = mind.create_memory_object(name, info)\n", - " memories[space_name] = memory\n", - " \n", - " else:\n", - " if action:\n", - " space_name = \"action\"\n", - " else:\n", - " space_name = \"observation\"\n", - "\n", - " name = space_name\n", - " if space_name in cls._last_indexes:\n", - " cls._last_indexes[space_name] += 1\n", - " name += str(cls._last_indexes[space_name])\n", - " else:\n", - " cls._last_indexes[space_name] = 0\n", - "\n", - " info = space.sample()\n", - " memory = mind.create_memory_object(name, info)\n", - " memories[space_name] = memory\n", - " \n", - "\n", - " return memories\n", - " \n", - " @classmethod\n", - " def sample_to_memories(cls, sample:dict[str, Any]|Any, memories:dict[str, Memory]) -> None:\n", - " if isinstance(sample, dict):\n", - " for name in sample:\n", - " element = sample[name]\n", - " memory = memories[name]\n", - " \n", - " memory.set_info(element)\n", - " else:\n", - " memory = memories[next(iter(memories))]\n", - " memory.set_info(sample)\n", - " \n", - "\n", - " @classmethod\n", - " def memories_to_space(cls, memories:dict[str, Memory], space:gym.spaces.Dict) -> dict[str, Any]|Any:\n", - " if isinstance(space, gym.spaces.Dict):\n", - " sample = {}\n", - " for memory_name in memories:\n", - " sample[memory_name] = memories[memory_name].get_info()\n", - " else:\n", - " sample = memories[next(iter(memories))].get_info()\n", - "\n", - " if not space.contains(sample):\n", - " raise ValueError(\"Memories do not correspond to an element of the Space.\")\n", - " \n", - " return sample" - ] - }, - { - "cell_type": "code", - "execution_count": 58, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -199,23 +35,16 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 4, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "GymCodelet execution\n" - ] - }, { "data": { "text/plain": [ "-1" ] }, - "execution_count": 59, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -232,20 +61,20 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816658, evaluation=0.0, I=2, name=dealer_card],\n", - " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816658, evaluation=0.0, I=15, name=player_sum],\n", - " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816658, evaluation=0.0, I=0, name=usable_ace]},\n", - " MemoryObject [idmemoryobject=6, timestamp=1732659816658, evaluation=0.0, I=False, name=terminated],\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816658, evaluation=0.0, I=0, name=reward])" + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732724413462, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732724413462, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732724413462, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732724413462, evaluation=0.0, I=False, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413462, evaluation=0.0, I=0, name=reward])" ] }, - "execution_count": 60, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -256,15 +85,14 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Observation {'player_sum': 25, 'dealer_card': 2, 'usable_ace': 0}\n", - "GymCodelet execution\n" + "Observation {'player_sum': 25, 'dealer_card': 2, 'usable_ace': 0}\n" ] }, { @@ -273,7 +101,7 @@ "-1" ] }, - "execution_count": 61, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -284,20 +112,20 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816687, evaluation=0.0, I=2, name=dealer_card],\n", - " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816687, evaluation=0.0, I=25, name=player_sum],\n", - " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816687, evaluation=0.0, I=0, name=usable_ace]},\n", - " MemoryObject [idmemoryobject=6, timestamp=1732659816687, evaluation=0.0, I=True, name=terminated],\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816687, evaluation=0.0, I=-1.0, name=reward])" + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732724413492, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732724413492, evaluation=0.0, I=25, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732724413492, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732724413492, evaluation=0.0, I=True, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413492, evaluation=0.0, I=-1.0, name=reward])" ] }, - "execution_count": 62, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -308,23 +136,16 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 8, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "GymCodelet execution\n" - ] - }, { "data": { "text/plain": [ "-1" ] }, - "execution_count": 63, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -335,20 +156,20 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816736, evaluation=0.0, I=2, name=dealer_card],\n", - " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816736, evaluation=0.0, I=15, name=player_sum],\n", - " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816736, evaluation=0.0, I=0, name=usable_ace]},\n", - " MemoryObject [idmemoryobject=6, timestamp=1732659816736, evaluation=0.0, I=False, name=terminated],\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816736, evaluation=0.0, I=0, name=reward])" + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732724413554, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732724413554, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732724413554, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732724413554, evaluation=0.0, I=False, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413554, evaluation=0.0, I=0, name=reward])" ] }, - "execution_count": 64, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -359,15 +180,14 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Observation {'player_sum': 15, 'dealer_card': 2, 'usable_ace': 0}\n", - "GymCodelet execution\n" + "Observation {'player_sum': 15, 'dealer_card': 2, 'usable_ace': 0}\n" ] }, { @@ -376,7 +196,7 @@ "-1" ] }, - "execution_count": 65, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -387,20 +207,20 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732659816814, evaluation=0.0, I=2, name=dealer_card],\n", - " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732659816814, evaluation=0.0, I=15, name=player_sum],\n", - " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732659816814, evaluation=0.0, I=0, name=usable_ace]},\n", - " MemoryObject [idmemoryobject=6, timestamp=1732659816814, evaluation=0.0, I=True, name=terminated],\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816814, evaluation=0.0, I=1.0, name=reward])" + "({'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732724413580, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732724413580, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732724413580, evaluation=0.0, I=0, name=usable_ace]},\n", + " MemoryObject [idmemoryobject=6, timestamp=1732724413580, evaluation=0.0, I=True, name=terminated],\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413580, evaluation=0.0, I=1.0, name=reward])" ] }, - "execution_count": 66, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -411,23 +231,16 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 12, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "GymCodelet execution\n" - ] - }, { "data": { "text/plain": [ "-1" ] }, - "execution_count": 67, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -446,18 +259,18 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732659816913, evaluation=0.0, I=(15, 2, 0), name=observation]},\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816913, evaluation=0.0, I=False, name=terminated1],\n", - " MemoryObject [idmemoryobject=2, timestamp=1732659816913, evaluation=0.0, I=0, name=reward1])" + "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732724413609, evaluation=0.0, I=(15, 2, 0), name=observation]},\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413609, evaluation=0.0, I=False, name=terminated1],\n", + " MemoryObject [idmemoryobject=2, timestamp=1732724413609, evaluation=0.0, I=0, name=reward1])" ] }, - "execution_count": 68, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -468,15 +281,14 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Observation (25, 2, 0)\n", - "GymCodelet execution\n" + "Observation (25, 2, 0)\n" ] }, { @@ -485,7 +297,7 @@ "-1" ] }, - "execution_count": 69, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -496,18 +308,18 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732659816947, evaluation=0.0, I=(25, 2, 0), name=observation]},\n", - " MemoryObject [idmemoryobject=4, timestamp=1732659816947, evaluation=0.0, I=True, name=terminated1],\n", - " MemoryObject [idmemoryobject=2, timestamp=1732659816947, evaluation=0.0, I=-1.0, name=reward1])" + "({'observation': MemoryObject [idmemoryobject=0, timestamp=1732724413632, evaluation=0.0, I=(25, 2, 0), name=observation]},\n", + " MemoryObject [idmemoryobject=4, timestamp=1732724413632, evaluation=0.0, I=True, name=terminated1],\n", + " MemoryObject [idmemoryobject=2, timestamp=1732724413632, evaluation=0.0, I=-1.0, name=reward1])" ] }, - "execution_count": 70, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } diff --git a/src/cst_python/python/gym/__init__.py b/src/cst_python/python/gym/__init__.py new file mode 100644 index 0000000..2f2b3d4 --- /dev/null +++ b/src/cst_python/python/gym/__init__.py @@ -0,0 +1 @@ +from .gym_codelet import GymCodelet \ No newline at end of file diff --git a/src/cst_python/python/gym/gym_codelet.py b/src/cst_python/python/gym/gym_codelet.py new file mode 100644 index 0000000..e702319 --- /dev/null +++ b/src/cst_python/python/gym/gym_codelet.py @@ -0,0 +1,255 @@ +from typing import Optional, Any, cast, Mapping + +try: + import gymnasium as gym +except ModuleNotFoundError: + import gym # type: ignore + +from cst_python.core.entities import Codelet, Mind, Memory, MemoryObject + +class GymCodelet(Codelet): + ''' + Codelet to interface with gymnasium/gym environments. Creates memories for the observation, + action, reward, reset, terminated, truncated, info and seed; and updates them stepping the + environment with the action. + ''' + + _last_indexes : dict[str, int] = {"reward":-1, "reset":-1, "terminated":-1, "truncated":-1, "info":-1, "seed":-1} + + def __init__(self, mind:Mind, env:gym.Env): + ''' + GymCodelet constructor. + + Always runs automatically in publish-subscribe mode. + + Args: + mind (Mind): agent's mind. + env (gym.Env): environment to interface. + ''' + super().__init__() + + assert mind._raw_memory is not None # RawMemory cannot be None for creating memories + + self.env = env + + self.observation_memories = self.space_to_memories(mind, env.observation_space) + self.action_memories = self.space_to_memories(mind, env.action_space, action=True) + + self._common_memories : dict[str, MemoryObject] = {} + for name in ["reward", "reset", "terminated", "truncated", "info", "seed"]: + self._last_indexes[name] += 1 + + memory_name = name + if self._last_indexes[name] != 0: + memory_name += str(self._last_indexes[name]) + + self._common_memories[name] = cast(MemoryObject, mind.create_memory_object(memory_name)) + + self._common_memories["reward"].set_info(0.0) + self._common_memories["reset"].set_info(False) + self._common_memories["terminated"].set_info(False) + self._common_memories["truncated"].set_info(False) + self._common_memories["info"].set_info({}) + self._common_memories["seed"].set_info(None) + + + self.is_memory_observer = True + for memory_name in self.action_memories: + memory = self.action_memories[memory_name] + memory.add_memory_observer(self) + self._common_memories["reset"].add_memory_observer(self) + + self._last_reset = self._common_memories["reset"].get_timestamp() + + @property + def reward_memory(self) -> MemoryObject: + ''' + Memory that contains the environment reward (float). + ''' + return self._common_memories["reward"] + + @property + def reset_memory(self) -> MemoryObject: + ''' + Memory that contains the environment reset. + + If timestamp changes, the codelet resets the environment. + ''' + return self._common_memories["reset"] + + @property + def terminated_memory(self) -> MemoryObject: + ''' + Memory that contains the environment terminated state. + ''' + return self._common_memories["terminated"] + + @property + def truncated_memory(self) -> MemoryObject: + ''' + Memory that contains the environment truncated state. + ''' + return self._common_memories["truncated"] + + @property + def info_memory(self) -> MemoryObject: + ''' + Memory that contains the environment info. + ''' + return self._common_memories["info"] + + @property + def seed_memory(self) -> MemoryObject: + ''' + Memory that contains the seed to use in the environment reset. + ''' + return self._common_memories["seed"] + + + def access_memory_objects(self) -> None: #NOSONAR + pass + + def calculate_activation(self) -> None: #NOSONAR + pass + + def proc(self) -> None: + if self._last_reset < self.reset_memory.get_timestamp(): + self._last_reset = self.reset_memory.get_timestamp() + + observation, info = self.env.reset(seed=self.seed_memory.get_info()) + reward = 0.0 + terminated = False + truncated = False + + else: + action = self.memories_to_space(self.action_memories, self.env.action_space) + observation, r, terminated, truncated, info = self.env.step(action) + reward = float(r) #SupportsFloat to float + + print("Observation", observation) + + self.reward_memory.set_info(reward) + self.terminated_memory.set_info(terminated) + self.truncated_memory.set_info(truncated) + self.info_memory.set_info(info) + + self.sample_to_memories(observation, self.observation_memories) + + @classmethod + def space_to_memories(cls, mind:Mind, + space:gym.Space, + action:bool=False, + memory_prefix:Optional[str]=None) -> dict[str, MemoryObject]: + ''' + Creates memories from a gym Space definition. + + Args: + mind (Mind): mind to create the memories. + space (gym.Space): space defining the memories to create. + If gym.space.Dict, creates a memory for each element, + creates a single memory otherwise. + action (bool, optional): If True, creates a memory with 'action' + name for non Dict space, uses 'observation' name otherwise. + Defaults to False. + memory_prefix (Optional[str], optional): prefix to memories name. + Defaults to None. + + Returns: + dict[str, MemoryObject]: created memories, indexed by the space + element name or 'action'/'observation'. + ''' + assert mind._raw_memory is not None # RawMemory cannot be None for creating memories + + if memory_prefix is None: + memory_prefix = "" + + memories : dict[str, MemoryObject] = {} + + if isinstance(space, gym.spaces.Dict): + for space_name in space: + subspace = space[space_name] + + name = space_name + if space_name in cls._last_indexes: + cls._last_indexes[space_name] += 1 + name += str(cls._last_indexes[space_name]) + else: + cls._last_indexes[space_name] = 0 + name = memory_prefix+name + + info = subspace.sample() + memory = cast(MemoryObject, mind.create_memory_object(name, info)) + memories[space_name] = memory + + else: + if action: + space_name = "action" + else: + space_name = "observation" + + name = space_name + if space_name in cls._last_indexes: + cls._last_indexes[space_name] += 1 + name += str(cls._last_indexes[space_name]) + else: + cls._last_indexes[space_name] = 0 + + name = memory_prefix+name + + info = space.sample() + memory = cast(MemoryObject, mind.create_memory_object(name, info)) + memories[space_name] = memory + + + return memories + + @classmethod + def sample_to_memories(cls, sample:Mapping[str, Any]|Any, + memories:Mapping[str, Memory]) -> None: + ''' + Writes a gym.Space sample to memories. + + Args: + sample (Mapping[str, Any] | Any): sample to write in the memories. + memories (Mapping[str, Memory]): memories corresponding to + the space elements. + ''' + if isinstance(sample, dict): + for name in sample: + element = sample[name] + memory = memories[name] + + memory.set_info(element) + else: + memory = memories[next(iter(memories))] + memory.set_info(sample) + + + @classmethod + def memories_to_space(cls, memories:Mapping[str, Memory], + space:gym.Space) -> dict[str, Any]|Any: + ''' + Convert the memories info to the space sample. + + Args: + memories (Mapping[str, Memory]): memories to get the sample. + space (gym.Space): space the sample belongs + + Raises: + ValueError: if the generated sample from the memories + doesn't belongs to the space + + Returns: + dict[str, Any]|Any: converted sample. + ''' + if isinstance(space, gym.spaces.Dict): + sample = {} + for memory_name in memories: + sample[memory_name] = memories[memory_name].get_info() + else: + sample = memories[next(iter(memories))].get_info() + + if not space.contains(sample): + raise ValueError("Memories do not correspond to an element of the Space.") + + return sample \ No newline at end of file From 13875fb1bc73517dc04cd1693be69ca914a6d790 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:59:54 -0300 Subject: [PATCH 53/59] Added "gym" dependencies --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 0f8634c..f5c97c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ Homepage = "https://hiaac.unicamp.br" tests = ["mypy", "testbook", "ipython", "ipykernel", "numpy", "matplotlib"] doc_generation = ["sphinx", "sphinx_rtd_theme", "nbsphinx", "sphinx-mdinclude==0.5.4"] dev = ["cffconvert"] +gym = ["gymnasium"] [tool.setuptools] include-package-data = true From 8d9befd72a94e96845d0e94503ff369574f247c7 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:00:11 -0300 Subject: [PATCH 54/59] Gym Codelet example --- .github/workflows/test.yml | 2 +- dev/Gym codelet.ipynb | 2 +- examples/Gymnasium Integration.ipynb | 714 +++++++++++++++++++++++ src/cst_python/python/gym/gym_codelet.py | 21 +- tests/examples/test_gym_integration.py | 45 ++ 5 files changed, 778 insertions(+), 6 deletions(-) create mode 100644 examples/Gymnasium Integration.ipynb create mode 100644 tests/examples/test_gym_integration.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a01d4e4..d6497dc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: python3 -m pip install --upgrade pip python3 -m pip install pytest python3 -m pip install pytest-cov - python3 -m pip install -e .[tests] + python3 -m pip install -e .[tests, gym] - name: Tests run: | diff --git a/dev/Gym codelet.ipynb b/dev/Gym codelet.ipynb index aab533e..ea44177 100644 --- a/dev/Gym codelet.ipynb +++ b/dev/Gym codelet.ipynb @@ -281,7 +281,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [ { diff --git a/examples/Gymnasium Integration.ipynb b/examples/Gymnasium Integration.ipynb new file mode 100644 index 0000000..ad81ade --- /dev/null +++ b/examples/Gymnasium Integration.ipynb @@ -0,0 +1,714 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Gymnasium Integration\n", + "\n", + "[![Open in Colab](https://img.shields.io/badge/Open%20in%20Colab-F9AB00?style=for-the-badge&logo=googlecolab&color=525252)](https://colab.research.google.com/github/H-IAAC/CST-Python/blob/main/examples/Gymnasium%20Integration.ipynb) [![Open in Github](https://img.shields.io/badge/Open%20in%20Github-100000?style=for-the-badge&logo=github&logoColor=white)](https://github.com/H-IAAC/CST-Python/blob/main/examples/Gymnasium%20Integration.ipynb)\n", + "\n", + "[Gymnasium](https://gymnasium.farama.org/) is the library that defines the most widely used interface for creating environments for reinforcement learning problems. CST-Python provides an interface for interacting with environments using a cognitive agent." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets start by importing the CST-Python and other required modules:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import cst_python as cst\n", + " import gymnasium as gym\n", + "except:\n", + " !python3 -m pip install cst_python[gym]" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "\n", + "from gymnasium.wrappers import TransformAction, TransformObservation\n", + "\n", + "from cst_python.python.gym import GymCodelet" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The GymCodelet\n", + "\n", + "The GymCodelet is the main interface with environments. Before we use it, we need to create the environment and the agent's mind.\n", + "\n", + "The environment we gonna use is the Blackjack card game. See the [environment documentation](https://gymnasium.farama.org/environments/toy_text/blackjack/) for more details about the game and the environment." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "env = gym.make(\"Blackjack-v1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "mind = cst.Mind()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the mind and environment, we can create the codelet, insert it inside the mind and start it:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "gym_codelet = GymCodelet(mind, env)\n", + "mind.insert_codelet(gym_codelet)\n", + "\n", + "mind.start()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One important detail is that the GymCodelet always runs in the [Publisher-Subscriber](https://h-iaac.github.io/CST-Python/_build/html/_examples/Publisher-Subscriber.html) mode.\n", + "\n", + "It creates two important memories for starting the environment: the seed memory and the reset memory.\n", + "\n", + "We gonna set the environment seed to 42 to exemplify how it works, and restart the environment: " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.seed_memory.set_info(42)\n", + "gym_codelet.reset_memory.set_info(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we look the observation memories, we gonna see a single memory with the environment provided observation, a tuple with the player current sum, dealer showing card value and usable ace:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [ + "observation0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'observation': MemoryObject [idmemoryobject=0, timestamp=1732730372039, evaluation=0.0, I=(15, 2, 0), name=observation]}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [ + "observation1" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(15, 2, 0)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories[\"observation\"].get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The step count memory shows the steps since the episode start:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [ + "step_count" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.step_count_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The action memories also contains a single \"action\" memory:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [ + "action0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'action': MemoryObject [idmemoryobject=1, timestamp=1732730372025, evaluation=0.0, I=1, name=action]}" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We gonna set it to `1` for a hit." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"action\"].set_info(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When the action memory changes, the codelet executes a step in the environment. We can see that the step count and observation changes:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "tags": [ + "step_count+observation0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, (25, 2, 0))" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.step_count_memory.get_info(), gym_codelet.observation_memories[\"observation\"].get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we busted, the environment terminated:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [ + "terminated0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.terminated_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the step reward is -1 as we lost:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "tags": [ + "reward0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "-1.0" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.reward_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We gonna start a new episode. Observes that the codelet resets the environment each time the reset memory timestamp changes, even if the content is the same. The first observation is the same as before, since we setted the environment seed:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "tags": [ + "observation2" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(15, 2, 0)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.reset_memory.set_info(True)\n", + "gym_codelet.observation_memories[\"observation\"].get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This time, we gonna choose to stick:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "tags": [ + "observation3" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(15, 2, 0)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"action\"].set_info(0)\n", + "gym_codelet.observation_memories[\"observation\"].get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we won this game:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "terminated+reward0" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, 1.0)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.terminated_memory.get_info(), gym_codelet.reward_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dict Spaces\n", + "\n", + "So far, we have used the codelet to map all observations in the environment to a single memory with a generic name. However, if the environment has observation and action spaces of type Dict, the Codelet will map each observation and each action to a specific memory.\n", + "\n", + "Let's see this." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "env = gym.make(\"Blackjack-v1\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Different from before, we will use TransformObservation and TransformAction to transform the original observations and actions into Dict Spaces:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "env = TransformObservation(env, \n", + " lambda obs:{\"player_sum\":obs[0], \"dealer_card\":obs[1], \"usable_ace\":obs[2]}, \n", + " gym.spaces.Dict({\"player_sum\":env.observation_space[0], \"dealer_card\":env.observation_space[1], \"usable_ace\":env.observation_space[2]}))\n", + "\n", + "env = TransformAction(env, \n", + " lambda action:action[\"hit\"], \n", + " gym.spaces.Dict({\"hit\":env.action_space}))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's create and start the agent and environment just like before:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mind = cst.Mind()\n", + "gym_codelet = GymCodelet(mind, env)\n", + "mind.insert_codelet(gym_codelet)\n", + "\n", + "mind.start()\n", + "\n", + "gym_codelet.seed_memory.set_info(42)\n", + "gym_codelet.reset_memory.set_info(True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This time, we can see that the observation memories changed, with a single memory for each observation:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "tags": [ + "observation4" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'dealer_card': MemoryObject [idmemoryobject=0, timestamp=1732730372367, evaluation=0.0, I=2, name=dealer_card],\n", + " 'player_sum': MemoryObject [idmemoryobject=1, timestamp=1732730372367, evaluation=0.0, I=15, name=player_sum],\n", + " 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=1732730372367, evaluation=0.0, I=0, name=usable_ace]}" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.observation_memories" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "tags": [ + "observation5" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'dealer_card': 2, 'player_sum': 15, 'usable_ace': 0}" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{memory_name:gym_codelet.observation_memories[memory_name].get_info() for memory_name in gym_codelet.observation_memories}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The action memory also changed it's name:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "tags": [ + "action1" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'hit': MemoryObject [idmemoryobject=3, timestamp=1732730372365, evaluation=0.0, I=0, name=hit]}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just like before, we choose to stick:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.action_memories[\"hit\"].set_info(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And won:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "tags": [ + "terminated+reward1" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, 1.0)" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gym_codelet.terminated_memory.get_info(), gym_codelet.reward_memory.get_info()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Next steps\n", + "\n", + "The idea is not to use the Codelet to manually interface with the environment like this example, but to create a cognitive architecture to perform the environment's task.\n", + "\n", + "Another possibility is to combine GymCodelet with MemoryStorage to use gym environments with a remote cognitive agent or in CST-Java." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/cst_python/python/gym/gym_codelet.py b/src/cst_python/python/gym/gym_codelet.py index e702319..2498f2b 100644 --- a/src/cst_python/python/gym/gym_codelet.py +++ b/src/cst_python/python/gym/gym_codelet.py @@ -14,7 +14,10 @@ class GymCodelet(Codelet): environment with the action. ''' - _last_indexes : dict[str, int] = {"reward":-1, "reset":-1, "terminated":-1, "truncated":-1, "info":-1, "seed":-1} + _last_indexes : dict[str, int] = {"reward":-1, "reset":-1, + "terminated":-1, "truncated":-1, + "info":-1, "seed":-1, + "step_count":-1} def __init__(self, mind:Mind, env:gym.Env): ''' @@ -36,7 +39,7 @@ def __init__(self, mind:Mind, env:gym.Env): self.action_memories = self.space_to_memories(mind, env.action_space, action=True) self._common_memories : dict[str, MemoryObject] = {} - for name in ["reward", "reset", "terminated", "truncated", "info", "seed"]: + for name in ["reward", "reset", "terminated", "truncated", "info", "seed", "step_count"]: self._last_indexes[name] += 1 memory_name = name @@ -51,6 +54,7 @@ def __init__(self, mind:Mind, env:gym.Env): self._common_memories["truncated"].set_info(False) self._common_memories["info"].set_info({}) self._common_memories["seed"].set_info(None) + self._common_memories["step_count"].set_info(0) self.is_memory_observer = True @@ -59,7 +63,7 @@ def __init__(self, mind:Mind, env:gym.Env): memory.add_memory_observer(self) self._common_memories["reset"].add_memory_observer(self) - self._last_reset = self._common_memories["reset"].get_timestamp() + self._last_reset = 0 @property def reward_memory(self) -> MemoryObject: @@ -105,6 +109,13 @@ def seed_memory(self) -> MemoryObject: ''' return self._common_memories["seed"] + @property + def step_count_memory(self) -> MemoryObject: + ''' + Memory that contains the step count for the current environment + episode. + ''' + return self._common_memories["step_count"] def access_memory_objects(self) -> None: #NOSONAR pass @@ -120,18 +131,20 @@ def proc(self) -> None: reward = 0.0 terminated = False truncated = False + step_count = 0 else: action = self.memories_to_space(self.action_memories, self.env.action_space) observation, r, terminated, truncated, info = self.env.step(action) reward = float(r) #SupportsFloat to float - print("Observation", observation) + step_count = self.step_count_memory.get_info()+1 self.reward_memory.set_info(reward) self.terminated_memory.set_info(terminated) self.truncated_memory.set_info(truncated) self.info_memory.set_info(info) + self.step_count_memory.set_info(step_count) self.sample_to_memories(observation, self.observation_memories) diff --git a/tests/examples/test_gym_integration.py b/tests/examples/test_gym_integration.py new file mode 100644 index 0000000..f1f7e55 --- /dev/null +++ b/tests/examples/test_gym_integration.py @@ -0,0 +1,45 @@ +import os +import re + +from testbook import testbook +from testbook.client import TestbookNotebookClient + +from ..utils import get_examples_path + +examples_path = get_examples_path() + +@testbook(os.path.join(examples_path, "Gymnasium Integration.ipynb"), execute=True) +def test_gym_integration(tb :TestbookNotebookClient): + + expected_result = {"observation0":"{'observation': MemoryObject [idmemoryobject=0, timestamp=, evaluation=0.0, I=(15, 2, 0), name=observation]}", + "observation1":"(15, 2, 0)", + "step_count":"0", + "action0":"{'action': MemoryObject [idmemoryobject=1, timestamp=, evaluation=0.0, I=, name=action]}", + "step_count+observation0":"(1, (25, 2, 0))", + "terminated0":"True", + "reward0":"-1.0", + "observation2":"(15, 2, 0)", + "observation3":"(15, 2, 0)", + "terminated+reward0":"(True, 1.0)", + + "observation4":'''{'dealer_card': MemoryObject [idmemoryobject=0, timestamp=, evaluation=0.0, I=2, name=dealer_card], + 'player_sum': MemoryObject [idmemoryobject=1, timestamp=, evaluation=0.0, I=15, name=player_sum], + 'usable_ace': MemoryObject [idmemoryobject=2, timestamp=, evaluation=0.0, I=0, name=usable_ace]}''', + + "observation5":"{'dealer_card': 2, 'player_sum': 15, 'usable_ace': 0}", + "action1":"{'hit': MemoryObject [idmemoryobject=3, timestamp=, evaluation=0.0, I=, name=hit]}", + "terminated+reward1":"(True, 1.0)" + } + + clear_info = ["action0", "action1"] + + for tag in expected_result: + result = tb.cell_output_text(tag) + result = re.sub(r"timestamp=[0-9]+", "timestamp=", result) + + if tag in clear_info: + result = re.sub(r"I=[0-9]+", "I=", result) + + assert result == expected_result[tag] + + From 34ae5acdb1b829c661dc9445597434685209b9b2 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:03:48 -0300 Subject: [PATCH 55/59] Gym example in documentation --- docs/index.rst | 1 + examples/README.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 06ffaa8..a8afed6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,6 +19,7 @@ _examples/Implementing a Architecture _examples/Publisher-Subscriber _examples/Activation and Monitoring + _examples/Gymnasium Integration .. toctree:: :maxdepth: 4 diff --git a/examples/README.md b/examples/README.md index 2116e3e..621060e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -5,4 +5,5 @@ Here we have some examples of how to use the CST-Python: - [Introduction to CST-Python](https://h-iaac.github.io/CST-Python/_build/html/_examples/Introduction%20to%20CST-Python.html): what is CST-Python, and basics about how to use it. - [Implementing a Architecture](https://h-iaac.github.io/CST-Python/_build/html/_examples/Implementing%20a%20Architecture.html): how to implement a cognitive architecture using CST-Python. - [Publisher-Subscriber](https://h-iaac.github.io/CST-Python/_build/html/_examples/Publisher-Subscriber.html): using the publisher-subscriber mechanism for synchronous codelets. -- [Activation and Monitoring](https://h-iaac.github.io/CST-Python/_build/html/_examples/Activation%20and%20Monitoring.html): using codelet's activation value and monitoring the agent. \ No newline at end of file +- [Activation and Monitoring](https://h-iaac.github.io/CST-Python/_build/html/_examples/Activation%20and%20Monitoring.html): using codelet's activation value and monitoring the agent. +- [Gymnasium Integration](https://h-iaac.github.io/CST-Python/_build/html/_examples/Gymnasium%20Integration.html): using gymnasium environments with CST. \ No newline at end of file From d5a219884aec048d11ac07ae87f78b474dbfa158 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:32:38 -0300 Subject: [PATCH 56/59] GymCodelet tests --- src/cst_python/python/gym/gym_codelet.py | 12 +- tests/cst_python/python/__init__.py | 0 tests/cst_python/python/gym/__init__.py | 0 .../cst_python/python/gym/test_gym_codelet.py | 124 ++++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/cst_python/python/__init__.py create mode 100644 tests/cst_python/python/gym/__init__.py create mode 100644 tests/cst_python/python/gym/test_gym_codelet.py diff --git a/src/cst_python/python/gym/gym_codelet.py b/src/cst_python/python/gym/gym_codelet.py index 2498f2b..3c99e50 100644 --- a/src/cst_python/python/gym/gym_codelet.py +++ b/src/cst_python/python/gym/gym_codelet.py @@ -64,7 +64,7 @@ def __init__(self, mind:Mind, env:gym.Env): self._common_memories["reset"].add_memory_observer(self) self._last_reset = 0 - + @property def reward_memory(self) -> MemoryObject: ''' @@ -148,6 +148,16 @@ def proc(self) -> None: self.sample_to_memories(observation, self.observation_memories) + @classmethod + def reset_indexes(cls) -> None: + ''' + Reset the indexes for setting the sufix of new memories. + ''' + cls._last_indexes : dict[str, int] = {"reward":-1, "reset":-1, + "terminated":-1, "truncated":-1, + "info":-1, "seed":-1, + "step_count":-1} + @classmethod def space_to_memories(cls, mind:Mind, space:gym.Space, diff --git a/tests/cst_python/python/__init__.py b/tests/cst_python/python/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/cst_python/python/gym/__init__.py b/tests/cst_python/python/gym/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/cst_python/python/gym/test_gym_codelet.py b/tests/cst_python/python/gym/test_gym_codelet.py new file mode 100644 index 0000000..5651016 --- /dev/null +++ b/tests/cst_python/python/gym/test_gym_codelet.py @@ -0,0 +1,124 @@ +from contextlib import redirect_stdout +import math +import unittest +import time +import threading +import io + +import gymnasium as gym +from gymnasium.spaces import Box, Dict +import numpy as np +from numpy.testing import assert_array_almost_equal + +from cst_python import MemoryObject, Mind +from cst_python.python.gym import GymCodelet + +class TestGymCodelet(unittest.TestCase): + def setUp(self) -> None: + ... + + def test_space_to_memories(self) -> None: + space = Box(-1, 1, (2,)) + mind = Mind() + + GymCodelet.reset_indexes() + + memories = GymCodelet.space_to_memories(mind, space) + keys = list(memories.keys()) + assert len(keys) == 1 + assert keys[0] == "observation" + memory = memories[keys[0]] + assert memory.get_name() == "observation" + assert space.contains(memory.get_info()) + + memories = GymCodelet.space_to_memories(mind, space) + memory = memories[next(iter(memories))] + assert memory.get_name() == "observation1" + + space = Dict({"x":Box(-1, 1, (2,)), "y":Box(-2, 1, (1,))}) + memories = GymCodelet.space_to_memories(mind, space) + keys = list(memories.keys()) + assert len(keys) == 2 + assert "x" in keys + assert "y" in keys + assert memories["x"].get_name() == "x" + assert memories["y"].get_name() == "y" + + memories = GymCodelet.space_to_memories(mind, space) + keys = list(memories.keys()) + assert len(keys) == 2 + assert "x" in keys + assert "y" in keys + assert memories["x"].get_name() == "x1" + assert memories["y"].get_name() == "y1" + + def test_sample_to_memories(self) -> None: + space = Box(-1, 1, (2,)) + sample = space.sample() + memories = {"observation":MemoryObject()} + + GymCodelet.sample_to_memories(sample, memories) + + assert_array_almost_equal(memories["observation"].get_info(), sample) + + + space = Dict({"x":Box(-1, 1, (2,)), "y":Box(-2, 1, (1,))}) + sample = space.sample() + memories = {"x":MemoryObject(), "y":MemoryObject()} + + GymCodelet.sample_to_memories(sample, memories) + + assert_array_almost_equal(memories["x"].get_info(), sample["x"]) + assert_array_almost_equal(memories["y"].get_info(), sample["y"]) + + def test_memories_to_space(self) -> None: + space = Box(-1, 1, (2,)) + sample = space.sample() + memories = {"observation":MemoryObject()} + memories["observation"].set_info(sample) + + reconstruced_sample = GymCodelet.memories_to_space(memories, space) + assert space.contains(reconstruced_sample) + assert_array_almost_equal(reconstruced_sample, sample) + + space = Dict({"x":Box(-1, 1, (2,)), "y":Box(-2, 1, (1,))}) + sample = space.sample() + memories = {"x":MemoryObject(), "y":MemoryObject()} + memories["x"].set_info(sample["x"]) + memories["y"].set_info(sample["y"]) + + reconstruced_sample = GymCodelet.memories_to_space(memories, space) + assert space.contains(reconstruced_sample) + assert_array_almost_equal(reconstruced_sample["x"], sample["x"]) + assert_array_almost_equal(reconstruced_sample["y"], sample["y"]) + + def test_episode(self) -> None: + env = gym.make("MountainCar-v0") + mind = Mind() + gym_codelet = GymCodelet(mind, env) + + mind.start() + + assert gym_codelet.step_count_memory.get_info() == 0 + gym_codelet.reset_memory.set_info(True) + assert gym_codelet.step_count_memory.get_info() == 0 + gym_codelet.action_memories["action"].set_info(1) + assert gym_codelet.step_count_memory.get_info() == 1 + gym_codelet.action_memories["action"].set_info(1) + assert gym_codelet.step_count_memory.get_info() == 2 + time.sleep(1e-3) #Minimum time for memory timestamp comparation is 1 ms + gym_codelet.reset_memory.set_info(True) + assert gym_codelet.step_count_memory.get_info() == 0 + + def test_env_memories(self) -> None: + env = gym.make("Blackjack-v1") + mind = Mind() + gym_codelet = GymCodelet(mind, env) + + assert len(gym_codelet.observation_memories) == 1 + assert "observation" in gym_codelet.observation_memories + assert env.observation_space.contains(gym_codelet.observation_memories["observation"].get_info()) + + assert len(gym_codelet.action_memories) == 1 + assert "action" in gym_codelet.action_memories + assert env.action_space.contains(gym_codelet.action_memories["action"].get_info()) \ No newline at end of file From 44915f1e629483601e3d9eab631c78a5d6cb3f5e Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:36:39 -0300 Subject: [PATCH 57/59] Fix test pipeline package install --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d6497dc..f8939f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: python3 -m pip install --upgrade pip python3 -m pip install pytest python3 -m pip install pytest-cov - python3 -m pip install -e .[tests, gym] + python3 -m pip install -e .[tests,gym] - name: Tests run: | From efb0a58a204e487d9c0f68949c05bb88a5cef126 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:39:30 -0300 Subject: [PATCH 58/59] Fix GymCodelet typecheking --- src/cst_python/python/gym/gym_codelet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cst_python/python/gym/gym_codelet.py b/src/cst_python/python/gym/gym_codelet.py index 3c99e50..055ec5c 100644 --- a/src/cst_python/python/gym/gym_codelet.py +++ b/src/cst_python/python/gym/gym_codelet.py @@ -153,7 +153,7 @@ def reset_indexes(cls) -> None: ''' Reset the indexes for setting the sufix of new memories. ''' - cls._last_indexes : dict[str, int] = {"reward":-1, "reset":-1, + cls._last_indexes = {"reward":-1, "reset":-1, "terminated":-1, "truncated":-1, "info":-1, "seed":-1, "step_count":-1} From 6a549614042f69c401c3c37013f20940f215f714 Mon Sep 17 00:00:00 2001 From: Elton Cardoso do Nascimento <43186596+EltonCN@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:17:31 -0300 Subject: [PATCH 59/59] RawMemory class documentation --- src/cst_python/core/entities/raw_memory.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cst_python/core/entities/raw_memory.py b/src/cst_python/core/entities/raw_memory.py index 6f7fabf..246834e 100644 --- a/src/cst_python/core/entities/raw_memory.py +++ b/src/cst_python/core/entities/raw_memory.py @@ -11,6 +11,10 @@ #TODO createMemoryContainer, REST methods class RawMemory: + ''' + The Raw Memory contains all memories in the system. + ''' + _last_id = 0 def __init__(self) -> None: