Documentation

RoleFlow.Flow.Basic

The flow instance (docs/roleflow.tex, sec:flow; module Flow) #

A sort is a dimension n with a reference measure on Vec n: Lebesgue (vec n, data), the standard normal (gauss n, randomness) or the standard logistic (unit n, a point of (0, 1)ⁿ in its logit chart). The operations are those of SemiInv2's flow signature, flat: arguments and results are separate variables. Each operation has at most one semi-inverse, which solves its first argument (or, for split/concat, all of them). An inverse pair is one constructor with a flag inv, and the semi-inverse flips it:

operationinv = falseinv = truelog-weight
addx + qx - q (sub)0
scaleexpx ⊙ e^sx ⊙ e^{-s} (scalenexp)±Σ s
triu (Glow's LU factors)M xM⁻¹ x±triuLogdet U
oddpow kx ^ (2k+1)y ^ (1/(2k+1))opowLogdet k x, -opowLogdet k (y ^ (1/(2k+1)))

The other pairs are perm ps/perm ps⁻¹ (a permutation given by its steps, Flow.PermS; its index map is read as an Equiv.Perm by permOf), split/concat (log-weight 0), and rebase r r'/rebase r' r, the identity from the sort (r, n) to (r', n) with log-weight log ρ_{r'} - log ρ_r (score, sample, sigmoid and logit against Lebesgue measure). The conditioners (mvmul, mul, relu, conv3x3, attend, …) have none.

The model flowModel is a ModelInv. Leaves are proved at one flag (by measure preservation, the Jacobian formula or a density) and derived at the other by leaf_dag, whose derived log-weight agrees with the one given here; rebase has one leaf for all pairs of measures. Every declared pair is mutual, so the right law of an operation is the left law of its semi-inverse.

Sorts #

The reference measures: Lebesgue, the standard normal, and the standard logistic.

Instances For
    @[implicit_reducible]
    Equations
    noncomputable def RoleFlow.Flow.Ref.logpdf :
    Ref → (n : ℕ) → Vec n → ℝ

    The log-density of the reference measure against Lebesgue measure.

    Equations
    Instances For

      The sorts: a reference measure and a dimension.

      Instances For
        def RoleFlow.Flow.instDecidableEqFS.decEq (x✝ x✝¹ : FS) :
        Decidable (x✝ = x✝¹)
        Equations
        Instances For
          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[reducible, inline]

            Data.

            Equations
            Instances For
              @[reducible, inline]

              Standard-normal randomness.

              Equations
              Instances For
                @[reducible, inline]

                Points of the unit cube in their logit chart.

                Equations
                Instances For
                  @[implicit_reducible]
                  noncomputable instance RoleFlow.Flow.instSortsFS :
                  Equations
                  • One or more equations did not get rendered due to their size.

                  Operations #

                  inductive RoleFlow.Flow.FOp :
                  List FS → List FS → Type

                  The flow operations, flat. The flag inv selects the second operation of an inverse pair.

                  Instances For

                    Names for the flipped flags and the changes of sort that the models use.

                    @[reducible, inline]
                    Equations
                    Instances For
                      @[reducible, inline]
                      Equations
                      Instances For
                        @[reducible, inline]
                        Equations
                        Instances For
                          @[reducible, inline]
                          abbrev RoleFlow.Flow.si1 {a b c : FS} (o : FOp [c, b] [a]) :

                          A semi-inverse solving the first argument from the result and the second argument.

                          Equations
                          Instances For
                            @[reducible, inline]
                            abbrev RoleFlow.Flow.si0 {a b : FS} (o : FOp [b] [a]) :

                            A semi-inverse of a one-argument operation.

                            Equations
                            Instances For

                              The flow signature.

                              Equations
                              Instances For

                                Tuples #

                                @[reducible, inline]
                                noncomputable abbrev RoleFlow.Flow.one {a : FS} (x : X a) :

                                A one-element tuple.

                                Equations
                                Instances For
                                  @[reducible, inline]
                                  noncomputable abbrev RoleFlow.Flow.two {a b : FS} (x : X a) (y : X b) :
                                  Val [a, b]

                                  A two-element tuple.

                                  Equations
                                  Instances For
                                    @[reducible, inline]
                                    noncomputable abbrev RoleFlow.Flow.a₀ {a : FS} {Γ : List FS} (v : Val (a :: Γ)) :
                                    X a

                                    The arguments of a tuple.

                                    Equations
                                    Instances For
                                      @[reducible, inline]
                                      noncomputable abbrev RoleFlow.Flow.a₁ {a b : FS} {Γ : List FS} (v : Val (a :: b :: Γ)) :
                                      X b
                                      Equations
                                      Instances For
                                        @[reducible, inline]
                                        noncomputable abbrev RoleFlow.Flow.a₂ {a b c : FS} {Γ : List FS} (v : Val (a :: b :: c :: Γ)) :
                                        X c
                                        Equations
                                        Instances For

                                          The model #

                                          t, or -t if inv.

                                          Equations
                                          Instances For
                                            theorem RoleFlow.Flow.negIf_not (inv : Bool) (t : ℝ) :
                                            negIf (!inv) t = -negIf inv t
                                            noncomputable def RoleFlow.Flow.permS (n : ℕ) (ps : PermS) :

                                            The permutation of Fin n whose index map is ps.idx (taken mod n), if that map is injective; otherwise the identity. A PermS.valid permutation is one, but nothing here needs it: every operation is interpreted, and Print.certify refuses invalid ones.

                                            Equations
                                            Instances For
                                              noncomputable def RoleFlow.Flow.permOf (n : ℕ) (ps : PermS) (inv : Bool) :

                                              perm n ps inv as a permutation of the entries.

                                              Equations
                                              Instances For
                                                theorem RoleFlow.Flow.permOf_not (n : ℕ) (ps : PermS) (inv : Bool) :
                                                (permOf n ps !inv) = Equiv.symm (permOf n ps inv)
                                                noncomputable def RoleFlow.Flow.ℓOp {as bs : List FS} :
                                                FOp as bs → Val as → ℝ

                                                The log-weights, on the whole argument tuple; 0 for the structural bijections and for the conditioners.

                                                Equations
                                                Instances For

                                                  Measurability #

                                                  theorem RoleFlow.Flow.measurable_a₀ {a : FS} {Γ : List FS} :
                                                  Measurable fun (v : Val (a :: Γ)) => a₀ v
                                                  theorem RoleFlow.Flow.measurable_a₁ {a b : FS} {Γ : List FS} :
                                                  Measurable fun (v : Val (a :: b :: Γ)) => a₁ v
                                                  theorem RoleFlow.Flow.measurable_a₂ {a b c : FS} {Γ : List FS} :
                                                  Measurable fun (v : Val (a :: b :: c :: Γ)) => a₂ v
                                                  theorem RoleFlow.Flow.measurable_one {a : FS} :
                                                  Measurable fun (x : X a) => one x
                                                  theorem RoleFlow.Flow.measurable_one' {a b : FS} {Γ : List FS} {f : X a → X b} (hf : Measurable f) :
                                                  Measurable fun (v : Val (a :: Γ)) => one (f (a₀ v))
                                                  theorem RoleFlow.Flow.measurable_two' {a b c : FS} {Γ : List FS} {f : X a → X b × X c} (hf : Measurable f) :
                                                  Measurable fun (v : Val (a :: Γ)) => two (f (a₀ v)).1 (f (a₀ v)).2
                                                  theorem RoleFlow.Flow.measurable_one₂ {a b c : FS} {Γ : List FS} {f : X a → X b → X c} (hf : Measurable fun (p : X a × X b) => f p.1 p.2) :
                                                  Measurable fun (v : Val (a :: b :: Γ)) => one (f (a₀ v) (a₁ v))
                                                  theorem RoleFlow.Flow.measurable_one₃ {a b c d : FS} {Γ : List FS} {f : X a → X b → X c → X d} (hf : Measurable fun (p : X a × X b × X c) => f p.1 p.2.1 p.2.2) :
                                                  Measurable fun (v : Val (a :: b :: c :: Γ)) => one (f (a₀ v) (a₁ v) (a₂ v))
                                                  theorem RoleFlow.Flow.measurable_semOp {as bs : List FS} (o : FOp as bs) :
                                                  theorem RoleFlow.Flow.measurable_ℓOp {as bs : List FS} (o : FOp as bs) :

                                                  Laws #

                                                  theorem RoleFlow.Flow.eq_one {a : FS} (v : Val [a]) :
                                                  one v.head = v
                                                  @[reducible, inline]
                                                  abbrev RoleFlow.Flow.LeftLaw {as bs : List FS} (o : FOp as bs) (si : SemiInv FOp as bs) :

                                                  The left law of o with the semi-inverse si.

                                                  Equations
                                                  Instances For
                                                    theorem RoleFlow.Flow.left0 {a b : FS} {o : FOp [a] [b]} {o' : FOp [b] [a]} (F : X a → X b) (G : X b → X a) (hF : ∀ (v : Val [a]), semOp o v = one (F v.head)) (hG : ∀ (v : Val [b]), semOp o' v = one (G v.head)) (h : ∀ (x : X a), G (F x) = x) :
                                                    LeftLaw o (si0 o')

                                                    The left law of a one-argument operation.

                                                    theorem RoleFlow.Flow.left1 {a b c : FS} {o : FOp [a, b] [c]} {o' : FOp [c, b] [a]} (F : X a → X b → X c) (G : X c → X b → X a) (hF : ∀ (v : Val [a, b]), semOp o v = one (F v.head v.tail.head)) (hG : ∀ (v : Val [c, b]), semOp o' v = one (G v.head v.tail.head)) (h : ∀ (x : X a) (q : X b), G (F x q) q = x) :
                                                    LeftLaw o (si1 o')

                                                    The left law of an operation that consumes its first argument.

                                                    theorem RoleFlow.Flow.left_split (m n : ℕ) (c : Val [FS.vec (m + n)]) (p : Val []) :
                                                    semOp (FOp.concat m n) ((semOp (FOp.split m n) (Val.cast ⋯ (c.append p))).append p) = c
                                                    theorem RoleFlow.Flow.left_concat (m n : ℕ) (c : Val [FS.vec m, FS.vec n]) (p : Val []) :
                                                    semOp (FOp.split m n) ((semOp (FOp.concat m n) (Val.cast ⋯ (c.append p))).append p) = c
                                                    theorem RoleFlow.Flow.left_perm (n : ℕ) (ps : PermS) (inv : Bool) :
                                                    LeftLaw (FOp.perm n ps inv) (si0 (FOp.perm n ps !inv))
                                                    theorem RoleFlow.Flow.left_rebase (r r' : Ref) (n : ℕ) :
                                                    LeftLaw (FOp.rebase r r' n) (si0 (FOp.rebase r' r n))
                                                    theorem RoleFlow.Flow.left_oddpow (n k : ℕ) (inv : Bool) :
                                                    LeftLaw (FOp.oddpow n k inv) (si0 (FOp.oddpow n k !inv))
                                                    theorem RoleFlow.Flow.left_add (n : ℕ) (inv : Bool) :
                                                    LeftLaw (FOp.add n inv) (si1 (FOp.add n !inv))
                                                    theorem RoleFlow.Flow.left_triu (c n : ℕ) (inv : Bool) :
                                                    LeftLaw (FOp.triu c n inv) (si1 (FOp.triu c n !inv))

                                                    Leaves #

                                                    theorem RoleFlow.Flow.cov_one {a b : FS} {f : X a → X b} {J : X a → ENNReal} (hf : Measurable f) (hJ : Measurable J) (h : Cov (μ a) (μ b) f J) :
                                                    Cov (vol [a]) (vol [b]) (fun (x : Val [a]) => one (f x.head)) fun (x : Val [a]) => J x.head

                                                    Change of variables on one value, carried to one-element contexts.

                                                    theorem RoleFlow.Flow.cov_toRef (r : Ref) (n : ℕ) :
                                                    Cov MeasureTheory.volume (r.μ n) (fun (x : Vec n) => x) fun (x : Vec n) => expw (r.logpdf n x)

                                                    From Lebesgue measure to a reference measure by the identity.

                                                    theorem RoleFlow.Flow.leaf_rebase (r r' : Ref) (n : ℕ) (p : Val []) :
                                                    Cov (vol [{ ref := r, dim := n }]) (vol [{ ref := r', dim := n }]) (fun (c : Val [{ ref := r, dim := n }]) => semOp (FOp.rebase r r' n) (Val.cast ⋯ (c.append p))) fun (c : Val [{ ref := r, dim := n }]) => expw (ℓOp (FOp.rebase r r' n) (Val.cast ⋯ (c.append p)))

                                                    rebase: from r to Lebesgue measure by Cov.inv, then to r'.

                                                    theorem RoleFlow.Flow.leaf_add (n : ℕ) (p : Val [FS.vec n]) :
                                                    Cov (vol [FS.vec n]) (vol [FS.vec n]) (fun (c : Val [FS.vec n]) => semOp (FOp.add n) (Val.cast ⋯ (c.append p))) fun (c : Val [FS.vec n]) => expw (ℓOp (FOp.add n) (Val.cast ⋯ (c.append p)))
                                                    theorem RoleFlow.Flow.leaf_scaleexp (n : ℕ) (p : Val [FS.vec n]) :
                                                    Cov (vol [FS.vec n]) (vol [FS.vec n]) (fun (c : Val [FS.vec n]) => semOp (FOp.scaleexp n) (Val.cast ⋯ (c.append p))) fun (c : Val [FS.vec n]) => expw (ℓOp (FOp.scaleexp n) (Val.cast ⋯ (c.append p)))
                                                    theorem RoleFlow.Flow.leaf_triu (c n : ℕ) (p : Val [FS.vec (c * c)]) :
                                                    Cov (vol [FS.vec (c * n)]) (vol [FS.vec (c * n)]) (fun (x : Val [FS.vec (c * n)]) => semOp (FOp.triu c n) (Val.cast ⋯ (x.append p))) fun (x : Val [FS.vec (c * n)]) => expw (ℓOp (FOp.triu c n) (Val.cast ⋯ (x.append p)))
                                                    theorem RoleFlow.Flow.leaf_perm (n : ℕ) (ps : PermS) (inv : Bool) (p : Val []) :
                                                    Cov (vol [FS.vec n]) (vol [FS.vec n]) (fun (c : Val [FS.vec n]) => semOp (FOp.perm n ps inv) (Val.cast ⋯ (c.append p))) fun (c : Val [FS.vec n]) => expw (ℓOp (FOp.perm n ps inv) (Val.cast ⋯ (c.append p)))
                                                    theorem RoleFlow.Flow.leaf_oddpow (n k : ℕ) (p : Val []) :
                                                    Cov (vol [FS.vec n]) (vol [FS.vec n]) (fun (c : Val [FS.vec n]) => semOp (FOp.oddpow n k) (Val.cast ⋯ (c.append p))) fun (c : Val [FS.vec n]) => expw (ℓOp (FOp.oddpow n k) (Val.cast ⋯ (c.append p)))
                                                    theorem RoleFlow.Flow.leaf_split (m n : ℕ) (p : Val []) :
                                                    Cov (vol [FS.vec (m + n)]) (vol [FS.vec m, FS.vec n]) (fun (c : Val [FS.vec (m + n)]) => semOp (FOp.split m n) (Val.cast ⋯ (c.append p))) fun (c : Val [FS.vec (m + n)]) => expw (ℓOp (FOp.split m n) (Val.cast ⋯ (c.append p)))

                                                    Derived leaves #

                                                    theorem RoleFlow.Flow.leaf_of_dag {as bs : List FS} {o : FOp as bs} {si : SemiInv FOp as bs} (left : LeftLaw o si) (leaf : ∀ (p : Val si.ps), Cov (vol si.cs) (vol bs) (fun (c : Val si.cs) => semOp o (Val.cast ⋯ (c.append p))) fun (c : Val si.cs) => expw (ℓOp o (Val.cast ⋯ (c.append p)))) {L : Val (bs ++ si.ps) → ℝ} (hL : ∀ (w : Val (bs ++ si.ps)), dagWeight (semOp si.op) (ℓOp o) ⋯ w = L w) (p : Val si.ps) :
                                                    Cov (vol bs) (vol si.cs) (fun (b : Val bs) => semOp si.op (b.append p)) fun (b : Val bs) => expw (L (b.append p))

                                                    The leaf of a semi-inverse, derived by leaf_dag from the leaf and the left law of the operation it inverts; the derived log-weight is checked against ℓOp.

                                                    Right laws #

                                                    theorem RoleFlow.Flow.flow_right {as bs : List FS} (o : FOp as bs) (si : SemiInv FOp as bs) (h : o.inv = some si) (b : Val bs) (p : Val si.ps) :
                                                    semOp o (si.glue (semOp si.op (b.append p)) p) = b

                                                    The right law: every declared pair is mutual, so the right law of an operation is the left law of its semi-inverse, at the flipped flag.

                                                    The model of the flow signature.

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