forloops not supported — onlywhileandfor...of. Must use while.i++/i--not supported — must usei = i + 1.+=/-=not supported — must usetotal = total + arr[i].//@ typeannotations must be before first statement —collectAnnotationsonly reads from function node + first body statement.
- No way to annotate array element types —
paidBy: number[]always becomesArray Int. Need something like//@ type paidBy nat[]to getArray Nat.
- TS imports don't generate Lean imports —
import { Foo } from './bar'is ignored. Workaround: put everything in one file.
Array fields in interfaces lose element type— fixedtypeToStringto detect arrays— added totonot escaped as Lean keywordLEAN_KEYWORDS, also escape var/param namesType declarations emitted in wrong order— fixed to use source orderRedundant— skip when all variants covered_ =>arm in exhaustive matchSpread syntax— extract as[...arr, e]not supportedArray.pushMethod calls in expressions not lifted— selective ANF (§4.6)Pure functions duplicate body in method— wrapperreturn Pure.fnName args— resolve tags spec-context calls to pure fnsspec-purecall classificationNat/Int for interface fields—//@ type nattrailing annotation on interface fieldsShares-sum-to-amount in TS invariant—validExpensenow checkssumTo(shares, mc) === amount— included in strengthened invariantvalidExpensechecksshares.length === memberCountUnified type mapping—parseTsTypereplaces separatetsTypeToLeanandresolveTsTypepaths
- Invariant on Model (
invwithvalidExpensechecking paidBy range, amount, shares length, shares sum) steppreservesinv(proven, no sorry) — validates all conditions before accepting- Single-expense conservation theorem (proven)
- Global conservation theorem (proven) — sum of all balances across all members is zero
- Settlement conservation theorem (proven) — from gets +amount, to gets -amount, net zero
expenseDelta,settlementDelta,computeBalanceverified (expenses + settlements)- React app wired to verified logic (expenses + settlements)
- Delta laws:
add_expense_delta,settlement_delta_from/to/other - Interface field type annotations (
//@ type nattrailing on field line) validExpensechecks shares.length = memberCount and sumTo(shares) = amountModel.memberCountisNat(via interface field annotation)
No sorry. No remaining proof obligations.
Full theorem set:
full_conservation— sum of all balances (expenses + settlements) across all members is zeroglobal_conservation— expense-only conservationglobal_settlement_conservation— settlement-only conservationsingle_expense_conservation— one expense, member deltas sum to zerosettlement_conservation— one settlement, member deltas sum to zeroadd_expense_delta— adding an expense changes balance by exactly expenseDeltasettlement_delta_from/to/other— precise settlement delta per membersteppreservesinv— invariant maintained through operationsexpenseDelta,settlementDelta,computeBalance— per-function verification