Spaces:
Running
Running
| """Social model (STAGE H): identity recognition, interaction history, trust | |
| that EMERGES from interaction outcomes (never hard-coded friendship), | |
| persistent relationships.""" | |
| from dataclasses import dataclass, field | |
| from typing import Any, Dict, List, Optional | |
| TRUST_INIT = 0.3 # neutral prior, not friendship | |
| TRUST_LEARNING_RATE = 0.2 | |
| class InteractionRecord: | |
| tick: int | |
| kind: str # taught_by | taught_to | communicated | cooperated | competed | |
| outcome: float # -1..1 signed outcome for SELF | |
| other_id: str = "" | |
| def to_dict(self) -> Dict[str, Any]: | |
| return dict(self.__dict__) | |
| class SocialRecord: | |
| other_id: str | |
| interactions: int = 0 | |
| positive_outcomes: int = 0 | |
| negative_outcomes: int = 0 | |
| trust: float = TRUST_INIT | |
| first_tick: int = 0 | |
| last_tick: int = 0 | |
| history: List[InteractionRecord] = field(default_factory=list) | |
| def to_dict(self) -> Dict[str, Any]: | |
| return {"other_id": self.other_id, "interactions": self.interactions, | |
| "positive_outcomes": self.positive_outcomes, | |
| "negative_outcomes": self.negative_outcomes, | |
| "trust": self.trust, "first_tick": self.first_tick, | |
| "last_tick": self.last_tick, | |
| "history": [h.to_dict() for h in self.history[-20:]]} | |
| def from_dict(cls, d: Dict[str, Any]) -> "SocialRecord": | |
| return cls(d["other_id"], int(d.get("interactions", 0)), | |
| int(d.get("positive_outcomes", 0)), | |
| int(d.get("negative_outcomes", 0)), float(d.get("trust", TRUST_INIT)), | |
| int(d.get("first_tick", 0)), int(d.get("last_tick", 0)), | |
| [InteractionRecord(**h) for h in d.get("history", [])]) | |
| class SocialMemory: | |
| """Per-organism social memory: recognition + emergent trust.""" | |
| def __init__(self, self_id: str, trust_lr: float = TRUST_LEARNING_RATE): | |
| self.self_id = self_id | |
| self.trust_lr = float(trust_lr) | |
| self.records: Dict[str, SocialRecord] = {} | |
| def knows(self, other_id: str) -> bool: | |
| return other_id in self.records | |
| def trust_of(self, other_id: str) -> float: | |
| rec = self.records.get(other_id) | |
| return rec.trust if rec is not None else TRUST_INIT | |
| def record_interaction(self, other_id: str, tick: int, kind: str, | |
| outcome: float) -> SocialRecord: | |
| if not other_id or other_id == self.self_id: | |
| raise ValueError("invalid interaction partner") | |
| outcome = max(-1.0, min(1.0, float(outcome))) | |
| rec = self.records.get(other_id) | |
| if rec is None: | |
| rec = SocialRecord(other_id=other_id, first_tick=tick) | |
| self.records[other_id] = rec | |
| rec.interactions += 1 | |
| rec.last_tick = tick | |
| rec.history.append(InteractionRecord(tick, kind, outcome, other_id)) | |
| if outcome > 0.05: | |
| rec.positive_outcomes += 1 | |
| elif outcome < -0.05: | |
| rec.negative_outcomes += 1 | |
| # trust EMERGES from outcomes (delta rule toward observed outcome) | |
| rec.trust = float(min(1.0, max(0.0, | |
| rec.trust + self.trust_lr * (outcome - rec.trust)))) | |
| return rec | |
| def relationship_strength(self, other_id: str) -> float: | |
| """Persistent-relationship evidence: repeated interactions + trust.""" | |
| rec = self.records.get(other_id) | |
| if rec is None: | |
| return 0.0 | |
| frequency = min(1.0, rec.interactions / 10.0) | |
| return round(0.5 * rec.trust + 0.5 * frequency, 4) | |
| def top_partners(self, k: int = 3) -> List[str]: | |
| ranked = sorted(self.records.values(), | |
| key=lambda r: (self.relationship_strength(r.other_id), | |
| r.interactions), reverse=True) | |
| return [r.other_id for r in ranked[:k]] | |
| def summary(self) -> Dict[str, Any]: | |
| return {"self_id": self.self_id, "known_others": len(self.records), | |
| "strong_relationships": sum( | |
| 1 for r in self.records.values() | |
| if self.relationship_strength(r.other_id) >= 0.5), | |
| "total_interactions": sum(r.interactions for r in self.records.values())} | |
| def snapshot(self) -> Dict[str, Any]: | |
| return {"self_id": self.self_id, "trust_lr": self.trust_lr, | |
| "records": [r.to_dict() for r in self.records.values()]} | |
| def restore(cls, payload: Dict[str, Any]) -> "SocialMemory": | |
| mem = cls(payload["self_id"], payload.get("trust_lr", TRUST_LEARNING_RATE)) | |
| for d in payload.get("records", []): | |
| rec = SocialRecord.from_dict(d) | |
| mem.records[rec.other_id] = rec | |
| return mem | |