-module(markov).
-export([load/1,make_sentence/1]).
clean_unicode([]) ->
[];
clean_unicode([H|T]) when H >= 127;H < 32 ->
clean_unicode(T);
clean_unicode([H|T]) ->
[H|clean_unicode(T)].
%{key,total,word_list}
load_sentence(MTable,[W1|[]]) ->
W2 = stop,
case ets:lookup(MTable,W1) of
[] -> ets:insert(MTable,{W1,1,dict:update_counter(W2,1,dict:new())});
[{_,Total,NextDict}] ->
ets:insert(MTable,
{W1,Total+1,
dict:update_counter(W2,1,NextDict)})
end;
load_sentence(MTable,[W1,W2|Rest]) ->
case ets:lookup(MTable,W1) of
[] -> ets:insert(MTable,{W1,1,dict:update_counter(W2,1,dict:new())});
[{_,Total,NextDict}] ->
ets:insert(MTable,
{W1,Total+1,
dict:update_counter(W2,1,NextDict)})
end,
load_sentence(MTable,[W2|Rest]).
load_lines(H,MTable,eof) ->
file:close(H),
ok;
load_lines(H,MTable,Sentence) ->
load_sentence(MTable,[start|string:tokens(clean_unicode(Sentence)," \r\n")]),
load_lines(H,MTable,io:get_line(H,'')).
load(FileName) ->
MTable = ets:new(markov,[set]),
{ok,H} = file:open(FileName,read),
load_lines(H,MTable,io:get_line(H,'')),
MTable
.
walk_next([{Key,Value}|[]],_,_) ->
Key
;
walk_next([{Key,Value}|Rest],Height,Sum) when Height =< Sum ->
Keymarkov:make_sentence(M).
;
walk_next([{Key,Value}|Rest],Height,Sum)->
%io:format("~s ~w ~n", [Key,Value]),
walk_next(Rest,Height,Sum+Value)
.
make_sentence(MTable,Seed) ->
[{_,Total,NextDict}] = ets:lookup(MTable,Seed),
Height = random:uniform(Total)-1,
case walk_next(dict:to_list(NextDict),Height,0) of
stop -> " ";
NextSeed -> NextSeed ++ " " ++ make_sentence(MTable,NextSeed)
end
.
make_sentence(MTable) ->
try
make_sentence(MTable,start)
catch
error:X -> error
end.