Navigation  without Java Scripts

Visual Prolog Language Manual On-line

Welcome to this introduction to Visual prolog. This is a HTML-version of the first 3 chapters of the Visual Prolog Language manual.
This manual (and the rest of the chapters) can be downloaded with the Visual Prolog Timelocked version.
Along with the manuals,
you will also find the example programs, that are refered to in this text.

1. Prolog Fundamentals

This is the first in a sequence of chapters giving a step-by-step tutorial introduction to the Visual Prolog language. We begin this chapter with an introduction to programming in logic. After that we discuss some of Prolog's basic concepts, including clauses, predicates, variables, goals, and matching.

PROgramming in LOGic

In Prolog, you arrive at solutions by logically inferring one thing from something already known. Typically, a Prolog program isn't a sequence of actions--it's a collection of facts together with rules for drawing conclusions from those facts. Prolog is therefore what is known as a declarative language.

Prolog is based on Horn clauses, which are a subset of a formal system called predicate logic. Don't let this name scare you. Predicate logic is simply a way of making it clear how reasoning is done. It's simpler than arithmetic once you get used to it.

Prolog uses a simplified variation of predicate logic syntax because it provides an easy-to-understand syntax very similar to natural language, and because computers are not as fast, large, or as inexpensive as we would like. If Prolog were to accept English statements, the compiler would need to know every possible way something could be worded in English. In many cases, it would take many times longer to translate the program into something the computer understands than it would to run the program. The computer hardware needed to run such a system would be monstrous.

Prolog includes an inference engine, which is a process for reasoning logically about information. The inference engine includes a pattern matcher, which retrieves stored (known) information by matching answers to questions. Prolog tries to infer that a hypothesis is true (in other words, answer a question) by questioning the set of information already known to be true. Prolog's known world is the finite set of facts (and rules) that are given in the program.

One important feature of Prolog is that, in addition to logically finding answers to the questions you pose, it can deal with alternatives and find all possible solutions rather than only one. Instead of just proceeding from the beginning of the program to the end, Prolog can actually back up and look for more than one way of solving each part of the problem.

Predicate logic was developed to easily convey logic-based ideas into a written form. Prolog takes advantage of this syntax to develop a programming language based on logic. In predicate logic, you first eliminate all unnecessary words from your sentences. You then transform the sentence, placing the relationship first and grouping the objects after the relationship. The objects then become arguments that the relationship acts upon. For example, the following sentences are transformed into predicate logic syntax:

Natural Language: Predicate Logic:
A car is fun.

A rose is red.

fun(car).

red(rose).

Bill likes a car if the car is fun. likes(bill, Car) if fun(Car).

Sentences: Facts and Rules

A Prolog programmer defines objects and relations, then defines rules about when these relations are true. For example, the sentence

Bill likes dogs.

shows a relation between the objects Bill and dogs; the relation is likes. Here is a rule that defines when the sentence Bill likes dogs. is true:

Bill likes dogs if the dogs are nice.

Facts: What Is Known

In Prolog, a relation between objects is called a predicate. In natural language, a relation is symbolized by a sentence. In the predicate logic that Prolog uses, a relation is summarized in a simple phrase--a fact--that consists of the relation name followed by the object or objects (enclosed in parentheses). As with a sentence, the fact ends with a period (.).

Here are some more facts expressing "likes" relations in natural language:

Bill likes Cindy.
Cindy likes Bill.
Bill likes dogs.

Here are the same facts, written in Prolog syntax:

likes(bill, cindy).
likes(cindy, bill).
likes(bill, dogs).

Facts can also express properties of objects as well as relations; in natural language "Kermit is green" and "Caitlin is a girl." Here are some Prolog facts that express these same properties:

green(kermit).
girl(caitlin).

Rules: What You Can Infer from Given Facts

Rules enable you to infer facts from other facts. Another way to say this is that a rule, as conclusions is a conclusion that is known to be true if one or more other conclusions or facts are found to be true. Here are some rules concerning a "likes" relation:

Cindy likes everything that Bill likes.      
Caitlin likes everything that is green.      

Given these rules, you can infer from the previous facts some of the things that Cindy and Caitlin like:

Cindy likes Cindy.
Caitlin likes Kermit.

To encode these same rules into Prolog, you only need to change the syntax a little, like this:

likes(cindy, Something):- likes(bill, Something).
likes(caitlin, Something):- green(Something).

The :- symbol is simply pronounced "if", and serves to separate the two parts of a rule: the head and the body.

You can also think of a rule as a procedure. In other words, these rules

likes(cindy, Something):- likes(bill, Something)
likes(caitlin, Something):- green(Something).

also mean "To prove that Cindy likes something, prove that Bill likes that same thing" and "To prove that Caitlin likes something, prove that it is green." In the sameside effects procedural way, a rule can ask Prolog to perform actions other than proving things--such as writing something or creating a file.

Queries

Once we give Prolog a set of facts, we can proceed to ask questions concerning these facts; this is known as querying the Prolog system. We can ask Prolog the same type of questions that we would ask you about these relations. Based upon the known facts and rules given earlier, you can answer questions about these relations, just as Prolog can.

In natural language, we ask you:

Does Bill like Cindy?

In Prolog syntax, we ask Prolog:

likes(bill, cindy).

Given this query, Prolog would answer

yes

because Prolog has a fact that says so. As a little more complicated and general question, we could ask you in natural language:

What does Bill like?

In Prolog syntax, we ask Prolog:

likes(bill, What).

Notice that Prolog syntax does not change when you ask a question: this query looks very similar to a fact. However, it is important to notice that the second object--What--begins with a capital letter, while the first object--bill--does not. This is because bill is a fixed, constant object--aconstants known value--but What is a variable. Variables always begin with an upper-case letter or an underscore.

Prolog always looks for an answer to a query by starting at the top of the facts. It looks at each fact until it reaches the bottom, where there are no more. Given the query about what Bill likes, Prolog will return

What=cindy
What=dogs
2 Solutions

This is because Prolog knows

likes(bill, cindy).

and

likes(bill, dogs).

We hope that you draw the same conclusion.

If we were to ask you (and Prolog):

What does Cindy like?
likes(cindy, What).

Prolog would answer

What = bill
What = cindy
What = dogs
3 solutions

This is because Prolog knows that Cindy likes Bill, and that Cindy likes what Bill likes, and that Bill likes Cindy and dogs.

We could ask Prolog other questions that we might ask a person; however, a question such as "What girl does Bill like?" will yield no solution because Prolog, in this case, knows no facts about girls, and it can't draw any conclusions based on material not known (supplied to it). In this example, we have not given Prolog any relation or property to determine if any of the objects are girls.

Putting Facts, Rules, and Queries Together

Suppose you have the following facts and rules:

A fast car is fun.
A big car is nice.
A little car is practical.
Bill likes a car if the car is fun.

When you read these facts, you can deduce that Bill likes a fast car. In much the same way, Prolog will come to the same conclusion. If no fact were given about fast cars, then you would not be able to logically deduce what kind of a car Bill likes. You could take a guess at what kind of a car might be fun, but Prolog only knows what you tell it; Prolog does not guess.

Here's an example demonstrating how Prolog uses rules to answer queries. Look at the facts and rules in this portion of Program 1:

likes(ellen, tennis).
likes(john, football).
likes(tom, baseball).
likes(eric, swimming).
likes(mark, tennis).
likes(bill, Activity):- likes(tom, Activity).

The last line in Program 1 is a rule:

likes(bill, Activity):- likes(tom, Activity).

This rule corresponds to the natural language statement

Bill likes an activity if Tom likes that activity.

In this rule, the head is likes(bill, Activity), and the body is likes(tom, Activity). Notice that there is no fact in this example about Bill liking baseball. For Prolog to discover if Bill likes baseball, you can give the query

likes(bill, baseball).

When attempting to find a solution to this query, Prolog will use the rule:

likes(bill, Activity):- likes(tom, Activity).

Load Program ch02e01.pro into the Prolog System and run it.

PREDICATES
nondeterm likes(symbol,symbol)
 
CLAUSES
likes(ellen,tennis).
likes(john,football).
likes(tom,baseball).
likes(eric,swimming).
likes(mark,tennis).
 
likes(bill,Activity):-
likes(tom, Activity).
 
GOAL
likes(bill, baseball).

The system replies in the Dialog window

yes

It has combined the rule

likes(bill, Activity):- likes(tom, Activity).

with the fact

likes(tom, baseball).

to decide that

likes(bill, baseball).

Try also this query:

likes(bill, tennis).

The system replies

no

Visual Prolog replies no to the latest query ("Does Bill like tennis?") because

There is no fact that says Bill likes tennis.

Bill's relationship with tennis can't be inferred using the given rule and the available facts.

Of course, it may be that Bill absolutely adores tennis in real life, but Visual Prolog's response is based only upon the facts and the rules you have given it in the program.

Variables: General Sentences

In Prolog, variables enable you to write general facts and rules and ask general questions. In natural language, you use variables in sentences all the time. A typical general statement in English could be

Bill likes the same thing as Kim.

As we mentioned earlier in this chapter, to represent a variable in Prolog, the first character of the name must be an upper-case letter or an underscore. For example, in the following line, Thing is a variable.

likes(bill, Thing):- likes(kim, Thing).

In the preceding discussion of rules, you saw this line:

likes(cindy, Something):- likes(bill, Something).

The object Something begins with a capital letter because it is a variable; it must be able to match anything that Bill likes. It could equally well have been called X or Zorro.

The objects bill and cindy begin with lower-case letters because they are not variables--instead, they are symbols, having a constant value. Visual Prolog can also handle arbitrary text strings, much like we've been handling symbols above, if the text is surrounded by double quotes. Hence, the token bill could have been written as "Bill", if you wanted it to begin with an upper-case letter.

Overview

1. A Prolog program is made up of two types of phrases (also known as clauses): facts and rules.

Facts are relations or properties that you, the programmer, know to be true.

Rules are dependent relations; they allow Prolog to infer one piece of information from another. A rule becomes true if a given set of conditions is proven to be true. Each rule depends upon proving its conditions to be true.

2. In Prolog, all rules have two parts: a head and a body separated by the special :- token.

The head is the fact that would be true if some number of conditions were true. This is also known as the conclusion or the dependent relation.

The body is the set of conditions that must be true so that Prolog can prove that the head of the rule is true.

3. As you may have already guessed, facts and rules are really the same, except that a fact has no explicit body. The fact simply behaves as if it had a body that was always true.

4. Once you give Prolog a set of facts and/or rules, you can proceed to ask questions concerning these; this is known as querying the Prolog system. Prolog always looks for a solution by starting at the top of the facts and/or rules, and keeps looking until it reaches the bottom.

5. Prolog's inference engine takes the conditions of a rule (the body of the rule) and looks through its list of known facts and rules, trying to satisfy the conditions. Once all the conditions have been met, the dependent relation (the head of the rule) is found to be true. If all the conditions can't be matched with known facts, the rule doesn't conclude anything.

Exercises

Write natural language sentences that represent what these Prolog facts might convey to a human reader. (Remember that, to the computer, these facts are simple pieces of information that can be used for matching answers to questions.)

1. likes(jeff, painting).

2. male(john).

3. building("Empire State Building", new_york).

4. person(roslin, jeanie, "1429 East Sutter St.",

"Scotts Valley", "CA", 95066).

Write Visual Prolog facts that represent the following natural language statements:

Helen likes pizza.

San Francisco is in California.

Amy's telephone number is 476-0299.

Len's father is Alphonso Grenaldi.

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.

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

1. This first example shows a rule that can be used to conclude whether a menu item is suitable for Diane.

Diane is a vegetarian and eats only what her doctor tells her to eat.

Given a menu and the preceding rule, you can conclude if Diane can order a particular item on the menu. To do this, you must check to see if the item on the menu matches the constraints given.

a. Is Food_on_menu a vegetable?

b. Is Food_on_menu on the doctor's list?

c. Conclusion: If both answers are yes, Diane can order Food_on_menu.

In Prolog, a relationship like this must be represented by a rule because the conclusion is based on facts. Here's one way of writing the rule:

diane_can_eat(Food_on_menu):-
vegetable(Food_on_menu),
on_doctor_list(Food_on_menu).

Notice here the comma after vegetable(Food_on_menu). The comma introduces a conjunction of several goals, and is simply read as "and"; both vegetable(Food_on_menu) and on_doctor_list(Food_on_menu) must be true, for diane_can_eat(Food_on_menu) to be true.

Suppose you want to make a Prolog fact that is true if Person1 is the parent of Person2. This is easy enough; simply state the Prolog fact

parent(paul, samantha).

This shows that Paul is the parent of Samantha. But, suppose your Prolog database already has facts stating father relationships. For example, "Paul is the father of Samantha":

father(paul, samantha).

And you also have facts stating mother relationships; "Julie is the mother of Samantha":

mother(julie, samantha).

If you already had a collection of facts stating these father/mother relationships, it would be a waste of time to write parent facts into the database for each parent relationship.

Since you know that Person1 is the parent of Person2 if Person1 is the father of Person2 or if Person1 is the mother of Person2, then why not write a rule to convey these constraints? After stating these conditions in natural language, it should be fairly simple to code this into a Prolog rule by writing a rule that states the relationships.

parent(Person1, Person2):- father(Person1, Person2).
parent(Person1, Person2):- mother(Person1, Person2).

These Prolog rules simply state that

Person1 is the parent of Person2 if Person1 is the father of Person2.
Person1 is the parent of Person2 if Person1 is the mother of Person2.

3. Here's another example:

A person can buy a car if the person likes the car and the car is for sale.

This natural language relationship can be conveyed in Prolog with the following rule:

can_buy(Name, Model):-
person(Name),
car(Model),
likes(Name, Model),
for_sale(Model).

This rule shows the following relationship:

Name can_buy Model if
Name is a person and
Model is a car and
Name likes Model and
Model is for sale.

This Prolog rule will succeed if all four conditions in the body of the rule succeed.

4. Here is a program designed to find solutions to this car-buying problem:

/* Program ch02e02.pro */

PREDICATES
nondeterm can_buy(symbol, symbol)
nondeterm person(symbol)
nondeterm car(symbol)
likes(symbol, symbol)
for_sale(symbol)
CLAUSES
can_buy(X,Y):-
person(X),
car(Y),
likes(X,Y),
for_sale(Y).
person(kelly).
person(judy).
person(ellen).
person(mark).
car(lemon).
car(hot_rod).
likes(kelly, hot_rod).
likes(judy, pizza).
likes(ellen, tennis).
likes(mark, tennis).
for_sale(pizza).
for_sale(lemon).
for_sale(hot_rod).

What can Judy and Kelly buy? Who can buy the hot rod? You can try the following goals:

can_buy(Who, What).
can_buy(judy, What).
can_buy(kelly, What).
can_buy(Who, hot_rod).

Experiment! Add other facts and maybe even a rule or two to this Prolog program. Test the new program with queries that you make up. Does Prolog respond in a way you would expect it to?

Exercises

Write natural-language sentences corresponding to the following Visual Prolog rules:

eats(Who, What):- food(What), likes(Who, What).
pass_class(Who):- did_homework(Who), good_attendance(Who).
does_not_eat(toby, Stuff):- food(Stuff), greasy(Stuff).
owns(Who, What):- bought(Who, What).

Write Visual Prolog rules that convey the meaning of these natural-language sentences:

a. A person is hungry if that person's stomach is empty.

b. Everybody likes a job if it's fun and it pays well.

c. Sally likes french fries if they're cooked.

d. Everybody owns a car who buys one, pays for it, and keeps it.

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.

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

IncomeAndExpenditureAccount

How Variables Get Their Values

You may have noticed that Prolog has no assignment statement; this is a significant distinction between Prolog and other programming languages. Variables in Prolog get their values by being matched to constants in facts or rules.

Until it gets a value, a variable is said to be free; when it gets a value, it becomes bound. But it only stays bound for the time needed to obtain one solution to the query; then Prolog unbinds it, backs up, and looks for alternative solutions.

This is a very important point: You can't store information by giving a value to a variable. Variables are used as part of the pattern-matching, process, not as a kind of information storage.

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

/* Program ch02e03.pro */

PREDICATES
nondeterm likes(symbol,symbol)
CLAUSES
likes(ellen,reading).
likes(john,computers).
likes(john,badminton).
likes(leonard,badminton).
likes(eric,swimming).
likes(eric,reading).

Consider this query: Is there a person who likes both reading and swimming?

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

Prolog will solve the two parts of this query by searching the program's clauses from top to bottom. In the first part of the query

likes(Person, reading)

the variable Person is free; its value is unknown before Prolog attempts to find a solution. On the other hand, the second argument, reading, is known. Prolog searches for a fact that matches the first part of the query. The first fact in the program

likes(ellen, reading)

is a match (reading in the fact matches reading in the query), so Prolog binds the free variable Person to the value ellen, the relevant value in the fact. At the same time, Prolog places a pointer in the list of facts indicating how far down the search procedure has reached.

Next, in order for the query to be fully satisfied (find a person who likes both reading and swimming), the second part must also be fulfilled. Since Person is now bound to ellen, Prolog must search for the fact

likes(ellen, swimming)

Prolog searches for this fact from the beginning of the program, but no match occurs (because there is no such fact in the program). The second part of the query is not true when Person is ellen.

Prolog now "unbinds" Person and attempts another solution of the first part of the query with Person once again a free variable. The search for another fact that fulfills the first part of the query starts from the pointer in the list of facts. (This returning to the place last marked is known as backtracking, which we'll cover in chapter 4.)

Prolog looks for the next person who likes reading and finds the fact likes(eric, reading). Person is now bound to eric, and Prolog tries once again to satisfy the second part of the query, this time by looking in the program for the fact

likes(eric, swimming)

This time it finds a match (the last clause in the program), and the query is fully satisfied. Prolog returns

Person=eric
1 Solution

Anonymous Variables

Anonymous variables enable you to unclutter your programs. If you only need certain information from a query, you can use anonymous variables to ignore the values you don't need. In Prolog, the anonymous variable is represented by a lone underscore ("_").

The following parents example demonstrates how the anonymous variable is used. Load Program 4.

/* Program ch02e04.pro */

PREDICATES
male(symbol)
female(symbol)
nondeterm parent(symbol, symbol)
CLAUSES
male(bill).
male(joe).
female(sue).
female(tammy).
parent(bill,joe).
parent(sue,joe).
parent(joe,tammy).

The anonymous variable can be used in place of any other variable. The difference is that the anonymous variable will never get set to a value.

For example, in the following query, you need to know which people are parents, but you don't need to know who their children are. Prolog realizes that each time you use the underscore symbol in the query, you don't need information about what value is represented in that variable's place.

GOAL
parent(Parent, _).
Given this query, Prolog replies
Parent=bill
Parent=sue
Parent=joe
3 Solutions

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.

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

As you have seen, you can use a compound goal to find a solution where both subgoal A and subgoal B are true (a conjunction), by separating the subgoals with a comma, but this is not all. You can also find a solution where subgoal A or subgoal B is true (a disjunction), by separating the subgoals with a semicolon. Here's an example program illustrating this idea:

/* Program ch02e05.pro */

PREDICATES
car(symbol,long,integer,symbol,long)
truck(symbol,long,integer,symbol,long)
nondeterm vehicle(symbol,long,integer,symbol,long)
CLAUSES
car(chrysler,130000,3,red,12000).
car(ford,90000,4,gray,25000).
car(datsun,8000,1,red,30000).
truck(ford,80000,6,blue,8000).
truck(datsun,50000,5,orange,20000).
truck(toyota,25000,2,black,25000).
vehicle(Make,Odometer,Age,Color,Price):-
car(Make,Odometer,Age,Color,Price);
truck(Make,Odometer,Age,Color,Price).

Load and run this program, then try the goal

GOAL car(Make, Odometer, Years_on_road, Body, 25000).

This goal attempts to find a car described in the clauses that costs exactly $25,000. Prolog replies

Make=ford, Odometer=90000, Years_on_road=4, Body=gray
1 Solution

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.

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 variables, 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.

What Is a Match?

In the previous sections of this chapter, we've talked about Prolog "matching answers to questions", "finding a match", "matching conditions with facts", "matching variables with constants", and so on. In this section we explain what we mean when we use the term "match."

There are several ways Prolog can match one thing to another. Obviously, identical structures match each other;

parent(joe,tammy) matches parent(joe,tammy).

However, a match usually involves one or more free variables. For example, with X free,

parent(joe,X) matches parent(joe,tammy)

and X takes on (is bound to) the value tammy.

If X is already bound, it acts exactly like a constant. Thus, if X is bound to the value tammy, then

parent(joe,X) matches parent(joe,tammy) but

parent(joe,X) would not match parent(joe,millie)

The second instance doesn't match because, once a variable becomes bound, its value can't change.

How could a variable, bindings already be bound when Prolog tries to match it with something? Remember that variables don't store values--they only stay bound for the length of time needed to find (or try to find) one solution to one goal. So the only way a variable could be bound before trying a match is that the goal involves more than one step, and the variable became bound in a previous step. For example,

parent(joe,X), parent(X,jenny)

is a legitimate goal; it means, "Find someone who is a child of Joe and a parent of Jenny." Here X will already be bound when the subgoal parent(X,jenny) is reached. If there is no solution to parent(X,jenny), Prolog will unbind X and go back and try to find another solution to parent(joe,X), then see if parent(X,jenny) will work with the new value of X.

Two free variables can even match each other. For example,

parent(joe,X) matches parent(joe,Y)

binding the variables X and Y to each other. As long as the binding lasts, X and Y are treated as a single variable, and if one of them gets a value the other one will immediately have the same value. When free variables are bound to each other like this, they're called pointers, shared free sharing variables. Some really powerful programming techniques involve binding together variables that were originally separate.

In Prolog, variable bindings (values) are passed in two ways: in and out. The direction in which a value is passed is referred to as its flow pattern. When a variable is passed into a clause, it is an input , argument, signified by (i); when passed out of a clause, a variable is an output argument, signified by (o).

Summary

These are the ideas we've introduced in this brief introduction:

1. A Prolog program is made up of clauses, which conceptually are two types of phrases: facts and rules.

Facts are relations or properties that you, the programmer, know to be true.

Rules are dependent relations; they allow Prolog to infer one piece of information from another.

2. Facts have the general form:

property(object1, object2, ..., objectN)

or

relation(object1, object2, ..., objectN)

where a property is a property of the objects and a relation is a relation between the objects. As far as Prolog programming goes, the distinction doesn't exist and we will refer to both as relations in this book.

3. Each fact given in a program consists of either a relation that affects one or more objects or a property of one or more objects. For example, in the Prolog fact

likes(tom, baseball).

the relation is likes, and the objects are tom and baseball; Tom likes baseball. Also, in the fact

left_handed(benjamin)

the property is left_handed and the object is benjamin; in other words, Benjamin is left-handed.

4. Rules have the general form Head:- Body, which looks like this in a program:

relation(object,object,...,object):-
relation(object,...,object),
.
.
relation(object,...,object).

5. You are free to choose names for the relations and objects in your programs, subject to the following constraints:

Object names must begin with a lower-case letter, followed by any number of characters; characters are upper-case or lower-case letters, digits, and underscores.

Properties and relation names must start with a lower-case letter, followed by any combination of letters, digits, and underscore characters.

6. A predicate is the symbolic name (identifier) for a relation and a sequence of arguments. A Prolog program is a sequence of clauses and directives, and a procedure is a sequence of clauses defining a predicate. Clauses that belong to the same predicate must follow one another.

7. Variables enable you to write general facts and rules and ask general questions.

Variable names in Visual Prolog must begin with a capital letter or an underscore character (_), after which you can use any number of letters (upper-case or lower-case), digits, or underscores.

Variables in Prolog get their values by being matched to constants in facts or rules. Until it gets a value, a variable is said to be free; when it gets a value, it becomes bound.

You can't store information globally by binding a value to a variable, because a variable is only bound within a clause.

8. If you only need certain information from a query, you can use anonymous variables to ignore the values you don't need. In Prolog, the anonymous variable is represented by a lone underscore (_).

The anonymous variable can be used in place of any other variable; it matches anything. The anonymous variable will never get set to a value.

9. Asking Prolog questions about the facts in your program is known as querying the Prolog system; the query is commonly called a goal. Prolog tries to satisfy a goal (answer the query) by starting at the top of the facts, looking at each fact until it reaches the bottom.

10. A compound goal is a goal made up of two or more parts; each part of the compound goal is called a subgoal. Compound goals can be conjunctions (subgoal A and subgoal B) or disjunctions (subgoal A or subgoal B).

11. Comments make your programs easier to read; you can enclose a comment with delimiters /* like this */ or precede a single-line comment with a percent sign, % like this.

12. There are several ways Prolog can match one thing to another:

Identical structures match each other.

A free variable matches a constant or a previously-bound variable (and becomes bound to that value).

Two free variables can match (and be bound to) each other. As long as the binding lasts, they are treated as a single variable; if one gets a value the other will immediately have the same value.

Go to next section