lean2js

Lean2Js.Agree

source

Runtime agreement between the reference semantics and the model of the generated JS #

Checks, on the shipped artifact itself, that the reference semantics and the model of the generated JS agree.

The guarantee comes in two layers. Here we check that eval and JsSem agree; the differential test on Node checks that the behaviour JsSem assumes and the real JS agree. The former lives on the model, so the gap that compiler correctness has to close as a proof is exactly here.

def

Lean2Js.encodeValue

source
@[irreducible]

A constructor value is written under the key its name is carried under. The key follows the name rather than the type, because that is all a Value carries: Compile.objOf reads it the same way, so the compiler and this write the same object.

Equations
Instances For
    Used by
      def

      Lean2Js.encodeFields

      source
      @[irreducible]
      Equations
      Instances For
        Used by
          def

          Lean2Js.encodeList

          source
          @[irreducible]
          Equations
          Instances For
            Used by
              def

              Lean2Js.encodeAt

              source
              @[irreducible]

              encodeValue composed with the crossing at each dictObj position of the declared type.

              The declared type is what says how a value leaves the module, and it is the only thing that says it: encodeValue takes no type, so a dictionary encodes to a Map whether or not the author declared it to cross as a plain object. This is what a public declaration's result is read through instead.

              The recursion is on sizeOf v rather than on the type, the way Value.hasTy's is: a named type's field types come out of the program, so the Ty need not shrink. Where the value and the type do not line up — which the entry check is what rules out — the value is encoded as it stands.

              Equations
              Instances For
                Used by
                  def

                  Lean2Js.encodeFieldsAt

                  source
                  @[irreducible]
                  Equations
                  Instances For
                    Used by
                      def

                      Lean2Js.encodeListAt

                      source
                      @[irreducible]
                      Equations
                      Instances For
                        Used by
                          def

                          Lean2Js.encodeEntriesAt

                          source
                          @[irreducible]
                          Equations
                          Instances For
                            Used by

                              Reading a result through its declared type #

                              encodeAt is a well-founded recursion for the reason Value.hasTy is, so each shape is unfolded once here rather than by simp at every use.

                              theorem

                              Lean2Js.encodeAt_bool

                              source
                              Used by
                                theorem

                                Lean2Js.encodeAt_int53

                                source
                                Used by
                                  theorem

                                  Lean2Js.encodeAt_uint32

                                  source
                                  Used by
                                    theorem

                                    Lean2Js.encodeAt_string

                                    source
                                    Used by
                                      theorem

                                      Lean2Js.encodeAt_bigint

                                      source
                                      Used by
                                        theorem

                                        Lean2Js.encodeAt_fn

                                        source
                                        Used by
                                          theorem

                                          Lean2Js.encodeAt_none

                                          source
                                          Used by
                                            theorem

                                            Lean2Js.encodeAt_some

                                            source
                                            [Core.Discriminators] (p : Core.Program) (fields : List (String × Value)) (elem : Core.Ty) :
                                            encodeAt p elem.option (Value.obj "some" fields) = Js.JsValue.obj (("tag", Js.JsValue.str "some") :: encodeFieldsAt p fields [("value", elem)])
                                            Used by
                                              theorem

                                              Lean2Js.encodeAt_ok

                                              source
                                              [Core.Discriminators] (p : Core.Program) (fields : List (String × Value)) (ok err : Core.Ty) :
                                              encodeAt p (ok.result err) (Value.obj "ok" fields) = Js.JsValue.obj (("tag", Js.JsValue.str "ok") :: encodeFieldsAt p fields [("value", ok)])
                                              Used by
                                                theorem

                                                Lean2Js.encodeAt_error

                                                source
                                                [Core.Discriminators] (p : Core.Program) (fields : List (String × Value)) (ok err : Core.Ty) :
                                                encodeAt p (ok.result err) (Value.obj "error" fields) = Js.JsValue.obj (("tag", Js.JsValue.str "error") :: encodeFieldsAt p fields [("error", err)])
                                                Used by
                                                  theorem

                                                  Lean2Js.encodeAt_array

                                                  source
                                                  Used by
                                                    theorem

                                                    Lean2Js.encodeAt_dict

                                                    source
                                                    Used by
                                                      theorem

                                                      Lean2Js.encodeAt_dictObj

                                                      source
                                                      Used by
                                                        theorem

                                                        Lean2Js.encodeAt_named

                                                        source
                                                        [Core.Discriminators] (p : Core.Program) (n : String) (args : List Core.Ty) (ctor : String) (fields : List (String × Value)) (t : Core.TypeDef) (c : Core.CtorDef) (ht : p.findType? n = some t) (hc : t.findAt? args ctor = some c) :
                                                        encodeAt p (Core.Ty.named n args) (Value.obj ctor fields) = Js.JsValue.obj ((Core.keyFor ctor, Js.JsValue.str ctor) :: encodeFieldsAt p fields (List.map (fun (f : Core.Field) => (f.name, f.ty)) c.fields))
                                                        Used by
                                                          theorem

                                                          Lean2Js.encodeFieldsAt_nil

                                                          source
                                                          Used by
                                                            theorem

                                                            Lean2Js.encodeFieldsAt_cons

                                                            source
                                                            [Core.Discriminators] (p : Core.Program) (k : String) (v : Value) (rest : List (String × Value)) (n : String) (ty : Core.Ty) (tys : List (String × Core.Ty)) :
                                                            encodeFieldsAt p ((k, v) :: rest) ((n, ty) :: tys) = (k, encodeAt p ty v) :: encodeFieldsAt p rest tys
                                                            Used by
                                                              theorem

                                                              Lean2Js.encodeListAt_nil

                                                              source
                                                              Used by
                                                                theorem

                                                                Lean2Js.encodeListAt_cons

                                                                source
                                                                [Core.Discriminators] (p : Core.Program) (x : Value) (rest : List Value) (elem : Core.Ty) :
                                                                encodeListAt p (x :: rest) elem = encodeAt p elem x :: encodeListAt p rest elem
                                                                Used by
                                                                  theorem

                                                                  Lean2Js.encodeEntriesAt_nil

                                                                  source
                                                                  Used by
                                                                    theorem

                                                                    Lean2Js.encodeEntriesAt_cons

                                                                    source
                                                                    [Core.Discriminators] (p : Core.Program) (k : String) (v : Value) (rest : List (String × Value)) (elem : Core.Ty) :
                                                                    encodeEntriesAt p ((k, v) :: rest) elem = (k, encodeAt p elem v) :: encodeEntriesAt p rest elem
                                                                    Used by

                                                                      Reading a value through the type it was declared at #

                                                                      encodeAt is encodeValue wherever no dictObj is reachable, which is every package built before one could be declared. The lemma below is what carries those claims across unchanged: each is rewritten through it and keeps the exact text it has, rather than gaining a hypothesis it did not have.

                                                                      theorem

                                                                      Lean2Js.encodeAt_eq_encodeValue

                                                                      source

                                                                      Where no type the program declares reaches a dictObj and the type reaches none, reading a value through its declared type is reading it without one.

                                                                      Used by
                                                                        partial def

                                                                        Lean2Js.reshapeJs

                                                                        source

                                                                        What the three perturbing shapes name, applied to an encoded argument. Reversing an object's keys and giving it a key no type declares are both things the .d.ts admits and encodeValue never writes. A dictionary's keys are left where they are: they are a Map's, and no order is declared for them.

                                                                        asObject leaves an encoded value alone, because it is not a perturbation of one: encodeArg reads the argument through its declared type instead, and never routes that shape here.

                                                                        Used by
                                                                          def

                                                                          Lean2Js.encodeArg

                                                                          source

                                                                          The JavaScript value a vector offers as one argument. Three of the four shapes perturb the canonical encoding and are applied to it; asObject is a second encoding — the argument read through the type it was declared at, which is what writes a Dict.Obj argument as the plain object a consumer would write.

                                                                          Reshaping an encoded value could not do it. Whether a dictionary crosses as an object is the declared type's to say and an encoded value no longer carries the type, so turning every Map into an object would be refused at a Dict parameter — and the vector says the call returns.

                                                                          Equations
                                                                          Instances For
                                                                            Used by
                                                                              def

                                                                              Lean2Js.TestVector.jsArgs

                                                                              source

                                                                              The arguments the generated code is called with: each Value written the way the vector says a caller may write it.

                                                                              Equations
                                                                              • One or more equations did not get rendered due to their size.
                                                                              Instances For
                                                                                Used by
                                                                                  def

                                                                                  Lean2Js.agrees

                                                                                  source

                                                                                  Whether the result of eval and the result of the model are the same. The expected value is read out through the declaration's return type, because that is what the entry hands back — decl_correct says so — and at a dictionary the declared type says crosses as a plain object the two readings differ. Two failures are compared by the thrown code.

                                                                                  Equations
                                                                                  Instances For
                                                                                    Used by
                                                                                      structure

                                                                                      Lean2Js.Disagreement

                                                                                      source
                                                                                      Instances For
                                                                                        Used by
                                                                                          def

                                                                                          Lean2Js.Disagreement.render

                                                                                          source
                                                                                          Equations
                                                                                          • One or more equations did not get rendered due to their size.
                                                                                          Instances For
                                                                                            Used by
                                                                                              def

                                                                                              Lean2Js.disagreementsIn

                                                                                              source
                                                                                              Equations
                                                                                              • One or more equations did not get rendered due to their size.
                                                                                              Instances For
                                                                                                Used by
                                                                                                  def

                                                                                                  Lean2Js.checkAgreement

                                                                                                  source
                                                                                                  (p : Core.Program) (edgeLimit randomCount : Nat) :

                                                                                                  Checks that the artifact does not disagree with the reference semantics, before writing it out.

                                                                                                  The keys the program declares are installed here, so the compiler and the encoding read one reading — Compile.validateType is what checks that reading against every type the program declares.

                                                                                                  Equations
                                                                                                  • One or more equations did not get rendered due to their size.
                                                                                                  Instances For
                                                                                                    Used by

                                                                                                      The file both checkers read #

                                                                                                      The vector's expected value is written as the JavaScript value the entry must hand back, which is encodeAt of what eval returned: a dictionary the declared type says crosses as a plain object is written as one. Writing the Value on its own instead was right only for as long as no declaration returned such a dictionary, and it was what left the walk on the way out unmeasured.

                                                                                                      An asObject argument is written the same way and for the same reason: the check on Node reads no types, so which dictionaries in an argument cross as plain objects has to be decided here. Every other argument is written as the Value and encoded there, which is what keeps the two sides' readings of a canonical argument independent enough to disagree.

                                                                                                      partial def

                                                                                                      Lean2Js.Js.JsValue.toJson

                                                                                                      source
                                                                                                      Used by
                                                                                                        def

                                                                                                        Lean2Js.TestVector.toJson

                                                                                                        source
                                                                                                        Equations
                                                                                                        • One or more equations did not get rendered due to their size.
                                                                                                        Instances For
                                                                                                          Used by
                                                                                                            def

                                                                                                            Lean2Js.renderVectors

                                                                                                            source
                                                                                                            (p : Core.Program) (edgeLimit randomCount : Nat) :
                                                                                                            Equations
                                                                                                            • One or more equations did not get rendered due to their size.
                                                                                                            Instances For
                                                                                                              Used by