lycien
lycien

Reputation: 3

Fail to display input and output in prolog

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

Answers (2)

David Tonhofer
David Tonhofer

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

Reema Q Khan
Reema Q Khan

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

Related Questions