Invertibility as a type system #
Prog.Invertible is a closure condition, decided by the schedule. Here it gets a syntax-directed
judgment InvTyped, one rule per line, that is sound and complete for it
(Prog.invTyped_iff). It annotates each variable v with a monotone Boolean formula Φ v over
variables, read as "v is recoverable from any set of variables that satisfies Φ v".
The supports of role typing are the special case where every formula is one conjunction.
- Prog:
Φ v = v. - Cond
ys = o(xs): eachy ∈ ysbecomesy ∨ ⋀ Φ(xs)(condF). - Spine
ys = o(cs, ps)with a partial inverse: every formula substitutesc := c ∨ (⋀ ys ∧ ⋀ Φ(ps))forc ∈ cs(spineF); without one,Φis unchanged. - Ret
ret xs: each input's formula holds when the weights andxsare true.
Both updates are upd Φ tgt args for the line's recipe tgt ← o'(args). The invariant is that
Φ v holds at A iff v is Known from A under the recipes of the lines so far
(known_cons, eval_upd); it needs no linearity, acyclicity or scoping.
Role typing is an instance (Typed.sim, Prog.Typed.invTyped): its invariant Recov says
Θ ∪ D(v) ⊨ Φ(v) (recov_iff_eval), so each support is a conjunction that implies the formula,
and the live set adds what role typing needs beyond invertibility.
Monotone formulas #
φ holds when exactly the variables of A are true.
Equations
- RoleFlow.MF.eval A (RoleFlow.MF.var v) = (v ∈ A)
- RoleFlow.MF.eval A RoleFlow.MF.tt = True
- RoleFlow.MF.eval A (φ.and ψ) = (RoleFlow.MF.eval A φ ∧ RoleFlow.MF.eval A ψ)
- RoleFlow.MF.eval A (φ.or ψ) = (RoleFlow.MF.eval A φ ∨ RoleFlow.MF.eval A ψ)
Instances For
Substitution of formulas for variables.
Equations
- RoleFlow.MF.bind σ (RoleFlow.MF.var v) = σ v
- RoleFlow.MF.bind σ RoleFlow.MF.tt = RoleFlow.MF.tt
- RoleFlow.MF.bind σ (φ.and ψ) = (RoleFlow.MF.bind σ φ).and (RoleFlow.MF.bind σ ψ)
- RoleFlow.MF.bind σ (φ.or ψ) = (RoleFlow.MF.bind σ φ).or (RoleFlow.MF.bind σ ψ)
Instances For
The conjunction of a list.
Equations
- RoleFlow.MF.all [] = RoleFlow.MF.tt
- RoleFlow.MF.all (φ :: φs) = φ.and (RoleFlow.MF.all φs)
Instances For
Firing the recipe tgt ← o'(args): each target t becomes t ∨ ⋀ Φ(args) in every
formula.
Equations
- RoleFlow.upd Φ tgt args v = RoleFlow.MF.bind (fun (t : ℕ) => if t ∈ tgt then (RoleFlow.MF.var t).or (RoleFlow.MF.all (List.map Φ args)) else RoleFlow.MF.var t) (Φ v)
Instances For
Adding a recipe to Known #
The judgment #
Cond: each result y becomes y ∨ ⋀ Φ(xs).
Equations
- RoleFlow.condF Φ l n = RoleFlow.upd Φ (l.ys n) l.args
Instances For
Spine, solving the first k arguments cs from the results ys and the parameters
ps: every formula substitutes c := c ∨ (⋀ ys ∧ ⋀ Φ(ps)).
Equations
- RoleFlow.spineF Φ l k n = RoleFlow.upd Φ (List.take k l.args) (l.ys n ++ List.drop k l.args)
Instances For
Γ; Φ ⊢ e : O with roles ρ, for the lines ls, the returned positions xs, nw
weights and the inputs I: Ret, Cond, Spine (with a partial inverse) and a spine
step without one, by recursion on the lines. Every rule checks the sorts of its line.
Equations
- One or more equations did not get rendered due to their size.
- RoleFlow.InvTyped Sg O nw I x✝² x✝¹ [] x✝ [] = (RoleFlow.Args x✝² x✝ O ∧ ∀ i ∈ I, RoleFlow.MF.eval ({w : ℕ | w < nw} ∪ ↑x✝.toFinset) (x✝¹ i))
- RoleFlow.InvTyped Sg O nw I x✝² x✝¹ (l :: ls) x✝ (RoleFlow.Role.cond :: ρ) = (RoleFlow.Args x✝² l.args l.as ∧ RoleFlow.InvTyped Sg O nw I (x✝² ++ l.bs) (RoleFlow.condF x✝¹ l x✝².length) ls x✝ ρ)
- RoleFlow.InvTyped Sg O nw I x✝⁴ x✝³ x✝² x✝¹ x✝ = False
Instances For
Soundness and completeness of InvTyped, for any context: if Φ tracks Known under
the recipes R₀ of the lines before, then the judgment holds iff the lines and returned
variables are well formed, there is one role per line, and every input is Known from the
weights and the returned variables.
Role typing as an instance #
Role typing's invariant is a conjunction below Φ: when Φ tracks Known, Recov
says that every variable's formula holds at the weights and its support, which is live.
Simulation: a role typing whose annotations satisfy Recov (equivalently
Θ ∪ D(v) ⊨ Φ(v), recov_iff_eval) for the recipes R₀ of the lines before gives an
invertibility typing line by line: Cond and Spine become I-Cond and I-Spine,
Recov is preserved for the recipes so far, and at Ret the support of every input lies in
the live set, the returned variables.
Equations
- P.instDecidableInvTypedOfDecidableEq ρ = decidable_of_iff (P.Invertible ρ ∧ ρ.length = P.lines.length) ⋯