Skip to content

Commit e376aa6

Browse files
committed
lambda transformation, holoatom ABC/polymorph
1 parent 0cec4c4 commit e376aa6

File tree

4 files changed

+480
-59
lines changed

4 files changed

+480
-59
lines changed

src/gg.py

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/holoatom.py

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
import ast
2+
import hashlib
3+
import json
4+
import logging
5+
import inspect
6+
from typing import Any, Callable, Dict, Generic, List, Type, TypeVar, Union
7+
from dataclasses import dataclass, field
8+
9+
#------------------------------------------------------------------------------
10+
# Holoiconic-Atomic-logic
11+
#------------------------------------------------------------------------------
12+
"""
13+
This module demonstrates the concept of combining imperative and non-imperative programming paradigms using Python's AST transformations. It allows dynamic modification and execution of source code at runtime, inspired by functional programming and lambda calculus principles.
14+
"""
15+
16+
@dataclass
17+
class GrammarRule:
18+
"""
19+
Represents a single grammar rule in a context-free grammar.
20+
21+
Attributes:
22+
lhs (str): Left-hand side of the rule.
23+
rhs (List[Union[str, 'GrammarRule']]): Right-hand side of the rule, which can be terminals or other rules.
24+
"""
25+
lhs: str
26+
rhs: List[Union[str, 'GrammarRule']]
27+
28+
def __repr__(self):
29+
"""
30+
Provide a string representation of the grammar rule.
31+
32+
Returns:
33+
str: The string representation.
34+
"""
35+
rhs_str = ' '.join([str(elem) for elem in self.rhs])
36+
return f"{self.lhs} -> {rhs_str}"
37+
38+
T = TypeVar('T')
39+
V = TypeVar('V')
40+
C = TypeVar('C')
41+
42+
class LambdaModifier(ast.NodeTransformer):
43+
def __init__(self, operation: str):
44+
self.operation = operation
45+
46+
def visit_Lambda(self, node: ast.Lambda) -> ast.Lambda:
47+
if self.operation == "multiply":
48+
node.body = ast.BinOp(left=node.body, op=ast.Mult(), right=ast.Constant(value=2))
49+
elif self.operation == "subtract":
50+
node.body = ast.BinOp(left=node.body, op=ast.Sub(), right=ast.Constant(value=1))
51+
elif self.operation == "divide":
52+
node.body = ast.BinOp(left=node.body, op=ast.Div(), right=ast.Constant(value=2))
53+
# Add more operations as needed
54+
return node
55+
56+
def transform_lambda(source_code: str, operation: str) -> str:
57+
tree = ast.parse(source_code, mode='eval')
58+
modifier = LambdaModifier(operation)
59+
modified_tree = modifier.visit(tree)
60+
return ast.unparse(modified_tree)
61+
62+
class Atom(Generic[T, V, C]):
63+
"""
64+
Abstract Base Class for all Atom types.
65+
66+
Atoms are the smallest units of data or executable code, and this interface
67+
defines common operations such as encoding, decoding, execution, and conversion
68+
to data classes.
69+
70+
Attributes:
71+
grammar_rules (List[GrammarRule]): List of grammar rules defining the syntax of the Atom.
72+
"""
73+
__slots__ = ('_id', '_value', '_type', '_metadata', '_children', '_parent', 'hash', 'tag', 'children', 'metadata')
74+
type: Union[str, str]
75+
value: Union[T, V, C] = field(default=None)
76+
grammar_rules: List[GrammarRule] = field(default_factory=list)
77+
id: str = field(init=False)
78+
case_base: Dict[str, Callable[..., bool]] = field(default_factory=dict)
79+
80+
def __init__(self, value: Union[T, V, C], type: Union[str, str]):
81+
self._value = value
82+
self._type = type
83+
self._metadata = {}
84+
self._children = []
85+
self._parent = None
86+
self.hash = hashlib.sha256(repr(self._value).encode()).hexdigest()
87+
self.tag = ''
88+
self.children = []
89+
self.metadata = {}
90+
self.__post_init__()
91+
92+
def __post_init__(self):
93+
self.case_base = {
94+
'⊤': lambda x, _: x,
95+
'⊥': lambda _, y: y,
96+
'¬': lambda a: not a,
97+
'∧': lambda a, b: a and b,
98+
'∨': lambda a, b: a or b,
99+
'→': lambda a, b: (not a) or b,
100+
'↔': lambda a, b: (a and b) or (not a and not b),
101+
}
102+
103+
reflexivity: Callable[[T], bool] = lambda x: x == x
104+
symmetry: Callable[[T, T], bool] = lambda x, y: x == y
105+
transitivity: Callable[[T, T, T], bool] = lambda x, y, z: (x == y and y == z)
106+
transparency: Callable[[Callable[..., T], T, T], T] = lambda f, x, y: f(True, x, y) if x == y else None
107+
108+
def process_attributes(self, mapping_description: Dict[str, Any], input_data: Dict[str, Any]) -> None:
109+
"""
110+
Use the `mapper` function to process input data and map it to attributes.
111+
112+
Args:
113+
mapping_description (Dict[str, Any]): The mapping description for transformation.
114+
input_data (Dict[str, Any]): Data to be processed and mapped.
115+
"""
116+
mapped_data = self.mapper(mapping_description, input_data)
117+
for key, value in mapped_data.items():
118+
if hasattr(self, key):
119+
setattr(self, key, value)
120+
121+
def mapper(self, mapping_description: Dict[str, Any], input_data: Dict[str, Any]) -> Dict[str, Any]:
122+
"""Example mapper function."""
123+
# Implement the actual mapping logic here
124+
return input_data
125+
126+
def encode(self) -> bytes:
127+
return json.dumps({
128+
'id': self.id,
129+
'attributes': self.attributes
130+
}).encode()
131+
132+
@classmethod
133+
def decode(cls, data: bytes) -> 'Atom':
134+
decoded_data = json.loads(data.decode())
135+
return cls(id=decoded_data['id'], **decoded_data['attributes'])
136+
137+
def introspect(self) -> str:
138+
"""
139+
Reflect on its own code structure via AST.
140+
"""
141+
source = inspect.getsource(self.__class__)
142+
return ast.dump(ast.parse(source))
143+
144+
def __repr__(self):
145+
return f"{self.value} : {self.type}"
146+
147+
def __str__(self):
148+
return str(self.value)
149+
150+
def __eq__(self, other: Any) -> bool:
151+
return isinstance(other, Atom) and self.hash == other.hash
152+
153+
def __hash__(self) -> int:
154+
return int(self.hash, 16)
155+
156+
def __getitem__(self, key):
157+
return self.value[key]
158+
159+
def __setitem__(self, key, value):
160+
self.value[key] = value
161+
162+
def __delitem__(self, key):
163+
del self.value[key]
164+
165+
def __len__(self):
166+
return len(self.value)
167+
168+
def __iter__(self):
169+
return iter(self.value)
170+
171+
def __contains__(self, item):
172+
return item in self.value
173+
174+
def __call__(self, *args, **kwargs):
175+
return self.value(*args, **kwargs)
176+
177+
def __bytes__(self) -> bytes:
178+
return bytes(self.value)
179+
180+
@property
181+
def memory_view(self) -> memoryview:
182+
if isinstance(self.value, (bytes, bytearray)):
183+
return memoryview(self.value)
184+
raise TypeError("Unsupported type for memoryview")
185+
186+
def __buffer__(self, flags: int) -> memoryview: # Buffer protocol
187+
return memoryview(self.value)
188+
189+
async def send_message(self, message: Any, ttl: int = 3) -> None:
190+
if ttl <= 0:
191+
logging.info(f"Message {message} dropped due to TTL")
192+
return
193+
logging.info(f"Atom {self.id} received message: {message}")
194+
for sub in self.subscribers:
195+
await sub.receive_message(message, ttl - 1)
196+
197+
async def receive_message(self, message: Any, ttl: int) -> None:
198+
logging.info(f"Atom {self.id} processing received message: {message} with TTL {ttl}")
199+
await self.send_message(message, ttl)
200+
201+
def subscribe(self, atom: 'Atom') -> None:
202+
self.subscribers.add(atom)
203+
logging.info(f"Atom {self.id} subscribed to {atom.id}")
204+
205+
def unsubscribe(self, atom: 'Atom') -> None:
206+
self.subscribers.discard(atom)
207+
logging.info(f"Atom {self.id} unsubscribed from {atom.id}")
208+
209+
def __add__(self, other):
210+
return self.value + other
211+
212+
def __sub__(self, other):
213+
return self.value - other
214+
215+
def __mul__(self, other):
216+
return self.value * other
217+
218+
def __truediv__(self, other):
219+
return self.value / other
220+
221+
def __floordiv__(self, other):
222+
return self.value // other
223+
224+
@staticmethod
225+
def serialize_data(data: Any) -> bytes:
226+
# return msgpack.packb(data, use_bin_type=True)
227+
pass
228+
229+
@staticmethod
230+
def deserialize_data(data: bytes) -> Any:
231+
# return msgpack.unpackb(data, raw=False)
232+
pass
233+
234+
# Example usage of transform_lambda
235+
source_code = "lambda x: x + 2"
236+
operations = ["multiply", "subtract", "divide"]
237+
238+
for operation in operations:
239+
modified_code = transform_lambda(source_code, operation)
240+
print(f"Operation: {operation}, Modified Code: {modified_code}")

0 commit comments

Comments
 (0)