Reputation: 3
I'm a beginner at prolog Can someone help me with this?
>go:-
write('Name?'),
read(Name), staff(Name, ID, Age),
write('ID?'),
read(ID), staff(Name, ID, Age),
write(Age).
staff(john, 123, 21).
staff(john, 222, 19).
staff(john, 333, 35).
The ID prompt keep repeating
Output
?-go
Name?
john
ID?
333
ID?
333
ID?
333
35
Upvotes: 0
Views: 79
Reputation: 15316
The tracer shows what's going on:
?- trace,go.
Call: (11) go ? creep -
Call: (12) write('Name?') ? creep -
Name? -
Exit: (12) write('Name?') ? creep -
Call: (12) read(_6414) ? creep -
|: john. - enter "john." (the term 'john' followed by a .)
-
Exit: (12) read(john) ? creep -
Call: (12) staff(john,_6508,_6510) ? creep - Prolog find the staff fact with 'john' as argument 1
Exit: (12) staff(john,123,21) ? creep - ID is now 123 and Age is now 21
Call: (12) write('ID?') ? creep -
ID? -
Exit: (12) write('ID?') ? creep -
Call: (12) read(123) ? creep - Prolog expects you to enter 123, the current value of ID.
|: 333. - Enter "333." (the term '333' followed by a ., which maps to an integer)
-
Fail: (12) read(123) ? creep - As 123 is not 333, reading is a failure!
Redo: (12) staff(john,_6508,_6510) ? creep - Backtracking! The earliest predicate that gives more solution is staff/3.
Exit: (12) staff(john,222,19) ? creep - The second solution is 'john' with ID 222 and age 19
Call: (12) write('ID?') ? creep -
ID? -
Exit: (12) write('ID?') ? creep -
Call: (12) read(222) ? creep - Prolog expects you to enter 222, the current value of ID.
|: 333. - Enter "222." (the term '222' followed by a ., which maps to an integer)
-
Fail: (12) read(222) ? creep - As 222 is not 333, reading is a failure!
Redo: (12) staff(john,_6508,_6510) ? creep - Backtracking! The earliest predicate that gives more solution is staff/3.
Exit: (12) staff(john,333,35) ? creep - The second solution is 'john' with ID 333 and age 35
Call: (12) write('ID?') ? creep -
ID? -
Exit: (12) write('ID?') ? creep -
Call: (12) read(333) ? creep - Prolog expects you to enter 333, the current value of ID.
|: 333. -
-
Exit: (12) read(333) ? creep - You entered 333 this time, reading is a success! Proceed!
Call: (12) staff(john,333,35) ? creep - Call staff(john,333,35).
Exit: (12) staff(john,333,35) ? creep - That fact exists, so succeess. Proceed.
Call: (12) write(35) ? creep - Write age value
35 -
Exit: (12) write(35) ? creep -
Exit: (11) go ? creep - The clause succeeds
true. -
Here is probably what you want, using a "failure-driven loop" whereby a fail
zips you back to the repeat
for another attempt:
staff(john, 123, 21).
staff(john, 222, 19).
staff(john, 333, 35).
go:-
repeat,
format("Name?~n",[]),
read(Name),
format("ID?~n",[]),
read(ID),
(staff(Name, ID, Age)
-> format("Age of ~q with ID ~q is ~d~n",[Name,ID,Age])
; (format("No entry with Name ~q and ID ~q~n",[Name,ID]),fail)).
Upvotes: 1
Reputation: 878
Just remove the first staff(Name, ID, Age),
go:-
write('Name?'),
read(Name),
write('ID?'),
read(ID),
staff(Name, ID, Age),
write(Age).
staff(john, 123, 21).
staff(john, 222, 19).
staff(john, 333, 35).
Example:
?- go.
Name?
john
ID?
333
35
true
?- go.
Name?
john
ID?
123
21
true
Upvotes: 1