Lean2Js.Example
Business logic written in Lean, and the theorems proved about it #
Ordinary Lean defs, each marked @[ship], and the theorems proved about them. Marking a def reads
a declaration out of it, and ship_package gathers them into the program and writes the proof that each
declaration denotes the def it was read from.
The program placed here is what ships as packages/verified-example.
Lean2Js.Example.add
sourceEquations
- Lean2Js.Example.add a b = a + b
Instances For
Used by
Lean2Js.Example.clampQuantity
sourceClamps a quantity to at least 1 and at most upper.
Equations
Instances For
Used by
Lean2Js.Example.maxLineQuantity
sourceThe most of one line a single order is billed for.
Equations
Instances For
Used by
Lean2Js.Example.lineTotal
sourceThe amount of a line item. The quantity is clamped before multiplying, so a negative quantity never makes the amount negative.
Equations
- Lean2Js.Example.lineTotal unitPrice quantity = unitPrice * Lean2Js.Example.clampQuantity quantity Lean2Js.Example.maxLineQuantity
Instances For
Used by
Lean2Js.Example.Role
sourceInstances For
Used by
Lean2Js.Example.Role.typeDef
sourceEquations
Instances For
Used by
Lean2Js.Example.Role.ofValue
sourceEquations
- Lean2Js.Example.Role.ofValue (Lean2Js.Value.obj "guest" []) = some Lean2Js.Example.Role.guest
- Lean2Js.Example.Role.ofValue (Lean2Js.Value.obj "member" []) = some Lean2Js.Example.Role.member
- Lean2Js.Example.Role.ofValue (Lean2Js.Value.obj "admin" []) = some Lean2Js.Example.Role.admin
- Lean2Js.Example.Role.ofValue v = none
Instances For
Used by
Lean2Js.Example.Role.ofValue_toValue
sourceUsed by
Lean2Js.Example.Role.toValue_eq
sourceUsed by
Lean2Js.Example.instEncRole
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.Role.toValue_hasTy
sourceUsed by
Lean2Js.Example.Role.ty_eq
sourceUsed by
Lean2Js.Example.Role.accepts
sourceEquations
- Lean2Js.Example.Role.accepts p Lean2Js.Example.Role.guest = (p.findType? "Role" = some Lean2Js.Example.Role.typeDef ∧ True)
- Lean2Js.Example.Role.accepts p Lean2Js.Example.Role.member = (p.findType? "Role" = some Lean2Js.Example.Role.typeDef ∧ True)
- Lean2Js.Example.Role.accepts p Lean2Js.Example.Role.admin = (p.findType? "Role" = some Lean2Js.Example.Role.typeDef ∧ True)
Instances For
Used by
Lean2Js.Example.Role.toValue
sourceEquations
Instances For
Used by
Lean2Js.Example.roleRank
sourceEquations
Instances For
Used by
Lean2Js.Example.lineTotals
sourceThe amount of every line of an order at one unit price.
Equations
- Lean2Js.Example.lineTotals unitPrice quantities = List.map (fun (quantity : Int) => Lean2Js.Example.lineTotal unitPrice quantity) quantities
Instances For
Used by
Lean2Js.Example.anyOverLimit
sourceEquations
Instances For
Used by
Lean2Js.Example.firstOverLimit
sourceThe first line that breaks the limit. Lines after it are never looked at.
Equations
- Lean2Js.Example.firstOverLimit amounts limit = List.find? (fun (amount : Int) => decide (amount > limit)) amounts
Instances For
Used by
Lean2Js.Example.everyLineWithinLimit
sourceEquations
Instances For
Used by
Lean2Js.Example.someLineIsFree
sourceEquations
- Lean2Js.Example.someLineIsFree amounts = amounts.any fun (amount : Int) => amount == 0
Instances For
Used by
Lean2Js.Example.pageOf
sourceOne window of a list. A window reaching past the end is refused rather than shortened.
Equations
- Lean2Js.Example.pageOf xs lo hi = Lean2Js.Arr.slice xs lo hi
Instances For
Used by
Lean2Js.Example.mostRecentFirst
sourceEquations
- Lean2Js.Example.mostRecentFirst events = events.reverse
Instances For
Used by
Lean2Js.Example.combinedCart
sourceEquations
- Lean2Js.Example.combinedCart saved added = saved ++ added
Instances For
Used by
Lean2Js.Example.headOr
sourceAn out-of-range read traps rather than yielding undefined.
Equations
- Lean2Js.Example.headOr xs fallback = if Lean2Js.Arr.length xs < 1 then fallback else Lean2Js.Arr.get xs 0
Instances For
Used by
Lean2Js.Example.slugOf
sourceEquations
- Lean2Js.Example.slugOf «prefix» name = «prefix» ++ "-" ++ name
Instances For
Used by
Lean2Js.Example.orderReference
sourceThe reference an order is filed under: the prefix and the order number in decimal.
Equations
- Lean2Js.Example.orderReference «prefix» orderNo = «prefix» ++ "-" ++ Lean2Js.Int53.toString orderNo
Instances For
Used by
Lean2Js.Example.amountOf
sourceThe amount a line carries, read back from the string the caller was handed. none unless the
string is exactly the decimal spelling of an Int53, so "007", " 5" and "+5" are refused.
Equations
- Lean2Js.Example.amountOf field = Lean2Js.Str.toInt? field
Instances For
Used by
Lean2Js.Example.amountOr
sourceThe same amount, with a fallback for a field that does not spell one.
Equations
- Lean2Js.Example.amountOr field fallback = Lean2Js.Opt.getD (Lean2Js.Str.toInt? field) fallback
Instances For
Used by
Lean2Js.Example.separatorAt
sourceWhere the separator first sits in a reference, counted in code points. none when the reference
carries none. JS's own indexOf counts UTF-16 units and answers -1.
Equations
- Lean2Js.Example.separatorAt reference sep = Lean2Js.Str.indexOf? reference sep
Instances For
Used by
Lean2Js.Example.referencePrefix
sourceThe part of a reference before its first separator, or the whole reference when it carries none.
Equations
- Lean2Js.Example.referencePrefix reference = match Lean2Js.Str.indexOf? reference "-" with | some i => Lean2Js.Str.substring reference 0 i | none => reference
Instances For
Used by
Lean2Js.Example.joinFields
sourceA row of an uploaded file written back out: the fields in order with the separator between them. An empty list of fields writes an empty row.
Equations
- Lean2Js.Example.joinFields fields separator = Lean2Js.Str.join fields separator
Instances For
Used by
Lean2Js.Example.referenceFrom
sourceThe reference an order is filed under, built from parts that are already in hand, under the same
separator referencePrefix reads back.
Equations
- Lean2Js.Example.referenceFrom parts = Lean2Js.Str.join parts "-"
Instances For
Used by
Lean2Js.Example.refiled
sourceA reference filed under one separator, rewritten under another. Every occurrence moves, and a reference carrying none comes back unchanged.
Equations
- Lean2Js.Example.refiled reference oldSep newSep = Lean2Js.Str.replace reference oldSep newSep
Instances For
Used by
Lean2Js.Example.receiptRule
sourceThe rule a printed receipt puts between its sections: mark written out 32 times, which is one
column each where mark is a single character.
Equations
- Lean2Js.Example.receiptRule mark = Lean2Js.Str.repeat mark 32
Instances For
Used by
Lean2Js.Example.amountColumn
sourceAn amount in minor units, right-aligned in the column a printed receipt gives it. Too wide an amount keeps its digits and overruns the column.
Equations
- Lean2Js.Example.amountColumn amount = Lean2Js.Str.padStart (Lean2Js.Int53.toString amount) 12 " "
Instances For
Used by
Lean2Js.Example.maxReceiptRows
sourceThe most rows a single printed receipt numbers.
Equations
Instances For
Used by
Lean2Js.Example.lineNumbers
sourceThe line numbers a printed receipt gives its rows, counting from one. The count is clamped: a
receipt prints at most maxReceiptRows rows, and Arr.range asks that the text bound how far it
counts.
Equations
- Lean2Js.Example.lineNumbers rows = List.map (fun (i : Int) => i + 1) (Lean2Js.Arr.range (min (max rows 0) Lean2Js.Example.maxReceiptRows))
Instances For
Used by
Lean2Js.Example.sortsBefore
sourceComparison in code point order. JS's < compares UTF-16 units, so it does not agree.
Equations
- Lean2Js.Example.sortsBefore a b = decide (a < b)
Instances For
Used by
Lean2Js.Example.mentionsTerm
sourceWhether a free-text note mentions a search term, ignoring case.
Equations
- Lean2Js.Example.mentionsTerm text term = Lean2Js.Str.includes (Lean2Js.Str.lower text) (Lean2Js.Str.lower term)
Instances For
Used by
Lean2Js.Example.storedCoupon
sourceA coupon code as it is stored: the campaign prefix and what the customer typed, upper-cased and with the surrounding whitespace gone.
Equations
- Lean2Js.Example.storedCoupon campaign entered = Lean2Js.Str.upper (Lean2Js.Str.trim (campaign ++ entered))
Instances For
Used by
Lean2Js.Example.comparable
sourceThe spelling two strings are compared under: the surrounding whitespace gone and the case levelled.
Every comparison below goes through it and no consumer has any business calling it, which is what
@[ship internal] says — it is compiled and called like any other declaration, and appears in neither
index.d.ts nor the exports of index.js.
Equations
Instances For
Used by
Lean2Js.Example.couponApplies
sourceWhether a coupon belongs to a campaign, comparing the way the codes are stored.
Equations
- Lean2Js.Example.couponApplies code campaign = Lean2Js.Str.startsWith (Lean2Js.Example.comparable code) (Lean2Js.Example.comparable campaign)
Instances For
Used by
Lean2Js.Example.fieldCount
sourceHow many columns a line of an uploaded file carries. An empty separator leaves the line whole rather than cutting it into characters.
Equations
- Lean2Js.Example.fieldCount row separator = Lean2Js.Arr.length (Lean2Js.Str.split row separator)
Instances For
Used by
Lean2Js.Example.truncateLabel
sourceA label cut to fit, counted in code points so a surrogate pair is never split in half. A negative limit has no string to return and fails the way an out-of-range index does.
Equations
- Lean2Js.Example.truncateLabel label limit = if Lean2Js.Str.length label ≤ limit then label else Lean2Js.Str.substring label 0 limit ++ "..."
Instances For
Used by
Lean2Js.Example.isSpreadsheet
sourceWhether an uploaded file is a spreadsheet, compared the way the names are stored.
Equations
- Lean2Js.Example.isSpreadsheet fileName = Lean2Js.Str.endsWith (Lean2Js.Example.comparable fileName) ".csv"
Instances For
Used by
Lean2Js.Example.limitsFor
sourceWhat a role may do in a day and in a month.
Equations
- Lean2Js.Example.limitsFor Lean2Js.Example.Role.guest = Lean2Js.Dict.ofList [("daily", 10), ("monthly", 100)]
- Lean2Js.Example.limitsFor Lean2Js.Example.Role.member = Lean2Js.Dict.ofList [("daily", 100), ("monthly", 3000)]
- Lean2Js.Example.limitsFor Lean2Js.Example.Role.admin = Lean2Js.Dict.ofList [("daily", 1000), ("monthly", 30000)]
Instances For
Used by
Lean2Js.Example.priceOf
sourceEquations
- Lean2Js.Example.priceOf prices sku = prices.get sku
Instances For
Used by
Lean2Js.Example.isListed
sourceEquations
- Lean2Js.Example.isListed prices sku = prices.has sku
Instances For
Used by
Lean2Js.Example.repriced
sourceThe price book after one price change. A sku already in the book keeps its place.
Equations
- Lean2Js.Example.repriced prices sku amount = prices.set sku amount
Instances For
Used by
Lean2Js.Example.listedSkus
sourceEquations
- Lean2Js.Example.listedSkus prices = prices.keys
Instances For
Used by
Lean2Js.Example.listedPrices
sourceEquations
- Lean2Js.Example.listedPrices prices = prices.values
Instances For
Used by
Lean2Js.Example.withdrawn
sourceThe price book after a sku is withdrawn. A sku that was never listed leaves the book unchanged.
Equations
- Lean2Js.Example.withdrawn prices sku = prices.erase sku
Instances For
Used by
Lean2Js.Example.catalogueSize
sourceEquations
- Lean2Js.Example.catalogueSize prices = prices.size
Instances For
Used by
The same price book at the other spelling. Dict.Obj crosses the boundary as a plain object rather
than as a Map, so JSON.stringify of what these hand back is the book itself. Inside the module the
two are one thing, and the operations below are the ones above under different names.
Lean2Js.Example.objPriceOf
sourceEquations
- Lean2Js.Example.objPriceOf prices sku = prices.get sku
Instances For
Used by
Lean2Js.Example.objIsListed
sourceEquations
- Lean2Js.Example.objIsListed prices sku = prices.has sku
Instances For
Used by
Lean2Js.Example.objRepriced
sourceThe price book after one price change, handed back as an object. A sku already in the book keeps its place.
Equations
- Lean2Js.Example.objRepriced prices sku amount = prices.set sku amount
Instances For
Used by
Lean2Js.Example.objWithdrawn
sourceThe price book after a sku is withdrawn, handed back as an object.
Equations
- Lean2Js.Example.objWithdrawn prices sku = prices.erase sku
Instances For
Used by
Lean2Js.Example.objListedSkus
sourceEquations
- Lean2Js.Example.objListedSkus prices = prices.keys
Instances For
Used by
Lean2Js.Example.objListedPrices
sourceEquations
- Lean2Js.Example.objListedPrices prices = prices.values
Instances For
Used by
Lean2Js.Example.objCatalogueSize
sourceEquations
- Lean2Js.Example.objCatalogueSize prices = prices.size
Instances For
Used by
Lean2Js.Example.objLimitsFor
sourceWhat a role may do, written out at the spelling that crosses as a plain object rather than as a
Map. Beside limitsFor it is one dictionary written twice: the same entries, the same operations, and
what the spelling decides is only what a consumer is handed.
Equations
- Lean2Js.Example.objLimitsFor Lean2Js.Example.Role.guest = Lean2Js.Dict.Obj.ofList [("daily", 10), ("monthly", 100)]
- Lean2Js.Example.objLimitsFor Lean2Js.Example.Role.member = Lean2Js.Dict.Obj.ofList [("daily", 100), ("monthly", 3000)]
- Lean2Js.Example.objLimitsFor Lean2Js.Example.Role.admin = Lean2Js.Dict.Obj.ofList [("daily", 1000), ("monthly", 30000)]
Instances For
Used by
Lean2Js.Example.divide
sourceTruncating division. Division by zero traps on the JS side too.
Equations
- Lean2Js.Example.divide a b = Lean2Js.Int53.div a b
Instances For
Used by
Lean2Js.Example.remainder
sourceEquations
Instances For
Used by
Lean2Js.Example.taxOn
sourceThe tax on an amount in minor units at a rate in basis points, rounded half away from zero — which is the rounding an amount of money gets where nothing says otherwise.
Equations
- Lean2Js.Example.taxOn amount rate = Lean2Js.Int53.divRound (amount * rate) 10000
Instances For
Used by
Lean2Js.Example.dayOfInstant
sourceWhich whole day an instant falls in, counting from the epoch, where an instant before it belongs to
the day it is inside rather than to the one after: divFloor and not div.
Equations
Instances For
Used by
Lean2Js.Example.dayNumber
sourceThe day a calendar date falls on, counting from 1970-01-01.
Equations
- Lean2Js.Example.dayNumber year month day = Lean2Js.Cal.fromCivil year month day
Instances For
Used by
Lean2Js.Example.yearOf
sourceThe calendar year a day number falls in.
Equations
- Lean2Js.Example.yearOf days = Lean2Js.Cal.year days
Instances For
Used by
Lean2Js.Example.monthOf
sourceThe calendar month a day number falls in, 1 through 12.
Equations
- Lean2Js.Example.monthOf days = Lean2Js.Cal.month days
Instances For
Used by
Lean2Js.Example.dayOfMonthOf
sourceThe day of the month a day number falls on, 1 through 31.
Equations
- Lean2Js.Example.dayOfMonthOf days = Lean2Js.Cal.day days
Instances For
Used by
Lean2Js.Example.weekdayOf
sourceThe day of the week a day number falls on, 0 for Sunday through 6 for Saturday.
Equations
- Lean2Js.Example.weekdayOf days = Lean2Js.Cal.weekday days
Instances For
Used by
Lean2Js.Example.monthLength
sourceHow many days a calendar month holds, a leap February included.
Equations
- Lean2Js.Example.monthLength year month = Lean2Js.Cal.daysInMonth year month
Instances For
Used by
Lean2Js.Example.negate
sourceEquations
Instances For
Used by
Lean2Js.Example.priceGap
sourceEquations
- Lean2Js.Example.priceGap a b = Lean2Js.Int53.abs (a - b)
Instances For
Used by
Lean2Js.Example.discounted
sourceThe amount after a percent% discount. The remainder is truncated.
Equations
Instances For
Used by
Lean2Js.Example.tenPercentOff
sourceEquations
- Lean2Js.Example.tenPercentOff amount = amount - Lean2Js.Int53.div amount 10
Instances For
Used by
Lean2Js.Example.rebindTwice
sourceBinds the same name twice. ESM runs in strict mode, so emitting const twice would fail at import
time.
Equations
- Lean2Js.Example.rebindTwice amount = (amount + 1) * 2
Instances For
Used by
Lean2Js.Example.noDiscount
sourceEquations
- Lean2Js.Example.noDiscount amount = amount
Instances For
Used by
Lean2Js.Example.priced
sourceCharges an amount under a pricing rule the caller picks. Taking a function keeps it off the public API: there is no way to check at the boundary that one handed in from JS is pure.
Equations
- Lean2Js.Example.priced rule amount = rule amount
Instances For
Used by
Lean2Js.Example.memberPrice
sourceEquations
Instances For
Used by
Lean2Js.Example.guestPrice
sourceEquations
Instances For
Used by
Lean2Js.Example.mixChannels
sourceEquations
- Lean2Js.Example.mixChannels a b = a * b + (a - b)
Instances For
Used by
Lean2Js.Example.bucketOf
sourceEquations
- Lean2Js.Example.bucketOf key buckets = key % buckets
Instances For
Used by
Lean2Js.Example.clampChannel
sourceA channel value held between a floor and a ceiling.
Equations
- Lean2Js.Example.clampChannel value lo hi = min (max value lo) hi
Instances For
Used by
Lean2Js.Example.scaleFee
sourceEquations
- Lean2Js.Example.scaleFee fee factor = fee * factor - 1
Instances For
Used by
Lean2Js.Example.bigQuotient
sourceEquations
- Lean2Js.Example.bigQuotient a b = a.div b
Instances For
Used by
Lean2Js.Example.sameLabel
sourceEquations
- Lean2Js.Example.sameLabel a b = (a == b)
Instances For
Used by
Lean2Js.Example.safeQuotientIsPositive
sourceDoubles as a check on short-circuiting. When b is 0 the right-hand side is not evaluated.
Equations
- Lean2Js.Example.safeQuotientIsPositive a b = (b != 0 && decide (Lean2Js.Int53.div a b > 0))
Instances For
Used by
Lean2Js.Example.canCheckout
sourceEquations
Instances For
Used by
Lean2Js.Example.cappedCharge
sourceEquations
- Lean2Js.Example.cappedCharge amount budget = min amount budget
Instances For
Used by
Lean2Js.Example.atLeast
sourceEquations
- Lean2Js.Example.atLeast amount floor = max amount floor
Instances For
Used by
Lean2Js.Example.Money
sourceThe constructor is named so that the subset reads it as Money; Lean's default mk would make the
generated object's tag mk.
constructor Money
Instances For
Used by
Lean2Js.Example.instDecidableEqMoney
sourceUsed by
Lean2Js.Example.instDecidableEqMoney.decEq
sourceEquations
Instances For
Used by
Lean2Js.Example.Money.toValue_eq
sourceUsed by
Lean2Js.Example.Money.typeDef
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.Money.ofValue
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.Money.ofValue v = none
Instances For
Used by
Lean2Js.Example.instEncMoney
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.Money.ofValue_toValue
sourceUsed by
Lean2Js.Example.Money.toValue
sourceEquations
Instances For
Used by
Lean2Js.Example.Money.accepts
sourceEquations
- Lean2Js.Example.Money.accepts p { amount := x0, currency := x1 } = (p.findType? "Money" = some Lean2Js.Example.Money.typeDef ∧ Lean2Js.Enc.accepts p x0 ∧ Lean2Js.Enc.accepts p x1)
Instances For
Used by
Lean2Js.Example.Money.toValue_hasTy
sourceUsed by
Lean2Js.Example.Money.ty_eq
sourceUsed by
Lean2Js.Example.OrderState
sourceTold apart by kind rather than the default tag: which key reads well is the author's call, and
the mark above the type is where it is made. The rest of the types here keep tag, so the generated
package carries both.
Instances For
Used by
Lean2Js.Example.instInhabitedOrderState
sourceEquations
Used by
Lean2Js.Example.OrderState.ofValue_toValue
sourceUsed by
Lean2Js.Example.OrderState.ofValue
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.OrderState.ofValue (Lean2Js.Value.obj "draft" []) = some Lean2Js.Example.OrderState.draft
- Lean2Js.Example.OrderState.ofValue (Lean2Js.Value.obj "placed" [("orderId", v0)]) = (Lean2Js.Enc.ofValue v0).bind fun (x0 : Int) => some (Lean2Js.Example.OrderState.placed x0)
- Lean2Js.Example.OrderState.ofValue (Lean2Js.Value.obj "cancelled" [("reason", v0)]) = (Lean2Js.Enc.ofValue v0).bind fun (x0 : String) => some (Lean2Js.Example.OrderState.cancelled x0)
- Lean2Js.Example.OrderState.ofValue v = none
Instances For
Used by
Lean2Js.Example.OrderState.typeDef
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.OrderState.toValue_eq
sourceUsed by
Lean2Js.Example.instEncOrderState
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.OrderState.accepts
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.OrderState.accepts p Lean2Js.Example.OrderState.draft = (p.findType? "OrderState" = some Lean2Js.Example.OrderState.typeDef ∧ True)
- Lean2Js.Example.OrderState.accepts p (Lean2Js.Example.OrderState.placed x0) = (p.findType? "OrderState" = some Lean2Js.Example.OrderState.typeDef ∧ Lean2Js.Enc.accepts p x0)
- Lean2Js.Example.OrderState.accepts p (Lean2Js.Example.OrderState.cancelled x0) = (p.findType? "OrderState" = some Lean2Js.Example.OrderState.typeDef ∧ Lean2Js.Enc.accepts p x0)
Instances For
Used by
Lean2Js.Example.OrderState.toValue
sourceEquations
- Lean2Js.Example.OrderState.draft.toValue = Lean2Js.Value.obj "draft" []
- (Lean2Js.Example.OrderState.placed x0).toValue = Lean2Js.Value.obj "placed" [("orderId", Lean2Js.Enc.toValue x0)]
- (Lean2Js.Example.OrderState.shipped x0 x1).toValue = Lean2Js.Value.obj "shipped" [("orderId", Lean2Js.Enc.toValue x0), ("trackingId", Lean2Js.Enc.toValue x1)]
- (Lean2Js.Example.OrderState.cancelled x0).toValue = Lean2Js.Value.obj "cancelled" [("reason", Lean2Js.Enc.toValue x0)]
Instances For
Used by
Lean2Js.Example.OrderState.toValue_hasTy
sourceUsed by
Lean2Js.Example.OrderState.ty_eq
sourceUsed by
Lean2Js.Example.addMoney
sourceAmounts in different currencies cannot be added. === is unusable on the JS side, so a structural
equality helper is called.
Equations
Instances For
Used by
Lean2Js.Example.sameMoney
sourceEquations
- Lean2Js.Example.sameMoney a b = (a == b)
Instances For
Used by
Lean2Js.Example.currenciesOf
sourceEquations
- Lean2Js.Example.currenciesOf items = List.map (fun (item : Lean2Js.Example.Money) => item.currency) items
Instances For
Used by
Lean2Js.Example.cartTotal
sourceAdds the amounts up whatever currency each carries; addMoney is the operation that refuses to mix
them.
Equations
- Lean2Js.Example.cartTotal items = List.foldl (fun (subtotal : Int) (item : Lean2Js.Example.Money) => subtotal + item.amount) 0 items
Instances For
Used by
Lean2Js.Example.cheapestFirst
sourceThe lines of a cart, cheapest first. Lines that cost the same keep the order they came in.
Equations
- Lean2Js.Example.cheapestFirst items = Lean2Js.Arr.sortByKey items fun (item : Lean2Js.Example.Money) => item.amount
Instances For
Used by
Lean2Js.Example.inLabelOrder
sourceLabels in the order the subset compares strings, which counts code points.
Equations
- Lean2Js.Example.inLabelOrder labels = Lean2Js.Arr.sortByKey labels fun (label : String) => label
Instances For
Used by
Lean2Js.Example.total
sourceEquations
- Lean2Js.Example.total xs = List.foldl (fun (sum x : Int) => sum + x) 0 xs
Instances For
Used by
Lean2Js.Example.trackingOf
sourceEquations
Instances For
Used by
Lean2Js.Example.canRefund
sourceEquations
- Lean2Js.Example.canRefund role Lean2Js.Example.OrderState.draft = false
- Lean2Js.Example.canRefund role (Lean2Js.Example.OrderState.placed x0) = decide (Lean2Js.Example.roleRank role ≥ 1)
- Lean2Js.Example.canRefund role (Lean2Js.Example.OrderState.shipped x0 x1) = decide (Lean2Js.Example.roleRank role ≥ 2)
- Lean2Js.Example.canRefund role (Lean2Js.Example.OrderState.cancelled x0) = false
Instances For
Used by
Lean2Js.Example.firstTracking
sourceEquations
- Lean2Js.Example.firstTracking states = if (Lean2Js.Arr.length states == 0) = true then none else Lean2Js.Example.trackingOf (Lean2Js.Arr.get states 0)
Instances For
Used by
Lean2Js.Example.refundableOnly
sourceThe orders this role may still refund. The predicate reads role from outside the lambda.
Equations
- Lean2Js.Example.refundableOnly role states = List.filter (fun (state : Lean2Js.Example.OrderState) => Lean2Js.Example.canRefund role state) states
Instances For
Used by
Lean2Js.Example.ship
sourceThe state transition to shipped. Rejects states that cannot transition and an empty tracking id.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.ship Lean2Js.Example.OrderState.draft trackingId = Except.error "a draft order cannot ship"
- Lean2Js.Example.ship (Lean2Js.Example.OrderState.shipped x0 x1) trackingId = Except.error "the order has already shipped"
- Lean2Js.Example.ship (Lean2Js.Example.OrderState.cancelled x0) trackingId = Except.error "a cancelled order cannot ship"
Instances For
Used by
Lean2Js.Example.quantityLabel
sourceThe label shown next to a line item.
Equations
- Lean2Js.Example.quantityLabel 0 = "out of stock"
- Lean2Js.Example.quantityLabel 1 = "last one"
- Lean2Js.Example.quantityLabel quantity = "in stock"
Instances For
Used by
Lean2Js.Example.renewalLabel
sourceWhether a subscription carries on. Both cases are named, so no fallback is needed.
Equations
- Lean2Js.Example.renewalLabel true = "renews"
- Lean2Js.Example.renewalLabel false = "ends"
Instances For
Used by
Lean2Js.Example.chargeable
sourceAn amount of zero is free whatever the currency, and an amount carrying no currency cannot be charged at all.
Equations
Instances For
Used by
Lean2Js.Example.settleMessage
sourceThe shipping line shown once a transition has been attempted. A draft or cancelled order has nothing
to show, so one arm reaches past ok and leaves the state itself open.
Equations
- Lean2Js.Example.settleMessage (Except.ok (Lean2Js.Example.OrderState.shipped orderId trackingId)) = trackingId
- Lean2Js.Example.settleMessage (Except.ok (Lean2Js.Example.OrderState.placed orderId)) = "awaiting shipment"
- Lean2Js.Example.settleMessage (Except.ok a) = "no update"
- Lean2Js.Example.settleMessage (Except.error message) = message
Instances For
Used by
Lean2Js.Example.settledOrderId
sourceThe order the settlement placed, if it placed one. The wildcard here stands for both the states that
are not placed and the error, so the split the certificate makes reaches Except as well.
Equations
- Lean2Js.Example.settledOrderId (Except.ok (Lean2Js.Example.OrderState.placed orderId)) = orderId
- Lean2Js.Example.settledOrderId outcome = 0
Instances For
Used by
Lean2Js.Example.dailyLimit
sourceA role with no daily limit recorded may do nothing.
Equations
- Lean2Js.Example.dailyLimit role = match (Lean2Js.Example.limitsFor role).get "daily" with | some value => value | none => 0
Instances For
Used by
Lean2Js.Example.monthlyLimit
sourceThe same read with the arms the other way round: an arm that binds, then a wildcard for the rest.
The certificate splits the scrutinee to show the binding arm did not fire, which Option needs as much
as a type the program declares.
Equations
- Lean2Js.Example.monthlyLimit role = match (Lean2Js.Example.limitsFor role).get "monthly" with | some value => value | x => 0
Instances For
Used by
Lean2Js.Example.Paginated
sourceOne page of results together with how many there are in all. The subset carries the parameter as a
Ty.var and a use substitutes what it was applied to, so the name here is the one the generated type
reads as.
constructor Paginated
Instances For
Used by
Lean2Js.Example.Paginated.toValue_eq
sourceUsed by
Lean2Js.Example.Paginated.ofValue_toValue
sourceUsed by
Lean2Js.Example.Paginated.ofValue
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.Paginated.ofValue v = none
Instances For
Used by
Lean2Js.Example.Paginated.typeDef
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.instEncPaginated
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.Paginated.toValue_hasTy
sourceUsed by
Lean2Js.Example.Paginated.ty_eq
sourceUsed by
Lean2Js.Example.Paginated.toValue
sourceEquations
Instances For
Used by
Lean2Js.Example.Paginated.accepts
sourceEquations
- Lean2Js.Example.Paginated.accepts p { items := x0, total := x1 } = (p.findType? "Paginated" = some Lean2Js.Example.Paginated.typeDef ∧ Lean2Js.Enc.accepts p x0 ∧ Lean2Js.Enc.accepts p x1)
Instances For
Used by
Lean2Js.Example.Validated
sourceWhat a check concluded: the value it accepted, or the reasons it refused. E is named by only one of
the two constructors, so a valid term cannot be read off for it and every use carries both arguments.
Instances For
Used by
Lean2Js.Example.Validated.ofValue_toValue
sourceUsed by
Lean2Js.Example.Validated.toValue_eq
sourceUsed by
Lean2Js.Example.Validated.toValue
sourceEquations
- (Lean2Js.Example.Validated.valid x0).toValue = Lean2Js.Value.obj "valid" [("value", Lean2Js.Enc.toValue x0)]
- (Lean2Js.Example.Validated.invalid x0).toValue = Lean2Js.Value.obj "invalid" [("errors", Lean2Js.Enc.toValue x0)]
Instances For
Used by
Lean2Js.Example.Validated.accepts
sourceEquations
- Lean2Js.Example.Validated.accepts p (Lean2Js.Example.Validated.valid x0) = (p.findType? "Validated" = some Lean2Js.Example.Validated.typeDef ∧ Lean2Js.Enc.accepts p x0)
- Lean2Js.Example.Validated.accepts p (Lean2Js.Example.Validated.invalid x0) = (p.findType? "Validated" = some Lean2Js.Example.Validated.typeDef ∧ Lean2Js.Enc.accepts p x0)
Instances For
Used by
Lean2Js.Example.Validated.toValue_hasTy
sourceUsed by
Lean2Js.Example.Validated.ty_eq
sourceUsed by
Lean2Js.Example.instEncValidated
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.Validated.ofValue
sourceEquations
- Lean2Js.Example.Validated.ofValue (Lean2Js.Value.obj "valid" [("value", v0)]) = (Lean2Js.Enc.ofValue v0).bind fun (x0 : A) => some (Lean2Js.Example.Validated.valid x0)
- Lean2Js.Example.Validated.ofValue (Lean2Js.Value.obj "invalid" [("errors", v0)]) = (Lean2Js.Enc.ofValue v0).bind fun (x0 : List E) => some (Lean2Js.Example.Validated.invalid x0)
- Lean2Js.Example.Validated.ofValue v = none
Instances For
Used by
Lean2Js.Example.Validated.typeDef
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.remainingItems
sourceHow many results lie beyond the page in hand.
Equations
- Lean2Js.Example.remainingItems page = page.total - Lean2Js.Arr.length page.items
Instances For
Used by
Lean2Js.Example.firstPage
sourceThe whole list served as a single page.
Equations
- Lean2Js.Example.firstPage amounts = { items := amounts, total := Lean2Js.Arr.length amounts }
Instances For
Used by
Lean2Js.Example.validateQuantity
sourceAccepts an order quantity or says why it was refused.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.validationMessage
sourceThe line shown once a quantity has been checked.
Equations
- Lean2Js.Example.validationMessage (Lean2Js.Example.Validated.valid value) = Lean2Js.Example.quantityLabel value
- Lean2Js.Example.validationMessage (Lean2Js.Example.Validated.invalid errors) = if (Lean2Js.Arr.length errors == 0) = true then "refused" else Lean2Js.Arr.get errors 0
Instances For
Used by
Lean2Js.Example.amountWithTax
sourceThe amount and the tax charged on it, as the two lines they are billed as.
Equations
- Lean2Js.Example.amountWithTax amount = [amount, Lean2Js.Int53.div amount 10]
Instances For
Used by
Lean2Js.Example.currencyOf
sourceEquations
- Lean2Js.Example.currencyOf item = item.currency
Instances For
Used by
Lean2Js.Example.previewLines
sourceThe lines shown before the fold. A count past the end of the order shows the whole of it, where
pageOf would have refused the window.
Equations
- Lean2Js.Example.previewLines amounts upTo = Lean2Js.Arr.take amounts upTo
Instances For
Used by
Lean2Js.Example.linesBelowFold
sourceEquations
- Lean2Js.Example.linesBelowFold amounts upTo = Lean2Js.Arr.drop amounts upTo
Instances For
Used by
Lean2Js.Example.cartIsEmpty
sourceEquations
- Lean2Js.Example.cartIsEmpty items = Lean2Js.Arr.isEmpty items
Instances For
Used by
Lean2Js.Example.stocksSku
sourceEquations
- Lean2Js.Example.stocksSku skus sku = Lean2Js.Arr.contains skus sku
Instances For
Used by
Lean2Js.Example.amountsTotal
sourceEquations
- Lean2Js.Example.amountsTotal amounts = Lean2Js.Arr.sum amounts
Instances For
Used by
Lean2Js.Example.spreadsheetCount
sourceEquations
- Lean2Js.Example.spreadsheetCount fileNames = Lean2Js.Arr.count fileNames Lean2Js.Example.isSpreadsheet
Instances For
Used by
Lean2Js.Example.firstAmount
sourceEquations
- Lean2Js.Example.firstAmount amounts = Lean2Js.Arr.head? amounts
Instances For
Used by
Lean2Js.Example.latestEvent
sourceEquations
- Lean2Js.Example.latestEvent events = Lean2Js.Arr.last? events
Instances For
Used by
Lean2Js.Example.allLines
sourceEvery line of every order in one list.
Equations
- Lean2Js.Example.allLines orders = Lean2Js.Arr.flatten orders
Instances For
Used by
Lean2Js.Example.linesWithTax
sourceEquations
Instances For
Used by
Lean2Js.Example.noteIsBlank
sourceEquations
Instances For
Used by
Lean2Js.Example.priceOr
sourceThe listed price, or the fallback where the sku is not in the book.
Equations
- Lean2Js.Example.priceOr prices sku fallback = prices.getD sku fallback
Instances For
Used by
Lean2Js.Example.byCurrency
sourceOne line per currency. Where a currency appears twice the later line is the one kept.
Equations
Instances For
Used by
Lean2Js.Example.quantityOr
sourceEquations
- Lean2Js.Example.quantityOr quantity fallback = Lean2Js.Opt.getD quantity fallback
Instances For
Used by
Lean2Js.Example.discountedIfAny
sourceEquations
Instances For
Used by
Lean2Js.Example.settledOrElse
sourceEquations
- Lean2Js.Example.settledOrElse outcome fallback = Lean2Js.Exc.getD outcome fallback
Instances For
Used by
Lean2Js.Example.settledCurrency
sourceEquations
- Lean2Js.Example.settledCurrency outcome = Lean2Js.Exc.map outcome Lean2Js.Example.currencyOf
Instances For
Used by
Lean2Js.Example.loudRefusal
sourceThe refusal upper-cased. What the settlement accepted is handed back untouched.
Equations
- Lean2Js.Example.loudRefusal outcome = Lean2Js.Exc.mapError outcome Lean2Js.Str.upper
Instances For
Used by
Lean2Js.Example.settledMoney
sourceEquations
- Lean2Js.Example.settledMoney outcome = Lean2Js.Exc.toOption outcome
Instances For
Used by
Lean2Js.Example.trackingIds
sourceThe tracking id of every order that has one, and an empty string for the rest. The match is inside
the traversal's own function rather than in a declaration of its own.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.refundCount
sourceHow many of the amounts are refunds, with the test written where the count is.
Equations
- Lean2Js.Example.refundCount amounts = Lean2Js.Arr.count amounts fun (amount : Int) => decide (amount < 0)
Instances For
Used by
Lean2Js.Example.creditNoteAmount
sourceA charge as it appears on a credit note, where money leaving is written negative.
Equations
- Lean2Js.Example.creditNoteAmount amount = -1 * max amount 0
Instances For
Used by
Lean2Js.Example.directionLabel
sourceWhat the sign on a statement line means.
Equations
- Lean2Js.Example.directionLabel (-1) = "credit"
- Lean2Js.Example.directionLabel 1 = "debit"
- Lean2Js.Example.directionLabel sign = "none"
Instances For
Used by
Lean2Js.Example.Category
sourceWhere a product sits in the catalogue. A group holds categories, so the type names itself and the
generated .d.ts type does too.
Instances For
Used by
Lean2Js.Example.Category.ty_eq
sourceUsed by
Lean2Js.Example.Category.toValue_hasTy
sourceUsed by
Lean2Js.Example.Category.toValues_hasTy
sourceUsed by
Lean2Js.Example.Category.toValue_eq
sourceUsed by
Lean2Js.Example.Category.ofValues
sourceEquations
Instances For
Used by
Lean2Js.Example.Category.denotes_fold
sourceUsed by
Lean2Js.Example.Category.denotes_foldList
sourceUsed by
Lean2Js.Example.Category.ofValues_map
sourceUsed by
Lean2Js.Example.Category.toValue
sourceEquations
- (Lean2Js.Example.Category.leaf x0).toValue = Lean2Js.Value.obj "leaf" [("name", Lean2Js.Enc.toValue x0)]
- (Lean2Js.Example.Category.group x0 x1).toValue = Lean2Js.Value.obj "group" [("name", Lean2Js.Enc.toValue x0), ("children", Lean2Js.Value.arr (List.map Lean2Js.Example.Category.toValue x1))]
Instances For
Used by
Lean2Js.Example.Category.accepts
sourceEquations
- Lean2Js.Example.Category.accepts p x = (p.findType? "Category" = some Lean2Js.Example.Category.typeDef ∧ Lean2Js.Example.Category.acceptsV p x)
Instances For
Used by
Lean2Js.Example.Category.ofValue_toValue
sourceUsed by
Lean2Js.Example.Category.acceptsV
sourceEquations
Instances For
Used by
Lean2Js.Example.Category.ofValue
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.Example.Category.ofValue (Lean2Js.Value.obj "leaf" [("name", v0)]) = (Lean2Js.Enc.ofValue v0).bind fun (x0 : String) => some (Lean2Js.Example.Category.leaf x0)
- Lean2Js.Example.Category.ofValue v = none
Instances For
Used by
Lean2Js.Example.Category.acceptsVs
sourceEquations
Instances For
Used by
Lean2Js.Example.Category.fold
sourceEquations
- Lean2Js.Example.Category.fold f0 f1 (Lean2Js.Example.Category.leaf x0) = f0 x0
- Lean2Js.Example.Category.fold f0 f1 (Lean2Js.Example.Category.group x0 x1) = f1 x0 (Lean2Js.Example.Category.foldList f0 f1 x1)
Instances For
Used by
Lean2Js.Example.Category.typeDef
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.instEncCategory
sourceEquations
- One or more equations did not get rendered due to their size.
Used by
Lean2Js.Example.Category.foldAlts
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.Category.foldList
sourceEquations
- Lean2Js.Example.Category.foldList f0 f1 [] = []
- Lean2Js.Example.Category.foldList f0 f1 (y :: ys) = Lean2Js.Example.Category.fold f0 f1 y :: Lean2Js.Example.Category.foldList f0 f1 ys
Instances For
Used by
Lean2Js.Example.categoryName
sourceEquations
Instances For
Used by
Lean2Js.Example.directChildren
sourceHow many categories sit directly under this one. What sits under those is a walk, which is what
categoryProducts takes.
Equations
Instances For
Used by
Lean2Js.Example.categoryProducts
sourceHow many products the catalogue holds, however deep the groups go. A group answers for everything under it, so this walks the whole tree rather than reading one level of it.
Equations
- Lean2Js.Example.categoryProducts category = Lean2Js.Example.Category.fold (fun (x : String) => 1) (fun (x : String) (counts : List Int) => Lean2Js.Arr.sum counts) category
Instances For
Used by
Lean2Js.Example.priceOf_certificate
sourceUsed by
Lean2Js.Example.discounted_certificate
sourceUsed by
Lean2Js.Example.settledOrElse_certificate
sourceUsed by
Lean2Js.Example.firstTracking_certificate
sourceUsed by
Lean2Js.Example.objIsListed_certificate
sourceUsed by
Lean2Js.Example.firstPage_certificate
sourceUsed by
Lean2Js.Example.lineTotals_certificate
sourceUsed by
Lean2Js.Example.divide_certificate
sourceUsed by
Lean2Js.Example.noteIsBlank_certificate
sourceUsed by
Lean2Js.Example.weekdayOf_certificate
sourceUsed by
Lean2Js.Example.objListedSkus_certificate
sourceUsed by
Lean2Js.Example.ship_certificate
sourceUsed by
Lean2Js.Example.cartTotal_certificate
sourceUsed by
Lean2Js.Example.validationMessage_certificate
sourceUsed by
Lean2Js.Example.monthlyLimit_certificate
sourceUsed by
Lean2Js.Example.monthOf_certificate
sourceUsed by
Lean2Js.Example.roleRank_certificate
sourceUsed by
Lean2Js.Example.safeQuotientIsPositive_certificate
sourceUsed by
Lean2Js.Example.loudRefusal_certificate
sourceUsed by
Lean2Js.Example.priceGap_certificate
sourceUsed by
Lean2Js.Example.objWithdrawn_certificate
sourceUsed by
Lean2Js.Example.guestPrice_certificate
sourceUsed by
Lean2Js.Example.settledCurrency_certificate
sourceUsed by
Lean2Js.Example.objListedPrices_certificate
sourceUsed by
Lean2Js.Example.firstAmount_certificate
sourceUsed by
Lean2Js.Example.bigQuotient_certificate
sourceUsed by
Lean2Js.Example.cappedCharge_certificate
sourceUsed by
Lean2Js.Example.spreadsheetCount_certificate
sourceUsed by
Lean2Js.Example.sameLabel_certificate
sourceUsed by
Lean2Js.Example.yearOf_certificate
sourceUsed by
Lean2Js.Example.trackingOf_certificate
sourceUsed by
Lean2Js.Example.add_certificate
sourceUsed by
Lean2Js.Example.trackingIds_certificate
sourceUsed by
Lean2Js.Example.canCheckout_certificate
sourceUsed by
Lean2Js.Example.mentionsTerm_certificate
sourceUsed by
Lean2Js.Example.categoryName_certificate
sourceUsed by
Lean2Js.Example.amountOr_certificate
sourceUsed by
Lean2Js.Example.total_certificate
sourceUsed by
Lean2Js.Example.joinFields_certificate
sourceUsed by
Lean2Js.Example.listedSkus_certificate
sourceUsed by
Lean2Js.Example.headOr_certificate
sourceUsed by
Lean2Js.Example.discountedIfAny_certificate
sourceUsed by
Lean2Js.Example.separatorAt_certificate
sourceUsed by
Lean2Js.Example.orderReference_certificate
sourceUsed by
Lean2Js.Example.settleMessage_certificate
sourceUsed by
Lean2Js.Example.sameMoney_certificate
sourceUsed by
Lean2Js.Example.catalogueSize_certificate
sourceUsed by
Lean2Js.Example.addMoney_certificate
sourceUsed by
Lean2Js.Example.slugOf_certificate
sourceUsed by
Lean2Js.Example.program
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.Example.negate_certificate
sourceUsed by
Lean2Js.Example.truncateLabel_certificate
sourceUsed by
Lean2Js.Example.refiled_certificate
sourceUsed by
Lean2Js.Example.canRefund_certificate
sourceUsed by
Lean2Js.Example.isSpreadsheet_certificate
sourceUsed by
Lean2Js.Example.amountWithTax_certificate
sourceUsed by
Lean2Js.Example.referenceFrom_certificate
sourceUsed by
Lean2Js.Example.storedCoupon_certificate
sourceUsed by
Lean2Js.Example.dayOfInstant_certificate
sourceUsed by
Lean2Js.Example.lineTotal_certificate
sourceUsed by
Lean2Js.Example.byCurrency_certificate
sourceUsed by
Lean2Js.Example.noDiscount_certificate
sourceUsed by
Lean2Js.Example.remainingItems_certificate
sourceUsed by
Lean2Js.Example.inLabelOrder_certificate
sourceUsed by
Lean2Js.Example.tenPercentOff_certificate
sourceUsed by
Lean2Js.Example.linesBelowFold_certificate
sourceUsed by
Lean2Js.Example.objPriceOf_certificate
sourceUsed by
Lean2Js.Example.pageOf_certificate
sourceUsed by
Lean2Js.Example.quantityOr_certificate
sourceUsed by
Lean2Js.Example.lineNumbers_certificate
sourceUsed by
Lean2Js.Example.settledOrderId_certificate
sourceUsed by
Lean2Js.Example.atLeast_certificate
sourceUsed by
Lean2Js.Example.dayNumber_certificate
sourceUsed by
Lean2Js.Example.amountOf_certificate
sourceUsed by
Lean2Js.Example.validateQuantity_certificate
sourceUsed by
Lean2Js.Example.chargeable_certificate
sourceUsed by
Lean2Js.Example.dayOfMonthOf_certificate
sourceUsed by
Lean2Js.Example.limitsFor_certificate
sourceUsed by
Lean2Js.Example.remainder_certificate
sourceUsed by
Lean2Js.Example.monthLength_certificate
sourceUsed by
Lean2Js.Example.repriced_certificate
sourceUsed by
Lean2Js.Example.scaleFee_certificate
sourceUsed by
Lean2Js.Example.sortsBefore_certificate
sourceUsed by
Lean2Js.Example.bucketOf_certificate
sourceUsed by
Lean2Js.Example.clampChannel_certificate
sourceUsed by
Lean2Js.Example.currencyOf_certificate
sourceUsed by
Lean2Js.Example.refundableOnly_certificate
sourceUsed by
Lean2Js.Example.isListed_certificate
sourceUsed by
Lean2Js.Example.priceOr_certificate
sourceUsed by
Lean2Js.Example.referencePrefix_certificate
sourceUsed by
Lean2Js.Example.settledMoney_certificate
sourceUsed by
Lean2Js.Example.comparable_certificate
sourceUsed by
Lean2Js.Example.cheapestFirst_certificate
sourceUsed by
Lean2Js.Example.objRepriced_certificate
sourceUsed by
Lean2Js.Example.currenciesOf_certificate
sourceUsed by
Lean2Js.Example.combinedCart_certificate
sourceUsed by
Lean2Js.Example.directionLabel_certificate
sourceUsed by
Lean2Js.Example.categoryProducts_certificate
sourceUsed by
Lean2Js.Example.someLineIsFree_certificate
sourceUsed by
Lean2Js.Example.couponApplies_certificate
sourceUsed by
Lean2Js.Example.directChildren_certificate
sourceUsed by
Lean2Js.Example.anyOverLimit_certificate
sourceUsed by
Lean2Js.Example.allLines_certificate
sourceUsed by
Lean2Js.Example.amountsTotal_certificate
sourceUsed by
Lean2Js.Example.stocksSku_certificate
sourceUsed by
Lean2Js.Example.everyLineWithinLimit_certificate
sourceUsed by
Lean2Js.Example.listedPrices_certificate
sourceUsed by
Lean2Js.Example.firstOverLimit_certificate
sourceUsed by
Lean2Js.Example.cartIsEmpty_certificate
sourceUsed by
Lean2Js.Example.mostRecentFirst_certificate
sourceUsed by
Lean2Js.Example.creditNoteAmount_certificate
sourceUsed by
Lean2Js.Example.fieldCount_certificate
sourceUsed by
Lean2Js.Example.previewLines_certificate
sourceUsed by
Lean2Js.Example.memberPrice_certificate
sourceUsed by
Lean2Js.Example.objCatalogueSize_certificate
sourceUsed by
Lean2Js.Example.amountColumn_certificate
sourceUsed by
Lean2Js.Example.priced_certificate
sourceUsed by
Lean2Js.Example.clampQuantity_certificate
sourceUsed by
Lean2Js.Example.quantityLabel_certificate
sourceUsed by
Lean2Js.Example.refundCount_certificate
sourceUsed by
Lean2Js.Example.taxOn_certificate
sourceUsed by
Lean2Js.Example.latestEvent_certificate
sourceUsed by
Lean2Js.Example.mixChannels_certificate
sourceUsed by
Lean2Js.Example.linesWithTax_certificate
sourceUsed by
Lean2Js.Example.dailyLimit_certificate
sourceUsed by
Lean2Js.Example.rebindTwice_certificate
sourceUsed by
Lean2Js.Example.objLimitsFor_certificate
sourceUsed by
Lean2Js.Example.renewalLabel_certificate
sourceUsed by
Lean2Js.Example.withdrawn_certificate
sourceUsed by
Lean2Js.Example.receiptRule_certificate
sourceUsed by
Lean2Js.Example.add_comm
sourceSwapping the arguments of add changes nothing: whatever the two integers, both orders give the same
sum.
Used by
Lean2Js.Example.cheapest_first_keeps_every_line
sourceOrdering a cart by price loses no line and invents none: the answer holds the same lines as the cart it was given, in some order.
Used by
Lean2Js.Example.monthly_limit_is_not_negative
sourceNo role's monthly limit is negative, including a role whose book records none.
Used by
Lean2Js.Example.nothing_under_it_counts_none
sourceA category with nothing under it counts nothing under it, whatever it is called. Two shapes have nothing under them — a leaf, and a group holding no categories — and both are here.
Used by
Lean2Js.Example.a_group_counts_what_is_directly_under_it
sourceA group counts what sits directly under it, however deep those categories go themselves.
Used by
Lean2Js.Example.a_leaf_holds_one_product
sourceA leaf holds one product, whatever it is called.
Used by
Lean2Js.Example.an_empty_group_holds_no_product
sourceA group is not itself a product: a group with nothing under it holds none.
Used by
Lean2Js.Example.nesting_keeps_the_product
sourceThe walk goes past the first level, which is the whole difference from directChildren: a group
whose only child is a group holding two leaves holds both those products, where counting what is
directly under it answers one.
Used by
Lean2Js.Example.a_group_holds_what_its_children_hold
sourceA group holds what its children hold and nothing besides: the count distributes over the children, however deep each of them goes.
Used by
Lean2Js.Example.failed_settlement_has_no_order_id
sourceA settlement that failed carries no order id, whatever it failed with.
Used by
Lean2Js.Example.line_total_caps_the_quantity
sourceA line ordered past the cap is billed at the cap, whatever the unit price.
Used by
Lean2Js.Example.reference_from_three_parts
sourceThree parts come out of referenceFrom in the order they went in, with a hyphen written between each
neighbouring pair. Hyphens the parts themselves carry are not counted, so this says nothing about how many
the answer holds.
Used by
Lean2Js.Example.line_numbers_counts_the_rows
sourceA receipt numbers one row per row it prints: as many numbers as the clamped count says, whatever
rows was asked for.
Used by
Lean2Js.Example.line_numbers_are_rows
sourceThe numbers a receipt prints are exactly the rows it has: a number is one of them when it is at least 1 and at most the clamped count, and is not one of them otherwise.
Used by
Lean2Js.Example.money
sourceAn amount of money as it crosses the boundary.
Equations
- Lean2Js.Example.money amount currency = Lean2Js.Value.obj "Money" [("amount", Lean2Js.Value.int53 amount), ("currency", Lean2Js.Value.str currency)]
Instances For
Used by
Lean2Js.Example.draft_never_ships
sourceA draft order cannot ship, whatever tracking id comes with it.
Used by
Lean2Js.Example.clamped_quantity_in_range
sourceClamping any Int53 quantity to at most 999 lands between 1 and 999.
Used by
Lean2Js.Example.same_currency_adds
sourceTwo amounts in the same currency add up, as long as their sum stays within Int53.
Used by
The generated function, not just the expression #
Decl.fragment_correct is about a compiled expression. Decl.decl_correct carries it up to a call of
the generated function, entry check and all. It holds of every declaration the program has: the fragment
covers the whole subset.
The arguments are whatever Decl.ArgsDecode admits, which is the set the entry check lets through and
not just the canonical spelling: a JS value whose keys are in another order, or which carries keys the
declared type does not name, decodes to the same Value and is covered by the same theorem.
The claims below hold for every reading of the keys the program compiles under, which for this program is the one its types declare: the compiled module and the encoding read one and the same, so the agreement does not depend on which.
Lean2Js.Example.program_typesNoDictObj
sourceNo type this program declares carries a dictionary the declaration told the compiler to hand across
the boundary as a plain object rather than as a Map. This is the half encodeAt reads — it recurses
into a declared type's fields and never into a declaration — so every claim below whose own return type
reaches no such dictionary is stated at encodeValue, the spelling it has always had, through
encodeAt_eq_encodeValue.
The program itself does hand one across: objRepriced and objWithdrawn return a Dict.Obj Int, so
their entries emit the walk out that Compile.retWalk expands and their results are read at encodeAt
rather than at encodeValue. Every other obj declaration takes one and returns something that reaches
none, so its entry emits no walk and this theorem carries it to encodeValue like any other.
Used by
Lean2Js.Example.add_calls_agree
sourceWhatever arguments the entry check accepts, the generated add returns what eval returns. Its body
is a single binary operation.
Used by
Lean2Js.Example.discounted_calls_agree
sourceThe same for a body that opens with a let, which the compiler emits as a const statement.
Used by
Lean2Js.Example.rebindTwice_calls_agree
sourceAnd for a body whose second let rebinds a name already in scope, which the compiler leaves as an
expression rather than a statement.
Used by
Lean2Js.Example.memberPrice_calls_agree
sourceAnd for a body that calls another declaration, handing it a third by name. The call is where the
proof leaves the expression it is looking at: priced applies the function it was given, so the claim
about memberPrice rests on the same claim about tenPercentOff.
Used by
Throwing what the reference semantics throws #
Decl.decl_traps is the other half of decl_correct: for arguments the entry accepts, a body that
throws is matched by a generated function that throws the same code.
Lean2Js.Example.program_progOk
sourceThe first of the two checks the emitter runs on a program before it writes anything: every call goes backwards.
Used by
Lean2Js.Example.program_cost_fits
sourceThe second: the fuel the artifact runs at covers the deepest call this program can make.
Used by
Lean2Js.Example.add_traps
sourceFor arguments the entry check decodes to the count and types add declares, whenever eval refuses
to return a value the generated function throws the code eval threw. Its body can reach int53Overflow.
Running out of fuel is not among the answers: the two checks above rule it out for this program. What
falls outside those types never reaches the body at all — that is add_refuses.
Used by
Lean2Js.Example.add_overflow_throws
sourceThe trap is reachable, and reached the same way on both sides: one past the top of Int53 throws
int53Overflow out of the generated function.
Used by
Lean2Js.Example.addMoney_calls_agree
sourceThe fragment reaches business logic, not just arithmetic: addMoney reads two fields, compares them,
and builds a Result around a constructor.
Used by
Lean2Js.Example.ship_calls_agree
sourceThe fragment reaches a match: ship chooses an arm by the constructor of its scrutinee and reads
the fields that arm binds.
Used by
Lean2Js.Example.cartTotal_calls_agree
sourceAnd an array traversal: cartTotal folds a body over the elements, each under its own binding.
Used by
Lean2Js.Example.cartTotal_traps
sourceThe trap side of a traversal: a fold whose running sum leaves Int53 throws where eval does, at
the element that overflowed rather than at the end.
Used by
Refusing what the reference semantics refuses #
Decl.decl_refuses needs no InFragment either — the entry check does not look at the body. What it
asks for instead is paramsCheckable, which decl_correct does not: a declaration taking another by
name has no boundary to check.
Lean2Js.Example.add_refuses
sourceWhatever add is handed, if no reading of those JS values is a pair of Int53s, the generated
function throws instead of computing. The one shape left out is a dictionary holding a key twice, which a
Map cannot hold.
Used by
Lean2Js.Example.add_refuses_string
sourceThe hypothesis discharged on a concrete call: a string where an Int53 was declared throws, because
no Int53 encodes to one.
Used by
Lean2Js.Example.addMoney_traps
sourceThe same for addMoney, under the same declared types: the only way its body throws is the Int53
overflow of the sum, and the generated function throws that code.
Used by
Lean2Js.Example.file_reads_back
sourceThe text lean2js writes for this program reads back as the module the compiler built. Nothing in
between is assumed: the roundtrip holds of whatever compileProgram produces, so the claim carries no
side condition about the shape of the module.
Used by
Lean2Js.Example.helpers_ship_as_modelled
sourceThe runtime helpers are the last hand-written JavaScript in the artifact, and the model of the
generated code reaches most of them through one table. Every row of that table is what the source the
compiler prints actually computes; helperArgsOk is what a call to a row is still asked for, and it asks
only for the Int53 range a type has already given, the distinct keys a Map cannot break, and the shapes
on which __eq's walk and the model's structural equality decide the same thing.
__ck and the seven traversal helpers are not rows: the model evaluates them as rules of its own, and
HelperProof answers those against the same printed source.
Used by
Lean2Js.Example.entry_check_fits_dts
sourceEverything the entry check lets through is a value admitted by the type the published .d.ts prints
for that parameter. The two are not the same set: the check reads a number's range, which a TypeScript
type cannot say, so a call the .d.ts accepts can still be refused at the boundary.
Used by
Lean2Js.Example.dts_fits_entry_check
sourceThe other direction, and the one a caller feels: an argument the published .d.ts type admits is one
the entry check accepts. Dts.inRange is the whole of what is assumed about the value — the Int53 and
UInt32 ranges the check reads, which a TypeScript type cannot express. The order the keys arrive in is
not read, and neither are keys the type does not declare.
Used by
Lean2Js.Example.encoded_values_fit_dts
sourceWhat comes back, rather than what goes in: a value the reference semantics gives a declared type to,
read out through that type, is one the published .d.ts admits at the type it prints for a return,
which is the narrower of the two where the type reaches a dictionary crossing as a plain object.
typeSound gives the type to whatever a declaration returns, and decl_correct says the generated
function returns exactly that reading — so this is the value a consumer meets. Where the type reaches no
such dictionary the reading is the encoding itself (encodeAt_eq_encodeValue,
program_typesNoDictObj).
Used by
Lean2Js.Example.returned_values_fit_parameter_types
sourceThe type the .d.ts prints for a return is one the type it prints for a parameter admits, so a call
chained onto another type-checks. That is a statement about the two printed types and nothing else; that
the value is accepted at run time is returned_values_pass_the_entry_check. This is what lets
encoded_values_fit_dts be handed to dts_fits_entry_check.
Used by
Lean2Js.Example.returned_values_pass_the_entry_check
sourceAnd it is accepted, not merely admitted by the type: what one call hands back passes the next call's
entry check, with none of the range caveat dts_fits_entry_check carries. The range is what
Value.hasTy already says about the value the first call returned, so two exported functions compose
with no check of the consumer's own in between. What the second call then computes on is
returned_values_read_back_unchanged.
Used by
Lean2Js.Example.returned_values_read_back_unchanged
sourceThe other half of composing two calls: the second entry does not merely accept what the first handed
back, it reads it back as the value the first one returned. Together with
returned_values_pass_the_entry_check that is the whole of what the crossing costs — what
decl_correct says the first call hands back is accepted, and rebuilt as the value it encodes. A
dictionary walked out to a plain object becomes the Map the body works in again, and nothing else
moves.
Used by
Lean2Js.Example.steps_agree
sourceThe small-step machine, given enough steps, answers exactly as eval does every call whose arguments
the entry check has a shape to read — which is every exported function, and every internal one that takes
no function.
Used by
Lean2Js.Example.no_rate_is_no_tax
sourceNothing is taxed at a rate of zero, whatever the amount.
Used by
Lean2Js.Example.a_refund_is_taxed_as_the_charge
sourceA refund is taxed exactly as the charge it reverses: the tax on a negative amount is the tax on the
positive one, negated. Rounding a half upwards, as JavaScript's Math.round does, would not hold
this.
Used by
Lean2Js.Example.tax_of_five_at_a_tenth
sourceWhere the tax lands exactly on a half, it goes away from zero and is not dropped: a tenth of five is one either way round, where truncating would answer zero to both. Two amounts rather than a rule — the symmetry above holds of truncation too, so it is this that says which way a half goes.
Used by
Lean2Js.Example.the_day_holds_the_instant
sourceThe day an instant is filed under is the day that holds it: the instant is at or after that day's first millisecond and before the next day's. It is what says an instant before the epoch belongs to the day it is inside rather than to the one after — truncating division puts the last millisecond before the epoch in day zero, where this rules it out for every instant rather than at one.
Used by
Lean2Js.Example.manifest
sourceEquations
- Lean2Js.Example.manifest = { package := "@lean2js/verified-example", version := "0.1.0" }