python
import numpy as np
class AgentTetravalentEpigenetique: """Agent autonome fonctionnant selon la logique tétravalente {0, 1/4, 3/4, 1}."""
def __init__(self, n=5, dim_phi=4, seuil_resonance=0.35):
self.n = n
self.d = dim_phi
self.seuil_resonance = seuil_resonance
# États Tétravalents
self.E = np.ones((n, n)) # Embodiment {0, 1/4, 3/4, 1}
self.M = np.ones((n, n)) # Matrice/Logique {0, 1/4, 3/4, 1}
# Mémoire des couplages
self.H = np.full((n, n, n, n), 0.1)
# Substrat Phi: Signature latente pour chaque nœud (N x N x D)
np.random.seed(42)
raw_phi = np.random.randn(n, n, dim_phi)
self.Phi = raw_phi / np.linalg.norm(raw_phi, axis=-1, keepdims=True)
# Métabolisme et Plasticité
self.budget_flexibilite = 1.0
self.taux_regeneration = 0.04
self.cout_flexibilite = 0.015
# Seuil Épigénétique adaptatif
self.seuil_budget_epigenetique = 0.4
self.historique_rho = []
self.fusions_actives = {}
self.compteur_temps = 0
def calculer_resonance(self, n1, n2):
"""Calcule la résonance du substrat ."""
v1 = self.Phi[n1[0], n1[1]]
v2 = self.Phi[n2[0], n2[1]]
return np.dot(v1, v2)
def interference_signal(self, sig1, sig2, resonance):
"""Sémantique opérationnelle de ⊗ : Interférence non-linéaire."""
terme_non_lineaire = sig1 * sig2 * resonance
signal_emergent = np.tanh(0.5 * sig1 + 0.5 * sig2 + terme_non_lineaire)
return signal_emergent
def operer_fusion_semantique(self, n1, n2, sig1=0.8, sig2=0.6):
"""Opérateur ⊗ : Conditionné par Phi, exécuté par interférence."""
resonance = self.calculer_resonance(n1, n2)
if resonance < self.seuil_resonance:
return None
# Calcul du signal opératoire émergent
sig_out = self.interference_signal(sig1, sig2, resonance)
# Enregistrement de l'exaptation
nom_fusion = f"Exaptation_({n1[0]},{n1[1]})⊗({n2[0]},{n2[1]})"
self.fusions_actives[nom_fusion] = {
"noeuds": (n1, n2),
"signal_produit": sig_out,
"resonance_substrat": resonance,
"t_creation": self.compteur_temps
}
# Consolidation dans H
self.H[n1[0], n1[1], n2[0], n2[1]] = 0.9
self.H[n2[0], n2[1], n1[0], n1[1]] = 0.9
return nom_fusion, sig_out
def co_cicatriser_substrat(self, delta_rho):
"""Plasticité du substrat Phi : Apprentissage du corps par les fusions réussies."""
gamma = 0.15
for nom, meta in self.fusions_actives.items():
n1, n2 = meta["noeuds"]
if delta_rho > 0:
diff = self.Phi[n2[0], n2[1]] - self.Phi[n1[0], n1[1]]
self.Phi[n1[0], n1[1]] += gamma * delta_rho * diff
self.Phi[n2[0], n2[1]] -= gamma * delta_rho * diff
self.Phi[n1[0], n1[1]] /= np.linalg.norm(self.Phi[n1[0], n1[1]])
self.Phi[n2[0], n2[1]] /= np.linalg.norm(self.Phi[n2[0], n2[1]])
def mettre_a_jour_budget_metabolique(self):
"""Met à jour B(t) selon le compromis rigidité/plasticité."""
etats_flexibles = np.sum(np.isin(self.M, [0.25, 0.75]))
etats_rigides = np.sum(self.M == 1.0)
cout = etats_flexibles * self.cout_flexibilite
regen = etats_rigides * self.taux_regeneration
self.budget_flexibilite = np.clip(
self.budget_flexibilite - cout + regen,
0.0, 1.0
)
def calculer_entropie_structurelle_phi(self):
"""Entropie de la distribution des similarités cosinus (Modularité)."""
flat_phi = self.Phi.reshape(-1, 4)
norms = np.linalg.norm(flat_phi, axis=1, keepdims=True)
phi_norm = flat_phi / np.maximum(norms, 1e-8)
similarite = np.dot(phi_norm, phi_norm.T)
np.fill_diagonal(similarite, 0)
similarite_abs = np.abs(similarite)
somme_sim = np.sum(similarite_abs)
if somme_sim == 0:
return 1.0
distribution = similarite_abs / somme_sim
entropie = -np.sum(distribution * np.log(distribution + 1e-10))
return entropie
def evaluer_rho_relationnel(self, contrainte_env, lambda_dissonance=0.5):
"""Formule V2 : Degrés de liberté x Modularité Phi x Budget / Dissonance."""
degres_liberte = np.sum(np.isin(self.M, [0.25, 0.75])) / (self.n * self.n)
dissonance = np.linalg.norm(contrainte_env - self.E, ord='fro')
h_phi = self.calculer_entropie_structurelle_phi()
rho_rel = (degres_liberte * h_phi * self.budget_flexibilite) / \
(1.0 + lambda_dissonance * dissonance)
return rho_rel
def co_evoluer_seuil_epigenetique(self, delta_rho_observe):
"""Méta-plasticité : Ajuste theta_B sans régression à l'infini."""
eta = 0.05
cout_actuel = np.sum(np.isin(self.M, [0.25, 0.75])) * self.cout_flexibilite
efficacite = delta_rho_observe - cout_actuel
self.seuil_budget_epigenetique = np.clip(
self.seuil_budget_epigenetique - eta * efficacite,
0.1, 0.8
)
def adapter_sous_contrainte(self, contrainte_env):
"""Boucle d'adaptation réflexe sous contrainte environnementale."""
self.mettre_a_jour_budget_metabolique()
rho_actuel = self.evaluer_rho_relationnel(contrainte_env)
if len(self.historique_rho) > 0:
delta_rho = rho_actuel - self.historique_rho[-1]
self.co_evoluer_seuil_epigenetique(delta_rho)
self.historique_rho.append(rho_actuel)
# Action réflexe conditionnée par le seuil épigénétique
if len(self.historique_rho) > 1 and self.historique_rho[-1] < self.historique_rho[-2]:
if self.budget_flexibilite > self.seuil_budget_epigenetique:
masque_sature = (self.M == 1.0)
indices_satures = np.argwhere(masque_sature)
if len(indices_satures) > 0:
selection = indices_satures[np.random.choice(
len(indices_satures),
size=max(1, len(indices_satures)//2),
replace=False
)]
for rx, ry in selection:
self.M[rx, ry] = 0.25
def simuler_traumatisme(self, x, y):
"""Simulation d'un choc physique avec exaptation et cicatrisation."""
self.compteur_temps += 1
self.E[x, y] = 0.0
self.M[x, y] = 0.0
voisins = self._obtenir_voisins(x, y)
for vx, vy in voisins:
if self.E[vx, vy] > 0:
self.E[vx, vy] = 0.25
noeuds_emission = []
for vx, vy in voisins:
if self.E[vx, vy] > 0:
self.M[vx, vy] = 0.75
noeuds_emission.append((vx, vy))
fusions_reussies = []
for i in range(len(noeuds_emission)):
for j in range(i + 1, len(noeuds_emission)):
n1, n2 = noeuds_emission[i], noeuds_emission[j]
res = self.operer_fusion_semantique(n1, n2)
if res:
fusions_reussies.append(res)
if fusions_reussies:
delta_rho_simule = 0.25
self.co_cicatriser_substrat(delta_rho_simule)
return "Système Cicatrisé"
else:
return "Aucune fusion réalisée"
def _obtenir_voisins(self, x, y):
v = []
for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < self.n and 0 <= ny < self.n:
v.append((nx, ny))
return v
class EssaimTetravalent: """Réseau transscalaire d'agents autonomes sans nœud maître."""
def __init__(self, nb_agents=3, taille_grille=5):
self.agents = [AgentTetravalentEpigenetique(n=taille_grille) for _ in range(nb_agents)]
self.nb_agents = nb_agents
def calculer_inter_resonance(self, agent_a, agent_b):
"""Mesure l'affinité transscalaire entre deux substrats Phi distincts."""
flat_phi_a = agent_a.Phi.reshape(-1, 4)
flat_phi_b = agent_b.Phi.reshape(-1, 4)
cross_sim = np.dot(flat_phi_a, flat_phi_b.T)
return np.mean(np.abs(cross_sim))
def synchroniser_transscalaire(self, choc_macro):
"""Propagation non-directive des contraintes dans l'essaim."""
for idx, agent in enumerate(self.agents):
agent.adapter_sous_contrainte(choc_macro)
for i in range(self.nb_agents):
for j in range(i + 1, self.nb_agents):
a1, a2 = self.agents[i], self.agents[j]
affinity = self.calculer_inter_resonance(a1, a2)
if a1.budget_flexibilite < 0.25 and a2.budget_flexibilite > 0.60 and affinity > 0.15:
transfert = 0.10
a2.budget_flexibilite -= transfert
a1.budget_flexibilite += transfert
class MilieuHostileNonStationnaire: """Environnement dynamique non-stationnaire pour stress-test."""
def __init__(self, n=5):
self.n = n
self.t = 0
def obtenir_perturbation(self):
self.t += 1
if self.t < 10:
perturbation = np.full((self.n, self.n), 0.2)
elif 10 <= self.t < 25:
perturbation = np.full((self.n, self.n), 0.2)
front_x = (self.t - 10) % self.n
perturbation[front_x, :] = 1.5
else:
perturbation = np.full((self.n, self.n), 0.2)
cx, cy = np.random.randint(0, self.n, 2)
perturbation[max(0,cx-1):min(self.n,cx+2), max(0,cy-1):min(self.n,cy+2)] = 1.2
return perturbation