Function calls: a signature extended by a typed program #
A typed program P (roles ρ), whose inverse program P† = P.inverse ρ is typed too (roles
ρi), becomes two operations of a new signature (Sig.declare): fwd, on P's inputs then
its weights, and inv, on its outputs then its weights. Each is the other's semi-inverse, with
the inputs (outputs) consumed and the weights as parameters. Every operation of the old signature
stays, as prim.
The model of the new signature (ModelInv.link) interprets fwd by ⟦P⟧ with log-weight
L_θ of P, and inv by ⟦P†⟧ with the log-weight of P†; its laws are theorems about every
typed program: the left laws are inverse_sem and sem_inverse, the leaves are density for
P and for P†. So a call needs nothing beyond the typings of the callee and its inverse.
Definitions are added one at a time (Linked), each over the signature of the ones before it:
a tower Sg₀, Sg₀.declare P₁, (Sg₀.declare P₁).declare P₂, …, so a body may call any
function defined before it, and none can recurse. A call to a function k definitions back is
its fwd under k prims (Linked.find). Linked.model is the model at the top, and every
theorem about typed programs holds for programs with calls (Linked.density,
Linked.bijective).
The declared operations #
The operations of Sg with P declared: Sg's own, and P's forward and inverse.
- prim {S : Type} {Sg : Sig S} {P : Prog Sg} {as bs : List S} : Sg.Op as bs → DeclOp Sg P as bs
- fwd {S : Type} {Sg : Sig S} {P : Prog Sg} : DeclOp Sg P (P.ins ++ P.wts) P.outs
- inv {S : Type} {Sg : Sig S} {P : Prog Sg} : DeclOp Sg P (P.outs ++ P.wts) P.ins
Instances For
Values of concatenated contexts #
The model #
The interpretation: fwd is ⟦P⟧, inv is ⟦P†⟧, on the inputs (outputs), then the
weights.
Equations
- RoleFlow.linkSem M P hT hTi (RoleFlow.DeclOp.prim o) = M.sem o
- RoleFlow.linkSem M P hT hTi RoleFlow.DeclOp.fwd = fun (v : RoleFlow.Val (P.ins ++ P.wts)) => RoleFlow.Prog.sem M.toModel P ⋯ v.right v.left
- RoleFlow.linkSem M P hT hTi RoleFlow.DeclOp.inv = fun (v : RoleFlow.Val (P.outs ++ P.wts)) => RoleFlow.Prog.sem M.toModel (P.inverse ρ) ⋯ v.right v.left
Instances For
The log-weights: L_θ of P for fwd, of P† for inv.
Equations
- RoleFlow.linkℓ M P hT hTi (RoleFlow.DeclOp.prim o) = M.ℓ o
- RoleFlow.linkℓ M P hT hTi RoleFlow.DeclOp.fwd = fun (v : RoleFlow.Val (P.ins ++ P.wts)) => RoleFlow.Prog.logw M.toModel P ⋯ ρ v.right v.left
- RoleFlow.linkℓ M P hT hTi RoleFlow.DeclOp.inv = fun (v : RoleFlow.Val (P.outs ++ P.wts)) => RoleFlow.Prog.logw M.toModel (P.inverse ρ) ⋯ ρi v.right v.left
Instances For
The model of Sg with P declared: the laws of fwd and inv are concordance
(inverse_sem, sem_inverse) and density, for P and for P†.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The tower of definitions #
Definitions added one at a time over the base signature Sg₀, each a typed program (with a
typed inverse program) over the signature of the ones before it; Sg is the signature with all
of them declared.
- base {S : Type} {Sg₀ : Sig S} : Linked Sg₀ Sg₀
- add {S : Type} {Sg₀ Sg : Sig S} (L : Linked Sg₀ Sg) (name : String) (P : Prog Sg) (ρ ρi : List Role) (hT : P.Typed ρ) (hTi : (P.inverse ρ).Typed ρi) (hi : P.ins ≠ []) (ho : P.outs ≠ []) : Linked Sg₀ (Sg.declare P hi ho)
Instances For
What an operation of the tower is: an operation of the base, or a call of a definition by
name, forward or inverse, with the number k of its leading arguments that are values (the rest
are its weights).
- base {S : Type} {Op : List S → List S → Type} {as bs : List S} : Op as bs → Callee Op as bs
- call {S : Type} {Op : List S → List S → Type} {as bs : List S} (name : String) (inv : Bool) (k : ℕ) : Callee Op as bs
Instances For
An operation of the base as one of the tower (under prims).
Equations
- RoleFlow.Linked.base.lift x✝ = x✝
- (L.add name P ρ ρi hT hTi hi ho).lift x✝ = RoleFlow.DeclOp.prim (L.lift x✝)
Instances For
The forward operation of the definition name (the latest of that name).
Equations
- One or more equations did not get rendered due to their size.
- RoleFlow.Linked.base.find x✝ = none
Instances For
What an operation of the tower is (Callee).
Equations
- RoleFlow.Linked.base.view x✝ = RoleFlow.Callee.base x✝
- (L.add name P ρ ρi hT hTi hi ho).view (RoleFlow.DeclOp.prim o) = L.view o
- (L.add name P ρ ρi hT hTi hi ho).view RoleFlow.DeclOp.fwd = RoleFlow.Callee.call name false P.ins.length
- (L.add name P ρ ρi hT hTi hi ho).view RoleFlow.DeclOp.inv = RoleFlow.Callee.call name true P.outs.length
Instances For
The model of the tower over a model of the base (ModelInv.link at each definition).
Equations
- RoleFlow.Linked.model M RoleFlow.Linked.base = M
- RoleFlow.Linked.model M (L.add name P ρ ρi hT hTi hi ho) = (RoleFlow.Linked.model M L).link P hT hTi hi ho
Instances For
Bijectivity of a typed program with calls, with its inverse program as the inverse.