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 (MArray s (S (length bs)) Nat)
43 | let arr # t := unsafeMArray1 (S (length bs)) t
44 | () # t := go (length bs) bs arr t
49 | -> (bs : ByteString)
50 | -> (arr : MArray s (S (length bs)) Nat)
55 | case tryNatToFin j of
57 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.kmpBorders.dec: can't convert Nat to Fin") # t
59 | let j'' # t := get arr j' t
63 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.kmpBorders.dec: can't index into ByteString") # t
65 | let wi := index (minus i 1) bs
68 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.kmpBorders.dec: can't index into ByteString") # t
70 | case (cast {to=Nat} wi') == (cast {to=Nat} wj') of
78 | assert_total (dec i j'' bs arr t)
80 | -> (bs : ByteString)
81 | -> (arr : MArray s (S (length bs)) Nat)
84 | case tryNatToFin 0 of
86 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.kmpBorders.go: can't convert Nat to Fin") # t
90 | let () # t := assert_total (go i bs arr t)
91 | in case tryNatToFin (S i) of
93 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.kmpBorders.go: can't convert Nat to Fin") # t
95 | let j # t := dec (S i) i bs arr t
146 | automaton : (bs : ByteString)
147 | -> F1 s (MArray s (mult (plus (length bs) 1) 256) Nat)
149 | let arr # t := unsafeMArray1 (mult (plus (length bs) 1) 256) t
150 | bord # t := kmpBorders bs t
151 | () # t := go Z bs arr bord t
154 | flattenIndex : (st : Nat)
156 | -> (bs : ByteString)
157 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
158 | -> F1 s (Fin (mult (plus (length bs) 1) 256))
159 | flattenIndex st byte bs arr t =
160 | let idx := plus (mult st 256) byte
161 | in case tryNatToFin idx of
163 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.automaton.loop: can't convert Nat to Fin") # t
168 | -> (patbyte : Maybe Bits8)
170 | -> (bs : ByteString)
171 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
173 | loop Z cur patbyte bordcur bs arr t =
174 | let idx # t := flattenIndex cur Z bs arr t
181 | let fidx # t := flattenIndex bordcur Z bs arr t
182 | bordcur' # t := get arr fidx t
183 | in set arr idx bordcur' t
185 | case Z == (cast {to=Nat} patbyte') of
187 | set arr idx (S cur) t
193 | let fidx # t := flattenIndex bordcur Z bs arr t
194 | bordcur' # t := get arr fidx t
195 | in 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
202 | let () # t := set arr idx Z t
203 | in assert_total (loop b cur patbyte bordcur bs arr t)
205 | let fidx # t := flattenIndex bordcur (S b) bs arr t
206 | bordcur' # t := get arr fidx t
207 | () # t := set arr idx bordcur' t
208 | in assert_total (loop b cur patbyte bordcur' bs arr t)
210 | case (S b) == (cast {to=Nat} patbyte') of
212 | let () # t := set arr idx (S cur) t
213 | in assert_total (loop b cur patbyte bordcur bs arr t)
217 | let () # t := set arr idx Z t
218 | in assert_total (loop b cur patbyte bordcur bs arr t)
220 | let fidx # t := flattenIndex bordcur (S b) bs arr t
221 | bordcur' # t := get arr fidx t
222 | () # t := set arr idx bordcur' t
223 | in assert_total (loop b cur patbyte bordcur' bs arr t)
224 | fillState : (cur : Nat)
225 | -> (bs : ByteString)
226 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
227 | -> (bord : MArray s (S (length bs)) Nat)
229 | fillState cur bs arr bord t =
230 | case tryNatToFin cur of
232 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.automaton.fillState: can't convert Nat to Fin") # t
234 | let bordcur # t := get bord cur' t
235 | patbyte := index cur bs
236 | in loop 255 cur patbyte bordcur bs arr t
238 | -> (bs : ByteString)
239 | -> (arr : MArray s (mult (plus (length bs) 1) 256) Nat)
240 | -> (bord : MArray s (S (length bs)) Nat)
242 | go state bs arr bord t =
243 | case state > (length bs) of
247 | let () # t := fillState state bs arr bord t
248 | in assert_total (go (S state) bs arr bord t)
287 | occurrences : (bs : ByteString)
288 | -> {0 prf : So (not $
null bs)}
289 | -> F1 s (MArray s 256 Int)
291 | let arr # t := marray1 256 (the Int 1) t
292 | () # t := go Z (length bs) bs arr t
297 | -> (bs : ByteString)
298 | -> (arr : MArray s 256 Int)
300 | go i patend bs arr t =
301 | case (S i) >= patend of
305 | let i' := index i bs
308 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.occurrences.go: can't index into ByteString") # t
310 | case tryNatToFin (cast {to=Nat} i'') of
312 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.occurrences.go: can't convert Nat to Fin") # t
314 | let () # t := set arr i''' (negate $
cast {to=Int} i) t
315 | in assert_total (go (plus i 1) patend bs arr t)
358 | suffixLengths : (bs : ByteString)
359 | -> {0 prf : So (not $
null bs)}
360 | -> F1 s (MArray s (length bs) Int)
361 | suffixLengths bs t =
362 | let arr # t := marray1 (length bs) (the Int 0) t
363 | in case tryNatToFin (minus (length bs) 1) of
365 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths: can't convert Nat to Fin") # t
367 | let () # t := set arr idx (cast {to=Int} (length bs)) t
368 | () # t := noSuffix (cast {to=Int} (minus (length bs) 2)) bs arr t
379 | let j' := index (cast {to=Nat} j) bs
382 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.dec: can't index into ByteString") # t
384 | let j''' := index (cast {to=Nat} (j + diff)) bs
387 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.dec: can't index into ByteString") # t
389 | case j'' /= j'''' of
393 | assert_total (dec diff (j - 1) t)
395 | suffixLoop : (pre : Int)
398 | -> (bs : ByteString)
399 | -> (arr : MArray s (length bs) Int)
401 | suffixLoop _ _ 0 _ _ t =
403 | suffixLoop pre end idx bs arr t =
406 | let idx' := index (cast {to=Nat} idx) bs
409 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.suffixLoop: can't index into ByteString") # t
411 | let idx''' := index (minus (length bs) 1) bs
414 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.suffixLoop: can't index into ByteString") # t
416 | case idx'' /= idx'''' of
418 | case tryNatToFin (cast {to=Nat} idx) of
420 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.suffixLoop: can't convert Nat to Fin") # t
422 | let () # t := set arr idxs 0 t
423 | in assert_total (suffixLoop pre (end - 1) (idx - 1) bs arr t)
425 | case tryNatToFin (cast {to=Nat} end) of
427 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.suffixLoop: can't convert Nat to Fin") # t
429 | let prevs # t := get arr end' t
430 | in case tryNatToFin (cast {to=Nat} idx) of
432 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.suffixLoop: can't convert Nat to Fin") # t
434 | case (pre + prevs) < idx of
436 | let () # t := set arr idxs prevs t
437 | in assert_total (suffixLoop pre (end - 1) (idx - 1) bs arr t)
439 | let pri # t := dec (cast {to=Int} (minus (length bs) (cast {to=Nat} idx))) pre t
440 | () # t := set arr idxs (idx - pri) t
441 | in assert_total (suffixLoop pri (cast {to=Int} (minus (length bs) 2)) (idx - 1) bs arr t)
443 | noSuffix idx bs arr t
444 | noSuffix : (i : Int)
445 | -> (bs : ByteString)
446 | -> (arr : MArray s (length bs) Int)
450 | noSuffix i bs arr t =
451 | let patati := index (cast {to=Nat} i) bs
454 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.noSuffix: can't index into ByteString") # t
456 | let patatend := index (minus (length bs) 1) bs
457 | in case patatend of
459 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.noSuffix: can't index into ByteString") # t
461 | case patati' == patatend' of
463 | let diff := (cast {to=Int} (minus (length bs) 1)) - i
465 | previ # t := dec diff nexti t
466 | in case tryNatToFin (cast {to=Nat} i) of
468 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.noSuffix: can't convert Nat to Fin") # t
470 | case previ == nexti of
472 | let () # t := set arr i' 1 t
473 | in assert_total (noSuffix nexti bs arr t)
475 | let () # t := set arr i' (i - previ) t
476 | in assert_total (suffixLoop previ (cast {to=Int} (minus (length bs) 2)) nexti bs arr t)
478 | case tryNatToFin (cast {to=Nat} i) of
480 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixLengths.noSuffix: can't convert Nat to Fin") # t
482 | let () # t := set arr i' 0 t
483 | in assert_total (noSuffix (i - 1) bs arr t)
534 | suffixShifts : (bs : ByteString)
535 | -> {0 prf : So (not $
null bs)}
536 | -> F1 s (MArray s (length bs) Int)
537 | suffixShifts bs {prf} t =
538 | let arr # t := marray1 (length bs) (cast {to=Int} (length bs)) t
539 | suff # t := suffixLengths bs {prf=prf} t
540 | () # t := prefixShift (cast {to=Int} (minus (length bs) 2)) 0 bs suff arr t
541 | () # t := suffixShift 0 bs suff arr t
544 | fillToShift : (i : Int)
546 | -> (bs : ByteString)
547 | -> (arr : MArray s (length bs) Int)
549 | fillToShift i shift bs arr t =
554 | case tryNatToFin (cast {to=Nat} i) of
556 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixShifts.fillToShift: can't convert Nat to Fin") # t
558 | let () # t := set arr i' shift t
559 | in assert_total (fillToShift (i + 1) shift bs arr t)
560 | prefixShift : (idx : Int)
562 | -> (bs : ByteString)
563 | -> (suff : MArray s (length bs) Int)
564 | -> (arr : MArray s (length bs) Int)
566 | prefixShift idx j bs suff arr t =
571 | case tryNatToFin (cast {to=Nat} idx) of
573 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixShifts.prefixShift: can't convert Nat to Fin") # t
575 | let idx'' # t := get suff idx' t
576 | in case idx'' == (idx + 1) of
578 | let shift := (cast {to=Int} (minus (length bs) 1)) - idx
579 | () # t := fillToShift j shift bs arr t
580 | in assert_total (prefixShift (idx - 1) shift bs suff arr t)
582 | assert_total (prefixShift (idx - 1) j bs suff arr t)
583 | suffixShift : (idx : Int)
584 | -> (bs : ByteString)
585 | -> (suff : MArray s (length bs) Int)
586 | -> (arr : MArray s (length bs) Int)
588 | suffixShift idx bs suff arr t =
589 | let patend := cast {to=Int} (minus (length bs) 1)
590 | in case idx >= patend of
594 | case tryNatToFin (cast {to=Nat} idx) of
596 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixShifts.suffixShift: can't convert Nat to Fin") # t
598 | let idx'' # t := get suff idx' t
599 | target := patend - idx''
600 | in case tryNatToFin (cast {to=Nat} target) of
602 | (assert_total $
idris_crash "Data.ByteString.Search.Internal.Utils.suffixShifts.suffixShift: can't convert Nat to Fin") # t
604 | let value := patend - idx
605 | () # t := set arr target' value t
606 | in assert_total (suffixShift (idx + 1) bs suff arr t)