FStarLang / steel

The Steel separation logic library for F*
Apache License 2.0
24 stars 5 forks source link

Ghost, Unobservable, Atomic #144

Open nikswamy opened 9 months ago

nikswamy commented 9 months ago

Reflecting a conversation with @mtzguido

We are consider a three-point lattice of Ghost < Unobservable < Atomic and indexing a new Pulse computation type with these labels as follows:

type label = Ghost | Unobservable | Atomic
val stpoly (a:Type) (_:inames) (_:label) (pre:vprop) (post: a -> vprop)

The bind for stpoly behaves like a graded monad on this label. st_poly a _ Atomic _ _ can be promoted to stt unconditionally. st_poly a _ (Ghost| Unobservable) _ _ can be promoted to Atomic if a is non-informative.

new_invariant is Unobservable. with_invariant both is always at least in Unobservable (never Ghost), but may be Atomic if its body is. Ghost (and only it) is also treated as an erasable effect, meaning that it composes with FStar.Ghost.

The distinction between Ghost/Atomic should be obvious. The need for Unobservable comes up because we want to prevent the use of ghost axioms to create invariants, as in FStar issue FStarLang/FStar#2814