Prolog - fail; true

1.4k Views Asked by At

I have some problem with my code here. Let's say I have a knowledge base like this:

university('University of Cambridge', 1, 'United Kingdom', 90.3, 92.8, 89.4).
university('University of Oxford', 2, 'United Kingdom', 88.9, 94.8, 88.0).
university('ETH Zurich - Swiss Federal Institute of Technology', 3, 'Switzerland', 86.4, 94.4, 92.2).
university('University of Edinburgh', 4, 'United Kingdom', 83.7, 88.8, 83.6).

Then I call it out like this: (Ignore the checkC(Country)/checkC(_))

checkC(Country):-
    university(U, R, Country, _, _, _),nl,
    write('University: '),write(U),nl,
    write('Rank: '),write(R),nl,
    write('Country: '),write(Country),nl,
    fail; true, nl,
    write('************'), nl,nl.

checkC(_):-
    write('Country not found'),nl,nl.

My question is, why is it if the user inputs a random country name not within the knowledge base, the write('Country not found') won't come out, I found out that it has something to do with the fail; true.

Any help?

1

There are 1 best solutions below

2
On

While the fail; true trick is nice for the command line, gathering multiple solutions is usually done via the predicates findall, bagof and setof.

I used format for readabilities sake.

checkC(X):-
    findall( [U,R,X], university(U,R,X,_,_,_), List),
    (List = [] -> 
     write('Country not found\n\n');
     writeCountries(List)).

writeCountries([]).
writeCountries([X|R]):-
    writeCountries(R),
    format('University: ~w~nRank: ~w~nCountry: ~w~n~n',X).

If you are using swipl, maplist comes in handy:

checkC(X):-
    findall( [U,R,X], university(U,R,X,_,_,_), List),
    (List = [] -> 
     write('Country not found\n\n');
     maplist(format('University: ~w~nRank: ~w~nCountry: ~w~n~n'),List)).

If you don't have format/2 look if you have writef/2 or printf/2.