EXPERT LAB Print
EXPERT LAB Print
What is Prolog
1. Prolog stands for programming in logic. In the logic programming paradigm,
prolog language is most widely available. Prolog is a declarative language,
which means that a program consists of data based on the facts and rules
(Logical relationship) rather than computing how to find a solution. A
logical relationship describes the relationships which hold for the given
application.
2. To obtain the solution, the user asks a question rather than running a
program. When a user asks a question, then to determine the answer, the run
time system searches through the database of facts and rules.
3. The first Prolog was 'Marseille Prolog', which is based on work by
Colmerauer. The major example of fourth-generation programming
language was prolog. It supports the declarative programming paradigm.
4. In 1981, a Japanese computer Project of 5th generation was announced. After
that, it was adopted Prolog as a development language. In this tutorial, the
program was written in the 'Standard' Edinburgh Prolog. Prologs of
PrologIIfamily are the other kind of prologs which are descendants of
Marseille Prolog.
5. Prolog features are 'Logical variable', which means that they behave like
uniform data structure, a backtracking strategy to search for proofs, a
pattern-matching facility, mathematical variable, and input and out are
interchangeable.
6. To deduce the answer, there will be more than one way. In such case, the run
time system will be asked to find another solution. To generate another
solution, use the backtracking strategy. Prolog is a weakly typed language
with static scope rules and dynamic type checking.
7. Prolog is a declarative language that means we can specify what problem we
want to solve rather than how to solve
8. Prolog is used in some areas like database, natural language processing,
artificial intelligence, but it is pretty useless in some areas like a numerical
algorithm or instance graphics.
9. In artificial intelligence applications, prolog is used. The artificial
intelligence applications can be automated reasoning systems, natural
language interfaces, and expert systems. The expert system consists of an
interface engine and a database of facts. The prolog's run time system
provides the service of an interface engine.
10. A basic logic programming environment has no literal values. An identifier
with upper case letters and other identifiers denote variables. Identifiers that
start with lower-case letters denote data values. The basic Prolog elements
are typeless. The most implementations of prolog have been enhanced to
include integer value, characters, and operations. The Mechanism of prolog
describes the tuples and lists.
11. Functional programming language and prolog have some similarities like
Hugs. A logic program is used to consist of relation definition. A functional
programming language is used to consist of a sequence of function
definitions. Both the logical programming and functional programming rely
heavily on recursive definitions.
Features of PROLOG:
Structure of PROLOG:
domains
/*…domain statements…*/
predicates
/*…predicate statements…*/
goal
clauses
Clauses:
This section contains all of the program’s information and regulations. The
same-named facts and rules must be grouped together. A procedure is a set of
sentences that define a predicate. The user is requested to write in a goal following
a goal during execution. PROLOG begins searching for a solution for the input
goal at the top of the clauses section, going through each fact and rule one by one
in search of a probable match.
Predicates:
One or more clauses make up a predicate. Clauses belonging to the same predicate
must be in order. A predicate can be declared as – in general.
There is no need for parenthesis if there are no arguments. Only the predicate name
is required; it starts with a lowercase letter and is followed by a string of letters,
numbers, and the underscore(_) character. The length of a predicate name is
limited to 250 characters.
Domains:
Even while PROLOG uses the same domains as in-built domains, a user can
choose problem-related meaningful names for domains. User-defined domain
names are commonly used, but the PROLOG system does not recognise them. As a
result, the user provides information about these user-defined domains in the
domains section.
The applications of PROLOG are as follows:
1. Specification Language
2. Robot Planning
3. Natural language understanding
4. Machine Learning
5. Problem Solving
6. Intelligent Database retrieval
7. Expert System
8. Automated Reasoning
Disadvantages:
File extension:
1. A .PL file includes Perl source code, which is a programming language that
is compiled and executed with the help of a Perl interpreter. Variables,
actions, functions, and comments are all included in the Perl programme
code.
2. Adobe Proto, a now-defunct Adobe Touch programme, generates a .PRO
file, which is a website or mobile application mockup. It includes one or
more UI layouts for a webpage or mobile app, each of which may have
interactive features. CSS, WebKit, and jQuery are all supported by .PRO
files.
3. Picture files made by Pascal are stored in .P files.The extension is used by
MATLAB to store binary-runtime files within the programme.
Conclusion:
A logic programming language is PROLOG. It is crucial in the field of
artificial intelligence. PROLOG, unlike many other programming languages, is
primarily intended as a declarative language. PROLOG expresses logic as a set of
relations (called as Facts and Rules). The reasoning being applied is at the heart of
PROLOG Running a query across these relations is used for formulation or
computation.
STUDY OF LISP
History of Lisp:
John McCarthy at Massachusetts Institute of Technology is credited with
creating the first version of Lisp in 1959. The first official implementation of the
language was performed on an IBM 704 mainframe using punched cards. Between
the 1960s and 2000s, more than a dozen mainstream dialects were created and used
in a variety of ways.
Benefits of Lisp:
While there are several reasons why the Lisp programming language is still
popular after all these years, perhaps the most important is that it's considered to be
a relatively simple language to learn. This is probably why it's still popular in
academia. Other benefits include the following:
1. symbolic AI programmers;
Today, Lisp dialects are used to create code in a variety of use-case scenarios
from basic HyperText Markup Language and web-based apps to software that
operates and controls mass transit systems, including the London Tube.
Output:
5! is 120
PROCEDURE:
LISP code to convert Centigrade to Fahrenheit is (+(*(/95)50)32).
Temperatures in degrees Fahrenheit and Celsius. . The freezing point of water in degrees
Celsius is 0 while in degrees Fahrenheit it is 32. The boiling point of water is 100 degrees
Celsius and 212 degrees Fahrenheit. Given that the function is linear, use this information
to find an equation for .
To convert temperatures in degrees Celsius to Fahrenheit, multiply by 1.8 (or 9/5) and
add 32. Well there IS a 1.8 x ratio between Fahrenheit degrees and Celsius degrees, but
the origin is at -40 degrees instead of at zero. For the boiling point of water F+40 = 1.8 x
(100+40) = 252 = 212 + 40.
To find the temperature when both are equal, we use an old algebra trick and just set ºF =
ºC and solve one of the equations. So the temperature when both the Celsius and
Fahrenheit scales are the same is -40 degrees.
Rule
Centigrade to Fahrenheit (c_to_f)F is C * 9 / 5 + 32
Problem Statement:
(defun convert ()
(defuncelsius-to-fahrenheit (celsius)
(+ (* celsius 9/5) 32))
;; Example usage
(format t "Enter temperature in Celsius: ")
(setqcelsius (read))
(setqfahrenheit (celsius-to-fahrenheitcelsius))
(format t "Temperature in Fahrenheit: ~a~%" fahrenheit)
OUTPUT:
> (convert)
(CELSIUS IS .65.5556)
> (convert)
Enter Fahrenheit:-150
> (convert)
(CELSIUS IS : 37.2222)
Problem Statement:
Suppose the problem is as given below
So if the monkey is clever enough, he can come to the block, drag the block to the
center, climb on it, and get the banana. Below are few observations in this case −
➢ Monkey can reach the block, if both of them are at the same level. From the
above image, we can see that both the monkey and the block are on the
floor.
➢ If the block position is not at the center, then monkey can drag it to the
center.
➢ If monkey and the block both are on the floor, and block is at the center,
then the monkey can climb up on the block. So the vertical position of the
monkey will be changed.
➢ When the monkey is on the block, and block is at the center, then the
monkey can get the bananas.
Now, let us see how we can solve this using Prolog. We will create some
predicates as follows −
We have some predicates that will move from one state to another state, by
performing action.
➢ When the block is at the middle, and monkey is on top of the block, and
monkey does not have the banana (i.e. has notstate), then using
the grasp action, it will change from has not state to have state.
➢ From the floor, it can move to the top of the block (i.e. on top state), by
performing the action climb.
➢ The push or drag operation moves the block from one place to another.
➢ Monkey can move from one place to another using walk or move clauses.
Another predicate will be canget(). Here we pass a state, so this will perform move
predicate from one state to another using different actions, then perform canget()
on state 2. When we have reached to the state ‘has>’, this indicates ‘has banana’.
We will stop the execution.
Program
move(state(middle,onbox,middle,hasnot),
grasp,
state(middle,onbox,middle,has)).
move(state(P,onfloor,P,H),
climb,
state(P,onbox,P,H)).
move(state(P1,onfloor,P1,H),
drag(P1,P2),
state(P2,onfloor,P2,H)).
move(state(P1,onfloor,B,H),
walk(P1,P2),
state(P2,onfloor,B,H)).
canget(state(_,_,_,has)).
canget(State1) :-
move(State1,_,State2),
canget(State2).
Output:
| ?- [monkey_banana].
compiling D:/TP Prolog/Sample_Codes/monkey_banana.pl for byte code...
D:/TP Prolog/Sample_Codes/monkey_banana.pl compiled, 17 lines read - 2167
bytes written, 19 ms
true ?
yes
| ?- trace
.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- canget(state(atdoor, onfloor, atwindow, hasnot)).
1 1 Call: canget(state(atdoor,onfloor,atwindow,hasnot)) ?
2 2 Call: move(state(atdoor,onfloor,atwindow,hasnot),_52,_92) ?
22
Exit:move(state(atdoor,onfloor,atwindow,hasnot),walk(atdoor,_80),state(_80,onflo
or,atwindow,hasnot)) ?
3 2 Call: canget(state(_80,onfloor,atwindow,hasnot)) ?
4 3 Call: move(state(_80,onfloor,atwindow,hasnot),_110,_150) ?
4 3 Exit:
move(state(atwindow,onfloor,atwindow,hasnot),climb,state(atwindow,onbox,atwin
dow,hasnot)) ?
5 3 Call: canget(state(atwindow,onbox,atwindow,hasnot)) ?
6 4 Call: move(state(atwindow,onbox,atwindow,hasnot),_165,_205) ?
6 4 Fail: move(state(atwindow,onbox,atwindow,hasnot),_165,_193) ?
5 3 Fail: canget(state(atwindow,onbox,atwindow,hasnot)) ?
4 3 Redo:
move(state(atwindow,onfloor,atwindow,hasnot),climb,state(atwindow,onbox,atwin
dow,hasnot)) ?
4 3 Exit:
move(state(atwindow,onfloor,atwindow,hasnot),drag(atwindow,_138),state(_138,o
nfloor,_138,hasnot)) ?
5 3 Call: canget(state(_138,onfloor,_138,hasnot)) ?
6 4 Call: move(state(_138,onfloor,_138,hasnot),_168,_208) ?
6 4 Exit:
move(state(_138,onfloor,_138,hasnot),climb,state(_138,onbox,_138,hasnot)) ?
7 4 Call: canget(state(_138,onbox,_138,hasnot)) ?
8 5 Call: move(state(_138,onbox,_138,hasnot),_223,_263) ?
8 5 Exit:
move(state(middle,onbox,middle,hasnot),grasp,state(middle,onbox,middle,has)) ?
9 5 Call: canget(state(middle,onbox,middle,has)) ?
9 5 Exit: canget(state(middle,onbox,middle,has)) ?
7 4 Exit: canget(state(middle,onbox,middle,hasnot)) ?
5 3 Exit: canget(state(middle,onfloor,middle,hasnot)) ?
3 2 Exit: canget(state(atwindow,onfloor,atwindow,hasnot)) ?
1 1 Exit: canget(state(atdoor,onfloor,atwindow,hasnot)) ?
true ?
(78 ms) yes
PROCEDURE:
The 4 Queens Problem consists in placing four queens on a 4 x 4 chessboard so
that no two queens attack each other. That is, no two queens are allowed to be
placed on the same row, the same column or the same diagonal.
We are going to look for the solution for n=4 on a 4 x 4 chessboard in this
article.
Place each queen one by one in different rows, starting from the topmost row.
While placing a queen in a row, check for clashes with already placed queens.
For any column, if there is no clash then mark this row and column as part of the
solution by placing the queen. In case, if no safe cell found due to clashes, then
backtrack (i.e, undo the placement of recent queen) and return false.
Illustration of 4 Queens Solution:
Step 0: Initialize a 4×4 board.
Step 1:
• Put our first Queen (Q1) in the (0,0) cell .
• ‘x‘ represents the cells which is not safe i.e. they are under attack by the
Queen (Q1).
• After this move to the next row [ 0 -> 1 ].
Step 2:
• Put our next Queen (Q2) in the (1,2) cell .
• After this move to the next row [ 1 -> 2 ].
Step 3:
• At row 2 there is no cell which are safe to place Queen (Q3) .
• So, backtrack and remove queen Q2 queen from cell ( 1, 2 ) .
Step 4:
• There is still a safe cell in the row 1 i.e. cell ( 1, 3 ).
• Put Queen ( Q2 ) at cell ( 1, 3).
Step 5:
• Put queen ( Q3 ) at cell ( 2, 1 ).
Step 6:
• There is no any cell to place Queen ( Q4 ) at row 3.
• Backtrack and remove Queen ( Q3 ) from row 2.
• Again there is no other safe cell in row 2, So backtrack again and remove
queen ( Q2 ) from row 1.
• Queen ( Q1 ) will be remove from cell (0,0) and move to next safe cell i.e. (0
, 1).
Step 7:
• Place Queen Q1 at cell (0 , 1), and move to next row.
Step 8:
• Place Queen Q2 at cell (1 , 3), and move to next row.
Step 9:
• Place Queen Q3 at cell (2 , 0), and move to next row.
Step 10:
• Place Queen Q4 at cell (3 , 2), and move to next row.
• This is one possible configuration of solution
#define N 4
// indices
int ld[30] = { 0 };
int rd[30] = { 0 };
// row or not*/
int cl[30] = { 0 };
// Queen problem
if (col >= N)
return true;
// board[i][col]
// diagonal respectively
&& cl[i] != 1) {
// Place this queen in board[i][col]
board[i][col] = 1;
return true;
board[i][col] = 0; // BACKTRACK
return false;
// feasible solutions.
bool solveNQ()
int board[N][N] = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };
if (solveNQUtil(board, 0) == false) {
return false;
printSolution(board);
return true;
int main()
solveNQ();
return 0;
}
Output:
. . Q .
Q . . .
. . . Q
. Q . .
Problem Statement:
fact(0,1).
fact(N,F):-
(
% The below is for +ve factorial.
N>0 ->
(
N1 is N-1,
fact(N1,F1),
F is N*F1
)
% The below is for -ve factorial.
N<0 ->
(
N1 is N+1,
fact(N1,F1),
F is N*F1
)
).
Output:
Problem Statement:
fib(0,0).
fib(1,1).
fib(F,N) :-
N>1,
N1 is N-1,
N2 is N-2,
F is F1+F2,
fib(F1,N1),
fib(F2,N2),
write(F," ,").
Output:
?- consult('C:/GNU-Prolog/bin/fib.pl').
compiling C:/GNU-Prolog/bin/fib.pl for byte code...
C:/GNU-Prolog/bin/fib.pl compiled, 3 lines read - 1253 bytes written, 15 ms
yes
| ?- fib(F,2).
uncaught exception: error(instantiation_error,(is)/2)
Problem Statement:
/* Description:
For example, there are four cities(Kansas City,Houston,Gordon and Tampa).
-> The distance between Kansas City and Houston is 120.
-> The distance between Kansas City and Tampa is 80.
-> The distance between Houston and Gordon is 100.
% Production Rules:-
route(Town1,Town2,Distance)🡪road(Town1,Town2,Distance).
route(Town1,Town2,Distance)🡪road(Town1,X,Dist1),
route(X,Town2,Dist2),
Distance=Dist1+Dist2,
% Domains
town = symbol
distance = integer
% Predicates
nondetermroad(town,town,distance)
nondetermroute(town,town,distance)
% Clauses
road("tampa","houston",200).
road("gordon","tampa",300).
road("houston","gordon",100).
road("houston","kansas_city",120).
road("gordon","kansas_city",130).
route(Town1,Town2,Distance):-
road(Town1,Town2,Distance).
route(Town1,Town2,Distance):-
road(Town1,X,Dist1),
route(X,Town2,Dist2),
Distance=Dist1+Dist2,
!.
Output:
% Goal
route("tampa","kansas_city", X),
write("Distance from Tampa to Kansas City is ",X),nl.
/* Description:
"You are given two jugs, a 4-gallon one and a 3-gallon one. Neither have any
measuring markers on it. There is a tap that can be used to fill the jugs with water.
How can you get exactly 2 gallons of water into the 4-gallon jug?".
/* Production Rules:-
R1: (x,y) --> (4,y) if x < 4
R2: (x,y) --> (x,3) if y < 3
R3: (x,y) --> (x-d,y) if x > 0
R4: (x,y) --> (x,y-d) if y > 0
R5: (x,y) --> (0,y) if x > 0
R6: (x,y) --> (x,0) if y > 0
R7: (x,y) --> (4,y-(4-x)) if x+y>= 4 and y > 0
R8: (x,y) --> (x-(3-y),y) if x+y>= 3 and x > 0
R9: (x,y) --> (x+y,0) if x+y =< 4 and y > 0
R10: (x,y) --> (0,x+y) if x+y =< 3 and x > 0
*/
%database
visited_state(integer,integer).
%predicates
state(integer,integer).
%clauses
state(2,0).
state(X,Y):- X <4,
not(visited_state(4,Y)),
assert(visited_state(X,Y)),
write("Fill the 4-Gallon Jug: (",X,",",Y,") --> (",4,",",Y,")\n"),
state(4,Y).
state(X,Y):- Y <3,
not(visited_state(X,3)),
assert(visited_state(X,Y)),
write("Fill the 3-Gallon Jug: (", X,",",Y,") --> (", X,",",3,")\n"),
state(X,3).
state(X,Y):- X >0,
not(visited_state(0,Y)),
assert(visited_state(X,Y)),
write("Empty the 4-Gallon jug on ground: (", X,",",Y,") --> (",0,",",Y,")\n"),
state(0,Y).
state(X,Y):- Y >0,
not(visited_state(X,0)),
assert(visited_state(X,0)),
write("Empty the 3-Gallon jug on ground: (", X,",",Y,") --> (", X,",",0,")\n"),
state(X,0).
state(X,Y):- X + Y >=4,
Y >0,
NEW_Y = Y -(4- X),
not(visited_state(4,NEW_Y)),
assert(visited_state(X,Y)),
write("Pour water from 3-Gallon jug to 4-gallon until it is full: (", X,",",Y,") -->
(",4,",",NEW_Y,")\n"),
state(4,NEW_Y).
state(X,Y):- X + Y >=3,
X >0,
NEW_X = X -(3- Y),
not(visited_state(X,3)),
assert(visited_state(X,Y)),
write("Pour water from 4-Gallon jug to 3-gallon until it is full: (", X,",",Y,") --> (",
NEW_X,",",3,")\n"),
state(NEW_X,3).
state(X,Y):- X + Y>=4,
Y >0,
NEW_X = X + Y,
not(visited_state(NEW_X,0)),
assert(visited_state(X,Y)),
write("Pour all the water from 3-Gallon jug to 4-gallon: (", X,",",Y,") --> (",
NEW_X,",",0,")\n"),
state(NEW_X,0).
state(0,2):-not(visited_state(2,0)),
assert(visited_state(0,2)),
write("Pour 2 gallons from 3-Gallon jug to 4-gallon: (",0,",",2,") -->
(",2,",",0,")\n"),
state(2,0).
state(2,Y):-not(visited_state(0,Y)),
assert(visited_state(2,Y)),
write("Empty 2 gallons from 4-Gallon jug on the ground: (",2,",",Y,") -->
(",0,",",Y,")\n"),
state(0,Y).
goal:-
makewindow(1,2,3,"4-3 Water Jug Problem",0,0,25,80),
state(0,0).
Output:
% Goal:-
makewindow(1,2,3,"4-3 Water Jug Problem",0,0,25,80),
state(0,0).
-----------------------------4-3 Water Jug Problem------------------
Fill the 4-Gallon Jug:(0,0)-->(4,0)
Fill the 3-Gallon Jug:(4,0)-->(4,3)
Empty the 4-Gallon jug on ground:(4,3)-->(0,3)
Pour all the water from 3-Gallon jug to 4-gallon:(0,3)-->(3,0)
Fill the 3-Gallon Jug:(3,0)-->(3,3)
Pour water from 3-Gallon jug to 4-gallon until it is full:(3,3)-->(4,2)|
Empty the 4-Gallon jug on ground:(4,2)-->(0,2)
Pour all the water from 3-Gallon jug to 4-gallon:(0,2)-->(2,0)
Problem Statement:
I have basic Tick-tack-toe game, where 2 players both make moves on a grid of 9
cells. The problem is that after the frist player makes the last and winnig move, the
game doesnt stop and player 2 still can play. And if second player, somehow,
makes winning move too, he will be the winner, despite player 1 actually getting
the win first. It doesnt make same error if second player wins frist. Draw works
fine. Here`s the code:
:- dynamic o/1.
:- dynamic x/1.
/* the various combinations of a successful horizontal, vertical
or diagonal line */
ordered_line(1,2,3).
ordered_line(4,5,6).
ordered_line(7,8,9).
ordered_line(1,4,7).
ordered_line(2,5,8).
ordered_line(3,6,9).
ordered_line(1,5,9).
ordered_line(3,5,7).
/*line predicate to complete lines
line(A,B,C) :- ordered_line(A,B,C).
line(A,B,C) :- ordered_line(A,C,B).
line(A,B,C) :- ordered_line(B,A,C).
line(A,B,C) :- ordered_line(B,C,A).
line(A,B,C) :- ordered_line(C,A,B).
line(A,B,C) :- ordered_line(C,B,A).
full(A) :- x(A).
full(A) :- o(A).
empty(A) :- not(full(A)).
all_full :- full(1),full(2),full(3),full(4),full(5),
full(6),full(7),full(8),full(9).
done :- ordered_line(A,B,C), x(A), x(B), x(C), write('Player 2 win.'),nl.
done :- ordered_line(A,B,C), o(A), o(B), o(C), write('Player 1 win.'),nl.
done :- all_full, write('Draw.'), nl.
move1 :- write('Player 1 (o) enter a move: '), read(X), between(1,9,X),
empty(X), assert(o(X)).
move1:-all_full.
move2 :- write('Player 2 (x) enter a move: '), read(X), between(1,9,X),
empty(X),assert(x(X)).
move2:- all_full.
printsquare(N) :- o(N), write(' o ').
printsquare(N) :- x(N), write(' x ').
printsquare(N) :- empty(N), write(' ').
printboard :- printsquare(1),printsquare(2),printsquare(3),nl,
printsquare(4),printsquare(5),printsquare(6),nl,
printsquare(7),printsquare(8),printsquare(9),nl.
clear :- x(A), retract(x(A)), fail.
clear :- o(A), retract(o(A)), fail.
play :- not(clear), repeat, move1, printboard, move2,printboard, done.
And that`s the error I get: Game doesnt stop when player 1 wins
Hope you can help me :) Thanks in advance.
Edit: The "Player 2 wins" shows in "done" predicate. After successfull finishing
line of 3 'o' or 'x' game should end with either Player 1 wins or Player 2 wins. I`ll
include original code, which might help with understanding the problem.
Output:
1|2|3
---------
4|5|6
---------
7|8|9
X|_|_
---------
_|X|_
---------
_|_|O
X|_|_
---------
_|X|_
---------
X|_|O
X|O|_
---------
_|X|_
---------
X|_|O
X|O|X
---------
_|X|_
---------
X|_|O
Player 2 wins!
Problem Statement:
(defun convert ()
> (convert)
(CELSIUS IS . 93.33333333333334)
> (convert)
Enter Fahrenheit
-200
> (convert)
Enter Fahrenheit 98
(CELSIUS IS : 36.6666666666666