I have seen similar previous posts, but I seem to still be stuck. My current if statement, even when it fails, outputs the "if true" code. So I'd like to ask what the proper syntax is if I don't want to do anything else if the condition turns to be false.
My code that fails:
(Disease == malaria
-> (patient_age(y)
-> writeln('Since patient is young, likelihood of malaria increases.')
; true)
;
Disease == tuberculosis
-> (patient_age(e)
-> writeln('Since patient is old, likelihood of tuberculosis increases.')
; true)
).
What happens is that, even if patient_age() is false, the writeln() statement is still executed. I have attempted replacing the "false code" with another writeln() statement, which did not display. I apologize that this has been asked before. Thank you very much.
It would be more declarative, idiomatic, and clear to rewrite the code to avoid the use of the if-then-else control construct. For example:
% likelihood(Disease, PatientAge)
likelihood(malaria, y) :-
writeln('Since patient is young, likelihood of malaria increases.').
likelihood(tuberculosis, e) :-
writeln('Since patient is old, likelihood of tuberculosis increases.').
Still, it would likely be best to move the written messages to a predicate that calls the likelihood/2 predicate. For example:
print_diagnostic(PatientAge) :-
likelihood(Disease, PatientAge),
write('Increased likelihood of '), write(Disease), nl.
Related
This is my first-day learning prolog and I would like to write a program that decides what shoes I should wear based on the weather and what kind of appointment I have at the office. The main "function" would be declared for example:
"go :- outfit(snow, 15, casual, F1), write(F1)."
Where snow is the weather, 15 is the temperature(not relevant now), and casual is the formality of the appointment. "write(F1)" will display the "output" so the variable F1 needs to be the result of said relation(s). Here are the rules for what shoes to wear:
%Rules for weather
rain(Weather) :- (Weather = 'rain').
snow(Weather) :- (Weather = 'snow').
nice(Weather) :- (Weather = 'nice').
clear(Weather) :- (Weather = 'clear').
%Rules for formality
formal(Appointment) :- (Appointment = 'formal').
semiformal(Appointment) :- (Appointment = 'semiformal').
casual(Appointment) :- (Appointment = 'casual').
%Rules for when to wear a type of footwear
dressShoes(Appointment) :- formal(Appointment).
boots(Appointment, Weather) :- not(formal(Appointment)), (rain(Weather);snow(Weather)).
sneakers(Appointment, Weather) :- not(formal(Appointment)), (nice(Weather);clear(Weather)).
This is where my issue is, I am not sure how to tie the last three relations to a single relation that fills the variable "F1" for my final "outfit" function. I am a C++ guy, so I would like to essentially place a string into F1 like "[sneakers]" or "[boots]" but this is part of my growing pains with prolog. Any help is much appreciated.
Some misunderstandings about Prolog I guess. This kind of rule:
rule(Variable) :- (Variable = 'value').
You don't need to quote 'value', it is already an atom. Whatever book you are reading, look up atoms. It becomes:
rule(Variable) :- (Variable = value).
You don't need the extra parentheses in the rule definition. It becomes:
rule(Variable) :- Variable = value.
You don't need the explicit unification in the body. There is nothing else happening between the head and the body. So you don't need a variable, either. It becomes:
rule(value).
Applying this to your program, I get:
rain(rain).
snow(snow).
nice(nice).
clear(clear).
%Rules for formality
formal(formal).
semiformal(semiformal).
casual(casual).
Those rules say pretty much nothing ;-)
Your example at the very top:
go :- outfit(snow, 15, casual, F1), write(F1).
Does exactly the same as just calling outfit(snow, 15, casual, F1). So what is the purpose of the "go" and the "write"? Skip them I guess.
The logic of your program: can you explain it without code? Your code is so unusual that I have to guess.
If you want to say, "If the appointment is formal, put on dress shoes", you could write it like this:
occasion_shoes(Occasion, Shoes) :-
formality_occasion(Formality, Occasion),
formality_shoes(Formality, Shoes).
formality_occasion(formal, evening_party).
formality_occasion(semi_formal, office).
formality_shoes(formal, dress_shoes).
Do you see what is going on? You match the occasion to the shoes. To do that, you look up the formality of the occasion in the table formality_occasion/2 and then match it to the formality of the shoes in the formality_shoes/2 table.
If you are struggling to model your problem, you can also read up on relational database design.
With the following rules:
test('John', ebola).
test('John', covid).
test('Maria', covid).
How can I create a predicate that would tell me if John or Maria took (both) the Ebola and Covid tests?
I want to do something similar to this (I know it's wrong, just the idea):
tests(Persona, Ebola, Covid) :-
Ebola = test(Persona, ebola),
Covid = test(Persona, covid).
Prolog is relational not functional. test(X, Y) either holds or fails and doesn't return a value like what you thought. Here's what you should have written:
tests(Persona) :-
test(Persona, ebola),
test(Persona, covid).
You can query tests('John') which is true since both test/2 calls succeeds. The query tests('Maria') fails because test('Maria', ebola) fails.
Does it answer your question ?
I have just started learning Prolog, and I'm wondering about the first question of this exercise.
%% Suppose we are working with the following knowledge base:
wizard(ron).
hasWand(harry).
quidditchPlayer(harry).
wizard(X) :- hasBroom(X), hasWand(X).
hasBroom(X) :- quidditchPlayer(X).
How does Prolog respond to the following queries?
wizard(ron). -> true
witch(ron). -> undefined procedure
wizard(hermione). -> false
witch(hermione). -> undefined procedure
wizard(harry). -> true
wizard(Y). -> Y = ron ; Y = harry.
witch(Y). -> undefined procedure
Using swipl on Ubuntu, importing the knowledge base for this exercise, first of course trying to decipher what Prolog will returns, and finally checking by myself.
Ok pretty boring stuff until now, I have seen a few answer to these exercises over Github (here, here and there), and I don't understand the answer to the first one: %% 1. wizard(ron). -> true.
First of all the interpreter is complaining about the two definition of what is a wizard:
Warning: /tmp/prolog/ex15.pl:4:
Clauses of wizard/1 are not together in the source-file
Earlier definition at /tmp/prolog/ex15.pl:1
Current predicate: quidditchPlayer/1
Use :- discontiguous wizard/1. to suppress this message
Secondly, when querying I obtain:
?- wizard(ron).
true ;
false.
The way I get it, first Prolog returns the first fact from the knowledge base, then apply the rule head and find out that ron has neither a broom nor a wand.
All this leading to my question: what subtlety have I missed that makes others writing true as an answer to this query?
what subtlety have I missed that makes others writing true as an answer to this query?
`?- wizard(ron).`
true;
false
You have the clause (fact) wizard(ron). in your KB.
To make the things clearer you can write the fact also as the rule clause:
wizard(ron) :- true.
As you can see this is pretty redundant notation but useful in some cases as the general fact representation.
So your query can be interpreted as follows:
Is there an wizard called ron?
Since you have the fact wizard(ron) :- true.
Prolog will first unify the goal and the head.
In your case unify is trivial comparison because no variables are in the goal and the head.
Then Prolog tries to prove body. The body is builtin predicate true, so you quickly get the answer - true.
Then pressing ';' you initiate the search for the alternative solution.
Since no (more) solutions exist for the query wizard(ron), Prolog writes false.
The dot operator designates the clause end. So you wrongly typed dots in your examples:
-> operator means if-then-else relation. It can be used within clause body.
For example you can write std_member/2 as if_member/2
std_member(X, [ X | _ ]).
std_member(X, [ _ | Xs ]) :-
std_member(X, [ _ | Xs).
if_member(X, [ Y | Xs ]) :-
X = Y -> true;
if_member( X, Xs ).
Hello I'm new to Prolog and some things about it just confuse me.
So I have this list of Facts and a predecate:
parent(gerlinde,mark).
parent(gerlinde,lena).
.
.
(and so on)
female(gerlinde).
.
.
(and so on)
male(mark).
sister(S,X) :- parent(F,S),parent(F,X),male(F),
parent(M,S),parent(M,X),female(M),female(S),S\==X.
So if I do ?-sister(S,X). I get the answers correclty without the answer that S is the sister of herself (S=X). However, if I Change the order like that:
sister(S,X) :- S\==X,parent(F,S),parent(F,X),male(F),
parent(M,S),parent(M,X),female(M),female(S).
or like that:
sister(S,X) :- parent(F,S),S\==X,parent(F,X),male(F),
parent(M,S),parent(M,X),female(M),female(S).
then I suddenly get the answer S=X too. So why is that happening? In my understanding there should be no difference between both predicates.
This is because X\==S is the same as \+X == S, and \+T means 'T cannot be proven'. So, in your second predicate:
sister(S,X) :- S\==X,parent(F,S),parent(F,X),male(F),
parent(M,S),parent(M,X),female(M),female(S).
When S\==X is called, both S and X are variables. Thus, it 'cannot be proven' that S == X and this goal succeeds.
Then, as the predicate continues to be evaluated, parent(F,S) will ground S - in your case, to mark.
Then, parent(F,X) will ground X - to mark again! And it is never required again that S be different from X. Of course, with S = X = mark the predicate fails, as mark is not a female (female(S) fails). But not with lena; she will indeed be her own sister.
I would need help about Prolog.
I posted my code, the problem is that i do not obtain the expected result.
I want planning actions for moving on table all blocks until is possible. To do this I prompt :
?- do(while(some(x, block(x) & -onTable(x)),pi(x,putOnTable(x))),s0,S).
I expect to see a response like :
S = do(putOnTable(e), do(putOnTable(b), do(putOnTable(c), s0)))
but Prolog returns "false" only. Someone can help me??
% Golog interpreter
%:- [golog_swi].
:- discontiguous clear/2, on/3, onTable/2.
:- op(800,xfy,[&]).
do(E,S,do(E,S)):- primitive_action(E),poss(a,S).
% Primitive Action Declarations.
primitive_action(putOn(_,_)).
primitive_action(putOnTable(_)).
poss(putOn(X,Y),S) :- clear(X,S), clear(Y,S), \+ on(X,Y,S), \+ X=Y.
poss(putOnTable(X),S):- clear(X,S), \+(onTable(X,S)).
% Successor State Axioms.
on(X,Y,do(A,S)):- A = putOn(X,Y); on(X,Y,S), \+ (A = putOnTable(X); A = putOn(X,_)).
onTable(X,do(A,S)) :- A = putOnTable(X); onTable(X,S), \+ A= putOn(X,_).
clear(X,do(A,S)) :- on(Y,X,S), (A = putOn(Y,_) ; A = putOnTable(Y)); clear(X,S), \+ A = putOn(_,X).
% Restore suppressed situation arguments
restoreSitArg(onTable(X),S,onTable(X,S)).
restoreSitArg(on(X,Y),S,on(X,Y,S)).
restoreSitArg(clear(X),S,clear(X,S)).
block(X):- member(X,[a,b,c,d,e]).
% iniTial COndition
onTable(a,s0).
on(b,a,s0).
on(c,b,s0).
clear(c,s0).
onTable(d,s0).
on(e,d,s0).
clear(3,s0).
thank you!!!
Your predicate do/3 cannot succeed because the goal primitive_action/1 will fail with your query.
Currently, while/2 is not described in primitive_action/1 and it seems it is missing also from your program. So you need to extend primitive_action/1 by further facts, or add a new rule to do/3. And in addition to that you need to describe what while/2 means.
This question is actually about Golog. Your mistake is pretty mundane: you didn't copy the Golog interpreter code into your source file/directory.
Golog defines a number of high-level programming constructs, including while-loops and non-deterministic picks (pi), used here. I'm sure you don't want to reinvent Golog, so just go and get it. I'm assuming that your question is part of an assignment of sorts, and your teacher probably pointed you to the Golog interpreter. Otherwise, you can always find it on the pages of the cognitive robotics group at the Univ. of Toronto: http://www.cs.toronto.edu/cogrobo/main/systems/index.html