Presentation on theme: "”assert” and ”retract” A Simple Chatbot Modifying Programs Dynamically Prolog’s Execution Tree."— Presentation transcript:
”assert” and ”retract” A Simple Chatbot Modifying Programs Dynamically Prolog’s Execution Tree
A Simple Chatbot – only producing random responses chatbot:- print_welcome, conversations. conversations:- repeat, % prolog built-in print_prompt(you), readin(S), % defined in file % readin.pl gen_reply(S,R), print_prompt(me), write_list(R), is_quit(S). is_quit(S):- member(bye, S). gen_reply(S, R):- % totally random respones_db(random, Res), % create a random number length(Res, Length), Upper is Length+1, random(1, Upper, Rand), nth_item(Res, Rand, R). respones_db(random, [ [hello, '!'], [hi, there, '.', this, is, not, a, hello_world, program, '!'], [it, is, a, nice, day, '.'], [have, you, talked, to, me, before, '?'], ['.', '.', '.', what, do, you, mean, '?'] ]).
| ?- chat. Welcome! I am a chatbot Please finish your line with a full stop, ?, or ! user Hi. bot1 : hello ! user |: what is your name? bot1 : have you talked to me before ? user |: no, I don't think so. bot1 : hi there. this is not a hello_world program ! user |: cool. bot1 : sorry, i am only a single minded chatbot. user |: ok, i don't mind. bot1 :... what do you mean ? user |: I mean I like you. (cont.) | bot1 : sorry i cannot remember everything you said. user |: ok. bot1 : sorry, i am only a single minded chatbot. user |: you said that. bot1 : sorry i cannot remember everything you said. user |: no problem. bot1 : oh ok user |: good. bot1 : can you say it again ? user |: good!!!! bot1 : have you talked to me before ? user |: getting boring now, bye. bot1 : bye !
A simple way to link chatbot to ‘cango’ program In get_reply(S,R) check if S has a pattern ‘to... from...’ if yes, call your ‘cango’, then generate the reply. pattern_tofm([to, X, from, Y|_], X, Y). % yes! pattern_tofm([_|T], X, Y):- % carry on checking pattern_tofm(T, X, Y).
Built-ins to Modify Prolog Programs The following built-ins allow modification of the loaded program as it is actually running. assert(C) - adds a prolog code (clause) C to program asserta(C) - C is added to front assertz(C) = assert(C) - C is added to end They always succeed. retract(C) - deletes a prolog code that matches C It fails if there is nothing to delete
Examples of using assert/retract ?-nice. ?-disgusting. ?-retract(fog). ?-disgusting. ?-assert(sunshine). ?-funny. ?-retract(raining). ?-nice. nice:- sunshine, \+ raining. % “\+ “ means not funny:- sunshine, raining. disgusting:- raining, fog. raining. fog.
Examples of using assert/retract Fibonacci numbers: 1,1,2,3,5,8,13,21,34,… fib(N,F) - F is the N'th Fibonacci number. fib(1,1). fib(2,1). fib(N,F) :- N > 2, N1 is N-1, N2 is N-2, fib(N1,F1), fib(N2,F2), F is F1 + F2.
Execution Tree to Compute fib(5,F) fib(5, F) fib(4, F1)fib(3, F2) F is F1+F2 fib(3, F1’) fib(2,F2’) F’ is F1’+F2’ fib(2, F1’’) fib(1,F2’’) F’’ is F1’’+F2’’
To improve the above program, we can use “assert” to save intermediate results :- dynamic myfib/2. myfib(1,1). myfib(2,1). myfib(N,F) :- N > 2, N1 is N-1, N2 is N-2, myfib(N1,F1), myfib(N2,F2), F is F1 + F2, % remember n-th Fibonacci number asserta( myfib(N,F) ).
assert/retract plays two roles Adding new information to the database (ref. previous examples) We will use this in our chatbot for collecting user’s information Communicating between or-branches An example:?- binary(X),binary(Y). binary(0). binary(1).
the following program collects a list of boy names :- dynamic tmp/1. find_all_boy_names(NameList):- % initialise the name list as an empty list assert(tmp()), boy_names(X, _, _), % return solution one by one retract(tmp(CurrentList)), assert(tmp([X|CurrentList])), % add new solution fail. find_all_boy_names(NameList):- retract(tmp(NameList)).
How to use “findall” Prolog has provided a built-in predicate findall(Vars, Goal, S) which collects all solutions of Goal into S. Here is an example: test(X,Y, AllRoutes):- findall( P, cango3(X,Y,P), AllRoutes). This returns AllRoutes = [path1,path2,…] where each path i is a solution
Back to chatbot If you want to remember some lines from user, you can have the following initially respones_db(echo, ). In the program, after reading a sentence S from user, you can do retract(respones_db(echo, CurrentList)), assert(respones(echo,([S|CurrentList])), If your user says, I am from London,.... assert(user_info(from, london)),