recall for free
play

Recall for free: preorder - respecting state monads in Danel Ahman - PowerPoint PPT Presentation

Recall for free: preorder - respecting state monads in Danel Ahman LFCS, University of Edinburgh (joint work with Aseem Rastogi and Nikhil Swamy) EUTypes WG Meeting in Lisbon 5 October 2016 An effectful dependently-typed functional


  1. get and put val get : #rel:preorder state → PST rel state ( fun _ → True) ( fun s 0 s s 1 → s 0 = s ∧ s = s 1 )

  2. get and put pre and post are exactly as for STATE and ST val get : #rel:preorder state → PST rel state ( fun _ → True) ( fun s 0 s s 1 → s 0 = s ∧ s = s 1 )

  3. get and put pre and post are exactly as for STATE and ST val get : #rel:preorder state → PST rel state ( fun _ → True) ( fun s 0 s s 1 → s 0 = s ∧ s = s 1 ) val put : #rel:preorder state → x:state → PST rel unit ( fun s 0 → rel s 0 x) ( fun _ _ s 1 → s 1 = x)

  4. get and put pre and post are exactly as for STATE and ST val get : #rel:preorder state → PST rel state ( fun _ → True) ( fun s 0 s s 1 → s 0 = s ∧ s = s 1 ) the change wrt. STATE and ST val put : #rel:preorder state val put : #rel:preorder state → x:state → x:state → PST rel unit ( fun s 0 → rel s 0 x) → PST rel unit ( fun s 0 → rel s 0 x) ( fun _ _ s 1 → s 1 = x) ( fun _ _ s 1 → s 1 = x)

  5. ■ - modality in

  6. ■ - modality in We introduce an uninterpreted function symbol val ■ : #rel:preorder state → p:stable_p rel → Type 0

  7. ■ - modality in We introduce an uninterpreted function symbol val ■ : #rel:preorder state → p:stable_p rel → Type 0 We assume logical axioms, e.g., functoriality: forall p p' . ( forall s . p s ⇒ p' s) ⇒ ( ■ p ⇒ ■ p')

  8. ■ - modality in We introduce an uninterpreted function symbol val ■ : #rel:preorder state → p:stable_p rel → Type 0 We assume logical axioms, e.g., functoriality: forall p p' . ( forall s . p s ⇒ p' s) ⇒ ( ■ p ⇒ ■ p') Two readings of ■ p 
 p held at some past state of an PSTATE computation p holds at all states reachable from the current with PSTATE

  9. witness and recall

  10. witness and recall val witness : #rel:preorder state → p:stable_p rel → PST rel unit ( fun s 0 → p s 0 ) ■ p) ( fun s 0 _ s 1 → s 0 = s 1 ∧

  11. witness and recall val witness : #rel:preorder state → p:stable_p rel → PST rel unit ( fun s 0 → p s 0 ) ■ p) ( fun s 0 _ s 1 → s 0 = s 1 ∧ val recall : #rel:preorder state → p:stable_p rel → PST rel unit ( fun _ → ■ p ) p s 1 ) ( fun s 0 _ s 1 → s 0 = s 1 ∧

  12. Examples

  13. Examples

  14. Examples • Recalling that allocated references remain allocated • using FStar.Heap.heap (need a source of freshness for alloc ) � using our own heap type (source of freshness built into the heap)

  15. Examples • Recalling that allocated references remain allocated • using FStar.Heap.heap (need a source of freshness for alloc ) � using our own heap type (source of freshness built into the heap) • Immutable references and other preorders

  16. Examples • Recalling that allocated references remain allocated • using FStar.Heap.heap (need a source of freshness for alloc ) � using our own heap type (source of freshness built into the heap) • Immutable references and other preorders • Monotonic references

  17. Examples • Recalling that allocated references remain allocated • using FStar.Heap.heap (need a source of freshness for alloc ) � using our own heap type (source of freshness built into the heap) • Immutable references and other preorders • Monotonic references � Temporarily ignoring the constraint on put via snapshots

  18. Our heap and ref types

  19. Our heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } let ref a = nat

  20. Our heap and ref types freshness counter The heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } { ... } let ref a = nat let ref a = nat

  21. Our heap and ref types freshness counter The heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } { ... } let ref a = nat let ref a = nat We can define sel and upd and gen_fresh operations

  22. Our heap and ref types freshness counter The heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } { ... } both ops. have (r ∈ h) let ref a = nat let ref a = nat refinements on references We can define sel and upd and gen_fresh operations

  23. Our heap and ref types freshness counter The heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } { ... } both ops. have (r ∈ h) let ref a = nat let ref a = nat refinements on references We can define sel and upd and gen_fresh operations and prove expected properties, e.g.: r <> r' ⇒ sel (upd h r x) r' = sel h r'

  24. Our heap and ref types freshness counter The heap and ref types The heap and ref types let heap = h:(nat * (nat → option (a:Type 0 & a))) let heap = h:(nat * (nat → option (a:Type 0 & a))) { ... } { ... } both ops. have (r ∈ h) let ref a = nat let ref a = nat refinements on references Goal: use this heap as drop-in replacement for F * 's heap We can define sel and upd and gen_fresh operations (but in F*'s heap , sel and upd don't have (r ∈ h) refinements) and prove expected properties, e.g.: • change the type of refs. to ( let ref a = nat * a) r <> r' ⇒ sel (upd h r x) r' = sel h r' • make use of the presence LEM in WPs for checking (r ∈ h)

  25. Allocated references example

  26. Allocated references example The type of refs. and preorder for recalling allocation let ref a = r:(Heap.ref a){ ■ ( fun h → r ∈ h) } let rel h 0 h 1 = forall a r . r ∈ h 0 ⇒ r ∈ h 1 AllocST a pre post = PST rel a pre post

  27. Allocated references example The type of refs. and preorder for recalling allocation let ref a = r:(Heap.ref a){ ■ ( fun h → r ∈ h) } let rel h 0 h 1 = forall a r . r ∈ h 0 ⇒ r ∈ h 1 AllocST a pre post = PST rel a pre post AllocST operations crucially use witness and recall , e.g., let read #a (r:ref a) = let h = get () in recall ( fun h → r ∈ h) ; sel h r

  28. Snapshots

  29. Snapshots We first define snaphsot-capable state as let s_state state = state * option state

  30. Snapshots We first define snaphsot-capable state as let s_state state = state * option state The snaphsot-capable preorder is indexed by rel on state let s_rel (rel:preorder state) s 0 s 1 = match (snd s 0 ) (snd s 1 ) with | None None ⇒ rel (fst s 0 ) (fst s 1 ) | None (Some s) ⇒ rel (fst s 0 ) s | (Some s) None ⇒ rel s (fst s 1 ) | (Some s 0 ') (Some s 1 ') ⇒ rel s 0 ' s 1 '

  31. Snapshots We first define snaphsot-capable state as let s_state state = state * option state The snaphsot-capable preorder is indexed by rel on state let s_rel (rel:preorder state) s 0 s 1 = match (snd s 0 ) (snd s 1 ) with | None None ⇒ rel (fst s 0 ) (fst s 1 ) | None (Some s) ⇒ rel (fst s 0 ) s | (Some s) None ⇒ rel s (fst s 1 ) | (Some s 0 ') (Some s 1 ') ⇒ rel s 0 ' s 1 '

  32. Snapshots We first define snaphsot-capable state as let s_state state = state * option state The snaphsot-capable preorder is indexed by rel on state let s_rel (rel:preorder state) s 0 s 1 = match (snd s 0 ) (snd s 1 ) with | None None ⇒ rel (fst s 0 ) (fst s 1 ) | None (Some s) ⇒ rel (fst s 0 ) s | (Some s) None ⇒ rel s (fst s 1 ) | (Some s 0 ') (Some s 1 ') ⇒ rel s 0 ' s 1 '

  33. Snapshots We first define snaphsot-capable state as let s_state state = state * option state The snaphsot-capable preorder is indexed by rel on state let s_rel (rel:preorder state) s 0 s 1 = match (snd s 0 ) (snd s 1 ) with | None None ⇒ rel (fst s 0 ) (fst s 1 ) | None (Some s) ⇒ rel (fst s 0 ) s | (Some s) None ⇒ rel s (fst s 1 ) | (Some s 0 ') (Some s 1 ') ⇒ rel s 0 ' s 1 '

  34. Snapshots We first define snaphsot-capable state as let s_state state = state * option state The snaphsot-capable preorder is indexed by rel on state let s_rel (rel:preorder state) s 0 s 1 = match (snd s 0 ) (snd s 1 ) with | None None ⇒ rel (fst s 0 ) (fst s 1 ) | None (Some s) ⇒ rel (fst s 0 ) s | (Some s) None ⇒ rel s (fst s 1 ) | (Some s 0 ') (Some s 1 ') ⇒ rel s 0 ' s 1 '

  35. read and write

  36. read and write val read : #rel:preorder state → SST rel state ( fun s 0 → True) ∧ fst s 1 ∧ ( fun s 0 s s 1 → fst s 0 = s s = snd s 0 = snd s 1 ) let write #rel x = ...

  37. read and write val read : #rel:preorder state → SST rel state ( fun s 0 → True) ∧ fst s 1 ∧ ( fun s 0 s s 1 → fst s 0 = s s = snd s 0 = snd s 1 ) let write #rel x = ... val write : #rel:preorder state → x:state → SST rel unit ( fun s 0 → s_rel rel s 0 (x,snd s 0 )) ( fun s 0 _ s 1 → s 1 = (x,snd s 0 )) let write #rel x = ...

  38. witness and recall

  39. witness and recall val witness : #rel:preorder state → p:stable_p rel → SST rel unit ( fun s 0 → p (fst s 0 ) ∧ snd s 0 = None) ■ p) ( fun s 0 _ s 1 → s 0 = s 1 ∧ let witness #rel p = ...

  40. witness and recall val witness : #rel:preorder state → p:stable_p rel → SST rel unit ( fun s 0 → p (fst s 0 ) ∧ snd s 0 = None) ■ p) ( fun s 0 _ s 1 → s 0 = s 1 ∧ let witness #rel p = ... val recall : #rel:preorder state → p:stable_p rel → SST rel unit ( fun s 0 → ■ p ∧ snd s 0 = None) ( fun s 0 _ s 1 → s 0 = s 1 ∧ p (fst s 1 )) let recall #rel p = ...

  41. snap and ok

  42. snap and ok val snap : #rel:preorder state → SST rel unit ( fun s 0 → snd s 0 = None) ( fun s 0 _ s 1 → fst s 0 = fst s 1 ∧ snd s 1 = Some (fst s 0 )) let snap #rel = ...

  43. snap and ok val snap : #rel:preorder state → SST rel unit ( fun s 0 → snd s 0 = None) ( fun s 0 _ s 1 → fst s 0 = fst s 1 ∧ snd s 1 = Some (fst s 0 )) let snap #rel = ... val ok : #rel:preorder state → SST rel unit ( fun s 0 → exists s . snd s 0 = Some s ∧ rel s (fst s 0 )) ( fun s 0 _ s 1 → fst s 0 = fst s 1 ∧ snd s 1 = None) let ok #rel = ...

  44. Example use of SST

  45. Example use of SST y 1 y 0 x 0 x 1 • Implementing a 2D point using two locations • E.g., want to enforce that can only move along some line

  46. A glimpse of the formal metatheory

  47. PSTATE formally

  48. PSTATE formally We work with a small calculus based on EMF * from DM4F t, wp, ::= state | rel | x:t1 → Tot t2 | x:t1 → PSTATE t2 wp | ... e, φ | x | fun x:t → e | e1 e2 | (e1,e2) | fst e | ... | return e | bind e1 x:t.e2 | get e | put e | witness e | recall e

  49. PSTATE formally We work with a small calculus based on EMF * from DM4F t, wp, ::= state | rel | x:t1 → Tot t2 | x:t1 → PSTATE t2 wp | ... e, φ | x | fun x:t → e | e1 e2 | (e1,e2) | fst e | ... | return e | bind e1 x:t.e2 | get e | put e | witness e | recall e Typing judgements have the form G ⊢ e : Tot t G ⊢ e : PSTATE t wp

  50. PSTATE formally We work with a small calculus based on EMF * from DM4F t, wp, ::= state | rel | x:t1 → Tot t2 | x:t1 → PSTATE t2 wp | ... e, φ | x | fun x:t → e | e1 e2 | (e1,e2) | fst e | ... | return e | bind e1 x:t.e2 | get e | put e | witness e | recall e Typing judgements have the form G ⊢ e : Tot t G ⊢ e : PSTATE t wp There is also a judgement for logical reasoning in WPs G | Φ ⊨ φ

  51. PSTATE formally We work with a small calculus based on EMF * from DM4F t, wp, ::= state | rel | x:t1 → Tot t2 | x:t1 → PSTATE t2 wp | ... e, φ | x | fun x:t → e | e1 e2 | (e1,e2) | fst e | ... | return e | bind e1 x:t.e2 | get e | put e | witness e | recall e Typing judgements have the form G ⊢ e : Tot t G ⊢ e : PSTATE t wp There is also a judgement for logical reasoning in WPs G | Φ ⊨ φ nat. deduction for classical predicate logic

  52. Operational semantics

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend