Lean2Js.Eval
The reference semantics of the subset, as a fuelled big-step evaluator #
The reference semantics of the subset. Every correctness theorem is stated as agreement between "the
result of this eval" and "the result of evaluating the generated JS".
It is a fuelled big-step semantics because partial would make termination an axiom, putting it beyond
the reach of proof.
Lean2Js.Env
sourceEquations
Instances For
Used by
Lean2Js.Env.lookup?
sourceEquations
- env.lookup? name = Option.map (fun (x : String × Lean2Js.Value) => x.snd) (List.find? (fun (x : String × Lean2Js.Value) => x.fst == name) env)
Instances For
Used by
Lean2Js.litValue
sourceEquations
- Lean2Js.litValue (Lean2Js.Core.Lit.bool b) = Lean2Js.Value.bool b
- Lean2Js.litValue (Lean2Js.Core.Lit.int53 i) = Lean2Js.Value.int53 i
- Lean2Js.litValue (Lean2Js.Core.Lit.uint32 n) = Lean2Js.Value.uint32 n
- Lean2Js.litValue (Lean2Js.Core.Lit.str s) = Lean2Js.Value.str s
- Lean2Js.litValue (Lean2Js.Core.Lit.bigint i) = Lean2Js.Value.bigint i
Instances For
Used by
Lean2Js.mkInt53
sourceInt53 traps rather than wraps. JS's Number silently loses precision past 2^53, so failing makes the semantics easier to line up than quietly returning a wrong answer.
Equations
Instances For
Used by
Lean2Js.rangeValues
sourceThe elements of Arr.range n: the whole numbers below n, and none of them when n is not
positive. Every element is smaller than n, so an argument that is an Int53 bounds them all and no
element of the answer can be out of range.
Equations
- Lean2Js.rangeValues n = List.map (fun (k : Nat) => Lean2Js.Value.int53 (Int.ofNat k)) (List.range n.toNat)
Instances For
Used by
Lean2Js.applyUn
sourceEquations
- Lean2Js.applyUn Lean2Js.Core.UnOp.not (Lean2Js.Value.bool b) = Except.ok (Lean2Js.Value.bool !b)
- Lean2Js.applyUn Lean2Js.Core.UnOp.neg (Lean2Js.Value.int53 i) = Lean2Js.mkInt53 (-i)
- Lean2Js.applyUn Lean2Js.Core.UnOp.neg (Lean2Js.Value.bigint i) = Except.ok (Lean2Js.Value.bigint (-i))
- Lean2Js.applyUn Lean2Js.Core.UnOp.abs (Lean2Js.Value.int53 i) = Lean2Js.mkInt53 ↑i.natAbs
- Lean2Js.applyUn Lean2Js.Core.UnOp.abs (Lean2Js.Value.bigint i) = Except.ok (Lean2Js.Value.bigint ↑i.natAbs)
- Lean2Js.applyUn Lean2Js.Core.UnOp.toString (Lean2Js.Value.int53 i) = Except.ok (Lean2Js.Value.str (toString i))
- Lean2Js.applyUn Lean2Js.Core.UnOp.range (Lean2Js.Value.int53 n) = Except.ok (Lean2Js.Value.arr (Lean2Js.rangeValues n))
- Lean2Js.applyUn x✝¹ x✝ = Except.error (Lean2Js.Err.typeError (toString "unary " ++ toString (repr x✝¹) ++ toString " applied to a value of the wrong type"))
Instances For
Used by
Lean2Js.applyArith
sourceInteger division is pinned to truncation. Lean's / is floor division (-7 / 2 = -4), which
disagrees with JS's Math.trunc(-7 / 2) = -3.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.applyArith Lean2Js.Core.BinOp.add (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = Lean2Js.mkInt53 (a + b)
- Lean2Js.applyArith Lean2Js.Core.BinOp.sub (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = Lean2Js.mkInt53 (a - b)
- Lean2Js.applyArith Lean2Js.Core.BinOp.mul (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = Lean2Js.mkInt53 (a * b)
- Lean2Js.applyArith Lean2Js.Core.BinOp.div (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = if (b == 0) = true then Except.error Lean2Js.Err.divByZero else Lean2Js.mkInt53 (a.tdiv b)
- Lean2Js.applyArith Lean2Js.Core.BinOp.mod (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = if (b == 0) = true then Except.error Lean2Js.Err.divByZero else Lean2Js.mkInt53 (a.tmod b)
- Lean2Js.applyArith op (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = Except.error (Lean2Js.Err.typeError "not an arithmetic operator")
- Lean2Js.applyArith Lean2Js.Core.BinOp.add (Lean2Js.Value.uint32 a) (Lean2Js.Value.uint32 b) = Except.ok (Lean2Js.Value.uint32 (a + b))
- Lean2Js.applyArith Lean2Js.Core.BinOp.sub (Lean2Js.Value.uint32 a) (Lean2Js.Value.uint32 b) = Except.ok (Lean2Js.Value.uint32 (a - b))
- Lean2Js.applyArith Lean2Js.Core.BinOp.mul (Lean2Js.Value.uint32 a) (Lean2Js.Value.uint32 b) = Except.ok (Lean2Js.Value.uint32 (a * b))
- Lean2Js.applyArith op (Lean2Js.Value.uint32 a) (Lean2Js.Value.uint32 b) = Except.error (Lean2Js.Err.typeError "not an arithmetic operator")
- Lean2Js.applyArith Lean2Js.Core.BinOp.add (Lean2Js.Value.bigint a) (Lean2Js.Value.bigint b) = Except.ok (Lean2Js.Value.bigint (a + b))
- Lean2Js.applyArith Lean2Js.Core.BinOp.sub (Lean2Js.Value.bigint a) (Lean2Js.Value.bigint b) = Except.ok (Lean2Js.Value.bigint (a - b))
- Lean2Js.applyArith Lean2Js.Core.BinOp.mul (Lean2Js.Value.bigint a) (Lean2Js.Value.bigint b) = Except.ok (Lean2Js.Value.bigint (a * b))
- Lean2Js.applyArith op (Lean2Js.Value.bigint a) (Lean2Js.Value.bigint b) = Except.error (Lean2Js.Err.typeError "not an arithmetic operator")
- Lean2Js.applyArith op x✝¹ x✝ = Except.error (Lean2Js.Err.typeError "arithmetic on mismatched or unsupported operand types")
Instances For
Used by
Lean2Js.compareValues
sourceEquations
- Lean2Js.compareValues op (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = Except.ok (Lean2Js.Value.bool (Lean2Js.compareValues.orderBy op (compare a b)))
- Lean2Js.compareValues op (Lean2Js.Value.uint32 a) (Lean2Js.Value.uint32 b) = Except.ok (Lean2Js.Value.bool (Lean2Js.compareValues.orderBy op (compare a.toNat b.toNat)))
- Lean2Js.compareValues op (Lean2Js.Value.bigint a) (Lean2Js.Value.bigint b) = Except.ok (Lean2Js.Value.bool (Lean2Js.compareValues.orderBy op (compare a b)))
- Lean2Js.compareValues op (Lean2Js.Value.str a) (Lean2Js.Value.str b) = Except.ok (Lean2Js.Value.bool (Lean2Js.compareValues.orderBy op (compare a b)))
- Lean2Js.compareValues op x✝¹ x✝ = Except.error (Lean2Js.Err.typeError "comparison on mismatched or unsupported operand types")
Instances For
Used by
Lean2Js.compareValues.orderBy
sourceEquations
- Lean2Js.compareValues.orderBy Lean2Js.Core.BinOp.lt o = (o == Ordering.lt)
- Lean2Js.compareValues.orderBy Lean2Js.Core.BinOp.le o = (o != Ordering.gt)
- Lean2Js.compareValues.orderBy Lean2Js.Core.BinOp.gt o = (o == Ordering.gt)
- Lean2Js.compareValues.orderBy Lean2Js.Core.BinOp.ge o = (o != Ordering.lt)
- Lean2Js.compareValues.orderBy op o = false
Instances For
Used by
Lean2Js.applyMinMax
sourceStrings are left out even though they are ordered: JS's < orders them by UTF-16 unit, so a String
min would have to route through __strcmp the way the ordering comparisons do.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.applyBin
sourceEquations
- Lean2Js.applyBin Lean2Js.Core.BinOp.add a b = Lean2Js.applyArith Lean2Js.Core.BinOp.add a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.sub a b = Lean2Js.applyArith Lean2Js.Core.BinOp.sub a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.mul a b = Lean2Js.applyArith Lean2Js.Core.BinOp.mul a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.div a b = Lean2Js.applyArith Lean2Js.Core.BinOp.div a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.mod a b = Lean2Js.applyArith Lean2Js.Core.BinOp.mod a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.min a b = Lean2Js.applyMinMax Lean2Js.Core.BinOp.min a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.max a b = Lean2Js.applyMinMax Lean2Js.Core.BinOp.max a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.lt a b = Lean2Js.compareValues Lean2Js.Core.BinOp.lt a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.le a b = Lean2Js.compareValues Lean2Js.Core.BinOp.le a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.gt a b = Lean2Js.compareValues Lean2Js.Core.BinOp.gt a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.ge a b = Lean2Js.compareValues Lean2Js.Core.BinOp.ge a b
- Lean2Js.applyBin Lean2Js.Core.BinOp.eq a b = Except.ok (Lean2Js.Value.bool (a == b))
- Lean2Js.applyBin Lean2Js.Core.BinOp.ne a b = Except.ok (Lean2Js.Value.bool (a != b))
- Lean2Js.applyBin Lean2Js.Core.BinOp.and a b = Except.error (Lean2Js.Err.typeError "logical operators are short-circuited by eval")
- Lean2Js.applyBin Lean2Js.Core.BinOp.or a b = Except.error (Lean2Js.Err.typeError "logical operators are short-circuited by eval")
- Lean2Js.applyBin Lean2Js.Core.BinOp.concat (Lean2Js.Value.str x) (Lean2Js.Value.str y) = Except.ok (Lean2Js.Value.str (x ++ y))
- Lean2Js.applyBin Lean2Js.Core.BinOp.concat (Lean2Js.Value.arr x) (Lean2Js.Value.arr y) = Except.ok (Lean2Js.Value.arr (x ++ y))
- Lean2Js.applyBin Lean2Js.Core.BinOp.concat a b = Except.error (Lean2Js.Err.typeError "concat expects two Strings or two Arrays")
Instances For
Used by
Lean2Js.isTrimmable
sourceThe whitespace trim strips. Written out rather than delegated to Char.isWhitespace because the
generated code has to strip exactly this set, and JS's own trim also takes NBSP, the BOM and the line
separators.
Instances For
Used by
Lean2Js.asciiUpper
sourceCase conversion is ASCII only. JS's toUpperCase is neither: it maps ß to SS, which changes the
length of the string.
Equations
Instances For
Used by
Lean2Js.asciiLower
sourceEquations
Instances For
Used by
Lean2Js.trimChars
sourceEquations
Instances For
Used by
Lean2Js.hasInfix
sourceEquations
- Lean2Js.hasInfix needle [] = needle.isEmpty
- Lean2Js.hasInfix needle (c :: rest) = (needle.isPrefixOf (c :: rest) || Lean2Js.hasInfix needle rest)
Instances For
Used by
Lean2Js.indexOfChars
sourceWhere needle first sits in the haystack, counted in code points. The empty needle sits at 0, so
this answers some 0 on the empty haystack too.
Equations
- Lean2Js.indexOfChars [] x✝ = if x✝.isPrefixOf [] = true then some 0 else none
- Lean2Js.indexOfChars (c :: rest) x✝ = if x✝.isPrefixOf (c :: rest) = true then some 0 else Option.map (fun (x : Nat) => x + 1) (Lean2Js.indexOfChars rest x✝)
Instances For
Used by
Lean2Js.splitStr
sourceSplitting on the empty separator gives back the whole string. JS's split("") instead returns the
UTF-16 units, which is why the generated code cannot call it unguarded.
Instances For
Used by
Lean2Js.joinFrom
sourceEquations
- Lean2Js.joinFrom sep acc [] = acc
- Lean2Js.joinFrom sep acc (s :: rest) = Lean2Js.joinFrom sep (acc ++ sep ++ s) rest
Instances For
Used by
Lean2Js.joinStr
sourceEquations
- Lean2Js.joinStr [] sep = ""
- Lean2Js.joinStr (s :: rest) sep = Lean2Js.joinFrom sep s rest
Instances For
Used by
Lean2Js.repeatStr
sources written n times over, one copy at a time. The halving the emitted helper uses is proved equal
to this in Correct; this is the shape the docstring claims.
Equations
- Lean2Js.repeatStr s 0 = ""
- Lean2Js.repeatStr s n.succ = s ++ Lean2Js.repeatStr s n
Instances For
Used by
Lean2Js.repeatStr_empty
sourceUsed by
Lean2Js.valueStrs
sourceEquations
- Lean2Js.valueStrs [] = some []
- Lean2Js.valueStrs (Lean2Js.Value.str s :: rest) = Option.map (fun (x : List String) => s :: x) (Lean2Js.valueStrs rest)
- Lean2Js.valueStrs x✝ = none
Instances For
Used by
Lean2Js.valueStrs_map_str
sourceUsed by
Lean2Js.dictLookup
sourceEquations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.dictWith
sourceWriting an existing key leaves it where it is and writing a new one appends, which is what Map.set
does. Iteration order is observable through keys, so the two have to agree on it.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.digitsValue
sourceThe digits read as a number, with no bound on the answer. A character that is not a digit
contributes its code point less 48, which parseInt53 throws away by printing the answer back.
Equations
- Lean2Js.digitsValue cs = List.foldl (fun (acc : Int) (c : Char) => acc * 10 + (↑c.toNat - 48)) 0 cs
Instances For
Used by
Lean2Js.parseInt53
sourceReading an Int53 back from its decimal spelling. The answer has to print as the string it was read
from, so what this accepts is exactly what toString prints: "007", "+5", " 5" and "-0" are
refused, and so is anything outside the Int53 range.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.parseInt53_range
sourceUsed by
Lean2Js.applyStrUn
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.applyStrUn Lean2Js.Core.StrUnOp.trim (Lean2Js.Value.str s) = Except.ok (Lean2Js.Value.str (String.ofList (Lean2Js.trimChars s.toList)))
- Lean2Js.applyStrUn Lean2Js.Core.StrUnOp.upper (Lean2Js.Value.str s) = Except.ok (Lean2Js.Value.str (String.ofList (List.map Lean2Js.asciiUpper s.toList)))
- Lean2Js.applyStrUn Lean2Js.Core.StrUnOp.lower (Lean2Js.Value.str s) = Except.ok (Lean2Js.Value.str (String.ofList (List.map Lean2Js.asciiLower s.toList)))
- Lean2Js.applyStrUn x✝¹ x✝ = Except.error (Lean2Js.Err.typeError (toString x✝¹.name ++ toString " expects a String"))
Instances For
Used by
Lean2Js.applyStrBin
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.applyStrBin Lean2Js.Core.StrBinOp.startsWith (Lean2Js.Value.str s) (Lean2Js.Value.str t) = Except.ok (Lean2Js.Value.bool (t.toList.isPrefixOf s.toList))
- Lean2Js.applyStrBin Lean2Js.Core.StrBinOp.endsWith (Lean2Js.Value.str s) (Lean2Js.Value.str t) = Except.ok (Lean2Js.Value.bool (t.toList.reverse.isPrefixOf s.toList.reverse))
- Lean2Js.applyStrBin Lean2Js.Core.StrBinOp.includes (Lean2Js.Value.str s) (Lean2Js.Value.str t) = Except.ok (Lean2Js.Value.bool (Lean2Js.hasInfix t.toList s.toList))
- Lean2Js.applyStrBin Lean2Js.Core.StrBinOp.split (Lean2Js.Value.str s) (Lean2Js.Value.str sep) = Except.ok (Lean2Js.Value.arr (List.map Lean2Js.Value.str (Lean2Js.splitStr s sep)))
- Lean2Js.applyStrBin x✝² x✝¹ x✝ = Except.error (Lean2Js.Err.typeError (toString x✝².name ++ toString " got operands of the wrong type"))
Instances For
Used by
Lean2Js.sliceStr
sourceIndices count code points, and one outside the string traps the way an array read does. Clamping is
what JS's own substring would do, and silently returning a shorter string is worse than failing.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.sliceStr s lo hi = Except.error (Lean2Js.Err.typeError "substring expects a String and two Int53 bounds")
Instances For
Used by
Lean2Js.sliceArr
sourceBounds count elements and one outside the array traps, exactly as substring's do on a String.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.sliceArr a lo hi = Except.error (Lean2Js.Err.typeError "slice expects an Array and two Int53 bounds")
Instances For
Used by
Lean2Js.asBool
sourceEquations
- Lean2Js.asBool (Lean2Js.Value.bool b) = Except.ok (Lean2Js.Value.bool b)
- Lean2Js.asBool x✝ = Except.error (Lean2Js.Err.typeError "expected a Bool")
Instances For
Used by
Lean2Js.calleeOf
sourceA function-typed parameter holds the name of a declaration, so applying it is an ordinary call to that name. Anything else bound to the name is rejected by the compiler, never here.
Equations
- Lean2Js.calleeOf env fn = match env.lookup? fn with | some (Lean2Js.Value.fn name) => name | x => fn
Instances For
Used by
Lean2Js.bindParams
sourceEquations
- Lean2Js.bindParams (p :: ps) (v :: vs) = (p.name, v) :: Lean2Js.bindParams ps vs
- Lean2Js.bindParams x✝¹ x✝ = []
Instances For
Used by
Lean2Js.bindNames
sourceEquations
- Lean2Js.bindNames (n :: ns) (v :: vs) = (n, v) :: Lean2Js.bindNames ns vs
- Lean2Js.bindNames x✝¹ x✝ = []
Instances For
Used by
Lean2Js.matchPat
sourceWhat a pattern binds when it matches the value, and nothing when it does not. Matching needs no
evaluation, so Step runs the same function in one transition rather than decomposing the scrutinee
across frames.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.matchPat Lean2Js.Core.Pat.wild x✝ = some []
- Lean2Js.matchPat (Lean2Js.Core.Pat.bind name) x✝ = some [(name, x✝)]
- Lean2Js.matchPat (Lean2Js.Core.Pat.lit l) x✝ = if (Lean2Js.litValue l == x✝) = true then some [] else none
- Lean2Js.matchPat (Lean2Js.Core.Pat.ctor name args) x✝ = none
Instances For
Used by
Lean2Js.matchPats
sourceEquations
- Lean2Js.matchPats [] [] = some []
- Lean2Js.matchPats (pat :: pats) (v :: vs) = do let here ← Lean2Js.matchPat pat v let rest ← Lean2Js.matchPats pats vs some (here ++ rest)
- Lean2Js.matchPats x✝¹ x✝ = none
Instances For
Used by
Lean2Js.firstMatch
sourceThe first arm whose pattern matches, with what it bound. Arms are tried in order, so an arm is reached only when every earlier one failed.
Equations
- Lean2Js.firstMatch [] x✝ = none
- Lean2Js.firstMatch (alt :: rest) x✝ = match Lean2Js.matchPat alt.pat x✝ with | some binds => some (binds, alt.body) | none => Lean2Js.firstMatch rest x✝
Instances For
Used by
Lean2Js.keyLe
sourceThe order the keys of a sortByKey are compared by. Int53 and String are the only key types the
compiler lets through, and both orders are the ones the subset already has: ≤ on Int53, and the
code-point order compare gives, which is what < on two strings already means here.
Equations
- Lean2Js.keyLe (Lean2Js.Value.int53 a) (Lean2Js.Value.int53 b) = decide (a ≤ b)
- Lean2Js.keyLe (Lean2Js.Value.str a) (Lean2Js.Value.str b) = (compare a b != Ordering.gt)
- Lean2Js.keyLe x✝¹ x✝ = false
Instances For
Used by
Lean2Js.isNumKey
sourceEquations
Instances For
Used by
Lean2Js.isStrKey
sourceEquations
Instances For
Used by
Lean2Js.keysOk
sourceThe keys are all Int53 or all String. A well-typed program cannot reach the other case: the
key type is settled by the compiler before the walk runs.
Equations
- Lean2Js.keysOk ps = ((ps.all fun (p : Lean2Js.Value × Lean2Js.Value) => Lean2Js.isNumKey p.fst) || ps.all fun (p : Lean2Js.Value × Lean2Js.Value) => Lean2Js.isStrKey p.fst)
Instances For
Used by
Lean2Js.sortPairs
sourceList.mergeSort is the model rather than a sort of our own so that what it already proves — the
answer is a permutation of the input, and equal keys keep the order they came in — is what an author
reasons with.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.sortPairs_ne_outOfFuel
sourceUsed by
Lean2Js.sortPairs_mem
sourceEvery value the sort answers with came in, which is what carries a property of the elements across
it. List.mergeSort gives the permutation; the pairing gives the element back.
Used by
Lean2Js.evalExpr
sourceand / or are handled first because JS's && / || short-circuit. Evaluating both sides would
make false && (1 / 0) give false in JS and a trap here, splitting the differential test at once.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.evalExpr p 0 env e = Except.error Lean2Js.Err.outOfFuel
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.lit l) = Except.ok (Lean2Js.litValue l)
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.var name) = match env.lookup? name with | some v => Except.ok v | none => Except.error (Lean2Js.Err.unknownVar name)
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.fnRef name) = if (p.find? name).isSome = true then Except.ok (Lean2Js.Value.fn name) else Except.error (Lean2Js.Err.unknownFn name)
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.un op x_1) = do let __do_lift ← Lean2Js.evalExpr p n env x_1 Lean2Js.applyUn op __do_lift
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.bin op lhs rhs) = do let a ← Lean2Js.evalExpr p n env lhs let b ← Lean2Js.evalExpr p n env rhs Lean2Js.applyBin op a b
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.letE name ty val body) = do let v ← Lean2Js.evalExpr p n env val Lean2Js.evalExpr p n ((name, v) :: env) body
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.noneE elem) = Except.ok (Lean2Js.Value.obj "none" [])
- Lean2Js.evalExpr p n.succ env e_2.someE = do let __do_lift ← Lean2Js.evalExpr p n env e_2 Except.ok (Lean2Js.Value.obj "some" [("value", __do_lift)])
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.okE err e_2) = do let __do_lift ← Lean2Js.evalExpr p n env e_2 Except.ok (Lean2Js.Value.obj "ok" [("value", __do_lift)])
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.errorE ok e_2) = do let __do_lift ← Lean2Js.evalExpr p n env e_2 Except.ok (Lean2Js.Value.obj "error" [("error", __do_lift)])
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.arrayLit elem items) = do let __do_lift ← Lean2Js.evalArgs p n env items Except.ok (Lean2Js.Value.arr __do_lift)
- Lean2Js.evalExpr p n.succ env (arr.arraySlice lo hi) = do let a ← Lean2Js.evalExpr p n env arr let i ← Lean2Js.evalExpr p n env lo let j ← Lean2Js.evalExpr p n env hi Lean2Js.sliceArr a i j
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.strUn op e_2) = do let __do_lift ← Lean2Js.evalExpr p n env e_2 Lean2Js.applyStrUn op __do_lift
- Lean2Js.evalExpr p n.succ env (Lean2Js.Core.Expr.strBin op lhs rhs) = do let a ← Lean2Js.evalExpr p n env lhs let b ← Lean2Js.evalExpr p n env rhs Lean2Js.applyStrBin op a b
- Lean2Js.evalExpr p n.succ env (str.substring lo hi) = do let s ← Lean2Js.evalExpr p n env str let a ← Lean2Js.evalExpr p n env lo let b ← Lean2Js.evalExpr p n env hi Lean2Js.sliceStr s a b
- Lean2Js.evalExpr p n.succ env (scrut.foldE typeName tyArgs result alts) = do let __do_lift ← Lean2Js.evalExpr p n env scrut Lean2Js.evalFold p n env typeName tyArgs alts __do_lift
Instances For
Used by
Lean2Js.evalArgs
sourceEquations
- Lean2Js.evalArgs p fuel env [] = Except.ok []
- Lean2Js.evalArgs p fuel env (e :: rest) = do let v ← Lean2Js.evalExpr p fuel env e let vs ← Lean2Js.evalArgs p fuel env rest Except.ok (v :: vs)
Instances For
Used by
Lean2Js.evalMapItems
sourceEquations
Instances For
Used by
Lean2Js.evalFilterItems
sourceEquations
Instances For
Used by
Lean2Js.evalFindItems
sourceStops at the first element the predicate accepts, so a predicate that would trap on a later element never sees it.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.evalFindItems p fuel env binder body [] = Except.ok (Lean2Js.Value.obj "none" [])
Instances For
Used by
Lean2Js.evalQuantItems
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.evalQuantItems p fuel env op binder body [] = Except.ok (Lean2Js.Value.bool (op == Lean2Js.Core.QuantOp.all))
Instances For
Used by
Lean2Js.evalFold
sourceA fold over a value of a declared type, from the leaves up. Each node is rebuilt with every field
that came round replaced by the fold's answer for it, and the alternatives then read the rebuilt node
exactly as a match's do — so the walk is here and not in the subset.
The recursion is on the value and not on the fuel, the way evalMapItems walks its list at the fuel it
was handed. That is what keeps a fold one expression node however deep the value is, and so what keeps
Cost.cost readable off the syntax.
A value whose constructor the declared type does not name, and a field the declaration names that the value does not carry, are both refused rather than guessed at: a well-typed program reaches neither.
Equations
- One or more equations did not get rendered due to their size.
- Lean2Js.evalFold p fuel env typeName tyArgs alts v = Except.error (Lean2Js.Err.typeError (toString "fold expects a value of " ++ toString typeName))
Instances For
Used by
Lean2Js.evalFoldList
sourceEquations
Instances For
Used by
Lean2Js.evalFoldListAt
sourceA field the declaration gives a list of the type coming round. Anything but an array is a value no well-typed program builds, so the walk refuses it rather than folding something else.
Equations
- Lean2Js.evalFoldListAt p fuel env typeName tyArgs alts (Lean2Js.Value.arr xs) = Lean2Js.evalFoldList p fuel env typeName tyArgs alts xs
- Lean2Js.evalFoldListAt p fuel env typeName tyArgs alts v = Except.error (Lean2Js.Err.typeError (toString "fold expects an Array of " ++ toString typeName))
Instances For
Used by
Lean2Js.evalFoldFields
sourceEquations
Instances For
Used by
Lean2Js.evalReduceItems
sourceEquations
- One or more equations did not get rendered due to their size.
- Lean2Js.evalReduceItems p fuel env accName elemName body acc [] = Except.ok acc
Instances For
Used by
Lean2Js.defaultFuel
sourceThe upper bound on call depth. Differential test calls are built so as not to exceed it.
Equations
- Lean2Js.defaultFuel = 10000
Instances For
Used by
Lean2Js.evalCall
sourceCalls one exported function. The argument types are checked against the declaration at the entry.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Used by
Lean2Js.defaultFuel_succ
sourceUsed by
Unfolding one step at a time #
evalExpr.eq_def cannot be handed to simp on its own: its right-hand side calls evalExpr again, so
rewriting with it does not stop. One lemma per syntactic form fires only where that form actually is,
which is what lets a proof about a declaration walk its body.
Lean2Js.evalExpr_zero
sourceUsed by
Lean2Js.evalExpr_lit
sourceUsed by
Lean2Js.evalExpr_var
sourceUsed by
Lean2Js.evalExpr_cond
sourceUsed by
Lean2Js.evalExpr_bin
sourceUsed by
Lean2Js.evalExpr_matchE
sourceUsed by
Lean2Js.evalExpr_foldE
sourceUsed by
Lean2Js.evalExpr_okE
sourceUsed by
Lean2Js.evalExpr_errorE
sourceUsed by
Lean2Js.evalExpr_ctor
sourceUsed by
Lean2Js.evalExpr_proj
sourceUsed by
Lean2Js.evalExpr_fnRef
sourceUsed by
Lean2Js.evalExpr_un
sourceUsed by
Lean2Js.evalExpr_and
sourceUsed by
Lean2Js.evalExpr_or
sourceUsed by
Lean2Js.evalExpr_letE
sourceUsed by
Lean2Js.evalExpr_call
sourceUsed by
Lean2Js.evalExpr_noneE
sourceUsed by
Lean2Js.evalExpr_someE
sourceUsed by
Lean2Js.evalExpr_arrayLit
sourceUsed by
Lean2Js.evalExpr_index
sourceUsed by
Lean2Js.evalExpr_length
sourceUsed by
Lean2Js.evalExpr_mapE
sourceUsed by
Lean2Js.evalExpr_filterE
sourceUsed by
Lean2Js.evalExpr_findE
sourceUsed by
Lean2Js.evalExpr_quantE
sourceUsed by
Lean2Js.evalExpr_reduceE
sourceUsed by
Lean2Js.evalExpr_sortByKeyE
sourceUsed by
Lean2Js.evalExpr_dictLit
sourceUsed by
Lean2Js.evalExpr_dictGet
sourceUsed by
Lean2Js.evalExpr_dictHas
sourceUsed by
Lean2Js.evalExpr_dictSet
sourceUsed by
Lean2Js.evalExpr_dictKeys
sourceUsed by
Lean2Js.evalExpr_dictValues
sourceUsed by
Lean2Js.evalExpr_dictDelete
sourceUsed by
Lean2Js.evalExpr_strUn
sourceUsed by
Lean2Js.evalExpr_strBin
sourceUsed by
Lean2Js.evalExpr_arraySlice
sourceUsed by
Lean2Js.evalExpr_arrayReverse
sourceUsed by
Lean2Js.evalExpr_substring
sourceUsed by
The four traversals evalExpr delegates to. A proof about a declaration that uses a combinator
walks the list here rather than through evalExpr.
Lean2Js.evalArgs_nil
sourceUsed by
Lean2Js.evalArgs_cons
sourceUsed by
Lean2Js.evalMapItems_nil
sourceUsed by
Lean2Js.evalMapItems_cons
sourceUsed by
Lean2Js.evalFold_obj
sourceUsed by
Lean2Js.evalFoldList_nil
sourceUsed by
Lean2Js.evalFoldList_cons
sourceUsed by
Lean2Js.evalFoldListAt_arr
sourceUsed by
Lean2Js.evalFoldFields_nil
sourceUsed by
Lean2Js.evalFoldFields_cons_none
sourceUsed by
Lean2Js.evalFoldFields_cons_some
sourceUsed by
Lean2Js.evalFilterItems_nil
sourceUsed by
Lean2Js.evalFilterItems_cons
sourceUsed by
Lean2Js.evalFindItems_nil
sourceUsed by
Lean2Js.evalFindItems_cons
sourceUsed by
Lean2Js.evalQuantItems_nil
sourceUsed by
Lean2Js.evalQuantItems_cons
sourceUsed by
Lean2Js.evalReduceItems_nil
sourceUsed by
Lean2Js.evalReduceItems_cons
sourceUsed by
Lean2Js.evalCall_eq
sourceEnters the body of an exported function once the entry checks are known to pass. Stating a theorem about a declaration otherwise means unfolding the whole program at the call, which puts every other declaration in front of the tactic.