Skip to content

Commit d082f10

Browse files
Merge pull request #62 from Matthew-Mosior/seq1
[ new ] Seq1
2 parents a5c7025 + 9482fb9 commit d082f10

6 files changed

Lines changed: 713 additions & 0 deletions

File tree

containers.ipkg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ modules = Data.BoundedQueue.Sized
4343
, Data.Seq.Internal
4444
, Data.Seq.Sized
4545
, Data.Seq.Unsized
46+
, Data.Seq1.Sized
47+
, Data.Seq1.Unsized
4648
, Data.Set
4749
, Data.Set.Internal
4850
, Data.SnocVect

src/Data/Seq1/Sized.idr

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
||| General purpose linear two-end finite sequences,
2+
||| with length in its type.
3+
|||
4+
||| This is implemented by finger tree.
5+
module Data.Seq1.Sized
6+
7+
import Control.WellFounded
8+
9+
import public Data.Fin
10+
import Data.Linear.Ref1
11+
import public Data.Nat
12+
import public Data.Vect
13+
import public Data.Zippable
14+
15+
import Data.Seq.Internal
16+
17+
%default total
18+
19+
||| A linear two-end finite sequence, with length in its type.
20+
export
21+
data Seq1 : (s : Type) -> (n : Nat) -> (e : Type) -> Type where
22+
MkSeq1 : Ref s (FingerTree (Elem e))
23+
-> Seq1 s n e
24+
25+
||| The empty sequence. O(1)
26+
export
27+
empty : F1 s (Seq1 s 0 e)
28+
empty t =
29+
let seq # t := ref1 Empty t
30+
in (MkSeq1 seq) # t
31+
32+
||| A singleton sequence. O(1)
33+
export
34+
singleton : e
35+
-> F1 s (Seq1 s 1 e)
36+
singleton a t =
37+
let seq # t := ref1 (Single (MkElem a)) t
38+
in (MkSeq1 seq) # t
39+
40+
||| A sequence of length n with a the value of every element. O(n)
41+
export
42+
replicate : (n : Nat)
43+
-> (a : e)
44+
-> F1 s (Seq1 s n e)
45+
replicate n a t =
46+
let seq # t := ref1 (replicate' n a) t
47+
in (MkSeq1 seq) # t
48+
49+
||| The number of elements in the sequence. O(1)
50+
export
51+
length : {n : Nat}
52+
-> Seq1 s n e
53+
-> F1 s Nat
54+
length _ t =
55+
n # t
56+
57+
||| Reverse the sequence. O(n)
58+
export
59+
reverse : Seq1 s n e
60+
-> F1' s
61+
reverse (MkSeq1 tr) t =
62+
let tr' # t := read1 tr t
63+
in casswap1 tr (reverseTree id tr') t
64+
65+
export infixr 5 `cons`
66+
||| Add an element to the left end of a sequence. O(1)
67+
export
68+
cons : e
69+
-> Seq1 s n e
70+
-> F1 s (Seq1 s (S n) e)
71+
(a `cons` MkSeq1 tr) t =
72+
let tr' # t := read1 tr t
73+
() # t := casswap1 tr (MkElem a `consTree` tr') t
74+
in (MkSeq1 tr) # t
75+
76+
export infixl 5 `snoc`
77+
||| Add an element to the right end of a sequence. O(1)
78+
export
79+
snoc : Seq1 s n e
80+
-> e
81+
-> F1 s (Seq1 s (S n) e)
82+
(MkSeq1 tr `snoc` a) t =
83+
let tr' # t := read1 tr t
84+
() # t := casswap1 tr (tr' `snocTree` MkElem a) t
85+
in (MkSeq1 tr) # t
86+
87+
||| Concatenate two sequences. O(log(min(m, n)))
88+
export
89+
(++) : Seq1 s m e
90+
-> Seq1 s n e
91+
-> F1 s (Seq1 s (m + n) e)
92+
(MkSeq1 t1 ++ MkSeq1 t2) t =
93+
let t1' # t := read1 t1 t
94+
t2' # t := read1 t2 t
95+
t1t2 # t := ref1 (addTree0 t1' t2') t
96+
in (MkSeq1 t1t2) # t
97+
98+
||| View from the left of the sequence. O(1)
99+
export
100+
viewl : Seq1 s (S n) e
101+
-> F1 s (Maybe (e, Seq1 s n e))
102+
viewl (MkSeq1 tr) t =
103+
let tr' # t := read1 tr t
104+
in case viewLTree tr' of
105+
Just (MkElem a, tr'') =>
106+
let () # t := casswap1 tr tr'' t
107+
in (Just (a, MkSeq1 tr)) # t
108+
Nothing =>
109+
Nothing # t
110+
111+
||| The first element of the sequence. O(1)
112+
export
113+
head : Seq1 s (S n) e
114+
-> F1 s (Maybe e)
115+
head seq t =
116+
let seq' # t := viewl seq t
117+
in case seq' of
118+
Nothing =>
119+
Nothing # t
120+
Just (h, _) =>
121+
(Just h) # t
122+
123+
||| The elements after the head of the sequence. O(1)
124+
export
125+
tail : Seq1 s (S n) e
126+
-> F1 s (Maybe (Seq1 s n e))
127+
tail seq t =
128+
let seq' # t := viewl seq t
129+
in case seq' of
130+
Nothing =>
131+
Nothing # t
132+
Just (_, seq'') =>
133+
(Just seq'') # t
134+
135+
||| View from the right of the sequence. O(1)
136+
export
137+
viewr : Seq1 s (S n) e
138+
-> F1 s (Maybe (Seq1 s n e, e))
139+
viewr (MkSeq1 tr) t =
140+
let tr' # t := read1 tr t
141+
in case viewRTree tr' of
142+
Just (tr'', MkElem a) =>
143+
let () # t := casswap1 tr tr'' t
144+
in (Just (MkSeq1 tr, a)) # t
145+
Nothing =>
146+
Nothing # t
147+
148+
||| The elements before the last element of the sequence. O(1)
149+
export
150+
init : Seq1 s (S n) e
151+
-> F1 s (Maybe (Seq1 s n e))
152+
init seq t =
153+
let seq' # t := viewr seq t
154+
in case seq' of
155+
Nothing =>
156+
Nothing # t
157+
Just (seq'', _) =>
158+
(Just seq'') # t
159+
160+
||| The last element of the sequence. O(1)
161+
export
162+
last : Seq1 s (S n) e
163+
-> F1 s (Maybe e)
164+
last seq t =
165+
let seq' # t := viewr seq t
166+
in case seq' of
167+
Nothing =>
168+
Nothing # t
169+
Just (_, l) =>
170+
(Just l) # t
171+
172+
||| Turn a vector into a sequence. O(n)
173+
export
174+
fromVect : Vect n e
175+
-> F1 s (Seq1 s n e)
176+
fromVect xs t =
177+
let seq # t := ref1 (foldr (\x, tr => MkElem x `consTree` tr) Empty xs) t
178+
in (MkSeq1 seq) # t
179+
180+
||| Turn a list into a sequence. O(n)
181+
export
182+
fromList : (xs : List e)
183+
-> F1 s (Seq1 s (length xs) e)
184+
fromList xs t =
185+
let vect := Vect.fromList xs
186+
in fromVect vect t
187+
188+
||| Turn a sequence into a list. O(n)
189+
export
190+
toList : {n : Nat}
191+
-> Seq1 s n e
192+
-> F1 s (List e)
193+
toList _ {n = 0} t =
194+
[] # t
195+
toList seq {n = S _} t =
196+
go seq Lin t
197+
where
198+
go : {n : Nat}
199+
-> Seq1 s n e
200+
-> (sl : SnocList e)
201+
-> F1 s (List e)
202+
go _ sl {n = 0} t =
203+
(sl <>> []) # t
204+
go seq sl {n = S _} t =
205+
let seq' # t := viewl seq t
206+
in case seq' of
207+
Nothing =>
208+
(sl <>> []) # t
209+
Just (x, seq'') =>
210+
go seq'' (sl :< x) t
211+
212+
||| The element at the specified position. O(log(min(i, n-i)))
213+
export
214+
index : (i : Nat)
215+
-> (t : Seq1 s n e)
216+
-> {auto ok : LT i n}
217+
-> F1 s e
218+
index i (MkSeq1 tr) t =
219+
let tr' # t := read1 tr t
220+
(_, MkElem a) := lookupTree i tr'
221+
in a # t
222+
223+
||| The element at the specified position.
224+
||| Use Fin n to index instead. O(log(min(i, n-i)))
225+
export
226+
index' : (t : Seq1 s n e)
227+
-> (i : Fin n)
228+
-> F1 s e
229+
index' (MkSeq1 tr) fn t =
230+
let tr' # t := read1 tr t
231+
(_, MkElem a) := lookupTree (finToNat fn) tr'
232+
in a # t
233+
234+
||| Update the element at the specified position. O(log(min(i, n-i)))
235+
export
236+
adjust : (f : e -> e)
237+
-> (i : Nat)
238+
-> (t : Seq1 s n e)
239+
-> {auto ok : LT i n}
240+
-> F1' s
241+
adjust f i (MkSeq1 tr) t =
242+
let tr' # t := read1 tr t
243+
in casswap1 tr (adjustTree (const (map f)) i tr') t
244+
245+
||| Replace the element at the specified position. O(log(min(i, n-i)))
246+
export
247+
update : (i : Nat)
248+
-> e
249+
-> (seq : Seq1 s n e)
250+
-> {auto ok : LT i n}
251+
-> F1' s
252+
update i a seq t =
253+
adjust (const a) i seq t
254+
255+
||| Split a sequence at a given position. O(log(min(i, n-i)))
256+
export
257+
splitAt : (i : Nat)
258+
-> Seq1 s (i + j) e
259+
-> F1 s (Seq1 s i e, Seq1 s j e)
260+
splitAt i (MkSeq1 tr) t =
261+
let tr' # t := read1 tr t
262+
(l, r) := split i tr'
263+
l' # t := ref1 l t
264+
r' # t := ref1 r t
265+
in (MkSeq1 l', MkSeq1 r') # t
266+
267+
||| The first i elements of a sequence. O(log(min(i, n-i)))
268+
export
269+
take : (i : Nat)
270+
-> Seq1 s (i + j) e
271+
-> F1 s (Seq1 s i e)
272+
take i seq t =
273+
let (seq1, _) # t := Data.Seq1.Sized.splitAt i seq t
274+
in seq1 # t
275+
276+
||| Elements of a sequence after the first i. O(log(min(i, n-i)))
277+
export
278+
drop : (i : Nat)
279+
-> Seq1 s (i + j) e
280+
-> F1 s (Seq1 s j e)
281+
drop i seq t =
282+
let (_, seq2) # t := Data.Seq1.Sized.splitAt i seq t
283+
in seq2 # t
284+
285+
||| Dump the internal structure of the finger tree.
286+
export
287+
show' : Show e
288+
=> Seq1 s n e
289+
-> F1 s String
290+
show' (MkSeq1 tr) t =
291+
let tr' # t := read1 tr t
292+
in (showPrec Open tr') # t

0 commit comments

Comments
 (0)