Before you answer, rephrase your question:
In Prolog, do you ever write a rule with nothing but anonymous variables in the head and no body?
The terminology is important here. Facts are just rules that only have the head and body (so your question is a bit confusing). Anonymous variables are variables that you explicitly tell the compiler to ignore in the context of a predicate clause (a predicate clause is the syntax of a variable). If you tried to give this predicate clause to the Prolog compiler:
foo(Bar).
you will get a warning "singleton variable". Instead you can write
foo(_).
and this tells the compiler that this argument is ignored on purpose, and you should not try to bind a variable to it.
Promptly, what happens when Prolog tries to prove a rule?
- Firstly, the union of all arguments in the chapter of the rule, which may lead to new variable bindings;
- He then tries to prove the body of the rule using all existing variable bindings.
As you can see, the second step makes this a recursively defined algorithm: checking the body of a rule means proving every rule in it.
To answer your question: what is the operational meaning of this:
foo(_).
There is a predicate foo/1 , and it is true for any argument, because there are no variable bindings in the head and always, because there is no need to prove that the subheadings are not checked.
I have seen at least one use of such a rule: look at the bottom in this section of the SWI-Prolog manual . An example of a small code is as follows:
term_expansion(my_class(_), Clauses) :- findall(my_class(C), string_code(_, "~!@#$", C), Clauses). my_class(_).
You should read the related documentation to see the motivation for this. The goal of the code itself is to add a fact table to the Prolog database at compile time. This is done by expanding the term, a code conversion mechanism commonly used by term_expansion/2 . You need the definition of my_class/1 so that term_expansion/2 can pick it up, convert it, and replace it with extended code. I highly recommend that you take a snapshot from above, put it in a file, consult it and use listing/1 to find out what the effect is. I get:
?- listing(my_class). my_class(126). my_class(33). my_class(64). my_class(35). my_class(36). true.
NB . In this example, you can replace two occurrences of my_class(_) with anything. You might as well have written:
term_expansion(foobar, Clauses) :- findall(my_class(C), string_code(_, "~!@#$", C), Clauses). foobar.
The end result is identical because the operational meaning is identical. However, using my_class(_) self-documenting and makes the code more obvious to at least the experienced Prolog developer as the author of SWI-Prolog;).