A Unit of S.V.S.U: Chhatrapati Shahuji Subharti Institute of Technology & Engineering
A Unit of S.V.S.U: Chhatrapati Shahuji Subharti Institute of Technology & Engineering
A Unit of S.V.S.U: Chhatrapati Shahuji Subharti Institute of Technology & Engineering
INSTITUTE
OF TECHNOLOGY &
ENGINEERING
A UNIT OF S.V.S.U
SUBHARTIPURAM, N.H 58, DELHI-HARIDWAR- BY PASS ROAD
MEERUT 250005
INDEX
S.NO
1.
LIST OF EXPERIMENTS
STUDY OF PROLOG
A program in prolog to find the factorial of a given no.
2.
3.
4.
5.
6.
7.
8.
9.
10.
.The
"Water-jugs Problem"
Goal of AI Lab
Prolog was invented in the early seventies at the University of
Marseille. Prolog stands for Programming in Logic. It is a logic
language that is particularly used by programs that use nonnumeric objects. For this reason it is a frequently used language in
Artificial Intelligence where manipulation of symbols is a common
task. Prolog differs from the most common programmings
languages because it is declarativre language. Traditional
programming languages are said to be procedural. This means that
the programmer specify how to solve a problem. In declarative
languages the programmers only give the problem and the language
find
himself
how
to
solve
the
problem.
Although it can be, and often is, used by itself, Prolog complements
traditional languages when used together in the same application.
Presentation of Prolog
1.1 What is a Prolog program
Programming in Prolog is very different from programming in a
traditional procedural language like Pascal. In Prolog you don't say
how the program will work.
Prolog can be separated in two parts :
2 The Facts
2.1 Simple facts
In Prolog we can make some statements by using facts. Facts either
consist of a particular item or a relation between items. For example
we can represent the fact that it is sunny by writing the program :
sunny.
We can now ask a query of Prolog by asking
?- sunny.
?- is the Prolog prompt. To this query, Prolog will answer yes. sunny
is true because (from above) Prolog matches it in its database of
facts.
Facts have some simple rules of syntax. Facts should always begin
with a lowercase letter and end with a full stop. The facts themselves
can consist of any letter or number combination, as well as the
underscore _ character. However, names containing the characters -,
+,*,/, or other mathematical operators should be avoided.
likes(john,mary).
In the above fact john and mary are two atomes. Atoms are usally
made from letters and digits with lowercase characters. The
underscore (_) can also be used to separe 2 words but is not allowed
as the first charactere. Atoms can also be legally made from
symbols. The followings are legal atoms :atoms
hello
zz42
two_words
====>
eats(tony,apple).
eats(john,apple).
VaRiAbLe
*/
?- eats(Who,oranges).
In this example we ask who eats oranges. To this query Prolog
should answer :
?- eats(Who,oranges).
Who=fred
yes
Now if we ask :
?- eats(Who,apple).
no
Prolog answer no because he can't find in his database any atom
than can match with this relation.
Now if we only want to know if something is eated by anyone and we
don't care about that person we can use the underscore. The '_' can
be used like any variable.
For example if we ask eats(fred,_) the result will be :
?- eats(fred,_).
yes
The result will be yes because Prolog can find a relation of eat
between fred and something. But Prolog will not tell use the value of
'_'.
Now if we have the following program :
eats(fred,apple).
eats(fred,oranges).
Now if we ask :
?- eats(fred,What).
4 Rules
4.1 Rules
Consider the following sentence : 'All men are mortal' We can
express this thing in Prolog by :
mortal(X) :- human(X).
The clause can be read as 'X is mortal if X is human'.
To continue with this example, let us define the fact that Socrate is a
human. Our program will be :
mortal(X) :- human(X).
human(socrate).
Now if we ask to prolog :
?- mortal(socrate).
Prolog will respond :
yes
In order to solve the query -? mortal(socrates). Prolog will use the
rule we have given. It says that in order to prove that someone is
mortal we can prove that he is human. So from the goal
mortal(socrate) Prolog generate the subgoal human(socrate).
We can still use variables. For example we might want to know who
is mortal :
?- mortal(X).
Then Prolog should respond :
P=socrate
This means that Prolog was able to succed the goal by unifying the
variable X to socrates. Again this was done by using the subgoal
human(X).
Sometimes we may wish to specify alternatives ways to provre
something. We can do this by using differents rules ands facts with
the same name. For exeample, we can represent the sentence
'Something is fun if it is a PC running UNIX or am old amiga or an
ice cream' with the following program :
fun(X) :pc(X),
unix(X).
/* something is fun if
/* it is a pc and
/* it is running unix
*/
*/
*/
fun(X) :old(X),
/* or it is fun if
/* it is old and
amiga(X). /* it is an amiga
*/
*/
*/
fun(ice_cream).
/* the ice_crean is also fun */
This program says that there are three ways to know if an object is
fun or not. Like for pure facts, Prolog will start from the first clause
(a clause can be a rule or a fact) of fun and try it. If that does not
succed Prolog will try the next clause. If there is no more clauses
then it fails and Prolog responds ' no '. We can also see in this
example that the 'and' is represented by a ',' and the 'or' by
differents clause. If needed the 'or' can also be represebted by ';'. In
the previous examples when we was asking eats(fred,What) and
pressing the key ';' to see the following results we was in fact asking
'or'.
All identically-named variables in a rule (for example X in the last
rule we've seem) are of course considered as one unic variable and
must have the same instantiation for each solution in a particular
query. Identical variables names in differents rules are considerated
as differents variables and are totally independent, this is the same
as
if
we
had
used
differents
names.
The following program :
fun(X) :pc(X),
unix(X).
fun(X) :old(X),
amiga(X).
Will be seen by Prolog as :
fun(X_1) :pc(X_1),
unix(X_1).
fun(X_2) :old(X_2),
amiga(X_2).
5 Backtracking
5.1 Fail
The fail/1 predicate is provided by Prolog. When it is called, it
causes the failure of the rule. And this will be for ever, nothing can
change the statement of this predicate. You can ask you what is its
utility. We can associate it to the Cut/1 predicate, described in the
next subsection in this report.it allow us to include the negation in a
rule.A typical use of fail is a negation of a predicate.We can resume
the fail with this sheme :
goal(X) :- failure(X),!,fail.
goal(X).
failure(X) are the conditions that make goal(X) fail.
5.2 Cut
Up to this point, we have worked with Prolog's backtracking. We
have seen how to use the backtracking to write compact predicates.
Sometimes it is desirable to selectively turn off backtracking. Prolog
provides a predicate that performs this function. It is called the
cut/1,
represented
by
an
exclamation
point
(!).
The cut/1 effectively tells Prolog to freeze all the decisions made so
far in this predicate. That is, if required to backtrack, it will
automatically fail without trying other alternatives. We will first
examine the effects of the cut/1 and then look at some practical
reasons to use it . When the cut/1 is encountered, it re-routes
backtracking. It short-circuits backtracking in the goals to its left on
its level, and in the level above, which contained the cut/1. That is,
both the parent goal and the goals of the particular rule being
execut/1ed are affected by the cut/1. The effect is undone if a new
route
is
taken
into
the
parent
goal.
We will write some simple predicates that illustrate the behavior of
the cut/1, first adding some data to backtrack over.
data(pentiumIII).
data(athlon).
Here is the first test case. It has no cut/1 and will be used for
comparison purposes.
compare_cut_1(X) :data(X).
compare_cut_1('last chip').
This is the control case, which exhibits the normal behavior.
?- compare_cut_1(X), write(X), nl, fail.
pentiumIII
athlon
last chip
no
Next, we put a cut/1 at the end of the first clause.
compare_cut_2(X) :data(X),
!.
compare_cut_2('last chip').
Note that it stops backtracking through both the data subgoal (left),
and the compare_cut_2/1 parent (above).
?- compare_cut_2(X), write(X), nl, fail.
pentiumIII
no
Next we put a cut/1 in the middle of two subgoals.
compare_cut_3(X,Y) :data(X),
!,
data(Y).
compare_cut_3('last chip').
Note that the cut inhibits backtracking in the parent
compare_cut_3/2 and in the goals to the left of (before) the cut (first
data). The second data/1 to the right of (after) the cut is still free to
backtrack.
?- compare_cut_3(X,Y), write(X-Y), nl, fail.
pentiumIII - pentiumIII
pentiumIII - athlon
no
Performance is the main reason to use the cut/1. This separates the
logical purists from the pragmatists. Various arguments can also be
made as to its effect on code readability and maintainability. It is
often called the 'goto' of logic programming. You will most often use
the cut/1 when you know that at a certain point in a given predicate,
Prolog has either found the only answer, or if it hasn't, there is no
answer. In this case you insert a cut/1 in the predicate at that point.
Similarly, you will use it when you want to force a predicate to fail in
a certain situation, and you don't want it to look any further.
5.3 Not
For logical puritey, it is always possible to rewrite the predicates
without the cut/1. This is done with the built-in predicate not/1.
Some claim this provides for clearer code, but often the explicit and
liberal use of 'not' clutters up the code, rather than clarifying it.
When using the cut/1, the order of the rules become important. Let's
try to rewrite compare_cut_2/1 with the not/1 predicate.
not_2(X) :- X = pentiumIII.
not_2(X) :- not(X = pentiumIII).
You can now see the difference between not/1 and cut/1, but the code
is here to simple to see really the difference of clarity.Try with
compare_cut_3 :
not_3(X,Y) :- X = pentiumIII,data(Y).
not_3(X,Y) :- not(X = pentiumIII),not(Y).
Now, you can imaginate what will be the difference between the
algorithms based on the cut/1 and those on the not/1. The result is
the
same,
it's
just
a
way
of
thinking.
it is interesting to note that not/1 is defined using the cut/1. It also
uses call/1, another built-in predicate that calls a predicate.
not(X) :- call(X), !, fail.
not(X).
6 Recursion
6.1 What is recursion
The recursion in any language is a function that can call itself until
the goal has been succeed.
In Prolog, recursion appears when a predicate contain a goal that
refers to itself.
?- [X|Y] = [].
no
The empty list does not unify with the standard list syntax because it
has no head.
?- [X|Y] = [].
no
?- X = [T|Q], display(X).
.(_01,_02)
Op(1100,xfy,';').
Op(1000,xfy,',').
Op(700,xfx,[=,is,<,>,=<,>=,==,=:=]).
Op(500,yfx,[+.-]).
Op(500,fx,[+,-,not]).
Op(400,yfx,[*,/,div]).
Op(300,xfx,mod).
8.2 Arithmetic
Prolog use the infix operator 'is' to give the result of an arithmetic
operation to a variable.is
X is 3 + 4.
Prolog responds
X=7
yes
When the goal operator 'is' is used the variables on the right must
have been unified to numbers before. Prolog is not oriented
calculations, so, after a certain point, he approximates the
calculations and he don't answer the exact number but his
approximation Fo example :
?- X is 1000 + .0001
X = 1000
yes
Prolog can read and write in a file. The file where Prolog read is
called input and the file where Prolog write is called output. When
you run Prolog the default output is your screen (the shell) and the
input is your keyboard. If you want to use files for thatr you have to
tell it to Prolog using the commands listed in the appendix on this
page.
10 SWI-Prolog
10.1 What is SWI-Prolog
If you want to use Prolog you need a compiler. There are many
compiler downloadables on internet. For this report we used SWIProlog. SWI-Prolog is free Prolog compiler licenced under the GPL,
targeting primaly the research and education.
10.2 Author
SWI-Prolog is designed and implemented by Jan Wielemaker from
the University of Amsterdam, department of Social Science
Informatics (SWI).
10.3 Platforms
SWI-Prolog is written in ANSI C and should configure for most
Unix
machines
having
an
ANSI
C
Compiler.
Ports have been made for :
1. MS Win32
2. MS Win3.1
3. MS DOS
4. OS/2
fib(1, 1, 0).
fib(X, Y1, Y2) :X > 1,
X1 is X - 1,
fib(X1, Y2, Y3),
Y1 is Y2 + Y3.
bubble(X,[Y|T],[Y|NT],Max):-X>Y,bubble(X,T,NT,Max).
bubble(X,[Y|T],[X|NT],Max):-X<=Y,bubble(Y,T,NT,Max).
Merge sort
Merge sort is usually used to sort large files but its idea can be
utilized to every list. If properly implemented it could be a very
efficient algorithm.
merge_sort([],[]).
merge_sort(List,Sorted):divide(List,L1,L2),merge_sort(L1,Sorted1),merge_sort(L2,Sorted
2),
merge(Sorted1,Sorted2,Sorted).
merge([],L,L).
merge(L,[],L):-L\=[].
merge([X|T1],[Y|T2],[X|T]):-X<=Y,merge(T1,[Y|T2],T).
merge([X|T1],[Y|T2],[Y|T]):-X>Y,merge([X|T1],T2,T).
Quick sort
Quick sort is one of the fastest sort algorithms. However, its
power is often overvalued. The efficiency of quick sort is sensitive
to choice of pivot which is used to distribute list into two "halfs".
quick_sort([],[]).
quick_sort([H|T],Sorted):pivoting(H,T,L1,L2),quick_sort(L1,Sorted1),quick_sort(L1,Sorte
d2),
append(Sorted1,[H|Sorted2]).
pivoting(H,[],[],[]).
pivoting(H,[X|T],[X|L],G):-X<=H,pivoting(H,T,L,G).
pivoting(H,[X|T],L,[X|G]):-X>H,pivoting(H,T,L,G).
7.Short notes:
The traveling salesman problem
The problem is that in what order should the salesman visit all
the sites so they minimize the total distance traveled. The
salesman has to return to the starting point of the tour, so he
could choose any starting point. Each site can only be visited
once.
yes
| ?8.Monkey & Banana
The Problem:
There is a monkey at the door into a room. Inthe middle of the
room a banana ishanging from the ceiling. The monkey is hungry
and
wants to get the banana, but he cannot stretch
high enough from the floor. At the window of
the room there is a box themonkey may use.
The monkey can perform the following
actions:
Walk on the floor
Climb the box
Push the box around (if it is already at the box)
Grasp the banana if standing on the box
directly under the banana.
Monkey World is described by some 'state'
that can change in time.
Current state is determined by the position of
the objects
State:
Monkey Horizontal
Monkey Vertical
Box Position
Has Banana
Initial State:
Monkey is at the door
Monkey is on floor
Box is at window
Monkey does not have banana
6. In prolog:
state(atdoor, onfloor, atwindow, hasnot).
Goal:
state(_, _, _, has). : Anonymous Variables
Allowed Moves:
Grasp banana
Climb box
Push box
Walk around
Not all moves are possible in every possible
state of the world e.g. grasp is only possible
if the monkey is standing on the box directly
under the banana and does not have the
banana yet.
Move from one state to another
In prolog:
move(State1, Move, State2)
Move :
Grasp
Climb
Push
Walk
Grasp
move(state(middle, onbox, middle, hasnot),
grasp,
state(middle, onbox, middle, has)).
Climb
move(state(P, onfloor, P, H),
climb,
state(P, onbox, P, H)).
Push
move(state(P1, onfloor, P1, H),
push(P1, P2),
state(P2, onfloor, P2, H)).
Walk
move(state(P1, onfloor, B, H),
walk(P1, P2),
state(P2, onfloor, B, H)).
Main question our program will pose:
Can the monkey in some initial state get the
banana?
Prolog predicate:
canget(State)
Canget(State)
(1) For any state in which the monkey already
has the banana the predicate is true
canget(state(_, _, _, has)).
Canget(State)
(2) In other cases one or more moves are
necessary. The monkey can get the banana in
any state (State1) if there is some move
(Move) from State1 to some state (State2),
such that the monkey can get the banana in
State2 (in zero or more moves).
canget(State1) :move(State1, Move, State2),
canget(State2).
Questions:
?- canget(state(atwindow, onfloor, atwindow, has)).
Yes
?- canget(state(atdoor, onfloor, atwindow, hasnot)).
Yes
?- canget(state(atwindow, onbox, atwindow, hasnot)).
No
Clause Order
Grasp
Climb
Push
Walk
Effectively says that the monkey prefers
grasping to climbing, climbing to pushing
etc...
This order of preferences helps the monkey
to solve the problem.
Reorder Clauses
Walk
7. Grasp
Climb
Push
This results in an infinite loop!
As the first move the monkey chooses will
always be move, therefore he moves
aimlessly around the room.
Conclusion:
A program in Prolog may be declaratively
correct, but procedurally incorrect.
i.e. Unable to find a solution when a solution
actually exists.
member(Item,[Item|Rest]).
member(Item,[First|Rest]) :member(Item,Rest).
template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).
After these
?- template(S), solution(S).
should give the solutions. Use ; to find more than one solution.
(0 0)
(4 0)
(4 3)
(0 3)
(4 3)
(0 0)
(0 0)
(4 0)
(3 0)
(0 3)
(1 3)