TheGreatUnknown commited on
Commit
af813e1
·
verified ·
1 Parent(s): 022d271

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +29 -0
  2. requirements (1).txt +4 -0
  3. tmfs_topo.py +136 -0
app.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+ from tmfs_topo import TMFS, CONFIG
4
+
5
+ def run_sim(n_agents, steps, phase_step):
6
+ CONFIG["n_agents"] = n_agents
7
+ CONFIG["steps"] = steps
8
+ CONFIG["phase_step"] = phase_step
9
+
10
+ sim = TMFS()
11
+ sim.run()
12
+
13
+ final_dna = [a.dna for a in sim.agents]
14
+ return f"Simulation complete. Final symbolic DNA: {final_dna}"
15
+
16
+ iface = gr.Interface(
17
+ fn=run_sim,
18
+ inputs=[
19
+ gr.Slider(2, 10, value=5, label="Number of Agents"),
20
+ gr.Slider(10, 100, value=50, step=10, label="Simulation Steps"),
21
+ gr.Slider(0.01, 0.5, value=0.15, label="Toroidal Phase Step")
22
+ ],
23
+ outputs="text",
24
+ title="Toroidal Morphic Field Simulator (TMFS)",
25
+ description="Live demo of symbolic agents evolving with morphic memory, DNA mutation, and topological phase logic."
26
+ )
27
+
28
+ if __name__ == "__main__":
29
+ iface.launch()
requirements (1).txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ torch
2
+ numpy
3
+ matplotlib
4
+ gradio
tmfs_topo.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+
6
+ # Config
7
+ CONFIG = {
8
+ "n_agents": 5,
9
+ "steps": 50,
10
+ "memory_capacity": 10,
11
+ "field_decay": 0.1,
12
+ "move_weight": 0.3,
13
+ "grid_size": 10.0,
14
+ "phase_step": 0.15,
15
+ }
16
+
17
+ SYMBOL_VECTORS = {
18
+ "∑": torch.tensor([1.0, 0.0]),
19
+ "Ω": torch.tensor([0.0, 1.0]),
20
+ "ε₀": torch.tensor([-1.0, -1.0]),
21
+ "∇": torch.tensor([1.0, 1.0]),
22
+ "Φ": torch.tensor([0.0, -1.0]),
23
+ "λ": torch.tensor([-1.0, 0.0]),
24
+ }
25
+
26
+ class SymbolicMemory:
27
+ def __init__(self, capacity=CONFIG["memory_capacity"]):
28
+ self.memory = []
29
+ self.capacity = capacity
30
+
31
+ def store(self, symbol):
32
+ if len(self.memory) >= self.capacity:
33
+ self.memory.pop(0)
34
+ self.memory.append(symbol)
35
+
36
+ def get_sequence(self):
37
+ return self.memory.copy() if self.memory else []
38
+
39
+ class Agent:
40
+ def __init__(self, position):
41
+ self.position = torch.tensor(position, dtype=torch.float32)
42
+ self.dna = ["∑", "Ω", "ε₀"]
43
+ self.memory = SymbolicMemory()
44
+ self.theta = 0.0
45
+
46
+ def update_phase(self, delta=CONFIG["phase_step"]):
47
+ self.theta = (self.theta + delta) % (2 * np.pi)
48
+
49
+ def emit_symbol(self, target):
50
+ distance = torch.norm(self.position - target).item()
51
+ idx = min(int(distance / 2), len(self.dna) - 1)
52
+ symbol = self.dna[idx]
53
+ self.memory.store(symbol)
54
+ return symbol
55
+
56
+ def evolve_dna(self, entropy):
57
+ if not self.memory.get_sequence():
58
+ return self.dna[0]
59
+ current = self.dna[0]
60
+ if entropy < 0.9 and current == "∑":
61
+ self.dna[0] = "Ω"
62
+ elif abs(self.theta - 2 * np.pi) < 0.1 and current == "Ω":
63
+ self.dna[0] = "ε₀"
64
+ return self.dna[0]
65
+
66
+ def move(self, field_vector, target):
67
+ field_pull = field_vector - self.position
68
+ target_pull = target - self.position
69
+ self.position += CONFIG["move_weight"] * (field_pull + target_pull)
70
+
71
+ class MorphicField:
72
+ def __init__(self):
73
+ self.position_memory = []
74
+ self.symbol_counts = {}
75
+
76
+ def update(self, positions, symbols):
77
+ self.position_memory.append(positions.clone())
78
+ if len(self.position_memory) > 50:
79
+ self.position_memory.pop(0)
80
+ for symbol in symbols:
81
+ self.symbol_counts[symbol] = self.symbol_counts.get(symbol, 0) + 1
82
+
83
+ def get_field(self, symbols):
84
+ pos_field = torch.zeros(2)
85
+ if self.position_memory:
86
+ weights = torch.exp(-CONFIG["field_decay"] * torch.arange(len(self.position_memory), 0, -1))
87
+ weights /= weights.sum()
88
+ pos_field = sum(w * p.mean(dim=0) for w, p in zip(weights, self.position_memory))
89
+ sym_field = torch.zeros(2)
90
+ for sym in symbols:
91
+ sym_field += SYMBOL_VECTORS.get(sym, torch.zeros(2))
92
+ return pos_field + (sym_field / len(symbols) if symbols else torch.zeros(2))
93
+
94
+ def dominant_symbol(self):
95
+ return max(self.symbol_counts, key=self.symbol_counts.get) if self.symbol_counts else "Ω"
96
+
97
+ class Tracker:
98
+ def __init__(self):
99
+ self.entropy = []
100
+ self.convergence = []
101
+ self.symbol_log = []
102
+
103
+ def update(self, positions, target, step, agents):
104
+ center = positions.mean(dim=0)
105
+ entropy = torch.norm(positions - center, dim=1).std().item() if len(positions) > 1 else 0
106
+ convergence = torch.norm(positions - target, dim=1).mean().item()
107
+ self.entropy.append(entropy)
108
+ self.convergence.append(convergence)
109
+ for i, agent in enumerate(agents):
110
+ self.symbol_log.append((step, agent.position.tolist(), agent.dna[0], agent.theta))
111
+
112
+ class TMFS:
113
+ def __init__(self):
114
+ self.agents = [Agent([np.random.rand()*CONFIG["grid_size"],
115
+ np.random.rand()*CONFIG["grid_size"]])
116
+ for _ in range(CONFIG["n_agents"])]
117
+ self.field = MorphicField()
118
+ self.target = torch.tensor([CONFIG["grid_size"]/2, CONFIG["grid_size"]/2])
119
+ self.tracker = Tracker()
120
+
121
+ def step(self, t):
122
+ positions = torch.stack([a.position for a in self.agents])
123
+ symbols = [a.emit_symbol(self.target) for a in self.agents]
124
+ field_vector = self.field.get_field(symbols)
125
+
126
+ for agent in self.agents:
127
+ agent.update_phase()
128
+ agent.evolve_dna(self.tracker.entropy[-1] if self.tracker.entropy else 2.0)
129
+ agent.move(field_vector, self.target)
130
+
131
+ self.field.update(positions, symbols)
132
+ self.tracker.update(positions, self.target, t, self.agents)
133
+
134
+ def run(self):
135
+ for t in range(CONFIG["steps"]):
136
+ self.step(t)