This is the code
verificar(S) :-
(si(S)
->
true ;
(no(S)
->
fail ;
preguntar(S))).
preguntar(Pregunta) :-
write('Tiene los siguientes sintomas: '),
write(Pregunta),
write('?'),
read(Respuesta),
nl,
( (Respuesta == si)
->
assert(si(Pregunta));
assert(no(Pregunta)), fail).
and the problem is
procedure `si(A)' does not exist
Reachable from:
verificar(A)
resfriado
hipotesis(A)
evaluar
The problem is for the first run, the program does not know what you mean with si(A) since there is no predicate or rule defined. Quickfix: Add dummy data like
si(nothing).
no(nothing).
which can be removed after the first "valid" entry in your knowledge base.
You have not written the predicate for si(). This is why you are getting the error:-
procedure `si(A)' does not exist
Related
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.
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.
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.
As the question says, thats kind of what i wanna simulate in prolog. So i'm making a game,here's some code:
move(X):-
get_char(Y)
get_char(_),
get_char(Z),
not(OldLoc='Z'),
not(NewLoc = 'Z'),
validmove(OldLoc,NewLoc).
move(_):-
write('Thanks for playing!'), nl.
move(X):-
write('Invalid move!'), nl,
write('Try Again?'), nl,
move(X).
what i want to do is if the first predicate check fails at not(OldLoc='Z'),not(NewLoc = 'Z'), then go to the next predicate move(_) and it fails at validmove(OldLoc,NewLoc) then go to the next move(X). I'm very new to prolog and i'm almost completely clueless.
If-then-else:
http://www.swi-prolog.org/pldoc/doc_for?object=send_arrow/2
Another if-then-else:
http://www.swi-prolog.org/pldoc/doc_for?object=(*-%3E)/2
Sample #1:
?- test = test -> print('TRUTH') ; print('FALSE').
TRUTH
Sample #2:
?- test = test -> (test2 = test3 -> print('TRUTH'); print('FALSE2')); print('FALSE').
FALSE2
Consider the following Prolog code. It edits lines of a particular type in its input and prints out the remaining lines w/o any change. It uses a DCG called rule which isn't included below, since it's not important to the question.
go:-
prompt(_, ''),
processInput.
processInput:-
read_line_to_codes(current_input, Codes),
processInput(Codes).
processInput(Codes):-
(Codes \= end_of_file
->
(phrase(rule(Part1, Part2), Codes)
->
format('~s - ~s\n', [ Part1, Part2 ])
;
format('~s\n', [ Codes ])),
processInput
;
true).
:- go, halt.
This works fine. However, suppose I change processInput/1 to the following, it just says that Warning: /home/asfernan/tmp/tmp.pl:28: Goal (directive) failed: user: (go,halt).
processInput(Codes):-
(Codes \= end_of_file
->
(\+phrase(rule(Part1, Part2), Codes)
->
format('~s\n', [ Codes ]))
;
format('~s - ~s\n', [ Part1, Part2 ]),
processInput
;
true).
The if & else parts of the phrase(rule(Part1, Part2), Codes) DCG match have been exchanged. This is obviously a newbie mistake, but the fact that go, halt failed isn't very helpful. What can I do to make the error message indicate that the failure was because Part1 & Part2 were not bound in the format('~s - ~s\n', [ Part1, Part2 ]) line? I was able to track down this error because the code is small, but I may not have been able to do so had the code been big.
In Prolog the following is not the same:
..., ( Cond -> Then ; Else ), ...
and
..., ( \+ Cond -> Else ; Then ), ...
In general, a goal \+ Cond will never instantiate its variables. So you
have to stick to the original formulation.
In case you are interested to process entire
files with DCGs, consider SWI's library(pio).