1 | module Data.ByteString.Search.DFA
3 | import Data.Array.Core
4 | import Data.Array.Mutable
6 | import Data.ByteString
7 | import Data.ByteString.Search.DFA.Internal
8 | import Data.ByteString.Search.DFA.Types
10 | import Data.Linear.Ref1
13 | %hide Data.Buffer.Core.get
14 | %hide Data.Buffer.Core.set
43 | -> F1 s (Maybe (List Nat))
44 | matcher overlap pat target t =
45 | let patlen := length pat
46 | targetlen := length target
47 | False := patlen == S Z
49 | let Just patzero := index Z pat
52 | Just headelem := elemIndex patzero target
55 | in Just (headelem :: []) # t
56 | Just patzero := index Z pat
59 | dfa # t := automaton pat t
63 | MkDFAutomaton stspace table := dfa'
64 | Just stateone := tryIndex {r = stspace.states} 1
67 | result # t := matchZero stspace Z Lin patlen targetlen patzero table stateone t
68 | Just result' := result
71 | in Just (result' <>> []) # t
85 | matchZero : (stspace : DFAStateSpace)
87 | -> (final : SnocList Nat)
89 | -> (targetlen : Nat)
90 | -> (patzero : Bits8)
91 | -> (dfa : DFATable s stspace.states)
92 | -> (stateone : DFAState stspace.states)
93 | -> F1 s (Maybe (SnocList Nat))
94 | matchZero stspace idx final patlen targetlen patzero dfa stateone t =
95 | let False := idx == targetlen
98 | Just byte := index idx target
102 | False := byte == patzero
104 | assert_total (matchState stspace stateone nxtidx final patlen targetlen patzero dfa stateone t)
105 | in assert_total (matchZero stspace nxtidx final patlen targetlen patzero dfa stateone t)
124 | matchState : (stspace : DFAStateSpace)
125 | -> (state : DFAState stspace.states)
127 | -> (final : SnocList Nat)
129 | -> (targetlen : Nat)
130 | -> (patzero : Bits8)
131 | -> (dfa : DFATable s stspace.states)
132 | -> (stateone : DFAState stspace.states)
133 | -> F1 s (Maybe (SnocList Nat))
134 | matchState stspace state idx final patlen targetlen patzero dfa stateone t =
135 | let False := idx == targetlen
138 | Just byte := index idx target
143 | {statesPrf = stspace.statesBounded}
149 | dfaStateValue nstate
152 | False := nstateval == cast {to=Bits32} patlen
155 | minus nxtidx patlen
160 | assert_total (matchZero stspace (S matchidx) final' patlen targetlen patzero dfa stateone t)
161 | in assert_total (matchZero stspace nxtidx final' patlen targetlen patzero dfa stateone t)
162 | False := nstateval == 0
164 | assert_total (matchZero stspace nxtidx final patlen targetlen patzero dfa stateone t)
165 | in assert_total (matchState stspace nstate nxtidx final patlen targetlen patzero dfa stateone t)
193 | matchDFA : (pat : ByteString)
194 | -> (target : ByteString)
195 | -> {0 prfpat : So (not $
null pat)}
196 | -> {0 prftarget : So (not $
null target)}
197 | -> F1 s (Maybe (List Nat))
198 | matchDFA pat target {prfpat} {prftarget} t =
199 | let matcher' # t := matcher False pat target t
200 | Just matcher'' := matcher'
203 | in Just matcher'' # t
228 | indicesDFA : (pat : ByteString)
229 | -> (target : ByteString)
230 | -> {0 prfpat : So (not $
null pat)}
231 | -> {0 prftarget : So (not $
null target)}
232 | -> F1 s (Maybe (List Nat))
233 | indicesDFA pat target {prfpat} {prftarget} t =
234 | let matcher' # t := matcher True pat target t
235 | Just matcher'' := matcher'
238 | in Just matcher'' # t
252 | breakDFA : (pat : ByteString)
253 | -> (target : ByteString)
254 | -> {0 prfpat : So (not $
null pat)}
255 | -> {0 prftarget : So (not $
null target)}
256 | -> {0 prflength : So ((length target) >= (length pat))}
257 | -> F1 s (Maybe (ByteString, ByteString))
258 | breakDFA pat target {prfpat} {prftarget} {prflength} t =
259 | let matcher' # t := matcher False pat target t
260 | Just matcher'' := matcher'
263 | (i :: _) := matcher''
265 | Just (target, empty) # t
266 | target' := splitAt (cast {to=Nat} i) target
267 | Just target'' := target'
270 | in Just target'' # t
285 | breakAfterDFA : (pat : ByteString)
286 | -> (target : ByteString)
287 | -> {0 prfpat : So (not $
null pat)}
288 | -> {0 prftarget : So (not $
null target)}
289 | -> {0 prflength : So ((length target) >= (length pat))}
290 | -> F1 s (Maybe (ByteString, ByteString))
291 | breakAfterDFA pat target {prfpat} {prftarget} {prflength} t =
292 | let matcher' # t := matcher False pat target t
293 | Just matcher'' := matcher'
296 | (i :: _) := matcher''
298 | Just (target, empty) # t
299 | target' := splitAt (plus (cast {to=Nat} i) (length pat)) target
300 | Just target'' := target'
303 | in Just target'' # t
320 | splitKeepFrontDFA : (pat : ByteString)
321 | -> (target : ByteString)
322 | -> {0 prfpat : So (not $
null pat)}
323 | -> {0 prftarget : So (not $
null target)}
324 | -> {0 prflength : So ((length target) >= (length pat))}
325 | -> F1 s (Maybe (List ByteString))
326 | splitKeepFrontDFA pat target {prfpat} {prftarget} {prflength} t =
327 | let splitter' # t := splitter pat target Lin t
328 | Just splitter'' := splitter'
331 | in Just (splitter'' <>> []) # t
333 | psSplitter : (pat : ByteString)
334 | -> (target : ByteString)
335 | -> (final : SnocList ByteString)
336 | -> F1 s (Maybe (SnocList ByteString))
337 | psSplitter pat target final t =
338 | let matcher' # t := matcher False pat (drop (length pat) target) t
339 | Just matcher'' := matcher'
342 | (i :: _) := matcher''
344 | let final' := final :< target
346 | length' := plus (cast {to=Nat} i) (length pat)
347 | final' := final :< (take length' target)
348 | in assert_total (psSplitter pat (drop length' target) final' t)
349 | splitter : (pat : ByteString)
350 | -> (target : ByteString)
351 | -> (final : SnocList ByteString)
352 | -> F1 s (Maybe (SnocList ByteString))
353 | splitter pat target final t =
354 | let matcher' # t := matcher False pat target t
355 | Just matcher'' := matcher'
358 | (i :: _) := matcher''
360 | let final' := final :< target
364 | assert_total (psSplitter pat target final t)
365 | final' := final :< (take (cast {to=Nat} i) target)
366 | in assert_total (psSplitter pat (drop (cast {to=Nat} i) target) final' t)
389 | splitKeepEndDFA : (pat : ByteString)
390 | -> (target : ByteString)
391 | -> {0 prfpat : So (not $
null pat)}
392 | -> {0 prftarget : So (not $
null target)}
393 | -> {0 prflength : So ((length target) >= (length pat))}
394 | -> F1 s (Maybe (List ByteString))
395 | splitKeepEndDFA pat target {prfpat} {prftarget} {prflength} t =
396 | let splitter' # t := splitter pat target Lin t
397 | Just splitter'' := splitter'
400 | in Just (splitter'' <>> []) # t
402 | splitter : (pat : ByteString)
403 | -> (target : ByteString)
404 | -> (final : SnocList ByteString)
405 | -> F1 s (Maybe (SnocList ByteString))
406 | splitter pat target final t =
407 | let matcher' # t := matcher False pat target t
408 | Just matcher'' := matcher'
411 | (i :: _) := matcher''
413 | let final' := final :< target
415 | length' := plus (cast {to=Nat} i) (length pat)
416 | final' := final :< (take length' target)
417 | in assert_total (splitter pat (drop length' target) final' t)
442 | splitDropDFA : (pat : ByteString)
443 | -> (target : ByteString)
444 | -> {0 prfpat : So (not $
null pat)}
445 | -> {0 prftarget : So (not $
null target)}
446 | -> {0 prflength : So ((length target) >= (length pat))}
447 | -> F1 s (Maybe (List ByteString))
448 | splitDropDFA pat target {prfpat} {prftarget} {prflength} t =
449 | let splitter' # t := splitter pat target Lin t
450 | Just splitter'' := splitter'
453 | in Just (splitter'' <>> []) # t
455 | splitter : (pat : ByteString)
456 | -> (target : ByteString)
457 | -> (final : SnocList ByteString)
458 | -> F1 s (Maybe (SnocList ByteString))
459 | splitter pat target final t =
460 | let matcher' # t := matcher False pat target t
461 | Just matcher'' := matcher'
464 | (i :: _) := matcher''
466 | let final' := final :< target
468 | length' := plus (cast {to=Nat} i) (length pat)
469 | final' := final :< (take (cast {to=Nat} i) target)
470 | in assert_total (splitter pat (drop length' target) final' t)
493 | replaceDFA : (pat : ByteString)
494 | -> (sub : ByteString)
495 | -> (target : ByteString)
496 | -> {0 prfpat : So (not $
null pat)}
497 | -> {0 prftarget : So (not $
null target)}
498 | -> {0 prflength : So ((length target) >= (length pat))}
499 | -> F1 s (Maybe (List ByteString))
500 | replaceDFA pat sub target {prfpat} {prftarget} {prflength} t =
501 | let replacer' # t := replacer pat sub target Lin t
502 | Just replacer'' := replacer'
505 | in Just (replacer'' <>> []) # t
507 | replacer : (pat : ByteString)
508 | -> (sub : ByteString)
509 | -> (target : ByteString)
510 | -> (final : SnocList ByteString)
511 | -> F1 s (Maybe (SnocList ByteString))
512 | replacer pat sub target final t =
513 | let matcher' # t := matcher False pat target t
514 | Just matcher'' := matcher'
517 | (i :: _) := matcher''
519 | let final' := final :< target
523 | let False := null sub
525 | let length' := plus (cast {to=Nat} i) (length pat)
526 | final' := final :< (take (cast {to=Nat} i) target)
527 | in assert_total (replacer pat sub (drop length' target) final' t)
528 | length' := plus (cast {to=Nat} i) (length pat)
529 | final' := final :< (take (cast {to=Nat} i) target) :< sub
530 | in assert_total (replacer pat sub (drop length' target) final' t)
533 | assert_total (replacer pat sub (drop (length pat) target) final t)
534 | final' := final :< sub
535 | in assert_total (replacer pat sub (drop (length pat) target) final') t