Linguistics 482 - Computational Linguistics Prolog Notes A. C. Brett acbrett@uvic.ca
Department of Linguistics
University of Victoria
Clearihue C139
Last updated: 9 October 2005

Typing Queries - An Introductory Tutorial

After you have made your Prolog program available to the Listener as described in the Consulting a Prolog Program or Reconsulting a Prolog Program sections, and the Listener has responded "yes" followed by the "?-" prompt, you can type queries (or claims) to which the Listener will respond on the basis of the facts and rules in your program.

For example, suppose your program includes the following lines that consist of some explanatory comments, which begin with the percent sign, %, together with two facts, which are clauses of a noun/1 predicate:

   % My first Prolog program -- 'a:first.pro'.

   % Definition of the "noun/1" predicate.
   %
   % The clauses comprising this predicate may be construed
   % as translations of the following phrase-structure rules
   % into Prolog:
   %
   % N --> cats
   % N --> dogs
   % 
     noun(cats).  % The word "cats" is a noun.
     noun(dogs).  % The word "dogs" is a noun.
The Listener ignores whatever has been typed to the right of a percent sign. This information is included only so that a human being who reads the program can figure out its purpose and what it is expected to do. The Listener pays attention only to the two Prolog clauses noun(cats) and noun(dogs) that make up the noun/1 predicate. Therefore, if you were to type the following statement:
  noun(dogs).
which may be translated into English either as the assertion that "dogs is a noun." or as the query "Is dogs a noun?", the Listener will respond "yes" and display the "?-" prompt.

In processing this query, the Listener has found a predicate with the same name and with the same number of arguments (that is, with one argument in this case), and the argument of one of the clauses of this predicate is the same as the argument in the assertion you typed. Thus, the Listener has been able to match or unify the statement you typed, sometimes called a goal, with a fact in your program.

If, on the other hand, you were to type

  noun(mice).
which may be translated into English as the query "Is mice a noun?", the Listener will respond "no".

In this case, the Listener has been unable to unify the goal you typed with an assertion in your program. It can match the predicate name noun with a predicate in your program, and this predicate also has one argument; but, in none of the clauses of this predicate does the argument match the argument you typed.

The Listener will still display the "?-" prompt to indicate that it is prepared to accept another query or claim. You might then type

   n(cats).
but, the Listener will respond "no" because it cannot unify this goal with a clause in your program.

The Listener has found that that the predicate name n does not match the name of a predicate in your program. Because the predicate names cannot be unified, the Listener does not check that the argument of the assertion of the n/1 predicate that you typed does match the argument of one of the clauses on the noun/1 predicate in your program.

You might then type a query such as the following:

   noun(X).
where the argument of the assertion of the noun/1 predicate that you have typed is the variable X.

The foregoing goal might be translated as the query "What Xs (words) are nouns?", or as the assertion that "There exists (an) X such that X is a noun." In responding to this assertion, or query, the Listener will display

   X = cats |
with the cursor one space over to the right. If you were to type a semicolon (or the pipe character corresponding to the split vertical bar on most keyboards), the Listener will display
   X = dogs |
If you were then to type the semicolon character again, the Listener will respond as follows:
   no
   ?- |
What has happened during this dialogue is that the Listener has unified the assertion noun(X) that you typed with the first clause of the noun/1 predicate in your program. During this process, the variable X is instantiated with the argument of the first clause of the noun/1 predicate, with the result that the Listener displays the X = cats line. Since it is possible that there is another clause in your program that will unify with the goal you typed, the Listener paused, awaiting your instructions.

By typing the semicolon, you indicated that you want it to seek additional matches. The Listener then uninstantiated the variable X and proceeded to the next clause of the noun/1 predicate. In unifying your goal with the next clause, the variable X was instantiated with the argument dogs, with the result that the line X = dogs was displayed.

Since it is possible, in principle, that there is another clause of the noun/1 that will unify with the assertion you typed, the Listener paused for your instructions. After you typed the semicolon, however, the Listener was unable to find another match, and hence, it displayed the response "no".

If, after the Listener had displayed the line X = cats, you were satisfied that, for example, there was at least one clause which could be unified with the assertion noun(X). You might then press the [Enter] or [Return] key, instead of the semicolon. In this case, the Listener will respond "yes" and will not seek any further alternatives. At any point in the process that you want the Listener to stop seeking and displaying alternatives, you can press the [Enter] or [Return] key.

Suppose now that you edit the Prolog program on which the foregoing examples are based by adding the clauses of a new det/1 predicate. The resulting program might appears as follows:

   % My first Prolog program -- 'a:first.pro'.

   % Definition of the "noun/1" predicate.
   %
   % The clauses comprising this predicate may be construed
   % as translations of the following phrase-structure rules
   % into Prolog:
   %
   % N --> cats
   % N --> dogs
   % 
     noun(cats).  % The word "cats" is a noun.
     noun(dogs).  % The word "dogs" is a noun.

   % Definition of the "det/1" predicate.
   %
   % The clauses of this predicate may be viewed as translations
   % of the following phrase-structure rules:
   %
   % DET --> the
   % DET --> these
   % DET --> those
   %
     det(the).    % The word "the" is a determiner.
     det(these).  % The word "these" is a determiner.
     det(those).  % The word "those" is a determiner. 
After reconsulting the modified program, if you were to type
   det(the), noun(dogs).
the Listener will respond "yes".

Your query in this instance consists of two goals, separated by a comma (but still, like all Prolog statements, ending with a period). The comma can be read as "and," and like the English word into which it can be translated, the comma functions as a co-ordinating conjunction. Thus, the Prolog statement can be translated as a compound sentence: "the is a determiner and dogs is a noun."

Both of the co-ordinate goals in a compound query must be satisfied in order that the Listener respond "yes". The Listener responds to such queries by attempting to satisfy the goals in the order in which they appear from left to right. Thus, if you were to type

   det(those), noun(mice).
the Listener will first attempt to unify the first goal, det(those), with a clause in your program. Since there is a clause that matches this goal, the Listener will then attempt to satisfy the second goal, noun(mice). There is, however, no matching clause clause in your program. Hence, the attempt fails, and the Listener will respond "no".

Your query can consist of more than two conjoined goals, and the Listener will attempt to satisfy each of them in the order in which you have typed them. All goals must succeed in order that the query elicit a positive from the Listener. As soon as the Listener is unable to satisfy one of your goals, it terminates the process, without testing any other of the goals conjoined in the query, and it displays a negative response.

Thus, for example, if you were to type the following query:

   det(some), noun(cats), noun(dogs).
the Listener will respond "no" after determining that the first goal fails, notwithstanding that the second and third goals would have succeeded had they been tested.

Suppose that you edit the program in the file 'a:first.pro' to add the following rules:

   %Definition of an np/1 rule.
   %
   % The Prolog rule comprising this predicate may be
   % construed as a translation of the following
   % phrase-structure rule:
   %
   %  NP --> N
   %
   % Note that the phrase-structure rule may be
   % translated into English as the assertion that
   %
   %  A noun phrase consists of a noun.
   
      np(X) :- noun(X).

   %Definition of an np/2 rule.
   %
   % This Prolog rule may be taken as a translation
   % of the following phrase-structure rule:
   %
   % NP --> DET N
   %
   % which itself may be translated into English as
   % asserting that
   %
   %  A noun phrase consists of a determiner and a
   %  noun.

      np(X, Y) :- det(X), noun(Y).
with the clauses of the noun/1 and det/1 facts remaining unchanged.

Note that the np(X) and np(X, Y) structures are each called the head of their respective np/1 and np/2 rules. The ":-" pair of characters is called the neck of the rule. These characters are translated into English by the conjunction "if." The structures to the right of the neck are called the body of the rule. Thus, the det(X) and the noun(X) structures comprise the body of the np/2 rule. The comma separating them is read as "and."

Then, after saving and reconsulting this modified program file, if you were to type

   np(dogs).
the Listener will respond "yes", indicating that it has been able to prove the np(dogs) goal.

The processes entailed in proving this goal consist, in the first place, of unifying it with the head np(X) of the np/1 rule. As a consequence this unification, the atom dogs is instantiated on the variable X in the argument of the np(X) structure. But X is also the argument of the goal noun(X) in the tail of the np/1 rule. Hence, this goal becomes, in effect, noun(dogs). The Listener then attempts to prove this goal. Since it matches the fact noun(dogs) in the program, the Listener succeeds.

Now suppose you were to type the following claim:

np(those, dogs).
The Listener will unify this goal with the head np(X, Y) of the np/2 rule, and in the process, the atoms those and dogs will get instantiated on the variables X and Y, respectively. Consequently, the two goals in the tail of the rule become det(those) and noun(dogs). Since the Listener can unify these with facts in the program, the claim you typed can be proved, and the Listener will respond "yes".

Linguistics 482 Prolog Introductory Notes Top of Page