|
| 1 | +module Pulse.Lib.BetterInv |
| 2 | +#lang-pulse |
| 3 | +open Pulse.Lib.Core |
| 4 | +open Pulse.Lib.SendSync |
| 5 | +open Pulse.Class.Duplicable |
| 6 | +module C = Pulse.Lib.Core |
| 7 | + |
| 8 | +unfold |
| 9 | +let move_tag0 l1 l2 p |
| 10 | + (f: unit -> stt_ghost unit emp_inames (on l1 p) (fun _ -> on l2 p)) |
| 11 | + = emp |
| 12 | + |
| 13 | +let move_tag l1 l2 p f g = |
| 14 | + move_tag0 l1 l2 p f ** move_tag0 l2 l1 p g |
| 15 | + |
| 16 | +let inv (i: iname) (p: slprop) = |
| 17 | + exists* l l' f g. |
| 18 | + loc l ** move_tag l l' p f g ** |
| 19 | + C.inv i (on l' p) |
| 20 | + |
| 21 | +let aux #p (inst: placeless p) l1 l2 = |
| 22 | + fun () -> inst l1 l2 |
| 23 | + |
| 24 | +ghost fn placeless_inv i p {| inst: placeless p |} : placeless (inv i p) = l1 l2 { |
| 25 | + ghost_impersonate l1 (on l1 (inv i p)) (on l2 (inv i p)) fn _ { |
| 26 | + on_elim (inv i p); |
| 27 | + unfold inv i p; with l_ l'. _; |
| 28 | + loc_gather l1 #l_; |
| 29 | + drop_ (move_tag l_ l' p _ _); |
| 30 | + ghost_impersonate l2 (C.inv i (on l' p)) (on l2 (inv i p)) fn _ { |
| 31 | + fold move_tag l2 l' p (aux inst l2 l') (aux inst l' l2); |
| 32 | + loc_dup l2; |
| 33 | + fold inv i p; |
| 34 | + on_intro (inv i p); |
| 35 | + } |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +ghost fn is_sync_inv i p {| is_sync p |} : is_sync (inv i p) = l1 l2 { |
| 40 | + ghost_impersonate l1 (on l1 (inv i p)) (on l2 (inv i p)) fn _ { |
| 41 | + on_elim (inv i p); |
| 42 | + unfold inv i p; with l_ l' f g. _; |
| 43 | + loc_gather l1 #l_; |
| 44 | + drop_ (move_tag l_ l' p _ _); |
| 45 | + ghost_impersonate l2 (C.inv i (on l' p)) (on l2 (inv i p)) fn _ { |
| 46 | + ghost fn f' () |
| 47 | + requires on l2 p |
| 48 | + ensures on l' p |
| 49 | + { |
| 50 | + is_sync_elim p l1; |
| 51 | + let f = f; f () |
| 52 | + }; |
| 53 | + ghost fn g' () |
| 54 | + requires on l' p |
| 55 | + ensures on l2 p |
| 56 | + { |
| 57 | + let g = g; g (); |
| 58 | + is_sync_elim p l2; |
| 59 | + }; |
| 60 | + fold move_tag l2 l' p f' g'; |
| 61 | + loc_dup l2; |
| 62 | + fold inv i p; |
| 63 | + on_intro (inv i p); |
| 64 | + } |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +ghost fn dup_inv i p () : duplicable_f (inv i p) = { |
| 69 | + unfold inv i p; with l l' f g. _; |
| 70 | + dup (C.inv i (on l' p)) (); |
| 71 | + loc_dup _; |
| 72 | + fold move_tag l l' p f g; |
| 73 | + fold inv i p; |
| 74 | + fold inv i p; |
| 75 | +} |
| 76 | + |
| 77 | +instance duplicable_inv i p : duplicable (inv i p) = |
| 78 | + { dup_f = dup_inv i p } |
0 commit comments