I would like to create KMP in prolog and started working like this. Unfortunately, I am unable to create prefix table required for Prolog? Am i doing it right, considering prolog a logical language?
compare(CharAtStartPos,CharAtNextPos,StartPos,NextPos,PrefixList,S,N,P):-
CharAtStartPos=CharAtNextPos,write('Equal'),
N is NextPos+1,
string_chars(N,Element),
write("Element is"), write(Element),
S is StartPos+1,!;
CharAtStartPos\=CharAtNextPos,NextPos\=0,write('Not equal'),
value is NextPos-1,
nth0(value,PrefixList, N),!;
write('Else'),
string_chars(0,Element),
P = Element,write("Element is"),
write(Element),
S is StartPos+1.
loop(CharAtStartPos,CharAtNextPos,StartPos,NextPos,TextLength,PrefixList):-
StartPos<TextLength,
write('Start position is: '),write(StartPos),nl,
compare(CharAtStartPos,CharAtNextPos, StartPos,NextPos,PrefixList,S,N,P),
loop(CharAtStartPos,CharAtNextPos,S,N,TextLength,P),!;
StartPos=TextLength,
write("Loop end"),
write(PrefixList).
createPrefixTable(Text,TextLength, PrefixList):-
getTextAsList(Text,ListText),
getTextLength(Text,TextLength),
StartPos=1,NextPos=0,
nth0(0,ListText,CharAtStartPos), nth0(1,ListText,CharAtNextPos),
write(StartPos),write(NextPos),nl,
write(CharAtStartPos),write(CharAtNextPos),nl,
loop(CharAtStartPos,CharAtNextPos,StartPos, NextPos,TextLength, PrefixList),
write(PrefixList),
write("Finish").
Your use of
;to implement disjunction is not idiomatic, and it is not correct. Even though;exists you should almost always use separate clauses instead. This will make it clearer what's going wrong:The second clause does not bind
PrefixListin any way. A caller will never be able to get information out of this predicate!I think you probably want to add an "accumulator" argument which "builds up" the prefix list over recursive calls. When the recursion stops, the final result should be the accumulator value. Something like this (not tested in any way):
The initial call from "outside" needs to pass a suitable initial accumulator value, something like: