symbolicai 1.0.0__py3-none-any.whl → 1.1.1__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.
- symai/__init__.py +198 -134
- symai/backend/base.py +51 -51
- symai/backend/engines/drawing/engine_bfl.py +33 -33
- symai/backend/engines/drawing/engine_gpt_image.py +4 -10
- symai/backend/engines/embedding/engine_llama_cpp.py +50 -35
- symai/backend/engines/embedding/engine_openai.py +22 -16
- symai/backend/engines/execute/engine_python.py +16 -16
- symai/backend/engines/files/engine_io.py +51 -49
- symai/backend/engines/imagecaptioning/engine_blip2.py +27 -23
- symai/backend/engines/imagecaptioning/engine_llavacpp_client.py +53 -46
- symai/backend/engines/index/engine_pinecone.py +116 -88
- symai/backend/engines/index/engine_qdrant.py +1011 -0
- symai/backend/engines/index/engine_vectordb.py +78 -52
- symai/backend/engines/lean/engine_lean4.py +65 -25
- symai/backend/engines/neurosymbolic/__init__.py +35 -28
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +137 -135
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +145 -152
- symai/backend/engines/neurosymbolic/engine_cerebras.py +328 -0
- symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py +75 -49
- symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +199 -155
- symai/backend/engines/neurosymbolic/engine_groq.py +106 -72
- symai/backend/engines/neurosymbolic/engine_huggingface.py +100 -67
- symai/backend/engines/neurosymbolic/engine_llama_cpp.py +121 -93
- symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py +213 -132
- symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py +180 -137
- symai/backend/engines/ocr/engine_apilayer.py +18 -20
- symai/backend/engines/output/engine_stdout.py +9 -9
- symai/backend/engines/{webscraping → scrape}/engine_requests.py +25 -11
- symai/backend/engines/search/engine_openai.py +95 -83
- symai/backend/engines/search/engine_parallel.py +665 -0
- symai/backend/engines/search/engine_perplexity.py +40 -41
- symai/backend/engines/search/engine_serpapi.py +33 -28
- symai/backend/engines/speech_to_text/engine_local_whisper.py +37 -27
- symai/backend/engines/symbolic/engine_wolframalpha.py +14 -8
- symai/backend/engines/text_to_speech/engine_openai.py +15 -19
- symai/backend/engines/text_vision/engine_clip.py +34 -28
- symai/backend/engines/userinput/engine_console.py +3 -4
- symai/backend/mixin/__init__.py +4 -0
- symai/backend/mixin/anthropic.py +48 -40
- symai/backend/mixin/cerebras.py +9 -0
- symai/backend/mixin/deepseek.py +4 -5
- symai/backend/mixin/google.py +5 -4
- symai/backend/mixin/groq.py +2 -4
- symai/backend/mixin/openai.py +132 -110
- symai/backend/settings.py +14 -14
- symai/chat.py +164 -94
- symai/collect/dynamic.py +13 -11
- symai/collect/pipeline.py +39 -31
- symai/collect/stats.py +109 -69
- symai/components.py +578 -238
- symai/constraints.py +14 -5
- symai/core.py +1495 -1210
- symai/core_ext.py +55 -50
- symai/endpoints/api.py +113 -58
- symai/extended/api_builder.py +22 -17
- symai/extended/arxiv_pdf_parser.py +13 -5
- symai/extended/bibtex_parser.py +8 -4
- symai/extended/conversation.py +88 -69
- symai/extended/document.py +40 -27
- symai/extended/file_merger.py +45 -7
- symai/extended/graph.py +38 -24
- symai/extended/html_style_template.py +17 -11
- symai/extended/interfaces/blip_2.py +1 -1
- symai/extended/interfaces/clip.py +4 -2
- symai/extended/interfaces/console.py +5 -3
- symai/extended/interfaces/dall_e.py +3 -1
- symai/extended/interfaces/file.py +2 -0
- symai/extended/interfaces/flux.py +3 -1
- symai/extended/interfaces/gpt_image.py +15 -6
- symai/extended/interfaces/input.py +2 -1
- symai/extended/interfaces/llava.py +1 -1
- symai/extended/interfaces/{naive_webscraping.py → naive_scrape.py} +3 -2
- symai/extended/interfaces/naive_vectordb.py +2 -2
- symai/extended/interfaces/ocr.py +4 -2
- symai/extended/interfaces/openai_search.py +2 -0
- symai/extended/interfaces/parallel.py +30 -0
- symai/extended/interfaces/perplexity.py +2 -0
- symai/extended/interfaces/pinecone.py +6 -4
- symai/extended/interfaces/python.py +2 -0
- symai/extended/interfaces/serpapi.py +2 -0
- symai/extended/interfaces/terminal.py +0 -1
- symai/extended/interfaces/tts.py +2 -1
- symai/extended/interfaces/whisper.py +2 -1
- symai/extended/interfaces/wolframalpha.py +1 -0
- symai/extended/metrics/__init__.py +1 -1
- symai/extended/metrics/similarity.py +5 -2
- symai/extended/os_command.py +31 -22
- symai/extended/packages/symdev.py +39 -34
- symai/extended/packages/sympkg.py +30 -27
- symai/extended/packages/symrun.py +46 -35
- symai/extended/repo_cloner.py +10 -9
- symai/extended/seo_query_optimizer.py +15 -12
- symai/extended/solver.py +104 -76
- symai/extended/summarizer.py +8 -7
- symai/extended/taypan_interpreter.py +10 -9
- symai/extended/vectordb.py +28 -15
- symai/formatter/formatter.py +39 -31
- symai/formatter/regex.py +46 -44
- symai/functional.py +184 -86
- symai/imports.py +85 -51
- symai/interfaces.py +1 -1
- symai/memory.py +33 -24
- symai/menu/screen.py +28 -19
- symai/misc/console.py +27 -27
- symai/misc/loader.py +4 -3
- symai/models/base.py +147 -76
- symai/models/errors.py +1 -1
- symai/ops/__init__.py +1 -1
- symai/ops/measures.py +17 -14
- symai/ops/primitives.py +933 -635
- symai/post_processors.py +28 -24
- symai/pre_processors.py +58 -52
- symai/processor.py +15 -9
- symai/prompts.py +714 -649
- symai/server/huggingface_server.py +115 -32
- symai/server/llama_cpp_server.py +14 -6
- symai/server/qdrant_server.py +206 -0
- symai/shell.py +98 -39
- symai/shellsv.py +307 -223
- symai/strategy.py +135 -81
- symai/symbol.py +276 -225
- symai/utils.py +62 -46
- {symbolicai-1.0.0.dist-info → symbolicai-1.1.1.dist-info}/METADATA +19 -9
- symbolicai-1.1.1.dist-info/RECORD +169 -0
- symbolicai-1.0.0.dist-info/RECORD +0 -163
- {symbolicai-1.0.0.dist-info → symbolicai-1.1.1.dist-info}/WHEEL +0 -0
- {symbolicai-1.0.0.dist-info → symbolicai-1.1.1.dist-info}/entry_points.txt +0 -0
- {symbolicai-1.0.0.dist-info → symbolicai-1.1.1.dist-info}/licenses/LICENSE +0 -0
- {symbolicai-1.0.0.dist-info → symbolicai-1.1.1.dist-info}/top_level.txt +0 -0
symai/ops/primitives.py
CHANGED
|
@@ -31,12 +31,18 @@ class Primitive:
|
|
|
31
31
|
super().__init__(*args, **kwargs)
|
|
32
32
|
# by default, disable shortcut matches and neuro-symbolic iterations
|
|
33
33
|
self.__semantic__ = self.__semantic__ or Primitive.__semantic__
|
|
34
|
-
self.__disable_nesy_engine__ =
|
|
35
|
-
|
|
34
|
+
self.__disable_nesy_engine__ = (
|
|
35
|
+
self.__disable_nesy_engine__ or Primitive.__disable_nesy_engine__
|
|
36
|
+
)
|
|
37
|
+
self.__disable_none_shortcut__ = (
|
|
38
|
+
self.__disable_none_shortcut__ or Primitive.__disable_none_shortcut__
|
|
39
|
+
)
|
|
36
40
|
|
|
37
41
|
@staticmethod
|
|
38
42
|
def _is_iterable(value):
|
|
39
|
-
return isinstance(
|
|
43
|
+
return isinstance(
|
|
44
|
+
value, (list, tuple, set, dict, bytes, bytearray, range, torch.Tensor, np.ndarray)
|
|
45
|
+
)
|
|
40
46
|
|
|
41
47
|
|
|
42
48
|
class OperatorPrimitives(Primitive):
|
|
@@ -47,14 +53,20 @@ class OperatorPrimitives(Primitive):
|
|
|
47
53
|
other = self._to_type(other)
|
|
48
54
|
# None shortcut
|
|
49
55
|
if not self.__disable_none_shortcut__ and (self.value is None or other.value is None):
|
|
50
|
-
UserMessage(
|
|
56
|
+
UserMessage(
|
|
57
|
+
f"unsupported {self._symbol_type.__class__} value operand type(s) for {op}: '{type(self.value)}' and '{type(other.value)}'",
|
|
58
|
+
raise_with=TypeError,
|
|
59
|
+
)
|
|
51
60
|
# try type specific function
|
|
52
61
|
try:
|
|
53
62
|
# try type specific function
|
|
54
63
|
value = func(self, other)
|
|
55
64
|
if value is NotImplemented:
|
|
56
|
-
operation =
|
|
57
|
-
UserMessage(
|
|
65
|
+
operation = "" if op is None else op
|
|
66
|
+
UserMessage(
|
|
67
|
+
f"unsupported {self._symbol_type.__class__} value operand type(s) for {operation}: '{type(self.value)}' and '{type(other.value)}'",
|
|
68
|
+
raise_with=TypeError,
|
|
69
|
+
)
|
|
58
70
|
return value
|
|
59
71
|
except Exception as ex:
|
|
60
72
|
self._metadata._error = ex
|
|
@@ -62,20 +74,23 @@ class OperatorPrimitives(Primitive):
|
|
|
62
74
|
return None
|
|
63
75
|
|
|
64
76
|
def __throw_error_on_nesy_engine_call(self, func):
|
|
65
|
-
|
|
77
|
+
"""
|
|
66
78
|
This function raises an error if the neuro-symbolic engine is disabled.
|
|
67
|
-
|
|
79
|
+
"""
|
|
68
80
|
if self.__disable_nesy_engine__:
|
|
69
|
-
UserMessage(
|
|
81
|
+
UserMessage(
|
|
82
|
+
f"unsupported {self.__class__} value operand type(s) for {func.__name__}: '{type(self.value)}'",
|
|
83
|
+
raise_with=TypeError,
|
|
84
|
+
)
|
|
70
85
|
|
|
71
86
|
def __bool__(self) -> bool:
|
|
72
|
-
|
|
87
|
+
"""
|
|
73
88
|
Get the boolean value of the Symbol.
|
|
74
89
|
If the Symbol's value is of type 'bool', the method returns the boolean value, otherwise it returns False.
|
|
75
90
|
|
|
76
91
|
Returns:
|
|
77
92
|
bool: The boolean value of the Symbol.
|
|
78
|
-
|
|
93
|
+
"""
|
|
79
94
|
val = False
|
|
80
95
|
if isinstance(self.value, bool):
|
|
81
96
|
val = self.value
|
|
@@ -84,12 +99,13 @@ class OperatorPrimitives(Primitive):
|
|
|
84
99
|
|
|
85
100
|
return val
|
|
86
101
|
|
|
87
|
-
|
|
102
|
+
"""
|
|
88
103
|
This mixin contains functions that perform arithmetic operations on symbols or symbol values.
|
|
89
104
|
The functions in this mixin are bound to the 'neurosymbolic' engine for evaluation.
|
|
90
|
-
|
|
105
|
+
"""
|
|
106
|
+
|
|
91
107
|
def __contains__(self, other: Any) -> bool:
|
|
92
|
-
|
|
108
|
+
"""
|
|
93
109
|
Check if a Symbol object is present in another Symbol object.
|
|
94
110
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
95
111
|
|
|
@@ -98,10 +114,12 @@ class OperatorPrimitives(Primitive):
|
|
|
98
114
|
|
|
99
115
|
Returns:
|
|
100
116
|
bool: True if the current Symbol contains the 'other' Symbol, otherwise False.
|
|
101
|
-
|
|
102
|
-
result = self.__try_type_specific_func(
|
|
117
|
+
"""
|
|
118
|
+
result = self.__try_type_specific_func(
|
|
119
|
+
other, lambda self, other: other.value in self.value, op="in"
|
|
120
|
+
)
|
|
103
121
|
|
|
104
|
-
if not self.__semantic__ and not getattr(other,
|
|
122
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
105
123
|
return result
|
|
106
124
|
|
|
107
125
|
self.__throw_error_on_nesy_engine_call(self.__contains__)
|
|
@@ -113,7 +131,7 @@ class OperatorPrimitives(Primitive):
|
|
|
113
131
|
return self._to_type(_func(self, other))
|
|
114
132
|
|
|
115
133
|
def __eq__(self, other: Any) -> bool:
|
|
116
|
-
|
|
134
|
+
"""
|
|
117
135
|
Check if the current Symbol is equal to another Symbol.
|
|
118
136
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
119
137
|
|
|
@@ -122,13 +140,15 @@ class OperatorPrimitives(Primitive):
|
|
|
122
140
|
|
|
123
141
|
Returns:
|
|
124
142
|
bool: True if the current Symbol is equal to the 'other' Symbol, otherwise False.
|
|
125
|
-
|
|
143
|
+
"""
|
|
126
144
|
if self is other:
|
|
127
145
|
return True
|
|
128
146
|
|
|
129
|
-
result = self.__try_type_specific_func(
|
|
147
|
+
result = self.__try_type_specific_func(
|
|
148
|
+
other, lambda self, other: self.value == other.value, op="=="
|
|
149
|
+
)
|
|
130
150
|
|
|
131
|
-
if not self.__semantic__ and not getattr(other,
|
|
151
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
132
152
|
return self._to_type(result)
|
|
133
153
|
|
|
134
154
|
self.__throw_error_on_nesy_engine_call(self.__eq__)
|
|
@@ -140,7 +160,7 @@ class OperatorPrimitives(Primitive):
|
|
|
140
160
|
return self._to_type(_func(self, other))
|
|
141
161
|
|
|
142
162
|
def __ne__(self, other: Any) -> bool:
|
|
143
|
-
|
|
163
|
+
"""
|
|
144
164
|
This method checks if a Symbol object is not equal to another Symbol by using the __eq__ method.
|
|
145
165
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
146
166
|
|
|
@@ -149,16 +169,18 @@ class OperatorPrimitives(Primitive):
|
|
|
149
169
|
|
|
150
170
|
Returns:
|
|
151
171
|
bool: True if the current Symbol is not equal to the 'other' Symbol, otherwise False.
|
|
152
|
-
|
|
153
|
-
result = self.__try_type_specific_func(
|
|
172
|
+
"""
|
|
173
|
+
result = self.__try_type_specific_func(
|
|
174
|
+
other, lambda self, other: self.value != other.value, op="!="
|
|
175
|
+
)
|
|
154
176
|
|
|
155
|
-
if not self.__semantic__ and not getattr(other,
|
|
177
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
156
178
|
return result
|
|
157
179
|
|
|
158
180
|
return not self.__eq__(other)
|
|
159
181
|
|
|
160
182
|
def __gt__(self, other: Any) -> bool:
|
|
161
|
-
|
|
183
|
+
"""
|
|
162
184
|
This method checks if a Symbol object is greater than another Symbol using the @core.compare() decorator with the '>' operator.
|
|
163
185
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
164
186
|
|
|
@@ -167,22 +189,24 @@ class OperatorPrimitives(Primitive):
|
|
|
167
189
|
|
|
168
190
|
Returns:
|
|
169
191
|
bool: True if the current Symbol is greater than the 'other' Symbol, otherwise False.
|
|
170
|
-
|
|
171
|
-
result = self.__try_type_specific_func(
|
|
192
|
+
"""
|
|
193
|
+
result = self.__try_type_specific_func(
|
|
194
|
+
other, lambda self, other: self.value > other.value, op=">"
|
|
195
|
+
)
|
|
172
196
|
|
|
173
|
-
if not self.__semantic__ and not getattr(other,
|
|
197
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
174
198
|
return self._to_type(result)
|
|
175
199
|
|
|
176
200
|
self.__throw_error_on_nesy_engine_call(self.__gt__)
|
|
177
201
|
|
|
178
|
-
@core.compare(operator=
|
|
202
|
+
@core.compare(operator=">")
|
|
179
203
|
def _func(_, other) -> bool:
|
|
180
204
|
pass
|
|
181
205
|
|
|
182
206
|
return self._to_type(_func(self, other))
|
|
183
207
|
|
|
184
208
|
def __lt__(self, other: Any) -> bool:
|
|
185
|
-
|
|
209
|
+
"""
|
|
186
210
|
This method checks if a Symbol object is less than another Symbol using the @core.compare() decorator with the '<' operator.
|
|
187
211
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
188
212
|
|
|
@@ -191,22 +215,24 @@ class OperatorPrimitives(Primitive):
|
|
|
191
215
|
|
|
192
216
|
Returns:
|
|
193
217
|
bool: True if the current Symbol is less than the 'other' Symbol, otherwise False.
|
|
194
|
-
|
|
195
|
-
result = self.__try_type_specific_func(
|
|
218
|
+
"""
|
|
219
|
+
result = self.__try_type_specific_func(
|
|
220
|
+
other, lambda self, other: self.value < other.value, op="<"
|
|
221
|
+
)
|
|
196
222
|
|
|
197
|
-
if not self.__semantic__ and not getattr(other,
|
|
223
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
198
224
|
return self._to_type(result)
|
|
199
225
|
|
|
200
226
|
self.__throw_error_on_nesy_engine_call(self.__lt__)
|
|
201
227
|
|
|
202
|
-
@core.compare(operator=
|
|
228
|
+
@core.compare(operator="<")
|
|
203
229
|
def _func(_, other) -> bool:
|
|
204
230
|
pass
|
|
205
231
|
|
|
206
232
|
return self._to_type(_func(self, other))
|
|
207
233
|
|
|
208
234
|
def __le__(self, other) -> bool:
|
|
209
|
-
|
|
235
|
+
"""
|
|
210
236
|
This method checks if a Symbol object is less than or equal to another Symbol using the @core.compare() decorator with the '<=' operator.
|
|
211
237
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
212
238
|
|
|
@@ -215,22 +241,24 @@ class OperatorPrimitives(Primitive):
|
|
|
215
241
|
|
|
216
242
|
Returns:
|
|
217
243
|
bool: True if the current Symbol is less than or equal to the 'other' Symbol, otherwise False.
|
|
218
|
-
|
|
219
|
-
result = self.__try_type_specific_func(
|
|
244
|
+
"""
|
|
245
|
+
result = self.__try_type_specific_func(
|
|
246
|
+
other, lambda self, other: self.value <= other.value, op="<="
|
|
247
|
+
)
|
|
220
248
|
|
|
221
|
-
if not self.__semantic__ and not getattr(other,
|
|
249
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
222
250
|
return self._to_type(result)
|
|
223
251
|
|
|
224
252
|
self.__throw_error_on_nesy_engine_call(self.__le__)
|
|
225
253
|
|
|
226
|
-
@core.compare(operator=
|
|
254
|
+
@core.compare(operator="<=")
|
|
227
255
|
def _func(_, other) -> bool:
|
|
228
256
|
pass
|
|
229
257
|
|
|
230
258
|
return self._to_type(_func(self, other))
|
|
231
259
|
|
|
232
260
|
def __ge__(self, other) -> bool:
|
|
233
|
-
|
|
261
|
+
"""
|
|
234
262
|
This method checks if a Symbol object is greater than or equal to another Symbol using the @core.compare() decorator with the '>=' operator.
|
|
235
263
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
236
264
|
|
|
@@ -239,29 +267,31 @@ class OperatorPrimitives(Primitive):
|
|
|
239
267
|
|
|
240
268
|
Returns:
|
|
241
269
|
bool: True if the current Symbol is greater than or equal to the 'other' Symbol, otherwise False.
|
|
242
|
-
|
|
243
|
-
result = self.__try_type_specific_func(
|
|
270
|
+
"""
|
|
271
|
+
result = self.__try_type_specific_func(
|
|
272
|
+
other, lambda self, other: self.value >= other.value, op=">="
|
|
273
|
+
)
|
|
244
274
|
|
|
245
|
-
if not self.__semantic__ and not getattr(other,
|
|
275
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
246
276
|
return self._to_type(result)
|
|
247
277
|
|
|
248
278
|
self.__throw_error_on_nesy_engine_call(self.__ge__)
|
|
249
279
|
|
|
250
|
-
@core.compare(operator=
|
|
280
|
+
@core.compare(operator=">=")
|
|
251
281
|
def _func(_, other) -> bool:
|
|
252
282
|
pass
|
|
253
283
|
|
|
254
284
|
return self._to_type(_func(self, other))
|
|
255
285
|
|
|
256
|
-
def __neg__(self) ->
|
|
257
|
-
|
|
286
|
+
def __neg__(self) -> "Symbol":
|
|
287
|
+
"""
|
|
258
288
|
Return the negated value of the Symbol.
|
|
259
289
|
The method uses the @core.negate decorator to compute the negation of the Symbol value.
|
|
260
290
|
|
|
261
291
|
Returns:
|
|
262
292
|
Symbol: The negated value of the Symbol.
|
|
263
|
-
|
|
264
|
-
result = self.__try_type_specific_func(False, lambda self, _: -self.value, op=
|
|
293
|
+
"""
|
|
294
|
+
result = self.__try_type_specific_func(False, lambda self, _: -self.value, op="-")
|
|
265
295
|
|
|
266
296
|
if not self.__semantic__:
|
|
267
297
|
return self._to_type(result)
|
|
@@ -274,19 +304,19 @@ class OperatorPrimitives(Primitive):
|
|
|
274
304
|
|
|
275
305
|
return self._to_type(_func(self))
|
|
276
306
|
|
|
277
|
-
def __invert__(self) ->
|
|
278
|
-
|
|
307
|
+
def __invert__(self) -> "Symbol":
|
|
308
|
+
"""
|
|
279
309
|
Return the inverted value of the Symbol (logical NOT).
|
|
280
310
|
The method uses the @core.invert decorator to compute the inversion of the Symbol value.
|
|
281
311
|
This allows using the ~ operator for semantic inversion.
|
|
282
312
|
|
|
283
313
|
Returns:
|
|
284
314
|
Symbol: The negated value of the Symbol.
|
|
285
|
-
|
|
315
|
+
"""
|
|
286
316
|
if isinstance(self.value, bool):
|
|
287
317
|
return self._to_type(not self.value)
|
|
288
318
|
|
|
289
|
-
result = self.__try_type_specific_func(False, lambda self, _: ~self.value, op=
|
|
319
|
+
result = self.__try_type_specific_func(False, lambda self, _: ~self.value, op="~")
|
|
290
320
|
|
|
291
321
|
if not self.__semantic__:
|
|
292
322
|
return self._to_type(result)
|
|
@@ -299,8 +329,8 @@ class OperatorPrimitives(Primitive):
|
|
|
299
329
|
|
|
300
330
|
return self._to_type(_func(self))
|
|
301
331
|
|
|
302
|
-
def __lshift__(self, other: Any) ->
|
|
303
|
-
|
|
332
|
+
def __lshift__(self, other: Any) -> "Symbol":
|
|
333
|
+
"""
|
|
304
334
|
Add new information to the Symbol.
|
|
305
335
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
306
336
|
|
|
@@ -309,10 +339,12 @@ class OperatorPrimitives(Primitive):
|
|
|
309
339
|
|
|
310
340
|
Returns:
|
|
311
341
|
Symbol: The Symbol with the new information included.
|
|
312
|
-
|
|
313
|
-
result = self.__try_type_specific_func(
|
|
342
|
+
"""
|
|
343
|
+
result = self.__try_type_specific_func(
|
|
344
|
+
other, lambda self, other: self.value << other.value, op="<<"
|
|
345
|
+
)
|
|
314
346
|
|
|
315
|
-
if not self.__semantic__ and not getattr(other,
|
|
347
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
316
348
|
return self._to_type(result)
|
|
317
349
|
|
|
318
350
|
self.__throw_error_on_nesy_engine_call(self.__lshift__)
|
|
@@ -323,8 +355,8 @@ class OperatorPrimitives(Primitive):
|
|
|
323
355
|
|
|
324
356
|
return self._to_type(_func(self, other))
|
|
325
357
|
|
|
326
|
-
def __rlshift__(self, other: Any) ->
|
|
327
|
-
|
|
358
|
+
def __rlshift__(self, other: Any) -> "Symbol":
|
|
359
|
+
"""
|
|
328
360
|
Add new information to the Symbol.
|
|
329
361
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
330
362
|
|
|
@@ -333,10 +365,12 @@ class OperatorPrimitives(Primitive):
|
|
|
333
365
|
|
|
334
366
|
Returns:
|
|
335
367
|
Symbol: The Symbol with the new information included.
|
|
336
|
-
|
|
337
|
-
result = self.__try_type_specific_func(
|
|
368
|
+
"""
|
|
369
|
+
result = self.__try_type_specific_func(
|
|
370
|
+
other, lambda self, other: other.value << self.value, op="<<"
|
|
371
|
+
)
|
|
338
372
|
|
|
339
|
-
if not self.__semantic__ and not getattr(other,
|
|
373
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
340
374
|
return self._to_type(result)
|
|
341
375
|
|
|
342
376
|
self.__throw_error_on_nesy_engine_call(self.__rlshift__)
|
|
@@ -347,8 +381,8 @@ class OperatorPrimitives(Primitive):
|
|
|
347
381
|
|
|
348
382
|
return self._to_type(_func(self, other))
|
|
349
383
|
|
|
350
|
-
def __ilshift__(self, other: Any) ->
|
|
351
|
-
|
|
384
|
+
def __ilshift__(self, other: Any) -> "Symbol":
|
|
385
|
+
"""
|
|
352
386
|
Add new information to the Symbol.
|
|
353
387
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
354
388
|
|
|
@@ -357,10 +391,12 @@ class OperatorPrimitives(Primitive):
|
|
|
357
391
|
|
|
358
392
|
Returns:
|
|
359
393
|
Symbol: The Symbol with the new information included.
|
|
360
|
-
|
|
361
|
-
result = self.__try_type_specific_func(
|
|
394
|
+
"""
|
|
395
|
+
result = self.__try_type_specific_func(
|
|
396
|
+
other, lambda self, other: self.value << other.value, op="<<="
|
|
397
|
+
)
|
|
362
398
|
|
|
363
|
-
if not self.__semantic__ and not getattr(other,
|
|
399
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
364
400
|
self._value = result
|
|
365
401
|
return self
|
|
366
402
|
|
|
@@ -369,12 +405,13 @@ class OperatorPrimitives(Primitive):
|
|
|
369
405
|
@core.include()
|
|
370
406
|
def _func(_, information: str):
|
|
371
407
|
pass
|
|
408
|
+
|
|
372
409
|
self._value = _func(self, other)
|
|
373
410
|
|
|
374
411
|
return self
|
|
375
412
|
|
|
376
|
-
def __rshift__(self, other: Any) ->
|
|
377
|
-
|
|
413
|
+
def __rshift__(self, other: Any) -> "Symbol":
|
|
414
|
+
"""
|
|
378
415
|
Add new information to the Symbol.
|
|
379
416
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
380
417
|
|
|
@@ -383,10 +420,12 @@ class OperatorPrimitives(Primitive):
|
|
|
383
420
|
|
|
384
421
|
Returns:
|
|
385
422
|
Symbol: The Symbol with the new information included.
|
|
386
|
-
|
|
387
|
-
result = self.__try_type_specific_func(
|
|
423
|
+
"""
|
|
424
|
+
result = self.__try_type_specific_func(
|
|
425
|
+
other, lambda self, other: self.value >> other.value, op=">>"
|
|
426
|
+
)
|
|
388
427
|
|
|
389
|
-
if not self.__semantic__ and not getattr(other,
|
|
428
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
390
429
|
return self._to_type(result)
|
|
391
430
|
|
|
392
431
|
self.__throw_error_on_nesy_engine_call(self.__rshift__)
|
|
@@ -397,8 +436,8 @@ class OperatorPrimitives(Primitive):
|
|
|
397
436
|
|
|
398
437
|
return self._to_type(_func(self, other))
|
|
399
438
|
|
|
400
|
-
def __rrshift__(self, other: Any) ->
|
|
401
|
-
|
|
439
|
+
def __rrshift__(self, other: Any) -> "Symbol":
|
|
440
|
+
"""
|
|
402
441
|
Add new information to the Symbol.
|
|
403
442
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
404
443
|
|
|
@@ -407,10 +446,12 @@ class OperatorPrimitives(Primitive):
|
|
|
407
446
|
|
|
408
447
|
Returns:
|
|
409
448
|
Symbol: The Symbol with the new information included.
|
|
410
|
-
|
|
411
|
-
result = self.__try_type_specific_func(
|
|
449
|
+
"""
|
|
450
|
+
result = self.__try_type_specific_func(
|
|
451
|
+
other, lambda self, other: other.value >> self.value, op=">>"
|
|
452
|
+
)
|
|
412
453
|
|
|
413
|
-
if not self.__semantic__ and not getattr(other,
|
|
454
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
414
455
|
return self._to_type(result)
|
|
415
456
|
|
|
416
457
|
self.__throw_error_on_nesy_engine_call(self.__rrshift__)
|
|
@@ -421,8 +462,8 @@ class OperatorPrimitives(Primitive):
|
|
|
421
462
|
|
|
422
463
|
return self._to_type(_func(self, other))
|
|
423
464
|
|
|
424
|
-
def __irshift__(self, other: Any) ->
|
|
425
|
-
|
|
465
|
+
def __irshift__(self, other: Any) -> "Symbol":
|
|
466
|
+
"""
|
|
426
467
|
Add new information to the Symbol.
|
|
427
468
|
The method uses the @core.include decorator to incorporate information into the Symbol.
|
|
428
469
|
|
|
@@ -431,10 +472,12 @@ class OperatorPrimitives(Primitive):
|
|
|
431
472
|
|
|
432
473
|
Returns:
|
|
433
474
|
Symbol: The Symbol with the new information included.
|
|
434
|
-
|
|
435
|
-
result = self.__try_type_specific_func(
|
|
475
|
+
"""
|
|
476
|
+
result = self.__try_type_specific_func(
|
|
477
|
+
other, lambda self, other: self.value >> other.value, op=">>="
|
|
478
|
+
)
|
|
436
479
|
|
|
437
|
-
if not self.__semantic__ and not getattr(other,
|
|
480
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
438
481
|
self._value = result
|
|
439
482
|
return self
|
|
440
483
|
|
|
@@ -443,12 +486,13 @@ class OperatorPrimitives(Primitive):
|
|
|
443
486
|
@core.include()
|
|
444
487
|
def _func(_, information: str):
|
|
445
488
|
pass
|
|
489
|
+
|
|
446
490
|
self._value = _func(self, other)
|
|
447
491
|
|
|
448
492
|
return self
|
|
449
493
|
|
|
450
|
-
def __add__(self, other: Any) ->
|
|
451
|
-
|
|
494
|
+
def __add__(self, other: Any) -> "Symbol":
|
|
495
|
+
"""
|
|
452
496
|
Combine the Symbol with another value.
|
|
453
497
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
454
498
|
The method uses the @core.combine decorator to merge the Symbol and the other value.
|
|
@@ -458,10 +502,12 @@ class OperatorPrimitives(Primitive):
|
|
|
458
502
|
|
|
459
503
|
Returns:
|
|
460
504
|
Symbol: The Symbol combined with the other value.
|
|
461
|
-
|
|
462
|
-
result = self.__try_type_specific_func(
|
|
505
|
+
"""
|
|
506
|
+
result = self.__try_type_specific_func(
|
|
507
|
+
other, lambda self, other: self.value + other.value, op="+"
|
|
508
|
+
)
|
|
463
509
|
|
|
464
|
-
if not self.__semantic__ and not getattr(other,
|
|
510
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
465
511
|
return self._to_type(result)
|
|
466
512
|
|
|
467
513
|
self.__throw_error_on_nesy_engine_call(self.__add__)
|
|
@@ -472,8 +518,8 @@ class OperatorPrimitives(Primitive):
|
|
|
472
518
|
|
|
473
519
|
return self._to_type(_func(self, other))
|
|
474
520
|
|
|
475
|
-
def __radd__(self, other) ->
|
|
476
|
-
|
|
521
|
+
def __radd__(self, other) -> "Symbol":
|
|
522
|
+
"""
|
|
477
523
|
Combine another value with the Symbol.
|
|
478
524
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
479
525
|
The method uses the @core.combine decorator to merge the other value and the Symbol.
|
|
@@ -483,10 +529,12 @@ class OperatorPrimitives(Primitive):
|
|
|
483
529
|
|
|
484
530
|
Returns:
|
|
485
531
|
Symbol: The other value combined with the Symbol.
|
|
486
|
-
|
|
487
|
-
result = self.__try_type_specific_func(
|
|
532
|
+
"""
|
|
533
|
+
result = self.__try_type_specific_func(
|
|
534
|
+
other, lambda self, other: other.value + self.value, op="+"
|
|
535
|
+
)
|
|
488
536
|
|
|
489
|
-
if not self.__semantic__ and not getattr(other,
|
|
537
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
490
538
|
return self._to_type(result)
|
|
491
539
|
|
|
492
540
|
self.__throw_error_on_nesy_engine_call(self.__radd__)
|
|
@@ -497,8 +545,8 @@ class OperatorPrimitives(Primitive):
|
|
|
497
545
|
|
|
498
546
|
return self._to_type(_func(other, self))
|
|
499
547
|
|
|
500
|
-
def __iadd__(self, other: Any) ->
|
|
501
|
-
|
|
548
|
+
def __iadd__(self, other: Any) -> "Symbol":
|
|
549
|
+
"""
|
|
502
550
|
This method adds another value to the Symbol and updates its value with the result.
|
|
503
551
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
504
552
|
|
|
@@ -507,10 +555,12 @@ class OperatorPrimitives(Primitive):
|
|
|
507
555
|
|
|
508
556
|
Returns:
|
|
509
557
|
Symbol: The updated Symbol with the added value.
|
|
510
|
-
|
|
511
|
-
result = self.__try_type_specific_func(
|
|
558
|
+
"""
|
|
559
|
+
result = self.__try_type_specific_func(
|
|
560
|
+
other, lambda self, other: self.value + other.value, op="+="
|
|
561
|
+
)
|
|
512
562
|
|
|
513
|
-
if not self.__semantic__ and not getattr(other,
|
|
563
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
514
564
|
self._value = result
|
|
515
565
|
return self
|
|
516
566
|
other = self._to_type(other)
|
|
@@ -518,8 +568,8 @@ class OperatorPrimitives(Primitive):
|
|
|
518
568
|
|
|
519
569
|
return self
|
|
520
570
|
|
|
521
|
-
def __sub__(self, other: Any) ->
|
|
522
|
-
|
|
571
|
+
def __sub__(self, other: Any) -> "Symbol":
|
|
572
|
+
"""
|
|
523
573
|
Replace occurrences of a value with another value in the Symbol.
|
|
524
574
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
525
575
|
The method uses the @core.replace decorator to replace occurrences of the other value with an empty string in the Symbol.
|
|
@@ -529,10 +579,12 @@ class OperatorPrimitives(Primitive):
|
|
|
529
579
|
|
|
530
580
|
Returns:
|
|
531
581
|
Symbol: The Symbol with occurrences of the other value replaced with an empty string.
|
|
532
|
-
|
|
533
|
-
result = self.__try_type_specific_func(
|
|
582
|
+
"""
|
|
583
|
+
result = self.__try_type_specific_func(
|
|
584
|
+
other, lambda self, other: self.value - other.value, op="-"
|
|
585
|
+
)
|
|
534
586
|
|
|
535
|
-
if not self.__semantic__ and not getattr(other,
|
|
587
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
536
588
|
return self._to_type(result)
|
|
537
589
|
|
|
538
590
|
self.__throw_error_on_nesy_engine_call(self.__sub__)
|
|
@@ -541,10 +593,10 @@ class OperatorPrimitives(Primitive):
|
|
|
541
593
|
def _func(_, text: str, replace: str, value: str):
|
|
542
594
|
pass
|
|
543
595
|
|
|
544
|
-
return self._to_type(_func(self, other,
|
|
596
|
+
return self._to_type(_func(self, other, ""))
|
|
545
597
|
|
|
546
|
-
def __rsub__(self, other: Any) ->
|
|
547
|
-
|
|
598
|
+
def __rsub__(self, other: Any) -> "Symbol":
|
|
599
|
+
"""
|
|
548
600
|
Subtracts the symbol value from another one and removes the substrings that match the symbol value.
|
|
549
601
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
550
602
|
Using the core.replace decorator, this function creates a _func method to remove matching substrings.
|
|
@@ -554,10 +606,12 @@ class OperatorPrimitives(Primitive):
|
|
|
554
606
|
|
|
555
607
|
Returns:
|
|
556
608
|
Symbol: A new symbol with the result of the subtraction.
|
|
557
|
-
|
|
558
|
-
result = self.__try_type_specific_func(
|
|
609
|
+
"""
|
|
610
|
+
result = self.__try_type_specific_func(
|
|
611
|
+
other, lambda self, other: other.value - self.value, op="-"
|
|
612
|
+
)
|
|
559
613
|
|
|
560
|
-
if not self.__semantic__ and not getattr(other,
|
|
614
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
561
615
|
return self._to_type(result)
|
|
562
616
|
|
|
563
617
|
self.__throw_error_on_nesy_engine_call(self.__rsub__)
|
|
@@ -565,12 +619,13 @@ class OperatorPrimitives(Primitive):
|
|
|
565
619
|
@core.replace()
|
|
566
620
|
def _func(_, text: str, replace: str, value: str):
|
|
567
621
|
pass
|
|
622
|
+
|
|
568
623
|
other = self._to_type(other)
|
|
569
624
|
|
|
570
|
-
return self._to_type(_func(other, self,
|
|
625
|
+
return self._to_type(_func(other, self, ""))
|
|
571
626
|
|
|
572
|
-
def __isub__(self, other: Any) ->
|
|
573
|
-
|
|
627
|
+
def __isub__(self, other: Any) -> "Symbol":
|
|
628
|
+
"""
|
|
574
629
|
In-place subtraction of the symbol value by the other symbol value.
|
|
575
630
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
576
631
|
|
|
@@ -579,10 +634,12 @@ class OperatorPrimitives(Primitive):
|
|
|
579
634
|
|
|
580
635
|
Returns:
|
|
581
636
|
Symbol: The current symbol with the updated value.
|
|
582
|
-
|
|
583
|
-
result = self.__try_type_specific_func(
|
|
637
|
+
"""
|
|
638
|
+
result = self.__try_type_specific_func(
|
|
639
|
+
other, lambda self, other: self.value - other.value, op="-="
|
|
640
|
+
)
|
|
584
641
|
|
|
585
|
-
if not self.__semantic__ and not getattr(other,
|
|
642
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
586
643
|
self._value = result
|
|
587
644
|
return self
|
|
588
645
|
val = self.__sub__(other)
|
|
@@ -591,7 +648,7 @@ class OperatorPrimitives(Primitive):
|
|
|
591
648
|
return self
|
|
592
649
|
|
|
593
650
|
def __and__(self, other: Any) -> Any:
|
|
594
|
-
|
|
651
|
+
"""
|
|
595
652
|
Performs a logical AND operation between the symbol value and another.
|
|
596
653
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
597
654
|
Uses the core.logic decorator with operator='and' to create a _func method for the AND operation.
|
|
@@ -601,22 +658,24 @@ class OperatorPrimitives(Primitive):
|
|
|
601
658
|
|
|
602
659
|
Returns:
|
|
603
660
|
Symbol: A new symbol with the result of the AND operation.
|
|
604
|
-
|
|
605
|
-
result = self.__try_type_specific_func(
|
|
661
|
+
"""
|
|
662
|
+
result = self.__try_type_specific_func(
|
|
663
|
+
other, lambda self, other: self.value & other.value, op="&"
|
|
664
|
+
)
|
|
606
665
|
|
|
607
|
-
if not self.__semantic__ and not getattr(other,
|
|
666
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
608
667
|
return self._to_type(result)
|
|
609
668
|
|
|
610
669
|
self.__throw_error_on_nesy_engine_call(self.__and__)
|
|
611
670
|
|
|
612
|
-
@core.logic(operator=
|
|
671
|
+
@core.logic(operator="and")
|
|
613
672
|
def _func(_, a: str, b: str):
|
|
614
673
|
pass
|
|
615
674
|
|
|
616
675
|
return self._to_type(_func(self, other))
|
|
617
676
|
|
|
618
677
|
def __rand__(self, other: Any) -> Any:
|
|
619
|
-
|
|
678
|
+
"""
|
|
620
679
|
Performs a logical AND operation between the symbol value and another.
|
|
621
680
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
622
681
|
Uses the core.logic decorator with operator='and' to create a _func method for the AND operation.
|
|
@@ -626,23 +685,26 @@ class OperatorPrimitives(Primitive):
|
|
|
626
685
|
|
|
627
686
|
Returns:
|
|
628
687
|
Symbol: A new symbol with the result of the AND operation.
|
|
629
|
-
|
|
630
|
-
result = self.__try_type_specific_func(
|
|
688
|
+
"""
|
|
689
|
+
result = self.__try_type_specific_func(
|
|
690
|
+
other, lambda self, other: other.value & self.value, op="&"
|
|
691
|
+
)
|
|
631
692
|
|
|
632
|
-
if not self.__semantic__ and not getattr(other,
|
|
693
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
633
694
|
return self._to_type(result)
|
|
634
695
|
|
|
635
696
|
self.__throw_error_on_nesy_engine_call(self.__rand__)
|
|
636
697
|
|
|
637
|
-
@core.logic(operator=
|
|
698
|
+
@core.logic(operator="and")
|
|
638
699
|
def _func(_, a: str, b: str):
|
|
639
700
|
pass
|
|
701
|
+
|
|
640
702
|
other = self._to_type(other)
|
|
641
703
|
|
|
642
704
|
return self._to_type(_func(other, self))
|
|
643
705
|
|
|
644
706
|
def __iand__(self, other: Any) -> Any:
|
|
645
|
-
|
|
707
|
+
"""
|
|
646
708
|
Performs a logical AND operation between the symbol value and another.
|
|
647
709
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
648
710
|
Uses the core.logic decorator with operator='and' to create a _func method for the AND operation.
|
|
@@ -652,24 +714,27 @@ class OperatorPrimitives(Primitive):
|
|
|
652
714
|
|
|
653
715
|
Returns:
|
|
654
716
|
Symbol: A new symbol with the result of the AND operation.
|
|
655
|
-
|
|
656
|
-
result = self.__try_type_specific_func(
|
|
717
|
+
"""
|
|
718
|
+
result = self.__try_type_specific_func(
|
|
719
|
+
other, lambda self, other: self.value & other.value, op="&="
|
|
720
|
+
)
|
|
657
721
|
|
|
658
|
-
if not self.__semantic__ and not getattr(other,
|
|
722
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
659
723
|
self._value = result
|
|
660
724
|
return self
|
|
661
725
|
|
|
662
726
|
self.__throw_error_on_nesy_engine_call(self.__iand__)
|
|
663
727
|
|
|
664
|
-
@core.logic(operator=
|
|
728
|
+
@core.logic(operator="and")
|
|
665
729
|
def _func(_, a: str, b: str):
|
|
666
730
|
pass
|
|
731
|
+
|
|
667
732
|
self._value = _func(self, other)
|
|
668
733
|
|
|
669
734
|
return self
|
|
670
735
|
|
|
671
736
|
def __or__(self, other: Any) -> Any:
|
|
672
|
-
|
|
737
|
+
"""
|
|
673
738
|
Performs a logical OR operation between the symbol value and another.
|
|
674
739
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
675
740
|
Uses the core.logic decorator with operator='or' to create a _func method for the OR operation.
|
|
@@ -679,27 +744,30 @@ class OperatorPrimitives(Primitive):
|
|
|
679
744
|
|
|
680
745
|
Returns:
|
|
681
746
|
Symbol: A new symbol with the result of the OR operation.
|
|
682
|
-
|
|
747
|
+
"""
|
|
683
748
|
# Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
|
|
684
|
-
from ..collect.stats import Aggregator
|
|
749
|
+
from ..collect.stats import Aggregator # noqa
|
|
750
|
+
|
|
685
751
|
if isinstance(other, Aggregator):
|
|
686
752
|
return NotImplemented
|
|
687
753
|
|
|
688
|
-
result = self.__try_type_specific_func(
|
|
754
|
+
result = self.__try_type_specific_func(
|
|
755
|
+
other, lambda self, other: self.value | other.value, op="|"
|
|
756
|
+
)
|
|
689
757
|
|
|
690
|
-
if not self.__semantic__ and not getattr(other,
|
|
758
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
691
759
|
return self._to_type(result)
|
|
692
760
|
|
|
693
761
|
self.__throw_error_on_nesy_engine_call(self.__or__)
|
|
694
762
|
|
|
695
|
-
@core.logic(operator=
|
|
763
|
+
@core.logic(operator="or")
|
|
696
764
|
def _func(_, a: str, b: str):
|
|
697
765
|
pass
|
|
698
766
|
|
|
699
767
|
return self._to_type(_func(self, other))
|
|
700
768
|
|
|
701
|
-
def __ror__(self, other: Any) ->
|
|
702
|
-
|
|
769
|
+
def __ror__(self, other: Any) -> "Symbol":
|
|
770
|
+
"""
|
|
703
771
|
Performs a logical OR operation between the symbol value and another.
|
|
704
772
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
705
773
|
|
|
@@ -708,28 +776,32 @@ class OperatorPrimitives(Primitive):
|
|
|
708
776
|
|
|
709
777
|
Returns:
|
|
710
778
|
Symbol: A new Symbol object with the concatenated value.
|
|
711
|
-
|
|
779
|
+
"""
|
|
712
780
|
# Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
|
|
713
|
-
from ..collect.stats import Aggregator
|
|
781
|
+
from ..collect.stats import Aggregator # noqa
|
|
782
|
+
|
|
714
783
|
if isinstance(other, Aggregator):
|
|
715
784
|
return NotImplemented
|
|
716
785
|
|
|
717
|
-
result = self.__try_type_specific_func(
|
|
786
|
+
result = self.__try_type_specific_func(
|
|
787
|
+
other, lambda self, other: self.value | other.value, op="|"
|
|
788
|
+
)
|
|
718
789
|
|
|
719
|
-
if not self.__semantic__ and not getattr(other,
|
|
790
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
720
791
|
return self._to_type(result)
|
|
721
792
|
|
|
722
793
|
self.__throw_error_on_nesy_engine_call(self.__ror__)
|
|
723
794
|
|
|
724
|
-
@core.logic(operator=
|
|
795
|
+
@core.logic(operator="or")
|
|
725
796
|
def _func(a: str, b: str):
|
|
726
797
|
pass
|
|
798
|
+
|
|
727
799
|
other = self._to_type(other)
|
|
728
800
|
|
|
729
801
|
return self._to_type(_func(other, self))
|
|
730
802
|
|
|
731
|
-
def __ior__(self, other: Any) ->
|
|
732
|
-
|
|
803
|
+
def __ior__(self, other: Any) -> "Symbol":
|
|
804
|
+
"""
|
|
733
805
|
Performs a logical OR operation between the symbol value and another.
|
|
734
806
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
735
807
|
|
|
@@ -738,30 +810,34 @@ class OperatorPrimitives(Primitive):
|
|
|
738
810
|
|
|
739
811
|
Returns:
|
|
740
812
|
Symbol: A new Symbol object with the concatenated value.
|
|
741
|
-
|
|
813
|
+
"""
|
|
742
814
|
# Exclude the evaluation for the Aggregator class; keep import local to avoid ops.primitives <-> collect.stats cycle.
|
|
743
|
-
from ..collect.stats import Aggregator
|
|
815
|
+
from ..collect.stats import Aggregator # noqa
|
|
816
|
+
|
|
744
817
|
if isinstance(other, Aggregator):
|
|
745
818
|
return NotImplemented
|
|
746
819
|
|
|
747
|
-
result = self.__try_type_specific_func(
|
|
820
|
+
result = self.__try_type_specific_func(
|
|
821
|
+
other, lambda self, other: self.value | other.value, op="|="
|
|
822
|
+
)
|
|
748
823
|
|
|
749
|
-
if not self.__semantic__ and not getattr(other,
|
|
824
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
750
825
|
self._value = result
|
|
751
826
|
return self
|
|
752
827
|
result = self._to_type(str(self) + str(other))
|
|
753
828
|
|
|
754
829
|
self.__throw_error_on_nesy_engine_call(self.__ior__)
|
|
755
830
|
|
|
756
|
-
@core.logic(operator=
|
|
831
|
+
@core.logic(operator="or")
|
|
757
832
|
def _func(_, a: str, b: str):
|
|
758
833
|
pass
|
|
834
|
+
|
|
759
835
|
self._value = _func(self, other)
|
|
760
836
|
|
|
761
837
|
return self
|
|
762
838
|
|
|
763
839
|
def __xor__(self, other: Any) -> Any:
|
|
764
|
-
|
|
840
|
+
"""
|
|
765
841
|
Performs a logical XOR operation between the symbol value and another.
|
|
766
842
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
767
843
|
Uses the core.logic decorator with operator='xor' to create a _func method for the XOR operation.
|
|
@@ -771,22 +847,24 @@ class OperatorPrimitives(Primitive):
|
|
|
771
847
|
|
|
772
848
|
Returns:
|
|
773
849
|
Symbol: A new symbol with the result of the XOR operation.
|
|
774
|
-
|
|
775
|
-
result = self.__try_type_specific_func(
|
|
850
|
+
"""
|
|
851
|
+
result = self.__try_type_specific_func(
|
|
852
|
+
other, lambda self, other: self.value ^ other.value, op="^"
|
|
853
|
+
)
|
|
776
854
|
|
|
777
|
-
if not self.__semantic__ and not getattr(other,
|
|
855
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
778
856
|
return self._to_type(result)
|
|
779
857
|
|
|
780
858
|
self.__throw_error_on_nesy_engine_call(self.__xor__)
|
|
781
859
|
|
|
782
|
-
@core.logic(operator=
|
|
860
|
+
@core.logic(operator="xor")
|
|
783
861
|
def _func(_, a: str, b: str):
|
|
784
862
|
pass
|
|
785
863
|
|
|
786
864
|
return self._to_type(_func(self, other))
|
|
787
865
|
|
|
788
|
-
def __rxor__(self, other: Any) ->
|
|
789
|
-
|
|
866
|
+
def __rxor__(self, other: Any) -> "Symbol":
|
|
867
|
+
"""
|
|
790
868
|
Performs a logical XOR operation between the symbol value and another.
|
|
791
869
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
792
870
|
Uses the core.logic decorator with operator='xor' to create a _func method for the XOR operation.
|
|
@@ -796,22 +874,24 @@ class OperatorPrimitives(Primitive):
|
|
|
796
874
|
|
|
797
875
|
Returns:
|
|
798
876
|
Symbol: A new symbol with the result of the XOR operation.
|
|
799
|
-
|
|
800
|
-
result = self.__try_type_specific_func(
|
|
877
|
+
"""
|
|
878
|
+
result = self.__try_type_specific_func(
|
|
879
|
+
other, lambda self, other: other.value ^ self.value, op="^"
|
|
880
|
+
)
|
|
801
881
|
|
|
802
|
-
if not self.__semantic__ and not getattr(other,
|
|
882
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
803
883
|
return self._to_type(result)
|
|
804
884
|
|
|
805
885
|
self.__throw_error_on_nesy_engine_call(self.__rxor__)
|
|
806
886
|
|
|
807
|
-
@core.logic(operator=
|
|
887
|
+
@core.logic(operator="xor")
|
|
808
888
|
def _func(_, a: str, b: str):
|
|
809
889
|
pass
|
|
810
890
|
|
|
811
891
|
return self._to_type(_func(other, self))
|
|
812
892
|
|
|
813
|
-
def __ixor__(self, other: Any) ->
|
|
814
|
-
|
|
893
|
+
def __ixor__(self, other: Any) -> "Symbol":
|
|
894
|
+
"""
|
|
815
895
|
Performs a logical XOR operation between the symbol value and another.
|
|
816
896
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
817
897
|
Uses the core.logic decorator with operator='xor' to create a _func method for the XOR operation.
|
|
@@ -821,24 +901,27 @@ class OperatorPrimitives(Primitive):
|
|
|
821
901
|
|
|
822
902
|
Returns:
|
|
823
903
|
Symbol: A new symbol with the result of the XOR operation.
|
|
824
|
-
|
|
825
|
-
result = self.__try_type_specific_func(
|
|
904
|
+
"""
|
|
905
|
+
result = self.__try_type_specific_func(
|
|
906
|
+
other, lambda self, other: self.value ^ other.value, op="^="
|
|
907
|
+
)
|
|
826
908
|
|
|
827
|
-
if not self.__semantic__ and not getattr(other,
|
|
909
|
+
if not self.__semantic__ and not getattr(other, "__semantic__", False):
|
|
828
910
|
self._value = result
|
|
829
911
|
return self
|
|
830
912
|
|
|
831
913
|
self.__throw_error_on_nesy_engine_call(self.__ixor__)
|
|
832
914
|
|
|
833
|
-
@core.logic(operator=
|
|
915
|
+
@core.logic(operator="xor")
|
|
834
916
|
def _func(_, a: str, b: str):
|
|
835
917
|
pass
|
|
918
|
+
|
|
836
919
|
self._value = _func(self, other)
|
|
837
920
|
|
|
838
921
|
return self
|
|
839
922
|
|
|
840
|
-
def __matmul__(self, other: Any) ->
|
|
841
|
-
|
|
923
|
+
def __matmul__(self, other: Any) -> "Symbol":
|
|
924
|
+
"""
|
|
842
925
|
This method concatenates the string representation of two Symbol objects and returns a new Symbol with the concatenated result.
|
|
843
926
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
844
927
|
|
|
@@ -847,16 +930,22 @@ class OperatorPrimitives(Primitive):
|
|
|
847
930
|
|
|
848
931
|
Returns:
|
|
849
932
|
Symbol: A new Symbol object with the concatenated value.
|
|
850
|
-
|
|
851
|
-
if (isinstance(self.value, str) and isinstance(other, str)) or
|
|
852
|
-
|
|
933
|
+
"""
|
|
934
|
+
if (isinstance(self.value, str) and isinstance(other, str)) or (
|
|
935
|
+
isinstance(self.value, str)
|
|
936
|
+
and isinstance(other, self._symbol_type)
|
|
937
|
+
and isinstance(other.value, str)
|
|
938
|
+
):
|
|
853
939
|
other = self._to_type(other)
|
|
854
|
-
return self._to_type(f
|
|
855
|
-
UserMessage(
|
|
940
|
+
return self._to_type(f"{self.value}{other.value}")
|
|
941
|
+
UserMessage(
|
|
942
|
+
f"This method is only supported for string concatenation! Got {type(self.value)} and {type(other)} instead.",
|
|
943
|
+
raise_with=TypeError,
|
|
944
|
+
)
|
|
856
945
|
return None
|
|
857
946
|
|
|
858
|
-
def __rmatmul__(self, other: Any) ->
|
|
859
|
-
|
|
947
|
+
def __rmatmul__(self, other: Any) -> "Symbol":
|
|
948
|
+
"""
|
|
860
949
|
This method concatenates the string representation of two Symbol objects in a reversed order and returns a new Symbol with the concatenated result.
|
|
861
950
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
862
951
|
|
|
@@ -865,13 +954,15 @@ class OperatorPrimitives(Primitive):
|
|
|
865
954
|
|
|
866
955
|
Returns:
|
|
867
956
|
Symbol: A new Symbol object with the concatenated value.
|
|
868
|
-
|
|
869
|
-
result = self.__try_type_specific_func(
|
|
957
|
+
"""
|
|
958
|
+
result = self.__try_type_specific_func(
|
|
959
|
+
other, lambda self, other: self._to_type(self.value).__matmul__(other), op="@"
|
|
960
|
+
)
|
|
870
961
|
|
|
871
962
|
return self._to_type(result)
|
|
872
963
|
|
|
873
|
-
def __imatmul__(self, other: Any) ->
|
|
874
|
-
|
|
964
|
+
def __imatmul__(self, other: Any) -> "Symbol":
|
|
965
|
+
"""
|
|
875
966
|
This method concatenates the string representation of two Symbol objects and assigns the concatenated result to the value of the current Symbol object.
|
|
876
967
|
By default, if 'other' is not a Symbol, it's casted to a Symbol object.
|
|
877
968
|
|
|
@@ -880,14 +971,16 @@ class OperatorPrimitives(Primitive):
|
|
|
880
971
|
|
|
881
972
|
Returns:
|
|
882
973
|
Symbol: The current Symbol object with the concatenated value.
|
|
883
|
-
|
|
884
|
-
result = self.__try_type_specific_func(
|
|
974
|
+
"""
|
|
975
|
+
result = self.__try_type_specific_func(
|
|
976
|
+
other, lambda self, other: self._to_type(self.value).__matmul__(other), op="@="
|
|
977
|
+
)
|
|
885
978
|
self._value = result
|
|
886
979
|
|
|
887
980
|
return self
|
|
888
981
|
|
|
889
|
-
def __truediv__(self, other: Any) ->
|
|
890
|
-
|
|
982
|
+
def __truediv__(self, other: Any) -> "Symbol":
|
|
983
|
+
"""
|
|
891
984
|
Divides the symbol value by another, splitting the symbol value by the other value.
|
|
892
985
|
The string representation of the other value is used to split the symbol value.
|
|
893
986
|
|
|
@@ -896,15 +989,17 @@ class OperatorPrimitives(Primitive):
|
|
|
896
989
|
|
|
897
990
|
Returns:
|
|
898
991
|
Symbol: A new symbol with the result of the division.
|
|
899
|
-
|
|
900
|
-
result = self.__try_type_specific_func(
|
|
992
|
+
"""
|
|
993
|
+
result = self.__try_type_specific_func(
|
|
994
|
+
other, lambda self, other: self.value / other.value, op="/"
|
|
995
|
+
)
|
|
901
996
|
if result is not None:
|
|
902
997
|
return self._to_type(result)
|
|
903
998
|
|
|
904
999
|
return self._to_type(str(self).split(str(other)))
|
|
905
1000
|
|
|
906
|
-
def __rtruediv__(self, other: Any) ->
|
|
907
|
-
|
|
1001
|
+
def __rtruediv__(self, other: Any) -> "Symbol":
|
|
1002
|
+
"""
|
|
908
1003
|
Divides the symbol value by another, splitting the symbol value by the other value.
|
|
909
1004
|
The string representation of the other value is used to split the symbol value.
|
|
910
1005
|
|
|
@@ -913,17 +1008,21 @@ class OperatorPrimitives(Primitive):
|
|
|
913
1008
|
|
|
914
1009
|
Returns:
|
|
915
1010
|
Symbol: A new symbol with the result of the division.
|
|
916
|
-
|
|
917
|
-
result = self.__try_type_specific_func(
|
|
1011
|
+
"""
|
|
1012
|
+
result = self.__try_type_specific_func(
|
|
1013
|
+
other, lambda self, other: other.value / self.value, op="/"
|
|
1014
|
+
)
|
|
918
1015
|
if result is not None:
|
|
919
1016
|
return self._to_type(result)
|
|
920
1017
|
|
|
921
|
-
UserMessage(
|
|
1018
|
+
UserMessage(
|
|
1019
|
+
"Division operation not supported semantically! Might change in the future.",
|
|
1020
|
+
raise_with=NotImplementedError,
|
|
1021
|
+
)
|
|
922
1022
|
return None
|
|
923
1023
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
'''
|
|
1024
|
+
def __itruediv__(self, other: Any) -> "Symbol":
|
|
1025
|
+
"""
|
|
927
1026
|
Divides the symbol value by another, splitting the symbol value by the other value.
|
|
928
1027
|
The string representation of the other value is used to split the symbol value.
|
|
929
1028
|
|
|
@@ -932,18 +1031,22 @@ class OperatorPrimitives(Primitive):
|
|
|
932
1031
|
|
|
933
1032
|
Returns:
|
|
934
1033
|
Symbol: A new symbol with the result of the division.
|
|
935
|
-
|
|
936
|
-
result = self.__try_type_specific_func(
|
|
1034
|
+
"""
|
|
1035
|
+
result = self.__try_type_specific_func(
|
|
1036
|
+
other, lambda self, other: self.value / other.value, op="/="
|
|
1037
|
+
)
|
|
937
1038
|
if result is not None:
|
|
938
1039
|
self._value = result
|
|
939
1040
|
return self
|
|
940
1041
|
|
|
941
|
-
UserMessage(
|
|
1042
|
+
UserMessage(
|
|
1043
|
+
"Division operation not supported semantically! Might change in the future.",
|
|
1044
|
+
raise_with=NotImplementedError,
|
|
1045
|
+
)
|
|
942
1046
|
return None
|
|
943
1047
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
'''
|
|
1048
|
+
def __floordiv__(self, other: Any) -> "Symbol":
|
|
1049
|
+
"""
|
|
947
1050
|
Floor divides the symbol value by another, splitting the symbol value by the other value.
|
|
948
1051
|
The string representation of the other value is used to split the symbol value.
|
|
949
1052
|
|
|
@@ -952,16 +1055,21 @@ class OperatorPrimitives(Primitive):
|
|
|
952
1055
|
|
|
953
1056
|
Returns:
|
|
954
1057
|
Symbol: A new symbol with the result of the division.
|
|
955
|
-
|
|
956
|
-
result = self.__try_type_specific_func(
|
|
1058
|
+
"""
|
|
1059
|
+
result = self.__try_type_specific_func(
|
|
1060
|
+
other, lambda self, other: self.value // other.value, op="//"
|
|
1061
|
+
)
|
|
957
1062
|
if result is not None:
|
|
958
1063
|
return self._to_type(result)
|
|
959
1064
|
|
|
960
|
-
UserMessage(
|
|
1065
|
+
UserMessage(
|
|
1066
|
+
"Floor division operation not supported semantically! Might change in the future.",
|
|
1067
|
+
raise_with=NotImplementedError,
|
|
1068
|
+
)
|
|
961
1069
|
return None
|
|
962
1070
|
|
|
963
|
-
def __rfloordiv__(self, other: Any) ->
|
|
964
|
-
|
|
1071
|
+
def __rfloordiv__(self, other: Any) -> "Symbol":
|
|
1072
|
+
"""
|
|
965
1073
|
Floor divides the symbol value by another, splitting the symbol value by the other value.
|
|
966
1074
|
The string representation of the other value is used to split the symbol value.
|
|
967
1075
|
|
|
@@ -970,16 +1078,21 @@ class OperatorPrimitives(Primitive):
|
|
|
970
1078
|
|
|
971
1079
|
Returns:
|
|
972
1080
|
Symbol: A new symbol with the result of the division.
|
|
973
|
-
|
|
974
|
-
result = self.__try_type_specific_func(
|
|
1081
|
+
"""
|
|
1082
|
+
result = self.__try_type_specific_func(
|
|
1083
|
+
other, lambda self, other: other.value // self.value, op="//"
|
|
1084
|
+
)
|
|
975
1085
|
if result is not None:
|
|
976
1086
|
return self._to_type(result)
|
|
977
1087
|
|
|
978
|
-
UserMessage(
|
|
1088
|
+
UserMessage(
|
|
1089
|
+
"Floor division operation not supported semantically! Might change in the future.",
|
|
1090
|
+
raise_with=NotImplementedError,
|
|
1091
|
+
)
|
|
979
1092
|
return None
|
|
980
1093
|
|
|
981
|
-
def __ifloordiv__(self, other: Any) ->
|
|
982
|
-
|
|
1094
|
+
def __ifloordiv__(self, other: Any) -> "Symbol":
|
|
1095
|
+
"""
|
|
983
1096
|
Floor divides the symbol value by another, splitting the symbol value by the other value.
|
|
984
1097
|
The string representation of the other value is used to split the symbol value.
|
|
985
1098
|
|
|
@@ -988,17 +1101,22 @@ class OperatorPrimitives(Primitive):
|
|
|
988
1101
|
|
|
989
1102
|
Returns:
|
|
990
1103
|
Symbol: A new symbol with the result of the division.
|
|
991
|
-
|
|
992
|
-
result = self.__try_type_specific_func(
|
|
1104
|
+
"""
|
|
1105
|
+
result = self.__try_type_specific_func(
|
|
1106
|
+
other, lambda self, other: self.value // other.value, op="//="
|
|
1107
|
+
)
|
|
993
1108
|
if result is not None:
|
|
994
1109
|
self._value = result
|
|
995
1110
|
return self
|
|
996
1111
|
|
|
997
|
-
UserMessage(
|
|
1112
|
+
UserMessage(
|
|
1113
|
+
"Floor division operation not supported semantically! Might change in the future.",
|
|
1114
|
+
raise_with=NotImplementedError,
|
|
1115
|
+
)
|
|
998
1116
|
return None
|
|
999
1117
|
|
|
1000
|
-
def __pow__(self, other: Any) ->
|
|
1001
|
-
|
|
1118
|
+
def __pow__(self, other: Any) -> "Symbol":
|
|
1119
|
+
"""
|
|
1002
1120
|
Power operation on symbol value by another, splitting the symbol value by the other value.
|
|
1003
1121
|
The string representation of the other value is used to split the symbol value.
|
|
1004
1122
|
|
|
@@ -1007,17 +1125,21 @@ class OperatorPrimitives(Primitive):
|
|
|
1007
1125
|
|
|
1008
1126
|
Returns:
|
|
1009
1127
|
Symbol: A new symbol with the result of the division.
|
|
1010
|
-
|
|
1011
|
-
result = self.__try_type_specific_func(
|
|
1128
|
+
"""
|
|
1129
|
+
result = self.__try_type_specific_func(
|
|
1130
|
+
other, lambda self, other: self.value**other.value, op="**"
|
|
1131
|
+
)
|
|
1012
1132
|
if result is not None:
|
|
1013
1133
|
return self._to_type(result)
|
|
1014
1134
|
|
|
1015
|
-
UserMessage(
|
|
1135
|
+
UserMessage(
|
|
1136
|
+
"Power operation not supported semantically! Might change in the future.",
|
|
1137
|
+
raise_with=NotImplementedError,
|
|
1138
|
+
)
|
|
1016
1139
|
return None
|
|
1017
1140
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
'''
|
|
1141
|
+
def __rpow__(self, other: Any) -> "Symbol":
|
|
1142
|
+
"""
|
|
1021
1143
|
Power operation on symbol value by another, splitting the symbol value by the other value.
|
|
1022
1144
|
The string representation of the other value is used to split the symbol value.
|
|
1023
1145
|
|
|
@@ -1026,16 +1148,21 @@ class OperatorPrimitives(Primitive):
|
|
|
1026
1148
|
|
|
1027
1149
|
Returns:
|
|
1028
1150
|
Symbol: A new symbol with the result of the division.
|
|
1029
|
-
|
|
1030
|
-
result = self.__try_type_specific_func(
|
|
1151
|
+
"""
|
|
1152
|
+
result = self.__try_type_specific_func(
|
|
1153
|
+
other, lambda self, other: other.value**self.value, op="**"
|
|
1154
|
+
)
|
|
1031
1155
|
if result is not None:
|
|
1032
1156
|
return self._to_type(result)
|
|
1033
1157
|
|
|
1034
|
-
UserMessage(
|
|
1158
|
+
UserMessage(
|
|
1159
|
+
"Power operation not supported semantically! Might change in the future.",
|
|
1160
|
+
raise_with=NotImplementedError,
|
|
1161
|
+
)
|
|
1035
1162
|
return None
|
|
1036
1163
|
|
|
1037
|
-
def __ipow__(self, other: Any) ->
|
|
1038
|
-
|
|
1164
|
+
def __ipow__(self, other: Any) -> "Symbol":
|
|
1165
|
+
"""
|
|
1039
1166
|
Power operation on symbol value by another, splitting the symbol value by the other value.
|
|
1040
1167
|
The string representation of the other value is used to split the symbol value.
|
|
1041
1168
|
|
|
@@ -1044,17 +1171,22 @@ class OperatorPrimitives(Primitive):
|
|
|
1044
1171
|
|
|
1045
1172
|
Returns:
|
|
1046
1173
|
Symbol: A new symbol with the result of the division.
|
|
1047
|
-
|
|
1048
|
-
result = self.__try_type_specific_func(
|
|
1174
|
+
"""
|
|
1175
|
+
result = self.__try_type_specific_func(
|
|
1176
|
+
other, lambda self, other: self.value**other.value, op="**="
|
|
1177
|
+
)
|
|
1049
1178
|
if result is not None:
|
|
1050
1179
|
self._value = result
|
|
1051
1180
|
return self
|
|
1052
1181
|
|
|
1053
|
-
UserMessage(
|
|
1182
|
+
UserMessage(
|
|
1183
|
+
"Power operation not supported semantically! Might change in the future.",
|
|
1184
|
+
raise_with=NotImplementedError,
|
|
1185
|
+
)
|
|
1054
1186
|
return None
|
|
1055
1187
|
|
|
1056
|
-
def __mod__(self, other: Any) ->
|
|
1057
|
-
|
|
1188
|
+
def __mod__(self, other: Any) -> "Symbol":
|
|
1189
|
+
"""
|
|
1058
1190
|
Modulo operation on symbol value by another, splitting the symbol value by the other value.
|
|
1059
1191
|
The string representation of the other value is used to split the symbol value.
|
|
1060
1192
|
|
|
@@ -1063,16 +1195,21 @@ class OperatorPrimitives(Primitive):
|
|
|
1063
1195
|
|
|
1064
1196
|
Returns:
|
|
1065
1197
|
Symbol: A new symbol with the result of the division.
|
|
1066
|
-
|
|
1067
|
-
result = self.__try_type_specific_func(
|
|
1198
|
+
"""
|
|
1199
|
+
result = self.__try_type_specific_func(
|
|
1200
|
+
other, lambda self, other: self.value % other.value, op="%"
|
|
1201
|
+
)
|
|
1068
1202
|
if result is not None:
|
|
1069
1203
|
return self._to_type(result)
|
|
1070
1204
|
|
|
1071
|
-
UserMessage(
|
|
1205
|
+
UserMessage(
|
|
1206
|
+
"Modulo operation not supported semantically! Might change in the future.",
|
|
1207
|
+
raise_with=NotImplementedError,
|
|
1208
|
+
)
|
|
1072
1209
|
return None
|
|
1073
1210
|
|
|
1074
|
-
def __rmod__(self, other: Any) ->
|
|
1075
|
-
|
|
1211
|
+
def __rmod__(self, other: Any) -> "Symbol":
|
|
1212
|
+
"""
|
|
1076
1213
|
Modulo operation on symbol value by another, splitting the symbol value by the other value.
|
|
1077
1214
|
The string representation of the other value is used to split the symbol value.
|
|
1078
1215
|
|
|
@@ -1081,17 +1218,19 @@ class OperatorPrimitives(Primitive):
|
|
|
1081
1218
|
|
|
1082
1219
|
Returns:
|
|
1083
1220
|
Symbol: A new symbol with the result of the division.
|
|
1084
|
-
|
|
1085
|
-
result = self.__try_type_specific_func(
|
|
1221
|
+
"""
|
|
1222
|
+
result = self.__try_type_specific_func(
|
|
1223
|
+
other, lambda self, other: other.value % self.value, op="%"
|
|
1224
|
+
)
|
|
1086
1225
|
if result is not None:
|
|
1087
1226
|
return self._to_type(result)
|
|
1088
1227
|
|
|
1089
|
-
msg =
|
|
1228
|
+
msg = "Modulo operation not supported! Might change in the future."
|
|
1090
1229
|
UserMessage(msg)
|
|
1091
1230
|
raise NotImplementedError(msg) from self._metadata._error
|
|
1092
1231
|
|
|
1093
|
-
def __imod__(self, other: Any) ->
|
|
1094
|
-
|
|
1232
|
+
def __imod__(self, other: Any) -> "Symbol":
|
|
1233
|
+
"""
|
|
1095
1234
|
Modulo operation on symbol value by another, splitting the symbol value by the other value.
|
|
1096
1235
|
The string representation of the other value is used to split the symbol value.
|
|
1097
1236
|
|
|
@@ -1100,17 +1239,22 @@ class OperatorPrimitives(Primitive):
|
|
|
1100
1239
|
|
|
1101
1240
|
Returns:
|
|
1102
1241
|
Symbol: A new symbol with the result of the division.
|
|
1103
|
-
|
|
1104
|
-
result = self.__try_type_specific_func(
|
|
1242
|
+
"""
|
|
1243
|
+
result = self.__try_type_specific_func(
|
|
1244
|
+
other, lambda self, other: self.value % other.value, op="%="
|
|
1245
|
+
)
|
|
1105
1246
|
if result is not None:
|
|
1106
1247
|
self._value = result
|
|
1107
1248
|
return self
|
|
1108
1249
|
|
|
1109
|
-
UserMessage(
|
|
1250
|
+
UserMessage(
|
|
1251
|
+
"Modulo operation not supported semantically! Might change in the future.",
|
|
1252
|
+
raise_with=NotImplementedError,
|
|
1253
|
+
)
|
|
1110
1254
|
return None
|
|
1111
1255
|
|
|
1112
|
-
def __mul__(self, other: Any) ->
|
|
1113
|
-
|
|
1256
|
+
def __mul__(self, other: Any) -> "Symbol":
|
|
1257
|
+
"""
|
|
1114
1258
|
Multiply operation on symbol value by another, splitting the symbol value by the other value.
|
|
1115
1259
|
The string representation of the other value is used to split the symbol value.
|
|
1116
1260
|
|
|
@@ -1119,16 +1263,21 @@ class OperatorPrimitives(Primitive):
|
|
|
1119
1263
|
|
|
1120
1264
|
Returns:
|
|
1121
1265
|
Symbol: A new symbol with the result of the division.
|
|
1122
|
-
|
|
1123
|
-
result = self.__try_type_specific_func(
|
|
1266
|
+
"""
|
|
1267
|
+
result = self.__try_type_specific_func(
|
|
1268
|
+
other, lambda self, other: self.value * other.value, op="*"
|
|
1269
|
+
)
|
|
1124
1270
|
if result is not None:
|
|
1125
1271
|
return self._to_type(result)
|
|
1126
1272
|
|
|
1127
|
-
UserMessage(
|
|
1273
|
+
UserMessage(
|
|
1274
|
+
"Multiply operation not supported semantically! Might change in the future.",
|
|
1275
|
+
raise_with=NotImplementedError,
|
|
1276
|
+
)
|
|
1128
1277
|
return None
|
|
1129
1278
|
|
|
1130
|
-
def __rmul__(self, other: Any) ->
|
|
1131
|
-
|
|
1279
|
+
def __rmul__(self, other: Any) -> "Symbol":
|
|
1280
|
+
"""
|
|
1132
1281
|
Multiply operation on symbol value by another, splitting the symbol value by the other value.
|
|
1133
1282
|
The string representation of the other value is used to split the symbol value.
|
|
1134
1283
|
|
|
@@ -1137,16 +1286,21 @@ class OperatorPrimitives(Primitive):
|
|
|
1137
1286
|
|
|
1138
1287
|
Returns:
|
|
1139
1288
|
Symbol: A new symbol with the result of the division.
|
|
1140
|
-
|
|
1141
|
-
result = self.__try_type_specific_func(
|
|
1289
|
+
"""
|
|
1290
|
+
result = self.__try_type_specific_func(
|
|
1291
|
+
other, lambda self, other: other.value * self.value, op="*"
|
|
1292
|
+
)
|
|
1142
1293
|
if result is not None:
|
|
1143
1294
|
return self._to_type(result)
|
|
1144
1295
|
|
|
1145
|
-
UserMessage(
|
|
1296
|
+
UserMessage(
|
|
1297
|
+
"Multiply operation not supported semantically! Might change in the future.",
|
|
1298
|
+
raise_with=NotImplementedError,
|
|
1299
|
+
)
|
|
1146
1300
|
return None
|
|
1147
1301
|
|
|
1148
|
-
def __imul__(self, other: Any) ->
|
|
1149
|
-
|
|
1302
|
+
def __imul__(self, other: Any) -> "Symbol":
|
|
1303
|
+
"""
|
|
1150
1304
|
Multiply operation on symbol value by another, splitting the symbol value by the other value.
|
|
1151
1305
|
The string representation of the other value is used to split the symbol value.
|
|
1152
1306
|
|
|
@@ -1155,20 +1309,26 @@ class OperatorPrimitives(Primitive):
|
|
|
1155
1309
|
|
|
1156
1310
|
Returns:
|
|
1157
1311
|
Symbol: A new symbol with the result of the division.
|
|
1158
|
-
|
|
1159
|
-
result = self.__try_type_specific_func(
|
|
1312
|
+
"""
|
|
1313
|
+
result = self.__try_type_specific_func(
|
|
1314
|
+
other, lambda self, other: self.value * other.value, op="*="
|
|
1315
|
+
)
|
|
1160
1316
|
if result is not None:
|
|
1161
1317
|
self._value = result
|
|
1162
1318
|
return self
|
|
1163
1319
|
|
|
1164
|
-
UserMessage(
|
|
1320
|
+
UserMessage(
|
|
1321
|
+
"Multiply operation not supported semantically! Might change in the future.",
|
|
1322
|
+
raise_with=NotImplementedError,
|
|
1323
|
+
)
|
|
1165
1324
|
return None
|
|
1166
1325
|
|
|
1167
1326
|
|
|
1168
1327
|
class CastingPrimitives(Primitive):
|
|
1169
|
-
|
|
1328
|
+
"""
|
|
1170
1329
|
This mixin contains functionalities related to casting symbols.
|
|
1171
|
-
|
|
1330
|
+
"""
|
|
1331
|
+
|
|
1172
1332
|
@property
|
|
1173
1333
|
def syn(self) -> "Symbol":
|
|
1174
1334
|
"""
|
|
@@ -1189,7 +1349,7 @@ class CastingPrimitives(Primitive):
|
|
|
1189
1349
|
return self._to_type(self.value, semantic=True)
|
|
1190
1350
|
|
|
1191
1351
|
def cast(self, as_type: type) -> Any:
|
|
1192
|
-
|
|
1352
|
+
"""
|
|
1193
1353
|
Cast the Symbol's value to a specific type.
|
|
1194
1354
|
|
|
1195
1355
|
Args:
|
|
@@ -1197,11 +1357,11 @@ class CastingPrimitives(Primitive):
|
|
|
1197
1357
|
|
|
1198
1358
|
Returns:
|
|
1199
1359
|
The Symbol's value casted to the specified type.
|
|
1200
|
-
|
|
1360
|
+
"""
|
|
1201
1361
|
return as_type(self.value)
|
|
1202
1362
|
|
|
1203
1363
|
def to(self, as_type: type) -> Any:
|
|
1204
|
-
|
|
1364
|
+
"""
|
|
1205
1365
|
Cast the Symbol's value to a specific type.
|
|
1206
1366
|
|
|
1207
1367
|
Args:
|
|
@@ -1209,65 +1369,65 @@ class CastingPrimitives(Primitive):
|
|
|
1209
1369
|
|
|
1210
1370
|
Returns:
|
|
1211
1371
|
The Symbol's value casted to the specified type.
|
|
1212
|
-
|
|
1372
|
+
"""
|
|
1213
1373
|
return self.cast(as_type)
|
|
1214
1374
|
|
|
1215
1375
|
def ast(self) -> Any:
|
|
1216
|
-
|
|
1376
|
+
"""
|
|
1217
1377
|
Converts the string representation of the Symbol's value to an abstract syntax tree using 'ast.literal_eval'.
|
|
1218
1378
|
|
|
1219
1379
|
Returns:
|
|
1220
1380
|
The abstract syntax tree representation of the Symbol's value.
|
|
1221
|
-
|
|
1381
|
+
"""
|
|
1222
1382
|
return ast.literal_eval(str(self.value))
|
|
1223
1383
|
|
|
1224
1384
|
def str(self) -> str:
|
|
1225
|
-
|
|
1385
|
+
"""
|
|
1226
1386
|
Get the string representation of the Symbol's value.
|
|
1227
1387
|
|
|
1228
1388
|
Returns:
|
|
1229
1389
|
str: The string representation of the Symbol's value.
|
|
1230
|
-
|
|
1390
|
+
"""
|
|
1231
1391
|
return str(self.value)
|
|
1232
1392
|
|
|
1233
1393
|
def int(self) -> int:
|
|
1234
|
-
|
|
1394
|
+
"""
|
|
1235
1395
|
Get the integer representation of the Symbol's value.
|
|
1236
1396
|
|
|
1237
1397
|
Returns:
|
|
1238
1398
|
int: The integer representation of the Symbol's value.
|
|
1239
|
-
|
|
1399
|
+
"""
|
|
1240
1400
|
return int(self.value)
|
|
1241
1401
|
|
|
1242
1402
|
def float(self) -> float:
|
|
1243
|
-
|
|
1244
|
-
'''
|
|
1403
|
+
"""
|
|
1245
1404
|
Get the float representation of the Symbol's value.
|
|
1246
1405
|
|
|
1247
1406
|
Returns:
|
|
1248
1407
|
float: The float representation of the Symbol's value.
|
|
1249
|
-
|
|
1408
|
+
"""
|
|
1250
1409
|
return float(self.value)
|
|
1251
1410
|
|
|
1252
1411
|
def bool(self) -> bool:
|
|
1253
|
-
|
|
1412
|
+
"""
|
|
1254
1413
|
Get the boolean representation of the Symbol's value.
|
|
1255
1414
|
|
|
1256
1415
|
Returns:
|
|
1257
1416
|
bool: The boolean representation of the Symbol's value.
|
|
1258
|
-
|
|
1417
|
+
"""
|
|
1259
1418
|
return bool(self.value)
|
|
1260
1419
|
|
|
1261
1420
|
|
|
1262
|
-
|
|
1421
|
+
# @TODO: We can do much better than asking the model to generate the entire thing. We can come up with a more structured way, e.g.,
|
|
1263
1422
|
# using a JSON schema (or contracts) and return only the keys where we need to set/del information.
|
|
1264
1423
|
class IterationPrimitives(Primitive):
|
|
1265
|
-
|
|
1424
|
+
"""
|
|
1266
1425
|
This mixin contains functions that perform iteration operations on symbols or symbol values.
|
|
1267
1426
|
The functions in this mixin are bound to the 'neurosymbolic' engine for evaluation.
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1427
|
+
"""
|
|
1428
|
+
|
|
1429
|
+
def __getitem__(self, key: str | int | slice) -> "Symbol":
|
|
1430
|
+
"""
|
|
1271
1431
|
Get the item of the Symbol value with the specified key or index.
|
|
1272
1432
|
If the Symbol value is a list, tuple, or numpy array, the key can be an integer or slice.
|
|
1273
1433
|
If the Symbol value is a dictionary, the key can be a string or an integer.
|
|
@@ -1281,12 +1441,12 @@ class IterationPrimitives(Primitive):
|
|
|
1281
1441
|
|
|
1282
1442
|
Raises:
|
|
1283
1443
|
KeyError: If the key or index is not found in the Symbol value.
|
|
1284
|
-
|
|
1444
|
+
"""
|
|
1285
1445
|
if not self.__semantic__:
|
|
1286
1446
|
try:
|
|
1287
1447
|
return self.value[key]
|
|
1288
1448
|
except Exception:
|
|
1289
|
-
UserMessage(f
|
|
1449
|
+
UserMessage(f"Key {key} not found in {self.value}", raise_with=Exception)
|
|
1290
1450
|
|
|
1291
1451
|
@core.getitem()
|
|
1292
1452
|
def _func(_, index: str):
|
|
@@ -1295,7 +1455,7 @@ class IterationPrimitives(Primitive):
|
|
|
1295
1455
|
return self._to_type(_func(self, key))
|
|
1296
1456
|
|
|
1297
1457
|
def __setitem__(self, key: str | int | slice, value: Any) -> None:
|
|
1298
|
-
|
|
1458
|
+
"""
|
|
1299
1459
|
Set the item of the Symbol value with the specified key or index to the given value.
|
|
1300
1460
|
If the Symbol value is a list, the key can be an integer or slice.
|
|
1301
1461
|
If the Symbol value is a dictionary, the key can be a string or an integer.
|
|
@@ -1307,19 +1467,22 @@ class IterationPrimitives(Primitive):
|
|
|
1307
1467
|
|
|
1308
1468
|
Raises:
|
|
1309
1469
|
KeyError: If the key or index is not found in the Symbol value.
|
|
1310
|
-
|
|
1470
|
+
"""
|
|
1311
1471
|
# Local import avoids ops.primitives -> post_processors -> symbol -> ops circular load.
|
|
1312
|
-
from ..post_processors import ASTPostProcessor
|
|
1472
|
+
from ..post_processors import ASTPostProcessor # noqa
|
|
1313
1473
|
|
|
1314
1474
|
if not isinstance(self.value, (str, dict, list)):
|
|
1315
|
-
UserMessage(
|
|
1475
|
+
UserMessage(
|
|
1476
|
+
f"Setting item is not supported for {type(self.value)}. Supported types are str, dict, and list.",
|
|
1477
|
+
raise_with=TypeError,
|
|
1478
|
+
)
|
|
1316
1479
|
|
|
1317
1480
|
if not self.__semantic__:
|
|
1318
1481
|
try:
|
|
1319
1482
|
self.value[key] = value
|
|
1320
1483
|
return
|
|
1321
1484
|
except Exception:
|
|
1322
|
-
UserMessage(f
|
|
1485
|
+
UserMessage(f"Key {key} not found in {self.value}", raise_with=Exception)
|
|
1323
1486
|
|
|
1324
1487
|
@core.setitem()
|
|
1325
1488
|
def _func(_, index: str, value: str):
|
|
@@ -1327,12 +1490,16 @@ class IterationPrimitives(Primitive):
|
|
|
1327
1490
|
|
|
1328
1491
|
result = _func(self, key, value)
|
|
1329
1492
|
try:
|
|
1330
|
-
self._value = ASTPostProcessor()(
|
|
1493
|
+
self._value = ASTPostProcessor()(
|
|
1494
|
+
result
|
|
1495
|
+
) # The type of the object that the model changed was a list or a dict
|
|
1331
1496
|
except Exception:
|
|
1332
|
-
self._value =
|
|
1497
|
+
self._value = (
|
|
1498
|
+
result # It was a string, or something failed (because } wasn't close, etc)
|
|
1499
|
+
)
|
|
1333
1500
|
|
|
1334
1501
|
def __delitem__(self, key: str | int) -> None:
|
|
1335
|
-
|
|
1502
|
+
"""
|
|
1336
1503
|
Delete the item of the Symbol value with the specified key or index.
|
|
1337
1504
|
If the Symbol value is a dictionary, the key can be a string or an integer.
|
|
1338
1505
|
If the direct item deletion fails, the method falls back to using the @core.delitem decorator, which deletes the item using core functions.
|
|
@@ -1342,19 +1509,22 @@ class IterationPrimitives(Primitive):
|
|
|
1342
1509
|
|
|
1343
1510
|
Raises:
|
|
1344
1511
|
KeyError: If the key or index is not found in the Symbol value.
|
|
1345
|
-
|
|
1512
|
+
"""
|
|
1346
1513
|
# Local import avoids ops.primitives -> post_processors -> symbol -> ops circular load.
|
|
1347
|
-
from ..post_processors import ASTPostProcessor
|
|
1514
|
+
from ..post_processors import ASTPostProcessor # noqa
|
|
1348
1515
|
|
|
1349
1516
|
if not isinstance(self.value, (str, dict, list)):
|
|
1350
|
-
UserMessage(
|
|
1517
|
+
UserMessage(
|
|
1518
|
+
f"Setting item is not supported for {type(self.value)}. Supported types are str, dict, and list.",
|
|
1519
|
+
raise_with=TypeError,
|
|
1520
|
+
)
|
|
1351
1521
|
|
|
1352
1522
|
if not self.__semantic__:
|
|
1353
1523
|
try:
|
|
1354
1524
|
del self.value[key]
|
|
1355
1525
|
return
|
|
1356
1526
|
except Exception:
|
|
1357
|
-
UserMessage(f
|
|
1527
|
+
UserMessage(f"Key {key} not found in {self.value}", raise_with=Exception)
|
|
1358
1528
|
|
|
1359
1529
|
@core.delitem()
|
|
1360
1530
|
def _func(_, index: str):
|
|
@@ -1362,70 +1532,76 @@ class IterationPrimitives(Primitive):
|
|
|
1362
1532
|
|
|
1363
1533
|
result = _func(self, key)
|
|
1364
1534
|
try:
|
|
1365
|
-
self._value = ASTPostProcessor()(
|
|
1535
|
+
self._value = ASTPostProcessor()(
|
|
1536
|
+
result
|
|
1537
|
+
) # The type of the object that the model changed was a list or a dict
|
|
1366
1538
|
except json.JSONDecodeError:
|
|
1367
|
-
self._value =
|
|
1539
|
+
self._value = (
|
|
1540
|
+
result # It was a string, or something failed (because } wasn't close, etc)
|
|
1541
|
+
)
|
|
1542
|
+
|
|
1368
1543
|
|
|
1369
|
-
|
|
1544
|
+
# @TODO: Add tests for this class
|
|
1370
1545
|
class ValueHandlingPrimitives(Primitive):
|
|
1371
|
-
|
|
1546
|
+
"""
|
|
1372
1547
|
This mixin includes functions responsible for handling symbol values - tokenization, type retrieval, value casting, indexing, etc.
|
|
1373
1548
|
Future functions might include different methods of processing or manipulating the values of symbols, working with metadata of values, etc.
|
|
1374
|
-
|
|
1549
|
+
"""
|
|
1550
|
+
|
|
1375
1551
|
@property
|
|
1376
1552
|
def size(self) -> int:
|
|
1377
|
-
|
|
1553
|
+
"""
|
|
1378
1554
|
Get the size of the container of the Symbol's value.
|
|
1379
1555
|
|
|
1380
1556
|
Returns:
|
|
1381
1557
|
int: The size of the container of the Symbol's value.
|
|
1382
|
-
|
|
1558
|
+
"""
|
|
1383
1559
|
return len(self.value)
|
|
1384
1560
|
|
|
1385
1561
|
@property
|
|
1386
1562
|
def tokens(self) -> int:
|
|
1387
|
-
|
|
1563
|
+
"""
|
|
1388
1564
|
Tokenize the Symbol's value using the tokenizer method.
|
|
1389
1565
|
The tokenizer method is bound to the 'neurosymbolic' engine using the @decorator.bind() decorator.
|
|
1390
1566
|
|
|
1391
1567
|
Returns:
|
|
1392
1568
|
int: The tokenized value of the Symbol.
|
|
1393
|
-
|
|
1569
|
+
"""
|
|
1394
1570
|
return self.tokenizer().encode(str(self))
|
|
1395
1571
|
|
|
1396
|
-
@core_ext.bind(engine=
|
|
1572
|
+
@core_ext.bind(engine="neurosymbolic", property="tokenizer")
|
|
1397
1573
|
def tokenizer(self) -> Callable:
|
|
1398
|
-
|
|
1574
|
+
"""
|
|
1399
1575
|
The tokenizer method.
|
|
1400
1576
|
This method is bound to the 'neurosymbolic' engine using the @decorator.bind() decorator.
|
|
1401
1577
|
|
|
1402
1578
|
Returns:
|
|
1403
1579
|
Callable: The tokenizer.
|
|
1404
|
-
|
|
1580
|
+
"""
|
|
1405
1581
|
pass
|
|
1406
1582
|
|
|
1407
1583
|
@property
|
|
1408
1584
|
def type(self):
|
|
1409
|
-
|
|
1585
|
+
"""
|
|
1410
1586
|
Get the type of the Symbol.
|
|
1411
1587
|
|
|
1412
1588
|
Returns:
|
|
1413
1589
|
type: The type of the Symbol.
|
|
1414
|
-
|
|
1590
|
+
"""
|
|
1415
1591
|
return type(self)
|
|
1416
1592
|
|
|
1417
1593
|
@property
|
|
1418
1594
|
def value_type(self):
|
|
1419
|
-
|
|
1595
|
+
"""
|
|
1420
1596
|
Get the type of the Symbol's value.
|
|
1421
1597
|
|
|
1422
1598
|
Returns:
|
|
1423
1599
|
type: The type of the Symbol's value.
|
|
1424
|
-
|
|
1600
|
+
"""
|
|
1425
1601
|
return type(self.value)
|
|
1426
1602
|
|
|
1427
|
-
def index(self, item: str, **kwargs) ->
|
|
1428
|
-
|
|
1603
|
+
def index(self, item: str, **kwargs) -> "Symbol":
|
|
1604
|
+
"""
|
|
1429
1605
|
Returns the index of a specified item in the symbol value.
|
|
1430
1606
|
Uses the core.getitem decorator to create a _func method that finds the index of the item.
|
|
1431
1607
|
|
|
@@ -1434,19 +1610,22 @@ class ValueHandlingPrimitives(Primitive):
|
|
|
1434
1610
|
|
|
1435
1611
|
Returns:
|
|
1436
1612
|
Symbol: A new symbol with the index of the specified item.
|
|
1437
|
-
|
|
1613
|
+
"""
|
|
1614
|
+
|
|
1438
1615
|
@core.getitem(**kwargs)
|
|
1439
1616
|
def _func(_, item: str) -> int:
|
|
1440
1617
|
pass
|
|
1618
|
+
|
|
1441
1619
|
return self._to_type(_func(self, item))
|
|
1442
1620
|
|
|
1443
1621
|
|
|
1444
1622
|
class StringHelperPrimitives(Primitive):
|
|
1445
|
-
|
|
1623
|
+
"""
|
|
1446
1624
|
This mixin contains functions that provide additional help for symbols or their values.
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1625
|
+
"""
|
|
1626
|
+
|
|
1627
|
+
def split(self, delimiter: str, **_kwargs) -> "Symbol":
|
|
1628
|
+
"""
|
|
1450
1629
|
Splits the symbol value by a specified delimiter.
|
|
1451
1630
|
Uses the core.split decorator to create a _func method that splits the symbol value by the specified delimiter.
|
|
1452
1631
|
|
|
@@ -1455,13 +1634,13 @@ class StringHelperPrimitives(Primitive):
|
|
|
1455
1634
|
|
|
1456
1635
|
Returns:
|
|
1457
1636
|
Symbol: A new symbol with the split value.
|
|
1458
|
-
|
|
1459
|
-
assert isinstance(delimiter, str), f
|
|
1460
|
-
assert isinstance(self.value, str), f
|
|
1637
|
+
"""
|
|
1638
|
+
assert isinstance(delimiter, str), f"delimiter must be a string, got {type(delimiter)}"
|
|
1639
|
+
assert isinstance(self.value, str), f"self.value must be a string, got {type(self.value)}"
|
|
1461
1640
|
return self._to_type([*self.value.split(delimiter)])
|
|
1462
1641
|
|
|
1463
|
-
def join(self, delimiter: str =
|
|
1464
|
-
|
|
1642
|
+
def join(self, delimiter: str = " ", **_kwargs) -> "Symbol":
|
|
1643
|
+
"""
|
|
1465
1644
|
Joins the symbol value with a specified delimiter.
|
|
1466
1645
|
|
|
1467
1646
|
Args:
|
|
@@ -1469,13 +1648,15 @@ class StringHelperPrimitives(Primitive):
|
|
|
1469
1648
|
|
|
1470
1649
|
Returns:
|
|
1471
1650
|
Symbol: A new symbol with the joined str value.
|
|
1472
|
-
|
|
1473
|
-
assert isinstance(delimiter, str),f
|
|
1474
|
-
assert isinstance(self.value, Iterable),
|
|
1651
|
+
"""
|
|
1652
|
+
assert isinstance(delimiter, str), f"delimiter must be a string, got {type(delimiter)}"
|
|
1653
|
+
assert isinstance(self.value, Iterable), (
|
|
1654
|
+
f"value must be an iterable, got {type(self.value)}"
|
|
1655
|
+
)
|
|
1475
1656
|
return self._to_type(delimiter.join(self.value))
|
|
1476
1657
|
|
|
1477
1658
|
def startswith(self, prefix: str, **_kwargs) -> bool:
|
|
1478
|
-
|
|
1659
|
+
"""
|
|
1479
1660
|
Checks if the symbol value starts with a specified prefix.
|
|
1480
1661
|
Uses the core.startswith decorator to create a _func method that checks if the symbol value starts with the specified prefix.
|
|
1481
1662
|
|
|
@@ -1484,9 +1665,9 @@ class StringHelperPrimitives(Primitive):
|
|
|
1484
1665
|
|
|
1485
1666
|
Returns:
|
|
1486
1667
|
bool: True if the symbol value starts with the specified prefix, otherwise False.
|
|
1487
|
-
|
|
1488
|
-
assert isinstance(prefix, str),
|
|
1489
|
-
assert isinstance(self.value, str), f
|
|
1668
|
+
"""
|
|
1669
|
+
assert isinstance(prefix, str), f"prefix must be a string, got {type(prefix)}"
|
|
1670
|
+
assert isinstance(self.value, str), f"self.value must be a string, got {type(self.value)}"
|
|
1490
1671
|
|
|
1491
1672
|
if not self.__semantic__:
|
|
1492
1673
|
return self.value.startswith(prefix)
|
|
@@ -1498,7 +1679,7 @@ class StringHelperPrimitives(Primitive):
|
|
|
1498
1679
|
return _func(self, prefix)
|
|
1499
1680
|
|
|
1500
1681
|
def endswith(self, suffix: str, **_kwargs) -> bool:
|
|
1501
|
-
|
|
1682
|
+
"""
|
|
1502
1683
|
Checks if the symbol value ends with a specified suffix.
|
|
1503
1684
|
Uses the core.endswith decorator to create a _func method that checks if the symbol value ends with the specified suffix.
|
|
1504
1685
|
|
|
@@ -1507,9 +1688,9 @@ class StringHelperPrimitives(Primitive):
|
|
|
1507
1688
|
|
|
1508
1689
|
Returns:
|
|
1509
1690
|
bool: True if the symbol value ends with the specified suffix, otherwise False.
|
|
1510
|
-
|
|
1511
|
-
assert isinstance(suffix, str),
|
|
1512
|
-
assert isinstance(self.value, str), f
|
|
1691
|
+
"""
|
|
1692
|
+
assert isinstance(suffix, str), f"suffix must be a string, got {type(suffix)}"
|
|
1693
|
+
assert isinstance(self.value, str), f"self.value must be a string, got {type(self.value)}"
|
|
1513
1694
|
|
|
1514
1695
|
if not self.__semantic__:
|
|
1515
1696
|
return self.value.endswith(suffix)
|
|
@@ -1522,12 +1703,13 @@ class StringHelperPrimitives(Primitive):
|
|
|
1522
1703
|
|
|
1523
1704
|
|
|
1524
1705
|
class ComparisonPrimitives(Primitive):
|
|
1525
|
-
|
|
1706
|
+
"""
|
|
1526
1707
|
This mixin is dedicated to functions that perform more complex comparison operations between symbols or symbol values.
|
|
1527
1708
|
This usually involves additional context, which the builtin overrode (e.g. __eq__) functions lack.
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1709
|
+
"""
|
|
1710
|
+
|
|
1711
|
+
def equals(self, string: str, context: str = "contextually", **kwargs) -> "Symbol":
|
|
1712
|
+
"""
|
|
1531
1713
|
Checks if the symbol value is equal to another string.
|
|
1532
1714
|
Uses the core.equals decorator to create a _func method that checks for equality in a specific context.
|
|
1533
1715
|
|
|
@@ -1537,7 +1719,8 @@ class ComparisonPrimitives(Primitive):
|
|
|
1537
1719
|
|
|
1538
1720
|
Returns:
|
|
1539
1721
|
Symbol: A new symbol indicating whether the two strings are equal or not.
|
|
1540
|
-
|
|
1722
|
+
"""
|
|
1723
|
+
|
|
1541
1724
|
@core.equals(context=context, **kwargs)
|
|
1542
1725
|
def _func(_, string: str) -> bool:
|
|
1543
1726
|
pass
|
|
@@ -1545,7 +1728,7 @@ class ComparisonPrimitives(Primitive):
|
|
|
1545
1728
|
return self._to_type(_func(self, string))
|
|
1546
1729
|
|
|
1547
1730
|
def contains(self, element: Any, **kwargs) -> bool:
|
|
1548
|
-
|
|
1731
|
+
"""
|
|
1549
1732
|
Uses the @core.contains decorator, checks whether the symbol's value contains the element.
|
|
1550
1733
|
|
|
1551
1734
|
Args:
|
|
@@ -1554,7 +1737,8 @@ class ComparisonPrimitives(Primitive):
|
|
|
1554
1737
|
|
|
1555
1738
|
Returns:
|
|
1556
1739
|
bool: True if the symbol's value contains the element, False otherwise.
|
|
1557
|
-
|
|
1740
|
+
"""
|
|
1741
|
+
|
|
1558
1742
|
@core.contains(**kwargs)
|
|
1559
1743
|
def _func(_, other) -> bool:
|
|
1560
1744
|
pass
|
|
@@ -1562,7 +1746,7 @@ class ComparisonPrimitives(Primitive):
|
|
|
1562
1746
|
return _func(self, element)
|
|
1563
1747
|
|
|
1564
1748
|
def isinstanceof(self, query: str, **kwargs) -> bool:
|
|
1565
|
-
|
|
1749
|
+
"""
|
|
1566
1750
|
Check if the current Symbol is an instance of a specific type.
|
|
1567
1751
|
|
|
1568
1752
|
Args:
|
|
@@ -1571,7 +1755,8 @@ class ComparisonPrimitives(Primitive):
|
|
|
1571
1755
|
|
|
1572
1756
|
Returns:
|
|
1573
1757
|
bool: True if the current Symbol is an instance of the specified type, otherwise False.
|
|
1574
|
-
|
|
1758
|
+
"""
|
|
1759
|
+
|
|
1575
1760
|
@core.isinstanceof()
|
|
1576
1761
|
def _func(_, query: str, **kwargs) -> bool:
|
|
1577
1762
|
pass
|
|
@@ -1580,35 +1765,41 @@ class ComparisonPrimitives(Primitive):
|
|
|
1580
1765
|
|
|
1581
1766
|
|
|
1582
1767
|
class ExpressionHandlingPrimitives(Primitive):
|
|
1583
|
-
|
|
1768
|
+
"""
|
|
1584
1769
|
This mixin consists of functions that handle symbolic expressions - evaluations, parsing, computation and more.
|
|
1585
1770
|
Future functionalities in this mixin might include operations to manipulate expressions, more complex evaluation techniques, etc.
|
|
1586
|
-
|
|
1771
|
+
"""
|
|
1772
|
+
|
|
1587
1773
|
def __init__(self, *args, **kwargs):
|
|
1588
1774
|
super().__init__(*args, **kwargs)
|
|
1589
1775
|
|
|
1590
1776
|
def init_results(self):
|
|
1591
1777
|
"""Ensures _accumulated_results exists, initializing if needed."""
|
|
1592
|
-
if not hasattr(self,
|
|
1778
|
+
if not hasattr(self, "_accumulated_results"):
|
|
1593
1779
|
self._accumulated_results = []
|
|
1594
1780
|
|
|
1595
|
-
def get_results(self) -> list[
|
|
1596
|
-
|
|
1781
|
+
def get_results(self) -> list["Symbol"]:
|
|
1782
|
+
"""
|
|
1597
1783
|
Retrieves accumulated results from previous interpretations.
|
|
1598
1784
|
|
|
1599
1785
|
Returns:
|
|
1600
1786
|
List[Symbol]: List of accumulated results
|
|
1601
|
-
|
|
1787
|
+
"""
|
|
1602
1788
|
self.init_results()
|
|
1603
1789
|
return self._accumulated_results
|
|
1604
1790
|
|
|
1605
1791
|
def clear_results(self):
|
|
1606
|
-
|
|
1792
|
+
"""Clears the accumulated results"""
|
|
1607
1793
|
self.init_results()
|
|
1608
1794
|
self._accumulated_results = []
|
|
1609
1795
|
|
|
1610
|
-
def interpret(
|
|
1611
|
-
|
|
1796
|
+
def interpret(
|
|
1797
|
+
self,
|
|
1798
|
+
prompt: str | None = "Evaluate the symbolic expressions and return only the result:\n",
|
|
1799
|
+
accumulate: bool = False,
|
|
1800
|
+
**kwargs,
|
|
1801
|
+
) -> "Symbol":
|
|
1802
|
+
"""
|
|
1612
1803
|
Evaluates simple symbolic expressions.
|
|
1613
1804
|
Uses the core.expression decorator to create a _func method that evaluates the given expression.
|
|
1614
1805
|
|
|
@@ -1619,9 +1810,9 @@ class ExpressionHandlingPrimitives(Primitive):
|
|
|
1619
1810
|
|
|
1620
1811
|
Returns:
|
|
1621
1812
|
Symbol: A new symbol with the result of the expression evaluation.
|
|
1622
|
-
|
|
1813
|
+
"""
|
|
1623
1814
|
# Propagate original input
|
|
1624
|
-
input_value = getattr(self,
|
|
1815
|
+
input_value = getattr(self, "_input", self) if hasattr(self, "_input") else self
|
|
1625
1816
|
|
|
1626
1817
|
@core.interpret(prompt=prompt, **kwargs)
|
|
1627
1818
|
def _func(_):
|
|
@@ -1639,26 +1830,28 @@ class ExpressionHandlingPrimitives(Primitive):
|
|
|
1639
1830
|
|
|
1640
1831
|
|
|
1641
1832
|
class DataHandlingPrimitives(Primitive):
|
|
1642
|
-
|
|
1833
|
+
"""
|
|
1643
1834
|
This mixin houses functions that clean, summarize and outline symbols or their values.
|
|
1644
1835
|
Future implementations in this mixin may include various other cleaning and summarization techniques, error detection/correction in symbols, complex filtering, bulk modifications, or other types of condition-based manipulations on symbols, etc.
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1836
|
+
"""
|
|
1837
|
+
|
|
1838
|
+
def clean(self, **kwargs) -> "Symbol":
|
|
1839
|
+
"""
|
|
1648
1840
|
Cleans the symbol value.
|
|
1649
1841
|
Uses the core.clean decorator to create a _func method that cleans the symbol value.
|
|
1650
1842
|
|
|
1651
1843
|
Returns:
|
|
1652
1844
|
Symbol: A new symbol with the cleaned value.
|
|
1653
|
-
|
|
1845
|
+
"""
|
|
1846
|
+
|
|
1654
1847
|
@core.clean(**kwargs)
|
|
1655
1848
|
def _func(_) -> str:
|
|
1656
1849
|
pass
|
|
1657
1850
|
|
|
1658
1851
|
return self._to_type(_func(self))
|
|
1659
1852
|
|
|
1660
|
-
def summarize(self, context: str | None = None, **kwargs) ->
|
|
1661
|
-
|
|
1853
|
+
def summarize(self, context: str | None = None, **kwargs) -> "Symbol":
|
|
1854
|
+
"""
|
|
1662
1855
|
Summarizes the symbol value.
|
|
1663
1856
|
Uses the core.summarize decorator with an optional context to create a _func method that summarizes the symbol value.
|
|
1664
1857
|
|
|
@@ -1667,29 +1860,31 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1667
1860
|
|
|
1668
1861
|
Returns:
|
|
1669
1862
|
Symbol: A new symbol with the summarized value.
|
|
1670
|
-
|
|
1863
|
+
"""
|
|
1864
|
+
|
|
1671
1865
|
@core.summarize(context=context, **kwargs)
|
|
1672
1866
|
def _func(_) -> str:
|
|
1673
1867
|
pass
|
|
1674
1868
|
|
|
1675
1869
|
return self._to_type(_func(self))
|
|
1676
1870
|
|
|
1677
|
-
def outline(self, **kwargs) ->
|
|
1678
|
-
|
|
1871
|
+
def outline(self, **kwargs) -> "Symbol":
|
|
1872
|
+
"""
|
|
1679
1873
|
Creates an outline of the symbol value.
|
|
1680
1874
|
Uses the core.outline decorator to create a _func method that generates an outline of the symbol value.
|
|
1681
1875
|
|
|
1682
1876
|
Returns:
|
|
1683
1877
|
Symbol: A new symbol with the outline of the value.
|
|
1684
|
-
|
|
1878
|
+
"""
|
|
1879
|
+
|
|
1685
1880
|
@core.outline(**kwargs)
|
|
1686
1881
|
def _func(_) -> str:
|
|
1687
1882
|
pass
|
|
1688
1883
|
|
|
1689
1884
|
return self._to_type(_func(self))
|
|
1690
1885
|
|
|
1691
|
-
def filter(self, criteria: str, include: bool | None = False, **kwargs) ->
|
|
1692
|
-
|
|
1886
|
+
def filter(self, criteria: str, include: bool | None = False, **kwargs) -> "Symbol":
|
|
1887
|
+
"""
|
|
1693
1888
|
Filters the symbol value based on a specified criteria.
|
|
1694
1889
|
Uses the core.filtering decorator with the provided criteria and include flag to create a _func method to filter the symbol value.
|
|
1695
1890
|
|
|
@@ -1699,15 +1894,16 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1699
1894
|
|
|
1700
1895
|
Returns:
|
|
1701
1896
|
Symbol: A new symbol with the filtered value.
|
|
1702
|
-
|
|
1897
|
+
"""
|
|
1898
|
+
|
|
1703
1899
|
@core.filtering(criteria=criteria, include=include, **kwargs)
|
|
1704
1900
|
def _func(_) -> str:
|
|
1705
1901
|
pass
|
|
1706
1902
|
|
|
1707
1903
|
return self._to_type(_func(self))
|
|
1708
1904
|
|
|
1709
|
-
def map(self, instruction: str, **kwargs) ->
|
|
1710
|
-
|
|
1905
|
+
def map(self, instruction: str, **kwargs) -> "Symbol":
|
|
1906
|
+
"""
|
|
1711
1907
|
Applies a semantic transformation instruction to each element in an iterable.
|
|
1712
1908
|
This method transforms each element based on the provided instruction while preserving
|
|
1713
1909
|
elements that don't match the transformation criteria.
|
|
@@ -1721,11 +1917,11 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1721
1917
|
|
|
1722
1918
|
Raises:
|
|
1723
1919
|
AssertionError: If the Symbol's value is not iterable or is an unsupported type
|
|
1724
|
-
|
|
1920
|
+
"""
|
|
1725
1921
|
try:
|
|
1726
1922
|
iter(self.value)
|
|
1727
1923
|
except TypeError:
|
|
1728
|
-
UserMessage(
|
|
1924
|
+
UserMessage("Map can only be applied to iterable objects", raise_with=AssertionError)
|
|
1729
1925
|
|
|
1730
1926
|
@core.map(instruction=instruction, **kwargs)
|
|
1731
1927
|
def _func(_):
|
|
@@ -1733,8 +1929,8 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1733
1929
|
|
|
1734
1930
|
return self._to_type(_func(self))
|
|
1735
1931
|
|
|
1736
|
-
def modify(self, changes: str, **kwargs) ->
|
|
1737
|
-
|
|
1932
|
+
def modify(self, changes: str, **kwargs) -> "Symbol":
|
|
1933
|
+
"""
|
|
1738
1934
|
Modifies the symbol value based on the specified changes.
|
|
1739
1935
|
Uses the core.modify decorator with the provided changes to create a _func method to modify the symbol value.
|
|
1740
1936
|
|
|
@@ -1743,15 +1939,16 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1743
1939
|
|
|
1744
1940
|
Returns:
|
|
1745
1941
|
Symbol: A new symbol with the modified value.
|
|
1746
|
-
|
|
1942
|
+
"""
|
|
1943
|
+
|
|
1747
1944
|
@core.modify(changes=changes, **kwargs)
|
|
1748
1945
|
def _func(_) -> str:
|
|
1749
1946
|
pass
|
|
1750
1947
|
|
|
1751
1948
|
return self._to_type(_func(self))
|
|
1752
1949
|
|
|
1753
|
-
def replace(self, old: str, new: str, **kwargs) ->
|
|
1754
|
-
|
|
1950
|
+
def replace(self, old: str, new: str, **kwargs) -> "Symbol":
|
|
1951
|
+
"""
|
|
1755
1952
|
Replaces one value in the symbol value with another.
|
|
1756
1953
|
Uses the core.replace decorator to create a _func method that replaces the values in the symbol value.
|
|
1757
1954
|
|
|
@@ -1761,15 +1958,16 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1761
1958
|
|
|
1762
1959
|
Returns:
|
|
1763
1960
|
Symbol: A new symbol with the replaced value.
|
|
1764
|
-
|
|
1961
|
+
"""
|
|
1962
|
+
|
|
1765
1963
|
@core.replace(**kwargs)
|
|
1766
1964
|
def _func(_, old: str, new: str):
|
|
1767
1965
|
pass
|
|
1768
1966
|
|
|
1769
1967
|
return self._to_type(_func(self, old, new))
|
|
1770
1968
|
|
|
1771
|
-
def remove(self, information: str, **kwargs) ->
|
|
1772
|
-
|
|
1969
|
+
def remove(self, information: str, **kwargs) -> "Symbol":
|
|
1970
|
+
"""
|
|
1773
1971
|
Removes a specified piece of information from the symbol value.
|
|
1774
1972
|
Uses the core.replace decorator to create a _func method that removes the specified information.
|
|
1775
1973
|
|
|
@@ -1778,15 +1976,16 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1778
1976
|
|
|
1779
1977
|
Returns:
|
|
1780
1978
|
Symbol: A new symbol with the removed information.
|
|
1781
|
-
|
|
1979
|
+
"""
|
|
1980
|
+
|
|
1782
1981
|
@core.replace(**kwargs)
|
|
1783
1982
|
def _func(_, text: str, replace: str, value: str):
|
|
1784
1983
|
pass
|
|
1785
1984
|
|
|
1786
|
-
return self._to_type(_func(self, information,
|
|
1985
|
+
return self._to_type(_func(self, information, ""))
|
|
1787
1986
|
|
|
1788
|
-
def include(self, information: str, **kwargs) ->
|
|
1789
|
-
|
|
1987
|
+
def include(self, information: str, **kwargs) -> "Symbol":
|
|
1988
|
+
"""
|
|
1790
1989
|
Includes a specified piece of information in the symbol value.
|
|
1791
1990
|
Uses the core.include decorator to create a _func method that includes the specified information.
|
|
1792
1991
|
|
|
@@ -1795,15 +1994,16 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1795
1994
|
|
|
1796
1995
|
Returns:
|
|
1797
1996
|
Symbol: A new symbol with the included information.
|
|
1798
|
-
|
|
1997
|
+
"""
|
|
1998
|
+
|
|
1799
1999
|
@core.include(**kwargs)
|
|
1800
2000
|
def _func(_, information: str):
|
|
1801
2001
|
pass
|
|
1802
2002
|
|
|
1803
2003
|
return self._to_type(_func(self, information))
|
|
1804
2004
|
|
|
1805
|
-
def combine(self, information: str, **kwargs) ->
|
|
1806
|
-
|
|
2005
|
+
def combine(self, information: str, **kwargs) -> "Symbol":
|
|
2006
|
+
"""
|
|
1807
2007
|
Combines the current symbol value with another string.
|
|
1808
2008
|
Uses the core.combine decorator to create a _func method that combines the symbol value with another string.
|
|
1809
2009
|
|
|
@@ -1812,7 +2012,8 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1812
2012
|
|
|
1813
2013
|
Returns:
|
|
1814
2014
|
Symbol: A new symbol with the combined value.
|
|
1815
|
-
|
|
2015
|
+
"""
|
|
2016
|
+
|
|
1816
2017
|
@core.combine(**kwargs)
|
|
1817
2018
|
def _func(_, a: str, b: str):
|
|
1818
2019
|
pass
|
|
@@ -1821,12 +2022,13 @@ class DataHandlingPrimitives(Primitive):
|
|
|
1821
2022
|
|
|
1822
2023
|
|
|
1823
2024
|
class UniquenessPrimitives(Primitive):
|
|
1824
|
-
|
|
2025
|
+
"""
|
|
1825
2026
|
This mixin includes functions that work with unique aspects of symbol values, like extracting unique information or composing new unique symbols.
|
|
1826
2027
|
Future functionalities might include finding duplicate information, defining levels of uniqueness, etc.
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
2028
|
+
"""
|
|
2029
|
+
|
|
2030
|
+
def unique(self, keys: list[str] | None = None, **kwargs) -> "Symbol":
|
|
2031
|
+
"""
|
|
1830
2032
|
Extracts unique information from the symbol value, using provided keys.
|
|
1831
2033
|
Uses the core.unique decorator with a list of keys to create a _func method that extracts unique data from the symbol value.
|
|
1832
2034
|
|
|
@@ -1835,23 +2037,25 @@ class UniquenessPrimitives(Primitive):
|
|
|
1835
2037
|
|
|
1836
2038
|
Returns:
|
|
1837
2039
|
Symbol: A new symbol with the unique information.
|
|
1838
|
-
|
|
2040
|
+
"""
|
|
1839
2041
|
if keys is None:
|
|
1840
2042
|
keys = []
|
|
2043
|
+
|
|
1841
2044
|
@core.unique(keys=keys, **kwargs)
|
|
1842
2045
|
def _func(_) -> str:
|
|
1843
2046
|
pass
|
|
1844
2047
|
|
|
1845
2048
|
return self._to_type(_func(self))
|
|
1846
2049
|
|
|
1847
|
-
def compose(self, **kwargs) ->
|
|
1848
|
-
|
|
2050
|
+
def compose(self, **kwargs) -> "Symbol":
|
|
2051
|
+
"""
|
|
1849
2052
|
Composes a text based on the symbol value.
|
|
1850
2053
|
Uses the core.compose decorator to create a _func method that composes a text using the symbol value.
|
|
1851
2054
|
|
|
1852
2055
|
Returns:
|
|
1853
2056
|
Symbol: A new symbol with the composed text.
|
|
1854
|
-
|
|
2057
|
+
"""
|
|
2058
|
+
|
|
1855
2059
|
@core.compose(**kwargs)
|
|
1856
2060
|
def _func(_) -> str:
|
|
1857
2061
|
pass
|
|
@@ -1860,12 +2064,15 @@ class UniquenessPrimitives(Primitive):
|
|
|
1860
2064
|
|
|
1861
2065
|
|
|
1862
2066
|
class PatternMatchingPrimitives(Primitive):
|
|
1863
|
-
|
|
2067
|
+
"""
|
|
1864
2068
|
This mixin houses functions that deal with ranking symbols, extracting details based on patterns, and correcting symbols.
|
|
1865
2069
|
It will house future functionalities that involve sorting, complex pattern detections, advanced correction techniques etc.
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
2070
|
+
"""
|
|
2071
|
+
|
|
2072
|
+
def rank(
|
|
2073
|
+
self, measure: str | None = "alphanumeric", order: str | None = "desc", **kwargs
|
|
2074
|
+
) -> "Symbol":
|
|
2075
|
+
"""
|
|
1869
2076
|
Ranks the symbol value based on a measure and a sort order.
|
|
1870
2077
|
Uses the core.rank decorator with the specified measure and order to create a _func method that ranks the symbol value.
|
|
1871
2078
|
|
|
@@ -1876,15 +2083,16 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1876
2083
|
|
|
1877
2084
|
Returns:
|
|
1878
2085
|
Symbol: A new symbol with the ranked value.
|
|
1879
|
-
|
|
2086
|
+
"""
|
|
2087
|
+
|
|
1880
2088
|
@core.rank(order=order, **kwargs)
|
|
1881
2089
|
def _func(_, measure: str) -> str:
|
|
1882
2090
|
pass
|
|
1883
2091
|
|
|
1884
2092
|
return self._to_type(_func(self, measure))
|
|
1885
2093
|
|
|
1886
|
-
def extract(self, pattern: str, **kwargs) ->
|
|
1887
|
-
|
|
2094
|
+
def extract(self, pattern: str, **kwargs) -> "Symbol":
|
|
2095
|
+
"""
|
|
1888
2096
|
Extracts data from the symbol value based on a pattern.
|
|
1889
2097
|
Uses the core.extract decorator with the specified pattern to create a _func method that extracts data from the symbol value.
|
|
1890
2098
|
|
|
@@ -1893,15 +2101,16 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1893
2101
|
|
|
1894
2102
|
Returns:
|
|
1895
2103
|
Symbol: A new symbol with the extracted data.
|
|
1896
|
-
|
|
2104
|
+
"""
|
|
2105
|
+
|
|
1897
2106
|
@core.extract(**kwargs)
|
|
1898
2107
|
def _func(_, pattern: str) -> str:
|
|
1899
2108
|
pass
|
|
1900
2109
|
|
|
1901
2110
|
return self._to_type(_func(self, pattern))
|
|
1902
2111
|
|
|
1903
|
-
def correct(self, context: str, exception: Exception, **kwargs) ->
|
|
1904
|
-
|
|
2112
|
+
def correct(self, context: str, exception: Exception, **kwargs) -> "Symbol":
|
|
2113
|
+
"""
|
|
1905
2114
|
Corrects the symbol value based on a specified context.
|
|
1906
2115
|
Uses the @core.correct decorator, corrects the value of the symbol based on the given context.
|
|
1907
2116
|
|
|
@@ -1912,15 +2121,16 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1912
2121
|
|
|
1913
2122
|
Returns:
|
|
1914
2123
|
Symbol: The corrected value as a Symbol.
|
|
1915
|
-
|
|
2124
|
+
"""
|
|
2125
|
+
|
|
1916
2126
|
@core.correct(context=context, exception=exception, **kwargs)
|
|
1917
2127
|
def _func(_) -> str:
|
|
1918
2128
|
pass
|
|
1919
2129
|
|
|
1920
2130
|
return self._to_type(_func(self))
|
|
1921
2131
|
|
|
1922
|
-
def translate(self, language: str | None =
|
|
1923
|
-
|
|
2132
|
+
def translate(self, language: str | None = "English", **kwargs) -> "Symbol":
|
|
2133
|
+
"""
|
|
1924
2134
|
Translates the symbol value to the specified language.
|
|
1925
2135
|
Uses the @core.translate decorator to translate the symbol's value to the specified language.
|
|
1926
2136
|
|
|
@@ -1930,15 +2140,16 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1930
2140
|
|
|
1931
2141
|
Returns:
|
|
1932
2142
|
Symbol: The translated value as a Symbol.
|
|
1933
|
-
|
|
2143
|
+
"""
|
|
2144
|
+
|
|
1934
2145
|
@core.translate(language=language, **kwargs)
|
|
1935
2146
|
def _func(_) -> str:
|
|
1936
2147
|
pass
|
|
1937
2148
|
|
|
1938
2149
|
return self._to_type(_func(self))
|
|
1939
2150
|
|
|
1940
|
-
def choice(self, cases: list[str], default: str, **kwargs) ->
|
|
1941
|
-
|
|
2151
|
+
def choice(self, cases: list[str], default: str, **kwargs) -> "Symbol":
|
|
2152
|
+
"""
|
|
1942
2153
|
Chooses one of the cases based on the symbol value.
|
|
1943
2154
|
Uses the @core.case decorator, selects one of the cases based on the symbol's value.
|
|
1944
2155
|
|
|
@@ -1949,7 +2160,8 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1949
2160
|
|
|
1950
2161
|
Returns:
|
|
1951
2162
|
Symbol: The chosen case as a Symbol.
|
|
1952
|
-
|
|
2163
|
+
"""
|
|
2164
|
+
|
|
1953
2165
|
@core.case(enum=cases, default=default, **kwargs)
|
|
1954
2166
|
def _func(_) -> str:
|
|
1955
2167
|
pass
|
|
@@ -1958,12 +2170,19 @@ class PatternMatchingPrimitives(Primitive):
|
|
|
1958
2170
|
|
|
1959
2171
|
|
|
1960
2172
|
class QueryHandlingPrimitives(Primitive):
|
|
1961
|
-
|
|
2173
|
+
"""
|
|
1962
2174
|
This mixin helps in transforming, preparing, and executing queries, and it is designed to be extendable as new ways of handling queries are developed.
|
|
1963
2175
|
Future methods could potentially include query optimization, enhanced query formatting, multi-level query execution, query error handling, etc.
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2176
|
+
"""
|
|
2177
|
+
|
|
2178
|
+
def query(
|
|
2179
|
+
self,
|
|
2180
|
+
context: str,
|
|
2181
|
+
prompt: str | None = None,
|
|
2182
|
+
examples: list[Prompt] | None = None,
|
|
2183
|
+
**kwargs,
|
|
2184
|
+
) -> "Symbol":
|
|
2185
|
+
"""
|
|
1967
2186
|
Queries the symbol value based on a specified context.
|
|
1968
2187
|
Uses the @core.query decorator, queries based on the context, prompt, and examples.
|
|
1969
2188
|
|
|
@@ -1975,15 +2194,16 @@ class QueryHandlingPrimitives(Primitive):
|
|
|
1975
2194
|
|
|
1976
2195
|
Returns:
|
|
1977
2196
|
Symbol: The result of the query as a Symbol.
|
|
1978
|
-
|
|
2197
|
+
"""
|
|
2198
|
+
|
|
1979
2199
|
@core.query(context=context, prompt=prompt, examples=examples, **kwargs)
|
|
1980
2200
|
def _func(_) -> str:
|
|
1981
2201
|
pass
|
|
1982
2202
|
|
|
1983
2203
|
return self._to_type(_func(self))
|
|
1984
2204
|
|
|
1985
|
-
def convert(self, format: str, **kwargs) ->
|
|
1986
|
-
|
|
2205
|
+
def convert(self, format: str, **kwargs) -> "Symbol":
|
|
2206
|
+
"""
|
|
1987
2207
|
Converts the symbol value to the specified format.
|
|
1988
2208
|
Uses the @core.convert decorator, converts the symbol's value to the specified format.
|
|
1989
2209
|
|
|
@@ -1993,15 +2213,16 @@ class QueryHandlingPrimitives(Primitive):
|
|
|
1993
2213
|
|
|
1994
2214
|
Returns:
|
|
1995
2215
|
Symbol: The converted value as a Symbol.
|
|
1996
|
-
|
|
2216
|
+
"""
|
|
2217
|
+
|
|
1997
2218
|
@core.convert(format=format, **kwargs)
|
|
1998
2219
|
def _func(_) -> str:
|
|
1999
2220
|
pass
|
|
2000
2221
|
|
|
2001
2222
|
return self._to_type(_func(self))
|
|
2002
2223
|
|
|
2003
|
-
def transcribe(self, modify: str, **kwargs) ->
|
|
2004
|
-
|
|
2224
|
+
def transcribe(self, modify: str, **kwargs) -> "Symbol":
|
|
2225
|
+
"""
|
|
2005
2226
|
Transcribes the symbol value based on a specified modification.
|
|
2006
2227
|
Uses the @core.transcribe decorator, modifies the symbol's value based on the modify parameter.
|
|
2007
2228
|
|
|
@@ -2011,7 +2232,8 @@ class QueryHandlingPrimitives(Primitive):
|
|
|
2011
2232
|
|
|
2012
2233
|
Returns:
|
|
2013
2234
|
Symbol: The modified value as a Symbol.
|
|
2014
|
-
|
|
2235
|
+
"""
|
|
2236
|
+
|
|
2015
2237
|
@core.transcribe(modify=modify, **kwargs)
|
|
2016
2238
|
def _func(_) -> str:
|
|
2017
2239
|
pass
|
|
@@ -2020,12 +2242,13 @@ class QueryHandlingPrimitives(Primitive):
|
|
|
2020
2242
|
|
|
2021
2243
|
|
|
2022
2244
|
class ExecutionControlPrimitives(Primitive):
|
|
2023
|
-
|
|
2245
|
+
"""
|
|
2024
2246
|
This mixin represents the core methods for dealing with symbol execution.
|
|
2025
2247
|
Possible future methods could potentially include async execution, pipeline chaining, execution profiling, improved error handling, version management, embedding more complex execution control structures etc.
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2248
|
+
"""
|
|
2249
|
+
|
|
2250
|
+
def analyze(self, exception: Exception, query: str | None = "", **kwargs) -> "Symbol":
|
|
2251
|
+
"""Uses the @core.analyze decorator, analyzes an exception and returns a symbol.
|
|
2029
2252
|
|
|
2030
2253
|
Args:
|
|
2031
2254
|
exception (Exception): The exception to be analyzed.
|
|
@@ -2034,15 +2257,16 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2034
2257
|
|
|
2035
2258
|
Returns:
|
|
2036
2259
|
Symbol: The analyzed result as a Symbol.
|
|
2037
|
-
|
|
2260
|
+
"""
|
|
2261
|
+
|
|
2038
2262
|
@core.analyze(exception=exception, query=query, **kwargs)
|
|
2039
2263
|
def _func(_) -> str:
|
|
2040
2264
|
pass
|
|
2041
2265
|
|
|
2042
2266
|
return self._to_type(_func(self))
|
|
2043
2267
|
|
|
2044
|
-
def execute(self, **kwargs) ->
|
|
2045
|
-
|
|
2268
|
+
def execute(self, **kwargs) -> "Symbol":
|
|
2269
|
+
"""
|
|
2046
2270
|
Executes the symbol's expression using the @core.execute decorator.
|
|
2047
2271
|
|
|
2048
2272
|
Args:
|
|
@@ -2050,15 +2274,16 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2050
2274
|
|
|
2051
2275
|
Returns:
|
|
2052
2276
|
Symbol: The result of the executed expression as a Symbol.
|
|
2053
|
-
|
|
2277
|
+
"""
|
|
2278
|
+
|
|
2054
2279
|
@core.execute(**kwargs)
|
|
2055
2280
|
def _func(_):
|
|
2056
2281
|
pass
|
|
2057
2282
|
|
|
2058
2283
|
return _func(self)
|
|
2059
2284
|
|
|
2060
|
-
def fexecute(self, **kwargs) ->
|
|
2061
|
-
|
|
2285
|
+
def fexecute(self, **kwargs) -> "Symbol":
|
|
2286
|
+
"""
|
|
2062
2287
|
Executes the symbol's expression using the fallback execute method (ftry).
|
|
2063
2288
|
|
|
2064
2289
|
Args:
|
|
@@ -2066,14 +2291,15 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2066
2291
|
|
|
2067
2292
|
Returns:
|
|
2068
2293
|
Symbol: The result of the executed expression as a Symbol.
|
|
2069
|
-
|
|
2070
|
-
|
|
2294
|
+
"""
|
|
2295
|
+
|
|
2296
|
+
def _func(sym: "Symbol", **kargs):
|
|
2071
2297
|
return sym.execute(**kargs)
|
|
2072
2298
|
|
|
2073
2299
|
return self.ftry(_func, **kwargs)
|
|
2074
2300
|
|
|
2075
|
-
def simulate(self, **kwargs) ->
|
|
2076
|
-
|
|
2301
|
+
def simulate(self, **kwargs) -> "Symbol":
|
|
2302
|
+
"""
|
|
2077
2303
|
Uses the @core.simulate decorator, simulates the value of the symbol. Used for hypothesis testing or code simulation.
|
|
2078
2304
|
|
|
2079
2305
|
Args:
|
|
@@ -2081,15 +2307,16 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2081
2307
|
|
|
2082
2308
|
Returns:
|
|
2083
2309
|
Symbol: The simulated value as a Symbol.
|
|
2084
|
-
|
|
2310
|
+
"""
|
|
2311
|
+
|
|
2085
2312
|
@core.simulate(**kwargs)
|
|
2086
2313
|
def _func(_):
|
|
2087
2314
|
pass
|
|
2088
2315
|
|
|
2089
2316
|
return self._to_type(_func(self))
|
|
2090
2317
|
|
|
2091
|
-
def sufficient(self, query: str, **kwargs) ->
|
|
2092
|
-
|
|
2318
|
+
def sufficient(self, query: str, **kwargs) -> "Symbol":
|
|
2319
|
+
"""
|
|
2093
2320
|
Uses the @core.sufficient decorator and checks if the symbol's value is sufficient based on the query.
|
|
2094
2321
|
|
|
2095
2322
|
Args:
|
|
@@ -2098,15 +2325,18 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2098
2325
|
|
|
2099
2326
|
Returns:
|
|
2100
2327
|
Symbol: The sufficiency result as a Symbol.
|
|
2101
|
-
|
|
2328
|
+
"""
|
|
2329
|
+
|
|
2102
2330
|
@core.sufficient(query=query, **kwargs)
|
|
2103
2331
|
def _func(_) -> bool:
|
|
2104
2332
|
pass
|
|
2105
2333
|
|
|
2106
2334
|
return self._to_type(_func(self))
|
|
2107
2335
|
|
|
2108
|
-
def list(
|
|
2109
|
-
|
|
2336
|
+
def list(
|
|
2337
|
+
self, condition: str, **kwargs
|
|
2338
|
+
) -> "Symbol": # @TODO: can't filter directly handle this case?
|
|
2339
|
+
"""
|
|
2110
2340
|
Uses the @core.listing decorator and lists elements based on the condition.
|
|
2111
2341
|
|
|
2112
2342
|
Args:
|
|
@@ -2115,15 +2345,16 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2115
2345
|
|
|
2116
2346
|
Returns:
|
|
2117
2347
|
Symbol: The filtered list as a Symbol.
|
|
2118
|
-
|
|
2348
|
+
"""
|
|
2349
|
+
|
|
2119
2350
|
@core.listing(condition=condition, **kwargs)
|
|
2120
2351
|
def _func(_) -> list:
|
|
2121
2352
|
pass
|
|
2122
2353
|
|
|
2123
2354
|
return self._to_type(_func(self))
|
|
2124
2355
|
|
|
2125
|
-
def foreach(self, condition: str, apply: str, **kwargs) ->
|
|
2126
|
-
|
|
2356
|
+
def foreach(self, condition: str, apply: str, **kwargs) -> "Symbol":
|
|
2357
|
+
"""
|
|
2127
2358
|
Uses the @core.foreach decorator, iterates through the symbol's value, and applies the provided functionality.
|
|
2128
2359
|
|
|
2129
2360
|
Args:
|
|
@@ -2133,15 +2364,16 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2133
2364
|
|
|
2134
2365
|
Returns:
|
|
2135
2366
|
Symbol: The result of the iterative application of the function as a Symbol.
|
|
2136
|
-
|
|
2367
|
+
"""
|
|
2368
|
+
|
|
2137
2369
|
@core.foreach(condition=condition, apply=apply, **kwargs)
|
|
2138
2370
|
def _func(_):
|
|
2139
2371
|
pass
|
|
2140
2372
|
|
|
2141
2373
|
return self._to_type(_func(self))
|
|
2142
2374
|
|
|
2143
|
-
def stream(self, expr:
|
|
2144
|
-
|
|
2375
|
+
def stream(self, expr: "Expression", token_ratio: float | None = 0.6, **kwargs) -> "Symbol":
|
|
2376
|
+
"""
|
|
2145
2377
|
Streams the Symbol's value through an Expression object.
|
|
2146
2378
|
This method divides the Symbol's value into chunks and processes each chunk through the given Expression object.
|
|
2147
2379
|
It is useful for processing large strings in smaller parts.
|
|
@@ -2156,9 +2388,11 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2156
2388
|
|
|
2157
2389
|
Raises:
|
|
2158
2390
|
ValueError: If the Expression object exceeds the maximum allowed tokens.
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2391
|
+
"""
|
|
2392
|
+
|
|
2393
|
+
@core_ext.bind(engine="neurosymbolic", property="max_context_tokens")
|
|
2394
|
+
def _max_tokens(_):
|
|
2395
|
+
pass
|
|
2162
2396
|
|
|
2163
2397
|
max_ctxt_tokens = int(_max_tokens(self) * token_ratio)
|
|
2164
2398
|
prev = expr(self, preview=True, **kwargs)
|
|
@@ -2168,7 +2402,7 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2168
2402
|
n_splits = (len(prev) // max_ctxt_tokens) + 1
|
|
2169
2403
|
|
|
2170
2404
|
for i in range(n_splits):
|
|
2171
|
-
tokens_sliced = self.tokens[i * max_ctxt_tokens: (i + 1) * max_ctxt_tokens]
|
|
2405
|
+
tokens_sliced = self.tokens[i * max_ctxt_tokens : (i + 1) * max_ctxt_tokens]
|
|
2172
2406
|
r = self._to_type(self.tokenizer().decode(tokens_sliced))
|
|
2173
2407
|
|
|
2174
2408
|
yield expr(r, **kwargs)
|
|
@@ -2176,9 +2410,9 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2176
2410
|
else:
|
|
2177
2411
|
yield expr(self, **kwargs)
|
|
2178
2412
|
|
|
2179
|
-
def ftry(self, expr:
|
|
2413
|
+
def ftry(self, expr: "Expression", retries: int | None = 1, **kwargs) -> "Symbol":
|
|
2180
2414
|
# TODO: find a way to pass on the constraints and behavior from the self.expr to the corrected code
|
|
2181
|
-
|
|
2415
|
+
"""
|
|
2182
2416
|
Tries to evaluate a Symbol using a given Expression.
|
|
2183
2417
|
This method evaluates a Symbol using a given Expression.
|
|
2184
2418
|
If it fails, it retries the evaluation a specified number of times.
|
|
@@ -2193,23 +2427,23 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2193
2427
|
|
|
2194
2428
|
Raises:
|
|
2195
2429
|
Exception: If the evaluation fails after all retries.
|
|
2196
|
-
|
|
2197
|
-
prompt = {
|
|
2430
|
+
"""
|
|
2431
|
+
prompt = {"out_msg": ""}
|
|
2198
2432
|
|
|
2199
2433
|
def output_handler(input_):
|
|
2200
|
-
prompt[
|
|
2434
|
+
prompt["out_msg"] = input_
|
|
2201
2435
|
|
|
2202
|
-
kwargs[
|
|
2436
|
+
kwargs["output_handler"] = output_handler
|
|
2203
2437
|
retry_cnt: int = 0
|
|
2204
|
-
code = self
|
|
2438
|
+
code = self # original input
|
|
2205
2439
|
|
|
2206
|
-
if hasattr(expr,
|
|
2207
|
-
prompt[
|
|
2440
|
+
if hasattr(expr, "prompt"):
|
|
2441
|
+
prompt["prompt_instruction"] = expr.prompt
|
|
2208
2442
|
|
|
2209
|
-
sym = self
|
|
2443
|
+
sym = self # used for getting passed from one iteration to the next
|
|
2210
2444
|
while True:
|
|
2211
2445
|
try:
|
|
2212
|
-
sym = expr(sym, **kwargs)
|
|
2446
|
+
sym = expr(sym, **kwargs) # run the expression
|
|
2213
2447
|
retry_cnt = 0
|
|
2214
2448
|
|
|
2215
2449
|
return sym
|
|
@@ -2219,40 +2453,51 @@ class ExecutionControlPrimitives(Primitive):
|
|
|
2219
2453
|
if retry_cnt > retries:
|
|
2220
2454
|
raise e
|
|
2221
2455
|
# analyze the error
|
|
2222
|
-
payload =
|
|
2223
|
-
|
|
2224
|
-
|
|
2456
|
+
payload = (
|
|
2457
|
+
f"[ORIGINAL_USER_PROMPT]\n{prompt['prompt_instruction']}\n\n"
|
|
2458
|
+
if "prompt_instruction" in prompt
|
|
2459
|
+
else ""
|
|
2460
|
+
)
|
|
2461
|
+
payload = (
|
|
2462
|
+
payload
|
|
2463
|
+
+ f"[ORIGINAL_USER_DATA]\n{code}\n\n[ORIGINAL_GENERATED_OUTPUT]\n{prompt['out_msg']}"
|
|
2464
|
+
)
|
|
2465
|
+
probe = sym.analyze(
|
|
2466
|
+
query="What is the issue in this expression?", payload=payload, exception=e
|
|
2467
|
+
)
|
|
2225
2468
|
# attempt to correct the error
|
|
2226
|
-
payload =
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2469
|
+
payload = (
|
|
2470
|
+
f"[ORIGINAL_USER_PROMPT]\n{prompt['prompt_instruction']}\n\n"
|
|
2471
|
+
if "prompt_instruction" in prompt
|
|
2472
|
+
else ""
|
|
2473
|
+
)
|
|
2474
|
+
payload = payload + f"[ANALYSIS]\n{probe}\n\n"
|
|
2475
|
+
context = f"Try to correct the error of the original user request based on the analysis above: \n [GENERATED_OUTPUT]\n{prompt['out_msg']}\n\n"
|
|
2476
|
+
constraints = expr.constraints if hasattr(expr, "constraints") else []
|
|
2477
|
+
|
|
2478
|
+
if hasattr(expr, "post_processor"):
|
|
2232
2479
|
post_processor = expr.post_processor
|
|
2233
2480
|
sym = code.correct(
|
|
2234
2481
|
context=context,
|
|
2235
2482
|
exception=e,
|
|
2236
2483
|
payload=payload,
|
|
2237
2484
|
constraints=constraints,
|
|
2238
|
-
post_processor=post_processor
|
|
2485
|
+
post_processor=post_processor,
|
|
2239
2486
|
)
|
|
2240
2487
|
else:
|
|
2241
2488
|
sym = code.correct(
|
|
2242
|
-
context=context,
|
|
2243
|
-
exception=e,
|
|
2244
|
-
payload=payload,
|
|
2245
|
-
constraints=constraints
|
|
2489
|
+
context=context, exception=e, payload=payload, constraints=constraints
|
|
2246
2490
|
)
|
|
2247
2491
|
|
|
2248
2492
|
|
|
2249
2493
|
class DictHandlingPrimitives(Primitive):
|
|
2250
|
-
|
|
2494
|
+
"""
|
|
2251
2495
|
This mixin hosts functions that deal with dictionary operations on symbol values.
|
|
2252
2496
|
It can be extended in the future with more advanced dictionary methods and operations.
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2497
|
+
"""
|
|
2498
|
+
|
|
2499
|
+
def dict(self, context: str, **kwargs) -> "Symbol":
|
|
2500
|
+
"""
|
|
2256
2501
|
Maps related content together under a common abstract topic as a dictionary of the Symbol value.
|
|
2257
2502
|
This method uses the @core.dictionary decorator to apply the given context to the Symbol.
|
|
2258
2503
|
It is useful for applying additional context to the symbol.
|
|
@@ -2263,7 +2508,8 @@ class DictHandlingPrimitives(Primitive):
|
|
|
2263
2508
|
|
|
2264
2509
|
Returns:
|
|
2265
2510
|
Symbol: A Symbol object with a dictionary applied.
|
|
2266
|
-
|
|
2511
|
+
"""
|
|
2512
|
+
|
|
2267
2513
|
@core.dictionary(context=context, **kwargs)
|
|
2268
2514
|
def _func(_):
|
|
2269
2515
|
pass
|
|
@@ -2272,12 +2518,15 @@ class DictHandlingPrimitives(Primitive):
|
|
|
2272
2518
|
|
|
2273
2519
|
|
|
2274
2520
|
class TemplateStylingPrimitives(Primitive):
|
|
2275
|
-
|
|
2521
|
+
"""
|
|
2276
2522
|
This mixin includes functionalities for stylizing symbols and applying templates.
|
|
2277
2523
|
Future functionalities might include a variety of new stylizing methods, application of more complex templates, etc.
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2524
|
+
"""
|
|
2525
|
+
|
|
2526
|
+
def template(
|
|
2527
|
+
that, template: str, placeholder: str | None = "{{placeholder}}", **_kwargs
|
|
2528
|
+
) -> "Symbol":
|
|
2529
|
+
"""
|
|
2281
2530
|
Applies a template to the Symbol.
|
|
2282
2531
|
This method uses the @core.template decorator to apply the given template and placeholder to the Symbol.
|
|
2283
2532
|
It is useful for providing structure to the Symbol's value.
|
|
@@ -2289,15 +2538,16 @@ class TemplateStylingPrimitives(Primitive):
|
|
|
2289
2538
|
|
|
2290
2539
|
Returns:
|
|
2291
2540
|
Symbol: A Symbol object with a template applied.
|
|
2292
|
-
|
|
2541
|
+
"""
|
|
2542
|
+
|
|
2293
2543
|
def _func(self):
|
|
2294
2544
|
res = template.replace(placeholder, str(self))
|
|
2295
2545
|
return that._to_type(res)
|
|
2296
2546
|
|
|
2297
2547
|
return _func(that)
|
|
2298
2548
|
|
|
2299
|
-
def style(self, description: str, libraries: list | None = None, **kwargs) ->
|
|
2300
|
-
|
|
2549
|
+
def style(self, description: str, libraries: list | None = None, **kwargs) -> "Symbol":
|
|
2550
|
+
"""
|
|
2301
2551
|
Applies a style to the Symbol.
|
|
2302
2552
|
This method uses the @core.style decorator to apply the given style description, libraries, and placeholder to the Symbol.
|
|
2303
2553
|
It is useful for providing structure and style to the Symbol's value.
|
|
@@ -2309,9 +2559,10 @@ class TemplateStylingPrimitives(Primitive):
|
|
|
2309
2559
|
|
|
2310
2560
|
Returns:
|
|
2311
2561
|
Symbol: A Symbol object with the style applied.
|
|
2312
|
-
|
|
2562
|
+
"""
|
|
2313
2563
|
if libraries is None:
|
|
2314
2564
|
libraries = []
|
|
2565
|
+
|
|
2315
2566
|
@core.style(description=description, libraries=libraries, **kwargs)
|
|
2316
2567
|
def _func(_):
|
|
2317
2568
|
pass
|
|
@@ -2320,12 +2571,13 @@ class TemplateStylingPrimitives(Primitive):
|
|
|
2320
2571
|
|
|
2321
2572
|
|
|
2322
2573
|
class DataClusteringPrimitives(Primitive):
|
|
2323
|
-
|
|
2574
|
+
"""
|
|
2324
2575
|
This mixin contains functionalities that deal with clustering symbol values or generating embeddings.
|
|
2325
2576
|
New functionalities in this mixin might include different types of clustering and embedding methods, dimensionality reduction techniques, etc.
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2577
|
+
"""
|
|
2578
|
+
|
|
2579
|
+
def cluster(self, **kwargs) -> "Symbol":
|
|
2580
|
+
"""
|
|
2329
2581
|
Creates a cluster from the Symbol's value.
|
|
2330
2582
|
This method uses the @core.cluster decorator to create a cluster from the Symbol's value.
|
|
2331
2583
|
It is useful for grouping values in the Symbol.
|
|
@@ -2335,7 +2587,8 @@ class DataClusteringPrimitives(Primitive):
|
|
|
2335
2587
|
|
|
2336
2588
|
Returns:
|
|
2337
2589
|
Symbol: A Symbol object with its value clustered.
|
|
2338
|
-
|
|
2590
|
+
"""
|
|
2591
|
+
|
|
2339
2592
|
@core.cluster(entries=self.value, **kwargs)
|
|
2340
2593
|
def _func(_, error=None, stack_trace=None):
|
|
2341
2594
|
pass
|
|
@@ -2344,12 +2597,13 @@ class DataClusteringPrimitives(Primitive):
|
|
|
2344
2597
|
|
|
2345
2598
|
|
|
2346
2599
|
class EmbeddingPrimitives(Primitive):
|
|
2347
|
-
|
|
2600
|
+
"""
|
|
2348
2601
|
This mixin contains functionalities that deal with embedding symbol values.
|
|
2349
2602
|
New functionalities in this mixin might include different types of embedding methods, similarity and distance measures etc.
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2603
|
+
"""
|
|
2604
|
+
|
|
2605
|
+
def embed(self, **kwargs) -> "Symbol":
|
|
2606
|
+
"""
|
|
2353
2607
|
Generates embeddings for the Symbol's value.
|
|
2354
2608
|
This method uses the @core.embed decorator to generate embeddings for the Symbol's value.
|
|
2355
2609
|
If the value is not a list, it is converted to a list.
|
|
@@ -2359,7 +2613,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2359
2613
|
|
|
2360
2614
|
Returns:
|
|
2361
2615
|
Symbol: A Symbol object with its value embedded.
|
|
2362
|
-
|
|
2616
|
+
"""
|
|
2363
2617
|
value = self.value
|
|
2364
2618
|
if not isinstance(value, list):
|
|
2365
2619
|
# must convert to list of str for embedding
|
|
@@ -2375,25 +2629,29 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2375
2629
|
|
|
2376
2630
|
@property
|
|
2377
2631
|
def embedding(self) -> np.array:
|
|
2378
|
-
|
|
2632
|
+
"""
|
|
2379
2633
|
Get the embedding as a numpy array.
|
|
2380
2634
|
|
|
2381
2635
|
Returns:
|
|
2382
2636
|
Any: The embedding of the symbol.
|
|
2383
|
-
|
|
2637
|
+
"""
|
|
2384
2638
|
# if the embedding is not yet computed, compute it
|
|
2385
2639
|
if self._metadata.embedding is None:
|
|
2386
|
-
if (
|
|
2387
|
-
|
|
2640
|
+
if (
|
|
2641
|
+
isinstance(self.value, (list, tuple))
|
|
2642
|
+
and all(isinstance(x, (int, float, bool)) for x in self.value)
|
|
2643
|
+
) or isinstance(self.value, np.ndarray):
|
|
2388
2644
|
if isinstance(self.value, (list, tuple)):
|
|
2389
|
-
assert len(self.value) > 0,
|
|
2645
|
+
assert len(self.value) > 0, "Cannot compute embedding of empty list"
|
|
2390
2646
|
symbol_type = self._symbol_type
|
|
2391
2647
|
if isinstance(self.value[0], symbol_type):
|
|
2392
2648
|
# convert each element to numpy array
|
|
2393
2649
|
self._metadata.embedding = np.asarray([x.embedding for x in self.value])
|
|
2394
2650
|
elif isinstance(self.value[0], str):
|
|
2395
2651
|
# embed each string
|
|
2396
|
-
self._metadata.embedding = np.asarray(
|
|
2652
|
+
self._metadata.embedding = np.asarray(
|
|
2653
|
+
[symbol_type(x).embedding for x in self.value]
|
|
2654
|
+
)
|
|
2397
2655
|
else:
|
|
2398
2656
|
# convert to numpy array
|
|
2399
2657
|
self._metadata.embedding = np.asarray(self.value)
|
|
@@ -2413,9 +2671,11 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2413
2671
|
def _ensure_numpy_format(self, x, cast=False):
|
|
2414
2672
|
# if it is a Symbol, get its value
|
|
2415
2673
|
if not isinstance(x, (np.ndarray, torch.Tensor, list)):
|
|
2416
|
-
if not isinstance(
|
|
2674
|
+
if not isinstance(
|
|
2675
|
+
x, self._symbol_type
|
|
2676
|
+
): # @NOTE: enforce Symbol to avoid circular import
|
|
2417
2677
|
if not cast:
|
|
2418
|
-
msg = f
|
|
2678
|
+
msg = f"Cannot compute similarity with type {type(x)}"
|
|
2419
2679
|
UserMessage(msg)
|
|
2420
2680
|
raise TypeError(msg)
|
|
2421
2681
|
x = self._symbol_type(x)
|
|
@@ -2423,7 +2683,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2423
2683
|
x = x.embedding
|
|
2424
2684
|
# if it is a list, convert it to numpy
|
|
2425
2685
|
if isinstance(x, (list, tuple)):
|
|
2426
|
-
assert len(x) > 0,
|
|
2686
|
+
assert len(x) > 0, "Cannot compute similarity with empty list"
|
|
2427
2687
|
x = np.asarray(x)
|
|
2428
2688
|
# if it is a tensor, convert it to numpy
|
|
2429
2689
|
elif isinstance(x, torch.Tensor):
|
|
@@ -2441,9 +2701,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2441
2701
|
if isinstance(operand, (list, tuple)):
|
|
2442
2702
|
if self._is_numeric_sequence(operand):
|
|
2443
2703
|
return self._ensure_numpy_format(operand, cast=True)
|
|
2444
|
-
formatted = [
|
|
2445
|
-
self._ensure_numpy_format(item, cast=True) for item in operand
|
|
2446
|
-
]
|
|
2704
|
+
formatted = [self._ensure_numpy_format(item, cast=True) for item in operand]
|
|
2447
2705
|
return np.concatenate(formatted, axis=1)
|
|
2448
2706
|
return self._ensure_numpy_format(operand, cast=True)
|
|
2449
2707
|
|
|
@@ -2458,38 +2716,44 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2458
2716
|
|
|
2459
2717
|
def _get_similarity_handler(self, metric, eps, kwargs):
|
|
2460
2718
|
def _cosine_similarity(lhs, rhs):
|
|
2461
|
-
return lhs.T@rhs / (np.sqrt(lhs.T@lhs) * np.sqrt(rhs.T@rhs) + eps)
|
|
2719
|
+
return lhs.T @ rhs / (np.sqrt(lhs.T @ lhs) * np.sqrt(rhs.T @ rhs) + eps)
|
|
2462
2720
|
|
|
2463
2721
|
def _angular_cosine_similarity(lhs, rhs):
|
|
2464
|
-
c = kwargs.get(
|
|
2465
|
-
return 1 - (
|
|
2722
|
+
c = kwargs.get("c", 1)
|
|
2723
|
+
return 1 - (
|
|
2724
|
+
c
|
|
2725
|
+
* np.arccos(lhs.T @ rhs / (np.sqrt(lhs.T @ lhs) * np.sqrt(rhs.T @ rhs) + eps))
|
|
2726
|
+
/ np.pi
|
|
2727
|
+
)
|
|
2466
2728
|
|
|
2467
2729
|
def _product_similarity(lhs, rhs):
|
|
2468
|
-
return lhs.T@rhs
|
|
2730
|
+
return lhs.T @ rhs
|
|
2469
2731
|
|
|
2470
2732
|
def _manhattan_similarity(lhs, rhs):
|
|
2471
2733
|
return np.abs(lhs - rhs).sum(axis=0, keepdims=True)
|
|
2472
2734
|
|
|
2473
2735
|
def _euclidean_similarity(lhs, rhs):
|
|
2474
|
-
return np.sqrt(np.sum((lhs - rhs)**2, axis=0, keepdims=True))
|
|
2736
|
+
return np.sqrt(np.sum((lhs - rhs) ** 2, axis=0, keepdims=True))
|
|
2475
2737
|
|
|
2476
2738
|
def _minkowski_similarity(lhs, rhs):
|
|
2477
|
-
p = kwargs.get(
|
|
2478
|
-
return np.sum(np.abs(lhs - rhs)**p, axis=0, keepdims=True)**(1/p)
|
|
2739
|
+
p = kwargs.get("p", 3)
|
|
2740
|
+
return np.sum(np.abs(lhs - rhs) ** p, axis=0, keepdims=True) ** (1 / p)
|
|
2479
2741
|
|
|
2480
2742
|
def _jaccard_similarity(lhs, rhs):
|
|
2481
2743
|
intersection = np.minimum(lhs, rhs)
|
|
2482
2744
|
union = np.maximum(lhs, rhs)
|
|
2483
|
-
return np.sum(intersection, axis=0, keepdims=True) / (
|
|
2745
|
+
return np.sum(intersection, axis=0, keepdims=True) / (
|
|
2746
|
+
np.sum(union, axis=0, keepdims=True) + eps
|
|
2747
|
+
)
|
|
2484
2748
|
|
|
2485
2749
|
metric_handlers = {
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2750
|
+
"cosine": _cosine_similarity,
|
|
2751
|
+
"angular-cosine": _angular_cosine_similarity,
|
|
2752
|
+
"product": _product_similarity,
|
|
2753
|
+
"manhattan": _manhattan_similarity,
|
|
2754
|
+
"euclidean": _euclidean_similarity,
|
|
2755
|
+
"minkowski": _minkowski_similarity,
|
|
2756
|
+
"jaccard": _jaccard_similarity,
|
|
2493
2757
|
}
|
|
2494
2758
|
|
|
2495
2759
|
handler = metric_handlers.get(metric)
|
|
@@ -2504,19 +2768,19 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2504
2768
|
|
|
2505
2769
|
def _get_kernel_handler(self, kernel):
|
|
2506
2770
|
kernel_handlers = {
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2771
|
+
"gaussian": self._kernel_gaussian,
|
|
2772
|
+
"rbf": self._kernel_rbf,
|
|
2773
|
+
"laplacian": self._kernel_laplacian,
|
|
2774
|
+
"polynomial": self._kernel_polynomial,
|
|
2775
|
+
"sigmoid": self._kernel_sigmoid,
|
|
2776
|
+
"linear": self._kernel_linear,
|
|
2777
|
+
"cauchy": self._kernel_cauchy,
|
|
2778
|
+
"t-distribution": self._kernel_t_distribution,
|
|
2779
|
+
"inverse-multiquadric": self._kernel_inverse_multiquadric,
|
|
2780
|
+
"cosine": self._kernel_cosine,
|
|
2781
|
+
"angular-cosine": self._kernel_angular_cosine,
|
|
2782
|
+
"frechet": self._kernel_frechet,
|
|
2783
|
+
"mmd": self._kernel_mmd,
|
|
2520
2784
|
}
|
|
2521
2785
|
|
|
2522
2786
|
handler = kernel_handlers.get(kernel)
|
|
@@ -2527,13 +2791,13 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2527
2791
|
return handler
|
|
2528
2792
|
|
|
2529
2793
|
def _kernel_gaussian(self, lhs, rhs, _eps, kwargs):
|
|
2530
|
-
gamma = kwargs.get(
|
|
2531
|
-
return np.exp(-gamma * np.sum((lhs - rhs)**2, axis=0))
|
|
2794
|
+
gamma = kwargs.get("gamma", 1)
|
|
2795
|
+
return np.exp(-gamma * np.sum((lhs - rhs) ** 2, axis=0))
|
|
2532
2796
|
|
|
2533
2797
|
def _kernel_rbf(self, lhs, rhs, _eps, kwargs):
|
|
2534
|
-
bandwidth = kwargs.get(
|
|
2535
|
-
gamma = kwargs.get(
|
|
2536
|
-
distance_sq = np.sum((lhs - rhs)**2, axis=0)
|
|
2798
|
+
bandwidth = kwargs.get("bandwidth")
|
|
2799
|
+
gamma = kwargs.get("gamma", 1)
|
|
2800
|
+
distance_sq = np.sum((lhs - rhs) ** 2, axis=0)
|
|
2537
2801
|
if bandwidth is not None:
|
|
2538
2802
|
val = 0
|
|
2539
2803
|
for a in bandwidth:
|
|
@@ -2543,35 +2807,35 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2543
2807
|
return np.exp(-gamma * distance_sq)
|
|
2544
2808
|
|
|
2545
2809
|
def _kernel_laplacian(self, lhs, rhs, _eps, kwargs):
|
|
2546
|
-
gamma = kwargs.get(
|
|
2810
|
+
gamma = kwargs.get("gamma", 1)
|
|
2547
2811
|
return np.exp(-gamma * np.sum(np.abs(lhs - rhs), axis=0))
|
|
2548
2812
|
|
|
2549
2813
|
def _kernel_polynomial(self, lhs, rhs, _eps, kwargs):
|
|
2550
|
-
gamma = kwargs.get(
|
|
2551
|
-
degree = kwargs.get(
|
|
2552
|
-
coef = kwargs.get(
|
|
2553
|
-
return (gamma * np.sum((lhs * rhs), axis=0) + coef)**degree
|
|
2814
|
+
gamma = kwargs.get("gamma", 1)
|
|
2815
|
+
degree = kwargs.get("degree", 3)
|
|
2816
|
+
coef = kwargs.get("coef", 1)
|
|
2817
|
+
return (gamma * np.sum((lhs * rhs), axis=0) + coef) ** degree
|
|
2554
2818
|
|
|
2555
2819
|
def _kernel_sigmoid(self, lhs, rhs, _eps, kwargs):
|
|
2556
|
-
gamma = kwargs.get(
|
|
2557
|
-
coef = kwargs.get(
|
|
2820
|
+
gamma = kwargs.get("gamma", 1)
|
|
2821
|
+
coef = kwargs.get("coef", 1)
|
|
2558
2822
|
return np.tanh(gamma * np.sum((lhs * rhs), axis=0) + coef)
|
|
2559
2823
|
|
|
2560
2824
|
def _kernel_linear(self, lhs, rhs, _eps, _kwargs):
|
|
2561
2825
|
return np.sum((lhs * rhs), axis=0)
|
|
2562
2826
|
|
|
2563
2827
|
def _kernel_cauchy(self, lhs, rhs, _eps, kwargs):
|
|
2564
|
-
gamma = kwargs.get(
|
|
2565
|
-
return 1 / (1 + np.sum((lhs - rhs)**2, axis=0) / gamma)
|
|
2828
|
+
gamma = kwargs.get("gamma", 1)
|
|
2829
|
+
return 1 / (1 + np.sum((lhs - rhs) ** 2, axis=0) / gamma)
|
|
2566
2830
|
|
|
2567
2831
|
def _kernel_t_distribution(self, lhs, rhs, _eps, kwargs):
|
|
2568
|
-
gamma = kwargs.get(
|
|
2569
|
-
degree = kwargs.get(
|
|
2570
|
-
return 1 / (1 + (np.sum((lhs - rhs)**2, axis=0) / (gamma * degree))**(degree + 1) / 2)
|
|
2832
|
+
gamma = kwargs.get("gamma", 1)
|
|
2833
|
+
degree = kwargs.get("degree", 1)
|
|
2834
|
+
return 1 / (1 + (np.sum((lhs - rhs) ** 2, axis=0) / (gamma * degree)) ** (degree + 1) / 2)
|
|
2571
2835
|
|
|
2572
2836
|
def _kernel_inverse_multiquadric(self, lhs, rhs, _eps, kwargs):
|
|
2573
|
-
gamma = kwargs.get(
|
|
2574
|
-
return 1 / np.sqrt(np.sum((lhs - rhs)**2, axis=0) / gamma**2 + 1)
|
|
2837
|
+
gamma = kwargs.get("gamma", 1)
|
|
2838
|
+
return 1 / np.sqrt(np.sum((lhs - rhs) ** 2, axis=0) / gamma**2 + 1)
|
|
2575
2839
|
|
|
2576
2840
|
def _kernel_cosine(self, lhs, rhs, eps, _kwargs):
|
|
2577
2841
|
numerator = np.sum(lhs * rhs, axis=0)
|
|
@@ -2579,15 +2843,17 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2579
2843
|
return 1 - (numerator / denominator)
|
|
2580
2844
|
|
|
2581
2845
|
def _kernel_angular_cosine(self, lhs, rhs, eps, kwargs):
|
|
2582
|
-
c = kwargs.get(
|
|
2846
|
+
c = kwargs.get("c", 1)
|
|
2583
2847
|
numerator = np.sum(lhs * rhs, axis=0)
|
|
2584
2848
|
denominator = np.sqrt(np.sum(lhs**2, axis=0)) * np.sqrt(np.sum(rhs**2, axis=0)) + eps
|
|
2585
2849
|
return c * np.arccos(numerator / denominator) / np.pi
|
|
2586
2850
|
|
|
2587
2851
|
def _kernel_frechet(self, lhs, rhs, eps, kwargs):
|
|
2588
|
-
sigma1 = kwargs.get(
|
|
2589
|
-
sigma2 = kwargs.get(
|
|
2590
|
-
assert sigma1 is not None and sigma2 is not None,
|
|
2852
|
+
sigma1 = kwargs.get("sigma1")
|
|
2853
|
+
sigma2 = kwargs.get("sigma2")
|
|
2854
|
+
assert sigma1 is not None and sigma2 is not None, (
|
|
2855
|
+
"Frechet distance requires covariance matrices for both inputs"
|
|
2856
|
+
)
|
|
2591
2857
|
return calculate_frechet_distance(lhs.T, sigma1, rhs.T, sigma2, eps)
|
|
2592
2858
|
|
|
2593
2859
|
def _kernel_mmd(self, lhs, rhs, eps, _kwargs):
|
|
@@ -2595,13 +2861,15 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2595
2861
|
|
|
2596
2862
|
def similarity(
|
|
2597
2863
|
self,
|
|
2598
|
-
other: Union[
|
|
2599
|
-
metric: Literal[
|
|
2864
|
+
other: Union["Symbol", list, np.ndarray, torch.Tensor],
|
|
2865
|
+
metric: Literal[
|
|
2866
|
+
"cosine", "angular-cosine", "product", "manhattan", "euclidean", "minkowski", "jaccard"
|
|
2867
|
+
] = "cosine",
|
|
2600
2868
|
eps: float = 1e-8,
|
|
2601
2869
|
normalize: Callable | None = None,
|
|
2602
2870
|
**kwargs,
|
|
2603
2871
|
) -> float:
|
|
2604
|
-
|
|
2872
|
+
"""
|
|
2605
2873
|
Calculates the similarity between two Symbol objects using a specified metric.
|
|
2606
2874
|
This method compares the values of two Symbol objects and calculates their similarity according to the specified metric.
|
|
2607
2875
|
It supports the 'cosine' metric, and raises a NotImplementedError for other metrics.
|
|
@@ -2619,7 +2887,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2619
2887
|
Raises:
|
|
2620
2888
|
TypeError: If any of the Symbol objects is not of type np.ndarray or Symbol.
|
|
2621
2889
|
NotImplementedError: If the given metric is not supported.
|
|
2622
|
-
|
|
2890
|
+
"""
|
|
2623
2891
|
v = self._ensure_numpy_format(self)
|
|
2624
2892
|
o = self._prepare_embedding_operand(other)
|
|
2625
2893
|
handler = self._get_similarity_handler(metric, eps, kwargs)
|
|
@@ -2638,13 +2906,27 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2638
2906
|
|
|
2639
2907
|
def distance(
|
|
2640
2908
|
self,
|
|
2641
|
-
other: Union[
|
|
2642
|
-
kernel: Literal[
|
|
2909
|
+
other: Union["Symbol", list, np.ndarray, torch.Tensor],
|
|
2910
|
+
kernel: Literal[
|
|
2911
|
+
"gaussian",
|
|
2912
|
+
"rbf",
|
|
2913
|
+
"laplacian",
|
|
2914
|
+
"polynomial",
|
|
2915
|
+
"sigmoid",
|
|
2916
|
+
"linear",
|
|
2917
|
+
"cauchy",
|
|
2918
|
+
"t-distribution",
|
|
2919
|
+
"inverse-multiquadric",
|
|
2920
|
+
"cosine",
|
|
2921
|
+
"angular-cosine",
|
|
2922
|
+
"frechet",
|
|
2923
|
+
"mmd",
|
|
2924
|
+
] = "gaussian",
|
|
2643
2925
|
eps: float = 1e-8,
|
|
2644
2926
|
normalize: Callable | None = None,
|
|
2645
2927
|
**kwargs,
|
|
2646
2928
|
) -> float:
|
|
2647
|
-
|
|
2929
|
+
"""
|
|
2648
2930
|
Calculates the kernel between two Symbol objects.
|
|
2649
2931
|
|
|
2650
2932
|
Args:
|
|
@@ -2659,7 +2941,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2659
2941
|
Raises:
|
|
2660
2942
|
TypeError: If any of the Symbol objects is not of type np.ndarray or Symbol.
|
|
2661
2943
|
NotImplementedError: If the given kernel is not supported.
|
|
2662
|
-
|
|
2944
|
+
"""
|
|
2663
2945
|
v = self._ensure_numpy_format(self)
|
|
2664
2946
|
o = self._prepare_embedding_operand(other)
|
|
2665
2947
|
handler = self._get_kernel_handler(kernel)
|
|
@@ -2673,7 +2955,7 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2673
2955
|
return val
|
|
2674
2956
|
|
|
2675
2957
|
def zip(self, **kwargs) -> list[tuple[str, list, dict]]:
|
|
2676
|
-
|
|
2958
|
+
"""
|
|
2677
2959
|
Zips the Symbol's value with its embeddings and a query containing the value.
|
|
2678
2960
|
This method zips the Symbol's value along with its embeddings and a query containing the value.
|
|
2679
2961
|
|
|
@@ -2685,19 +2967,19 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2685
2967
|
|
|
2686
2968
|
Raises:
|
|
2687
2969
|
ValueError: If the Symbol's value is not a string or list of strings.
|
|
2688
|
-
|
|
2970
|
+
"""
|
|
2689
2971
|
if isinstance(self.value, str):
|
|
2690
2972
|
self._value = [self.value]
|
|
2691
2973
|
elif isinstance(self.value, list):
|
|
2692
2974
|
pass
|
|
2693
2975
|
else:
|
|
2694
|
-
msg = f
|
|
2976
|
+
msg = f"Expected id to be a string, got {type(self.value)}"
|
|
2695
2977
|
UserMessage(msg)
|
|
2696
2978
|
raise ValueError(msg)
|
|
2697
2979
|
|
|
2698
2980
|
embeds = self.embed(**kwargs).value
|
|
2699
|
-
idx
|
|
2700
|
-
query
|
|
2981
|
+
idx = [str(uuid.uuid4()) for _ in range(len(self.value))]
|
|
2982
|
+
query = [{"text": str(self.value[i])} for i in range(len(self.value))]
|
|
2701
2983
|
|
|
2702
2984
|
# convert embeds to list if it is a tensor or numpy array
|
|
2703
2985
|
if isinstance(embeds, np.ndarray):
|
|
@@ -2709,11 +2991,12 @@ class EmbeddingPrimitives(Primitive):
|
|
|
2709
2991
|
|
|
2710
2992
|
|
|
2711
2993
|
class IOHandlingPrimitives(Primitive):
|
|
2712
|
-
|
|
2994
|
+
"""
|
|
2713
2995
|
This mixin contains functionalities related to input/output operations.
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2996
|
+
"""
|
|
2997
|
+
|
|
2998
|
+
def input(self, message: str = "Please add more information", **kwargs) -> "Symbol":
|
|
2999
|
+
"""
|
|
2717
3000
|
Request user input and return a Symbol containing the user input.
|
|
2718
3001
|
|
|
2719
3002
|
Args:
|
|
@@ -2734,7 +3017,8 @@ class IOHandlingPrimitives(Primitive):
|
|
|
2734
3017
|
>>> [output: 'I was born in 1990'] # if Symbol has a <str> value inputs will be concatenated
|
|
2735
3018
|
|
|
2736
3019
|
# Works identically for the `Expression` class
|
|
2737
|
-
|
|
3020
|
+
"""
|
|
3021
|
+
|
|
2738
3022
|
@core.userinput(**kwargs)
|
|
2739
3023
|
def _func(_, message) -> str:
|
|
2740
3024
|
pass
|
|
@@ -2742,12 +3026,12 @@ class IOHandlingPrimitives(Primitive):
|
|
|
2742
3026
|
res = _func(self, message)
|
|
2743
3027
|
condition = self.value is not None and isinstance(self.value, str)
|
|
2744
3028
|
|
|
2745
|
-
if hasattr(self,
|
|
2746
|
-
return self.sym_return_type(self.value if condition else
|
|
2747
|
-
return self._to_type(self.value if condition else
|
|
3029
|
+
if hasattr(self, "sym_return_type"):
|
|
3030
|
+
return self.sym_return_type(self.value if condition else "") | res
|
|
3031
|
+
return self._to_type(self.value if condition else "") | self._to_type(res)
|
|
2748
3032
|
|
|
2749
|
-
def open(self, path: str | None = None, **kwargs) ->
|
|
2750
|
-
|
|
3033
|
+
def open(self, path: str | None = None, **kwargs) -> "Symbol":
|
|
3034
|
+
"""
|
|
2751
3035
|
Open a file and store its content in an Expression object as a string.
|
|
2752
3036
|
|
|
2753
3037
|
Args:
|
|
@@ -2766,11 +3050,11 @@ class IOHandlingPrimitives(Primitive):
|
|
|
2766
3050
|
>>> s = s.open()
|
|
2767
3051
|
|
|
2768
3052
|
# Works identically for the `Expression` class
|
|
2769
|
-
|
|
3053
|
+
"""
|
|
2770
3054
|
|
|
2771
3055
|
path = path if path is not None else self.value
|
|
2772
3056
|
if path is None:
|
|
2773
|
-
msg =
|
|
3057
|
+
msg = "Path is not provided; either provide a path or set the value of the Symbol to the path"
|
|
2774
3058
|
UserMessage(msg)
|
|
2775
3059
|
raise ValueError(msg)
|
|
2776
3060
|
|
|
@@ -2778,45 +3062,53 @@ class IOHandlingPrimitives(Primitive):
|
|
|
2778
3062
|
def _func(_):
|
|
2779
3063
|
pass
|
|
2780
3064
|
|
|
2781
|
-
if hasattr(self,
|
|
3065
|
+
if hasattr(self, "sym_return_type"):
|
|
2782
3066
|
return self.sym_return_type(_func(self))
|
|
2783
3067
|
return self._to_type(_func(self))
|
|
2784
3068
|
|
|
2785
3069
|
|
|
2786
|
-
|
|
3070
|
+
# @TODO: add tests
|
|
2787
3071
|
class IndexingPrimitives(Primitive):
|
|
2788
|
-
|
|
3072
|
+
"""
|
|
2789
3073
|
This mixin contains functionalities related to indexing symbols locally.
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
3074
|
+
"""
|
|
3075
|
+
|
|
3076
|
+
def config(self, path: str, index_name: str, **kwargs) -> "Symbol":
|
|
3077
|
+
"""Execute a configuration operation on the index."""
|
|
3078
|
+
|
|
3079
|
+
@core.index(prompt=path, index_name=index_name, operation="config", **kwargs)
|
|
2794
3080
|
def _func(_):
|
|
2795
3081
|
pass
|
|
3082
|
+
|
|
2796
3083
|
return _func(self)
|
|
2797
3084
|
|
|
2798
|
-
def add(self, doc: list[str], index_name: str, **kwargs) ->
|
|
2799
|
-
|
|
2800
|
-
|
|
3085
|
+
def add(self, doc: list[str], index_name: str, **kwargs) -> "Symbol":
|
|
3086
|
+
"""Add an entry to the existing index."""
|
|
3087
|
+
|
|
3088
|
+
@core.index(prompt=doc, index_name=index_name, operation="add", **kwargs)
|
|
2801
3089
|
def _func(_):
|
|
2802
3090
|
pass
|
|
3091
|
+
|
|
2803
3092
|
return _func(self)
|
|
2804
3093
|
|
|
2805
|
-
def get(self, query: list[str], index_name: str, **kwargs) ->
|
|
2806
|
-
|
|
2807
|
-
|
|
3094
|
+
def get(self, query: list[str], index_name: str, **kwargs) -> "Symbol":
|
|
3095
|
+
"""Search the index based on the provided query."""
|
|
3096
|
+
|
|
3097
|
+
@core.index(prompt=query, index_name=index_name, operation="search", **kwargs)
|
|
2808
3098
|
def _func(_):
|
|
2809
3099
|
pass
|
|
3100
|
+
|
|
2810
3101
|
return _func(self)
|
|
2811
3102
|
|
|
2812
3103
|
|
|
2813
3104
|
class PersistencePrimitives(Primitive):
|
|
2814
|
-
|
|
3105
|
+
"""
|
|
2815
3106
|
This mixin contains functionalities related to expanding symbols and saving/loading symbols to/from disk.
|
|
2816
3107
|
Future functionalities in this mixin might include different ways of serialization and deserialization, or more complex expansion techniques etc.
|
|
2817
|
-
|
|
3108
|
+
"""
|
|
3109
|
+
|
|
2818
3110
|
def expand(self, *args, **kwargs) -> str:
|
|
2819
|
-
|
|
3111
|
+
"""
|
|
2820
3112
|
Expand the current Symbol and create a new sub-component.
|
|
2821
3113
|
The function writes a self-contained function (with all imports) to solve a specific user problem task.
|
|
2822
3114
|
This method uses the `@core.expand` decorator with a maximum token limit of 2048, and allows additional keyword
|
|
@@ -2828,24 +3120,26 @@ class PersistencePrimitives(Primitive):
|
|
|
2828
3120
|
|
|
2829
3121
|
Returns:
|
|
2830
3122
|
Symbol: The name of the newly created sub-component.
|
|
2831
|
-
|
|
3123
|
+
"""
|
|
3124
|
+
|
|
2832
3125
|
@core.expand(**kwargs)
|
|
2833
|
-
def _func(_, *args):
|
|
3126
|
+
def _func(_, *args):
|
|
3127
|
+
pass
|
|
2834
3128
|
|
|
2835
3129
|
_tmp_llm_func = self._to_type(_func(self, *args))
|
|
2836
|
-
func_name = str(_tmp_llm_func.extract(
|
|
3130
|
+
func_name = str(_tmp_llm_func.extract("function name"))
|
|
2837
3131
|
|
|
2838
3132
|
def _llm_func(*args, **kwargs):
|
|
2839
3133
|
res = _tmp_llm_func.fexecute(*args, **kwargs)
|
|
2840
3134
|
|
|
2841
|
-
return res[
|
|
3135
|
+
return res["locals"][func_name]()
|
|
2842
3136
|
|
|
2843
3137
|
setattr(self, func_name, _llm_func)
|
|
2844
3138
|
|
|
2845
3139
|
return func_name
|
|
2846
3140
|
|
|
2847
3141
|
def save(self, path: str, replace: bool | None = False, serialize: bool | None = True) -> None:
|
|
2848
|
-
|
|
3142
|
+
"""
|
|
2849
3143
|
Save the current Symbol to a file.
|
|
2850
3144
|
|
|
2851
3145
|
Args:
|
|
@@ -2855,29 +3149,29 @@ class PersistencePrimitives(Primitive):
|
|
|
2855
3149
|
|
|
2856
3150
|
Returns:
|
|
2857
3151
|
Symbol: The current Symbol.
|
|
2858
|
-
|
|
3152
|
+
"""
|
|
2859
3153
|
file_path = Path(path)
|
|
2860
3154
|
|
|
2861
3155
|
if not replace:
|
|
2862
3156
|
cnt = 0
|
|
2863
3157
|
candidate = file_path
|
|
2864
3158
|
while candidate.exists():
|
|
2865
|
-
candidate = candidate.with_name(f
|
|
3159
|
+
candidate = candidate.with_name(f"{file_path.stem}_{cnt}{file_path.suffix}")
|
|
2866
3160
|
cnt += 1
|
|
2867
3161
|
file_path = candidate
|
|
2868
3162
|
|
|
2869
3163
|
if serialize:
|
|
2870
3164
|
# serialize the object via pickle instead of writing the string
|
|
2871
3165
|
path_str = str(file_path)
|
|
2872
|
-
pickle_path = Path(path_str if path_str.endswith(
|
|
2873
|
-
with pickle_path.open(
|
|
3166
|
+
pickle_path = Path(path_str if path_str.endswith(".pkl") else f"{path_str}.pkl")
|
|
3167
|
+
with pickle_path.open("wb") as f:
|
|
2874
3168
|
pickle.dump(self, file=f)
|
|
2875
3169
|
else:
|
|
2876
|
-
with file_path.open(
|
|
3170
|
+
with file_path.open("w") as f:
|
|
2877
3171
|
f.write(str(self))
|
|
2878
3172
|
|
|
2879
3173
|
def load(self, path: str) -> Any:
|
|
2880
|
-
|
|
3174
|
+
"""
|
|
2881
3175
|
Load a Symbol from a file.
|
|
2882
3176
|
|
|
2883
3177
|
Args:
|
|
@@ -2885,18 +3179,18 @@ class PersistencePrimitives(Primitive):
|
|
|
2885
3179
|
|
|
2886
3180
|
Returns:
|
|
2887
3181
|
Symbol: The loaded Symbol.
|
|
2888
|
-
|
|
2889
|
-
with Path(path).open(
|
|
3182
|
+
"""
|
|
3183
|
+
with Path(path).open("rb") as f:
|
|
2890
3184
|
return pickle.load(f)
|
|
2891
3185
|
|
|
2892
3186
|
|
|
2893
3187
|
class OutputHandlingPrimitives(Primitive):
|
|
2894
|
-
|
|
3188
|
+
"""
|
|
2895
3189
|
This mixin include functionalities related to outputting symbols. It can be expanded in the future to include different types of output methods or complex output formatting, etc.
|
|
2896
|
-
|
|
3190
|
+
"""
|
|
2897
3191
|
|
|
2898
|
-
def output(self, *args, **kwargs) ->
|
|
2899
|
-
|
|
3192
|
+
def output(self, *args, **kwargs) -> "Symbol":
|
|
3193
|
+
"""
|
|
2900
3194
|
Output the current Symbol to an output handler.
|
|
2901
3195
|
This method uses the `@core.output` decorator and allows additional keyword arguments to be passed to the decorator.
|
|
2902
3196
|
|
|
@@ -2906,7 +3200,8 @@ class OutputHandlingPrimitives(Primitive):
|
|
|
2906
3200
|
|
|
2907
3201
|
Returns:
|
|
2908
3202
|
Symbol: The resulting Symbol after the output operation.
|
|
2909
|
-
|
|
3203
|
+
"""
|
|
3204
|
+
|
|
2910
3205
|
@core.output(**kwargs)
|
|
2911
3206
|
def _func(_, *_func_args, **_func_kwargs):
|
|
2912
3207
|
return self.value
|
|
@@ -2914,13 +3209,14 @@ class OutputHandlingPrimitives(Primitive):
|
|
|
2914
3209
|
return self._to_type(_func(self, self.value, *args))
|
|
2915
3210
|
|
|
2916
3211
|
|
|
2917
|
-
|
|
3212
|
+
# @TODO: add tests
|
|
2918
3213
|
class FineTuningPrimitives(Primitive):
|
|
2919
|
-
|
|
3214
|
+
"""
|
|
2920
3215
|
This mixin contains functionalities related to fine tuning models.
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
3216
|
+
"""
|
|
3217
|
+
|
|
3218
|
+
def tune(self, operation: str = "create", **kwargs) -> "Symbol":
|
|
3219
|
+
"""
|
|
2924
3220
|
Fine tune a base model.
|
|
2925
3221
|
|
|
2926
3222
|
Args:
|
|
@@ -2929,20 +3225,22 @@ class FineTuningPrimitives(Primitive):
|
|
|
2929
3225
|
|
|
2930
3226
|
Returns:
|
|
2931
3227
|
Symbol: The resulting Symbol containing the fine tuned model ID.
|
|
2932
|
-
|
|
3228
|
+
"""
|
|
3229
|
+
|
|
2933
3230
|
@core.tune(operation=operation, **kwargs)
|
|
2934
3231
|
def _func(_, *args, **kwargs) -> str:
|
|
2935
3232
|
pass
|
|
3233
|
+
|
|
2936
3234
|
return self.sym_return_type(_func(self))
|
|
2937
3235
|
|
|
2938
3236
|
@property
|
|
2939
3237
|
def data(self) -> torch.Tensor:
|
|
2940
|
-
|
|
3238
|
+
"""
|
|
2941
3239
|
Get the data as a Pytorch tensor.
|
|
2942
3240
|
|
|
2943
3241
|
Returns:
|
|
2944
3242
|
Any: The data of the symbol.
|
|
2945
|
-
|
|
3243
|
+
"""
|
|
2946
3244
|
# if the data is not yet computed, compute it
|
|
2947
3245
|
if self._metadata.data is None:
|
|
2948
3246
|
# compute the data and store as numpy array
|
|
@@ -2956,16 +3254,16 @@ class FineTuningPrimitives(Primitive):
|
|
|
2956
3254
|
# convert to tensor
|
|
2957
3255
|
self._metadata.data = torch.from_numpy(self._metadata.data)
|
|
2958
3256
|
return self._metadata.data
|
|
2959
|
-
msg = f
|
|
3257
|
+
msg = f"Expected data to be a tensor or numpy array, got {type(self._metadata.data)}"
|
|
2960
3258
|
UserMessage(msg)
|
|
2961
3259
|
raise TypeError(msg)
|
|
2962
3260
|
|
|
2963
3261
|
@data.setter
|
|
2964
3262
|
def data(self, data: torch.Tensor) -> None:
|
|
2965
|
-
|
|
3263
|
+
"""
|
|
2966
3264
|
Set the data of the symbol.
|
|
2967
3265
|
|
|
2968
3266
|
Args:
|
|
2969
3267
|
data (torch.Tensor): The data to set.
|
|
2970
|
-
|
|
3268
|
+
"""
|
|
2971
3269
|
self._metadata.data = data
|