#!/usr/bin/env python3 """ MLE — Morpho-Logic Engine — Interactive Demo ============================================== Demonstrates the full reasoning pipeline: 1. Knowledge base construction 2. Query injection → routing → binding → energy minimization → response 3. Analogy solving 4. Concept composition 5. Multi-hop reasoning """ import numpy as np import time import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from mle import MorphoLogicEngine from mle.binding import BinaryBinding def banner(text): w = 70 print(f"\n{'━'*w}") print(f" {text}") print(f"{'━'*w}") def main(): print(""" ╔══════════════════════════════════════════════════════════════════════╗ ║ ║ ║ ███╗ ███╗ ██╗ ███████╗ ║ ║ ████╗ ████║ ██║ ██╔════╝ ║ ║ ██╔████╔██║ ██║ █████╗ Morpho-Logic Engine ║ ║ ██║╚██╔╝██║ ██║ ██╔══╝ v0.1.0 ║ ║ ██║ ╚═╝ ██║ ███████╗███████╗ ║ ║ ╚═╝ ╚═╝ ╚══════╝╚══════╝ Energy-Based Reasoning AI ║ ║ ║ ║ 4096-bit Hyperdimensional Vectors · SIMD-Optimized · CPU-Native ║ ║ Sparse Distributed Memory · Circular Convolution Binding ║ ║ Hopfield Energy Dynamics · Gradient-Free Reasoning ║ ║ ║ ╚══════════════════════════════════════════════════════════════════════╝ """) np.random.seed(42) # ══════════════════════════════════════════════════════════════════════ # 1. Initialize Engine # ══════════════════════════════════════════════════════════════════════ banner("1. INITIALIZING ENGINE") engine = MorphoLogicEngine( beam_width=500, max_routing_depth=3, max_reasoning_steps=5, energy_mode='hybrid', hopfield_beta=8.0, relaxation_iterations=30, ) print(" ✓ Engine initialized (beam=500, hybrid energy, Hopfield β=8.0)") # ══════════════════════════════════════════════════════════════════════ # 2. Build Knowledge Base # ══════════════════════════════════════════════════════════════════════ banner("2. BUILDING KNOWLEDGE BASE") # Concepts organized by category knowledge = { 'Animals': { 'concepts': ['cat', 'dog', 'fish', 'bird', 'horse', 'eagle', 'dolphin', 'snake'], 'relations': [ ('cat', 'is_a', 'animal'), ('dog', 'is_a', 'animal'), ('fish', 'is_a', 'animal'), ('bird', 'is_a', 'animal'), ('horse', 'is_a', 'animal'), ('eagle', 'is_a', 'bird'), ('dolphin', 'is_a', 'animal'), ('snake', 'is_a', 'animal'), ('cat', 'is_a', 'pet'), ('dog', 'is_a', 'pet'), ('fish', 'lives_in', 'water'), ('dolphin', 'lives_in', 'water'), ('bird', 'has', 'wing'), ('bird', 'can', 'fly'), ('eagle', 'can', 'fly'), ('fish', 'can', 'swim'), ('dolphin', 'can', 'swim'), ('horse', 'can', 'run'), ('snake', 'can', 'crawl'), ] }, 'Nature': { 'concepts': ['water', 'ocean', 'river', 'sky', 'forest', 'mountain', 'tree', 'leaf', 'flower', 'rain'], 'relations': [ ('tree', 'has', 'leaf'), ('tree', 'in', 'forest'), ('flower', 'has', 'color'), ('rain', 'from', 'sky'), ('river', 'contains', 'water'), ('ocean', 'contains', 'water'), ('mountain', 'has', 'peak'), ] }, 'Royalty': { 'concepts': ['king', 'queen', 'prince', 'princess', 'man', 'woman', 'child', 'crown', 'throne'], 'relations': [ ('king', 'is_a', 'man'), ('queen', 'is_a', 'woman'), ('prince', 'is_a', 'man'), ('princess', 'is_a', 'woman'), ('king', 'married_to', 'queen'), ('king', 'has', 'crown'), ('king', 'sits_on', 'throne'), ('prince', 'child_of', 'king'), ('princess', 'child_of', 'queen'), ] }, 'Vehicles': { 'concepts': ['car', 'boat', 'airplane', 'bicycle', 'wheel', 'engine', 'road', 'wing'], 'relations': [ ('car', 'has', 'wheel'), ('car', 'has', 'engine'), ('car', 'on', 'road'), ('boat', 'on', 'water'), ('airplane', 'has', 'wing'), ('airplane', 'can', 'fly'), ('bicycle', 'has', 'wheel'), ] }, 'Abstract': { 'concepts': ['animal', 'pet', 'color', 'peak', 'speed', 'size'], 'relations': [] } } # Meta-relations meta_relations = ['is_a', 'has', 'can', 'lives_in', 'in', 'on', 'married_to', 'child_of', 'from', 'contains', 'sits_on'] total_concepts = 0 total_relations = 0 for category, data in knowledge.items(): for c in data['concepts']: engine.add_concept(c) total_concepts += 1 for s, r, o in data['relations']: engine.add_relation(s, r, o) total_relations += 1 for r in meta_relations: if engine.binding.get_concept(r) is None: engine.add_concept(r) total_concepts += 1 stats = engine.stats() print(f" ✓ {total_concepts} concepts loaded") print(f" ✓ {total_relations} relations stored") print(f" ✓ Memory: {stats['memory']['size']} entries, " f"{stats['memory']['memory_mb']:.2f} MB") # ══════════════════════════════════════════════════════════════════════ # 3. Simple Concept Queries # ══════════════════════════════════════════════════════════════════════ banner("3. CONCEPT QUERIES") queries = ["cat", "ocean", "king", "airplane"] for q in queries: result = engine.reason(q, max_steps=3) top3 = result['response']['nearest_concepts'][:3] energies = [s.energy for s in result['reasoning_chain'] if s.energy != float('inf')] e_str = " → ".join(f"{e:.4f}" for e in energies) if energies else "N/A" print(f"\n Query: '{q}'") print(f" Nearest: {[(n, f'{s:.3f}') for n, s in top3]}") print(f" Energy: {e_str}") print(f" Steps: {result['num_steps']}, Latency: {result['latency_ms']:.0f}ms") # ══════════════════════════════════════════════════════════════════════ # 4. Association # ══════════════════════════════════════════════════════════════════════ banner("4. ASSOCIATION QUERIES") for concept in ["cat", "water", "king"]: assocs = engine.associate(concept, top_k=5) print(f"\n '{concept}' → {[(n, f'{s:.3f}') for n, s in assocs[:5]]}") # ══════════════════════════════════════════════════════════════════════ # 5. Analogy Solving # ══════════════════════════════════════════════════════════════════════ banner("5. ANALOGY SOLVING") analogies = [ ("king", "man", "queen"), # king:man :: queen:? → woman ("bird", "fly", "fish"), # bird:fly :: fish:? → swim ("car", "road", "boat"), # car:road :: boat:? → water ] for a, b, c in analogies: result = engine.solve_analogy(a, b, c) ranking = result['codebook_ranking'][:5] print(f"\n {a} : {b} :: {c} : ?") print(f" Top-5: {[(n, f'{s:.3f}') for n, s in ranking]}") print(f" Latency: {result['latency_ms']:.0f}ms") # ══════════════════════════════════════════════════════════════════════ # 6. Concept Composition # ══════════════════════════════════════════════════════════════════════ banner("6. CONCEPT COMPOSITION") compositions = [ ("water", "animal"), # → fish/dolphin ("sky", "animal"), # → bird/eagle ("man", "crown"), # → king ] for concepts in compositions: result = engine.compose(*concepts) top5 = result['response']['nearest_concepts'][:5] print(f"\n {' + '.join(concepts)} → ?") print(f" Top-5: {[(n, f'{s:.3f}') for n, s in top5]}") # ══════════════════════════════════════════════════════════════════════ # 7. Structured Queries (Role-Filler) # ══════════════════════════════════════════════════════════════════════ banner("7. STRUCTURED QUERIES") struct_queries = [ ({"subject": "bird", "relation": "can"}, ["subject", "relation"]), ({"subject": "king", "relation": "has"}, ["subject", "relation"]), ] for query_dict, roles in struct_queries: result = engine.reason(query_dict, max_steps=2, roles=roles) print(f"\n Query: {query_dict}") if result['response'].get('role_fillers'): for role, fillers in result['response']['role_fillers'].items(): print(f" {role} → {[(n, f'{s:.3f}') for n, s in fillers[:3]]}") # ══════════════════════════════════════════════════════════════════════ # 8. Multi-Step Reasoning Chain # ══════════════════════════════════════════════════════════════════════ banner("8. MULTI-STEP REASONING (Energy Trajectory)") result = engine.reason("forest", max_steps=5) chain = result['reasoning_chain'] print(f"\n Query: 'forest'") print(f" Steps: {len(chain)}") for i, step in enumerate(chain): routing = step.routing_result n_candidates = len(routing.indices) if routing else 0 print(f" Step {i}: E={step.energy:.4f}, " f"candidates={n_candidates}, " f"t={step.timestamp:.3f}s") print(f"\n Total energy reduction: {result['total_energy_reduction']:.4f}") print(f" Total latency: {result['latency_ms']:.0f}ms") print(f"\n Final response:") top5 = result['response']['nearest_concepts'][:5] print(f" Nearest: {[(n, f'{s:.3f}') for n, s in top5]}") # ══════════════════════════════════════════════════════════════════════ # 9. Performance Summary # ══════════════════════════════════════════════════════════════════════ banner("9. PERFORMANCE SUMMARY") # Benchmark: 100 random queries latencies = [] for _ in range(100): concept = np.random.choice(list(engine.binding._codebook.keys())) t0 = time.perf_counter() engine.reason(concept, max_steps=2) latencies.append((time.perf_counter() - t0) * 1000) print(f""" Query Performance (100 queries, 2 reasoning steps): Average latency: {np.mean(latencies):>8.1f} ms Median latency: {np.median(latencies):>8.1f} ms P95 latency: {np.percentile(latencies, 95):>8.1f} ms P99 latency: {np.percentile(latencies, 99):>8.1f} ms Throughput: {1000/np.mean(latencies):>8.1f} queries/sec Memory Footprint: Entries: {stats['memory']['size']:>8d} Memory: {stats['memory']['memory_mb']:>8.2f} MB Per entry: {stats['memory']['memory_mb']*1024*1024/max(stats['memory']['size'],1):>8.0f} bytes Architecture: Vector dimension: {4096:>8d} bits Storage per vec: {512:>8d} bytes (64 × uint64) Beam width: {engine.router.beam_width:>8d} LSH tables: {engine.memory.lsh.n_tables:>8d} LSH projections: {engine.memory.lsh.n_projections:>8d} """) print("━" * 70) print(" MLE Demo Complete ✓") print("━" * 70) if __name__ == '__main__': main()