characterize: – How data may change over time • Side effects, type state, protocols, invariants, monotonicity… • Lots of prior work, all working around aliasing – Safe assumptions in the presence of mutation through aliases • Eye towards backwards compatibility: – Subsume standard references, reference immutability
programs • Formal core type system + proofs – Uses dependent types • Implementation as Coq DSL • Characterized proof burden for 4 examples – Roughly on par w/ pure functional equivalents
thread interference • Actions through aliases can be seen as concurrent • Rely-Guarantee reasoning is good for threads – Summarizes possible interference • We can adapt concurrent analyses to treat aliasing – A few differences to discuss later
expected interference 2. Guarantee bounds thread actions 3. Stable assertions are preserved by interference 4. Compatible threads: each rely assumes at least the other’s guarantee
alias interference 2. Guarantee bounds actions through this alias 3. Stable predicates preserved by interference 4. Compatible aliases: if x == y, then x.G ⊆ y.R && y.G ⊆ x.R • Subsumes ML references! (OCaml, SML, etc.)
Duplicates must be compatible (#4) – havoc ⊈ ≈ • Must track & restrict duplication: – let y = x in … could create • Two immutable refs (ref{nat|P}[≈, ≈]) • Two unrestricted refs (ref{nat|any}[havoc, havoc]) • Producer/consumer (ref{nat|any}[≥,≤] and ref{nat|any}[≤,≥])
in a proof assistant • Satisfying proof obligations – Separated from program text – Semi-automatic • Examples include – Monotonic Counter • Simple, but illustrative • Specify how data changes over time, not inc operation – Reference Immutability
ref, and x’s type disallows mutation to anything, type of !x.f should, too • Containment – ref{T|P}[R,G]: if T contains refs, R permits their interference as well • Precision – P,R,G only depend on heap reachable from the T they apply to Non-issues in concurrent program logics: no “threads to threads”
P is stable with respect to R (#3) – Enforce containment, precision • Aliases as x:ref{τ|P}[R,G] and y:ref{τ|P’}[R’,G’] – Relies summarize guarantees (#4): G’ ⊆ R, G ⊆ R’ – Ensured by splitting semantics and folding • Actions in x.G are included in alias y’s y.R, and thus by stability preserves y.P
Route to a full system: – Non-atomic updates – Internalizing proof terms (in progress) – Better datatype definitions – Borrowing – Concurrency (in progress) – More examples / experience
Explicit Stabilization (Wickerson’10) used for malloc – We apply RG at a much finer granularity • Reference Immutability, Ownership – Notion of per-reference read-only – Tschantz’05, Zibin’07, Dietl’07, Zibin’10, Gordon’12 – We generalize read-only to arbitrary relations • Dependent types for imperative programs – Types depend only on immutable data (DML, etc.) – Or bake in a low-level program logic (Ynot / Hoare Type Theory) – Our types directly treat interference
Key challenge: nested references – Apply concurrent verification insights to aliasing • We applied rely-guarantee • Other correspondences exist • Promising early results – Modest proof burden – Backwards compatible with more traditional systems https://github.com/csgordon/rgref/