Creating a Knowledge Base and Querying in Prolog - prolog

I want to create the Knowledge base equivalent to the statements as below in Prolog.
John likes all kind of food.
Apple and vegetable are food
Anything anyone eats and not killed is food.
Anil eats peanuts and still alive
Harry eats everything that Anil eats.
So this one of the version borrowed from here
Once this file is created I want to find the answer for the query "John likes peanuts." saying likes(john, peanut).
Attempt to write rules in Prolog from my side is as below
alive(anil).
eats(anil,peanut).
food(apple).
food(vegitables).
food(X):-likes(john,X).
eats(X,Y),not(killed(X)):-food(Y).
eats(anil,X):-eats(harry,X).
killed(X):-not(alive(X)).
alive(X):-not(killed(X)).
But I am getting the errors and warnings as below;
ERROR: No permission to modify static procedure `(',')/2'
Warning: Clauses of eats/2 are not together in the source-file
Warning: Current predicate: food/1
Warning: Use ':- discontiguous eats/2.' to suppress this message
Warning: Clauses of alive/1 are not together in the source-file
Warning: Current predicate: killed/1
Warning: Use ':- discontiguous alive/1.' to suppress this message

"John likes all kind of food."
likes(john,X) :- food(X).
"Apple and vegetable are food."
food(apple).
food(X) :- vegetable(X).
"Anything anyone eats and not killed is food."
food(X) :- eats(P,X), alive(P).
"Anil eats peanuts and still alive."
eats(anil,peanuts).
alive(anil).
"Harry eats everything that Anil eats."
eats(harry,X) :- eats(anil,X).
Asking
?- likes(john,X).
produces (in SWI Prolog)
70 ?- likes(john,X).
X = apple ;
ERROR: food/1: Undefined procedure: vegetable/1
Exception: (9) vegetable(_G19387424) ? fail
Exception: (8) food(_G19387424) ? fail
71 ?-
Fixing it with
:- dynamic(vegetable/1).
we get
75 ?- likes(john,X).
X = apple ;
X = peanuts ;
false.
and so, of course,
101 ?- likes(john,peanuts).
true .

Related

I'm new to Prolog and I don't know where I'm going wrong

Current predicate: wings/1
Warning: Use :- discontiguous size/1. to suppress this message
Warning: Clauses of bill/1 are not together in the source-file
Warning: Current predicate: size/1
Warning: Use :- discontiguous bill/1. to suppress this message
Warning: Clauses of live/1 are not together in the source-file
Warning: Current predicate: bill/1
Warning: Use :- discontiguous live/1. to suppress this message
Warning: Clauses of nostrils/1 are not together in the source-file
Warning: Current predicate: live/1
This is the code I'm using.
:-dynamic known/3.
top_goal(X):-bird(X).
bird(laysan_albatross):-
family(albatross),
color(white).
bird(black_footed_albatross):-
family(albatross),
color(dark).
bird(whistling_swan):-
family(swan),
voice(muffled_musical_whistle).
bird(trumpeter_swan):-
family(swan),
voice(loud_trumpeting).
order(tubenose):-
nostrils(external_tubular),
live(at_sea),
bill(hooked).
order(waterfowl):-
feet(webbed),
bill(flat).
family(albatross):-
order(tubenose),
size(large),
wings(long_narrow).
family(swan):-
order(waterfowl),
neck(long),
color(white),
flight(ponderous).
nostrils(external_tubular).
live(at_sea).
bill(hooked).
size(large).
wings(long_narrow).
color(dark).
color(X):-ask(color,X).
wings(X):-ask(wings,X).
size(X):-ask(size,X).
bill(X):-ask(bill,X).
live(X):-ask(live,X).
nostrils(X):-ask(nostrils,X).
voice(X):-ask(voice,X).
flight(X):-ask(flight,X).
feet(X):-ask(feet,X).
neck(X):-ask(neck,X).
ask(A, V):-
known(yes, A, V),
!.
ask(A, V):-
known(_, A, V),
!,fail.
ask(A, V):-
write(A:V),
write('? : '),
read(Y),
asserta(known(Y, A, V)),
Y==yes.
solve:-
retractall(known(_,_,_)),
top_goal(X),
write('The bird is'),write(X),nl.
solve:-
write('This is an unknown bird.'),nl.
You are putting a full stop character where you should be using a comma in the swan family:
family(swan):-
order(waterfowl),
neck(long),
color(white),
flight(ponderous). %Should be ',' instead of '.'
nostrils(external_tubular). %idem
live(at_sea). bill(hooked). size(large). %idem
wings(long_narrow). %idem
color(dark). %This full stop is ok
These characters are very different in purpose !
As per your code, you are defining bill/1 or live/1 after the swan family code, and again when you ask the user. So prolog sees that as two separate definitions of the same predicate, which it flagged as "discontinous" error.

Prolog Query Exercise - Beginner

I'm a begginer at Prolog and I need some help with this exercise, this is the knowledge base provided:
album(‘R. Stevie Moore’, ‘Manuscription’).
album(‘Lane Steinberg’, ‘Manuscription’).
album(‘R. Stevie Moore’, ‘The Yung & Moore Show’).
album(‘Yukio Yung’, ‘The Yung & Moore Show’).
album(‘Jessie Evans’, ‘Autonervous’).
album(‘Bettina Koster’, ‘Autonervous’).
album(‘Lucia Pamela’, ‘Walkin on the moon’).
album(‘Shooby Taylor’, ‘The Human Horn’).
album(‘Tiny Tim’, ‘God Bless Tiny Tim’).
album(‘The Legendary Stardust Cowboy’, ‘Rock-It to Stardom’).
vinil(‘Rock-It to Stardom’).
vinil(‘Walking on the Moon’).
cd( ‘God Bless Tiny Tim’).
cd(‘Walking on the Moon’).
cd(‘Autonervous’).
cd(‘Manuscription’).
cassette(‘The Human Horn’).
cassette(‘The Yung & Moore Show’).
mp3(‘Walkin on the Moon’).
I need to make a query that will return to me all the albums that were made by only one musician.
Thanks for your help :)
In the comments you have provided your code album(X,B),album(Y,C), B \= C. Actually, this is not too far away from a correct solution.
A correct solution could be:
one_musician_album(X) :-
album(A, X),
\+ (album(B, X), A \= B).
The meaning of the predicate is: an album X is a "one-musician album" if this album is authored by some musician A and it's not possible to find a different musician B authored the album X.
Test run:
?- one_musician_album(X).
X = 'Walkin on the moon' ;
X = 'The Human Horn' ;
X = 'God Bless Tiny Tim' ;
X = 'Rock-It to Stardom'.
To get all answers you have to type ';' after each answer.
Maybe this is not needed for you, but it's possible to get all answers in a list with findall:
?- findall(X, one_musician_album(X), Albums).
Albums = ['Walkin on the moon', 'The Human Horn', 'God Bless Tiny Tim', 'Rock-It to Stardom'].
Here is a generalization, based on 'all solutions' builtin bagof/3.
Note that
?- bagof(A, album(A,T), As).
T = 'Autonervous',
As = ['Jessie Evans', 'Bettina Koster'] ;
T = 'God Bless Tiny Tim',
As = ['Tiny Tim']
....
then, restricting the authors (As) to be a list of a single element, we get albums with a single author
?- bagof(A, album(A,T), [A]).
A = 'Tiny Tim',
T = 'God Bless Tiny Tim' ;
...
then, we could use findall/3, as in the good answer by Sergey, or, again, bagof/3, with explicit quantification:
?- bagof(T, A^bagof(A, album(A, T), [A]), Ts).
Ts = ['God Bless Tiny Tim', 'Rock-It to Stardom', 'The Human Horn', 'Walkin on the moon'].

swi prolog , matching data

this is my source code , can someone tell me what is error , and wat is the best way to do this , i want to show out who matching who ...can somebody help me ?
% Author:
% Date: 08-Sep-11
person(may,female,25,blue).
person(john,male,30,blue).
match:-person(Fn,'female',Fage,Fatt),
person(Mn,'male',Mage,Matt),
Fage<=Mage,
Fatt=Matt,
write(Fn ,'-- match with----',Mn).
error message :55 ?- match.
ERROR: Undefined procedure: match/0
ERROR: However, there are definitions for:
ERROR: catch/3
false.
match :-
person(Fn,female,Fage,Fatt),
person(Mn,male,Mage,Matt),
Fage =< Mage,
Fatt = Matt,
format('~w~s~w~n',[Fn ,'-- match with----',Mn]).

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.

"dynamic" predicate in prolog

If I want to make a rule dynamic so i can use assert after the database file has been loaded, how do i do it? I'm using XSB Prolog at the moment, the file is something like this:
:- dynamic likes/2
likes(mary,tom)
when i try to consult the file with XSB i get an error:
? consult('D:\file.P).
not permitted to assert to static predicatelikes/2
forward continuation...blahblah
Any ideas?
The dynamic predicate works as you are expecting, so there is something else wrong if it is not working for you.
If test.P looks like this:
:- dynamic likes/2.
likes(mary,tom).
It can be consulted, and then more likes/2 facts can be asserted:
XSB Version 3.2 (Kopi Lewak) of March 15, 2009
[i686-pc-linux-gnu; mode: optimal; engine: slg-wam; scheduling: local; word size: 32]
| ?- consult('test.P').
[Compiling ./test]
[test compiled, cpu time used: 0.0440 seconds]
[test loaded]
yes
| ?- assert(likes(mary, bob)).
yes
| ?- likes(X,Y).
X = mary
Y = tom;
X = mary
Y = bob;

Resources