Делаете strIndex в быстром поиске?

Я работаю над версией алгоритма быстрого поиска строки в Idris и придумала это:

quickSearch : (needle       : String) ->
              (haystack     : String) ->
              {auto lengths : (length needle) `LTE` (length haystack)} ->
              Maybe Nat
quickSearch needle haystack = let n = length needle in
                              let h = length haystack in
                                  go (makeBadShift needle) n (h - n)
  where
    go : (badShift : CharShift) ->
         (n        : Nat) ->
         (last     : Nat) ->
         Maybe Nat
    go badShift n last = go' 0
      where
        go' : Nat -> Maybe Nat
        go' i = if i > last then Nothing
                else if (substr i n haystack) == needle then Just i
                else if i == last then Nothing
                else let ch = strIndex haystack (cast (n + i)) in
                     let shift = lookupChar badShift ch in
                         go' (i + shift)

(lookupChar и makeBadShift находятся в другом месте.)

Это прекрасно работает, но я хотел сделать это более формально правильным. Начнем с того, что он не тотален из-за использования strIndex. Нетрудно создать полную версию strIndex (либо через List Char, либо через это:)

strIndex' : (str : String) ->
            (n : Nat) ->
            {auto ok : (n `LT` (Strings.length str))} ->
            Char
strIndex' str n = assert_total $ prim__strIndex str (cast n)

но тогда у меня должен быть способ доказать, что (n + i) меньше h. (Это потому, что в этот момент я <ч - п.)

Если я напрямую заменю ">" и "==" их двоюродными братьями, имеющими доказательство, я в конечном итоге смотрю на отрицания:

iNEQlast : (i = last) -> Void

а также

iNGTlast : (S last) `LTE` i -> Void

что оставило меня в тупике.

С другой стороны, я могу отменить условия, в конечном итоге с

"quicksearch.idr" 115L, 4588C written
  needle : String
  haystack : String
  lengths : LTE (fromIntegerNat (prim__zextInt_BigInt (prim_lenString needle))) (fromIntegerNat (prim__zextInt_BigInt (prim_lenString haystack)))
  badShift : CharShift
  n : Nat
  h : Nat
  nh : LTE n h
  i : Nat
  iLTlast : LTE (S i) (minus h n)
  iLTElast : LTE i (minus h n)
--------------------------------------
go'_rhs_1 : Maybe Nat

но в этот момент я полностью сбит с толку и не знаю, как двигаться дальше.

Что лучше всего делать сейчас?

0 ответов

Другие вопросы по тегам