Question

I'm Prolog beginner, and now I'm stuck, because Prolog doesn't show me any result. I'm reading a few tutorials, and all they has an example code like this:

main.
human(ann).
human(george).
human(mike).

?- bagof(H, human(H), Humans).
% Expected result:
% Humans = [ann, george, mike].

?- human(Who).
% Expected result:
%
% Who = ann;
% Who = george;
% Who = mike.

But all output I get is:

Warning: /Users/admin/prolog/test.pl:105:
    Singleton variables: [Who]
% test.pl compiled 0.00 sec, 34 clauses
true.

Or:

Warning: /Users/admin/prolog/test.pl:105:
    Singleton variables: [Humans]
% test.pl compiled 0.02 sec, 1,409 clauses
true.

What am I doing wrong? I really read everything I could, but all manuals say that such code must return result. But it doesn't for me.

SWI-Prolog version: 6.6.5 for x86_64-darwin13.1.0

OS: MAC OS X 10.9.2 Maverix

Était-ce utile?

La solution

If you go back to the tutorials you've been looking at, they should be making clear (as @PauloMoura points out) that there's a difference between consulting a file in Prolog and interacting with Prolog at it's interactive prompt.

If you simply run Prolog without consulting a file, you can manually enter facts and rules, then press ctrl-D to finish. For example:

? - [user].
|: human(ann).
|: human(george).
|: human(mike).
|: % user://1 compiled 0.00 sec, 2 clauses
true.

Then you can query by typing (at the shown prompt):

?- human(Who).
Who = ann ;
Who = george ;
Who = mike.

?- bagof(H, human(H), Humans).
Humans = [ann, george, mike].

?-

If you want to put things in a file, you can put your facts in a file, say, humans.pl:

human(ann).
human(george).
human(mike).

Then consult the file from the Prolog prompt:

?- [humans].
% humans compiled 0.00 sec, 5 clauses
true.

And then do my queries (again, manually in this case) shown above with the same results:

?- human(Who).
Who = ann ;
Who = george ;
Who = mike.

?- bagof(H, human(H), Humans).
Humans = [ann, george, mike].

These outputs are provided courtesy of the interactive prompt. If you want to have everything in the file, you need to have a predicate in the file which would use I/O functions to output the information you want.

So we can make humans.pl look like this:

human(ann).
human(george).
human(mike).

?- human(Who), write(Who), nl, fail.

?- bagof(H, human(H), Humans), write(Humans), nl.

And then you'd get:

?- [humans].
ann
george
mike
Warning: /home/mark/src/prolog/_play_/humans.pl:5:
        Goal (directive) failed: user: (human(_G606),write(_G606),nl,fail)
[ann,george,mike]
% humans compiled 0.00 sec, 5 clauses
true.

?-

The warning comes because the first query fails (used to do the backtrack for more results). you can get rid of that failure just by adding an alternative true path to that query:

?- human(H), write(H), nl, fail ; true.

Or, you can introduce a single predicate to output all the humans:

human(ann).
human(george).
human(mike).

show_humans :-
    human(H),
    write(H), nl,
    fail.
show_humans.

?- show_humans.

?- bagof(H, human(H), Humans), write(Humans), nl.

Which results in:

?- [humans].
ann
george
mike
[ann,george,mike]
% humans compiled 0.00 sec, 7 clauses
true.

Autres conseils

It seems that you're writing your queries in the file itself instead of trying them at the Prolog top-level interpreter. Queries in a file such as ?- human(Who). are (usually) executed silently. The queries in your file are also the reason you're getting the singleton variable warnings. If you want a query embed in a source file to output anything you need to explicitly add the necessary calls to output the results.

If you want to use Prolog in batch mode, not in interactive mode, you can write the code in human.pl.

:- initialization main.

human(ann).
human(george).
human(mike).

main :- 
    bagof(X, human(X), L),
    write(L),
    halt.

To run it with swipl human.pl (I use swi prolog). Then, the results will be:

% human.pl compiled 0.00 sec, 6 clauses
[ann,george,mike]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top