1 | module Data.ByteString.Search.Internal.Utils
3 | import Data.Array.Core
4 | import Data.Array.Mutable
6 | import Data.ByteString
7 | import Data.Linear.Ref1
10 | %hide Data.Buffer.Core.get
11 | %hide Data.Buffer.Core.set
40 | kmpBorders : (bs : ByteString)
41 | -> F1 s (Maybe (MArray s (S (length bs)) Nat))
43 | let arr # t := unsafeMArray1 (S (length bs)) t
44 | arr' # t := go (length bs) bs arr t
49 | -> (bs : ByteString)
50 | -> (arr : MArray s (S (length bs)) Nat)
55 | let Just j' := tryNatToFin j
56 | | Nothing => Nothing # t
57 | j'' # t := get arr j' t
60 | | Nothing => Nothing # t
61 | wi := index (minus i 1) bs
63 | | Nothing => Nothing # t
64 | False := (cast {to=Nat} wi') == (cast {to=Nat} wj')
65 | | True => Just (plus j'' 1) # t
67 | | True => Just Z # t
68 | in assert_total (dec i j'' bs arr t)
70 | -> (bs : ByteString)
71 | -> (arr : MArray s (S (length bs)) Nat)
72 | -> F1 s (Maybe (MArray s (S (length bs)) Nat))
74 | let Just zero := tryNatToFin 0
75 | | Nothing => Nothing # t
76 | () # t := set arr zero 0 t
79 | let i' # t := assert_total (go i bs arr t)
81 | | Nothing => Nothing # t
82 | Just i'' := tryNatToFin (S i)
83 | | Nothing => Nothing # t
84 | j # t := dec (S i) i bs arr t
86 | | Nothing => Nothing # t
87 | () # t := set arr i'' j' t
135 | automaton : (bs : ByteString)
136 | -> F1 s (Maybe (MArray s (mult (plus (length bs) 1) 256) Nat))
138 | let arr # t := unsafeMArray1 (mult (plus (length bs) 1) 256) t
139 | bord # t := kmpBorders bs t
141 | | Nothing => Nothing # t
142 | arr' # t := go Z bs arr bord' t
144 | | Nothing => Nothing # t
147 | flattenIndex : (st : Nat)
149 | -> (bs : ByteString)
150 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
151 | -> F1 s (Maybe (Fin (mult (plus (length bs) 1) 256)))
152 | flattenIndex st byte bs arr t =
153 | let idx := plus (mult st 256) byte
154 | Just idx' := tryNatToFin idx
155 | | Nothing => Nothing # t
159 | -> (patbyte : Maybe Bits8)
161 | -> (bs : ByteString)
162 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
163 | -> F1 s (Maybe (MArray s (mult (plus (length bs) 1) 256) Nat))
164 | loop Z cur patbyte bordcur bs arr t =
165 | let idx # t := flattenIndex cur Z bs arr t
167 | | Nothing => Nothing # t
168 | Just patbyte' := patbyte
170 | let False := cur == Z
172 | let () # t := set arr idx' Z t
174 | fidx # t := flattenIndex bordcur Z bs arr t
178 | bordcur' # t := get arr fidx' t
179 | () # t := set arr idx' bordcur' t
181 | False := Z == (cast {to=Nat} patbyte')
183 | let () # t := set arr idx' (S cur) t
187 | let () # t := set arr idx' Z t
189 | fidx # t := flattenIndex bordcur Z bs arr t
193 | bordcur' # t := get arr fidx' t
194 | () # t := set arr idx' bordcur' t
196 | loop (S b) cur patbyte bordcur bs arr t =
197 | let idx # t := flattenIndex cur (S b) bs arr t
199 | | Nothing => Nothing # t
200 | Just patbyte' := patbyte
202 | let False := cur == Z
204 | let () # t := set arr idx' Z t
205 | in loop b cur patbyte bordcur bs arr t
206 | fidx # t := flattenIndex bordcur (S b) bs arr t
210 | bordcur' # t := get arr fidx' t
211 | () # t := set arr idx' bordcur' t
212 | in loop b cur patbyte bordcur' bs arr t
213 | False := (S b) == (cast {to=Nat} patbyte')
215 | let () # t := set arr idx' (S cur) t
216 | in loop b cur patbyte bordcur bs arr t
219 | let () # t := set arr idx' Z t
220 | in loop b cur patbyte bordcur bs arr t
221 | fidx # t := flattenIndex bordcur (S b) bs arr t
225 | bordcur' # t := get arr fidx' t
226 | () # t := set arr idx' bordcur' t
227 | in loop b cur patbyte bordcur' bs arr t
228 | fillState : (cur : Nat)
229 | -> (bs : ByteString)
230 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
231 | -> (bord : MArray s (S (length bs)) Nat)
232 | -> F1 s (Maybe (MArray s (mult (plus (length bs) 1) 256) Nat))
233 | fillState cur bs arr bord t =
234 | let Just cur' := tryNatToFin cur
237 | bordcur # t := get bord cur' t
238 | patbyte := index cur bs
239 | arr' # t := loop 255 cur patbyte bordcur bs arr t
245 | -> (bs : ByteString)
246 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
247 | -> (bord : MArray s (S (length bs)) Nat)
248 | -> F1 s (Maybe (MArray s (mult (plus (length bs) 1) 256) Nat))
249 | go state bs arr bord t =
250 | let False := state > (length bs)
253 | arr' # t := fillState state bs arr bord t
257 | in assert_total (go (S state) bs arr'' bord t)
296 | occurrences : (bs : ByteString)
297 | -> {0 prf : So (not $
null bs)}
298 | -> F1 s (Maybe (MArray s 256 Int))
300 | let arr # t := marray1 256 (the Int 1) t
301 | arr' # t := go Z (length bs) bs arr t
309 | -> (bs : ByteString)
310 | -> (arr : MArray s 256 Int)
311 | -> F1 s (Maybe (MArray s 256 Int))
312 | go i patend bs arr t =
313 | let False := (S i) >= patend
320 | Just i''' := tryNatToFin (cast {to=Nat} i'')
323 | () # t := set arr i''' (negate $
cast {to=Int} i) t
324 | in assert_total (go (plus i 1) patend bs arr t)
367 | suffixLengths : (bs : ByteString)
368 | -> {0 prf : So (not $
null bs)}
369 | -> F1 s (Maybe (MArray s (length bs) Int))
370 | suffixLengths bs t =
371 | let arr # t := marray1 (length bs) (the Int 0) t
372 | Just idx := tryNatToFin (minus (length bs) 1)
375 | () # t := set arr idx (cast {to=Int} (length bs)) t
376 | arr' # t := noSuffix (cast {to=Int} (minus (length bs) 2)) bs arr t
384 | -> F1 s (Maybe Int)
389 | j' := index (cast {to=Nat} j) bs
393 | j''' := index (cast {to=Nat} (j + diff)) bs
397 | False := j'' /= j''''
400 | in assert_total (dec diff (j - 1) t)
402 | suffixLoop : (pre : Int)
405 | -> (bs : ByteString)
406 | -> (arr : MArray s (length bs) Int)
407 | -> F1 s (Maybe (MArray s (length bs) Int))
408 | suffixLoop _ _ 0 _ arr t =
410 | suffixLoop pre end idx bs arr t =
411 | let True := pre < idx
413 | noSuffix idx bs arr t
414 | idx' := index (cast {to=Nat} idx) bs
418 | idx''' := index (minus (length bs) 1) bs
419 | Just idx'''' := idx'''
422 | False := idx'' /= idx''''
424 | let Just idxs := tryNatToFin (cast {to=Nat} idx)
427 | () # t := set arr idxs 0 t
428 | in assert_total (suffixLoop pre (end - 1) (idx - 1) bs arr t)
429 | Just end' := tryNatToFin (cast {to=Nat} end)
432 | prevs # t := get arr end' t
433 | Just idxs := tryNatToFin (cast {to=Nat} idx)
436 | False := (pre + prevs) < idx
438 | let () # t := set arr idxs prevs t
439 | in assert_total (suffixLoop pre (end - 1) (idx - 1) bs arr t)
440 | pri # t := dec (cast {to=Int} (minus (length bs) (cast {to=Nat} idx))) pre t
444 | () # t := set arr idxs (idx - pri') t
445 | in assert_total (suffixLoop pri' (cast {to=Int} (minus (length bs) 2)) (idx - 1) bs arr t)
446 | noSuffix : (i : Int)
447 | -> (bs : ByteString)
448 | -> (arr : MArray s (length bs) Int)
449 | -> F1 s (Maybe (MArray s (length bs) Int))
450 | noSuffix 0 _ arr t =
452 | noSuffix i bs arr t =
453 | let patati := index (cast {to=Nat} i) bs
454 | Just patati' := patati
457 | patatend := index (minus (length bs) 1) bs
458 | Just patatend' := patatend
461 | True := patati' == patatend'
463 | let Just i' := tryNatToFin (cast {to=Nat} i)
466 | () # t := set arr i' 0 t
467 | in assert_total (noSuffix (i - 1) bs arr t)
468 | diff := (cast {to=Int} (minus (length bs) 1)) - i
470 | previ # t := dec diff nexti t
471 | Just previ' := previ
474 | Just i' := tryNatToFin (cast {to=Nat} i)
477 | False := previ' == nexti
479 | let () # t := set arr i' 1 t
480 | in assert_total (noSuffix nexti bs arr t)
481 | () # t := set arr i' (i - previ') t
482 | in assert_total (suffixLoop previ' (cast {to=Int} (minus (length bs) 2)) nexti bs arr t)
533 | suffixShifts : (bs : ByteString)
534 | -> {0 prf : So (not $
null bs)}
535 | -> F1 s (Maybe (MArray s (length bs) Int))
536 | suffixShifts bs {prf} t =
537 | let arr # t := marray1 (length bs) (cast {to=Int} (length bs)) t
538 | suff # t := suffixLengths bs {prf=prf} t
542 | arr' # t := prefixShift (cast {to=Int} (minus (length bs) 2)) 0 bs suff' arr t
546 | arr''' # t := suffixShift 0 bs suff' arr'' t
547 | Just arr'''' := arr'''
550 | in Just arr'''' # t
552 | fillToShift : (i : Int)
554 | -> (bs : ByteString)
555 | -> (arr : MArray s (length bs) Int)
556 | -> F1 s (Maybe (MArray s (length bs) Int))
557 | fillToShift i shift bs arr t =
558 | let False := i == shift
561 | Just i' := tryNatToFin (cast {to=Nat} i)
564 | () # t := set arr i' shift t
565 | in assert_total (fillToShift (i + 1) shift bs arr t)
566 | prefixShift : (idx : Int)
568 | -> (bs : ByteString)
569 | -> (suff : MArray s (length bs) Int)
570 | -> (arr : MArray s (length bs) Int)
571 | -> F1 s (Maybe (MArray s (length bs) Int))
572 | prefixShift idx j bs suff arr t =
573 | let False := idx < 0
576 | Just idx' := tryNatToFin (cast {to=Nat} idx)
579 | idx'' # t := get suff idx' t
580 | True := idx'' == (idx + 1)
582 | assert_total (prefixShift (idx - 1) j bs suff arr t)
583 | shift := (cast {to=Int} (minus (length bs) 1)) - idx
584 | arr' # t := fillToShift j shift bs arr t
588 | in assert_total (prefixShift (idx - 1) shift bs suff arr'' t)
589 | suffixShift : (idx : Int)
590 | -> (bs : ByteString)
591 | -> (suff : MArray s (length bs) Int)
592 | -> (arr : MArray s (length bs) Int)
593 | -> F1 s (Maybe (MArray s (length bs) Int))
594 | suffixShift idx bs suff arr t =
595 | let patend := cast {to=Int} (minus (length bs) 1)
596 | False := idx >= patend
599 | Just idx' := tryNatToFin (cast {to=Nat} idx)
602 | idx'' # t := get suff idx' t
603 | target := patend - idx''
604 | Just target' := tryNatToFin (cast {to=Nat} target)
607 | value := patend - idx
608 | () # t := set arr target' value t
609 | in assert_total (suffixShift (idx + 1) bs suff arr t)