Prologue: rules with nothing but anonymous variables in the head and no body

The grammar prologue uses the <head> :- <body> format for rules as such:

tree(G) :- acyclic(G) , connected(G). denoting the status of G as a tree depends on the status as acyclic and related.

This grammar can be implicitly extended to facts. Following the same example:

connected(graphA) suggests connected(graphA):-true.

In this sense, you can freely define the facts of the Prolog as the rules of the Prolog, which are always true.

My question is: In any context, the incorporeal rule (which is considered true under any conditions) is ever appropriate? Syntactically, this rule will look as follows.

graph(X). (suggesting graph(X):-true. )

+1
prolog
source share
4 answers

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;).

+3
source share

In fact, this is simply an incorporeal rule, as you call it. And yes, there are many examples of use for barren facts:

  • represents static data
  • base registers for recursion
  • instead of some pseudocode curly bracket cursor

     boolean is_three (integer x) {
         if (x == 3) {return true;  }
         else {return false;  }
     }
    

    we can just write

     is_three (3).
    
+3
source share

It often happens as the basic case of a recursive definition is expressed.

+1
source share

To highlight what I was originally looking for, I will include the following short answer for those who might ask their initial question in the future.

An example of the incorporeal rule is, as @Anniepoo suggested, the base case for a recursive definition. Take a look at the example predicate member (X, L) to illustrate:

 member(X,[X|T]). /* recursive base case*/ member(X,[H|T]):- member(X,T). 

Here, the first entry of the member rule represents the final base case - interest element X, corresponding to the head of the remaining list.

I suggest visiting @Boris's answer (accepted) for a more complete treatment.

0
source share

All Articles