polycog-cognition 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. polycog_cognition-1.0.0/LICENSE.md +105 -0
  2. polycog_cognition-1.0.0/PKG-INFO +38 -0
  3. polycog_cognition-1.0.0/README.md +19 -0
  4. polycog_cognition-1.0.0/pyproject.toml +53 -0
  5. polycog_cognition-1.0.0/setup.cfg +4 -0
  6. polycog_cognition-1.0.0/src/cognition/__init__.py +22 -0
  7. polycog_cognition-1.0.0/src/cognition/cogent/__init__.py +44 -0
  8. polycog_cognition-1.0.0/src/cognition/cogent/cogent.py +384 -0
  9. polycog_cognition-1.0.0/src/cognition/cogent/env.py +280 -0
  10. polycog_cognition-1.0.0/src/cognition/decision/__init__.py +101 -0
  11. polycog_cognition-1.0.0/src/cognition/decision/chain.py +171 -0
  12. polycog_cognition-1.0.0/src/cognition/decision/core.py +920 -0
  13. polycog_cognition-1.0.0/src/cognition/decision/dp.py +731 -0
  14. polycog_cognition-1.0.0/src/cognition/decision/stage.py +130 -0
  15. polycog_cognition-1.0.0/src/cognition/decision/state.py +218 -0
  16. polycog_cognition-1.0.0/src/cognition/knowledge/__init__.py +34 -0
  17. polycog_cognition-1.0.0/src/cognition/knowledge/organization.py +647 -0
  18. polycog_cognition-1.0.0/src/cognition/knowledge/representation.py +280 -0
  19. polycog_cognition-1.0.0/src/cognition/language/__init__.py +45 -0
  20. polycog_cognition-1.0.0/src/cognition/language/classification.py +237 -0
  21. polycog_cognition-1.0.0/src/cognition/language/description.py +648 -0
  22. polycog_cognition-1.0.0/src/cognition/language/population.py +162 -0
  23. polycog_cognition-1.0.0/src/cognition/py.typed +0 -0
  24. polycog_cognition-1.0.0/src/cognition/reasoning/__init__.py +37 -0
  25. polycog_cognition-1.0.0/src/cognition/reasoning/planning.py +622 -0
  26. polycog_cognition-1.0.0/src/cognition/util/__init__.py +59 -0
  27. polycog_cognition-1.0.0/src/cognition/util/enumeration.py +114 -0
  28. polycog_cognition-1.0.0/src/cognition/util/functypes.py +34 -0
  29. polycog_cognition-1.0.0/src/cognition/util/misc.py +249 -0
  30. polycog_cognition-1.0.0/src/polycog_cognition.egg-info/PKG-INFO +38 -0
  31. polycog_cognition-1.0.0/src/polycog_cognition.egg-info/SOURCES.txt +44 -0
  32. polycog_cognition-1.0.0/src/polycog_cognition.egg-info/dependency_links.txt +1 -0
  33. polycog_cognition-1.0.0/src/polycog_cognition.egg-info/requires.txt +3 -0
  34. polycog_cognition-1.0.0/src/polycog_cognition.egg-info/top_level.txt +1 -0
  35. polycog_cognition-1.0.0/tests/test_chain.py +125 -0
  36. polycog_cognition-1.0.0/tests/test_cogent.py +478 -0
  37. polycog_cognition-1.0.0/tests/test_core.py +716 -0
  38. polycog_cognition-1.0.0/tests/test_dp.py +1093 -0
  39. polycog_cognition-1.0.0/tests/test_enumeration.py +86 -0
  40. polycog_cognition-1.0.0/tests/test_env.py +170 -0
  41. polycog_cognition-1.0.0/tests/test_knowledge.py +521 -0
  42. polycog_cognition-1.0.0/tests/test_language.py +790 -0
  43. polycog_cognition-1.0.0/tests/test_planning.py +465 -0
  44. polycog_cognition-1.0.0/tests/test_stage.py +178 -0
  45. polycog_cognition-1.0.0/tests/test_state.py +429 -0
  46. polycog_cognition-1.0.0/tests/test_utility.py +227 -0
@@ -0,0 +1,105 @@
1
+ # Functional Source License, Version 1.1, ALv2 Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-ALv2
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Polycog, Inc.
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the Apache License, Version 2.0 that is effective on the second anniversary of
91
+ the date we make the Software available. On or after that date, you may use the
92
+ Software under the Apache License, Version 2.0, in which case the following
93
+ will apply:
94
+
95
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
96
+ this file except in compliance with the License.
97
+
98
+ You may obtain a copy of the License at
99
+
100
+ http://www.apache.org/licenses/LICENSE-2.0
101
+
102
+ Unless required by applicable law or agreed to in writing, software distributed
103
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
104
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
105
+ specific language governing permissions and limitations under the License.
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: polycog-cognition
3
+ Version: 1.0.0
4
+ Summary: Polycog cognition library
5
+ Author-email: Nate Derbinsky <nate@polycog.ai>
6
+ Project-URL: Homepage, https://polycog.ai
7
+ Project-URL: Repository, https://github.com/polycog/cognition.git
8
+ Keywords: ai,neurosymbolic
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.13
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE.md
15
+ Requires-Dist: pydantic-ai-slim[spec]~=2.9.1
16
+ Requires-Dist: networkx~=3.6.1
17
+ Requires-Dist: types-networkx~=3.6.1.0
18
+ Dynamic: license-file
19
+
20
+ <div align="center">
21
+
22
+ # Polycog cognition
23
+
24
+ [![Checks](https://github.com/polycog/cognition/actions/workflows/checks.yml/badge.svg)](https://github.com/polycog/cognition/actions/workflows/checks.yml)
25
+ [![License: FSL-1.1-ALv2](https://img.shields.io/badge/license-FSL--1.1--ALv2-blue.svg)](https://fsl.software)
26
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fpolycog%2Fcognition%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)
27
+ [![Discord](https://img.shields.io/discord/1498434981788123206)](https://discord.gg/Uqhjq9vBnV)
28
+
29
+ <p>
30
+ <a href="https://polycog.ai" target="_blank">Website</a> &bull;
31
+ <a href="https://github.com/polycog/tutorials" target="_blank">Tutorials</a> &bull;
32
+ <a href="https://docs.polycog.ai" target="_blank">Docs</a>
33
+ </p>
34
+
35
+ </div>
36
+
37
+ Reasoning infrastructure for trustworthy agents.
38
+
@@ -0,0 +1,19 @@
1
+ <div align="center">
2
+
3
+ # Polycog cognition
4
+
5
+ [![Checks](https://github.com/polycog/cognition/actions/workflows/checks.yml/badge.svg)](https://github.com/polycog/cognition/actions/workflows/checks.yml)
6
+ [![License: FSL-1.1-ALv2](https://img.shields.io/badge/license-FSL--1.1--ALv2-blue.svg)](https://fsl.software)
7
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fpolycog%2Fcognition%2Frefs%2Fheads%2Fmain%2Fpyproject.toml)
8
+ [![Discord](https://img.shields.io/discord/1498434981788123206)](https://discord.gg/Uqhjq9vBnV)
9
+
10
+ <p>
11
+ <a href="https://polycog.ai" target="_blank">Website</a> &bull;
12
+ <a href="https://github.com/polycog/tutorials" target="_blank">Tutorials</a> &bull;
13
+ <a href="https://docs.polycog.ai" target="_blank">Docs</a>
14
+ </p>
15
+
16
+ </div>
17
+
18
+ Reasoning infrastructure for trustworthy agents.
19
+
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 82.0.1"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "polycog-cognition"
7
+ dynamic = ["version"]
8
+ dependencies = [
9
+ "pydantic-ai-slim[spec] ~= 2.9.1",
10
+ "networkx ~= 3.6.1",
11
+ "types-networkx ~= 3.6.1.0",
12
+ ]
13
+ requires-python = ">=3.13"
14
+ authors = [
15
+ { name="Nate Derbinsky", email="nate@polycog.ai" }
16
+ ]
17
+ description = "Polycog cognition library"
18
+ readme = "README.md"
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Operating System :: OS Independent",
23
+ ]
24
+ keywords = [
25
+ "ai",
26
+ "neurosymbolic",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://polycog.ai"
31
+ Repository = "https://github.com/polycog/cognition.git"
32
+
33
+ [tool.setuptools.dynamic]
34
+ version = {attr = "cognition.__version__"}
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["src"]
38
+
39
+ [tool.setuptools.package-data]
40
+ "cognition" = ["py.typed"]
41
+
42
+ [tool.black]
43
+ target-version = ["py313",]
44
+
45
+ [tool.mypy]
46
+ python_version = "3.13"
47
+ strict = true
48
+
49
+ [tool.pylint.MAIN]
50
+ ignored-classes = ["AttrReferral"]
51
+
52
+ [tool.pylint.similarities]
53
+ min-similarity-lines=8
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ """
2
+ Polycog cognition library
3
+ """
4
+
5
+ import logging
6
+
7
+ from .cogent import *
8
+ from .decision import *
9
+ from .knowledge import *
10
+ from .language import *
11
+ from .reasoning import *
12
+ from .util import *
13
+
14
+ # ===
15
+
16
+ logger = logging.getLogger(__name__)
17
+ logger.setLevel(logging.NOTSET)
18
+ logger.addHandler(logging.NullHandler())
19
+
20
+ # ===
21
+
22
+ __version__ = "1.0.0"
@@ -0,0 +1,44 @@
1
+ """
2
+ Cogent sub-module
3
+ """
4
+
5
+ from . import cogent, env
6
+ from .cogent import (
7
+ Cogent,
8
+ self_actuator,
9
+ self_sensor,
10
+ )
11
+ from .env import (
12
+ Actuator,
13
+ ActuatorInvoker,
14
+ BaseActuator,
15
+ BaseSensor,
16
+ Sensor,
17
+ SensorReader,
18
+ create_actuator,
19
+ create_sensor,
20
+ install,
21
+ invoke_actuator,
22
+ perceive,
23
+ read_sensor_data,
24
+ )
25
+
26
+ __all__ = [
27
+ "Actuator",
28
+ "ActuatorInvoker",
29
+ "BaseActuator",
30
+ "BaseSensor",
31
+ "Cogent",
32
+ "Sensor",
33
+ "SensorReader",
34
+ "cogent",
35
+ "create_actuator",
36
+ "create_sensor",
37
+ "env",
38
+ "install",
39
+ "invoke_actuator",
40
+ "perceive",
41
+ "read_sensor_data",
42
+ "self_actuator",
43
+ "self_sensor",
44
+ ]
@@ -0,0 +1,384 @@
1
+ """
2
+ (Cog)nitive ag(ents)
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ import logging
8
+ from collections.abc import Mapping
9
+ from types import MappingProxyType
10
+ from typing import Any, Literal, Self
11
+
12
+ from ..decision.core import (
13
+ BaseDecisionProcess,
14
+ DecisionProcessErrorMessage,
15
+ DecisionProcessExecutionError,
16
+ )
17
+ from ..decision.dp import NamedObject, args_added, format_name_params
18
+ from ..util.functypes import BiFunction, BiPredicate, Function, Predicate, Supplier
19
+ from ..util.misc import stringify
20
+ from .env import (
21
+ BaseActuator,
22
+ BaseSensor,
23
+ create_actuator,
24
+ create_sensor,
25
+ install,
26
+ perceive,
27
+ )
28
+
29
+ # ===
30
+
31
+ _logger = logging.getLogger(__name__)
32
+
33
+ # ===
34
+
35
+
36
+ def self_sensor[C: Cogent[Any], T](m: Function[C, T]) -> Function[C, T]:
37
+ """
38
+ Decorator to mark a cogent method for use as a sensor upon instance init
39
+
40
+ :param m: method
41
+ :return: supplied method (tagged for later init)
42
+ """
43
+
44
+ # pylint: disable=protected-access
45
+ m._is_selfsensor = True # type: ignore[attr-defined]
46
+ return m
47
+
48
+
49
+ def self_actuator[C: Cogent[Any], P, F](
50
+ m: BiFunction[C, P, F],
51
+ ) -> BiFunction[C, P, F]:
52
+ """
53
+ Decorator to mark a cogent method for use as an actuator upon instance init
54
+
55
+ :param m: method
56
+ :return: supplied method (tagged for later init)
57
+ """
58
+
59
+ # pylint: disable=protected-access
60
+ m._is_selfactuator = True # type: ignore[attr-defined]
61
+ return m
62
+
63
+
64
+ class Cogent[DP: BaseDecisionProcess[Any]](NamedObject):
65
+ """
66
+ Base for a cognitive agent that uses type ``S``
67
+ for decision process state, and ``DP`` as the
68
+ type of decision process
69
+ """
70
+
71
+ DEFAULT_NAME: str = "cogent"
72
+
73
+ _self_sensors: dict[str, Function[Cogent[DP], Any]]
74
+ _self_actuators: dict[str, BiFunction[Cogent[DP], Any, Any]]
75
+
76
+ def __init_subclass__(cls, **kwargs: Any) -> None:
77
+ super().__init_subclass__(**kwargs)
78
+
79
+ cls._self_sensors = {
80
+ name: val
81
+ for name, val in vars(cls).items()
82
+ if callable(val) and getattr(val, "_is_selfsensor", False)
83
+ }
84
+
85
+ cls._self_actuators = {
86
+ name: val
87
+ for name, val in vars(cls).items()
88
+ if callable(val) and getattr(val, "_is_selfactuator", False)
89
+ }
90
+
91
+ def _add_self_tagged(self) -> None:
92
+
93
+ if hasattr(self, "_self_sensors"):
94
+ for s_n, s_m in self._self_sensors.items():
95
+
96
+ def _self_sensor[T](orig_method: Function[Cogent[DP], T] = s_m) -> T:
97
+ return orig_method(self)
98
+
99
+ self.add_sensor(create_sensor(s_n, _self_sensor))
100
+
101
+ if hasattr(self, "_self_actuators"):
102
+ for a_n, a_m in self._self_actuators.items():
103
+
104
+ def _self_actuator[P, F](
105
+ param: P, orig_method: BiFunction[Cogent[DP], P, F] = a_m
106
+ ) -> F:
107
+ return orig_method(self, param)
108
+
109
+ self.add_actuator(create_actuator(a_n, _self_actuator))
110
+
111
+ # ===
112
+
113
+ def __init__(
114
+ self, decision_process: DP, name: str = DEFAULT_NAME, **kwargs: Any
115
+ ) -> None:
116
+ """
117
+ :param decision_process: agent control
118
+ :param name: agent name
119
+ :param kwargs: optional parameters to describe the agent
120
+ """
121
+
122
+ self._dp = decision_process
123
+ self._sensors: set[BaseSensor[Any]] = set()
124
+
125
+ self._name = name
126
+ self._params = kwargs
127
+ self._str = format_name_params(name, **kwargs)
128
+
129
+ # ===
130
+
131
+ self._add_self_tagged()
132
+
133
+ _logger.info("Cogent (%s): initialized", self)
134
+
135
+ def __str__(self) -> str:
136
+ return self._str
137
+
138
+ @property
139
+ def dp(self) -> DP:
140
+ """
141
+ :return: decision process for this cogent
142
+ """
143
+
144
+ return self._dp
145
+
146
+ @property
147
+ def name(self) -> str:
148
+ """
149
+ :return: cogent's name
150
+ """
151
+
152
+ return self._name
153
+
154
+ @property
155
+ def params(self) -> Mapping[str, Any]:
156
+ """
157
+ :return: optional augmentations to the cogent
158
+ """
159
+
160
+ return MappingProxyType(self._params)
161
+
162
+ def add_sensor(self, sensor: BaseSensor[Any]) -> Self:
163
+ """
164
+ Add a sensor to the cogent
165
+
166
+ :param sensor: sensor to add
167
+ :return: this cogent (for chaining)
168
+ """
169
+
170
+ _logger.info("Cogent (%s): sensor (%s) added", self, sensor.name)
171
+
172
+ self._sensors.add(sensor)
173
+ return self
174
+
175
+ def sensor(
176
+ self,
177
+ **kwargs: Any,
178
+ ) -> Function[type[BaseSensor[Any]], type[BaseSensor[Any]]]:
179
+ """
180
+ Decorator version of :meth:`Cogent.add_sensor`
181
+
182
+ :param kwargs: instantiation argument(s)
183
+ :return: parameterized decorator
184
+ """
185
+
186
+ def cls_dec(cls: type[BaseSensor[Any]]) -> type[BaseSensor[Any]]:
187
+ """
188
+ Adds a sensor instance to this cogent.
189
+
190
+ :param cls: sensor to instantiate
191
+ :return: added class
192
+ """
193
+
194
+ self.add_sensor(cls(**kwargs))
195
+ return cls
196
+
197
+ return cls_dec
198
+
199
+ def as_sensor[T](self, name: str) -> Function[Supplier[T], Supplier[T]]:
200
+ """
201
+ Decorator version of :func:`.env.create_sensor`
202
+
203
+ :param name: name for the sensor instance
204
+ :return: parameterized decorator
205
+ """
206
+
207
+ def dec(f: Supplier[T]) -> Supplier[T]:
208
+ self.add_sensor(create_sensor(name, f))
209
+ return f
210
+
211
+ return dec
212
+
213
+ def add_actuator(self, actuator: BaseActuator[Any, Any]) -> Self:
214
+ """
215
+ Add an actuator to the cogent
216
+
217
+ :param actuator: actuator to add
218
+ :return: this cogent (for chaining)
219
+ """
220
+
221
+ _logger.info("Cogent (%s): actuator (%s) installed", self, actuator.name)
222
+
223
+ install(actuator, self._dp)
224
+ return self
225
+
226
+ def actuator(
227
+ self,
228
+ **kwargs: Any,
229
+ ) -> Function[type[BaseActuator[Any, Any]], type[BaseActuator[Any, Any]]]:
230
+ """
231
+ Decorator version of :meth:`Cogent.add_actuator`
232
+
233
+ :param kwargs: instantiation argument(s)
234
+ :return: parameterized decorator
235
+ """
236
+
237
+ def cls_dec(cls: type[BaseActuator[Any, Any]]) -> type[BaseActuator[Any, Any]]:
238
+ """
239
+ Adds a actuator instance to this cogent.
240
+
241
+ :param cls: actuator to instantiate
242
+ :return: added class
243
+ """
244
+
245
+ self.add_actuator(cls(**kwargs))
246
+ return cls
247
+
248
+ return cls_dec
249
+
250
+ def as_actuator[P, F](self, name: str) -> Function[Function[P, F], Function[P, F]]:
251
+ """
252
+ Decorator version of :func:`.env.create_actuator`
253
+
254
+ :param name: name for the actuator instance
255
+ :return: parameterized decorator
256
+ """
257
+
258
+ def dec(f: Function[P, F]) -> Function[P, F]:
259
+ self.add_actuator(create_actuator(name, f))
260
+ return f
261
+
262
+ return dec
263
+
264
+ def perception(self) -> None:
265
+ """
266
+ All added sensors are routed to the decision process IO container
267
+ """
268
+
269
+ _logger.info("Cogent (%s): all-sensor perception", self)
270
+
271
+ for s in self._sensors:
272
+ perceive(s, self._dp)
273
+
274
+ @stringify("run_once")
275
+ @staticmethod
276
+ def gate_run_once(_c: Cogent[Any]) -> Literal[False]:
277
+ """
278
+ Immediate end upon decision process termination
279
+ """
280
+
281
+ return False
282
+
283
+ @stringify("run_forever")
284
+ @staticmethod
285
+ def gate_run_forever(_c: Cogent[Any]) -> Literal[True]:
286
+ """
287
+ Restarts decision process upon termination
288
+ """
289
+
290
+ return True
291
+
292
+ def __call__(
293
+ self,
294
+ repeat_p: Predicate[Cogent[DP]] = gate_run_once,
295
+ max_cycles: int | None = None,
296
+ dp_err_p: BiPredicate[DecisionProcessErrorMessage, Self] | None = None,
297
+ other_err_p: BiPredicate[Exception, Self] | None = None,
298
+ **args: Any,
299
+ ) -> Self:
300
+ """
301
+ After initialization (dp.reinit, add arguments),
302
+ runs a cogent loop...
303
+
304
+ 1. Cache sensor(s) perception to IO
305
+ 2. Run the decision process
306
+ 3. Check the gating predicate
307
+ (reinitialize the decision process if not done)
308
+
309
+ until the supplied gating predicate returns ``False``
310
+
311
+ :param repeat_p: gating predicate (assuming no errors)
312
+ :param max_cycles: maximum dp cycles to run per loop;
313
+ ``None`` indicates no limit
314
+ :param dp_err_p: gating predicate to continue if a known
315
+ error type occurs (or raise if ``None``)
316
+ (see :class:`cognition.decision.core.DecisionProcessExecutionError`)
317
+ :param other_err_p: gating predicate to continue if an unknown
318
+ error type occurs (or raise if ``None``)
319
+ :param args: IO args to add (see :func:`cognition.decision.dp.args_added`)
320
+ :return: this cogent (for chaining)
321
+ """
322
+
323
+ _logger.info("Cogent (%s): run started", self)
324
+ _logger.debug(
325
+ "repeat_p=%s, max_cycles=%s, dp_err_p=%s, args=%s",
326
+ repeat_p,
327
+ max_cycles,
328
+ dp_err_p,
329
+ args,
330
+ )
331
+
332
+ proceed = True
333
+ self._dp.reinit()
334
+
335
+ with args_added(self._dp, **args):
336
+ while proceed:
337
+ _logger.debug("Cogent (%s): loop start", self)
338
+
339
+ try:
340
+ self.perception()
341
+ if max_cycles is None:
342
+ self._dp.run_until_done()
343
+ else:
344
+ self._dp.run_cycles(max_cycles)
345
+
346
+ _logger.debug("Cogent (%s): dp run complete", self)
347
+
348
+ proceed = repeat_p(self)
349
+ _logger.debug(
350
+ "Cogent (%s): gate checked (keep going: %s)", self, proceed
351
+ )
352
+ except DecisionProcessExecutionError as err_dp:
353
+ _logger.error(err_dp)
354
+
355
+ if dp_err_p is not None:
356
+ proceed = dp_err_p(err_dp.msg, self)
357
+
358
+ _logger.debug(
359
+ "Cogent (%s): known error gate checked (keep going: %s)",
360
+ self,
361
+ proceed,
362
+ )
363
+ else:
364
+ raise
365
+ except Exception as err_other: # pylint: disable=broad-exception-caught
366
+ _logger.error(err_other)
367
+
368
+ if other_err_p is not None:
369
+ proceed = other_err_p(err_other, self)
370
+
371
+ _logger.debug(
372
+ "Cogent (%s): unknown error gate checked (keep going: %s)",
373
+ self,
374
+ proceed,
375
+ )
376
+ else:
377
+ raise
378
+
379
+ if proceed:
380
+ self._dp.reinit()
381
+
382
+ _logger.info("Cogent (%s): run ended", self)
383
+
384
+ return self