Documentation

LambdaS.Algorithms

Numeric algorithms, as a sanity check on the calculus #

Λs is pure and total: no recursion and no mutable state. It has a compare-and-branch form, ifle, but no general boolean type, and the methods in this file are straight-line terms that use neither. The question this file answers is whether that leaves enough to write recognizable numerical methods, or only formulas.

The answer is that straight-line numerical methods transcribe directly, and their types are their specifications. A central difference has type (Q v → Q u) → Q v → Q v → Q (u/v): differentiate a position with respect to a time and you get a velocity, by derivation rather than by comment. What is missing is iteration: one Runge–Kutta step is expressible, a solver loop is not. The file ends by running declared conversions (yards, feet, meters) at Float.

Checking unit equality with exponent vectors #

Unit equality here is decided by arithmetic on exponent vectors, not by normalizing syntax. In the Runge–Kutta step below, the intermediate (h/2)·k₁ has unit t · (y/t), and add demands it equal y. As exponent vectors those are t + (y − t) and y, and the checker settles it by adding rationals. There is no normalization pass, so the class of bugs that lives in one, an incomplete or non-confluent rewrite on unit syntax, cannot arise.

Scopes #

Two nested dimension binders and two nested unit binders. Inside the body the innermost unit variable is de Bruijn 0 and the outer one is 1; likewise for dimensions.

@[reducible, inline]

The value's unit, u.

Equations
Instances For
    @[reducible, inline]

    The argument's unit, v.

    Equations
    Instances For
      @[reducible, inline]

      The bound on u, at the scope where its binder sits.

      Equations
      Instances For
        @[reducible, inline]

        The bound on v.

        Equations
        Instances For
          @[reducible, inline]

          Wrap a body in Λδu. Λu:δu. Λδv. Λv:δv.

          Equations
          Instances For
            @[reducible, inline]

            Instantiate both quantifiers.

            Equations
            Instances For

              Central difference #

              f'(x) ≈ (f(x+h) − f(x−h)) / 2h. Inside the three value binders, %0 is h, %1 is x, %2 is f.

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

                Simpson's rule #

                ∫ₐᵇ f ≈ ((b−a)/6)·(f(a) + 4·f((a+b)/2) + f(b)). %0 is b, %1 is a, %2 is f.

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

                  One Runge–Kutta step #

                  y' = y + (h/6)(k₁ + 2k₂ + 2k₃ + k₄) for dy/dt = f(t,y). Binders, innermost first: %0 is y, %1 is t, %2 is h, %3 is f.

                  This is where unit equality does real work. k₁ : Q (y/t), so (h/2)·k₁ has unit t·(y/t), and adding it to y requires the checker to see those as the same exponent vector.

                  Λδy. Λy:δy. Λδt. Λt:δt.: note the value unit is bound first here, so inside the body uU is the state unit and vU the time unit.

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

                    Tolerances, where dimensioned types catch the common bug #

                    An absolute tolerance has the unit of the quantity; a relative one is dimensionless. Writing |x − y| < 1e-6 with a bare literal is a type error, and the fix the checker forces is the correct one.

                    Running them #

                    Free fall: s(t) = ½·g·t² with g = 9.81 m/s². A central difference is exact on a quadratic and Simpson's rule is exact on a cubic, so both answers are exact and the guards can be tight.

                    λ(t : Q s). ½·g·t²

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

                        Declared conversions, compiled #

                        The conversion oracle below is not fun _ _ => 1.0: it is computed from the declared magnitudes (meter 1, foot 0.3048, yard 0.9144). magB is a transcription by hand, at Float, of the valuation ψyd that LambdaS.Examples proves satisfies the declaration set; nothing derives it from ψyd, and the agreement between the two is checked by the numbers below rather than by a theorem. evalC_convert_declared is the theorem that the instrumented evaluator at carrier ℝ multiplies by exactly the declared factor. The Float runs below are executed checks of a separate example, not a real-to-Float correspondence theorem.

                        Two routes from yards to meters (direct, and through feet) print the same number, which is convChain_eq and yard_forced made observable: the factors are forced by the declarations, so there is no route to get wrong.

                        The magnitude of a compound unit: the product of its bases' declared magnitudes, at their exponents.

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

                          The conversion oracle the declarations determine: a ratio of magnitudes, which is conv at the Float shadow of ψyd.

                          Equations
                          Instances For

                            Run a closed term under the declared-conversion oracle cfDecl, returning its scalar magnitude; the declared-factor counterpart of run.

                            Equations
                            Instances For

                              One yard per foot #

                              1_yd / 1_ft denotes the magnitude 1, at unit yd/ft: unit constants denote the number one, so the quotient is convert-free and, by den_indep, cannot see the declared magnitudes. The number 3 is one conversion away, (1_yd / 1_ft) in 1, and it must be: the 3 is data from the declaration table, and conversion is the only construct that reads it.

                              @[reducible, inline]

                              The unit one: the SI's name for the unit of dimension-one quantities (9th SI Brochure, 5.4.7), which the brochure calls the neutral element of any system of units. Here it is the empty exponent vector. The surface reading of the conversion below is (1 yd / 1 ft) in one.

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

                                  The other route to the same number: convert one operand before dividing, (1_yd in ft) / 1_ft. The quotient is at unit ft/ft = 1 with no conversion of its own, and the 3 again enters through the one conversion in the term.

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