Download tests/test_engine.py from theapemachine/tensegrity: direct link, hf CLI and curl.
- Browser
- Download file 9.15 kB
-
https://huggingface.co/theapemachine/tensegrity/resolve/refs%2Fpr%2F2/tests/test_engine.py
- Command line
-
hf download hf://theapemachine/tensegrity@refs/pr/2/tests/test_engine.py
-
curl -L -o test_engine.py https://huggingface.co/theapemachine/tensegrity/resolve/refs%2Fpr%2F2/tests/test_engine.py
9.15 kB
| """ | |
| Tests for the unified cognitive engine: FHRR, NGC, and UnifiedField. | |
| """ | |
| import numpy as np | |
| import sys | |
| np.random.seed(42) | |
| def test_fhrr_encoding(): | |
| """Test FHRR compositional encoding.""" | |
| print("=" * 60) | |
| print("TEST 1: FHRR-RNS Compositional Encoding") | |
| print("=" * 60) | |
| from tensegrity.engine.fhrr import FHRREncoder, bind, unbind, bundle | |
| enc = FHRREncoder(dim=2048) | |
| # Test position encoding: similar positions β similar vectors | |
| p10 = enc.encode_position(10) | |
| p11 = enc.encode_position(11) | |
| p100 = enc.encode_position(100) | |
| sim_close = enc.similarity(p10, p11) | |
| sim_far = enc.similarity(p10, p100) | |
| print(f" sim(pos=10, pos=11) = {sim_close:.4f}") | |
| print(f" sim(pos=10, pos=100) = {sim_far:.4f}") | |
| assert np.isfinite(sim_close) | |
| assert np.isfinite(sim_far) | |
| # Test binding + unbinding: encode "red ball on table" | |
| obs = enc.encode_observation({ | |
| "color": "red", | |
| "object": "ball", | |
| "location": "table", | |
| }) | |
| # Unbind to recover | |
| recovered = enc.decode_role(obs, "color") | |
| print(f"\n Encoded: {{color:red, object:ball, location:table}}") | |
| print(f" Decoded role 'color': {recovered[:3]}") | |
| # The top result should be "red" | |
| top_label, top_sim = recovered[0] | |
| print(f" Top match: '{top_label}' (sim={top_sim:.4f})") | |
| assert top_label == "red", f"Expected 'red', got '{top_label}'" | |
| print(f" β Compositional binding β unbinding recovers 'red'") | |
| # Test sequence encoding | |
| seq1 = enc.encode_sequence(["the", "cat", "sat"]) | |
| seq2 = enc.encode_sequence(["the", "cat", "sat"]) | |
| seq3 = enc.encode_sequence(["the", "dog", "ran"]) | |
| sim_same = enc.similarity(seq1, seq2) | |
| sim_diff = enc.similarity(seq1, seq3) | |
| print(f"\n sim('the cat sat', 'the cat sat') = {sim_same:.4f}") | |
| print(f" sim('the cat sat', 'the dog ran') = {sim_diff:.4f}") | |
| assert sim_same > sim_diff, "Same sequence should be more similar" | |
| print(f" β Same sequences more similar than different ones") | |
| # Test numeric vector encoding (modality-agnostic) | |
| v_base = enc.encode_numeric_vector(np.array([1.0, 2.0, 3.0])) | |
| v_near = enc.encode_numeric_vector(np.array([1.0, 2.0, 3.1])) | |
| v_far = enc.encode_numeric_vector(np.array([9.0, 8.0, 7.0])) | |
| sim_near = enc.similarity(v_base, v_near) | |
| sim_numeric_far = enc.similarity(v_base, v_far) | |
| print(f"\n sim([1,2,3], [1,2,3.1]) = {sim_near:.4f}") | |
| print(f" sim([1,2,3], [9,8,7]) = {sim_numeric_far:.4f}") | |
| assert sim_near > sim_numeric_far, ( | |
| "Numeric vectors should be more similar when inputs are nearer in value space " | |
| f"(sim_near={sim_near}, sim_far={sim_numeric_far})" | |
| ) | |
| print(f" β Numeric vectors: similar inputs β similar encodings") | |
| def test_predictive_coding(): | |
| """Test the NGC predictive coding circuit.""" | |
| print("\n" + "=" * 60) | |
| print("TEST 2: Hierarchical Predictive Coding (NGC)") | |
| print("=" * 60) | |
| from tensegrity.engine.ngc import PredictiveCodingCircuit | |
| # 3-layer hierarchy: 64 β 32 β 8 | |
| ngc = PredictiveCodingCircuit( | |
| layer_sizes=[64, 32, 8], | |
| precisions=[1.0, 1.0, 0.5], | |
| settle_steps=30, | |
| learning_rate=0.01, | |
| ) | |
| # Feed repeated observations β the system should learn to predict them | |
| pattern_a = np.sin(np.linspace(0, 2*np.pi, 64)) | |
| pattern_b = np.cos(np.linspace(0, 2*np.pi, 64)) | |
| energies = [] | |
| prediction_errors = [] | |
| for epoch in range(40): | |
| pattern = pattern_a if epoch % 2 == 0 else pattern_b | |
| # Before settling: how surprised? | |
| pe = ngc.prediction_error(pattern) | |
| prediction_errors.append(pe) | |
| # Settle (minimize VFE) | |
| result = ngc.settle(pattern) | |
| energies.append(result["final_energy"]) | |
| # Learn (Hebbian update) | |
| ngc.learn() | |
| print(f" Architecture: {ngc.layer_sizes}") | |
| print(f" Epochs: 40 (alternating sin/cos patterns)") | |
| print(f"\n Energy trajectory:") | |
| print(f" First 5: {[f'{e:.3f}' for e in energies[:5]]}") | |
| print(f" Last 5: {[f'{e:.3f}' for e in energies[-5:]]}") | |
| print(f"\n Prediction error trajectory:") | |
| print(f" First 5: {[f'{e:.3f}' for e in prediction_errors[:5]]}") | |
| print(f" Last 5: {[f'{e:.3f}' for e in prediction_errors[-5:]]}") | |
| # Energy should decrease | |
| early = np.mean(energies[:5]) | |
| late = np.mean(energies[-5:]) | |
| print(f"\n Mean energy (early): {early:.4f}") | |
| print(f" Mean energy (late): {late:.4f}") | |
| # Prediction error should decrease | |
| pe_early = np.mean(prediction_errors[:5]) | |
| pe_late = np.mean(prediction_errors[-5:]) | |
| print(f" Mean PE (early): {pe_early:.4f}") | |
| print(f" Mean PE (late): {pe_late:.4f}") | |
| assert np.all(np.isfinite(energies)) | |
| assert pe_late < pe_early, "Prediction error should decrease after Hebbian updates" | |
| # THE KEY TEST: the system now PREDICTS its input | |
| predicted = ngc.predict_observation() | |
| residual = np.linalg.norm(predicted) | |
| print(f"\n Prediction norm: {residual:.4f} (>0 means the system has learned to predict)") | |
| assert residual > 0.01, "System should generate non-trivial predictions" | |
| print(f" β System generates predictions of sensory input") | |
| print(f" β Prediction error decreases via Hebbian learning (no backprop)") | |
| def test_unified_field(): | |
| """Test the unified energy landscape.""" | |
| print("\n" + "=" * 60) | |
| print("TEST 3: Unified Energy Landscape") | |
| print("=" * 60) | |
| from tensegrity.engine.unified_field import UnifiedField | |
| field = UnifiedField( | |
| obs_dim=128, | |
| hidden_dims=[64, 16], | |
| fhrr_dim=1024, | |
| hopfield_beta=0.05, | |
| ngc_settle_steps=15, | |
| ngc_learning_rate=0.01, | |
| ) | |
| # Feed a sequence of structured observations | |
| observations = [ | |
| {"object": "ball", "color": "red", "location": "table"}, | |
| {"object": "cup", "color": "blue", "location": "shelf"}, | |
| {"object": "ball", "color": "red", "location": "table"}, # Repeated | |
| {"object": "key", "color": "gold", "location": "drawer"}, | |
| {"object": "ball", "color": "red", "location": "table"}, # Repeated again | |
| ] | |
| print(f" Architecture: FHRR({field.fhrr_dim}) β NGC{field.ngc.layer_sizes} β Hopfield") | |
| print(f" Feeding {len(observations)} structured observations...\n") | |
| for i, obs in enumerate(observations): | |
| result = field.observe(obs, input_type="bindings") | |
| e = result["energy"] | |
| print(f" Obs {i+1}: {obs}") | |
| print(f" Total energy: {e.total:.4f}") | |
| print(f" Perception: {e.perception:.4f}") | |
| print(f" Memory: {e.memory:.4f}") | |
| print(f" Prediction error: {e.prediction_error_norm:.4f}") | |
| print(f" Memory similarity: {result['memory_similarity']:.4f}") | |
| # Check that repeated observations become less surprising | |
| energies = [e.total for e in field.energy_history] | |
| pe_list = [e.prediction_error_norm for e in field.energy_history] | |
| print(f"\n Energy trajectory: {[f'{e:.3f}' for e in energies]}") | |
| print(f" Pred. error trajectory: {[f'{p:.3f}' for p in pe_list]}") | |
| # Memory should recall the repeated pattern | |
| print(f"\n Memory patterns stored: {field.memory.n_patterns}") | |
| assert field.memory.n_patterns == len(observations) | |
| assert pe_list[-1] < pe_list[0] | |
| # Make a prediction before seeing the next observation | |
| predicted = field.predict() | |
| print(f" Prediction vector norm: {np.linalg.norm(predicted):.4f}") | |
| print(f" β System predicts, remembers, and settles via unified energy minimization") | |
| # Test with text input | |
| print(f"\n --- Text input mode ---") | |
| result = field.observe("the red ball is on the table", input_type="text") | |
| print(f" Text: 'the red ball is on the table'") | |
| print(f" Energy: {result['energy'].total:.4f}") | |
| assert np.isfinite(result["energy"].total) | |
| print(f" β Modality-agnostic: same pipeline handles structured and text input") | |
| def main(): | |
| tests = [ | |
| ("FHRR Encoding", test_fhrr_encoding), | |
| ("Predictive Coding", test_predictive_coding), | |
| ("Unified Field", test_unified_field), | |
| ] | |
| print("\n" + "β" * 60) | |
| print(" Tensegrity engine: unified energy architecture") | |
| print(" FHRR-RNS Γ Predictive Coding Γ Hopfield memory") | |
| print("β" * 60) | |
| results = [] | |
| for name, fn in tests: | |
| try: | |
| ok = fn() | |
| results.append((name, ok)) | |
| except Exception as e: | |
| print(f"\n β FAILED: {e}") | |
| import traceback; traceback.print_exc() | |
| results.append((name, False)) | |
| print(f"\n{'=' * 60}") | |
| for name, ok in results: | |
| print(f" {'β' if ok else 'β'} {name}") | |
| print(f" {sum(1 for _, ok in results if ok)}/{len(results)} passed") | |
| return all(ok for _, ok in results) | |
| if __name__ == "__main__": | |
| ok = main() | |
| sys.exit(0 if ok else 1) | |