The first edition's five laws (debits equal credits; the accounting equation; the trial balance balances; net income articulates to equity; the cash-flow sections sum to the change in cash) are theorems in bookspec/lean, ported from verify/lean (Basic, Entry, Statements, Closing, Ledger under namespace Bookspec) and restated by name in Laws.lean, each a statement about every reachable state of the books. Audit.lean prints their axioms; the checker's lean.rs test fails on a sorry, a law not audited, or any axiom beyond propext, Quot.sound and Classical.choice. Money is Int, the exact count of the smallest unit: every law is a law of addition, so the model is faithful to exact decimals. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
63 lines
2.8 KiB
Lean4
63 lines
2.8 KiB
Lean4
import Bookspec.Ledger
|
||
|
||
/-!
|
||
# bookspec's five laws
|
||
|
||
The five laws of the first edition (`bookspec/spec/00-model.md`, "The five
|
||
laws"), each stated once, by name, as a theorem about *every* reachable
|
||
state of the books, ported from `verify/lean` (P13 step 4). Money is `Int`,
|
||
an exact count of the smallest unit; any finite set of exact decimals
|
||
scales to integers without loss, and every law is a law of addition.
|
||
|
||
1. Debits equal credits (BS-entry-1).
|
||
2. Assets = Liabilities + Equity + (Revenue - Expenses) (BS-statement-2).
|
||
3. The trial balance balances (BS-statement-1).
|
||
4. Net income articulates to equity: a close credits equity with exactly
|
||
revenue less expenses (BS-period-1).
|
||
5. The cash-flow sections sum to the change in cash (BS-statement-3).
|
||
-/
|
||
|
||
namespace Bookspec
|
||
|
||
/-- Law 1. In every reachable state the posted lines' debits equal their
|
||
credits (`net` is debits less credits). -/
|
||
theorem law_debits_equal_credits {L : Ledger} (r : Reachable L) :
|
||
net (allLines L.posted) = 0 :=
|
||
r.books_net_zero
|
||
|
||
/-- Law 2. The accounting equation, in every reachable state. -/
|
||
theorem law_accounting_equation {L : Ledger} (r : Reachable L) :
|
||
let ls := allLines L.posted
|
||
typeTotal .asset ls L.chart
|
||
= typeTotal .liability ls L.chart + typeTotal .equity ls L.chart
|
||
+ (typeTotal .revenue ls L.chart - typeTotal .expense ls L.chart) :=
|
||
r.accounting_equation
|
||
|
||
/-- Law 3. The trial balance balances, in every reachable state. -/
|
||
theorem law_trial_balance {L : Ledger} (r : Reachable L) :
|
||
tbDebits (allLines L.posted) (codes L.chart)
|
||
= tbCredits (allLines L.posted) (codes L.chart) :=
|
||
r.trial_balance
|
||
|
||
/-- Law 4. A close credits equity with exactly the period's net income. -/
|
||
theorem law_net_income_articulates (L : Ledger) (p : Period) (ts : List (Nat × Int))
|
||
(hsum : total (ts.map Prod.snd)
|
||
= net (closings (nominalCodes L.chart) (allLines (through p.stop L.posted)))) :
|
||
let ls := allLines (through p.stop L.posted)
|
||
total (ts.map Prod.snd) = typeTotal .revenue ls L.chart - typeTotal .expense ls L.chart :=
|
||
close_credits_net_income L p ts hsum
|
||
|
||
/-- Law 5. The three sections of the statement of cash flows sum to the
|
||
change in the cash accounts. -/
|
||
theorem law_cash_flow_is_change_in_cash {L : Ledger} (r : Reachable L) (b c : Nat)
|
||
(hbc : b ≤ c) (F : List Line → Line → Flow) (C : List Line → List Int)
|
||
(hC : ∀ e, sum3 (C e) = 0) (cash : List Nat) (hd : Distinct cash)
|
||
(hF : ∀ e l, F e l = .cash ↔ l.account ∈ cash) :
|
||
let es := (between b c L.posted).map Entry.lines
|
||
sectionTotal F C 0 es + sectionTotal F C 1 es + sectionTotal F C 2 es
|
||
= sumOver (fun a => movement a (allLines (through c L.posted))) cash
|
||
- sumOver (fun a => movement a (allLines (through b L.posted))) cash :=
|
||
r.cashflow_is_change_in_cash b c hbc F C hC cash hd hF
|
||
|
||
end Bookspec
|