0 | module IO.Async.Loop.Queue
2 | import Data.Linear.Ref1
8 | inc : IORef Nat -> IO1 ()
11 | let v # t := read1 r t
12 | True # t := caswrite1 r v (S v) t | _ # t => inc r t
16 | dec : IORef Nat -> IO1 Bool
17 | dec r t = assert_total $
let v # t := read1 r t in go v v t
19 | go : Nat -> Nat -> IO1 Bool
20 | go x 0 t = False # t
22 | let True # t := caswrite1 r x k t | _ # t => dec r t
32 | record Queue a where
39 | queueOf : (0 a : Type) -> Queue a
40 | queueOf _ = Q False [] [<]
43 | isEmpty : Queue a -> Bool
44 | isEmpty (Q _ [] [<]) = True
48 | enq : IORef (Queue a) -> a -> IO1 Bool
49 | enq r v t = assert_total $
let q # t := read1 r t in go q q t
51 | go : Queue a -> Queue a -> IO1 Bool
52 | go x (Q as [] [<]) t = case caswrite1 r x (Q as [v] [<]) t of
55 | go x (Q as h tl) t = case caswrite1 r x (Q as h (tl:<v)) t of
60 | enqall : IORef (Queue a) -> List a -> IO1 Bool
61 | enqall r vs t = assert_total $
let q # t := read1 r t in go q q t
63 | go : Queue a -> Queue a -> IO1 Bool
64 | go x (Q as [] [<]) t = case caswrite1 r x (Q as vs [<]) t of
66 | _ # t => enqall r vs t
67 | go x (Q as h tl) t = case caswrite1 r x (Q as h (tl<><vs)) t of
69 | _ # t => enqall r vs t
72 | deq : IORef (Queue a) -> IO1 (Maybe a)
73 | deq r t = assert_total $
let q # t := read1 r t in go q q t
75 | go : Queue a -> Queue a -> IO1 (Maybe a)
76 | go x (Q as h tl) t =
78 | y::z => case caswrite1 r x (Q False z tl) t of
79 | True # t => Just y # t
81 | [] => case tl <>> [] of
82 | y::z => case caswrite1 r x (Q False z [<]) t of
83 | True # t => Just y # t
88 | deqAndSleep : IORef (Queue a) -> IO1 (Maybe a)
89 | deqAndSleep r t = assert_total $
let q # t := read1 r t in go q q t
91 | go : Queue a -> Queue a -> IO1 (Maybe a)
92 | go x (Q as h tl) t =
94 | y::z => case caswrite1 r x (Q False z tl) t of
95 | True # t => Just y # t
97 | [] => case tl <>> [] of
98 | y::z => case caswrite1 r x (Q False z [<]) t of
99 | True # t => Just y # t
101 | [] => case caswrite1 r x (Q True [] [<]) t of
102 | True # t => Nothing # t
115 | count : List a -> Nat -> Nat
119 | count (_::_::xs) (S k) = S (count xs k)
122 | countsl : SnocList a -> Nat -> Nat
126 | countsl (sx:<_:<_) (S k) = S (countsl sx k)
128 | splitList : SnocList a -> Nat -> List a -> (List a, List a)
129 | splitList sx (S k) (x::xs) = splitList (sx:<x) k xs
130 | splitList sx _ xs =(xs, sx <>> [])
132 | splitSnoc : SnocList a -> Nat -> List a -> (SnocList a, List a)
133 | splitSnoc (sx:<x) (S k) xs = splitSnoc sx k (x::xs)
134 | splitSnoc sx _ xs = (sx, xs)
136 | splitHead : List a -> (List a, List a)
137 | splitHead xs = splitList [<] (count xs STEAL_MAX) xs
139 | splitTail : Nat -> List a -> List a -> SnocList a -> (SnocList a, List a)
140 | splitTail (S n) res (_::t) (i:<v) = splitTail n (v::res) t i
141 | splitTail 0 res _ sx = (sx, res)
142 | splitTail n res _ [<] = ([<], res)
143 | splitTail n res [] sx =
144 | splitSnoc sx (countsl sx n) res
149 | steal : IORef (Queue a) -> IO1 (Maybe a)
150 | steal r t = assert_total $
let q # t := read1 r t in go q q t
152 | go : Queue a -> Queue a -> IO1 (Maybe a)
153 | go x (Q a hs ts) t =
155 | (rem:<v) => case caswrite1 r x (Q a hs rem) t of
156 | True # t => Just v # t
159 | v::rem => case caswrite1 r x (Q a rem [<]) t of
160 | True # t => Just v # t
181 | 0 count1 : (n : Nat) -> count [] n === 0
184 | 0 count2 : (n : Nat) -> (xs : List a) -> LTE (count xs n) n
185 | count2 0 [] = LTEZero
186 | count2 0 (x :: xs) = LTEZero
187 | count2 (S k) [] = LTEZero
188 | count2 (S k) [x] = LTESucc LTEZero
189 | count2 (S k) (_::_::xs)= LTESucc (count2 k xs)
191 | 0 count3 : (n : Nat) -> (xs : List a) -> LTE (count xs n) (length xs)
192 | count3 0 [] = LTEZero
193 | count3 0 (x :: xs) = LTEZero
194 | count3 (S k) [] = LTEZero
195 | count3 (S k) [x] = LTESucc LTEZero
196 | count3 (S k) (_::_::xs)= lteSuccRight (LTESucc $
count3 k xs)
198 | 0 count4 : count [1,2,3,4,5] 2 === 2
201 | 0 count5 : count [1,2,3,4] 2 === 2
204 | 0 count6 : count [1,2,3] 2 === 2
207 | 0 count7 : count [1,2] 2 === 1
210 | 0 countsl1 : (n : Nat) -> countsl [<] n === 0
213 | 0 countsl2 : (n : Nat) -> (sx : SnocList a) -> LTE (countsl sx n) n
214 | countsl2 0 [<] = LTEZero
215 | countsl2 0 (sx :< x) = LTEZero
216 | countsl2 (S k) [<] = LTEZero
217 | countsl2 (S k) [<x] = LTESucc LTEZero
218 | countsl2 (S k) (sx:<_:<_)= LTESucc (countsl2 k sx)
220 | 0 countsl3 : (n : Nat) -> (sx : SnocList a) -> LTE (countsl sx n) (length sx)
221 | countsl3 0 [<] = LTEZero
222 | countsl3 0 (sx:<x) = LTEZero
223 | countsl3 (S k) [<] = LTEZero
224 | countsl3 (S k) [<x] = LTESucc LTEZero
225 | countsl3 (S k) (sx:<_:<_)= lteSuccRight (LTESucc $
countsl3 k sx)
227 | 0 countsl4 : countsl [<1,2,3,4,5] 2 === 2
230 | 0 countsl5 : countsl [<1,2,3,4] 2 === 2
233 | 0 countsl6 : countsl [<1,2,3] 2 === 2
236 | 0 countsl7 : countsl [<1,2] 2 === 1