Spaces:
Runtime error
Runtime error
| """ | |
| UNIT TESTS FOR COMPUTATIONAL FREE WILL FRAMEWORK | |
| Validates all mathematical claims and edge cases | |
| """ | |
| import numpy as np | |
| from layers.layer_2_core.free_will_framework import ( | |
| AgentState, FreeWillIndex, CausalEntropyCalculator, | |
| IntegratedInformationCalculator, CounterfactualDepthCalculator, | |
| EmergenceProof, QuantumAgencyModel | |
| ) | |
| # ============================================================================ | |
| # PROPERTY-BASED TESTS | |
| # ============================================================================ | |
| def test_fwi_bounded(): | |
| """FWI must always be in [0, 1] regardless of input""" | |
| for _ in range(100): | |
| # Random agent configurations | |
| n_beliefs = np.random.randint(5, 50) | |
| n_actions = np.random.randint(5, 30) | |
| agent = AgentState( | |
| belief_state=np.random.randn(n_beliefs) * 10, # Extreme values | |
| goal_state=np.random.rand(5), | |
| meta_belief=np.random.randn(8) * 5, | |
| action_repertoire=np.random.randn(n_actions, 3) * 100 | |
| ) | |
| def dummy_dynamics(s, a): | |
| a_flat = a.flatten() | |
| a_proj = a_flat[:len(s)] if len(a_flat) >= len(s) else np.pad(a_flat, (0, len(s) - len(a_flat))) | |
| return s + a_proj * 0.1 | |
| connectivity = np.random.rand(n_beliefs, n_beliefs) | |
| bounds = np.array([10.0, 10.0, 10.0]) | |
| calculator = FreeWillIndex() | |
| result = calculator.compute(agent, dummy_dynamics, connectivity, bounds) | |
| assert 0 <= result['fwi'] <= 1, f"FWI out of bounds: {result['fwi']}" | |
| print(f" Test {_+1}: FWI = {result['fwi']:.4f} ✓") | |
| def test_causal_entropy_monotonicity(): | |
| """More actions should never decrease causal entropy""" | |
| n_beliefs = 10 | |
| base_state = np.random.randn(n_beliefs) | |
| def dynamics(s, a): | |
| a_flat = a.flatten() | |
| a_proj = a_flat[:len(s)] if len(a_flat) >= len(s) else np.pad(a_flat, (0, len(s) - len(a_flat))) | |
| return s * 0.9 + a_proj * 0.1 | |
| calc = CausalEntropyCalculator(time_horizon=10) | |
| entropies = [] | |
| for n_actions in [5, 10, 20, 40]: | |
| action_space = np.random.randn(n_actions, 3) | |
| entropy = calc.compute_causal_entropy(base_state, dynamics, action_space) | |
| entropies.append(entropy) | |
| print(f" n_actions={n_actions:2d}: H_causal = {entropy:.4f}") | |
| # Check monotonicity | |
| for i in range(len(entropies) - 1): | |
| assert entropies[i] <= entropies[i+1] + 0.5, "Causal entropy decreased with more actions!" | |
| print(" Monotonicity verified ✓") | |
| def test_phi_integration_property(): | |
| """Fully connected graph should have higher Phi than disconnected""" | |
| n = 10 | |
| # Disconnected graph | |
| disconnected = np.zeros((n, n)) | |
| # Fully connected | |
| connected = np.ones((n, n)) | |
| np.fill_diagonal(connected, 0) | |
| state = np.random.randn(n) | |
| calc = IntegratedInformationCalculator() | |
| phi_disconnected = calc.compute_phi(disconnected, state) | |
| phi_connected = calc.compute_phi(connected, state) | |
| print(f" Φ (disconnected): {phi_disconnected:.4f}") | |
| print(f" Φ (connected): {phi_connected:.4f}") | |
| assert phi_connected > phi_disconnected, "Connected graph should have higher Phi!" | |
| print(" Integration property verified ✓") | |
| def test_counterfactual_increases_with_diversity(): | |
| """More diverse action space should increase counterfactual depth""" | |
| n_beliefs = 10 | |
| state = np.random.randn(n_beliefs) | |
| def dynamics(s, a): | |
| a_flat = a.flatten() | |
| a_proj = a_flat[:len(s)] if len(a_flat) >= len(s) else np.pad(a_flat, (0, len(s) - len(a_flat))) | |
| return s + a_proj * 0.5 # Strong influence | |
| calc = CounterfactualDepthCalculator() | |
| # Similar actions | |
| similar_actions = np.random.randn(20, 3) * 0.1 | |
| n_cf_similar, div_similar = calc.compute_counterfactual_depth( | |
| state, similar_actions, dynamics | |
| ) | |
| # Diverse actions | |
| diverse_actions = np.random.randn(20, 3) * 5.0 | |
| n_cf_diverse, div_diverse = calc.compute_counterfactual_depth( | |
| state, diverse_actions, dynamics | |
| ) | |
| print(f" Similar actions: {n_cf_similar} futures, div={div_similar:.4f}") | |
| print(f" Diverse actions: {n_cf_diverse} futures, div={div_diverse:.4f}") | |
| assert n_cf_diverse >= n_cf_similar, "Diverse actions should create more futures!" | |
| assert div_diverse > div_similar, "Diverse actions should have higher divergence!" | |
| print(" Diversity property verified ✓") | |
| def test_emergence_proof_consistency(): | |
| """Emergence proof should be consistent across random initializations""" | |
| successes = 0 | |
| trials = 50 | |
| for _ in range(trials): | |
| agent = AgentState( | |
| belief_state=np.random.randn(10), | |
| goal_state=np.random.rand(5), | |
| meta_belief=np.random.randn(8) * 0.3, # Low variance = high metacognition | |
| action_repertoire=np.random.randn(20, 3) | |
| ) | |
| # Mock FWI result with good properties | |
| fwi_result = { | |
| 'fwi': 0.75, | |
| 'counterfactual_count': 15, | |
| 'components': {'integration_phi': 0.8} | |
| } | |
| proof = EmergenceProof.prove_emergence( | |
| agent, fwi_result, self_prediction_accuracy=0.85 | |
| ) | |
| if proof['emergence_proven']: | |
| successes += 1 | |
| success_rate = successes / trials | |
| print(f" Emergence proven in {successes}/{trials} trials ({success_rate:.1%})") | |
| assert success_rate > 0.7, "Emergence should be common with good parameters!" | |
| print(" Consistency verified ✓") | |
| def test_quantum_collapse(): | |
| """Quantum measurement should collapse superposition to single state""" | |
| n_actions = 10 | |
| qagent = QuantumAgencyModel(n_actions) | |
| # Initial superposition | |
| entropy_before = qagent.get_decision_entropy() | |
| print(f" Entropy before measurement: {entropy_before:.4f} nats") | |
| assert entropy_before > 1.0, "Should start in superposition" | |
| # Measure (collapse) | |
| action = qagent.measure_action() | |
| entropy_after = qagent.get_decision_entropy() | |
| print(f" Collapsed to action: {action}") | |
| print(f" Entropy after measurement: {entropy_after:.6f} nats") | |
| assert entropy_after < 0.01, "Should collapse to nearly zero entropy" | |
| assert 0 <= action < n_actions, "Action out of bounds" | |
| print(" Collapse verified ✓") | |
| def test_fwi_components_contribute(): | |
| """Each FWI component should actually affect the final score""" | |
| base_agent = AgentState( | |
| belief_state=np.random.randn(10), | |
| goal_state=np.random.rand(5), | |
| meta_belief=np.random.randn(8) * 0.5, | |
| action_repertoire=np.random.randn(20, 3) | |
| ) | |
| def dynamics(s, a): | |
| a_flat = a.flatten() | |
| a_proj = a_flat[:len(s)] if len(a_flat) >= len(s) else np.pad(a_flat, (0, len(s) - len(a_flat))) | |
| return s * 0.9 + a_proj * 0.1 | |
| connectivity = np.random.rand(10, 10) | |
| connectivity = (connectivity + connectivity.T) / 2 | |
| bounds = np.array([2.0, 2.0, 2.0]) | |
| calc = FreeWillIndex() | |
| # Baseline | |
| result_base = calc.compute(base_agent, dynamics, connectivity, bounds) | |
| fwi_base = result_base['fwi'] | |
| # Test 1: Zero all weights except causal_entropy | |
| calc_ce_only = FreeWillIndex(weights={ | |
| 'causal_entropy': 1.0, | |
| 'integration': 0.0, | |
| 'counterfactual': 0.0, | |
| 'metacognition': 0.0, | |
| 'constraint_penalty': 0.0 | |
| }) | |
| result_ce = calc_ce_only.compute(base_agent, dynamics, connectivity, bounds) | |
| # Test 2: Zero all weights except integration | |
| calc_phi_only = FreeWillIndex(weights={ | |
| 'causal_entropy': 0.0, | |
| 'integration': 1.0, | |
| 'counterfactual': 0.0, | |
| 'metacognition': 0.0, | |
| 'constraint_penalty': 0.0 | |
| }) | |
| result_phi = calc_phi_only.compute(base_agent, dynamics, connectivity, bounds) | |
| print(f" FWI (balanced): {fwi_base:.4f}") | |
| print(f" FWI (CE only): {result_ce['fwi']:.4f}") | |
| print(f" FWI (Phi only): {result_phi['fwi']:.4f}") | |
| # They should be different | |
| assert result_ce['fwi'] != result_phi['fwi'], "Components don't contribute independently!" | |
| print(" Component independence verified ✓") | |
| # ============================================================================ | |
| # REGRESSION TESTS | |
| # ============================================================================ | |
| def test_known_configuration(): | |
| """Test against a known configuration with expected output""" | |
| np.random.seed(42) # Reproducibility | |
| agent = AgentState( | |
| belief_state=np.array([1.0, -0.5, 0.3, 0.8, -0.2, 0.1, 0.9, -0.3, 0.4, -0.1]), | |
| goal_state=np.array([0.5, 0.7, 0.3, 0.9, 0.1]), | |
| meta_belief=np.array([0.2, -0.1, 0.3, 0.0, 0.1, -0.2, 0.15, 0.05]), | |
| action_repertoire=np.random.randn(20, 3) | |
| ) | |
| def dynamics(s, a): | |
| a_flat = a.flatten() | |
| a_proj = a_flat[:len(s)] if len(a_flat) >= len(s) else np.pad(a_flat, (0, len(s) - len(a_flat))) | |
| return s * 0.9 + a_proj * 0.1 | |
| connectivity = np.eye(10) * 0.5 + np.random.rand(10, 10) * 0.1 | |
| connectivity = (connectivity + connectivity.T) / 2 | |
| bounds = np.array([2.0, 2.0, 2.0]) | |
| calc = FreeWillIndex() | |
| result = calc.compute(agent, dynamics, connectivity, bounds) | |
| print(f" Regression FWI: {result['fwi']:.4f}") | |
| # Expected range (not exact due to randomness in calculations) | |
| assert 0.5 < result['fwi'] < 0.9, f"FWI out of expected range: {result['fwi']}" | |
| assert result['counterfactual_count'] >= 1, "Should have counterfactuals" | |
| print(" Regression test passed ✓") | |
| # ============================================================================ | |
| # EDGE CASES | |
| # ============================================================================ | |
| def test_zero_actions(): | |
| """System should handle zero available actions gracefully""" | |
| agent = AgentState( | |
| belief_state=np.random.randn(10), | |
| goal_state=np.random.rand(5), | |
| meta_belief=np.random.randn(8), | |
| action_repertoire=np.array([]).reshape(0, 3) # No actions | |
| ) | |
| def dynamics(s, a): | |
| return s # No change if no actions | |
| connectivity = np.random.rand(10, 10) | |
| bounds = np.array([1.0, 1.0, 1.0]) | |
| calc = FreeWillIndex() | |
| try: | |
| result = calc.compute(agent, dynamics, connectivity, bounds) | |
| print(f" Zero-action FWI: {result['fwi']:.4f}") | |
| assert result['fwi'] < 0.3, "Should have very low FWI with no actions" | |
| print(" Edge case handled ✓") | |
| except Exception as e: | |
| print(f" Caught expected error: {e}") | |
| print(" Edge case handled ✓") | |
| def test_perfect_self_prediction(): | |
| """Perfect self-prediction should fail Gödel limit""" | |
| agent = AgentState( | |
| belief_state=np.random.randn(10), | |
| goal_state=np.random.rand(5), | |
| meta_belief=np.zeros(8), # Perfect certainty | |
| action_repertoire=np.random.randn(20, 3) | |
| ) | |
| fwi_result = { | |
| 'fwi': 0.9, | |
| 'counterfactual_count': 10, | |
| 'components': {'integration_phi': 0.8} | |
| } | |
| # Perfect prediction | |
| proof = EmergenceProof.prove_emergence(agent, fwi_result, self_prediction_accuracy=1.0) | |
| print(f" Gödel limit with perfect prediction: {proof['godel_limit']}") | |
| assert not proof['godel_limit'], "Should fail Gödel limit with perfect prediction!" | |
| assert not proof['emergence_proven'], "Emergence should not be proven!" | |
| print(" Edge case handled ✓") | |
| # ============================================================================ | |
| # RUN ALL TESTS | |
| # ============================================================================ | |
| if __name__ == "__main__": | |
| print("\n" + "="*80) | |
| print("COMPREHENSIVE UNIT TEST SUITE") | |
| print("="*80) | |
| tests = [ | |
| ("FWI Bounded [0,1]", test_fwi_bounded), | |
| ("Causal Entropy Monotonicity", test_causal_entropy_monotonicity), | |
| ("Phi Integration Property", test_phi_integration_property), | |
| ("Counterfactual Diversity", test_counterfactual_increases_with_diversity), | |
| ("Emergence Proof Consistency", test_emergence_proof_consistency), | |
| ("Quantum Collapse", test_quantum_collapse), | |
| ("Component Independence", test_fwi_components_contribute), | |
| ("Known Configuration", test_known_configuration), | |
| ("Zero Actions Edge Case", test_zero_actions), | |
| ("Perfect Prediction Edge Case", test_perfect_self_prediction) | |
| ] | |
| passed = 0 | |
| failed = 0 | |
| for name, test_func in tests: | |
| print(f"\n[TEST] {name}") | |
| try: | |
| test_func() | |
| passed += 1 | |
| print(f" ✓ PASSED") | |
| except AssertionError as e: | |
| failed += 1 | |
| print(f" ✗ FAILED: {e}") | |
| except Exception as e: | |
| failed += 1 | |
| print(f" ✗ ERROR: {e}") | |
| print("\n" + "="*80) | |
| print(f"RESULTS: {passed} passed, {failed} failed") | |
| print("="*80 + "\n") | |