|
|
class CascadingBody: |
|
|
def __init__(self): |
|
|
self.actions = {} |
|
|
self.things = {} |
|
|
self.relationships = {} |
|
|
self.execution_stack = [] |
|
|
self.meta_actions = {} |
|
|
|
|
|
|
|
|
self._bootstrap_core_actions() |
|
|
|
|
|
def _bootstrap_core_actions(self): |
|
|
|
|
|
self.define_action('define_action', self._define_action) |
|
|
self.define_action('relate', self._relate_thing_action) |
|
|
self.define_action('cascade', self._execute_cascade) |
|
|
self.define_action('compose', self._compose_actions) |
|
|
|
|
|
def define_action(self, name, function): |
|
|
"""Define or redefine an action""" |
|
|
self.actions[name] = function |
|
|
return f"Action '{name}' defined" |
|
|
|
|
|
def _define_action(self, action_name, *params): |
|
|
"""Meta-action: Define new actions at runtime""" |
|
|
if len(params) >= 1: |
|
|
|
|
|
source_action = params[0] |
|
|
if source_action in self.actions: |
|
|
self.actions[action_name] = self.actions[source_action] |
|
|
return f"Action '{action_name}' created from '{source_action}'" |
|
|
|
|
|
|
|
|
def new_action(*args): |
|
|
|
|
|
result = f"Executing programmable action: {action_name}" |
|
|
|
|
|
return result |
|
|
|
|
|
self.actions[action_name] = new_action |
|
|
return f"Programmable action '{action_name}' defined" |
|
|
|
|
|
def _relate_thing_action(self, thing, action): |
|
|
"""Create thing-action relationships""" |
|
|
if thing not in self.relationships: |
|
|
self.relationships[thing] = [] |
|
|
self.relationships[thing].append(action) |
|
|
return f"Thing '{thing}' now relates to action '{action}'" |
|
|
|
|
|
def execute_on_thing(self, thing, *args): |
|
|
"""Execute all actions related to a thing, creating cascades""" |
|
|
if thing not in self.relationships: |
|
|
return f"No actions defined for thing '{thing}'" |
|
|
|
|
|
results = [] |
|
|
for action_name in self.relationships[thing]: |
|
|
if action_name in self.actions: |
|
|
self.execution_stack.append(f"{thing}->{action_name}") |
|
|
result = self.actions[action_name](*args) |
|
|
results.append(result) |
|
|
|
|
|
|
|
|
if isinstance(result, str) and result in self.relationships: |
|
|
cascade_result = self.execute_on_thing(result) |
|
|
results.append(f"CASCADE: {cascade_result}") |
|
|
|
|
|
self.execution_stack.pop() |
|
|
|
|
|
return results |
|
|
|
|
|
def _execute_cascade(self, trigger, depth=3): |
|
|
"""Explicit cascade execution""" |
|
|
if depth <= 0: |
|
|
return "Max cascade depth reached" |
|
|
|
|
|
results = [] |
|
|
current = trigger |
|
|
for i in range(depth): |
|
|
if current in self.relationships: |
|
|
action_results = self.execute_on_thing(current) |
|
|
results.append(f"Level {i}: {action_results}") |
|
|
|
|
|
if action_results and isinstance(action_results[-1], str): |
|
|
current = action_results[-1] |
|
|
else: |
|
|
break |
|
|
return results |
|
|
|
|
|
def _compose_actions(self, new_action_name, *action_sequence): |
|
|
"""Compose multiple actions into one new action""" |
|
|
def composed(*args): |
|
|
results = [] |
|
|
for action_name in action_sequence: |
|
|
if action_name in self.actions: |
|
|
result = self.actions[action_name](*args) |
|
|
results.append(result) |
|
|
return results |
|
|
|
|
|
self.actions[new_action_name] = composed |
|
|
return f"Composed action '{new_action_name}' from {action_sequence}" |