Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Editing Eliza chatbot in Prolog

Tags:

prolog

I've been struggling trying to edit Eliza chatbot in Prolog. every time I try to edit something, a new error show up. Is it protected to any sort of editing?

I edited using SWI-prolog editor. The problem is that I'm trying to minimize the code without fully understanding it. I'm trying to do a simple short version of it. So, I might removed something essential perhaps! like "my_char_type" for example. The error I got is " retract/1: No permission to modify static procedure `rules/1'"

Is there any code for a smaller chatbot that I can understand?

Please help :'(

like image 452
D.X Avatar asked Oct 20 '22 00:10

D.X


2 Answers

Prolog has a static store and a dynamic store. If you open up a file, say program.pl and you put some lines in it like this:

foo(tabitha).
foo(darlene).

those facts wind up in the static store. They're not a mutable part of your program (by default).

The asserta/1, assertz/1 and retract/1 and retractall/1 procedures form the basis of the dynamic store. If you are just sitting at the console you could just add some facts to the dynamic store and remove them by doing something like this:

?- asserta(baz(tabitha)).
true.

?- baz(X).
X = tabitha.

?- retract(baz(tabitha)).
true.

?- baz(X).
false.

However, if you are sitting at the prompt after loading program.pl and you try to retract foo(tabitha) you're going to get the static procedure message:

?- retract(foo(tabitha)).
ERROR: retract/1: No permission to modify static procedure `foo/1'
ERROR: Defined at /Users/fusion/program.pl:1

The reason is because the foo/1 facts were placed in the static store rather than the dynamic store, because you didn't put them there with asserta/1 or assertz/1 or declare the predicate as dynamic, like this:

:- dynamic foo/1.

So there are two ways forward:

  1. Edit the program source directly and reload it.
  2. Declare the rules/1 predicate dynamic as above.

Incidentally, reloading in SWI-Prolog is best done by running make. from the prompt.

I would recommend option #1 since otherwise it will be difficult to reconstruct your working program's state when you like what it is doing.

like image 187
Daniel Lyons Avatar answered Oct 21 '22 22:10

Daniel Lyons


SWISH has the simplest Eliza ever, I have the old code below, used to test my Prolog interpreter.

here is an example session

1 ?- eliza.
? i am hungry
how long have you been hungry ? 
? very long
please go on 
? bye
Goodbye. I hope I have helped you
true.

SWI-Prolog tested version, ported from below ELIZA.IL (alas, SWISH is apparently missing IO primitive like read_line_from_codes, so it's simpler to paste the full code)

eliza :-
    write('? '), read_word_list(Input), eliza(Input), !.

eliza([bye]) :-
    write('Goodbye. I hope I have helped you'), nl.
eliza(Input) :-
    pattern(Stimulus, Response),
    match(Stimulus, Dictionary, Input),
    match(Response, Dictionary, Output),
    reply(Output),
    !, eliza.

match([N|Pattern], Dictionary, Target) :-
    integer(N), lookup(N, Dictionary, LeftTarget),
    append(LeftTarget, RightTarget, Target),
    match(Pattern, Dictionary, RightTarget).
match([Word | Pattern], Dictionary, [Word | Target]) :-
    atom(Word), match(Pattern, Dictionary, Target).
match([], _Dictionary, []).

pattern([i,am,1],[how,long,have,you,been,1,'?']).
pattern([1,you,2,me],[what,makes,you,think,i,2,you,'?']).
pattern([i,like,1],[does,anyone,else,in,your,family,like,1,'?']).
pattern([i,feel,1],[do,you,often,feel,that,way,'?']).
pattern([1,X,2],[can,you,tell,me,more,about,your,X,'?']) :- important(X).
pattern([1],[please,go,on]).

important(father).
important(mother).
important(son).
important(sister).
important(brother).
important(daughter).

reply([Head | Tail]) :-
    write(Head), write(' '), reply(Tail).
reply([]) :- nl.

lookup(Key, [(Key, Value) | _Dict], Value).
lookup(Key, [(Key1, _Val1) | Dictionary], Value) :-
    Key \= Key1, lookup(Key, Dictionary, Value).

read_word_list(Ws) :-
    read_line_to_codes(user_input, Cs),
    atom_codes(A, Cs),
    tokenize_atom(A, Ws).

Older code: eliza and rwl

like image 26
CapelliC Avatar answered Oct 21 '22 23:10

CapelliC