The inverse program (docs/roleflow.tex, sec:inverse) #
The schedule is a forward closure (fire) over the recipes of the lines (Prog.xrecs):
starting from the weights and the outputs, it fires a recipe whose sources are all known, until
none is left, and emits each fired recipe as a line of the inverse program. A renaming maps the variables of P to those of the inverse
program. Firing keeps the renaming sort-preserving (Good) and, on a trace of P, the values
of the inverse program equal to those of the trace (Agree), since the recipes hold
(xrecs_holds). At the end the known set is
closed under the recipes (fire_closed), so by Recov at Ret it contains every input
(Typed.known_xrecs, prop:schedule).
Prog.inverse is the inverse program P†, a program of the same signature
(Prog.inverse_wf). Concordance (Prog.inverse_sem, thm:conc):
⟦P†⟧_θ ∘ ⟦P⟧_θ = id. With the right law, ⟦P⟧_θ is bijective with inverse ⟦P†⟧_θ
(Prog.bijective, Prog.sem_inverse, Prog.equiv), and ⟦P†⟧_θ pushes μ_O back to μ_I
with the negated log-weight (Prog.inverse_density, thm:invdensity), which needs only the left
law.
Concordance needs less than the typing: Prog.Invertible asks only that the schedule reaches
every input, and the recipes hold under any roles. A program that is invertible but not typed
(say ret x + b, x + b) gets a left inverse, without a density.
Existence of the schedule, the recoverability half: under Recov, every variable, in
scope or introduced by the lines, is known from the weights and the returned variables.
The forward closure #
The first element of a list with a property, and the list without it.
Equations
Instances For
The schedule, as a forward closure: fire a recipe of X whose sources are all known,
emit it as a line at the next free position m, and continue; ren renames the variables of
P into the inverse program and K is the hash set of known variables.
Equations
Instances For
Sorts and values along the schedule #
On known variables, the value u of the inverse program agrees with the trace t.
Equations
Instances For
On a trace on which the recipes hold, the inverse program reproduces the trace on every known variable.
The inverse program #
The schedule of P: the forward closure from the weights and the outputs. The outputs
get the positions after the weights, so the renaming starts as renStep P.ret P.nw id.
Equations
- P.schedule ρ = RoleFlow.fire (P.xrecs ρ).length (P.xrecs ρ) (P.nw + P.outs.length) (RoleFlow.renStep P.ret P.nw id) (RoleFlow.insertAll (RoleFlow.insertAll ∅ (List.range P.nw)) P.ret)
Instances For
The inverse program P† = (Θ, O, e†): it fires the schedule and returns the inputs.
Equations
Instances For
P is invertible under the roles ρ: it is well formed and the schedule reaches every
input. Decidable, and implied by the typing (Typed.invertible).
Equations
- P.Invertible ρ = (P.WF ∧ ∀ x ∈ List.range' P.nw P.ins.length, x ∈ (P.schedule ρ).2.2)
Instances For
Invertibility is Known: the schedule reaches exactly the variables that are Known
from the weights and the returned variables (known_fire, fire_known).
The inverse program is well formed (a program over the same signature).
The inverse program is measurable at fixed weights.
Density of the inverse (thm:invdensity): ⟦P†⟧_θ pushes μ_O back to
μ_I with the negated log-weight at the recomputed inputs. Only the left law is used.
Model density (cor:modeldensity): e^{L_θ} is the density of (⟦P†⟧_θ)_* μ_O with
respect to μ_I, by the density theorem and the left inverse. Here and not in Density.lean,
since it mentions P†.