Prolog lab
Prolog lab
The syntax is actually the sequence The syntax is basically the logic
of statements like (a, s, I). formulae (Horn Clauses).
What is Prolog?
Prolog or PROgramming in LOGics is a logical and declarative
programming language. It is one major example of the fourth-generation
language that supports the declarative programming paradigm. This is
particularly suitable for programs that involve symbolic or non-numeric
computation. This is the main reason to use Prolog as the programming
language in Artificial Intelligence, where symbol
manipulation and inference manipulation are the fundamental tasks.
In Prolog, we need not mention the way how one problem can be solved,
we just need to mention what the problem is, so that Prolog automatically
solves it. However, in Prolog we are supposed to give clues as
the solution method.
Prolog language basically has three different elements −
Facts − The fact is predicate that is true, for example, if we say, “Tom is
the son of Jack”, then this is a fact.
Rules − Rules are extinctions of facts that contain conditional clauses. To
satisfy a rule these conditions should be met. For example, if we define a
rule as −
grandfather(X, Y) :- father(X, Z), parent(Z, Y)
This implies that for X to be the grandfather of Y, Z should be a parent of Y
and X should be father of Z.
Questions − And to run a prolog program, we need some questions, and
those questions can be answered by the given facts and rules.
History of Prolog
The heritage of prolog includes the research on theorem provers and
some other automated deduction system that were developed in 1960s
and 1970s. The Inference mechanism of the Prolog is based on Robinson’s
Resolution Principle, that was proposed in 1965, and Answer extracting
mechanism by Green (1968). These ideas came together forcefully with
the advent of linear resolution procedures.
The explicit goal-directed linear resolution procedures, gave impetus to
the development of a general purpose logic programming system.
The first Prolog was the Marseille Prolog based on the work
by Colmerauer in the year 1970. The manual of this Marseille Prolog
interpreter (Roussel, 1975) was the first detailed description of the Prolog
language.
Prolog is also considered as a fourth generation programming language
supporting the declarative programming paradigm. The well-known
Japanese Fifth-Generation Computer Project, that was announced in 1981,
adopted Prolog as a development language, and thereby grabbed
considerable attention on the language and its capabilities.
Now let us see how to run the Prolog script file (extension is *.pl)
into the Prolog console.
Before running *.pl file, we must store the file into the directory
where the GNU prolog console is pointing, otherwise just change the
directory by the following steps −
Step 1 − From the prolog console, go to File > Change Dir, then
click on that menu.
Step 2 − Select the proper folder and press OK.
Step 3 − Now create one file (extension is *.pl) and write the code
as follows −
main :- write('This is sample Prolog program'),
write(' This program is written into hello_world.pl file').
Now let’s run the code. To run it, we have to write the file name as
follows −
[hello_world]
The output is as follows −
Prolog - Basics
Knowledge Base − This is one of the fundamental parts of Logic
Programming. We will see in detail about the Knowledge Base, and how it
helps in logic programming.
Facts, Rules and Queries − These are the building blocks of logic
programming. We will get some detailed knowledge about facts and rules,
and also see some kind of queries that will be used in logic programming.
Here, we will discuss about the essential building blocks of logic
programming. These building blocks are Facts, Rules and the Queries.
Facts
We can define fact as an explicit relationship between objects, and
properties these objects might have. So facts are unconditionally true in
nature. Suppose we have some facts as given below −
Tom is a cat
Kunal loves to eat Pasta
Hair is black
Nawaz loves to play games
Pratyusha is lazy.
So these are some facts, that are unconditionally true. These are actually
statements, that we have to consider as true.
Following are some guidelines to write facts −
Names of properties/relationships begin with lower case
letters.
The relationship name appears as the first term.
Objects appear as comma-separated arguments within
parentheses.
A period "." must end a fact.
Objects also begin with lower case letters. They also can begin
with digits (like 1234), and can be strings of characters
enclosed in quotes e.g. color(penink, ‘red’).
phoneno(agnibha, 1122334455). is also called a predicate or
clause.
Syntax
The syntax for facts is as follows −
relation(object1,object2...).
Example
Following is an example of the above concept −
cat(tom).
loves_to_eat(kunal,pasta).
of_color(hair,black).
loves_to_play_games(nawaz).
lazy(pratyusha).
Rules
We can define rule as an implicit relationship between objects. So facts
are conditionally true. So when one associated condition is true, then the
predicate is also true. Suppose we have some rules as given below −
Lili is happy if she dances.
Tom is hungry if he is searching for food.
Jack and Bili are friends if both of them love to play cricket.
will go to play if school is closed, and he is free.
So these are some rules that are conditionally true, so when the right
hand side is true, then the left hand side is also true.
Here the symbol ( :- ) will be pronounced as “If”, or “is implied by”. This is
also known as neck symbol, the LHS of this symbol is called the Head, and
right hand side is called Body. Here we can use comma (,) which is known
as conjunction, and we can also use semicolon, that is known as
disjunction.
Syntax
rule_name(object1, object2, ...) :- fact/rule(object1,
object2, ...)
Suppose a clause is like :
P :- Q;R.
This can also be written as
P :- Q.
P :- R.
Is understood as
P :- (Q,R);(S,T,U).
Or can also be written as:
P :- Q,R.
P :- S,T,U.
Example
happy(lili) :- dances(lili).
hungry(tom) :- search_for_food(tom).
friends(jack, bili) :- lovesCricket(jack), lovesCricket(bili).
goToPlay(ryan) :- isClosed(school), free(ryan).
Queries
Queries are some questions on the relationships between objects and
object properties. So question can be anything, as given below −
Is tom a cat?
Does Kunal love to eat pasta?
Is Lili happy?
Will Ryan go to play?
So according to these queries, Logic programming language can find the
answer and return them.
Knowledge Base 1
Suppose we have some knowledge, that Priya, Tiyasha, and Jaya are three
girls, among them, Priya can cook. Let’s try to write these facts in a more
generic way as shown below −
girl(priya).
girl(tiyasha).
girl(jaya).
can_cook(priya).
Note − Here we have written the name in lowercase letters, because in
Prolog, a string starting with uppercase letter indicates a variable.
Now we can use this knowledge base by posing some queries. “Is priya a
girl?”, it will reply “yes”, “is jamini a girl?” then it will answer “No”,
because it does not know who jamini is. Our next question is “Can Priya
cook?”, it will say “yes”, but if we ask the same question for Jaya, it will
say “No”.
Output
GNU Prolog 1.4.5 (64 bits)
Compiled Jul 14 2018, 13:19:42 with x86_64-w64-mingw32-gcc
By Daniel Diaz
Copyright (C) 1999-2018 Daniel Diaz
| ?- change_directory('D:/TP Prolog/Sample_Codes').
yes
| ?- [kb1]
.
compiling D:/TP Prolog/Sample_Codes/kb1.pl for byte code...
D:/TP Prolog/Sample_Codes/kb1.pl compiled, 3 lines read - 489 bytes written,
10 ms
yes
| ?- girl(priya)
.
yes
| ?- girl(jamini).
no
| ?- can_cook(priya).
yes
| ?- can_cook(jaya).
no
| ?-
Let us see another knowledge base, where we have some rules. Rules
contain some information that are conditionally true about the domain of
interest. Suppose our knowledge base is as follows −
sing_a_song(ananya).
listens_to_music(rohit).
listens_to_music(ananya) :- sing_a_song(ananya).
happy(ananya) :- sing_a_song(ananya).
happy(rohit) :- listens_to_music(rohit).
playes_guitar(rohit) :- listens_to_music(rohit).
So there are some facts and rules given above. The first two are facts, but
the rest are rules. As we know that Ananya sings a song, this implies she
also listens to music. So if we ask “Does Ananya listen to music?”, the
answer will be true. Similarly, “is Rohit happy?”, this will also be true
because he listens to music. But if our question is “does Ananya play
guitar?”, then according to the knowledge base, it will say “No”. So these
are some examples of queries based on this Knowledge base.
Output
| ?- [kb2].
compiling D:/TP Prolog/Sample_Codes/kb2.pl for byte code...
D:/TP Prolog/Sample_Codes/kb2.pl compiled, 6 lines read - 1066 bytes
written, 15 ms
yes
| ?- happy(rohit).
yes
| ?- sing_a_song(rohit).
no
| ?- sing_a_song(ananya).
yes
| ?- playes_guitar(rohit).
yes
| ?- playes_guitar(ananya).
no
| ?- listens_to_music(ananya).
yes
| ?-
Knowledge Base 3
The facts and rules of Knowledge Base 3 are as follows −
can_cook(priya).
can_cook(jaya).
can_cook(tiyasha).
likes(priya,jaya) :- can_cook(jaya).
likes(priya,tiyasha) :- can_cook(tiyasha).
Suppose we want to see the members who can cook, we can use
one variable in our query. The variables should start with uppercase
letters. In the result, it will show one by one. If we press enter, then it will
come out, otherwise if we press semicolon (;), then it will show the next
result.
Let us see one practical demonstration output to understand how it works.
Output
| ?- [kb3].
compiling D:/TP Prolog/Sample_Codes/kb3.pl for byte code...
D:/TP Prolog/Sample_Codes/kb3.pl compiled, 5 lines read - 737 bytes written,
22 ms
warning: D:/TP Prolog/Sample_Codes/kb3.pl:1: redefining procedure
can_cook/1
D:/TP Prolog/Sample_Codes/kb1.pl:4: previous definition
yes
| ?- can_cook(X).
X = priya ? ;
X = jaya ? ;
X = tiyasha
yes
| ?- likes(priya,X).
X = jaya ? ;
X = tiyasha
yes
| ?-
Relationship is one of the main features that we have to properly mention
in Prolog. These relationships can be expressed as facts and rules. After
that we will see about the family relationships, how we can express family
based relationships in Prolog, and also see the recursive relationships of
the family.
We will create the knowledge base by creating facts and rules, and play
query on them.
Relations in Prolog
In Prolog programs, it specifies relationship between objects and
properties of the objects.
Suppose, there’s a statement, “Amit has a bike”, then we are actually
declaring the ownership relationship between two objects — one is Amit
and the other is bike.
If we ask a question, “Does Amit own a bike?”, we are actually trying to
find out about one relationship.
There are various kinds of relationships, of which some can be rules as
well. A rule can find out about a relationship even if the relationship is not
defined explicitly as a fact.
We can define a brother relationship as follows −
Two person are brothers, if,
They both are male.
They have the same parent.
Now consider we have the below phrases −
parent(sudip, piyus).
parent(sudip, raj).
male(piyus).
male(raj).
brother(X,Y) :- parent(Z,X), parent(Z,Y),male(X), male(Y)
These clauses can give us the answer that piyus and raj are brothers, but
we will get three pairs of output here. They are: (piyus, piyus), (piyus, raj),
(raj, raj). For these pairs, given conditions are true, but for the pairs
(piyus, piyus), (raj, raj), they are not actually brothers, they are the same
persons. So we have to create the clauses properly to form a relationship.
The revised relationship can be as follows −
A and B are brothers if −
A and B, both are male
They have same father
They have same mother
A and B are not same
Family Relationship in Prolog
Here we will see the family relationship. This is an example of complex
relationship that can be formed using Prolog. We want to make a family
tree, and that will be mapped into facts and rules, then we can run some
queries on them.
Suppose the family tree is as follows −
Here from this tree, we can understand that there are few relationships.
Here bob is a child of pam and tom, and bob also has two children — ann
and pat. Bob has one brother liz, whose parent is also tom. So we want to
make predicates as follows −
Predicates
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
parent(bob, peter).
parent(peter, jim).
From our example, it has helped to illustrate some important points −
We have defined parent relation by stating the n-tuples of
objects based on the given info in the family tree.
The user can easily query the Prolog system about relations
defined in the program.
A Prolog program consists of clauses terminated by a full stop.
The arguments of relations can (among other things) be:
concrete objects, or constants (such as pat and jim), or
general objects such as X and Y. Objects of the first kind in our
program are called atoms. Objects of the second kind are
called variables.
Questions to the system consist of one or more goals.
Some facts can be written in two different ways, like sex of family
members can be written in either of the forms −
female(pam).
male(tom).
male(bob).
female(liz).
female(pat).
female(ann).
male(jim).
Or in the below form −
sex( pam, feminine).
sex( tom, masculine).
sex( bob, masculine).
… and so on.
Now if we want to make mother and sister relationship, then we can write
as given below −
In Prolog syntax, we can write −
mother(X,Y) :- parent(X,Y), female(X).
sister(X,Y) :- parent(Z,X), parent(Z,Y), female(X), X \== Y.
Now let us see the practical demonstration −
X = pat ? ;
X = peter
yes
| ?-
mother(X,Y).
X = pam
Y = bob ? ;
X = pat
Y = jim ? ;
no
| ?- haschild(X).
X = pam ? ;
X = tom ? ;
X = tom ? ;
X = bob ? ;
X = bob ? ;
X = pat ? ;
X = bob ? ;
X = peter
yes
| ?- sister(X,Y).
X = liz
Y = bob ? ;
X = ann
Y = pat ? ;
X = ann
Y = peter ? ;
X = pat
Y = ann ? ;
X = pat
Y = peter ? ;
(16 ms) no
| ?-
Now let us see some more relationships that we can make from the
previous relationships of a family. So if we want to make a grandparent
relationship, that can be formed as follows −
We can also create some other relationships like wife, uncle, etc. We can
write the relationships as given below −
grandparent(X,Y) :- parent(X,Z), parent(Z,Y).
grandmother(X,Z) :- mother(X,Y), parent(Y,Z).
grandfather(X,Z) :- father(X,Y), parent(Y,Z).
wife(X,Y) :- parent(X,Z),parent(Y,Z), female(X),male(Y).
uncle(X,Z) :- brother(X,Y), parent(Y,Z).
So let us write a prolog program to see this in action. Here we will also see
the trace to trace-out the execution.
parent(pam,bob).
parent(tom,bob).
parent(tom,liz).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
parent(bob,peter).
parent(peter,jim).
mother(X,Y):- parent(X,Y),female(X).
father(X,Y):-parent(X,Y),male(X).
sister(X,Y):-parent(Z,X),parent(Z,Y),female(X),X\==Y.
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X),X\==Y.
grandparent(X,Y):-parent(X,Z),parent(Z,Y).
grandmother(X,Z):-mother(X,Y),parent(Y,Z).
grandfather(X,Z):-father(X,Y),parent(Y,Z).
wife(X,Y):-parent(X,Z),parent(Y,Z),female(X),male(Y).
uncle(X,Z):-brother(X,Y),parent(Y,Z).
Output
| ?- [family_ext].
compiling D:/TP Prolog/Sample_Codes/family_ext.pl for byte code...
D:/TP Prolog/Sample_Codes/family_ext.pl compiled, 27 lines read - 4646 bytes
written, 10 ms
| ?- uncle(X,Y).
X = peter
Y = jim ? ;
no
| ?- grandparent(X,Y).
X = pam
Y = ann ? ;
X = pam
Y = pat ? ;
X = pam
Y = peter ? ;
X = tom
Y = ann ? ;
X = tom
Y = pat ? ;
X = tom
Y = peter ? ;
X = bob
Y = jim ? ;
X = bob
Y = jim ? ;
no
| ?- wife(X,Y).
X = pam
Y = tom ? ;
X = pat
Y = peter ? ;
(15 ms) no
| ?-
Tracing the output
In Prolog we can trace the execution. To trace the output, you have to
enter into the trace mode by typing “trace.”. Then from the output we can
see that we are just tracing “pam is mother of whom?”. See the tracing
output by taking X = pam, and Y as variable, there Y will be bob as
answer. To come out from the tracing mode press “notrace.”
Program
| ?- [family_ext].
compiling D:/TP Prolog/Sample_Codes/family_ext.pl for byte code...
D:/TP Prolog/Sample_Codes/family_ext.pl compiled, 27 lines read - 4646 bytes
written, 10 ms
X = pam
Y = bob ? ;
X = pat
Y = jim ? ;
no
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- mother(pam,Y).
1 1 Call: mother(pam,_23) ?
2 2 Call: parent(pam,_23) ?
2 2 Exit: parent(pam,bob) ?
3 2 Call: female(pam) ?
3 2 Exit: female(pam) ?
1 1 Exit: mother(pam,bob) ?
Y = bob
yes
| ?-
male(jim).
male(bob).
male(tom).
male(peter).
parent(pam,bob).
parent(tom,bob).
parent(tom,liz).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
parent(bob,peter).
parent(peter,jim).
yes
| ?- predecessor(peter,X).
X = jim ? ;
no
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- predecessor(bob,X).
1 1 Call: predecessor(bob,_23) ?
2 2 Call: parent(bob,_23) ?
2 2 Exit: parent(bob,ann) ?
1 1 Exit: predecessor(bob,ann) ?
X = ann ? ;
1 1 Redo: predecessor(bob,ann) ?
2 2 Redo: parent(bob,ann) ?
2 2 Exit: parent(bob,pat) ?
1 1 Exit: predecessor(bob,pat) ?
X = pat ? ;
1 1 Redo: predecessor(bob,pat) ?
2 2 Redo: parent(bob,pat) ?
2 2 Exit: parent(bob,peter) ?
1 1 Exit: predecessor(bob,peter) ?
X = peter ? ;
1 1 Redo: predecessor(bob,peter) ?
2 2 Call: parent(bob,_92) ?
2 2 Exit: parent(bob,ann) ?
3 2 Call: predecessor(ann,_23) ?
4 3 Call: parent(ann,_23) ?
4 3 Fail: parent(ann,_23) ?
4 3 Call: parent(ann,_141) ?
4 3 Fail: parent(ann,_129) ?
3 2 Fail: predecessor(ann,_23) ?
2 2 Redo: parent(bob,ann) ?
2 2 Exit: parent(bob,pat) ?
3 2 Call: predecessor(pat,_23) ?
4 3 Call: parent(pat,_23) ?
4 3 Exit: parent(pat,jim) ?
3 2 Exit: predecessor(pat,jim) ?
1 1 Exit: predecessor(bob,jim) ?
X = jim ? ;
1 1 Redo: predecessor(bob,jim) ?
3 2 Redo: predecessor(pat,jim) ?
4 3 Call: parent(pat,_141) ?
4 3 Exit: parent(pat,jim) ?
5 3 Call: predecessor(jim,_23) ?
6 4 Call: parent(jim,_23) ?
6 4 Fail: parent(jim,_23) ?
6 4 Call: parent(jim,_190) ?
6 4 Fail: parent(jim,_178) ?
5 3 Fail: predecessor(jim,_23) ?
3 2 Fail: predecessor(pat,_23) ?
2 2 Redo: parent(bob,pat) ?
2 2 Exit: parent(bob,peter) ?
3 2 Call: predecessor(peter,_23) ?
4 3 Call: parent(peter,_23) ?
4 3 Exit: parent(peter,jim) ?
3 2 Exit: predecessor(peter,jim) ?
1 1 Exit: predecessor(bob,jim) ?
X = jim ?