assert and retract v A Simple Chatbot v
”assert” and ”retract” v A Simple Chatbot v Modifying Programs Dynamically v Prolog’s Execution Tree
A Simple Chatbot – only producing random responses chatbot: print_welcome, 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): - 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, 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. bot 1 : hello ! user |: what is your name? bot 1 : have you talked to me before ? user |: no, I don't think so. bot 1 : hi there. this is not a hello_world program ! user |: cool. bot 1 : sorry , i am only a single minded chatbot. user |: ok, i don't mind. bot 1 : . . . what do you mean ? user |: I mean I like you. (cont. ) | bot 1 : sorry i cannot remember everything you said. user |: ok. bot 1 : sorry , i am only a single minded chatbot. user |: you said that. bot 1 : sorry i cannot remember everything you said. user |: no problem. bot 1 : oh. . . ok user |: good. bot 1 : can you say it again ? user |: good!!!! bot 1 : have you talked to me before ? user |: getting boring now, bye. bot 1 : 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, N 1 is N-1, N 2 is N-2, fib(N 1, F 1), fib(N 2, F 2), F is F 1 + F 2.
Execution Tree to Compute fib(5, F) fib(4, F 1) fib(3, F 1’) fib(2, F 2’) fib(2, F 1’’) fib(1, F 2’’) fib(3, F 2) F’ is F 1’+F 2’ F’’ is F 1’’+F 2’’ F is F 1+F 2
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, N 1 is N-1, N 2 is N-2, myfib(N 1, F 1), myfib(N 2, F 2), F is F 1 + F 2, % 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(Name. List): % initialise the name list as an empty list assert(tmp([])), boy_names(X, _, _), % return solution one by one retract(tmp(Current. List)), assert(tmp([X|Current. List])), % add new solution fail. find_all_boy_names(Name. List): - retract(tmp(Name. List)).
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, All. Routes): findall( P, cango 3(X, Y, P), All. Routes). This returns All. Routes = [path 1, path 2, …] where each pathi 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, Current. List)), assert(respones(echo, ([S|Current. List])), • If your user says, I am from London, . . assert(user_info(from, london)),
- Slides: 13