gprolog expert system - issues reading user input - prolog

I'm working through this prolog expert system example that accepts user input. I am having issues with the way user_input is read. I am using gprolog.
animal(dog) :-
is_true('has fur'),
is_true('says woof').
animal(cat) :-
is_true('has fur'),
is_true('says meow').
animal(duck) :-
is_true('has feathers'),
is_true('says quack').
is_true(Question) :-
write('Does the animal have the following attribute: '),
write(Question), write('? '),
read_string(user_input,"\n","\r",End,Response), Response == "yes". /*this line*/
go:-
animal(Animal),
write('I guess that the animal is: '),
write(Animal).
go:-
write('I cannot recognize your animal').
I am getting:
uncaught exception: error(existence_error(procedure,read_string/5),is_true/1)
It's the same error if I try:
read_string(user_input,"\n","\r",_,Response), Response == "yes".

Related

how do I solve an error in asking question in prolog?

I am fairly familiar in Prolog language. was writing a DSS in prolog and I encountered the error
pl:96:12: syntax error: . or operator expected after expression
1 error(s)
personally I don't see where the error is
here is a part of the code where the compiler is indicating the error
ask(Question) :-
write('Do you have ?:'),
write(Question),
write('?,y/n '),
read(Response), nl,
( (Response == yes ; Response == no)
->
assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.

How to delete entry from rdf file in prolog

I want to write a program in Prolog where a menu is given to the users. They choose to either add data, see existing data based on surname or age, or/and delete data based on surname or age. I don't know how to delete an entry based on age or surname. Here is what I've written. Can anyone tell me what I do wrong? Thank you.
:- use_module(library(semweb/rdf_db)).
:- use_module(library(semweb/rdf_http_plugin)).
:- use_module(library(semweb/turtle)).
:- dynamic id/1.
id(1).
run :- nl,
write('Option 1: Load new path'),nl,
write('Option 2: Create new user'),nl,
write('Option 3: Display data based on Surname'),nl,
write('Option 4: Display data based on Age'),nl,
write('Option 5: Delete data based on Surname'),nl,
write('Option 6: Delete data based on Age'),nl,
write('Option 7: Exit'),nl, %It saves the program before exiting
write('Option(1-7): '), read(X), nl,
( shouldExit(X)
; (option(X), run)
; (nl, write('Invalid option.'), nl, run)
).
shouldExit(7) :- save.
option(1) :- write('Give path for rdf file'), read(Path), doOpen(Path).
option(2) :- doRead.
option(3) :- write('Surname: '), read(Surname), findS(Surname).
option(4) :- write('Age: '), read(Age), findA(Age).
option(5) :- write('Surname: '), read(Surname), delS(Surname).
option(6) :- write('Age: '), read(Age), delA(Age).
/*Enter new user*/
doRead :- rdf_register_prefix(foaf,'http://xmlns.com/foaf/0.1/'),
write('Surname:'), read(Surname),
write('First Name:'), read(FirstName),
write('Age:'), read(Age),
id(N),
New is N+1,
retract(id(N)),
asserta(id(New)),
atom_concat('foaf:person', N, Person),
rdf_assert(Person, rdf:type, foaf:'Person'),
rdf_assert(Person, foaf:surname, literal(Surname)),
rdf_assert(Person, foaf:firstName, literal(FirstName)),
rdf_assert(Person, foaf:age, literal(Age)).
/*Display data based on Surname*/
findS(Surname) :- rdf(X, foaf:surname, literal(Surname)),
rdf(X, foaf:firstName, literal(FirstName)),
rdf(X, foaf:age, literal(Age)),
write('Found '), write(FirstName), write(' '),
write(Surname), write(', '), write(Age), nl, fail.
/*Display data based on Age*/
findA(Age) :- rdf(X, foaf:surname, literal(Surname)),
rdf(X, foaf:firstName, literal(FirstName)),
rdf(X, foaf:age, literal(Age)),
write('Found '), write(FirstName), write(' '),
write(Surname), write(', '), write(Age), nl, fail.
/*Loads the file from the path the user asks ''*/
doOpen(Path) :- rdf_load(Path).
/*Saves the changes before exiting*/
save :- rdf_save(Path, [foaf]).
/*Deletes user based on their surname*/
/*delS(Surname) :- .*/
/*Deletes user based on their age*/
delA(Age) :- rdf(X, foaf:surname, literal(Surname)),
rdf(X, foaf:firstName, literal(FirstName)),
rdf(X, foaf:age, literal(Age)),
retract(rdf(Surname, FirstName, Age)).
I don't know it, so this is a guess, but you are using:
retract(rdf(Surname, FirstName, Age)).
and that is Prolog retract/1, I think you need rdf_retractall instead.

New to Prolog - procedure `temp(A)' does not exist Reachable from: weather(A) go

I've typed out code from a textbook and don't understand where the error lies. It seems to be at weather(Weather),
The error is:
procedure `temp(A)' does not exist
Reachable from:
weather(A)
go
/* Weather knowledge base */
weather(good):-
temp(high),
humidity(dry),
sky(sunny).
weather(bad):-
(humidity(wet);
temp(low);
sky(cloudy)).
/* interface */
go:-
write('Is the temperature high or low? '),
read(Temp), nl,
write('Is the sky sunny or cloudy? '),
read(Sky), nl,
write('Is the humidity dry or wet? '),
read(Humidity), nl,
assert(temp(Temp)),
assert(sky(Sky)),
assert(humidity(Humidity)),
weather(Weather),
write('The weather is '), write(Weather),
retractall(temp( __ )),
retractall(sky( __ ) ),
retractall(humidity( _) ).
If you are using SWI-Prolog, you should declare temp/1, humidity/1, and sky/1 as dynamic, by inserting these three lines in your code.
:- dynamic temp/1.
:- dynamic humidity/1.
:- dynamic sky/1.
Moreover, if your run your program you get a warning: Singleton-marked variable appears more than once: __.
You should replace __ with _ in your code to avoid this.

How to allow program to proceed?

How to make the program proceed to menu1/0 after false appear
mylist([a,b,c]).
myprog(X) :- mylist(L), member(X, L).
go :- start_message,menu1.
start_message :-
write('This is a program.'),nl,
write('Below are a list:'),nl,
myprog(X),
write(X),nl,
fail.
menu1 :-
nl,write('Select operation:'),nl,
write('1. Input time'),nl,
write('2. Exit program'),nl.
Below is what I am stuck with:
go.
This is a program.
Below are a list:
a
b
c
false
You can do like this
start_message :-
write('This is a program.'),nl,
write('Below are a list:'),nl,
( myprog(X),
write(X),nl,
fail
; true ).
Now when myprog/1 cannot succeed anymore, control goes to true/0 and start_message/0 succeeds.
Remove the fail statement in the last line of start_message.

error message, not working properly - prolog

How to repair a program to be ready to be used with SWI Prolog?
Link to source: http://ai-programming.com/prolog_bot_tutorial.htm
chatterbot2:
I modified read_string and write_string to read and write:
knowledge_base([
['WHAT IS YOUR NAME',
['MY NAME IS CHATTERBOT2.',
'YOU CAN CALL ME CHATTERBOT2.',
'WHY DO YOU WANT TO KNOW MY NAME?']
],
['HI',
['HI THERE!',
'HOW ARE YOU?',
'HI!']
],
['HOW ARE YOU',
['I''M DOING FINE!',
'I''M DOING WELL AND YOU?',
'WHY DO YOU WANT TO KNOW HOW AM I DOING?']
],
['WHO ARE YOU',
['I''M AN A.I PROGRAM.',
'I THINK THAT YOU KNOW WHO I''M.',
'WHY ARE YOU ASKING?']
],
['ARE YOU INTELLIGENT',
['YES,OFCORSE.',
'WHAT DO YOU THINK?',
'ACTUALY,I''M VERY INTELLIGENT!']
],
['ARE YOU REAL',
['DOES THAT QUESTION REALLY MATERS TO YOU?',
'WHAT DO YOU MEAN BY THAT?',
'I''M AS REAL AS I CAN BE.']
] ]).
select(0, [H|_], H).
select(N, [_|T], L) :- N > 0, N1 is N - 1, select(N1, T, L).
list_length([], 0).
list_length([_|T], Length):- list_length(T, Length2), Length is Length2 + 1.
quit_session(X):- X = bye,
nl, write('IT WAS NICE TALKING TO YOU USER, SEE YOU NEXT TIME!').
no_response_found(ListOfResponse):-
list_length(ListOfResponse, NumOfResponse),
NumOfResponse == 0,
write('I''M NOT SURE IF I UNDERSTAND WHAT YOU ARE TALKING ABOUT.'), !.
no_response_found(_).
get_keyword(KeyList, [KeyList,_]).
get_response(RespList, [_, RespList]).
select_response(RespList, Response):-
list_length(RespList, NumOfResponse),
IndexOfResponse is integer(random(NumOfResponse)),
select(IndexOfResponse, RespList, Response), !.
select_response(_, _).
find_match(Input, [FirstRecord|RestDatabase], ListOfResponse):-
get_keyword(Keyword, FirstRecord),
Keyword == Input, get_response(ListOfResponse, FirstRecord), !;
find_match(Input, RestDatabase, ListOfResponse).
find_match(_, [_], _).
chatterbot2:-
repeat,
nl, write('>'),
read(Input),
knowledge_base(ListOfRecord),
find_match(Input, ListOfRecord, ListOfResponse),
no_response_found(ListOfResponse),
select_response(ListOfResponse, Response),
write(Response), nl,
quit_session(Input).
When I try to use it I get:
鐀1 ?- chatterbot2.
>hi.
I'M NOT SURE IF I UNDERSTAND WHAT YOU ARE TALKING ABOUT.
ERROR: random/1: Domain error: `not_less_than_one' expected, found `0'
Exception: (7) select_response([], _G492) ? creep
2 ?- chatterbot2.
>'What do you do ?'.
I'M NOT SURE IF I UNDERSTAND WHAT YOU ARE TALKING ABOUT.
ERROR: random/1: Domain error: `not_less_than_one' expected, found `0'
Exception: (7) select_response([], _G485) ? creep
3 ?- chatterbot2.
>'Dog is black'.
I'M NOT SURE IF I UNDERSTAND WHAT YOU ARE TALKING ABOUT.
ERROR: random/1: Domain error: `not_less_than_one' expected, found `0'
Exception: (7) select_response([], _G485) ? creep
4 ?-
EDIT:
With random value =/= 0 :
1 ?- chatterbot2.
>'NOT IN BASE'.
I'M NOT SURE WHAT ARE YOU TALKING ABOUT._G907
is it possible to delete that value of blank arguement _G907 ?> and become only sentence?
Your errors in this particular example are caused by your input. Your input is matched to the first entries in your knowledge_base. Since none of your inputs match, the list that is returned has length 0, causing a problem with the call to random, which seems to need a value of at least 1.
Try 'WHAT IS YOUR NAME' as input for example and see if that works.

Resources