Source code for mercurial.consciousness.biasing

"""Top‑down biasing operator (MERCURIAL A.4, Definition 4.5)."""

from typing import Optional, Tuple

import numpy as np

from mercurial.core.patterns import Pattern
from mercurial.core.wilson_cowan import WilsonCowanPopulation


[docs] class TopDownBiasing: """ Implements organizational causation: consciousness biases reality patterns. The biasing strength κ_bias determines how strongly conscious patterns influence the evolution of local reality patterns. """
[docs] def __init__(self, kappa_bias: float = 0.1): """ Parameters ---------- kappa_bias : float Biasing strength (κ_bias). Typical range 0.01–0.5. """ self.kappa_bias = kappa_bias
[docs] def compute_biasing_field( self, consciousness_pattern: Pattern, reality_pattern: Pattern, target_level: int, projection_dim: Optional[int] = None, ) -> np.ndarray: """ Compute the biasing term B[reality] from consciousness. """ from mercurial.core.dynamics import free_energy_gradient # Project consciousness onto reality's state space v_conscious = consciousness_pattern.V.flatten() v_reality = reality_pattern.V.flatten() min_dim = min(len(v_conscious), len(v_reality)) v_projected = v_conscious[:min_dim] # Compute gradient of reality's free energy (returns tuple) grad_F, _ = free_energy_gradient(reality_pattern) grad_flat = grad_F.flatten()[:min_dim] # Biasing term: consciousness pulls reality toward its own configuration bias = -self.kappa_bias * (v_projected - grad_flat) # Apply range enforcement penalty penalty = self.enforce_range(consciousness_level=9, target_level=target_level) bias *= penalty # Reshape to match reality's pattern shape if bias.shape != reality_pattern.V.shape: bias = bias.reshape(reality_pattern.V.shape) return bias
[docs] def apply_biasing( self, reality_pattern: Pattern, consciousness_pattern: Pattern, dt: float, target_level: int ) -> Pattern: """ Apply biasing to reality pattern for one time step. """ bias = self.compute_biasing_field(consciousness_pattern, reality_pattern, target_level) new_V = reality_pattern.V + bias * dt return Pattern( new_V, reality_pattern.C, reality_pattern.R, label=f"{reality_pattern.label}_biased" )
[docs] def enforce_range(self, consciousness_level: int, target_level: int) -> float: """ Return a multiplicative penalty (0-1) for biasing outside allowed range. Consciousness can only bias Levels 7-10 effectively. """ allowed_min = 7 allowed_max = 10 if allowed_min <= target_level <= allowed_max: return 1.0 # no penalty # Distance outside allowed range if target_level < allowed_min: distance = allowed_min - target_level else: distance = target_level - allowed_max # Exponential decay penalty: halved every level outside range return np.exp(-distance) # distance=1 → 0.368, distance=2 → 0.135
[docs] def compute_external_input( self, consciousness_pattern, target_population: WilsonCowanPopulation, target_level: int ) -> Tuple[float, float]: """ Compute P_ext and Q_ext from consciousness biasing. """ # Biasing strength from range enforcement penalty = self.enforce_range(consciousness_level=9, target_level=target_level) # Simple: bias modulates the input to both populations bias_strength = self.kappa_bias * penalty # For simplicity, add bias to both P and Q equally P_bias = bias_strength * np.mean(consciousness_pattern.V.flatten()) Q_bias = bias_strength * np.mean(consciousness_pattern.V.flatten()) return P_bias, Q_bias
# ======================================================================== # Biasing for Wilson‑Cowan neural populations (appended) # ========================================================================
[docs] def compute_neural_bias( self, consciousness_pattern, target_neural_pattern, target_level: int ) -> Tuple[float, float]: """ Compute external input bias (P_ext, Q_ext) for a Wilson‑Cowan population. """ penalty = self.enforce_range(consciousness_level=9, target_level=target_level) # Use the consciousness pattern's mean activity as bias strength if ( hasattr(consciousness_pattern, "E_history") and consciousness_pattern.E_history is not None ): bias_val = np.mean(consciousness_pattern.E_history[-100:]) else: bias_val = 0.5 # default bias = self.kappa_bias * penalty * bias_val # Add to both excitatory and inhibitory inputs return bias, bias
def _compute_gradient(self, pattern: Pattern) -> np.ndarray: """Compute gradient of free energy with respect to pattern state.""" from mercurial.core.dynamics import free_energy_gradient grad, _ = free_energy_gradient(pattern) return grad.flatten()