Prolog's grammar uses a <head> :- <body>
format for rules as such:
tree(G) :- acyclic(G) , connected(G).
, denoting status of G as a tree depends on status as acyclic and connected.
This grammar can be extended in an implicit fashion to facts. Following the same example:
connected(graphA)
suggests connected(graphA):-true.
In this sense, one might loosely define Prolog facts as Prolog rules that are always true.
My question: Is in any context a bodiless rule (one that is presumed to be true under all conditions) ever appropriate? Syntactically such a rule would look as follows.
graph(X).
(suggesting graph(X):-true.
)
This is often how the base case of a recursive definition is expressed.
Before answering, to rephrase your question:
The terminology is kind of important here. Facts are simply rules that have only a head and no body (which is why 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 syntactical scope of a variable). If you did try to give this predicate clause to the Prolog compiler:
you will get a "singleton variable" warning. Instead, you can write
and this tells the compiler that this argument is ignored on purpose, and no variable binding should be attempted with it.
Operationally, what happens when Prolog tries to prove a rule?
As you can see, the second step makes this a recursively defined algorithm: proving the body of a rule means proving each rule in it.
To come to your question: what is the operational meaning of this:
I have seen at least one use of such a rule: look at the very bottom of this section of the SWI-Prolog manual. The small code example goes like this:
You should read the linked documentation to see the motivation for doing this. The purpose of the code itself is to add at compile time a table of facts to the Prolog database. This is done by term expansion, a mechanism for code transformations, usually used through
term_expansion/2
. You need the definition ofmy_class/1
so thatterm_expansion/2
can pick it up, transform it, and replace it with the expanded code. I strongly suggest you take the snipped above, put it in a file, consult it and uselisting/1
to see what is the effect. I get:NB: In this example, you could replace the two occurrences of
my_class(_)
with anything. You could have just as well written:The end result is identical, because the operational meaning is identical. However, using
my_class(_)
is self-documenting, and makes the intention of the code more obvious, at least to an experienced Prolog developer as the author of SWI-Prolog ;).A fact is just a bodiless rule, as you call it. And yes, there are plenty of use cases for bodiless facts:
instead of some curly brace language pseudo code
we can simply write
To highlight what I was initially looking for, I'll include the following short answer for those who might find themselves asking my initial question in the future.
An example of a bodiless rule is, as @Anniepoo suggested, a base case for a recursive definition. Look to the example of a predicate, member(X,L) for illustration:
Here, the first entry of the member rule represents a terminating base case-- the item of interest X matching to the head of the remaining list.
I suggest visiting @Boris's answer (accepted) for a more complete treatment.