From Natural Language to Prolog Programs

In the first section of this chapter we talked about facts and rules, relations, general sentences, and queries. Those words are all part of a discussion of logic and natural language. Now we're going to discuss the same ideas, but we're going to use more Prolog-ish words, like clauses, predicates, variables, and goals.

1. Clauses (Facts and Rules)

Basically, there are only two types of phrases that make up the Prolog language; a phrase can be either a fact or a rule. These phrases are known in Prolog as clauses. The heart of a Prolog program is made up of clauses.

More About Facts

A fact represents one single instance of either a property of an object or a relation between objects. A fact is self-standing; Prolog doesn't need to look any further for confirmation of the fact, and the fact can be used as a basis for inferences.

More About Rules

In Prolog, as in ordinary life, it is often possible to find out that something is true by inferring it from other facts. The Prolog construct that describes what you can infer from other information is a rule. A rule is a property or relation known to be true when some set of other relations is known. Syntactically, these relations are separated by commas, as we illustrate in example 1 below.

Examples of Rules

Exercises

2. Predicates (Relations)

The symbolic name of a relation is called the predicate name. The objects that it relates are called its arguments; in the fact likes(bill, cindy)., the relation likes is the predicate and the objects bill and cindy are the arguments.

Here are some examples of Prolog predicates with zero or more arguments:

    pred(integer, symbol)
   person(last, first, gender)
   run
   insert_mode
   birthday(firstName, lastName, date)

As we've shown here, a predicate might not have any arguments at all, but the use of such a predicate is limited. You can use a query such as person(rosemont,Name,male). to find out Mr. Rosemont's first name. But what can you do with the zero-argument query run? You can find out whether the clause run is in the program, or--if run is the head of a rule, you can evaluate that rule. This can be useful in a few cases--for instance, you might want to make a program behave differently depending on whether the clause insert_mode. is present.

3. Variables (General Clauses)

In a simple query, you can use variables to ask Prolog to find who likes tennis. For example:

    likes(X, tennis).

This query uses the letter X as a variable to indicate an unknown person. Variable names in Visual Prolog must begin with a capital letter (or an underscore), after which any number of letters (upper-case or lower-case), digits, or underline characters (_) can be used. For example, the following are valid variable names:

    My_first_correct_variable_name
   Sales_10_11_86

while the next three are invalid:

   1stattempt
   second_attempt
   "disaster"

(Careful choice of variable names makes programs more readable. For example,

    likes(Person, tennis).

is better than

    likes(X, tennis).

because Person makes more sense than X.) Now try the goal

    GOAL likes(Person, tennis).

Visual Prolog replies

    Person=ellen
    Person=mark
    2 Solutions

because the goal can be solved in just two ways; namely, by taking the variable Person and successively matching it with the values ellen and mark.

In variable names, except for the first character (which must be an upper-case letter or an underscore), Visual Prolog allows lower-case or upper-case letters in any position. One way to make variable names more readable is by using mixed upper-case and lower-case letters, as in

    IncomeAndExpenditureAccou

º¯¼ö°¡ °ªÀ» ¾ò´Â ¹æ¹ý

prolog ´Â ÇҴ翬»êÀÚ( assignment statement ) °¡ ¾ø´Ù.  ÀÌ°ÍÀÌ ´Ù¸¥ ¾ð¾î¿ÍÀÇ Áß¿äÇÑ Â÷ÀÌ´Ù.  prolog¿¡¼­ º¯¼ö´Â fact ³ª rule¿¡¼­ÀÇ »ó¼ö( constant )¿Í match µÊÀ¸·Î½á °ªÀ» ¾ò´Â´Ù. º¯¼ö°¡ °ªÀ» ¾ò±â Àü±îÁö¸¦ free ¶ó°íÇÏ°í °ªÀ» ¾òÀ¸¸é bound µÇ¾ú´Ù°í ÇÑ´Ù. query ¿¡¼­ one solution À» ¾ò±âÀ§ÇØ ÇÊ¿ä·Î µÇ´Â ½Ã°£±îÁö¸¸ bound »óÅ·ΠÀÖ°í ,one solutionÀ» ãÀ¸¸é unbind µÇ°í back up µÇ¾î ´Ù¸¥ solutionÀ» ã´Â´Ù. Áï º¯¼ö¿¡ °ªÀ» ºÎ¿©ÇÏ¿© Á¤º¸¸¦ ÀúÀåÇÒ¼ö ¾ø´Ù. º¯¼ö´Â Á¤º¸ÀúÀå ¿ëµµ°¡ ¾Æ´Ï¶ó pattern matching process ÀÇ ÀϺκÐÀ¸·Î »ç¿ëµÈ´Ù.

Take a look at the following example, which uses program 3 to demonstrate how and when variables get their values.

/* Program ch02e03.pro */

Anonymous Variables

/* Program ch02e04.pro */

In this case, because of the anonymous variable, Prolog finds and reports three parents, but it does not report the values associated with the second argument in the parent clause.

Anonymous variables can also be used in facts. The following Prolog facts

    owns(_, shoes).
    eats(_).

could be used to express the natural language statements

    Everyone owns shoes.
    Everyone eats.

The anonymous variable matches anything. A named variable would work equally well in most cases, but its name would serve no useful purpose.

4. Goals (Queries)

Up to now, we've been mixing the word query when talking about the questions you ask Prolog, with the more common name goal, which we'll use from now on. Referring to queries as goals should make sense: when you query Prolog, you are actually giving it a goal to accomplish ("Find an answer to this question, if one exists: ...").

Goals can be simple, such as these two:

    likes(ellen, swimming).
    likes(bill, What).

or they can be more complex. In the "Variables" section of this chapter, you saw a goal made up of two parts:

    likes(Person, reading), likes(Person, swimming).

A goal made up of two or more parts is known as a compound goal, and each part of the compound goal is called a subgoal.

Often you need to know the intersection of two goals. For instance, in the previous parents example, you might also need to know which persons are male parents. You can get Prolog to search for the solutions to such a query by setting a compound goal. Load the Program 4 and enter the following compound goal:

    Goal parent(Person, _), male(Person).

Prolog will first try to solve the subgoal

    parent(Person, _)

by searching the clauses for a match, then binding the variable Person to a value returned by parent (Person is a parent). The value that parent returns will then provide the second subgoal with the value on which to search (Is Person--now bound--a male?).

    male(Person)

If you entered the goal correctly, Prolog will answer

    Person=bill
    Person=joe
    2 Solutions

Compound Goals: Conjunctions and Disjunctions

But this goal is slightly unnatural, since you'd probably rather ask a question like:

    Is there a car listed that costs less than $25,000?

You can get Visual Prolog to search for a solution by setting this compound goal:

    car(Make, Odometer, Years_on_road, Body, Cost), /*subgoal A and*/
    Cost < 25000.
                                      /*subgoal B */

This is known as a conjunction. To fulfill this compound goal, Prolog will try to solve the subgoals in order. First, it will try to solve

    car(Make, Odometer, Years_on_road, Body, Cost).

and then

    Cost < 25000.

with the variable Cost referring to the same value in both subgoals. Try it out now.

Note: The subgoal Cost < 25000 involves the relation less than, which is built into the Visual Prolog system. The less than relation is no different from any other relation involving two numeric objects, but it is more natural to place the symbol for it between the two objects.

Now we will try to see if the following, expressed in natural language, is true:goals, disjunctivedisjunctive goals queries, disjunctive

    Is there a car listed that costs less than $25,000?, or is there a truck listed that costs less than $20,000?

Prolog will search for a solution if you set this compound goal:

    car(Make,Odometer,Years_on_road,Body,Cost), Cost<25000 ;
                                               /* subgoal A or */

    truck(Make,Odometer,Years_on_road,Body,Cost), Cost < 20000.
                                                /* subgoal B */

This kind of compound goal is known as a disjunction. This one sets up the two subgoals as alternatives, much as though they were two clauses for the same rule. Prolog will then find any solution that satisfies either of the subgoals.

To fulfill this compound goal, Prolog will try to solve the first subgoal ("find a car ..."), which is composed of these subgoals:

    car(Make, Odometer, Years_on_road, Body, Cost.)

and

    Cost < 25000.

If a car is found, the goal will succeed; if not, Prolog will try to fulfill the second compound goal ("find a truck ..."), made up of the subgoals

    truck(Make, Odometer, Years_on_road, Body, Cost),

and

    Cost < 20000.

5. Comments

It's good programming style to include comments in your program to explain things that might not be obvious to someone else (or to you in six months). This makes the program easy for you and others to understand. If you choose appropriate names for vari­ables, predicates, and domains, you'll need fewer comments, since the program will be more self-explanatory.

Multiple-line comments must begin with the characters /* (slash, asterisk) and end with the characters */ (asterisk, slash). To set off single-line comments, you can use these same characters, or you can begin the comment with a percent sign (%).

/* This is an example of a comment */
% This is also a comment
/***************************************/
/* and so are these three lines
        */
/***************************************/
/*You can also nest a Visual Prolog comment /*within a comment*/ like this */

In Visual Prolog 5.0 you can also use a comment after de decalratition of a domain.

    DOMAINS
        articles = book(STRING title, STRING author); horse(STRING name)

    PREDICATES
        conv(STRING uppercase,STRING lowercase)

The words title, author, name, uppercase and lowercase will be ignored by the compiler, but makes the program much more readable.