pith. machine review for the scientific record. sign in
theorem proved tactic proof high

conservation_from_balance

show as:
view Lean formalization →

In a balanced ledger the net flow at any agent vanishes. Number theorists constructing Euler ledgers and physicists deriving conservation from J-symmetry cite this result. The proof rewrites net flow as a sum of flow contributions, establishes that the event multiset equals its image under reciprocal, and invokes the antisymmetry property of flow_contribution to conclude the sum is zero.

claimLet $L$ be a ledger whose events satisfy the balanced-list condition. For any agent $a$, the net flow of $L$ at $a$ equals zero.

background

The module shows that J-symmetry forces double-entry ledger structure. A Ledger consists of a list of RecognitionEvent together with the balanced_list predicate asserting that every event e appears exactly as often as its reciprocal. The flow_contribution function extracts the signed logarithmic increment an event contributes to a given agent's net flow.

proof idea

The proof first equates net_flow to the sum of flow_contribution over the event list by unfolding the foldl definition and using induction on the list. It then switches to a multiset view M of the events. Because balanced_list implies M equals M.map reciprocal (via count equality and injectivity of reciprocal), and because flow_contribution satisfies f(reciprocal e) = -f(e), the sum of f over M equals its own negative and therefore vanishes.

why it matters in Recognition Science

This theorem supplies the conservation law required by the finite Euler ledger construction in ConcreteEulerLedger. It closes the step from J-symmetry to zero net flow in the LedgerForcing module, which itself sits inside the forcing chain that derives double-entry accounting from the Recognition Composition Law. The result touches the open question of extending the argument from finite lists to infinite or continuous ledgers.

scope and limits

Lean usage

theorem finiteEulerLedger_net_flow_zero (σ : ℝ) (hσ : 0 < σ) (support : List Nat.Primes) (agent : ℕ) : LedgerForcing.net_flow (finiteEulerLedger σ hσ support) agent = 0 := by exact LedgerForcing.conservation_from_balance _ (finiteEulerLedger_balanced σ hσ support) agent

formal statement (Lean)

 168theorem conservation_from_balance (L : Ledger) (_hbal : balanced L) (agent : ℕ) :
 169    net_flow L agent = 0 := by

proof body

Tactic-mode proof.

 170  have hbal : balanced_list L.events := _hbal
 171
 172  -- Rewrite `net_flow` as a `List.sum` of `flow_contribution`.
 173  have step_eq :
 174      ∀ (acc : ℝ) (e : RecognitionEvent),
 175        (if e.source = agent then acc + Real.log e.ratio
 176          else if e.target = agent then acc + Real.log e.ratio
 177          else acc)
 178          = acc + flow_contribution e agent := by
 179    intro acc e
 180    unfold flow_contribution
 181    by_cases hs : e.source = agent
 182    · simp [hs]
 183    · by_cases ht : e.target = agent
 184      · simp [hs, ht]
 185      · simp [hs, ht]
 186
 187  have h_foldl :
 188      ∀ acc,
 189        L.events.foldl (fun acc e =>
 190            if e.source = agent then acc + Real.log e.ratio
 191            else if e.target = agent then acc + Real.log e.ratio
 192            else acc) acc
 193          =
 194        L.events.foldl (fun acc e => acc + flow_contribution e agent) acc := by
 195    intro acc
 196    induction L.events generalizing acc with
 197    | nil =>
 198        simp
 199    | cons e rest ih =>
 200        simp [List.foldl, step_eq]
 201
 202  have h_foldl_sum :
 203      ∀ acc,
 204        L.events.foldl (fun acc e => acc + flow_contribution e agent) acc
 205          =
 206        acc + (L.events.map (fun e => flow_contribution e agent)).sum := by
 207    intro acc
 208    induction L.events generalizing acc with
 209    | nil =>
 210        simp
 211    | cons e rest ih =>
 212        simp [List.foldl, ih, add_assoc]
 213
 214  have h_netflow :
 215      net_flow L agent
 216        = (L.events.map (fun e => flow_contribution e agent)).sum := by
 217    unfold net_flow
 218    rw [h_foldl 0]
 219    have := h_foldl_sum 0
 220    simpa using this
 221
 222  -- Switch to a `Multiset` view to use the balance property as an invariance under `reciprocal`.
 223  let M : Multiset RecognitionEvent := (L.events : Multiset RecognitionEvent)
 224  let f : RecognitionEvent → ℝ := fun e => flow_contribution e agent
 225
 226  have h_inj : Function.Injective reciprocal := by
 227    intro x y hxy
 228    exact (reciprocal_inj x y).1 hxy
 229
 230  have hM : M = M.map reciprocal := by
 231    ext e
 232    have hcount_map : (M.map reciprocal).count e = M.count (reciprocal e) := by
 233      -- `count_map_eq_count'` with `x := reciprocal e` gives `(map reciprocal).count e = count (reciprocal e)`.
 234      simpa [M, reciprocal_reciprocal] using
 235        (Multiset.count_map_eq_count' reciprocal M h_inj (reciprocal e))
 236    have hcount_bal : M.count e = M.count (reciprocal e) := by
 237      -- `balanced_list` is stated in terms of `List.count`; `simp` converts to multiset counts.
 238      simpa [M] using (hbal e)
 239    calc
 240      M.count e = M.count (reciprocal e) := hcount_bal
 241      _ = (M.map reciprocal).count e := by simp [hcount_map]
 242
 243  have hneg : ∀ e, f (reciprocal e) = -f e := by
 244    intro e
 245    have h := flow_contribution_reciprocal e agent
 246    -- `f e + f (reciprocal e) = 0`
 247    linarith
 248
 249  have hsum_neg :
 250-- ... 33 more lines elided ...

used by (1)

From the project-wide theorem graph. These declarations reference this one in their body.

depends on (33)

Lean names referenced from this declaration's body.

… and 3 more