symbolicai 1.0.0__py3-none-any.whl → 1.1.0__py3-none-any.whl

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 (127) hide show
  1. symai/__init__.py +198 -134
  2. symai/backend/base.py +51 -51
  3. symai/backend/engines/drawing/engine_bfl.py +33 -33
  4. symai/backend/engines/drawing/engine_gpt_image.py +4 -10
  5. symai/backend/engines/embedding/engine_llama_cpp.py +50 -35
  6. symai/backend/engines/embedding/engine_openai.py +22 -16
  7. symai/backend/engines/execute/engine_python.py +16 -16
  8. symai/backend/engines/files/engine_io.py +51 -49
  9. symai/backend/engines/imagecaptioning/engine_blip2.py +27 -23
  10. symai/backend/engines/imagecaptioning/engine_llavacpp_client.py +53 -46
  11. symai/backend/engines/index/engine_pinecone.py +116 -88
  12. symai/backend/engines/index/engine_qdrant.py +1011 -0
  13. symai/backend/engines/index/engine_vectordb.py +78 -52
  14. symai/backend/engines/lean/engine_lean4.py +65 -25
  15. symai/backend/engines/neurosymbolic/__init__.py +28 -28
  16. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +137 -135
  17. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +145 -152
  18. symai/backend/engines/neurosymbolic/engine_cerebras.py +328 -0
  19. symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py +75 -49
  20. symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +199 -155
  21. symai/backend/engines/neurosymbolic/engine_groq.py +106 -72
  22. symai/backend/engines/neurosymbolic/engine_huggingface.py +100 -67
  23. symai/backend/engines/neurosymbolic/engine_llama_cpp.py +121 -93
  24. symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py +213 -132
  25. symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py +180 -137
  26. symai/backend/engines/ocr/engine_apilayer.py +18 -20
  27. symai/backend/engines/output/engine_stdout.py +9 -9
  28. symai/backend/engines/{webscraping → scrape}/engine_requests.py +25 -11
  29. symai/backend/engines/search/engine_openai.py +95 -83
  30. symai/backend/engines/search/engine_parallel.py +665 -0
  31. symai/backend/engines/search/engine_perplexity.py +40 -41
  32. symai/backend/engines/search/engine_serpapi.py +33 -28
  33. symai/backend/engines/speech_to_text/engine_local_whisper.py +37 -27
  34. symai/backend/engines/symbolic/engine_wolframalpha.py +14 -8
  35. symai/backend/engines/text_to_speech/engine_openai.py +15 -19
  36. symai/backend/engines/text_vision/engine_clip.py +34 -28
  37. symai/backend/engines/userinput/engine_console.py +3 -4
  38. symai/backend/mixin/anthropic.py +48 -40
  39. symai/backend/mixin/deepseek.py +4 -5
  40. symai/backend/mixin/google.py +5 -4
  41. symai/backend/mixin/groq.py +2 -4
  42. symai/backend/mixin/openai.py +132 -110
  43. symai/backend/settings.py +14 -14
  44. symai/chat.py +164 -94
  45. symai/collect/dynamic.py +13 -11
  46. symai/collect/pipeline.py +39 -31
  47. symai/collect/stats.py +109 -69
  48. symai/components.py +556 -238
  49. symai/constraints.py +14 -5
  50. symai/core.py +1495 -1210
  51. symai/core_ext.py +55 -50
  52. symai/endpoints/api.py +113 -58
  53. symai/extended/api_builder.py +22 -17
  54. symai/extended/arxiv_pdf_parser.py +13 -5
  55. symai/extended/bibtex_parser.py +8 -4
  56. symai/extended/conversation.py +88 -69
  57. symai/extended/document.py +40 -27
  58. symai/extended/file_merger.py +45 -7
  59. symai/extended/graph.py +38 -24
  60. symai/extended/html_style_template.py +17 -11
  61. symai/extended/interfaces/blip_2.py +1 -1
  62. symai/extended/interfaces/clip.py +4 -2
  63. symai/extended/interfaces/console.py +5 -3
  64. symai/extended/interfaces/dall_e.py +3 -1
  65. symai/extended/interfaces/file.py +2 -0
  66. symai/extended/interfaces/flux.py +3 -1
  67. symai/extended/interfaces/gpt_image.py +15 -6
  68. symai/extended/interfaces/input.py +2 -1
  69. symai/extended/interfaces/llava.py +1 -1
  70. symai/extended/interfaces/{naive_webscraping.py → naive_scrape.py} +3 -2
  71. symai/extended/interfaces/naive_vectordb.py +2 -2
  72. symai/extended/interfaces/ocr.py +4 -2
  73. symai/extended/interfaces/openai_search.py +2 -0
  74. symai/extended/interfaces/parallel.py +30 -0
  75. symai/extended/interfaces/perplexity.py +2 -0
  76. symai/extended/interfaces/pinecone.py +6 -4
  77. symai/extended/interfaces/python.py +2 -0
  78. symai/extended/interfaces/serpapi.py +2 -0
  79. symai/extended/interfaces/terminal.py +0 -1
  80. symai/extended/interfaces/tts.py +2 -1
  81. symai/extended/interfaces/whisper.py +2 -1
  82. symai/extended/interfaces/wolframalpha.py +1 -0
  83. symai/extended/metrics/__init__.py +1 -1
  84. symai/extended/metrics/similarity.py +5 -2
  85. symai/extended/os_command.py +31 -22
  86. symai/extended/packages/symdev.py +39 -34
  87. symai/extended/packages/sympkg.py +30 -27
  88. symai/extended/packages/symrun.py +46 -35
  89. symai/extended/repo_cloner.py +10 -9
  90. symai/extended/seo_query_optimizer.py +15 -12
  91. symai/extended/solver.py +104 -76
  92. symai/extended/summarizer.py +8 -7
  93. symai/extended/taypan_interpreter.py +10 -9
  94. symai/extended/vectordb.py +28 -15
  95. symai/formatter/formatter.py +39 -31
  96. symai/formatter/regex.py +46 -44
  97. symai/functional.py +184 -86
  98. symai/imports.py +85 -51
  99. symai/interfaces.py +1 -1
  100. symai/memory.py +33 -24
  101. symai/menu/screen.py +28 -19
  102. symai/misc/console.py +27 -27
  103. symai/misc/loader.py +4 -3
  104. symai/models/base.py +147 -76
  105. symai/models/errors.py +1 -1
  106. symai/ops/__init__.py +1 -1
  107. symai/ops/measures.py +17 -14
  108. symai/ops/primitives.py +933 -635
  109. symai/post_processors.py +28 -24
  110. symai/pre_processors.py +58 -52
  111. symai/processor.py +15 -9
  112. symai/prompts.py +714 -649
  113. symai/server/huggingface_server.py +115 -32
  114. symai/server/llama_cpp_server.py +14 -6
  115. symai/server/qdrant_server.py +206 -0
  116. symai/shell.py +98 -39
  117. symai/shellsv.py +307 -223
  118. symai/strategy.py +135 -81
  119. symai/symbol.py +276 -225
  120. symai/utils.py +62 -46
  121. {symbolicai-1.0.0.dist-info → symbolicai-1.1.0.dist-info}/METADATA +19 -9
  122. symbolicai-1.1.0.dist-info/RECORD +168 -0
  123. symbolicai-1.0.0.dist-info/RECORD +0 -163
  124. {symbolicai-1.0.0.dist-info → symbolicai-1.1.0.dist-info}/WHEEL +0 -0
  125. {symbolicai-1.0.0.dist-info → symbolicai-1.1.0.dist-info}/entry_points.txt +0 -0
  126. {symbolicai-1.0.0.dist-info → symbolicai-1.1.0.dist-info}/licenses/LICENSE +0 -0
  127. {symbolicai-1.0.0.dist-info → symbolicai-1.1.0.dist-info}/top_level.txt +0 -0
symai/symbol.py CHANGED
@@ -3,7 +3,7 @@ import html
3
3
  import json
4
4
  from collections.abc import Callable, Iterator
5
5
  from json import JSONEncoder
6
- from typing import Any, ClassVar
6
+ from typing import Any, ClassVar, Generic, TypeVar
7
7
 
8
8
  import numpy as np
9
9
  from box import Box
@@ -11,10 +11,12 @@ from box import Box
11
11
  from . import core
12
12
  from .ops import SYMBOL_PRIMITIVES
13
13
 
14
+ T = TypeVar("T")
15
+
14
16
 
15
17
  class SymbolEncoder(JSONEncoder):
16
18
  def default(self, o):
17
- '''
19
+ """
18
20
  Encode a Symbol instance into its dictionary representation.
19
21
 
20
22
  Args:
@@ -22,7 +24,7 @@ class SymbolEncoder(JSONEncoder):
22
24
 
23
25
  Returns:
24
26
  dict: The dictionary representation of the Symbol instance.
25
- '''
27
+ """
26
28
  if isinstance(o, Symbol):
27
29
  return o.__getstate__()
28
30
  return JSONEncoder.default(self, o)
@@ -38,7 +40,7 @@ class Metadata:
38
40
  return self.__dict__.keys()
39
41
 
40
42
  def __getattr__(self, name):
41
- '''
43
+ """
42
44
  Get a metadata attribute by name.
43
45
 
44
46
  Args:
@@ -46,30 +48,30 @@ class Metadata:
46
48
 
47
49
  Returns:
48
50
  Any: The value of the metadata attribute.
49
- '''
51
+ """
50
52
  return self.__dict__.get(name)
51
53
 
52
54
  def __setattr__(self, name, value):
53
- '''
55
+ """
54
56
  Set a metadata attribute by name.
55
57
 
56
58
  Args:
57
59
  name (str): The name of the metadata attribute to set.
58
60
  value (Any): The value of the metadata attribute.
59
- '''
61
+ """
60
62
  self.__dict__[name] = value
61
63
 
62
64
  def __delattr__(self, name):
63
- '''
65
+ """
64
66
  Delete a metadata attribute by name.
65
67
 
66
68
  Args:
67
69
  name (str): The name of the metadata attribute to delete.
68
- '''
70
+ """
69
71
  del self.__dict__[name]
70
72
 
71
73
  def __getitem__(self, name):
72
- '''
74
+ """
73
75
  Get a metadata attribute by name.
74
76
 
75
77
  Args:
@@ -77,75 +79,82 @@ class Metadata:
77
79
 
78
80
  Returns:
79
81
  Any: The value of the metadata attribute.
80
- '''
82
+ """
81
83
  return self.__getattr__(name)
82
84
 
83
85
  def __setitem__(self, name, value):
84
- '''
86
+ """
85
87
  Set a metadata attribute by name.
86
88
 
87
89
  Args:
88
90
  name (str): The name of the metadata attribute to set.
89
91
  value (Any): The value of the metadata attribute.
90
- '''
92
+ """
91
93
  self.__setattr__(name, value)
92
94
 
93
95
  def __delitem__(self, name):
94
- '''
96
+ """
95
97
  Delete a metadata attribute by name.
96
98
 
97
99
  Args:
98
100
  name (str): The name of the metadata attribute to delete.
99
- '''
101
+ """
100
102
  self.__delattr__(name)
101
103
 
102
104
  def __str__(self) -> str:
103
- '''
105
+ """
104
106
  Get the string representation of the Symbol's value.
105
107
 
106
108
  Returns:
107
109
  str: The string representation of the Symbol's value.
108
- '''
109
- _val = ''
110
+ """
111
+ _val = ""
110
112
  if self.value is not None:
111
113
  _val += str(self.value)
112
- return _val + f"Properties({ {k: str(v) for k, v in self.__dict__.items() if not k.startswith('_')}!s})"
114
+ return (
115
+ _val
116
+ + f"Properties({ {k: str(v) for k, v in self.__dict__.items() if not k.startswith('_')}!s})"
117
+ )
113
118
 
114
119
  def __repr__(self) -> str:
115
- '''
120
+ """
116
121
  Get the representation of the Symbol object as a string.
117
122
 
118
123
  Returns:
119
124
  str: The representation of the Symbol object.
120
- '''
125
+ """
121
126
  # class with full path
122
- class_ = self.__class__.__module__ + '.' + self.__class__.__name__
123
- hex_ = hex(id(self))
124
- from_symbol = f' from {self.symbol_type.__module__}.{self.symbol_type.__name__}' if self.symbol_type else ''
125
- return f'<class {class_} at {hex_}{from_symbol}>'
127
+ class_ = self.__class__.__module__ + "." + self.__class__.__name__
128
+ hex_ = hex(id(self))
129
+ from_symbol = (
130
+ f" from {self.symbol_type.__module__}.{self.symbol_type.__name__}"
131
+ if self.symbol_type
132
+ else ""
133
+ )
134
+ return f"<class {class_} at {hex_}{from_symbol}>"
126
135
 
127
136
 
128
137
  class Linker(Metadata):
129
138
  def keys(self) -> list[str]:
130
- '''
139
+ """
131
140
  Get all keys of the linker.
132
141
 
133
142
  Returns:
134
143
  List[str]: All keys of the linker.
135
- '''
144
+ """
136
145
  return list(self.results.keys())
137
146
 
138
147
  def values(self) -> list[Any]:
139
- '''
148
+ """
140
149
  Get all values of the linker.
141
150
 
142
151
  Returns:
143
152
  List[Any]: All values of the linker.
144
- '''
153
+ """
145
154
  return list(self.results.values())
146
155
 
147
156
  def find(self, name: str, single: bool = True, strict: bool = False) -> Any:
148
- '''
157
+ """
149
158
  Find a result in the linker.
150
159
 
151
160
  Args:
@@ -155,9 +164,10 @@ class Linker(Metadata):
155
164
 
156
165
  Returns:
157
166
  Any: The result.
158
- '''
167
+ """
159
168
  # search all results and return the first one that matches the name
160
169
  res = []
170
+
161
171
  def match_(key, search_name):
162
172
  if strict:
163
173
  return str(search_name) == str(key)
@@ -167,7 +177,7 @@ class Linker(Metadata):
167
177
  if match_(k, name):
168
178
  res.append(self.results[k])
169
179
  if single:
170
- assert len(res) == 1, f'Found {len(res)} results for name {name}. Expected 1.'
180
+ assert len(res) == 1, f"Found {len(res)} results for name {name}. Expected 1."
171
181
  if len(res) == 0:
172
182
  return None
173
183
  if len(res) == 1:
@@ -178,13 +188,16 @@ class Linker(Metadata):
178
188
  class PropertyReservedError(AttributeError):
179
189
  def __init__(self, property_name):
180
190
  self.property_name = property_name
181
- super().__init__(f"Cannot set reserved property '{property_name}'. This property is defined in the 'Symbol' base class and cannot be assigned.")
191
+ super().__init__(
192
+ f"Cannot set reserved property '{property_name}'. This property is defined in the 'Symbol' base class and cannot be assigned."
193
+ )
182
194
 
183
195
 
184
196
  class SymbolMeta(type):
185
197
  """
186
198
  Metaclass to unify metaclasses of mixed-in primitives.
187
199
  """
200
+
188
201
  def __call__(cls, *args, **kwargs):
189
202
  obj = type.__call__(cls, *args, **kwargs)
190
203
  obj.__post_init__(*args, **kwargs)
@@ -202,24 +215,40 @@ class SymbolMeta(type):
202
215
  # create a new cls type that inherits from Symbol and the mixin primitive types
203
216
  cls = type.__new__(mcls, name, bases, attrs)
204
217
  # inherit the base class module for dynamic type creation
205
- if '__module__' in attrs:
206
- cls.__module__ = attrs['__module__']
218
+ if "__module__" in attrs:
219
+ cls.__module__ = attrs["__module__"]
207
220
  elif len(bases) > 0:
208
221
  cls.__module__ = bases[0].__module__
209
222
  return cls
210
223
 
211
224
 
212
- class Symbol(metaclass=SymbolMeta):
225
+ class Symbol(Generic[T], metaclass=SymbolMeta):
213
226
  _mixin: ClassVar[bool] = True
214
227
  _primitives: ClassVar[dict[str, type]] = SYMBOL_PRIMITIVES
215
228
  _metadata: ClassVar[Metadata] = Metadata()
216
229
  _metadata_primitives: ClassVar[dict[str, Callable]] = {}
217
230
  _metadata._primitives = _metadata_primitives
218
231
  _dynamic_context: ClassVar[dict[str, list[str]]] = {}
219
- _RESERVED_PROPERTIES: ClassVar[set[str]] = {'graph', 'linker', 'parent', 'children', 'metadata', 'value', 'root', 'nodes', 'edges', 'global_context', 'static_context', 'dynamic_context', 'shape'}
220
-
221
- def __init__(self, *value, static_context: str | None = '', dynamic_context: str | None = None, **kwargs) -> None:
222
- '''
232
+ _RESERVED_PROPERTIES: ClassVar[set[str]] = {
233
+ "graph",
234
+ "linker",
235
+ "parent",
236
+ "children",
237
+ "metadata",
238
+ "value",
239
+ "root",
240
+ "nodes",
241
+ "edges",
242
+ "global_context",
243
+ "static_context",
244
+ "dynamic_context",
245
+ "shape",
246
+ }
247
+
248
+ def __init__(
249
+ self, *value, static_context: str | None = "", dynamic_context: str | None = None, **kwargs
250
+ ) -> None:
251
+ """
223
252
  Initialize a Symbol instance with a specified value. Unwraps nested symbols.
224
253
 
225
254
  Args:
@@ -229,37 +258,35 @@ class Symbol(metaclass=SymbolMeta):
229
258
  Attributes:
230
259
  value (Any): The value of the symbol.
231
260
  metadata (Optional[Dict[str, Any]]): The metadata associated with the symbol.
232
- '''
261
+ """
233
262
  super().__init__()
234
- self._value = None
263
+ self._value = None
235
264
  # store kwargs for new symbol instance type passing
236
- self._kwargs = {
237
- 'static_context': static_context,
238
- **kwargs
239
- }
240
- self._metadata = Metadata() # use global metadata by default
265
+ self._kwargs = {"static_context": static_context, **kwargs}
266
+ self._metadata = Metadata() # use global metadata by default
241
267
  self._metadata.symbol_type = type(self)
242
- self._parent = None
243
- self._children = []
244
- self._static_context = static_context
268
+ self._parent = None
269
+ self._children = []
270
+ self._static_context = static_context
245
271
  self._dynamic_context = dynamic_context or Symbol._dynamic_context
246
272
  # if value is a single value, unwrap it
247
- _value = self._unwrap_symbols_args(*value)
248
- self._value = _value
273
+ _value = self._unwrap_symbols_args(*value)
274
+ self._value = _value
249
275
  # construct dependency graph for symbol
250
276
  self._construct_dependency_graph(*value)
251
277
 
252
- def __post_init__(self, *args, **kwargs): # this is called at the end of __init__
253
- '''
278
+ def __post_init__(self, *args, **kwargs): # this is called at the end of __init__
279
+ """
254
280
  Post-initialization method that is called at the end of the __init__ method.
255
- '''
281
+ """
282
+
256
283
  def _func(k, v):
257
284
  # check if property is of type Symbol and not private and a class variable (not a function)
258
- if isinstance(v, Symbol) and not k.startswith('_') and v is not self:
285
+ if isinstance(v, Symbol) and not k.startswith("_") and v is not self:
259
286
  v._parent = self
260
287
  self._children.append(v)
261
288
  # else if iterable, check if it contains symbols
262
- elif isinstance(v, (list, tuple)) and not k.startswith('_'):
289
+ elif isinstance(v, (list, tuple)) and not k.startswith("_"):
263
290
  for i in v:
264
291
  _func(k, i)
265
292
 
@@ -273,7 +300,10 @@ class Symbol(metaclass=SymbolMeta):
273
300
  if len(args) == 1:
274
301
  return self._unwrap_single_symbol_arg(args[0], nested=nested)
275
302
  if len(args) > 1:
276
- return [self._unwrap_symbols_args(a, nested=True) if isinstance(a, Symbol) else a for a in args]
303
+ return [
304
+ self._unwrap_symbols_args(a, nested=True) if isinstance(a, Symbol) else a
305
+ for a in args
306
+ ]
277
307
  return None
278
308
 
279
309
  def _unwrap_single_symbol_arg(self, value: Any, *, nested: bool) -> Any:
@@ -281,9 +311,9 @@ class Symbol(metaclass=SymbolMeta):
281
311
  return value
282
312
  if isinstance(value, Symbol):
283
313
  if not nested:
284
- self._metadata = value.metadata
314
+ self._metadata = value.metadata
285
315
  self._static_context = value.static_context
286
- self._kwargs = value._kwargs
316
+ self._kwargs = value._kwargs
287
317
  return value.value
288
318
  if isinstance(value, list):
289
319
  return [self._unwrap_symbols_args(v, nested=True) for v in value]
@@ -299,12 +329,12 @@ class Symbol(metaclass=SymbolMeta):
299
329
  return value
300
330
 
301
331
  def _construct_dependency_graph(self, *value):
302
- '''
332
+ """
303
333
  Construct a dependency graph for the symbol.
304
334
 
305
335
  Args:
306
336
  value (Any): The value of the symbol.
307
- '''
337
+ """
308
338
  # for each value
309
339
  for v in value:
310
340
  if isinstance(v, Symbol) and v is not self:
@@ -313,13 +343,16 @@ class Symbol(metaclass=SymbolMeta):
313
343
  # add new instance to children of previous instance
314
344
  self._children.append(v)
315
345
 
316
- def __new__(cls, *_args,
317
- mixin: bool | None = None,
318
- primitives: list[type] | None = None,
319
- callables: list[tuple[str, Callable]] | None = None,
320
- semantic: bool = False,
321
- **kwargs) -> "Symbol":
322
- '''
346
+ def __new__(
347
+ cls,
348
+ *_args,
349
+ mixin: bool | None = None,
350
+ primitives: list[type] | None = None,
351
+ callables: list[tuple[str, Callable]] | None = None,
352
+ semantic: bool = False,
353
+ **kwargs,
354
+ ) -> "Symbol":
355
+ """
323
356
  Create a new Symbol instance.
324
357
 
325
358
  Args:
@@ -332,10 +365,10 @@ class Symbol(metaclass=SymbolMeta):
332
365
 
333
366
  Returns:
334
367
  Symbol: The new Symbol instance.
335
- '''
336
- use_mixin = mixin if mixin is not None else cls._mixin
368
+ """
369
+ use_mixin = mixin if mixin is not None else cls._mixin
337
370
  standard_primitives = primitives is None
338
- primitives = primitives if not standard_primitives else cls._primitives
371
+ primitives = primitives if not standard_primitives else cls._primitives
339
372
  if not isinstance(primitives, list):
340
373
  primitives = [primitives]
341
374
  # Initialize instance as a combination of Symbol and the mixin primitive types
@@ -346,11 +379,11 @@ class Symbol(metaclass=SymbolMeta):
346
379
  obj = super().__new__(target_cls)
347
380
  # store to inherit when creating new instances
348
381
  obj._kwargs = {
349
- 'mixin': use_mixin,
350
- 'primitives': primitives,
351
- 'callables': callables,
352
- 'semantic': semantic,
353
- **kwargs
382
+ "mixin": use_mixin,
383
+ "primitives": primitives,
384
+ "callables": callables,
385
+ "semantic": semantic,
386
+ **kwargs,
354
387
  }
355
388
  # configure standard primitives
356
389
  if use_mixin and standard_primitives and semantic:
@@ -371,7 +404,7 @@ class Symbol(metaclass=SymbolMeta):
371
404
  return obj
372
405
 
373
406
  def __setattr__(self, name: str, value: Any) -> None:
374
- '''
407
+ """
375
408
  Set the attribute of the Symbol's value with the specified name.
376
409
 
377
410
  Args:
@@ -380,13 +413,13 @@ class Symbol(metaclass=SymbolMeta):
380
413
 
381
414
  Raises:
382
415
  PropertyReservedError: If the property is reserved and cannot be set.
383
- '''
416
+ """
384
417
  if name in self._RESERVED_PROPERTIES:
385
418
  raise PropertyReservedError(name)
386
419
  super().__setattr__(name, value)
387
420
 
388
421
  def __getattr__(self, name: str) -> Any:
389
- '''
422
+ """
390
423
  Get the attribute of the Symbol's value with the specified name or the attribute of the Symbol value with the specified name.
391
424
 
392
425
  Args:
@@ -394,7 +427,7 @@ class Symbol(metaclass=SymbolMeta):
394
427
 
395
428
  Returns:
396
429
  Any: The attribute of the Symbol's value with the specified name.
397
- '''
430
+ """
398
431
  try:
399
432
  # try to get attribute from current instance
400
433
  if name in self.__dict__:
@@ -406,21 +439,21 @@ class Symbol(metaclass=SymbolMeta):
406
439
  raise AttributeError(msg)
407
440
  except AttributeError as ex:
408
441
  # if has attribute and is public function
409
- if hasattr(self.value, name) and not name.startswith('_'):
442
+ if hasattr(self.value, name) and not name.startswith("_"):
410
443
  return getattr(self.value, name)
411
444
  raise ex
412
445
 
413
446
  def __array__(self, dtype=None):
414
- '''
447
+ """
415
448
  Get the numpy array representation of the Symbol's value.
416
449
 
417
450
  Returns:
418
451
  np.ndarray: The numpy array representation of the Symbol's value.
419
- '''
452
+ """
420
453
  return self.embedding.astype(dtype, copy=False)
421
454
 
422
455
  def __buffer__(self, flags=0):
423
- '''
456
+ """
424
457
  Get the buffer of the Symbol's value.
425
458
 
426
459
  Args:
@@ -428,12 +461,12 @@ class Symbol(metaclass=SymbolMeta):
428
461
 
429
462
  Returns:
430
463
  memoryview: The buffer of the Symbol's value.
431
- '''
464
+ """
432
465
  return memoryview(self.embedding)
433
466
 
434
467
  @staticmethod
435
468
  def symbols(*values) -> list["Symbol"]:
436
- '''
469
+ """
437
470
  Create a list of Symbol instances from a list of values.
438
471
 
439
472
  Args:
@@ -441,11 +474,11 @@ class Symbol(metaclass=SymbolMeta):
441
474
 
442
475
  Returns:
443
476
  List[Symbol]: The list of Symbol instances.
444
- '''
477
+ """
445
478
  return [Symbol(value) for value in values]
446
479
 
447
480
  def __reduce__(self):
448
- '''
481
+ """
449
482
  This method is called by pickle to serialize the object.
450
483
  It returns a tuple that contains:
451
484
  - A callable object that when called produces a new object (e.g., the class of the object)
@@ -454,7 +487,7 @@ class Symbol(metaclass=SymbolMeta):
454
487
 
455
488
  Returns:
456
489
  tuple: A tuple containing the callable object, the arguments for the callable object, and the state of the object.
457
- '''
490
+ """
458
491
  # Get the state of the object
459
492
  state = self.__getstate__()
460
493
 
@@ -477,7 +510,7 @@ class Symbol(metaclass=SymbolMeta):
477
510
  # This will be called by pickle with the info from __reduce__ to recreate the dynamic class
478
511
  @staticmethod
479
512
  def _reconstruct_class(base_cls, use_mixin, primitives_info):
480
- '''
513
+ """
481
514
  Reconstruct the class from the serialized state.
482
515
 
483
516
  Args:
@@ -487,53 +520,53 @@ class Symbol(metaclass=SymbolMeta):
487
520
 
488
521
  Returns:
489
522
  Type: The reconstructed class.
490
- '''
523
+ """
491
524
  if use_mixin:
492
525
  # Convert primitive info tuples back to types
493
- primitives = [primitive for primitive, name in primitives_info]
526
+ primitives = [primitive for primitive, name in primitives_info]
494
527
  # Create new cls with UnifiedMeta metaclass
495
528
  cls = SymbolMeta(base_cls.__name__, (base_cls, *tuple(primitives)), {})
496
529
  return cls()
497
530
  return base_cls()
498
531
 
499
532
  def __getstate__(self) -> dict[str, Any]:
500
- '''
533
+ """
501
534
  Get the state of the symbol for serialization.
502
535
 
503
536
  Returns:
504
537
  dict: The state of the symbol.
505
- '''
538
+ """
506
539
  state = vars(self).copy()
507
- state.pop('_metadata', None)
508
- state.pop('_parent', None)
509
- state.pop('_children', None)
540
+ state.pop("_metadata", None)
541
+ state.pop("_parent", None)
542
+ state.pop("_children", None)
510
543
  return state
511
544
 
512
545
  def __setstate__(self, state) -> None:
513
- '''
546
+ """
514
547
  Set the state of the symbol for deserialization.
515
548
 
516
549
  Args:
517
550
  state (dict): The state to set the symbol to.
518
- '''
551
+ """
519
552
  vars(self).update(state)
520
- self._metadata = Metadata()
553
+ self._metadata = Metadata()
521
554
  self._metadata.symbol_type = type(self)
522
- self._kwargs = self._kwargs
523
- self._parent = None
524
- self._children = []
555
+ self._kwargs = self._kwargs
556
+ self._parent = None
557
+ self._children = []
525
558
 
526
559
  def json(self) -> dict[str, Any]:
527
- '''
560
+ """
528
561
  Get the json-serializable dictionary representation of the Symbol instance.
529
562
 
530
563
  Returns:
531
564
  dict: The json-serializable dictionary representation of the Symbol instance.
532
- '''
565
+ """
533
566
  return self.__getstate__()
534
567
 
535
568
  def serialize(self):
536
- '''
569
+ """
537
570
  Encode an Symbol instance into its dictionary representation.
538
571
 
539
572
  Args:
@@ -541,11 +574,11 @@ class Symbol(metaclass=SymbolMeta):
541
574
 
542
575
  Returns:
543
576
  dict: The dictionary representation of the Symbol instance.
544
- '''
577
+ """
545
578
  return json.dumps(self, cls=SymbolEncoder)
546
579
 
547
580
  def _to_symbol(self, value: Any, **kwargs) -> "Symbol":
548
- '''
581
+ """
549
582
  Convert a value to a Symbol instance.
550
583
 
551
584
  Args:
@@ -553,8 +586,8 @@ class Symbol(metaclass=SymbolMeta):
553
586
 
554
587
  Returns:
555
588
  Symbol: The Symbol instance.
556
- '''
557
- type_ = Symbol
589
+ """
590
+ type_ = Symbol
558
591
  if isinstance(value, type_):
559
592
  return value
560
593
  # inherit kwargs for new symbol instance
@@ -562,7 +595,7 @@ class Symbol(metaclass=SymbolMeta):
562
595
  return type_(value, **kwargs)
563
596
 
564
597
  def _to_type(self, value: Any, **kwargs) -> "Symbol":
565
- '''
598
+ """
566
599
  Convert a value to its own type instance.
567
600
 
568
601
  Args:
@@ -570,8 +603,8 @@ class Symbol(metaclass=SymbolMeta):
570
603
 
571
604
  Returns:
572
605
  Type: The type instance.
573
- '''
574
- type_ = type(self)
606
+ """
607
+ type_ = type(self)
575
608
  if isinstance(value, type_):
576
609
  return value
577
610
  # inherit kwargs for new symbol instance
@@ -580,101 +613,101 @@ class Symbol(metaclass=SymbolMeta):
580
613
 
581
614
  @property
582
615
  def _symbol_type(self) -> "Symbol":
583
- '''
616
+ """
584
617
  Get the type of the Symbol instance.
585
618
 
586
619
  Returns:
587
620
  Symbol: The type of the Symbol instance.
588
- '''
621
+ """
589
622
  return Symbol
590
623
 
591
624
  def __hash__(self) -> int:
592
- '''
625
+ """
593
626
  Get the hash value of the symbol.
594
627
 
595
628
  Returns:
596
629
  int: The hash value of the symbol.
597
- '''
630
+ """
598
631
  return str(self.value).__hash__()
599
632
 
600
633
  @property
601
634
  def metadata(self) -> dict[str, Any]:
602
- '''
635
+ """
603
636
  Get the metadata associated with the symbol.
604
637
 
605
638
  Returns:
606
639
  Dict[str, Any]: The metadata associated with the symbol.
607
- '''
640
+ """
608
641
  return self._metadata
609
642
 
610
643
  @property
611
644
  def value(self) -> Any:
612
- '''
645
+ """
613
646
  Get the value of the symbol.
614
647
 
615
648
  Returns:
616
649
  Any: The value of the symbol.
617
- '''
650
+ """
618
651
  return self._value
619
652
 
620
653
  @property
621
654
  def global_context(self) -> str:
622
- '''
655
+ """
623
656
  Get the global context of the symbol, which consists of the static and dynamic context.
624
657
 
625
658
  Returns:
626
659
  str: The global context of the symbol.
627
- '''
660
+ """
628
661
  return (self.static_context, self.dynamic_context)
629
662
 
630
663
  @property
631
664
  def static_context(self) -> str:
632
- '''
665
+ """
633
666
  Get the static context of the symbol which is defined by the user when creating a symbol subclass.
634
667
 
635
668
  Returns:
636
669
  str: The static context of the symbol.
637
- '''
638
- return f'{self._static_context}' if self._static_context else ''
670
+ """
671
+ return f"{self._static_context}" if self._static_context else ""
639
672
 
640
673
  @static_context.setter
641
674
  def static_context(self, value: str):
642
- '''
675
+ """
643
676
  Set the static context of the symbol which is defined by the user when creating a symbol subclass.
644
- '''
677
+ """
645
678
  self._static_context = value
646
679
 
647
680
  @property
648
681
  def dynamic_context(self) -> str:
649
- '''
682
+ """
650
683
  Get the dynamic context which is defined by the user at runtime.
651
684
  It helps to alter the behavior of the symbol at runtime.
652
685
 
653
686
  Returns:
654
687
  str: The dynamic context associated with this symbol type.
655
- '''
688
+ """
656
689
  # if dynamic context is manually set to a string, return it
657
690
  if isinstance(self._dynamic_context, str):
658
691
  return self._dynamic_context
659
692
  type_ = str(type(self))
660
693
  if type_ not in Symbol._dynamic_context:
661
694
  Symbol._dynamic_context[type_] = []
662
- return ''
695
+ return ""
663
696
  dyn_ctxt = Symbol._dynamic_context[type_]
664
697
  if len(dyn_ctxt) == 0:
665
- return ''
698
+ return ""
666
699
  sym_val = [str(v.value) if isinstance(v, Symbol) else str(v) for v in dyn_ctxt]
667
- val = '\n'.join(sym_val)
668
- return f'\n{val}' if val else ''
700
+ val = "\n".join(sym_val)
701
+ return f"\n{val}" if val else ""
669
702
 
670
703
  @property
671
704
  def root(self) -> "Symbol":
672
- '''
705
+ """
673
706
  Get the root of the symbol.
674
707
 
675
708
  Returns:
676
709
  Symbol: The root of the symbol.
677
- '''
710
+ """
678
711
  root = self
679
712
  while root.parent is not None:
680
713
  root = root.parent
@@ -682,12 +715,13 @@ class Symbol(metaclass=SymbolMeta):
682
715
 
683
716
  @property
684
717
  def nodes(self) -> list["Symbol"]:
685
- '''
718
+ """
686
719
  Get all nodes descending recursively from the symbol.
687
720
 
688
721
  Returns:
689
722
  List[Symbol]: All nodes of the symbol.
690
- '''
723
+ """
724
+
691
725
  def _func(node, nodes):
692
726
  nodes.append(node)
693
727
  for child in node.children:
@@ -699,12 +733,13 @@ class Symbol(metaclass=SymbolMeta):
699
733
 
700
734
  @property
701
735
  def edges(self) -> list[tuple]:
702
- '''
736
+ """
703
737
  Get all edges descending recursively from the symbol.
704
738
 
705
739
  Returns:
706
740
  List[tuple]: All edges of the symbol.
707
- '''
741
+ """
742
+
708
743
  def _func(node, edges):
709
744
  for child in node.children:
710
745
  edges.append((node, child))
@@ -716,46 +751,46 @@ class Symbol(metaclass=SymbolMeta):
716
751
 
717
752
  @property
718
753
  def graph(self) -> (list["Symbol"], list[tuple]):
719
- '''
754
+ """
720
755
  Get the graph representation of the symbol.
721
756
 
722
757
  Returns:
723
758
  List[Symbol], List[tuple]: The nodes and edges of the symbol.
724
- '''
759
+ """
725
760
  return self.nodes, self.edges
726
761
 
727
762
  @property
728
763
  def linker(self) -> list["Symbol"]:
729
- '''
764
+ """
730
765
  Returns the link object metadata by descending recursively from the root of the symbol to the root_link object.
731
766
 
732
767
  Returns:
733
768
  List[Symbol]: All results of the symbol.
734
- '''
769
+ """
735
770
  return self.root.metadata.root_link
736
771
 
737
772
  @property
738
773
  def parent(self) -> "Symbol":
739
- '''
774
+ """
740
775
  Get the parent of the symbol.
741
776
 
742
777
  Returns:
743
778
  Symbol: The parent of the symbol.
744
- '''
779
+ """
745
780
  return self._parent
746
781
 
747
782
  @property
748
783
  def children(self) -> list["Symbol"]:
749
- '''
784
+ """
750
785
  Get the children of the symbol.
751
786
 
752
787
  Returns:
753
788
  List[Symbol]: The children of the symbol.
754
- '''
789
+ """
755
790
  return self._children
756
791
 
757
792
  def _root_link(self, sym: Any, **_kwargs) -> Any:
758
- '''
793
+ """
759
794
  Call the forward method and assign the result to the graph value attribute.
760
795
 
761
796
  Args:
@@ -764,7 +799,7 @@ class Symbol(metaclass=SymbolMeta):
764
799
 
765
800
  Returns:
766
801
  Any: The result of the forward method.
767
- '''
802
+ """
768
803
  # transport results to the root node for global access
769
804
  if self is not self.root and not self.metadata.detach:
770
805
  ref = self.root.metadata
@@ -774,7 +809,7 @@ class Symbol(metaclass=SymbolMeta):
774
809
  ref.root_link.results = {}
775
810
  prev = None
776
811
  if len(ref.root_link.results) > 0:
777
- prev = list(ref.root_link.results.values())[-1] # get previous result
812
+ prev = list(ref.root_link.results.values())[-1] # get previous result
778
813
  # create new symbol to avoid circular references
779
814
  res_ = Symbol(sym)
780
815
  if prev is not None and prev is not res_.root:
@@ -783,14 +818,14 @@ class Symbol(metaclass=SymbolMeta):
783
818
  ref.root_link.results[self.__repr__()] = res_
784
819
 
785
820
  def adapt(self, context: str, types: list[type] | None = None) -> None:
786
- '''
821
+ """
787
822
  Update the dynamic context with a given runtime context.
788
823
 
789
824
  Args:
790
825
  context (str): The context to be added to the dynamic context.
791
826
  type (Type): The type used to update the dynamic context
792
827
 
793
- '''
828
+ """
794
829
  if types is None:
795
830
  types = []
796
831
  if not isinstance(types, list):
@@ -806,9 +841,9 @@ class Symbol(metaclass=SymbolMeta):
806
841
  Symbol._dynamic_context[type_key].append(str(context))
807
842
 
808
843
  def clear(self, types: list[type] | None = None) -> None:
809
- '''
844
+ """
810
845
  Clear the dynamic context associated with this symbol type.
811
- '''
846
+ """
812
847
  if types is None:
813
848
  types = []
814
849
  if not isinstance(types, list):
@@ -825,33 +860,33 @@ class Symbol(metaclass=SymbolMeta):
825
860
  Symbol._dynamic_context[type_key].clear()
826
861
 
827
862
  def __len__(self) -> int:
828
- '''
863
+ """
829
864
  Get the length of the value of the Symbol.
830
865
 
831
866
  Returns:
832
867
  int: The length of the value of the Symbol.
833
- '''
868
+ """
834
869
  return len(self.value)
835
870
 
836
871
  @property
837
872
  def shape(self) -> tuple:
838
- '''
873
+ """
839
874
  Get the shape of the value of the Symbol.
840
875
 
841
876
  Returns:
842
877
  tuple: The shape of the value of the Symbol.
843
- '''
878
+ """
844
879
  return self.value.shape
845
880
 
846
881
  def __str__(self) -> str:
847
- '''
882
+ """
848
883
  Get the string representation of the Symbol's value.
849
884
 
850
885
  Returns:
851
886
  str: The string representation of the Symbol's value.
852
- '''
887
+ """
853
888
  if self.value is None:
854
- return ''
889
+ return ""
855
890
  if isinstance(self.value, (list, np.ndarray, tuple)):
856
891
  return str([str(v) for v in self.value])
857
892
  if isinstance(self.value, dict):
@@ -861,54 +896,56 @@ class Symbol(metaclass=SymbolMeta):
861
896
  return str(self.value)
862
897
 
863
898
  def __repr__(self, simplified: bool = False) -> str:
864
- '''
899
+ """
865
900
  Get the representation of the Symbol object as a string.
866
901
 
867
902
  Returns:
868
903
  str: The representation of the Symbol object.
869
- '''
904
+ """
870
905
  # class with full path
871
- class_ = self.__class__.__module__ + '.' + self.__class__.__name__
872
- hex_ = hex(id(self))
873
- val = str(self.value)
906
+ class_ = self.__class__.__module__ + "." + self.__class__.__name__
907
+ hex_ = hex(id(self))
908
+ val = str(self.value)
874
909
  # only show first n characters of value and then add '...' and the last x characters
875
910
  if len(val) > 50:
876
- val = val[:25] + ' ... ' + val[-20:]
877
- return f'<class {class_} at {hex_}>(value={val})' if not simplified else f'{class_} at {hex_}'
911
+ val = val[:25] + " ... " + val[-20:]
912
+ return (
913
+ f"<class {class_} at {hex_}>(value={val})" if not simplified else f"{class_} at {hex_}"
914
+ )
878
915
 
879
916
  def _repr_html_(self) -> str:
880
- '''
917
+ """
881
918
  Get the HTML representation of the Symbol's value.
882
919
 
883
920
  Returns:
884
921
  str: The HTML representation of the Symbol's value.
885
- '''
922
+ """
886
923
  return html.escape(self.__repr__())
887
924
 
888
925
  def __iter__(self) -> Iterator:
889
- '''
926
+ """
890
927
  Get an iterator for the Symbol's value.
891
928
  If the Symbol's value is a list, tuple, or numpy.ndarray, iterate over the elements. Otherwise, create a new list with a single item and iterate over the list.
892
929
 
893
930
  Returns:
894
931
  Iterator: An iterator for the Symbol's value.
895
- '''
932
+ """
896
933
  if isinstance(self.value, (list, tuple, np.ndarray)):
897
934
  return iter(self.value)
898
935
 
899
- return self.list('item').value.__iter__()
936
+ return self.list("item").value.__iter__()
900
937
 
901
938
  def __reversed__(self) -> Iterator:
902
- '''
939
+ """
903
940
  Get a reversed iterator for the Symbol's value.
904
941
 
905
942
  Returns:
906
943
  Iterator: A reversed iterator for the Symbol's value.
907
- '''
944
+ """
908
945
  return reversed(list(self.__iter__()))
909
946
 
910
947
  def __next__(self) -> Any:
911
- '''
948
+ """
912
949
  Get the next item in the iterable value of the Symbol.
913
950
  If it is not a list, tuple, or numpy array, the method falls back to using the @core.next() decorator, which retrieves and returns the next item using core functions.
914
951
 
@@ -917,11 +954,11 @@ class Symbol(metaclass=SymbolMeta):
917
954
 
918
955
  Raises:
919
956
  StopIteration: If the iterable value reaches its end.
920
- '''
957
+ """
921
958
  return next(self.__iter__())
922
959
 
923
960
  def primitive(self, name: str, callable: callable) -> None:
924
- '''
961
+ """
925
962
  Set a primitive function to the Symbol instance.
926
963
 
927
964
  Args:
@@ -931,21 +968,25 @@ class Symbol(metaclass=SymbolMeta):
931
968
 
932
969
  Args:
933
970
  callable (callable): The primitive function to set.
934
- '''
971
+ """
972
+
935
973
  def _func(*args, **kwargs):
936
974
  return callable(self, *args, **kwargs)
975
+
937
976
  setattr(self, name, _func)
938
977
 
939
978
  @staticmethod
940
979
  def _global_primitive(name: str, callable: callable) -> None:
941
- '''
980
+ """
942
981
  Set a primitive function to the Symbol class.
943
982
 
944
983
  Args:
945
984
  callable (callable): The primitive function to set.
946
- '''
985
+ """
986
+
947
987
  def _func(obj):
948
988
  return lambda *args, **kwargs: callable(obj, *args, **kwargs)
989
+
949
990
  Symbol._metadata._primitives[name] = _func
950
991
 
951
992
 
@@ -954,7 +995,7 @@ class Symbol(metaclass=SymbolMeta):
954
995
  # Need to contact Python developers to fix this bug.
955
996
  class Call:
956
997
  def __new__(cls, name, callable: Callable) -> Any:
957
- '''
998
+ """
958
999
  Prepare a callable for use in a Symbol instance.
959
1000
 
960
1001
  Args:
@@ -962,15 +1003,17 @@ class Call:
962
1003
 
963
1004
  Returns:
964
1005
  Callable: The prepared callable.
965
- '''
1006
+ """
1007
+
966
1008
  def _func(obj):
967
1009
  return lambda *args, **kwargs: callable(obj, *args, **kwargs)
1010
+
968
1011
  return (name, _func)
969
1012
 
970
1013
 
971
1014
  class GlobalSymbolPrimitive:
972
1015
  def __new__(cls, name, callable: Callable) -> Any:
973
- '''
1016
+ """
974
1017
  Prepare a callable for use in a Symbol instance.
975
1018
 
976
1019
  Args:
@@ -978,7 +1021,7 @@ class GlobalSymbolPrimitive:
978
1021
 
979
1022
  Returns:
980
1023
  Callable: The prepared callable.
981
- '''
1024
+ """
982
1025
  Symbol._global_primitive(name, callable)
983
1026
 
984
1027
 
@@ -990,9 +1033,8 @@ class ExpressionEncoder(JSONEncoder):
990
1033
 
991
1034
 
992
1035
  class Expression(Symbol):
993
-
994
- def __init__(self, value = None, *args, **kwargs):
995
- '''
1036
+ def __init__(self, value=None, *args, **kwargs):
1037
+ """
996
1038
  Create an Expression object that will be evaluated lazily using the forward method.
997
1039
 
998
1040
  Args:
@@ -1000,12 +1042,12 @@ class Expression(Symbol):
1000
1042
  is computed using the forward method when called. Defaults to None.
1001
1043
  *args: Variable length argument list.
1002
1044
  **kwargs: Arbitrary keyword arguments.
1003
- '''
1045
+ """
1004
1046
  super().__init__(value, *args, **kwargs)
1005
1047
  self._sym_return_type = type(self)
1006
1048
 
1007
1049
  def __call__(self, *args, **kwargs) -> Any:
1008
- '''
1050
+ """
1009
1051
  Evaluate the expression using the forward method and assign the result to the value attribute.
1010
1052
 
1011
1053
  Args:
@@ -1014,7 +1056,7 @@ class Expression(Symbol):
1014
1056
 
1015
1057
  Returns:
1016
1058
  Any: The result of the forward method.
1017
- '''
1059
+ """
1018
1060
  # evaluate the expression
1019
1061
  res = self.forward(*args, **kwargs)
1020
1062
  # store the result in the root node and link it to the previous result
@@ -1023,7 +1065,7 @@ class Expression(Symbol):
1023
1065
 
1024
1066
  def __getstate__(self):
1025
1067
  state = super().__getstate__().copy()
1026
- state.pop('_sym_return_type', None)
1068
+ state.pop("_sym_return_type", None)
1027
1069
  return state
1028
1070
 
1029
1071
  def __setstate__(self, state):
@@ -1031,16 +1073,16 @@ class Expression(Symbol):
1031
1073
  self._sym_return_type = type(self)
1032
1074
 
1033
1075
  def __json__(self):
1034
- '''
1076
+ """
1035
1077
  Get the json-serializable dictionary representation of the Expression instance.
1036
1078
 
1037
1079
  Returns:
1038
1080
  dict: The json-serializable dictionary representation of the Expression instance.
1039
- '''
1081
+ """
1040
1082
  return self.__getstate__()
1041
1083
 
1042
1084
  def serialize(self):
1043
- '''
1085
+ """
1044
1086
  Encode an Expression instance into its dictionary representation.
1045
1087
 
1046
1088
  Args:
@@ -1048,31 +1090,33 @@ class Expression(Symbol):
1048
1090
 
1049
1091
  Returns:
1050
1092
  dict: The dictionary representation of the Expression instance.
1051
- '''
1093
+ """
1052
1094
  return json.dumps(self, cls=ExpressionEncoder)
1053
1095
 
1054
1096
  @property
1055
1097
  def sym_return_type(self) -> type:
1056
- '''
1098
+ """
1057
1099
  Returns the casting type of this expression.
1058
1100
 
1059
1101
  Returns:
1060
1102
  Type: The casting type of this expression. Defaults to the current Expression-type.
1061
- '''
1103
+ """
1062
1104
  return self._sym_return_type
1063
1105
 
1064
1106
  @sym_return_type.setter
1065
1107
  def sym_return_type(self, type: type) -> None:
1066
- '''
1108
+ """
1067
1109
  Sets the casting type of this expression.
1068
1110
 
1069
1111
  Args:
1070
1112
  type (Type): The casting type of this expression.
1071
- '''
1113
+ """
1072
1114
  self._sym_return_type = type
1073
1115
 
1074
- def forward(self, *args, **kwargs) -> Symbol: #TODO make reserved kwargs with underscore: __<cmd>__
1075
- '''
1116
+ def forward(
1117
+ self, *args, **kwargs
1118
+ ) -> Symbol: # TODO make reserved kwargs with underscore: __<cmd>__
1119
+ """
1076
1120
  Needs to be implemented by subclasses to specify the behavior of the expression during evaluation.
1077
1121
 
1078
1122
  Args:
@@ -1081,12 +1125,12 @@ class Expression(Symbol):
1081
1125
 
1082
1126
  Returns:
1083
1127
  Symbol: The evaluated result of the implemented forward method.
1084
- '''
1128
+ """
1085
1129
  raise NotImplementedError
1086
1130
 
1087
1131
  @staticmethod
1088
- def command(engines: list[str] | None = None, **kwargs) -> 'Symbol':
1089
- '''
1132
+ def command(engines: list[str] | None = None, **kwargs) -> "Symbol":
1133
+ """
1090
1134
  Execute command(s) on engines.
1091
1135
 
1092
1136
  Args:
@@ -1095,18 +1139,19 @@ class Expression(Symbol):
1095
1139
 
1096
1140
  Returns:
1097
1141
  Symbol: An Expression object representing the command execution result.
1098
- '''
1142
+ """
1099
1143
  if engines is None:
1100
- engines = ['all']
1144
+ engines = ["all"]
1101
1145
 
1102
1146
  @core.command(engines=engines, **kwargs)
1103
1147
  def _func(_):
1104
1148
  pass
1149
+
1105
1150
  return Expression(_func(Expression()))
1106
1151
 
1107
1152
  @staticmethod
1108
- def register(engines: dict[str, Any], **kwargs) -> 'Symbol':
1109
- '''
1153
+ def register(engines: dict[str, Any], **kwargs) -> "Symbol":
1154
+ """
1110
1155
  Configure multiple engines.
1111
1156
 
1112
1157
  Args:
@@ -1115,24 +1160,26 @@ class Expression(Symbol):
1115
1160
 
1116
1161
  Returns:
1117
1162
  Symbol: An Expression object representing the register result.
1118
- '''
1163
+ """
1164
+
1119
1165
  @core.register(engines=engines, **kwargs)
1120
1166
  def _func(_):
1121
1167
  pass
1168
+
1122
1169
  return Expression(_func(Expression()))
1123
1170
 
1124
1171
  def copy(self) -> Any:
1125
- '''
1172
+ """
1126
1173
  Returns a deep copy of the own object.
1127
1174
 
1128
1175
  Returns:
1129
1176
  Any: A deep copy of the own object.
1130
- '''
1177
+ """
1131
1178
  return copy.deepcopy(self)
1132
1179
 
1133
1180
  @staticmethod
1134
- def prompt(message: str, **kwargs) -> 'Symbol':
1135
- '''
1181
+ def prompt(message: str, **kwargs) -> "Symbol":
1182
+ """
1136
1183
  General raw input prompt method.
1137
1184
 
1138
1185
  Args:
@@ -1141,16 +1188,18 @@ class Expression(Symbol):
1141
1188
 
1142
1189
  Returns:
1143
1190
  Symbol: An Expression object representing the prompt result.
1144
- '''
1191
+ """
1192
+
1145
1193
  @core.prompt(message=message, **kwargs)
1146
1194
  def _func(_):
1147
1195
  pass
1196
+
1148
1197
  return Expression(_func(None))
1149
1198
 
1150
1199
 
1151
1200
  class Result(Expression):
1152
- def __init__(self, value = None, *_args, **kwargs):
1153
- '''
1201
+ def __init__(self, value=None, *_args, **kwargs):
1202
+ """
1154
1203
  Create a Result object that stores the results operations, including the raw result, value and metadata, if any.
1155
1204
 
1156
1205
  Args:
@@ -1158,8 +1207,10 @@ class Result(Expression):
1158
1207
  is computed using the forward method when called. Defaults to None.
1159
1208
  *args: Variable length argument list.
1160
1209
  **kwargs: Arbitrary keyword arguments.
1161
- '''
1162
- super().__init__(value, **kwargs) # value is the same as raw when initialized, however, it can be changed later
1210
+ """
1211
+ super().__init__(
1212
+ value, **kwargs
1213
+ ) # value is the same as raw when initialized, however, it can be changed later
1163
1214
  self._sym_return_type = type(self)
1164
1215
  try:
1165
1216
  # try to make the values easily accessible
@@ -1170,20 +1221,20 @@ class Result(Expression):
1170
1221
 
1171
1222
  @property
1172
1223
  def value(self) -> Any:
1173
- '''
1224
+ """
1174
1225
  Get the value of the symbol.
1175
1226
 
1176
1227
  Returns:
1177
1228
  Any: The value of the symbol.
1178
- '''
1229
+ """
1179
1230
  return self._value
1180
1231
 
1181
1232
  @value.setter
1182
1233
  def value(self, value: Any) -> None:
1183
- '''
1234
+ """
1184
1235
  Set the value of the Result object.
1185
1236
 
1186
1237
  Args:
1187
1238
  value (Any): The value to set the Result object to.
1188
- '''
1239
+ """
1189
1240
  self._value = value