I am trying to implement the KMP algorithm in Dafny according to CLRS [sec. 32.4], and I am having trouble implementing the *[q]:
function FuncStarIter(func: seq<nat>, q: nat, count: nat): nat
requires 0 <= q < |func|
requires forall i :: 0 <= i < |func| ==> 0 <= func[i] < |func|
ensures count != 0 && func[q] != 0 ==> 0 <= FuncStarIter(func, q, count-1) - 1 <= |func|
{
if count == 0 then q else
if func[q] == 0 then func[q] else
func[FuncStarIter(func, q, count-1) - 1]
}
function FuncStar(func: seq<nat>, q: nat) : set<nat>
requires q < |func|
requires forall i :: 0 <= i < |func| ==> 0 <= func[i] < |func|
{
set count | 1 <= count <= |func| :: FuncStarIter(func, q, count)
}
The ensures count != 0 ==> 0 <= FuncStarIter(func, q, count-1) - 1 <= |func| is to make sure that FuncStarIter(func, q, count-1) - 1 is a valid index for func, however I get Error: index out of range.
Alternatively, Is there a way to prove claims in a function?
So, you have an off by one error here. Specifically, you are using
FuncStarIter(func, q, count-1) - 1 <= |func|to showFuncStarIter(func, q, count-1) - 1is a valid index. But, in Dafny, a valid indeximust be0 <= i < |arr|for some arrayarr.Anyway, without knowing more about the algorithm, I can't exactly say what the right fix is. However, this version verifies and looks roughly like what you are after: