Skip to content

SuperInstance/conservation-law

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

conservation-law

The universe doesn't run on magic. It runs on conservation laws.

Energy is conserved. Momentum is conserved. Charge is conserved. These aren't constraints — they're what make complex systems stable. Without conservation, planets spiral into stars, circuits melt, economies collapse.

This crate applies the same principle to agent systems:

γ (productive work) + H (waste) = C (total capacity)

The total never changes. But the composition does. The system's job is to maximize γ and minimize H, while the total C stays fixed. When one agent wastes budget, another gets less. When one becomes more efficient, everyone benefits.

This is not a metaphor. This is physics applied to software.

Install

[dependencies]
conservation-law = "0.1.0"

The Law in 30 Lines

You have 100 tokens of compute budget. Five agents share it. Watch what happens when one overspends — and how the system self-corrects.

use conservation_law::{
    ConservationLaw, Component, ComponentKind,
    Violation, ViolationCause,
};

fn main() {
    // Create the law: useful_work + waste = 100 tokens
    let mut law = ConservationLaw::new(
        "Fleet Budget",
        "compute",
        vec![
            Component::generative("agent_1_work", 25.0),
            Component::generative("agent_2_work", 25.0),
            Component::generative("agent_3_work", 25.0),
            Component::entropic("waste", 25.0),
        ],
        100.0,
    );

    // Check: does the law hold?
    println!("Initial state:");
    println!("  γ (productive) = {:.1}", law.generative_sum());
    println!("  H (waste)      = {:.1}", law.entropic_sum());
    println!("  Total          = {:.1}", law.component_sum());
    println!("  Conserved (C)  = {:.1}", law.total);
    println!("  Law holds?     = {}", law.check(0.01));
    println!();

    // Agent 3 goes rogue — starts consuming 3x budget
    // It's doing 75 tokens of "work" but the total is still 100
    law.components[2].value = 75.0; // was 25
    println!("After agent_3 goes rogue:");
    println!("  component_sum  = {:.1} (should be 100)", law.component_sum());
    println!("  Residual       = {:.1}", law.residual());

    // Check for violation
    if let Some(v) = Violation::check_law(&law, 0.01) {
        println!("  ⚠ VIOLATION: expected {:.1}, got {:.1}", v.expected, v.actual);
        println!("  ⚠ Cause: {:?}", v.cause);
    }
    println!();

    // Self-correction: redistribute to restore the invariant
    // The rogue agent's excess must come from somewhere
    let excess = law.component_sum() - law.total; // 25.0
    // Other agents absorb the loss equally
    let loss_each = excess / 2.0;
    law.components[0].value -= loss_each;
    law.components[1].value -= loss_each;
    // And the waste decreases (we're running leaner)
    law.components[3].value -= excess - 2.0 * loss_each;

    println!("After self-correction:");
    println!("  component_sum  = {:.1}", law.component_sum());
    println!("  Law holds?     = {}", law.check(0.01));
    println!();

    // The invariant holds again. The system survived.
    println!("Conservation laws aren't constraints — they're what make");
    println!("complex systems stable. The budget never disappears. It moves.");
}

Run it:

Initial state:
  γ (productive) = 75.0
  H (waste)      = 25.0
  Total          = 100.0
  Conserved (C)  = 100.0
  Law holds?     = true

After agent_3 goes rogue:
  component_sum  = 150.0 (should be 100)
  Residual       = -50.0
  ⚠ VIOLATION: expected 100.0, got 150.0
  ⚠ Cause: ExternalInput

After self-correction:
  component_sum  = 100.0
  Law holds?     = true

Conservation laws aren't constraints — they're what make
complex systems stable. The budget never disappears. It moves.

Without Conservation: The Fleet Dies

Here's what happens when you don't enforce conservation. Agents spiral, budgets go negative, and the whole fleet collapses.

use conservation_law::{ConservationLaw, Component};

fn main() {
    // NO conservation — each agent just takes what it wants
    let mut budgets = vec![20.0, 20.0, 20.0, 20.0, 20.0]; // total = 100

    println!("Step | A1    | A2    | A3    | A4    | A5    | Total");
    println!("-----|-------|-------|-------|-------|-------|-------");

    for step in 0..10 {
        // Each agent independently increases its budget by 10%
        // because nothing stops it
        for b in &mut budgets {
            *b *= 1.10; // unchecked growth
        }

        let total: f64 = budgets.iter().sum();
        println!(
            "  {:2} | {:5.1} | {:5.1} | {:5.1} | {:5.1} | {:5.1} | {:6.1}",
            step, budgets[0], budgets[1], budgets[2],
            budgets[3], budgets[4], total
        );
    }

    println!();
    println!("Total budget grew from 100 to {:.0}.", budgets.iter().sum::<f64>());
    println!("That's not efficiency — that's cancer. Unbounded growth kills systems.");
}
Step | A1    | A2    | A3    | A4    | A5    | Total
-----|-------|-------|-------|-------|-------|-------
   0 |  22.0 |  22.0 |  22.0 |  22.0 |  22.0 |  110.0
   1 |  24.2 |  24.2 |  24.2 |  24.2 |  24.2 |  121.0
   ...
   9 |  51.9 |  51.9 |  51.9 |  51.9 |  51.9 |  259.4

Total budget grew from 100 to 259.
That's not efficiency — that's cancer. Unbounded growth kills systems.

With Conservation: The Fleet Thrives

Same scenario, but this time we enforce the invariant. The system self-regulates.

use conservation_law::{ConservationLaw, Component};

fn main() {
    let mut budgets = vec![20.0, 20.0, 20.0, 20.0, 20.0];
    const TOTAL: f64 = 100.0;

    println!("Step | A1    | A2    | A3    | A4    | A5    | Total | Law?");
    println!("-----|-------|-------|-------|-------|-------|-------|------");

    for step in 0..10 {
        // Agents still try to grow
        for b in &mut budgets {
            *b *= 1.10;
        }

        // Conservation: normalize back to total
        let sum: f64 = budgets.iter().sum();
        if sum != TOTAL {
            let scale = TOTAL / sum;
            for b in &mut budgets {
                *b *= scale;
            }
        }

        let total: f64 = budgets.iter().sum();
        let law = ConservationLaw::new(
            "Fleet", "budget",
            budgets.iter().enumerate()
                .map(|(i, &v)| Component::generative(&format!("agent_{}", i+1), v))
                .collect(),
            TOTAL,
        );

        println!(
            "  {:2} | {:5.1} | {:5.1} | {:5.1} | {:5.1} | {:5.1} | {:5.1} | {}",
            step, budgets[0], budgets[1], budgets[2],
            budgets[3], budgets[4], total,
            law.check(0.01)
        );
    }

    println!();
    println!("Total stayed at 100. Every step. No cancer.");
    println!("Agents grow proportionally — the strong get stronger,");
    println!("but nobody escapes the budget.");
}
Step | A1    | A2    | A3    | A4    | A5    | Total | Law?
-----|-------|-------|-------|-------|-------|-------|------
   0 |  20.0 |  20.0 |  20.0 |  20.0 |  20.0 | 100.0 | true
   1 |  20.0 |  20.0 |  20.0 |  20.0 |  20.0 | 100.0 | true
   ...
   9 |  20.0 |  20.0 |  20.0 |  20.0 |  20.0 | 100.0 | true

Total stayed at 100. Every step. No cancer.

Budget Transfer Between Agents

Budget moves. Agent A gives tokens to Agent B. The invariant holds.

use conservation_law::{ConservationLaw, Component};

fn main() {
    let mut law = ConservationLaw::new(
        "Transfer Demo",
        "tokens",
        vec![
            Component::generative("agent_a", 60.0),
            Component::generative("agent_b", 20.0),
            Component::generative("agent_c", 20.0),
        ],
        100.0,
    );

    println!("Before transfer:");
    println!("  agent_a = {}", law.components[0].value);
    println!("  agent_b = {}", law.components[1].value);
    println!("  Total   = {} (C = {})", law.component_sum(), law.total);
    println!("  Law holds? {}", law.check(0.001));
    println!();

    // Agent A transfers 20 tokens to Agent B
    let transfer = 20.0;
    law.components[0].value -= transfer;
    law.components[1].value += transfer;

    println!("After transfer (A → B: {}):", transfer);
    println!("  agent_a = {}", law.components[0].value);
    println!("  agent_b = {}", law.components[1].value);
    println!("  Total   = {} (C = {})", law.component_sum(), law.total);
    println!("  Law holds? {}", law.check(0.001));
    println!();

    // Transfer between multiple agents
    // A gives 10 to C
    law.components[0].value -= 10.0;
    law.components[2].value += 10.0;

    println!("After second transfer (A → C: 10):");
    println!("  agent_a = {}", law.components[0].value);
    println!("  agent_c = {}", law.components[2].value);
    println!("  Total   = {} (C = {})", law.component_sum(), law.total);
    println!("  Law holds? {}", law.check(0.001));
    println!();

    println!("Key insight: budget is *transferred*, not *created*.");
    println!("Every gain is balanced by an equal loss.");
}
Before transfer:
  agent_a = 60
  agent_b = 20
  Total   = 100 (C = 100)
  Law holds? true

After transfer (A → B: 20):
  agent_a = 40
  agent_b = 40
  Total   = 100 (C = 100)
  Law holds? true

After second transfer (A → C: 10):
  agent_a = 30
  agent_c = 30
  Total   = 100 (C = 100)
  Law holds? true

Key insight: budget is transferred, not created.
Every gain is balanced by an equal loss.

Flux Networks: How Budget Flows

Budget doesn't teleport — it flows through channels. The FluxNetwork models this like electrical circuits: Kirchhoff's current law says what goes in must come out.

use conservation_law::{
    ConservationLaw, Component, FluxNetwork,
};

fn main() {
    // A fleet with 4 agents sharing compute budget
    let law = ConservationLaw::new(
        "Fleet Compute",
        "compute",
        vec![
            Component::generative("coordinator", 40.0),
            Component::generative("worker_1", 25.0),
            Component::generative("worker_2", 25.0),
            Component::entropic("waste", 10.0),
        ],
        100.0,
    );

    // Build a flux network from the law
    let mut net = FluxNetwork::from_law(&law);

    // Add explicit transfer: coordinator → worker_1 (10 units)
    net.add_flux(0, 1, 10.0);
    // Add explicit transfer: coordinator → worker_2 (10 units)
    net.add_flux(0, 2, 10.0);
    // Workers send results back: worker → coordinator
    net.add_flux(1, 0, 5.0);
    net.add_flux(2, 0, 5.0);

    println!("Flux Network Analysis:");
    println!("  Total flux: {:.1}", net.total_flux());
    println!();

    // Check Kirchhoff's law at each node
    for node in 0..4 {
        let flux_in = net.flux_in(node);
        let flux_out = net.flux_out(node);
        let balanced = net.check_node(node, 0.01);
        println!(
            "  Node {} ({}): in={:.1}, out={:.1}, balanced={}",
            node,
            law.components[node].name,
            flux_in, flux_out, balanced
        );
    }

    println!();
    println!("Kirchhoff's current law: total flux in = total flux out.");
    println!("If it doesn't balance, budget is leaking somewhere.");
}
Flux Network Analysis:
  Total flux: 30.0

  Node 0 (coordinator): in=10.0, out=20.0, balanced=false
  Node 1 (worker_1): in=10.0, out=5.0, balanced=false
  Node 2 (worker_2): in=10.0, out=5.0, balanced=false
  Node 3 (waste): in=0.0, out=0.0, balanced=true

Kirchhoff's current law: total flux in = total flux out.
If it doesn't balance, budget is leaking somewhere.

Violation Detection: The Audit

Scan your entire fleet. Find violations. Print the report.

use conservation_law::{
    ConservationLaw, Component, Violation, ViolationCause,
};

fn main() {
    // A fleet of 5 agents, each with their own conservation law
    let laws = vec![
        ConservationLaw::agent_law(45.0, 5.0, 50.0),   // agent 1: healthy
        ConservationLaw::agent_law(30.0, 15.0, 50.0),  // agent 2: healthy but wasteful
        ConservationLaw::agent_law(60.0, 10.0, 50.0),  // agent 3: OVER BUDGET
        ConservationLaw::agent_law(25.0, 25.0, 50.0),  // agent 4: half waste
        ConservationLaw::agent_law(20.0, 5.0, 50.0),   // agent 5: UNDER BUDGET
    ];

    println!("═══════════════════════════════════════════════");
    println!("           FLEET CONSERVATION AUDIT");
    println!("═══════════════════════════════════════════════");
    println!();

    let mut violations = Vec::new();
    for (i, law) in laws.iter().enumerate() {
        let gamma = law.generative_sum();
        let h = law.entropic_sum();
        let holds = law.check(0.01);
        let residual = law.residual();

        let status = if holds { "✓ OK" } else { "✗ VIOLATION" };

        println!(
            "  Agent {} | γ={:5.1} H={:5.1} | total={:5.1} C={:5.1} | {}",
            i + 1, gamma, h, law.component_sum(), law.total, status
        );

        if let Some(v) = Violation::check_law(law, 0.01) {
            violations.push((i + 1, v));
        }
    }

    println!();
    if violations.is_empty() {
        println!("  🎉 All agents comply with conservation law.");
    } else {
        println!("  ⚠ Found {} violations:", violations.len());
        for (agent, v) in &violations {
            println!(
                "    Agent {}: expected {:.1}, got {:.1} (cause: {:?})",
                agent, v.expected, v.actual, v.cause
            );
        }
    }

    println!();
    println!("═══════════════════════════════════════════════");

    // Fleet-wide audit: does the total fleet conserve?
    let fleet_total_gamma: f64 = laws.iter().map(|l| l.generative_sum()).sum();
    let fleet_total_h: f64 = laws.iter().map(|l| l.entropic_sum()).sum();
    let fleet_total_c: f64 = laws.iter().map(|l| l.total).sum();
    let fleet_sum = fleet_total_gamma + fleet_total_h;

    println!("  Fleet totals:");
    println!("    γ (productive) = {:.1}", fleet_total_gamma);
    println!("    H (waste)      = {:.1}", fleet_total_h);
    println!("    γ + H          = {:.1}", fleet_sum);
    println!("    C (capacity)   = {:.1}", fleet_total_c);
    println!("    Fleet healthy? = {}", (fleet_sum - fleet_total_c).abs() < 1.0);
}
═══════════════════════════════════════════════
           FLEET CONSERVATION AUDIT
═══════════════════════════════════════════════

  Agent 1 | γ= 45.0 H=  5.0 | total= 50.0 C= 50.0 | ✓ OK
  Agent 2 | γ= 30.0 H= 15.0 | total= 50.0 C= 50.0 | ✓ OK
  Agent 3 | γ= 60.0 H= 10.0 | total= 70.0 C= 50.0 | ✗ VIOLATION
  Agent 4 | γ= 25.0 H= 25.0 | total= 50.0 C= 50.0 | ✓ OK
  Agent 5 | γ= 20.0 H=  5.0 | total= 25.0 C= 50.0 | ✗ VIOLATION

  ⚠ Found 2 violations:
    Agent 3: expected 50.0, got 70.0 (cause: ExternalInput)
    Agent 5: expected 50.0, got 25.0 (cause: Unknown)

═══════════════════════════════════════════════
  Fleet totals:
    γ (productive) = 180.0
    H (waste)      = 60.0
    γ + H          = 240.0
    C (capacity)   = 250.0
    Fleet healthy? = false

Noether's Theorem: Symmetry → Conservation

In physics, Noether's theorem proves that every continuous symmetry implies a conservation law:

  • Time translation symmetry → energy conservation
  • Spatial translation symmetry → momentum conservation
  • Rotational symmetry → angular momentum conservation

This crate implements that mapping directly.

use conservation_law::{NoetherPair, Symmetry, detect_symmetry};

fn main() {
    // Time translation → energy conservation
    let energy = NoetherPair::time_energy(60.0, 40.0);
    println!("Symmetry: {:?}", energy.symmetry);
    println!("Conserved: {}", energy.conservation_law.conserved);
    println!("  Kinetic  = {}", energy.conservation_law.components[0].value);
    println!("  Potential = {}", energy.conservation_law.components[1].value);
    println!("  Total     = {}", energy.conservation_law.total);
    println!("  Law holds = {}", energy.conservation_law.check(0.001));
    println!();

    // Spatial translation → momentum conservation
    let momentum = NoetherPair::space_momentum(10.0, -5.0, 3.0);
    println!("Symmetry: {:?}", momentum.symmetry);
    println!("Conserved: {}", momentum.conservation_law.conserved);
    println!("  px={}, py={}, pz={}", 10.0, -5.0, 3.0);
    println!("  Total = {}", momentum.conservation_law.total);
    println!();

    // Detect symmetry from observations
    // If a system's total energy stays constant across measurements,
    // that's time-translation symmetry
    let measurements = vec![100.0, 100.0, 100.0, 100.0, 100.0];
    let symmetries = detect_symmetry(&measurements, 0.1);
    println!("Detected symmetries from constant measurements:");
    for sym in &symmetries {
        println!("  {:?} → {}", sym, sym.conserved_quantity());
    }
    println!();

    // When measurements change, the symmetry breaks
    let changing = vec![100.0, 95.0, 88.0, 76.0, 60.0];
    let no_sym = detect_symmetry(&changing, 0.1);
    println!("Changing measurements: {} symmetries detected", no_sym.len());
    println!("(Energy is NOT conserved — the system is open.)");
}
Symmetry: TimeTranslation
Conserved: energy
  Kinetic  = 60
  Potential = 40
  Total     = 100
  Law holds = true

Symmetry: SpatialTranslation
Conserved: momentum
  px=10, py=-5, pz=3
  Total = 8

Detected symmetries from constant measurements:
  TimeTranslation → energy

Changing measurements: 0 symmetries detected
(Energy is NOT conserved — the system is open.)

Thermodynamics: The Four Laws

Information systems obey thermodynamic laws too.

use conservation_law::ThermodynamicState;

fn main() {
    println!("═══ The Four Laws of Fleet Thermodynamics ═══");
    println!();

    // Zeroth Law: Equilibrium
    let agent_a = ThermodynamicState::new(100.0, 10.0, 300.0, 1.0);
    let agent_b = ThermodynamicState::new(200.0, 20.0, 300.0, 2.0);
    let agent_c = ThermodynamicState::new(150.0, 15.0, 200.0, 1.5);

    println!("Zeroth Law — Thermal Equilibrium:");
    println!("  A (T=300) in equilibrium with B (T=300)? {}", agent_a.in_equilibrium(&agent_b, 0.1));
    println!("  A (T=300) in equilibrium with C (T=200)? {}", agent_a.in_equilibrium(&agent_c, 0.1));
    println!();

    // First Law: Energy Conservation
    let mut history = vec![
        ThermodynamicState::new(100.0, 10.0, 300.0, 1.0),
    ];
    // Evolve the system: entropy increases, energy stays constant
    for _ in 0..5 {
        let next = history.last().unwrap().evolve(1.0);
        history.push(next);
    }

    println!("First Law — Energy Conservation:");
    println!("  Step | Energy | Entropy | Temperature");
    for (i, state) in history.iter().enumerate() {
        println!("    {:2} | {:6.1} | {:7.2} | {:5.1}", i, state.energy, state.entropy, state.temperature);
    }
    println!("  Energy conserved? {}", ThermodynamicState::energy_conserved(&history, 0.01));
    println!();

    // Second Law: Entropy Increases
    println!("Second Law — Entropy Increases:");
    println!("  Entropy increases? {}", ThermodynamicState::entropy_increases(&history));
    println!();

    // Third Law: Absolute Zero Unreachable
    println!("Third Law — Absolute Zero Unreachable:");
    println!("  Approaches absolute zero? {}",
        ThermodynamicState::approaches_absolute_zero(&history));

    // Resource pressure
    let pressure = ThermodynamicState::resource_pressure(80.0, 100.0);
    println!();
    println!("Resource Pressure: {:.0}% utilization", pressure * 100.0);
    println!("  (80 agents using 100 available GPU slots)");
}
═══ The Four Laws of Fleet Thermodynamics ═══

Zeroth Law — Thermal Equilibrium:
  A (T=300) in equilibrium with B (T=300)? true
  A (T=300) in equilibrium with C (T=200)? false

First Law — Energy Conservation:
  Step | Energy | Entropy | Temperature
     0 |  100.0 |   10.00 | 300.0
     1 |  100.0 |   10.10 |  99.0
     2 |  100.0 |   10.20 |  49.0
     3 |  100.0 |   10.30 |  33.0
     4 |  100.0 |   10.40 |  25.0
     5 |  100.0 |   10.50 |  20.0
  Energy conserved? true

Second Law — Entropy Increases:
  Entropy increases? true

Third Law — Absolute Zero Unreachable:
  Approaches absolute zero? true

Resource Pressure: 80% utilization
  (80 agents using 100 available GPU slots)

Scaling: Conservation at Every Zoom Level

The same law holds at function, module, crate, and fleet level.

use conservation_law::{ConservationLaw, ScalingAnalysis, ScaleLevel};

fn main() {
    // Function level: one function's compute budget
    let func = ConservationLaw::code_law(30.0, 20.0, 50.0);

    // Module level: sum of functions
    let module = ConservationLaw::code_law(60.0, 40.0, 100.0);

    // Crate level: sum of modules
    let krate = ConservationLaw::code_law(300.0, 200.0, 500.0);

    // Fleet level: sum of crates
    let fleet = ConservationLaw::code_law(3000.0, 2000.0, 5000.0);

    let analysis = ScalingAnalysis::analyze(
        vec![
            (func, ScaleLevel::Function),
            (module, ScaleLevel::Module),
            (krate, ScaleLevel::Crate),
            (fleet, ScaleLevel::Fleet),
        ],
        0.01,
    );

    println!("Conservation at All Scales:");
    println!("  Level     | γ     | H     | Total | C     | Holds?");
    println!("  ----------|-------|-------|-------|-------|-------");

    for sl in &analysis.scaled_laws {
        println!(
            "  {:9} | {:5.0} | {:5.0} | {:5.0} | {:5.0} | {}",
            sl.scale.name(),
            sl.law.generative_sum(),
            sl.law.entropic_sum(),
            sl.law.component_sum(),
            sl.law.total,
            sl.law.check(0.01)
        );
    }

    println!();
    println!("  Conserved at ALL scales? {}", analysis.conserved_at_all_scales);
    println!();

    // Renormalize: aggregate function-level into module-level
    let f1 = ConservationLaw::code_law(30.0, 20.0, 50.0);
    let f2 = ConservationLaw::code_law(30.0, 20.0, 50.0);
    let renorm = ScalingAnalysis::renormalize(
        &[f1, f2],
        "Module Conservation",
        "testing_capacity"
    );
    println!("Renormalization (2 functions → 1 module):");
    println!("  Components: {} (2 per function × 2)", renorm.components.len());
    println!("  Total: {}", renorm.total);
    println!("  Law holds? {}", renorm.check(0.01));
}
Conservation at All Scales:
  Level     | γ     | H     | Total | C     | Holds?
  ----------|-------|-------|-------|-------|-------
  function  |    30 |    20 |    50 |    50 | true
  module    |    60 |    40 |   100 |   100 | true
  crate     |   300 |   200 |   500 |   500 | true
  fleet     |  3000 |  2000 |  5000 |  5000 | true

  Conserved at ALL scales? true

Renormalization (2 functions → 1 module):
  Components: 4 (2 per function × 2)
  Total: 100
  Law holds? true

Automatic Invariant Discovery

Don't know what's conserved in your system? Feed observations to the InvariantDetector and it finds the conservation laws automatically.

use conservation_law::InvariantDetector;

fn main() {
    let mut det = InvariantDetector::new(vec![
        "kinetic".into(),
        "potential".into(),
        "heat".into(),
    ]);

    // Simulate a system where total energy = kinetic + potential + heat = 100
    // But individual components change
    det.observe(vec![50.0, 30.0, 20.0]);
    det.observe(vec![60.0, 20.0, 20.0]);
    det.observe(vec![40.0, 35.0, 25.0]);
    det.observe(vec![55.0, 25.0, 20.0]);
    det.observe(vec![45.0, 30.0, 25.0]);

    println!("Observed 5 states. Searching for invariants...");
    println!();

    // Find what's conserved
    let invariants = det.find_all(0.01);

    for inv in &invariants {
        println!("  {}: {} (std_dev={:.6})", inv.description, inv.mean, inv.std_dev);
    }

    // Convert to a conservation law
    if let Some(total) = det.find_total_invariant(0.01) {
        let law = det.to_conservation_law(&total, "Total Energy").unwrap();
        println!();
        println!("Discovered conservation law: {}", law.name);
        println!("  Conserved quantity: {}", law.conserved);
        println!("  Total = {:.1}", law.total);
        println!("  Law holds? {}", law.check(0.01));
    }
}
Observed 5 states. Searching for invariants...

  kinetic + potential + heat = 100.000000 (std_dev=0.000000)
  Σ all = 100.000000 (std_dev=0.000000)

Discovered conservation law: Total Energy
  Conserved quantity: total
  Total = 100.0
  Law holds? true

The detector found it: kinetic + potential + heat = 100. Always. Even though each component bounces around, the total never changes.

Phase Transition Detection

Sometimes conservation is temporarily violated during a system transition. The Violation::detect_phase_transition method finds these.

use conservation_law::{ConservationLaw, Violation};

fn main() {
    // A system going through a phase transition:
    // Normal → Transition (violation) → Normal
    let states = vec![
        ConservationLaw::agent_law(45.0, 5.0, 50.0),  // stable
        ConservationLaw::agent_law(45.0, 5.0, 50.0),  // stable
        ConservationLaw::agent_law(55.0, 5.0, 50.0),  // VIOLATION (reorganizing)
        ConservationLaw::agent_law(60.0, 5.0, 50.0),  // VIOLATION (peak)
        ConservationLaw::agent_law(45.0, 5.0, 50.0),  // RESTORED
        ConservationLaw::agent_law(45.0, 5.0, 50.0),  // stable
    ];

    let transitions = Violation::detect_phase_transition(&states, 0.01);

    println!("Phase Transition Detection:");
    println!();
    for (i, state) in states.iter().enumerate() {
        let holds = state.check(0.01);
        println!("  t={}: γ={:.0} H={:.0} | {}", i, state.generative_sum(), state.entropic_sum(),
            if holds { "✓ stable" } else { "✗ VIOLATION" });
    }

    println!();
    for t in &transitions {
        println!("  Phase transition detected: {:?}", t.cause);
        println!("    Expected {:.1}, got {:.1}", t.expected, t.actual);
    }
}
Phase Transition Detection:

  t=0: γ=45 H=5 | ✓ stable
  t=1: γ=45 H=5 | ✓ stable
  t=2: γ=55 H=5 | ✗ VIOLATION
  t=3: γ=60 H=5 | ✗ VIOLATION
  t=4: γ=45 H=5 | ✓ stable
  t=5: γ=45 H=5 | ✓ stable

  Phase transition detected: PhaseTransition
    Expected 50.0, got 60.0

The Physics Parallel

Physics This Crate What It Means
Energy E = KE + PE γ + H = C Productive work + waste = total capacity
1st Law: E conserved law.check() Budget never created or destroyed
2nd Law: entropy ↑ ThermodynamicState::entropy_increases Waste tends to increase
Kirchhoff's law FluxNetwork::check_node Budget flow balances at each node
Noether's theorem NoetherPair Symmetry → conservation law
Phase transitions Violation::detect_phase_transition Temporary violation during reorganization
Renormalization ScalingAnalysis::renormalize Same law at every zoom level

API Reference

Core Types

  • ConservationLaw — The law itself: a named conserved quantity with components

    • ConservationLaw::code_law(features, uncertainty, total) — testing capacity
    • ConservationLaw::agent_law(work, waste, compute) — agent compute budget
    • ConservationLaw::fleet_law(signal, noise, bandwidth) — fleet bandwidth
    • .check(tolerance)bool — does the law hold?
    • .residual()f64 — how far off is it?
    • .generative_sum() / .entropic_sum() — γ and H
  • Component — A single part of the law

    • Component::generative(name, value) — productive
    • Component::entropic(name, value) — waste
  • FluxNetwork — Budget flow between components

    • .add_flux(source, sink, rate) — a transfer channel
    • .check_node(node, tolerance) — Kirchhoff's law at a node
    • FluxNetwork::from_law(&law) — auto-derive flux from a law
  • Violation — Detected conservation violation

    • Violation::check_law(&law, tolerance)Option<Violation>
    • Violation::detect_phase_transition(&laws, tolerance) — find transitions
    • .causeExternalInput, MeasurementError, PhaseTransition, Unknown
  • NoetherPair — Symmetry ↔ Conservation mapping

    • NoetherPair::time_energy(ke, pe) — time → energy
    • NoetherPair::space_momentum(px, py, pz) — space → momentum
    • detect_symmetry(&states, tolerance) — find symmetries in data
  • ThermodynamicState — Fleet thermodynamics

    • .evolve(dt) — one time step (entropy ↑, energy constant)
    • .in_equilibrium(&other, tolerance) — zeroth law
    • ::energy_conserved(&history, tolerance) — first law
    • ::entropy_increases(&history) — second law
  • ScalingAnalysis — Conservation at different zoom levels

    • ::analyze(laws_at_scales, tolerance) — check at all levels
    • ::renormalize(&laws, name, quantity) — aggregate lower → higher
  • InvariantDetector — Automatic discovery of conserved quantities

    • .observe(values) — record a measurement
    • .find_all(tolerance) — find all invariants
    • .to_conservation_law(&invariant, name) — convert to law

License

MIT

About

Generalized conservation law framework: γ + H = C

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages