Vitalis_Devcore / src /cognition /abstraction.py
FerrellSyntheticIntelligence
Sync GitHub with HuggingFace version
f3072b7
"""
AbstractionEngine — Vitalis FSI
The system doesn't just remember experiences.
It builds CONCEPTS from clusters of experiences.
This is the difference between memory and understanding.
Example:
50 individual auth patterns →
one abstract AUTH concept vector →
faster retrieval, analogical reasoning, cross-domain transfer
"""
import numpy as np
import os
import json
from vitalis_ide.math_core.kernel import VitalisKernel
from src.hippocampus import Hippocampus
class AbstractionEngine:
CLUSTER_THRESHOLD = 0.55
MIN_CLUSTER_SIZE = 2
def __init__(self):
self.kernel = VitalisKernel()
self.hippocampus = Hippocampus()
self.path = os.path.expanduser("~/.vitalis_workspace/abstractions.json")
self.abstract_path = os.path.expanduser("~/.vitalis_workspace/abstract_vectors.npy")
self._load()
def _load(self):
self.abstractions = {}
self.abstract_vectors = {}
if os.path.exists(self.path):
with open(self.path) as f:
self.abstractions = json.load(f)
if os.path.exists(self.abstract_path):
self.abstract_vectors = np.load(
self.abstract_path, allow_pickle=True).item()
def _save(self):
os.makedirs(os.path.dirname(self.path), exist_ok=True)
with open(self.path, 'w') as f:
json.dump(self.abstractions, f, indent=2)
np.save(self.abstract_path, self.abstract_vectors)
def abstract(self, vectors: dict) -> dict:
"""
Takes a dict of {slot: vector}.
Finds clusters. Builds concept vectors from each cluster.
Returns {concept_name: abstract_vector}.
"""
slots = list(vectors.keys())
visited = set()
concepts = {}
for i, slot_a in enumerate(slots):
if slot_a in visited:
continue
cluster = [slot_a]
vec_a = vectors[slot_a]
for slot_b in slots[i+1:]:
if slot_b in visited:
continue
vec_b = vectors[slot_b]
sim = self.kernel.similarity(vec_a, vec_b)
if sim > self.CLUSTER_THRESHOLD:
cluster.append(slot_b)
visited.add(slot_b)
if len(cluster) >= self.MIN_CLUSTER_SIZE:
# Bundle cluster into abstract concept
bundle = np.zeros(self.kernel.dim, dtype=np.int32)
for s in cluster:
bundle += vectors[s].astype(np.int32)
concept_vec = np.sign(bundle).astype(np.int8)
concept_vec[concept_vec == 0] = 1
concept_name = f"concept_{len(concepts)}"
concepts[concept_name] = {
"vector": concept_vec,
"members": cluster,
"size": len(cluster)
}
visited.add(slot_a)
return concepts
def run_abstraction_cycle(self, pattern_meta: dict) -> list:
"""
Called during dream cycles.
Takes current pattern library and forms higher-order concepts.
"""
vectors = {}
for slot in self.hippocampus.all_slots():
vec = self.hippocampus.recall(slot)
if vec is not None:
vectors[slot] = vec
if len(vectors) < self.MIN_CLUSTER_SIZE:
return []
new_concepts = self.abstract(vectors)
formed = []
for name, data in new_concepts.items():
full_name = f"abstract_{len(self.abstractions)}_{name}"
self.abstractions[full_name] = {
"members": data["members"],
"size": data["size"]
}
self.abstract_vectors[full_name] = data["vector"]
formed.append(full_name)
print(f"[ABSTRACTION] Concept formed: {full_name} ({data['size']} members)")
if formed:
self._save()
return formed
def query_abstractions(self, query_vec: np.ndarray, top_k: int = 3) -> list:
"""Search abstract concept space — faster than raw pattern search."""
results = []
for name, vec in self.abstract_vectors.items():
sim = self.kernel.similarity(query_vec, vec)
results.append((sim, name, self.abstractions.get(name, {})))
results.sort(reverse=True)
return results[:top_k]