<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.visual-prolog.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DmitriRybakov</id>
	<title>wiki.visual-prolog.com - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.visual-prolog.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=DmitriRybakov"/>
	<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Special:Contributions/DmitriRybakov"/>
	<updated>2026-05-24T03:32:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Fundamental_Prolog_Part_2&amp;diff=751</id>
		<title>Fundamental Prolog Part 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Fundamental_Prolog_Part_2&amp;diff=751"/>
		<updated>2007-12-20T13:11:37Z</updated>

		<summary type="html">&lt;p&gt;DmitriRybakov: /* Recursion Using Functors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FundamentalPrologNavbar}}&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn about some more fundamental ideas of Prolog programming; continuing from where we left off in the Part 1 of this tutorial (Fundamental Prolog). In this tutorial, we are going to concentrate on how data is &amp;#039;&amp;#039;modeled&amp;#039;&amp;#039; in Prolog, before we can perform actions on them. Hence, there are not much examples concerning code execution here. We are assuming that you are already familiar with the issues concerning &amp;#039;&amp;#039;&amp;#039;execution strategy&amp;#039;&amp;#039;&amp;#039; and how &amp;#039;&amp;#039;&amp;#039;side effects&amp;#039;&amp;#039;&amp;#039; convert the logic of a Prolog program into the desired &amp;#039;&amp;#039;&amp;#039;results&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
As in the [[Fundamental Prolog Part 1|Part 1]] of this tutorial, we shall continue to use the &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; environment to develop and learn Prolog. We shall get into the &amp;#039;&amp;#039;&amp;#039;Visual Prolog IDE&amp;#039;&amp;#039;&amp;#039; only in the latter parts of this series.&lt;br /&gt;
&lt;br /&gt;
==Functors==&lt;br /&gt;
&lt;br /&gt;
In Part 1 of the tutorial, all the people were represented as &amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot; and &amp;quot;Pam&amp;quot; etc. Now &amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot; and &amp;quot;Pam&amp;quot; are just the names of the individuals. The values of the names are simple data types or &amp;#039;&amp;#039;&amp;#039;simple domains&amp;#039;&amp;#039;&amp;#039;. In the case of the names of the people, the &amp;#039;&amp;#039;&amp;#039;simple domain&amp;#039;&amp;#039;&amp;#039; was a &amp;#039;&amp;#039;&amp;#039;string&amp;#039;&amp;#039;&amp;#039;. Other &amp;#039;&amp;#039;&amp;#039;simple domains&amp;#039;&amp;#039;&amp;#039; would be &amp;#039;&amp;#039;&amp;#039;numbers&amp;#039;&amp;#039;&amp;#039; (e.g.: &amp;#039;&amp;#039;&amp;#039;123&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;3.14&amp;#039;&amp;#039;&amp;#039;), &amp;#039;&amp;#039;&amp;#039;symbols&amp;#039;&amp;#039;&amp;#039; (e.g.: &amp;#039;&amp;#039;&amp;#039;xyz&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;chil_10&amp;#039;&amp;#039;&amp;#039;), and &amp;#039;&amp;#039;&amp;#039;characters&amp;#039;&amp;#039;&amp;#039; (e.g.: &amp;#039;&amp;#039;&amp;#039;&amp;amp;#39;5&amp;amp;#39;&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;&amp;amp;#39;c&amp;amp;#39;&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
However, individuals are represented by more characteristics than just their names. What if we need to represent all those characteristics together, instead of representing just their names? That means, we need some mechanism to represent &amp;#039;&amp;#039;&amp;#039;compound domains&amp;#039;&amp;#039;&amp;#039;; a collection of simpler &amp;#039;&amp;#039;&amp;#039;domains&amp;#039;&amp;#039;&amp;#039; held together.&lt;br /&gt;
&lt;br /&gt;
In the first part of this tutorial, we had tried putting together several characteristics of individuals together, (like the &amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039; and the &amp;#039;&amp;#039;&amp;#039;gender&amp;#039;&amp;#039;&amp;#039;), by inserting facts into the PIE system that concentrated on &amp;#039;&amp;#039;&amp;#039;entities&amp;#039;&amp;#039;&amp;#039; instead of relationships. Thus we had given the following facts to the system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;).&lt;br /&gt;
person(&amp;quot;John&amp;quot;, &amp;quot;male&amp;quot;).&lt;br /&gt;
person(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, there is another elegant method to sharpen our focus on the &amp;#039;&amp;#039;&amp;#039;entities&amp;#039;&amp;#039;&amp;#039; being represented.&lt;br /&gt;
&lt;br /&gt;
We can package both the Name and the Gender into a package using a formalization known as a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039;. The entire package can then be represented using a logical variable inside any Prolog clause, just like any other variables. For example, the above facts can be generically represented in a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;person(Name, Gender)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the above statement is neither a fact nor a predicate. Logically, it states that there is some &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; called &amp;#039;&amp;#039;&amp;#039;person&amp;#039;&amp;#039;&amp;#039; in the system, each of which has two characteristics, represented by the logical variables Name and Gender. The word &amp;#039;&amp;#039;person&amp;#039;&amp;#039; is known as a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, and the variables are its &amp;#039;&amp;#039;&amp;#039;arguments&amp;#039;&amp;#039;&amp;#039;. We shall now package our facts using these &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
As a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; always has a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, we shall henceforth use the term &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; in this tutorial, to represent the respective &amp;#039;&amp;#039;&amp;#039;compound domain.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
For now, let us modify the first example of the previous tutorial, so that we use our newly defined &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;person&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Please note that in the &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; (Prolog Inference Engine) that we are using, we can directly use a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; without any prior intimation to the Prolog engine (for example. we need NOT define a predicate or a fact called &amp;#039;&amp;#039;person&amp;#039;&amp;#039; for our code to work).&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig1.jpg]]&lt;br /&gt;
&lt;br /&gt;
If you study the two facts for the father relationship, you would notice that the persons described are richer than what was done before (The earlier code is commented out in-between the tokens &amp;#039;&amp;#039;&amp;#039;/*&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;*/&amp;#039;&amp;#039;&amp;#039; .). This time, each person is described with both the person&amp;#039;s name &amp;#039;&amp;#039;&amp;#039;and&amp;#039;&amp;#039;&amp;#039; his/her gender, using the person &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, whereas in the earlier tutorial (Fundamental Prolog (Part1)) we were only using the person&amp;#039;s name.&lt;br /&gt;
&lt;br /&gt;
After you have written the new code, ensure that the PIE engine is reset. Use &amp;#039;&amp;#039;&amp;#039;Engine -&amp;gt; Reset.&amp;#039;&amp;#039;&amp;#039; Then, you re-consult the code using &amp;#039;&amp;#039;&amp;#039;Engine -&amp;gt; Reconsult.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As before, on a blank line in the &amp;#039;&amp;#039;&amp;#039;Dialog&amp;#039;&amp;#039;&amp;#039; window type a goal (without the &amp;quot;?&amp;quot; sign- in front).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig2.jpg]]&lt;br /&gt;
&lt;br /&gt;
When the caret is placed at the end of the line, press the &amp;#039;&amp;#039;&amp;#039;Enter&amp;#039;&amp;#039;&amp;#039; key on your keyboard. &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; will now consider the text from the beginning of the line to the caret as a goal to execute. You should see the following result:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Now, you will notice that the results that are yielded are richer than what you got previously (See Tutorial 04: Fundamental Prolog (Part 1)).&lt;br /&gt;
&lt;br /&gt;
==Refining Further==&lt;br /&gt;
&lt;br /&gt;
If you take a look at the grandfather predicate, you would notice that it has a subtle bug: A person would have two grandfathers: one from the mother&amp;#039;s side and one from the father&amp;#039;s side, but the grandfather predicate as defined earlier would only yield the grandfather on the father&amp;#039;s side.&lt;br /&gt;
&lt;br /&gt;
Hence the grandfather predicate should be re-written as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;grandFather(Person, TheGrandFather):-&lt;br /&gt;
     parent(Person, ParentOfPerson), &lt;br /&gt;
     father(ParentOfPerson, TheGrandFather).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this predicate the logic states that a father of &amp;#039;&amp;#039;any&amp;#039;&amp;#039; parent could be the grandfather of the person in consideration.&lt;br /&gt;
&lt;br /&gt;
For that predicate to work, we need to define a predicate called father using the person &amp;#039;&amp;#039;&amp;#039;functor.&amp;#039;&amp;#039;&amp;#039; This predicate would troll through a database of facts explaining the &amp;quot;&amp;#039;&amp;#039;parents&amp;#039;&amp;#039;&amp;quot; defined in the system. This is a more elegant method for finding out the fathers, instead of presenting them as facts (as shown previously) because later on we can extend this concept to find out &amp;quot;&amp;#039;&amp;#039;mothers&amp;#039;&amp;#039;&amp;quot; in a similar fashion.&lt;br /&gt;
&lt;br /&gt;
This can be done in either of the following ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;/*1st version */&lt;br /&gt;
father(P, F) :-&lt;br /&gt;
    parent(P, F), &lt;br /&gt;
    F = person(_, &amp;quot;male&amp;quot;).    %Line 2&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;/* 2nd version */&lt;br /&gt;
father(P, person(Name, &amp;quot;male&amp;quot;)) :-&lt;br /&gt;
    parent(P, person(Name, &amp;quot;male&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The logic behind both the versions is the same, but the manner in which the logic is indicated to the Prolog engine is different. In the first version, the code in Prolog systematically examines each parent fact asserted into the code, and sees if the first logical variable (P) matches that passed down from the predicate head. If the variable does match, it checks if the second argument consists of a person &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, whose second argument is the string literal &amp;quot;male&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This example shows one important feature of &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;: The arguments of a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; can be taken apart and examined using regular Prolog variables and bound values (like the string literal in this example) If you see Line 2 (Look at the side of the comment &amp;#039;&amp;#039;%Line 2&amp;#039;&amp;#039; in the code for the first version), you would notice that we have used an anonymous variable (the underscore) for the first argument of the person &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; as we are (in that predicate) not interested in the name of the father.&lt;br /&gt;
&lt;br /&gt;
The second version also does the same thing as the first one. But this time, as the set of parent facts is examined; on arriving at the correct value for P, the code halts and returns the correct &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; data back to the predicate head, &amp;#039;&amp;#039;provided the second argument of that &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; is the string literal &amp;quot;male&amp;quot;&amp;#039;&amp;#039;. If you note, the functor was NOT bound to any intermediate Prolog variable, as it was done in the first version.&lt;br /&gt;
&lt;br /&gt;
The second version is much terser than the first one, and sometimes this method of writing the code can be less legible to beginners.&lt;br /&gt;
&lt;br /&gt;
Let us now use this code in a complete example, where we will give a suitable set of person&amp;#039;&amp;#039;&amp;#039;&amp;#039; facts:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig3b.jpg]]&lt;br /&gt;
&lt;br /&gt;
Now, after you re-consult the above code into &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039;, and give the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;grandFather(person&amp;#039;(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;), W)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the results would be as follows:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig3c.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Functors and Predicates==&lt;br /&gt;
&lt;br /&gt;
Technically, a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; represents a logical function that binds several domains together. In simpler words, a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; is a mechanism that teaches the Prolog Engine how to put together data from its component parts. It effectively puts parts of the data into a common box. You can also retrieve the parts subsequently, whenever required (like seen the previous examples). It may look like a Prolog fact or a predicate call, but it is not. It&amp;#039;s just a piece of data, which you can handle in much the same way as a string or a number.&lt;br /&gt;
&lt;br /&gt;
Please note that a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; has nothing to do with a function in other programming languages. It does not stand for some computation to be performed. It simply identifies the &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; and holds its arguments together.&lt;br /&gt;
&lt;br /&gt;
When you study the above example, you would notice that nothing special need to be done when logical variables are used to stand in for data represented by &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;. The logical variable that is used to stand in for such data, is written just like any other logical variable: A word starting with a capital letter. Thus, if we take a look at the &amp;#039;&amp;#039;grandFather&amp;#039;&amp;#039; predicate in the example in this tutorial; you would notice that nothing has changed when you compare it with the same predicate that was defined in the earlier tutorial (Fundamental Prolog (part 1)). After all, the logic of that predicate has not changed. So, you would not find any changes to the variables used inside that predicate.&lt;br /&gt;
&lt;br /&gt;
The biggest advantage of using &amp;#039;&amp;#039;&amp;#039;a functor&amp;#039;&amp;#039;&amp;#039; is that you are free to change the internal arguments of the &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; without changing much of the predicates that uses such a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; as you keep revising the code.&lt;br /&gt;
&lt;br /&gt;
That means, if you decide (in a later version of the code you are writing) to have one more argument for the &amp;#039;&amp;#039;person&amp;#039;&amp;#039;, you still need not change anything in the &amp;#039;&amp;#039;grandfather&amp;#039;&amp;#039; predicate.&lt;br /&gt;
&lt;br /&gt;
==Functors as Arguments==&lt;br /&gt;
&lt;br /&gt;
In the previous section, the person &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; was having two arguments: the Name and the Gender. Both happened to be simple domains i.e. &amp;#039;&amp;#039;&amp;#039;constants&amp;#039;&amp;#039;&amp;#039; such as &amp;quot;Bill&amp;quot; and, &amp;quot;male&amp;quot;. However, there is nothing that prevents us from putting a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; itself as an &amp;#039;&amp;#039;&amp;#039;argument&amp;#039;&amp;#039;&amp;#039; of another &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Suppose, you wanted to define a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; for a &amp;#039;&amp;#039;couple&amp;#039;&amp;#039; (i.e. a husband and a wife). This is an example of how you would use such a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;myPredicate(ACouple):-&lt;br /&gt;
    ACouple = couple(person(Husband, &amp;quot;male&amp;quot;), person(Wife, &amp;quot;female&amp;quot;)), &lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, you would notice that the &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; is defined by two &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;, each of which is a mixture of &amp;#039;&amp;#039;&amp;#039;variables&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;constants&amp;#039;&amp;#039;&amp;#039;. This can be done to reflect the logic of the data being represented. The logic used here is that a husband is always a &amp;quot;male&amp;quot; and wife is always a &amp;quot;female&amp;quot;; and a couple consists of a husband and a wife. All of which is consistent with the most common interpretation of what one means by a &amp;#039;&amp;#039;couple&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Though in &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; you cannot predefine the kind of grammar &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; can actually have; in &amp;#039;&amp;#039;&amp;#039;Visual Prolog&amp;#039;&amp;#039;&amp;#039; you can make such definitions. The advantage of defining a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; in such a manner is that later, when you create actual data using this &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, the Prolog engine will always check if the data being created was consistent with the grammar that data was supposed to adhere to.&lt;br /&gt;
&lt;br /&gt;
This comes to another characteristic of &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;: the &amp;#039;&amp;#039;couple&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; has been defined with two arguments and the &amp;#039;&amp;#039;&amp;#039;position&amp;#039;&amp;#039;&amp;#039; of these arguments reflects their logical association. It was explained in the first part of this tutorial, that the positions of the arguments of predicates have to be formalized by the programmer, who designs the code. Once formalized; the same positional formalization should be consistently used.&lt;br /&gt;
&lt;br /&gt;
The same strategy applies to the creation of &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; too: In the case of the &amp;#039;&amp;#039;couple&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, it so happened that we decided to represent the husband as the first argument, and the wife as the second one. Once this is done, then whenever data is created using such a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, then we need to ensure that the husband is always at the first position, and the wife in the second (in spite of what the women&amp;#039;s lib people may say!)&lt;br /&gt;
&lt;br /&gt;
Now, when we look back on the &amp;#039;&amp;#039;couple &amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, someone can correctly argue that if were so sure that the first argument is always a husband (who is always a male), and the second one is always a wife (who is always a female) then what is the need for making the arguments of the &amp;#039;&amp;#039;couple &amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; also as &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;? Hence, an example with a more simplified &amp;#039;&amp;#039;couple &amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; would be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;myPredicate(ACouple):-&lt;br /&gt;
    ACouple=couple(Husband, Wife), &lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hence; let us revert back to using &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; for the husband and wife... but this time we will use them, because we are not sure which position is for the husband and which is for the wife.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;myPredicate(Couple):-&lt;br /&gt;
     Couple = couple(person(PersonsName, PersonsGender), person(SpouseName, SpouseGender)), &lt;br /&gt;
     ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039;, both the following examples make logical sense:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;myPredicate(C1):-&lt;br /&gt;
    C1=couple(person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;), person(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;)), &lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
/* or */&lt;br /&gt;
myPredicate(C2):-&lt;br /&gt;
    C2=couple(person(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;), person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;)), &lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It should be pointed out that in the PIE (and many other Prolog Engines), there is no way to indicate whether a functor will receive simple domain or compound domain arguments, by looking at the variables that define the functor. This stems from the fact that in &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;compound domains&amp;#039;&amp;#039;&amp;#039; are directly used, without being declared anywhere, other than in the mind of the programmer.&lt;br /&gt;
&lt;br /&gt;
For example, if you wanted to use a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;person(Name, Gender)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; would as easily accept a logical variable such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;regardingAPerson(Somebody):-&lt;br /&gt;
    Somebody = &lt;br /&gt;
        person(&amp;quot;Pam&amp;quot;, &lt;br /&gt;
            person(&amp;quot;Pam&amp;quot;, &lt;br /&gt;
                person(&amp;quot;Pam&amp;quot;, &lt;br /&gt;
                   person(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;)&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        ), &lt;br /&gt;
    ...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which actually does not make any logical sense, in the current context. Luckily, &amp;#039;&amp;#039;&amp;#039;Visual Prolog&amp;#039;&amp;#039;&amp;#039;, does a much better job of differentiating between &amp;#039;&amp;#039;&amp;#039;simple domains&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;compound domains&amp;#039;&amp;#039;&amp;#039;, so, when you get to the latter tutorials, you would not have any such problems.&lt;br /&gt;
&lt;br /&gt;
==Recursion Using Functors==&lt;br /&gt;
&lt;br /&gt;
When data is described using &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;, it can be treated like any other piece of data. For example, you can write a predicate that can be made to recursively search through data which used &amp;#039;&amp;#039;&amp;#039;compound domains&amp;#039;&amp;#039;&amp;#039; using &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Let us get back briefly to the ancestor predicate, which we had used in the first part of the tutorial.&lt;br /&gt;
&lt;br /&gt;
In order to determine if somebody is an ancestor of someone else, we used a recursive definition for the predicate, i.e. a definition that is defined in terms of itself. like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;ancestor(Person, Ancestor) :- parent(Person, Ancestor).&lt;br /&gt;
ancestor(Person, Ancestor) :- parent(Person, P1), ancestor(P1, Ancestor).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This declaration states that a parent is an ancestor, and that an ancestor to a parent is also an ancestor. If you examine the variables in the above definition, it can very well stand for either &amp;#039;&amp;#039;&amp;#039;simple domains&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;compound domains.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Let us define the data thus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;parent(person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;), person(&amp;quot;John&amp;quot;, &amp;quot;male&amp;quot;)).&lt;br /&gt;
parent(person(&amp;quot;pam&amp;quot;, &amp;quot;female&amp;quot;), person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;)).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we now ask &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; to solve the following goal, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;P=person(&amp;quot;pam&amp;quot;, &amp;quot;female&amp;quot;), ancestor(P, Who)&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...this is what we will get:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_2_fig4.jpg]]&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039; engine has recursively examined the parent facts to reveal the two possible solutions to the answer. By the way, in the above query, you would also notice that we have bound a variable P to the person &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; when specifying the goal to &amp;#039;&amp;#039;&amp;#039;PIE&amp;#039;&amp;#039;&amp;#039;. This was done to make the code more readable but it also demonstrates the fact that we can bind a piece of data specified as a &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; into any Prolog variable.&lt;br /&gt;
&lt;br /&gt;
==Strategies for Using Functors==&lt;br /&gt;
&lt;br /&gt;
Software will be only as good as allowed by the modeled data. By the term &amp;#039;&amp;#039;modeling&amp;#039;&amp;#039;, we mean the establishment of a relationship between the subset of the outside real-world that is being tackled with the internal data structures of the software. If the modeling of data is poor, then it is likely that the software will also be poor; or at best, inefficient. This is true of any software written in any programming language. That was the reason in the latter part of the earlier tutorial (Fundamental Prolog (part 1)), we had tried to focus on the &amp;#039;&amp;#039;&amp;#039;entities&amp;#039;&amp;#039;&amp;#039; and tried to correct the situation by inserting richer facts. Similarly, we introduced the concept of &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; in this tutorial to get even more clarity on the data regarding &amp;#039;&amp;#039;&amp;#039;entities&amp;#039;&amp;#039;&amp;#039; that are being modeled.&lt;br /&gt;
&lt;br /&gt;
The advantage of Prolog is that it allows easy &amp;#039;&amp;#039;&amp;#039;description&amp;#039;&amp;#039;&amp;#039; of the real-world data in a form that can be internally utilized by the code in an efficient manner. Simultaneously, it also makes the code very readable by fellow programmers who are working together on a project.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Functors&amp;#039;&amp;#039;&amp;#039; can be used to create any type of &amp;#039;&amp;#039;&amp;#039;compound domain&amp;#039;&amp;#039;&amp;#039; to help in this modeling process. You would have to carefully examine the various parts of real-world data that you plan to process and convert them using &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; (and other data types that you would encounter in future tutorials) keeping in mind their usage in all critical parts of the software. Some data structures that were useful in one area of the software may prove to be a hindrance in other areas.&lt;br /&gt;
&lt;br /&gt;
You should take a holistic approach while zeroing in on the &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; (and other data structures) you plan to use in your software. Pause and look around at all the corners of your software. Only then should you code the necessary &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Just thinking carefully about the data structures is not the only thing that is required. You would also need to (often simultaneously) write/modify the various goals and sub-goals (i.e. predicates) and then use the data developed thus far in those predicates. The &amp;#039;&amp;#039;&amp;#039;side effects&amp;#039;&amp;#039;&amp;#039; of attaining those goals and sub-goals would make your software work and you can get valuable feedback with which you can further refine your data structures.&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we have not fleshed out a software design holistically. We have only nibbled at bits and pieces of data which establishes the &amp;#039;&amp;#039;&amp;#039;feel&amp;#039;&amp;#039;&amp;#039; for some kind of real-world data concerning relationship between people (&amp;#039;&amp;#039;parents&amp;#039;&amp;#039;, &amp;#039;&amp;#039;grandparents&amp;#039;&amp;#039;, &amp;#039;&amp;#039;families&amp;#039;&amp;#039;, &amp;#039;&amp;#039;ancestors&amp;#039;&amp;#039; etc.) In forthcoming tutorials, we will use this experience to establish a &amp;#039;&amp;#039;&amp;#039;red thread&amp;#039;&amp;#039;&amp;#039; that connects all these tutorials together; eventually ending up with a useful software that requires such data structures.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
In this lesson we learnt that data can comprise of &amp;#039;&amp;#039;&amp;#039;simple domains&amp;#039;&amp;#039;&amp;#039;, or they can be &amp;#039;&amp;#039;&amp;#039;compound domains&amp;#039;&amp;#039;&amp;#039; represented using &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039;. We found that the arguments of &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; must be positionally consistent with the logic they were meant to represent. We understood that a &amp;#039;&amp;#039;&amp;#039;functor&amp;#039;&amp;#039;&amp;#039; need not have just simple domains as arguments, but it can also have other &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; as arguments. We then learnt that data represented as &amp;#039;&amp;#039;&amp;#039;functors&amp;#039;&amp;#039;&amp;#039; can be used like any regular Prolog variable, and we can even perform all operations; including recursion, on such data.&lt;br /&gt;
&lt;br /&gt;
We also learnt that we must spend time modeling our subset of the real world for which we are developing the software, and get a feel for the data. We should simultaneously experiment with the predicates that you may wish to use with the data that is being modeled, so that they can be refined further.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>DmitriRybakov</name></author>
	</entry>
	<entry>
		<id>https://wiki.visual-prolog.com/index.php?title=Fundamental_Prolog_Part_1&amp;diff=750</id>
		<title>Fundamental Prolog Part 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.visual-prolog.com/index.php?title=Fundamental_Prolog_Part_1&amp;diff=750"/>
		<updated>2007-12-20T13:10:43Z</updated>

		<summary type="html">&lt;p&gt;DmitriRybakov: /* Program Control */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FundamentalPrologNavbar}}&lt;br /&gt;
&lt;br /&gt;
In this &amp;#039;&amp;#039;&amp;#039;Prolog tutorial&amp;#039;&amp;#039;&amp;#039; you will learn about the very fundamental ideas of Prolog language programming.&lt;br /&gt;
&lt;br /&gt;
Visual Prolog is object oriented, strictly typed and mode checked.&lt;br /&gt;
You will of course have to master all this to write Visual Prolog programs.&lt;br /&gt;
But in this tutorial we will focus on the &amp;#039;&amp;#039;core&amp;#039;&amp;#039; of the code, i.e. the Prolog code when disregarding classes, types and modes.&lt;br /&gt;
&lt;br /&gt;
For this purpose we will use the PIE example that is included in the Visual Prolog distribution PIE might be also [http://www.visual-prolog.com/vip/example/pie/pie.htm downloaded] from the WEB as an executable.&lt;br /&gt;
PIE is a &amp;quot;classical&amp;quot; Prolog interpreter, by using this you can learn and experiment with Prolog without at all being concerned with classes, types, etc.&lt;br /&gt;
&lt;br /&gt;
== Horn Clause Logic ==&lt;br /&gt;
&lt;br /&gt;
Visual Prolog and other Prolog language dialects are based on Horn Clause logic.&lt;br /&gt;
Horn Clause logic is a formal system for reasoning about things and the way they relate to each other.&lt;br /&gt;
&lt;br /&gt;
In natural language I can express a statement like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;John is the father of Bill.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here I have two &amp;quot;things&amp;quot;: John and Bill, and a &amp;quot;relation&amp;quot; between these, namely that one is the father of the other.&lt;br /&gt;
In Horn Clause Logic I can formalize this statement in the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;father(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
father is a predicate/relation taking two arguments, where the second is the father of the first.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Notice&amp;#039;&amp;#039;&amp;#039; that &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;I &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;have chosen that the &amp;#039;&amp;#039;&amp;#039;second&amp;#039;&amp;#039;&amp;#039; person should be the father of the &amp;#039;&amp;#039;&amp;#039;first&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
I might as well have chosen it the other way around:  The order of the arguments is the choice of the &amp;quot;designer&amp;quot; of the formalization.&lt;br /&gt;
However, once you have chosen, you must be consistent.&lt;br /&gt;
So in &amp;#039;&amp;#039;&amp;#039;my&amp;#039;&amp;#039;&amp;#039; formalization the father must &amp;#039;&amp;#039;&amp;#039;always&amp;#039;&amp;#039;&amp;#039; be the second person.&lt;br /&gt;
&lt;br /&gt;
I have chosen to represent the persons by their names (which are string literals).&lt;br /&gt;
In a more complex world this would not be sufficient because many people have same name.&lt;br /&gt;
But for now we will be content with this simple formalization.&lt;br /&gt;
&lt;br /&gt;
With formalizations like the one above I can state any kind of family relation between any persons.&lt;br /&gt;
But for this to become really interesting I will also have to formalize &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;rules&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X is the grandfather of Z, if X is the father of Y and Y is the father of Z&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where X, Y and Z are persons.&lt;br /&gt;
In Horn Clause Logic I can formalize this rule like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;grandFather(Person, GrandFather) :-&lt;br /&gt;
    father(Person, Father), father(Father, GrandFather).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I have chosen to use &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;variable&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; names that help understanding better than X, Y and Z.&lt;br /&gt;
I have also introduced a predicate for the grandfather relation.&lt;br /&gt;
Again I have chosen that the grandfather should be the second argument.&lt;br /&gt;
It is wise to be consistent like that, i.e. that the arguments of the different predicates follow some common principle.&lt;br /&gt;
When reading rules you should interpret :- as &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and the comma that separates the relations as &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;and&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Statements like &amp;quot;John is the father of Bill&amp;quot; are called &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;facts&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, while statements like &amp;quot;X is the grandfather of Z, if X is the father of Y and Y is the father of Z&amp;quot; are called &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;rules&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
With facts and rules we are ready to formulate theories.&lt;br /&gt;
A &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;theory&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; is a collection of facts and rules.&lt;br /&gt;
Let me state a little theory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;father(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
father(&amp;quot;Pam&amp;quot;, &amp;quot;Bill&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
grandFather(Person, GrandFather) :-&lt;br /&gt;
    father(Person, Father),&lt;br /&gt;
    father(Father, GrandFather).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The purpose of the theory is to answer questions like these:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;Is John the father of Sue?&lt;br /&gt;
Who is the father of Pam?&lt;br /&gt;
Is John the grandfather of Pam?&lt;br /&gt;
...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such questions are called goals.&lt;br /&gt;
And they can be formalized like this (respectively):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(&amp;quot;Sue&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
?- father(&amp;quot;Pam&amp;quot;, X).&lt;br /&gt;
?- grandFather(&amp;quot;Pam&amp;quot;, &amp;quot;John&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such questions are called &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;goal clauses&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; or simply &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;goals&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
Together &amp;#039;&amp;#039;facts&amp;#039;&amp;#039;, &amp;#039;&amp;#039;rules&amp;#039;&amp;#039; and &amp;#039;&amp;#039;goals&amp;#039;&amp;#039; are called Horn clauses, hence the name Horn Clause Logic.&lt;br /&gt;
&lt;br /&gt;
Some goals like the first and last are answered with a simple &amp;#039;&amp;#039;yes&amp;#039;&amp;#039; or &amp;#039;&amp;#039;no&amp;#039;&amp;#039;.&lt;br /&gt;
For other goals like the second we seek a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;solution&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, like X = &amp;quot;Bill&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Some goals may even have many solutions.&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(X, Y).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
has two solutions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;X = &amp;quot;Bill&amp;quot;, Y = &amp;quot;John&amp;quot;.&lt;br /&gt;
X = &amp;quot;Pam&amp;quot;, Y = &amp;quot;Bill&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A Prolog program is a theory and a goal.&lt;br /&gt;
When the program starts it tries to find a solution to the goal in the theory.&lt;br /&gt;
&lt;br /&gt;
== PIE: Prolog Inference Engine ==&lt;br /&gt;
&lt;br /&gt;
Now we will try the little example above in PIE, the Prolog Inference Engine that comes with Visual Prolog.&lt;br /&gt;
You can also [http://www.visual-prolog.com/vip/example/pie/pie.htm download] it from the web.&lt;br /&gt;
&lt;br /&gt;
Before we start you should install and build the PIE example.&lt;br /&gt;
&lt;br /&gt;
*Select &amp;quot;Install Examples&amp;quot; in the Windows start menu (&amp;#039;&amp;#039;&amp;#039;Start -&amp;gt; Visual Prolog -&amp;gt; Install Examples&amp;#039;&amp;#039;&amp;#039;).&lt;br /&gt;
*Open the PIE project in the VDE and &amp;#039;&amp;#039;&amp;#039;run&amp;#039;&amp;#039;&amp;#039; the program, as it is described in &amp;lt;a href=&amp;quot;../tut01/default.htm&amp;quot;&amp;gt;Tutorial 01: Environment Overview&amp;lt;/a&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When the program starts it will look like this:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_1_PIE.png|Prolog Inference Engine]]&lt;br /&gt;
&lt;br /&gt;
Select &amp;#039;&amp;#039;&amp;#039;File -&amp;gt; New&amp;#039;&amp;#039;&amp;#039; and enter the father and grandFather clauses above:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_1_GrandFather.png|Grand Father example]]&lt;br /&gt;
&lt;br /&gt;
While the editor window is active choose &amp;#039;&amp;#039;&amp;#039;Engine -&amp;gt; Reconsult&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
This will load the file into the engine.&lt;br /&gt;
In the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Dialog&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; window you should receive a message like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Reconsulted from: ....\pie\Exe\FILE4.PRO&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reconsult loads whatever is in the editor, &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;without&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; saving the contents to the file, if you want to save the contents use &amp;#039;&amp;#039;&amp;#039;File -&amp;gt; Save&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;File -&amp;gt; Consult&amp;#039;&amp;#039;&amp;#039; will load the disc contents of the file regardless of whether the file is opened for editing or not.&lt;br /&gt;
&lt;br /&gt;
Once you have &amp;quot;consulted&amp;quot; the theory, you can use it to answer goals.&lt;br /&gt;
&lt;br /&gt;
On a blank line in the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;Dialog&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; window type a goal (without the &amp;#039;&amp;#039;&amp;#039;?-&amp;#039;&amp;#039;&amp;#039; in front).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_1_goal1.png|Typing a goal]]&lt;br /&gt;
&lt;br /&gt;
When the caret is placed at the end of the line, press the &amp;#039;&amp;#039;&amp;#039;Enter&amp;#039;&amp;#039;&amp;#039; key on your keyboard.&lt;br /&gt;
PIE will now consider the text from the beginning of the line to the caret as a goal to execute.&lt;br /&gt;
You should see a result like this:&lt;br /&gt;
&lt;br /&gt;
[[Image:Fundamental_Prolog_1_goal2.png|Goal result]]&lt;br /&gt;
&lt;br /&gt;
== Extending the family theory ==&lt;br /&gt;
&lt;br /&gt;
It is straight forward to extend the family theory above with predicates like mother and grandMother.&lt;br /&gt;
You should try that yourself.&lt;br /&gt;
You should also add more persons.&lt;br /&gt;
I suggest that you use persons from your own family, because that makes it lot easier to validate, whether some person is indeed the grandMother of some other person, etc.&lt;br /&gt;
&lt;br /&gt;
Given mother and father we can also define a parent predicate.&lt;br /&gt;
You are a parent if you are a mother; you are also a parent if you are a father.&lt;br /&gt;
Therefore we can define parent using two clauses like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;parent(Person, Parent) :- mother(Person, Parent).&lt;br /&gt;
parent(Person, Parent) :- father(Person, Parent).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first rule reads (recall that the second argument corresponds to the predicate name):&lt;br /&gt;
&lt;br /&gt;
Parent is the parent of Person, if Parent is the mother of Person&lt;br /&gt;
&lt;br /&gt;
You can also define the parent relation using semicolon &amp;quot;;&amp;quot; which means or, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;parent(Person, Parent) :-&lt;br /&gt;
    mother(Person, Parent);&lt;br /&gt;
    father(Person, Parent).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This rule reads:&lt;br /&gt;
&lt;br /&gt;
Parent is the parent of Person, if Parent is the mother of Person &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;or&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; Parent is the father of Person&lt;br /&gt;
&lt;br /&gt;
I will however advise you to use semicolon as little as possible (or actually not at all).&lt;br /&gt;
There are several reasons for this:&lt;br /&gt;
&lt;br /&gt;
*The typographical difference &amp;quot;,&amp;quot; and &amp;quot;;&amp;quot; is very small, but the semantic difference is rather big.  &amp;quot;;&amp;quot; is often a source of confusion, since it is easily misinterpreted as &amp;quot;,&amp;quot;, especially when it is on the end of a long line.&lt;br /&gt;
*Visual Prolog only allows to use semicolon on the outermost level (PIE will allow arbitrarily deep nesting).&lt;br /&gt;
&lt;br /&gt;
Try creating a sibling predicate! Did that give problems?&lt;br /&gt;
&lt;br /&gt;
You might find that siblings are found &amp;#039;&amp;#039;&amp;#039;twice&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
At least if you say: Two persons are siblings if they have same mother, two persons are also siblings if they have same father.&lt;br /&gt;
I.e. if you have rules like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;sibling(Person, Sibling) :- mother(Person, Mother), mother(Sibling, Mother).&lt;br /&gt;
sibling(Person, Sibling) :- father(Person, Father), father(Sibling, Father).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first rule reads:&lt;br /&gt;
&lt;br /&gt;
Sibling is the sibling of Person, if Mother is the mother of Person &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;and&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; Mother is the mother of Sibling&lt;br /&gt;
&lt;br /&gt;
The reason that you receive siblings twice is that most siblings both have same father and mother, and therefore they fulfill both requirements above.&lt;br /&gt;
And therefore they are found twice.&lt;br /&gt;
&lt;br /&gt;
We shall not deal with this problem now; currently we will just accept that some rules give too many results.&lt;br /&gt;
&lt;br /&gt;
A fullBlodedSibling predicate does not have the same problem, because it will require that both the father and the mother are the same:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;fullBlodedSibling(Person, Sibling) :-&lt;br /&gt;
    mother(Person, Mother),&lt;br /&gt;
    mother(Sibling, Mother),&lt;br /&gt;
    father(Person, Father),&lt;br /&gt;
    father(Sibling, Father).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Prolog is a Programming Language ==&lt;br /&gt;
&lt;br /&gt;
From the description so far you might think that Prolog is an expert system, rather than a programming language.&lt;br /&gt;
And indeed Prolog can be used as an expert system, but it is designed to be a programming language.&lt;br /&gt;
&lt;br /&gt;
We miss two important ingredients to turn Horn Clause logic into a programming language:&lt;br /&gt;
&lt;br /&gt;
*Rigid search order/program control&lt;br /&gt;
*Side effects&lt;br /&gt;
&lt;br /&gt;
== Program Control ==&lt;br /&gt;
&lt;br /&gt;
When you try to find a solution to a goal like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(X, Y).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can do it in many ways.&lt;br /&gt;
For example, you might just consider at the second fact in the theory and then you have a solution.&lt;br /&gt;
&lt;br /&gt;
But Prolog does not use a &amp;quot;random&amp;quot; search strategy, instead it always use the same strategy.&lt;br /&gt;
The system maintains a &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;current goal&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, which is always solved from &amp;#039;&amp;#039;&amp;#039;left to right&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
I.e. if the current goal is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- grandFather(X, Y), mother(Y, Z).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the system will always try to solve the sub-goal grandFather(X, Y) before it solves mother(Y, Z), if the first (i.e. left-most) sub-goal cannot be solved then there is no solution to the overall problem and then the second sub-goal is not tried at all.&lt;br /&gt;
&lt;br /&gt;
When solving a particular sub-goal, the facts and rules are always tried from &amp;#039;&amp;#039;&amp;#039;top to bottom&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
When a sub-goal is solved by using a rule, the right hand side replaces the sub-goal in the current goal.&lt;br /&gt;
&lt;br /&gt;
I.e. if the current goal is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- grandFather(X, Y), mother(Y, Z).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And we are using the rule&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;grandFather(Person, GrandFather) :- father(Person, Father), father(Father, GrandFather).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to solve the first sub-goal, then the resulting current goal will be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(X, Father), father(Father, Y), mother(Y, Z).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that some variables in the rule have been replaced by variables from the sub-goal.&lt;br /&gt;
I will explain this in details later.&lt;br /&gt;
&lt;br /&gt;
Given this evaluation strategy you can interpret clauses much more &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;procedural&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;. Consider this rule:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;grandFather(Person, GrandFather) :- father(Person, Father), father(Father, GrandFather).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Given the strict evaluation we can read this rule like this:&lt;br /&gt;
&lt;br /&gt;
To solve grandFather(Person, GrandFather) &amp;#039;&amp;#039;&amp;#039;first&amp;#039;&amp;#039;&amp;#039; solve father(Person, Father) &amp;#039;&amp;#039;&amp;#039;and then &amp;#039;&amp;#039;&amp;#039;solve father(Father, GrandFather).&lt;br /&gt;
&lt;br /&gt;
Or even like this:&lt;br /&gt;
&lt;br /&gt;
When grandFather(Person, GrandFather) is &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;called&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, first &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;call&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; father(Person, Father) and then &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;call&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; father(Father, GrandFather).&lt;br /&gt;
&lt;br /&gt;
With this &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;procedural &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;reading you can see that predicates correspond to procedures/subroutines in other languages.&lt;br /&gt;
The main difference is that a Prolog predicate can return several solutions to a single invocation or even &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fail&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
This will be discussed in details in the next sections.&lt;br /&gt;
&lt;br /&gt;
== Failing ==&lt;br /&gt;
&lt;br /&gt;
A predicate invocation might not have any solution in the theory.&lt;br /&gt;
For example calling parent(&amp;quot;Hans&amp;quot;, X) has no solution as there are no parent facts or rules that applies to &amp;quot;Hans&amp;quot;.&lt;br /&gt;
We say that the predicate call &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;fails&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
If the goal fails then there is simply no solution to the goal in the theory.&lt;br /&gt;
The next section will explain how failing is treated in the general case, i.e. when it is not the goal that fails.&lt;br /&gt;
&lt;br /&gt;
== Backtracking ==&lt;br /&gt;
&lt;br /&gt;
In the procedural interpretation of a Prolog program &amp;quot;or&amp;quot; is treated in a rather special way.&lt;br /&gt;
Consider the clause&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;parent(Person, Parent) :-&lt;br /&gt;
    mother(Person, Parent);&lt;br /&gt;
    father(Person, Parent).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the logical reading we interpreted this clause as:&lt;br /&gt;
&lt;br /&gt;
Parent&lt;br /&gt;
is the parent of Person &amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Parent is the mother of&lt;br /&gt;
Person &amp;#039;&amp;#039;&amp;#039;or&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Parent is the father of Person.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;or&amp;quot; introduces two possible solutions to an invocation of the parent predicate.&lt;br /&gt;
Prolog handles such multiple choices by first trying one choice and later (if necessary) &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;backtracking&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; to the next alternative choice, etc.&lt;br /&gt;
&lt;br /&gt;
During the execution of a program a lot of alternative choices (known as &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;backtrack points&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;) might exist from earlier predicate calls.&lt;br /&gt;
If some predicate call fails, then we will backtrack to the last backtrack point we met and try the alternative solution instead.&lt;br /&gt;
If no further backtrack points exists then the overall goal has failed, meaning that there was no solution to it.&lt;br /&gt;
&lt;br /&gt;
With this in mind we can interpret the clause above like this:&lt;br /&gt;
&lt;br /&gt;
When parent(Person, Parent) is called first record a backtrack point to the second alternative solution (i.e. to the call to father(Person, Parent)) and then call mother(Person, Parent)&lt;br /&gt;
&lt;br /&gt;
A predicate that has several classes behave in a similar fashion.&lt;br /&gt;
Consider the clauses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;father(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
father(&amp;quot;Pam&amp;quot;, &amp;quot;Bill&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When father is invoked we first record a backtrack point to the second clause, and then try the first clause.&lt;br /&gt;
&lt;br /&gt;
If there are three or more choices we still only create one backtrack point, but that backtrack point will start by creating another backtrack point.&lt;br /&gt;
Consider the clauses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;father(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
father(&amp;quot;Pam&amp;quot;, &amp;quot;Bill&amp;quot;).&lt;br /&gt;
father(&amp;quot;Jack&amp;quot;, &amp;quot;Bill&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When father is invoked, we first record a backtrack point.&lt;br /&gt;
And then we try the first clause.&lt;br /&gt;
The backtrack point we create points to some code, which will itself create a backtrack point (namely to the third clause) and then try the second clause.&lt;br /&gt;
Thus all choice points have only two choices, but one choice might itself involve a choice.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Example&amp;#039;&amp;#039;&amp;#039; To illustrate how programs are executed I will go through an example in details.&lt;br /&gt;
Consider these clauses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;mother(&amp;quot;Bill&amp;quot;, &amp;quot;Lisa&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
father(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
father(&amp;quot;Pam&amp;quot;, &amp;quot;Bill&amp;quot;).&lt;br /&gt;
father(&amp;quot;Jack&amp;quot;, &amp;quot;Bill&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
parent(Person, Parent) :-&lt;br /&gt;
    mother(Person, Parent);&lt;br /&gt;
    father(Person, Parent).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then consider this goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(AA, BB), parent(BB, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This goal states that we want to find three persons AA, BB and CC, such that BB is the father of AA and CC is a parent of BB.&lt;br /&gt;
&lt;br /&gt;
As mentioned we always solve the goals from left to right, so first we call the father predicate.&lt;br /&gt;
When executing the father predicate we first create a backtrack point to the second clause, and then use the first clause.&lt;br /&gt;
&lt;br /&gt;
Using the first clause we find that AA is &amp;quot;Bill&amp;quot; and BB is &amp;quot;John&amp;quot;.&lt;br /&gt;
So we now effectively have the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;John&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we call parent, which gives the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- mother(&amp;quot;John&amp;quot;, CC); father(&amp;quot;John&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will notice that the variables in the clause have been replaced with the actual parameters of the call (exactly like when you call subroutines in other languages).&lt;br /&gt;
&lt;br /&gt;
The current goal is an &amp;quot;or&amp;quot; goal, so we create a backtrack point to the second alternative and pursuit the first.&lt;br /&gt;
We now have two active backtrack points, one to the second alternative in the parent clause, and one to the second clause in the father predicate.&lt;br /&gt;
&lt;br /&gt;
After the creation of this backtrack point we are left with the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- mother(&amp;quot;John&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we call the mother predicate.&lt;br /&gt;
The mother predicate fails when the first argument is &amp;quot;John&amp;quot; (because it has no clauses that match this value in the first argument).&lt;br /&gt;
&lt;br /&gt;
In case of failure we backtrack to the last backtrack point we created.&lt;br /&gt;
So we will now pursuit the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(&amp;quot;John&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When calling father this time, we will again first create a backtrack point to the second father clause.&lt;br /&gt;
&lt;br /&gt;
Recall that we also still have a backtrack point to the second clause of the father predicate, which corresponds to the first call in the original goal.&lt;br /&gt;
&lt;br /&gt;
We now try to use the first father clause on the goal, but that fails, because the first arguments do not match (i.e. &amp;quot;John&amp;quot; does not match &amp;quot;Bill&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Therefore we backtrack to the second clause, but before we use this clause we create a backtrack point to the third clause.&lt;br /&gt;
&lt;br /&gt;
The second clause also fails, since &amp;quot;John&amp;quot; does not match &amp;quot;Pam&amp;quot;, so we backtrack to the third clause.&lt;br /&gt;
This also fails, since &amp;quot;John&amp;quot; does not match &amp;quot;Jack&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now we must backtrack all the way back to the first father call in the original goal; here we created a backtrack point to the second father clause.&lt;br /&gt;
&lt;br /&gt;
Using the second clause we find that AA is &amp;quot;Pam&amp;quot; and BB is &amp;quot;Bill&amp;quot;.&lt;br /&gt;
So we now effectively have the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;Bill&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When calling parent we now get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- mother(&amp;quot;Bill&amp;quot;, CC); father(&amp;quot;Bill&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again we create a backtrack point to the second alternative and pursuit the first:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- mother(&amp;quot;Bill&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This goal succeeds with CC being &amp;quot;Lisa&amp;quot;.&lt;br /&gt;
So now we have found a solution to the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;AA = &amp;quot;Pam&amp;quot;, BB = &amp;quot;Bill&amp;quot;, CC = &amp;quot;Lisa&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When trying to find additional solutions we backtrack to the last backtrack point, which was the second alternative in the parent predicate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- father(&amp;quot;Bill&amp;quot;, CC).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This goal will also succeed with CC being &amp;quot;John&amp;quot;.&lt;br /&gt;
So now we have found one more solution to the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;AA = &amp;quot;Pam&amp;quot;, BB = &amp;quot;Bill&amp;quot;, CC = &amp;quot;John&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If we try to find more solutions we will find:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;AA = &amp;quot;Jack&amp;quot;, BB = &amp;quot;Bill&amp;quot;, CC = &amp;quot;John&amp;quot;.&lt;br /&gt;
AA = &amp;quot;Jack&amp;quot;, BB = &amp;quot;Bill&amp;quot;, CC = &amp;quot;Lisa&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After that we will experience that everything will eventually fail leaving no more backtrack points.&lt;br /&gt;
So all in all there are four solutions to the goal.&lt;br /&gt;
&lt;br /&gt;
== Improving the Family Theory ==&lt;br /&gt;
&lt;br /&gt;
If you continue to work with the family relation above, you will probably find out that you have problems with relations like &amp;#039;&amp;#039;brother&amp;#039;&amp;#039; and &amp;#039;&amp;#039;sister&amp;#039;&amp;#039;, because it is rather difficult to determine the sex of a person (unless the person is a father or mother).&lt;br /&gt;
&lt;br /&gt;
The problem is that we have chosen a bad way to formalize our theory.&lt;br /&gt;
&lt;br /&gt;
The reason that we arrived at this theory is because we started by considering the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;relations&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; between the entities.&lt;br /&gt;
If we instead first focus on the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;entities&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, then the result will naturally become different.&lt;br /&gt;
&lt;br /&gt;
Our main entities are persons.&lt;br /&gt;
Persons have a name (in this simple context will still assume that the name identifies the person, in a real scale program this would not be true).&lt;br /&gt;
Persons also have a sex.&lt;br /&gt;
Persons have many other properties, but none of them have any interest in our context.&lt;br /&gt;
&lt;br /&gt;
Therefore we define a person predicate, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;person(&amp;quot;Bill&amp;quot;, &amp;quot;male&amp;quot;).&lt;br /&gt;
person(&amp;quot;John&amp;quot;, &amp;quot;male&amp;quot;).&lt;br /&gt;
person(&amp;quot;Pam&amp;quot;, &amp;quot;female&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first argument of the person predicate is the name and the second is the sex.&lt;br /&gt;
&lt;br /&gt;
Instead of using mother and father as facts, I will choose to have parent as facts and mother and father as rules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;parent(&amp;quot;Bill&amp;quot;, &amp;quot;John&amp;quot;).&lt;br /&gt;
parent(&amp;quot;Pam&amp;quot;, &amp;quot;Bill&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
father(Person, Father) :- parent(Person, Father), person(Father, &amp;quot;male&amp;quot;).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that when father is a &amp;quot;derived&amp;quot; relation like this, it is impossible to state &amp;#039;&amp;#039;female&amp;#039;&amp;#039; fathers.&lt;br /&gt;
So this theory also has a built-in consistency on this point, which did not exist in the other formulation.&lt;br /&gt;
&lt;br /&gt;
== Recursion ==&lt;br /&gt;
&lt;br /&gt;
Most family relations are easy to construct given the principles above.&lt;br /&gt;
But when it comes to &amp;quot;infinite&amp;quot; relations like &amp;#039;&amp;#039;ancestor&amp;#039;&amp;#039; we need something more.&lt;br /&gt;
If we follow the principle above, we should define ancestor like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;ancestor(Person, Ancestor) :- parent(Person, Ancestor).&lt;br /&gt;
ancestor(Person, Ancestor) :- parent(Person, P1), parent(P1, Ancestor).&lt;br /&gt;
ancestor(Person, Ancestor) :- parent(Person, P1), parent(P1, P2), parent(P2, Ancestor).&lt;br /&gt;
...&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main problem is that this line of clauses never ends.&lt;br /&gt;
The way to overcome this problem is to use a recursive definition, i.e. a definition that is defined in terms of itself. like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;ancestor(Person, Ancestor) :- parent(Person, Ancestor).&lt;br /&gt;
ancestor(Person, Ancestor) :- parent(Person, P1), ancestor(P1, Ancestor).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This declaration states that a parent is an ancestor, and that an ancestor to a parent is also an ancestor.&lt;br /&gt;
&lt;br /&gt;
If you are not already familiar with recursion you might find it tricky (in several senses).&lt;br /&gt;
Recursion is however fundamental to Prolog programming.&lt;br /&gt;
You will use it again and again, so eventually you will find it completely natural.&lt;br /&gt;
&lt;br /&gt;
Let us try to execute an ancestor goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- ancestor(&amp;quot;Pam&amp;quot;, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We create a backtrack point to the second ancestor clause, and then we use the first, finding the new goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;Pam&amp;quot;, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This succeeds with the solution:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;AA = &amp;quot;Bill&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then we try to find another solution by using our backtrack point to the second ancestor clause.&lt;br /&gt;
This gives the new&lt;br /&gt;
goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;Pam&amp;quot;, P1), ancestor(P1, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again &amp;quot;Bill&amp;quot; is the&lt;br /&gt;
parent of &amp;quot;Pam&amp;quot;,&lt;br /&gt;
so we find P1=&lt;br /&gt;
&amp;quot;Bill&amp;quot;, and then we have the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- ancestor(&amp;quot;Bill&amp;quot;, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To solve this goal we first create a backtrack point to the second ancestor clause and then we use the first one.&lt;br /&gt;
This gives the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;Bill&amp;quot;, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This goal has the gives the solution:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;AA = &amp;quot;John&amp;quot;.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So now we have found two ancestors of &amp;quot;Pam&amp;quot;:&lt;br /&gt;
* &amp;quot;Bill&amp;quot; and&lt;br /&gt;
* &amp;quot;John&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
If we use the backtrack point to the second ancestor clause we get the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- parent(&amp;quot;Bill&amp;quot;, P1), ancestor(P1, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we will again find that&lt;br /&gt;
&amp;quot;John&amp;quot; is the parent of&lt;br /&gt;
&amp;quot;Bill&amp;quot;, and thus that&lt;br /&gt;
P1 is&lt;br /&gt;
&amp;quot;John&amp;quot;.&lt;br /&gt;
This gives the goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- ancestor(&amp;quot;John&amp;quot;, AA).&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you pursuit this goal you will find that it will not have any solution.&lt;br /&gt;
So all in all we can only find two ancestors of&lt;br /&gt;
&amp;quot;Pam&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Recursion is very powerful but it can also be a bit hard to control.&lt;br /&gt;
Two things are important to remember:&lt;br /&gt;
&lt;br /&gt;
*the recursion must make progress&lt;br /&gt;
*the recursion must terminate&lt;br /&gt;
&lt;br /&gt;
In the code above the first clause ensures that the recursion can terminate, because this clause is not recursive (i.e. it makes no calls to the predicate itself).&lt;br /&gt;
&lt;br /&gt;
In the second clause (which is recursive) we have made sure, that we go one ancestor-step further back, before making the recursive call.&lt;br /&gt;
I.e. we have ensured that we make some progress in the problem.&lt;br /&gt;
&lt;br /&gt;
== Side Effects ==&lt;br /&gt;
&lt;br /&gt;
Besides a strict evaluation order Prolog also has side effects.&lt;br /&gt;
For example Prolog has a number of predefined predicates for reading and writing.&lt;br /&gt;
&lt;br /&gt;
The following goal will write the found ancestors of &amp;quot;Pam&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- ancestor(&amp;quot;Pam&amp;quot;, AA), write(&amp;quot;Ancestor of Pam : &amp;quot;, AA), nl().&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ancestor call will find an ancestor of &amp;quot;Pam&amp;quot; in AA.&lt;br /&gt;
&lt;br /&gt;
The write call will write the string literal &amp;quot;Ancestor of Pam : &amp;quot;, and then it will write the value of AA.&lt;br /&gt;
&lt;br /&gt;
The nl call will shift to a new line in the output.&lt;br /&gt;
&lt;br /&gt;
When running programs in PIE, PIE itself writes solutions, so the overall effect is that your output and PIE&amp;#039;s own output will be mixed.&lt;br /&gt;
This might of course not be desirable.&lt;br /&gt;
&lt;br /&gt;
A very simple way to avoid PIE&amp;#039;s own output is to make sure that the goal has no solutions.&lt;br /&gt;
Consider the following goal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vip&amp;gt;?- ancestor(&amp;quot;Pam&amp;quot;, AA), write(&amp;quot;Ancestor of Pam : &amp;quot;, AA), nl(), fail.&amp;lt;/vip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fail is a predefined call that always fails (i.e. it has no solutions).&lt;br /&gt;
&lt;br /&gt;
The first three predicate calls have exactly the same effect as above: an ancestor is found (if such one exists, of course) and then it is written.&lt;br /&gt;
But then we call fail this will of course &amp;#039;&amp;#039; fail&amp;#039;&amp;#039;. Therefore we must pursuit a backtrack point if we have any.&lt;br /&gt;
&lt;br /&gt;
When pursuing this backtrack point, we will find another ancestor (if such one exists) and write that, and then we will fail again.&lt;br /&gt;
And so forth.&lt;br /&gt;
&lt;br /&gt;
So, we will find and write all ancestors. and eventually there will be no more backtrack points, and then the complete goal will fail.&lt;br /&gt;
&lt;br /&gt;
There are a few important points to notice here:&lt;br /&gt;
&lt;br /&gt;
*The goal itself did not have a single solution, but nevertheless all the solutions we wanted was given as side effects.&lt;br /&gt;
*Side effects in failing computations are not undone.&lt;br /&gt;
&lt;br /&gt;
These points are two sides of the same thing.&lt;br /&gt;
But they represent different level of optimism.&lt;br /&gt;
The first optimistically states some possibilities that you can use, while the second is more pessimistic and states that you should be aware about using side effects, because they are not undone even if the current goal does not lead to any solution.&lt;br /&gt;
&lt;br /&gt;
Anybody, who learns Prolog, will sooner or later experience unexpected output coming from failing parts of the program.&lt;br /&gt;
Perhaps, this little advice can help you:  Separate the &amp;quot;calculating&amp;quot; code from the code that performs input/output.&lt;br /&gt;
&lt;br /&gt;
In our examples above all the stated predicate are &amp;quot;calculating&amp;quot; predicates.&lt;br /&gt;
They all calculate some family relation.&lt;br /&gt;
If you need to write out, for example, &amp;quot;parents&amp;quot;, create a separate predicate for writing parents and let that predicate call the &amp;quot;calculating&amp;quot; parent predicate.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
In this tutorial we have looked at some of the basic features of Prolog.&lt;br /&gt;
You have seen &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;facts&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;rules&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;goals&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
You learned about the &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;execution strategy &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;for Prolog including the notion of &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;failing&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;backtracking&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
You have also seen that backtracking can give &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;many results &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;to a single question.&lt;br /&gt;
And finally you have been introduced to &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;side effects&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Fundamental Prolog Part 2]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>DmitriRybakov</name></author>
	</entry>
</feed>