0% found this document useful (0 votes)
25 views42 pages

Artificial Intelligence AI

The document outlines a series of Prolog programming experiments aimed at implementing various algorithms and knowledge bases. It includes tasks such as creating programs to determine player preferences, login validation, and solving logic puzzles like the Tower of Hanoi and the 8 Puzzle Problem. Additionally, it covers theoretical concepts of Prolog, including facts, rules, predicates, and logical inference.

Uploaded by

parekhbhavika694
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views42 pages

Artificial Intelligence AI

The document outlines a series of Prolog programming experiments aimed at implementing various algorithms and knowledge bases. It includes tasks such as creating programs to determine player preferences, login validation, and solving logic puzzles like the Tower of Hanoi and the 8 Puzzle Problem. Additionally, it covers theoretical concepts of Prolog, including facts, rules, predicates, and logical inference.

Uploaded by

parekhbhavika694
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Artificial Intelligence (3161608) Meet Chikani(210130116011)

INDEX
(Progressive Assessment Sheet)

Sr. No. Objective(s) of Experiment Page Date of Date of Assessme Sign. of Remar
No. perform submiss nt Teacher ks
ance ion Marks with date
A. Write a prolog program to put facts
indicating that sachin likes cricket, saurav
likes cricket, raj likes football, karan likes
basketball, indra likes chess and add rule
that parth likes whatever saurav likes.
Write goal for following queries:
a. Find the name of all players who
like cricket.
b. Check whether raj likes cricket or
not.
c. Display the list of all players with
the game they like.
1.
d. Display the name of players who
likes any game except cricket.
B. Implement prolog program that asks
username and password from user and
display whether login is successful or not
according to knowledge base considered
in the program.
a. Perform above program without
recursion.
b. Perform above program with
recursion.

Implement following prolog programs.:


a. To find the greatest variable among
the three variables.
b. To find a factorial of a given number.
2.
c. To check whether a given number is
palindrome or not.
d. To check whether a given number is
prime or not.
Solve 8 Puzzle Problem using A* Algorithm in
3. any programming Language.

Implement following prolog programs


based on list.
a. To display first element of a list.
4. b. To display last element of a list.
c. To display all element of a list
d. To display elements up to specified
index of a list.
Write a prolog program to solve water jug
5. problem.
Artificial Intelligence (3161608) Meet Chikani(210130116011)
Implement the Minimax algorithm for a
6. simple tic-tac-toe game using Python
Language.
Implement Bayesian Networks algorithm for
7. the Monty Hall Problem using any
programming Language.
Demonstrate Connectionist Model using
8.
Tool.
Implement Genetic Algorithm using any
9.
programming Language.
Write a prolog program to solve Tower of
10.
Hanoi problem.
Artificial Intelligence (3161608) Meet Chikani(210130116011)
Experiment No: 1

A. Write a prolog program to put facts indicating that sachin likes cricket, saurav likes cricket, raj
likes football, karan likes basketball, indra likes chess and add rule that parth likes whatever
saurav likes. Write goal for following queries:
a. Find the name of all players who like cricket.
b. Check whether raj likes cricket or not.
c. Display the list of all players with the game they like.
d. Display the name of players who likes any game except cricket.
B. Implement prolog program that asks username and password from user and display whether
login is successful or not according to knowledge base considered in the program.
a. Perform above program without recursion.
b. Perform above program with recursion.

Competency and Practical Skills: Basic Understanding of Predicated and Prolog Syntax

Relevant CO: CO1

Objectives: To learn different kinds of knowledge bases of Prolog Programming.


To create a powerful and flexible system for representing, manipulating, and
reasoning about information in a logical and structured way.

Equipment/Instruments: Personal Computer, SWI-Prolog Interpreter

Theory:

There are only three basic constructs in Prolog: facts, rules, and queries. A collection of facts and
rules is called a knowledge base (or a database) and Prolog programming is all about writing
knowledge bases. That is, Prolog programs simply are knowledge bases, collections of facts and
rules which describe some collection of relationships that we find interesting.

Knowledge Base 1

Knowledge Base 1 (KB1) is simply a collection of facts. Facts are used to state things that are
unconditionally true of some situation of interest. For example, we can state that Mia, Jody, and
Yolanda are women, that Jody plays air guitar, and that a party is taking place, using the following
five facts:

woman(mia).
woman (jody).
woman (yolanda).
playsAirGuitar(jody).
party.

We can ask Prolog whether Mia is a woman by posing the query:


Artificial Intelligence (3161608) Meet Chikani(210130116011)
?- woman (mia).
Prolog will answer
yes

Knowledge Base 2

happy (yolanda).
listens 2Music(mia).
listens 2Music(yolanda): - happy (yolanda). playsAirGuitar(mia):- listens2Music(mia).
playsAirGuitar(yolanda):- listens 2Music(yolanda).

There are two facts in KB2, listens2Music(mia) and happy(yolanda). The last three items it contains
are rules.
Rules state information that is conditionally true of the situation of interest The part on the left hand
side of the: - is called the head of the rule, the part on the right hand side is called the body. So in
general rules say: if the body of the rule is true, then the head of the rule is true too. And now for
the key point:
If a knowledge base contains a rule head - body, and Prolog knows that body follows from the
information in the knowledge base, then Prolog can infer head. This fundamental deduction step is
called modus ponens.

Knowledge Base 3

KB3, our third knowledge base, consists of five clauses:


happy(vincent).
listens2Music (butch). playsAirGuitar (vincent):-
listens 2Music(vincent),
happy(vincent). playsAirGuitar(butch):-
happy(butch).
playsAirGuitar(butch):-
listens2Music(butch). There are two facts, happy(vincent) and listens2Music(butch), and three
rules.
KB3 defines the same three predicates as KB2 (namely happy, listens2Music, and playsAirGuitar)
but it defines them differently. In particular, the three rules that define the playsAirGuitar predicate
introduce some new ideas.

Knowledge Base 4

Here is KB4, our fourth knowledge base:


woman(mia).
woman(jody).
woman (yolanda).
loves (vincent,mia).
loves (marsellus,mia).
loves (pumpkin, honey_bunny).
loves (honey_bunny, pumpkin).

There are no rules, only a collection of facts. we're going to make use of variables. Here's an
example:
?- woman(X).

Prolog answers this query by working its way through KB4, from top to bottom, trying to unify
Artificial Intelligence (3161608) Meet Chikani(210130116011)
(or match) the expression woman(X) with the information KB4 contains. Now the first item in the
knowledge base is woman(mia). So, Prolog unifies X with mia, thus making the query agree
perfectly with this first item. (Incidentally, there's a lot of different terminology for this process: we
can also say that Prolog instantiates X to mia, or that it binds X to mia .) Prolog then reports back
to us as follows:
X = mia
That is, it not only says that there is information about at least one woman in KB4, it actually tells
us who she is. It didn't just say yes, it actually gave us the variable binding (or variable instantiation)
that led to success.

Knowledge Base 5

person(john).
person(susan).
person(bob).
person(alice).

city(new_york).
city(london).
city(paris).
city(tokyo).

lives_in(john, new_york).
lives_in(susan, london).
lives_in(bob, paris).
lives_in(alice, tokyo).

likes(john, sushi).
likes(john, pizza).
likes(susan, pizza).
likes(bob, croissants).
likes(alice, sushi).

likes_same_food(X, Y) :-
likes(X, Z),
likes(Y, Z),
X \= Y.

In this example, we have defined a knowledge base that includes facts about people and cities, as
well as rules that define relationships between them. Specifically, we have defined the following:
● Four facts that define the people in our knowledge base (john, susan, bob, and alice) and
the cities they live in (new_york, london, paris, and tokyo).
● Five facts that define the food preferences of our people.
● A rule called likes_same_food/2 that defines a relationship between two people who like
the same food.
To use this knowledge base, we can query it using Prolog's built-in ?- operator. For example, we
can ask:

?- likes(john, sushi).
true.
This will return true, indicating that John likes sushi.

Safety and necessary Precautions:


Artificial Intelligence (3161608) Meet Chikani(210130116011)

Use appropriate names and arguments for the predicates.


Make sure that the rules are accurate and cover all possible cases.

Procedure:
1. Define the domain of the knowledge base.
2. Define the facts.
3. Define the rules.
4. Test the knowledge base.

Observation/Program:
For Part A

% Facts likes(sachin, cricket).


% sachin likes cricket likes(saurav, cricket).
% saurav likes cricket likes(raj, football).
% raj likes football likes(karan, basketball).
% karan likes basketball likes(indra, chess).
% indra likes chess
% Rules likes(parth, X) :- likes(saurav, X). % parth likes whatever saurav likes
Output of the program:
For Part A:

For Part B:-


a.
% Knowledge base
user_credentials('user1', 'pass1').
user_credentials('user2', 'pass2').
user_credentials('user3', 'pass3').

% Login predicate
login(Username, Password) :-
user_credentials(Username, Password),
format('Login successful. Welcome, ~w!~n', [Username]).
login(_, _) :-
format('Login failed. Invalid username or password.~n').
b.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

% Login predicate with recursion


login_recursive(Username, Password) :-
user_credentials(Username, Password),
format('Login successful. Welcome, ~w!~n', [Username]).
login_recursive(Username, Password) :-
\+ user_credentials(Username, Password),
format('Login failed. Invalid username or password.~n'),
retry_login.

% Retry login predicate


retry_login :-
write('Please enter your username: '),
read(User),
write('Please enter your password: '),
read(Pass),
login_recursive(User, Pass).
Output of the program:
For Part B:

Conclusion:

Prolog is a useful tool for implementing knowledge bases for various domains, including family
relationships, and can provide efficient and effective reasoning capabilities for querying and
analyzing such data.)
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 2

Implement following prolog programs.


a. To find the greatest variable among the three variables.
b. To find a factorial of a given number.
c. To check whether a given number is palindrome or not.
d. To check whether a given number is prime or not.

Competency and Practical Skills: Knowledge of logic programming,Basics of search


Techniques

Relevant CO: CO1

Objectives:To create a functional and efficient Prolog program for solving logic puzzles.

Equipment/Instruments: Personal Computer, SWI-Prolog Interpreter

Theory:

In Prolog, a program consists of a set of facts and rules that define relationships and properties in
a knowledge base. The primary theoretical foundation of Prolog is based on formal logic,
specifically first-order logic. Here's a brief overview of the key theoretical concepts that underlie
Prolog programs:

1. Predicates:
In Prolog, predicates are used to represent relationships or properties in the form of clauses.
Predicates consist of a name (an atom) and a fixed number of arguments. For example, `parent(X,
Y)` represents the "parent" relationship with two arguments, X and Y.

2. Facts:
Facts are the basic building blocks of Prolog programs. They represent simple, unconditionally
true statements. For example:
```
parent(john, mary).
```

3. Rules:
Rules define relationships and properties based on the satisfaction of certain conditions. Rules
have a head and a body. The head specifies the predicate to be derived, and the body specifies the
conditions that must be satisfied for the rule to apply. For example:
```
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
```

In this rule, `grandparent(X, Y)` is derived if `parent(X, Z)` and `parent(Z, Y)` are satisfied.

4. Logical Inference:
Prolog uses logical inference to make queries and derive conclusions from the facts and rules. It
employs a resolution-based mechanism to perform backward chaining, where it works backward
Artificial Intelligence (3161608) Meet Chikani(210130116011)
from the goal (query) to the premises (facts and rules) to find a solution. This is done using
unification, a process that matches variables in the query with terms in the knowledge base.

5. Soundness and Completeness:


Prolog is sound, which means that if it derives a conclusion, that conclusion is guaranteed to be
true according to the rules and facts. It is also complete, meaning that it will find all valid solutions
to a query if they exist within the given knowledge base.

6. Recursion:
Recursion is a common and powerful technique in Prolog. It allows rules to refer to themselves,
enabling the definition of complex relationships and properties. For example, a rule for calculating
factorial using recursion:
```
factorial(0, 1).
factorial(N, F) :- N > 0, N1 is N - 1, factorial(N1, F1), F is N * F1.
```

7. Termination:
It is essential to ensure that Prolog programs terminate for all possible queries. Non-terminating
programs can lead to infinite loops and are generally undesirable.

8. Cut Operator (!):


The cut operator is used in Prolog to control the search process and prune certain branches of the
search tree. It can be used to prevent backtracking in some cases.

Prolog's theoretical foundation in logic, along with its mechanism for logical inference, allows it to
express and solve complex problems in a declarative way. Prolog is particularly well-suited for tasks
involving symbolic reasoning, knowledge representation, and search problems. It is widely used in
artificial intelligence, expert systems, natural language processing, and more.

Observation/Program:
a. To find the greatest variable among the three variables.
greatest(X, Y, Z, Max) :-
( X >= Y, X >= Z -> Max = X
; Y >= X, Y >= Z -> Max = Y
; Max = Z ).
b. To find a factorial of a given number.
factorial(0, 1).
factorial(N, Fact) :-
N > 0,
N1 is N - 1,
factorial(N1, Fact1),
Fact is N * Fact1.
c. To check whether a given number is palindrome or not.
reverse_number(0, Num, Num).
reverse_number(N, Num, Rev) :-
N > 0,
N1 is N div 10,
Digit is N mod 10,
NewNum is Num * 10 + Digit,
reverse_number(N1, NewNum, Rev).

is_palindrome(N) :-
Artificial Intelligence (3161608) Meet Chikani(210130116011)
reverse_number(N, 0, Rev),
N =:= Rev.
d. To check whether a given number is prime or not.
is_prime(N) :-
N > 1,
N1 is floor(sqrt(N)),
\+ (between(2, N1, X), N mod X =:= 0).

Conclusion:
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 3

Solve 8 Puzzle Problem using A* Algorithm in any programming Language.

Competency and Practical Skills:Knowledge of logic programming

Relevant CO: CO1

Objectives:To optimize the performance of the A* algorithm by minimizing the number of states
explored and improving the efficiency of the heuristic function.

Equipment/Instruments: Personal Computer, open-source software for programming

Theory:

A* Algorithm

A* is a computer algorithm that is widely used in pathfinding and graph traversal, the process of
plotting an efficiently traversable path between multiple points, called nodes. Noted for its
performance and accuracy, it enjoys widespread use.

The key feature of the A* algorithm is that it keeps a track of each visited node which helps in
ignoring the nodes that are already visited, saving a huge amount of time. It also has a list that holds
all the nodes that are left to be explored and it chooses the most optimal node from this list, thus
saving time not exploring unnecessary or less optimal nodes.

So we use two lists namely ‘open list‘ and ‘closed list‘ the open list contains all the nodes that are
being generated and are not existing in the closed list and each node explored after it’s neighboring
nodes are discovered is put in the closed list and the neighbors are put in the open list this is how
the nodes expand. Each node has a pointer to its parent so that at any given point it can retrace the
path to the parent. Initially, the open list holds the start(Initial) node. The next node chosen from
the open list is based on its f score, the node with the least f score is picked up and explored.

f-score = h-score + g-score

A* uses a combination of heuristic value (h-score: how far the goal node is) as well as the g-score
(i.e. the number of nodes traversed from the start node to current node).

In our 8-Puzzle problem, we can define the h-score as the number of misplaced tiles by comparing
the current state and the goal state or summation of the Manhattan distance between misplaced
nodes.

g-score will remain as the number of nodes traversed from start node to get to the current node.

calculate the h-score by comparing the initial(current) state and goal state and counting the number
of misplaced tiles.
Artificial Intelligence (3161608) Meet Chikani(210130116011)
Thus, h-score = 5 and g-score = 0 as the number of nodes traversed from the start node to the
current node is 0.

How A* solves the 8-Puzzle problem.

We first move the empty space in all the possible directions in the start state and calculate
the f-score for each state. This is called expanding the current state.

After expanding the current state, it is pushed into the closed list and the newly generated states
are pushed into the open list. A state with the least f-score is selected and expanded again. This
process continues until the goal state occurs as the current state. Basically, here we are providing
the algorithm a measure to choose its actions. The algorithm chooses the best possible action and
proceeds in that path.

This solves the issue of generating redundant child states, as the algorithm will expand the node
with the least f-score.

Safety and necessary Precautions:

It is important to handle edge cases such as unsolvable puzzles, invalid puzzle states, and memory
limitations to avoid program crashes or incorrect results.

Procedure:
1. Define the starting and goal states of the puzzle.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

2. Implement the A* algorithm, which uses the heuristic function to determine the best path to
reach the goal state.

Observation/Program:
can_it_move_left(Left):-
Left >= 0,
Left \= 2,
Left \= 5.
can_it_move_right(Right):-
8 >= Right,
Right \= 3,
Right \= 6.
can_it_move_down(Down):-
Down < 9.
can_it_move_up(Up):-
Up > 0.
countInversions(_,[],Inversions):-
Inversions is 0.
countInversions(Number,[Head|Tail],Inversions):-
Number>Head,
Count is 1,
countInversions(Number,Tail,Aux_inversions),
Inversions is Count+Aux_inversions.
countInversions(Number,[Head|Tail],Inversions):-
Number<Head,
Count is 0,
countInversions(Number,Tail,Aux_inversions),
Inversions is Count+Aux_inversions.
issolvable([],A):-
A is 0.
issolvable([Head|Tail],Inversions):-
countInversions(Head,Tail,Aux_inversions),
issolvable(Tail,Next_inversions),
Inversions is Next_inversions+Aux_inversions.
iseven(Number):-
0 is mod(Number,2).
solvepuzzle(Initial_state,Goal_state,Result):-
flatten(Initial_state, List_initial_state),
delete(List_initial_state, 0, X),
issolvable(X,Inversions),
0 is mod(Inversions,2),
flatten(Goal_state, List_goal_state),
delete(List_goal_state, 0, Y),
issolvable(Y,Inversions_two),
0 is mod(Inversions_two,2),
empty_heap(Inital_heap),
Explored_set = [List_initial_state],
astar([List_initial_state,0],List_goal_state,Goal_state,Inital_heap,Explored_set,Iterations),
copy_term(Iterations, Result),
!.
solvepuzzle(Initial_state,Goal_state,Result):-
flatten(Initial_state, List_initial_state),
delete(List_initial_state, 0, X),
Artificial Intelligence (3161608) Meet Chikani(210130116011)

issolvable(X,Inversions),
\+0 is mod(Inversions,2),
flatten(Goal_state, List_goal_state),
delete(List_goal_state, 0, Y),
issolvable(Y,Inversions_two),
\+0 is mod(Inversions_two,2),
empty_heap(Inital_heap),
Explored_set = [List_initial_state],
astar([List_initial_state,0],List_goal_state,Goal_state,Inital_heap,Explored_set,Iterations),
copy_term(Iterations, Result),
!.
solvepuzzle(_,_,Result):-
Result = 'No solution'.
create_explored_set(Old_Set,Element,X):-
Aux = [Element],
append(Old_Set,Aux,X).
divide_list([Head|_],Head).
print_element([],_).
print_element([Head|Tail],I):-
0 is mod(I,3),
Newi=I+1,
nl,
print(Head),
print_element(Tail,Newi).
print_element([Head|Tail],I):-
Newi=I+1,
print(Head),
print_element(Tail,Newi).
print_list([],_).
print_list([Head|Tail],I):-
number(Head),
print_list(Tail,I).
print_list([Head|Tail],I):-
Newi=I+1,
print_list(Tail,Newi),
print_element(Head,0),
nl.
create_list_with_new_cost([],_,_,_).
create_list_with_new_cost([Head|Tail],Iterator,Pos_cost,[New_cost|Tail]):-
Iterator == Pos_cost,
New_iterator is Iterator+1,
New_cost is Head + 1,
create_list_with_new_cost(Tail,New_iterator,Pos_cost,Tail).
create_list_with_new_cost([Head|Tail],Iterator,Pos_cost,[Head|Tail2]):-
New_iterator is Iterator+1,
create_list_with_new_cost(Tail,New_iterator,Pos_cost,Tail2).
astar([Head|Tail],Head,_,_,_,Result):-
append([Head],Tail,Fathers),
print_list(Fathers,0),
length(Tail,Aux),
Result is Aux-1.
astar(State,Goal_state,Grid_goal_state,Priority_queue,Explored_set,Result):-
divide_list(State,State_to_esplore),
nth0(Position_blank_tile,State_to_esplore, 0),
length(State,Pos_cost),
Artificial Intelligence (3161608) Meet Chikani(210130116011)

nth1(Pos_cost, State, Cost),


New_cost is Cost + 1,
create_list_with_new_cost(State,1,Pos_cost,New_state),
findcombinations(New_state,Grid_goal_state,Position_blank_tile,0,Priority_queue,New_cost,Explore
d_set,New_priority_queue),
get_from_heap(New_priority_queue, _, P, Next_priority_queue),
divide_list(P,Explored),
create_explored_set(Explored_set,Explored,New_explored_set),
astar(P,Goal_state,Grid_goal_state,Next_priority_queue,New_explored_set,Result).
astar(_,_,_,Priority_queue,_,Result):-
empty_heap(Priority_queue),
Result = 'No solution'.
findcost([],_,_,Nextcost):-
Nextcost is 0.
findcost([Head|Tail],Matrixinitialstate ,Matrixgoalstate, Cost):-
Head == 0,
findcost(Tail,Matrixinitialstate ,Matrixgoalstate, Nextcost),
Cost is 0 + Nextcost.
findcost([Head|Tail], Matrixinitialstate ,Matrixgoalstate, Cost):-
matrix(Matrixgoalstate,K,L,Head),
matrix(Matrixinitialstate,I,J,Head),
Manhattan_distance is abs(I-K) + abs(J-L),
findcost(Tail,Matrixinitialstate,Matrixgoalstate,Nextcost),
Cost is Manhattan_distance + Nextcost.
convert_to_matrix(Lista,Nueva_lista):-
aux_convert_to_matrix(Lista,1,N1,T1),
aux_convert_to_matrix(T1,1,N2,T2),
aux_convert_to_matrix(T2,1,N3,_),
append([N1],[N2],Aux),
append(Aux,[N3],Nueva_lista),
!.
aux_convert_to_matrix([Head|Tail], Iterator, [Head|Tail2], Sobra):-
Iterator < 3,
Nuevoi is Iterator+1,
aux_convert_to_matrix(Tail,Nuevoi,Tail2, Sobra).
aux_convert_to_matrix([Head|Tail], Iterator, [Head], Tail):-
0 is mod(Iterator,3).
create_list_of_explored_states(List,Element,New_list):-
Aux = [Element],
append(Aux,List,New_list).
findcombinations(State,Matrix_goal_state,Position_blank_tile,0,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
divide_list(State,State_to_esplore),
Left is Position_blank_tile - 1,
can_it_move_left(Left),
swap_tiles(State_to_esplore, Position_blank_tile, Left, Permutation_left),
\+member(Permutation_left,Explored_set),
convert_to_matrix(Permutation_left,Matrix_per_left),
findcost(Permutation_left,Matrix_per_left,Matrix_goal_state,Cost),
create_list_of_explored_states(State,Permutation_left,State_with_fathers),
New_cost is Cost_move_grid + Cost,
add_to_heap(Old_priority_queue,New_cost,State_with_fathers,Aux_priority_queue),
findcombinations(State,Matrix_goal_state,Position_blank_tile,1,Aux_priority_queue,Cost_move_grid
,Explored_set,New_priority_queue).
Artificial Intelligence (3161608) Meet Chikani(210130116011)

findcombinations(State,Matrix_goal_state,Position_blank_tile,0,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
findcombinations(State,Matrix_goal_state,Position_blank_tile,1,Old_priority_queue,Cost_move_grid,
Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,1,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
divide_list(State,State_to_esplore),
Right is Position_blank_tile + 1,
can_it_move_right(Right),
swap_tiles(State_to_esplore, Position_blank_tile, Right, Permutation_right),
\+member(Permutation_right,Explored_set),
convert_to_matrix(Permutation_right,Matrix_per_right),
findcost(Permutation_right,Matrix_per_right,Matrix_goal_state,Cost),
create_list_of_explored_states(State,Permutation_right,State_with_fathers),
New_cost is Cost_move_grid + Cost,
add_to_heap(Old_priority_queue,New_cost,State_with_fathers,Aux_priority_queue),
findcombinations(State,Matrix_goal_state,Position_blank_tile,2,Aux_priority_queue,Cost_move_grid
,Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,1,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
findcombinations(State,Matrix_goal_state,Position_blank_tile,2,Old_priority_queue,Cost_move_grid,
Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,2,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
divide_list(State,State_to_esplore),
Down is Position_blank_tile + 3,
can_it_move_down(Down),
swap_tiles(State_to_esplore, Position_blank_tile, Down, Permutation_down),
\+member(Permutation_down,Explored_set),
convert_to_matrix(Permutation_down,Matrix_per_down),
findcost(Permutation_down,Matrix_per_down,Matrix_goal_state,Cost),
create_list_of_explored_states(State,Permutation_down,State_with_fathers),
New_cost is Cost_move_grid + Cost,
add_to_heap(Old_priority_queue,New_cost,State_with_fathers,Aux_priority_queue),
findcombinations(State,Matrix_goal_state,Position_blank_tile,3,Aux_priority_queue,Cost_move_grid
,Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,2,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
findcombinations(State,Matrix_goal_state,Position_blank_tile,3,Old_priority_queue,Cost_move_grid,
Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,3,Old_priority_queue,Cost_move_grid,Explor
ed_set,New_priority_queue):-
divide_list(State,State_to_esplore),
Up is Position_blank_tile -3,
can_it_move_up(Up),
swap_tiles(State_to_esplore, Position_blank_tile, Up, Permutation_up),
\+member(Permutation_up,Explored_set),
convert_to_matrix(Permutation_up,Matrix_per_up),
findcost(Permutation_up,Matrix_per_up,Matrix_goal_state,Cost),
create_list_of_explored_states(State,Permutation_up,State_with_fathers),
New_cost is Cost_move_grid + Cost,
add_to_heap(Old_priority_queue,New_cost,State_with_fathers,Aux_priority_queue),
findcombinations(State,Matrix_goal_state,Position_blank_tile,4,Aux_priority_queue,Cost_move_grid
,Explored_set,New_priority_queue).
findcombinations(State,Matrix_goal_state,Position_blank_tile,3,Old_priority_queue,Cost_move_grid,Explor
Artificial Intelligence (3161608) Meet Chikani(210130116011)

ed_set,New_priority_queue):-
findcombinations(State,Matrix_goal_state,Position_blank_tile,4,Old_priority_queue,Cost_move_grid,
Explored_set,New_priority_queue).
findcombinations(_,_,_,4,Old_priority_queue,_,_,New_priority_queue):-
copy_term(Old_priority_queue,New_priority_queue).
matrix(M, X, Y, Element) :-
nth0(X, M, R),
nth0(Y, R, Element).
swap_tiles(List,Zero,Move,Nl):-
Ayuda is Move+1,
Zero==Ayuda,
nth0(Move,List, Number_to_find),
aux_swap_tiles(List,Move,0,New_list,_,List_to_explore_more),
append(New_list,[0],Nl_aux),
append(Nl_aux,[Number_to_find],Nl_aux2),
delete(List_to_explore_more, 0, X),
append(Nl_aux2,X,Nl),
!.
swap_tiles(List,Zero,Move,Nl):-
Ayuda is Move-1,
Zero==Ayuda,
nth0(Move,List,Number_to_find),
aux_swap_tiles(List,Zero,0,New_list,_,List_to_explore_more),
append(New_list,[Number_to_find],Nl_aux),
append(Nl_aux,[0],Nl_aux2),
delete(List_to_explore_more, Number_to_find, X),
append(Nl_aux2,X,Nl),
!.
swap_tiles(List,Zero,Move,Nl):-
Ayuda is Move+1,
Ayuda_dos is Move-1,
Zero<Move,
\+Zero==Ayuda,
\+Zero==Ayuda_dos,
nth0(Move,List, Number_to_find),
aux_swap_tiles(List,Zero,0,New_list,Current_iterator,List_to_explore_more),
append(New_list,[Number_to_find],Nl_aux),
aux_swap_tiles(List_to_explore_more,Move,Current_iterator+1,New_list_two,_,List_to_explore_mor
e_two),
append(Nl_aux,New_list_two,Nl_aux_two),
append(Nl_aux_two,[0],Nl_aux_three),
append(Nl_aux_three,List_to_explore_more_two,Nl),
!.
swap_tiles(List,Zero,Move,Nl):-
Ayuda is Move+1,
Ayuda_dos is Move-1,
Zero>Move,
\+Zero==Ayuda,
\+Zero==Ayuda_dos,
nth0(Move,List, Number_to_find),
aux_swap_tiles(List,Move,0,New_list,Current_iterator,List_to_explore_more),
append(New_list,[0],Nl_aux),
aux_swap_tiles(List_to_explore_more,Zero,Current_iterator+1,New_list_two,_,List_to_explore_more
_two),
append(Nl_aux,New_list_two,Nl_aux_two),
Artificial Intelligence (3161608) Meet Chikani(210130116011)

append(Nl_aux_two,[Number_to_find],Nl_aux_three),
append(Nl_aux_three,List_to_explore_more_two,Nl),
!.
aux_swap_tiles([_|Tail],Limit,Iterator,[],X,Tail):-
Iterator==Limit,
copy_term(Iterator,X).
aux_swap_tiles([Head|Tail],Limit,Iterator,[Head|Tail2],X,List_to_explore_more):-
Iterator<Limit,
New_iterator is Iterator+1,
aux_swap_tiles(Tail,Limit,New_iterator,Tail2,X,List_to_explore_more).

Conclusion:
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 4

Implement following prolog programs based on list.


a. To display first element of a list.
b. To display last element of a list.
c. To display all element of a list
d. To display elements up to specified index of a list.
e. To count number of elements in a list.
f. To count odd and even elements of a list.

Competency and Practical Skills: Understanding of basics of lists.

Relevant CO: CO1

Objectives: Learning about lists in Prolog is a fundamental and valuable concept as it allows you to
work with structured data and perform a wide range of tasks.

Equipment/Instruments: Personal Computer, open-source software for programming

Theory:
Lists are a fundamental data structure in Prolog, allowing you to work with collections of
elements. In Prolog, a list is a sequence of terms enclosed in square brackets (`[ ]`). Lists
can contain a mix of elements, including atoms, variables, and other lists. Here's an
overview of the theory behind lists in Prolog:
1. List Syntax:
- In Prolog, lists are denoted by square brackets, such as `[a, b, c]`, which represents a
list of three atoms: 'a,' 'b,' and 'c.'
- Lists can be empty, represented as `[]`.

2. List Elements:
- Lists in Prolog can contain a mix of elements, including:
- Atoms (e.g., `a`, `b`, `c`)
- Variables (e.g., `X`, `Y`)
- Other lists (e.g., `[a, [b, c], d]`)

3. List Construction:
- Lists can be constructed using the "cons" operator, represented as `|` (often referred to
as "pipe").
- The "cons" operator allows you to prepend an element to an existing list or split a
list into its head and tail.
- For example, `[X | Rest]` represents a list with the first element `X` and the
remaining elements in `Rest`.

4. List Operations:
- Prolog provides various built-in predicates for working with lists, including:
- `length/2`: Finding the length of a list.
- `append/3`: Concatenating lists.
- `member/2`: Checking if an element is a member of a list.
- `nth0/3` and `nth1/3`: Accessing elements at a specific position in the list.
- `reverse/2`: Reversing a list.
- `select/3`: Removing an element from a list.
- `permutation/2`: Generating permutations of a list.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

5. List Processing with Recursion:


- Recursion is a common technique for processing lists in Prolog.
- Recursive predicates can be used to traverse, modify, and perform various operations on
lists.

6. List Comprehensions:
- Prolog supports list comprehensions, which provide a declarative way to generate lists
based on conditions.
- List comprehensions are concise and resemble set-builder notation.

7. Higher-Order Predicates:
- Prolog allows you to define and use higher-order predicates that take lists as
arguments.
- Higher-order predicates can simplify list processing, making code more elegant and
concise.

8. Lists as Knowledge Representation:


- Lists are often used to represent structured data in Prolog, such as facts, rules, and
databases.
- Lists can represent records, where each element corresponds to a field of
information.

9. List as Stacks and Queues:


- Lists can be used as stacks (Last-In, First-Out) or queues (First-In, First-Out) to
implement various data structures.

10. Error Handling and Edge Cases:


- Consideration should be given to handling empty lists and other edge cases to
ensure the robustness of Prolog programs.

Understanding lists in Prolog is crucial for a wide range of applications, from basic data
manipulation to complex problem-solving. Lists are a versatile data structure that enables
you to represent and process structured information efficiently in Prolog.

Observation/Program:
(a) To display first elements of a list.
Facts:-
first_element ([FirstElement |_ ], FirstElement).
Output:

(b) To display last element of a list.


Facts:-
last_element([X], X).
last_element([_ | ], X) :- last_element(T, X).
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Output:

(c) To display all element of a list.


Facts:-
display_list([]).
display_list([X | Xs]):- writeln(X),
display_list(Xs).
Output:

(d) To display element up to specified index of a list.


Facts:-
Display_element(List, Index, Result):-
length(List, Length),
Length>=Index,
Append(Result, List),
Length(Result, Index).
Output:

(e) To count number of elements in a list.


Fact:-
Count_element([],0).
Count_element([_|T],N):-
Count_element(T,X),
N is X+1.
Output:

(f) To count odd and even elements of a list.


Fact:-
count_odd_even ([], 0, 0).
count_odd_even([H | T ], oddCount, EvenCount) :-
H mod 2 =:= 1, % check is H is odd
(H mod 2 =:= 1)
count_odd_even(T, NewOddCount,
EvenCount), OddCount is
NewOddCount + 1.
count_odd_even ([H | T], OddCount, EvenCount):-
H mod 2 =:= 1, % check is H is odd
(H mod 2 =:= 1)
Artificial Intelligence (3161608) Meet Chikani(210130116011)

count_odd_even(T, OddCount,
NewEvenCount), EvenCount is
NewEvenCount + 1.
Output:

Conclusion:-

The above Prolog programs are designed to perform various operations on lists. These
programs can be used to extract specific elements, count the number of elements, count
odd and even elements, and find the sum of elements in a list. By utilizing these
programs, one can efficiently work with list data structures in Prolog.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 5

Write a prolog program to solve water jug problem.

Competency and Practical Skills: Understanding of basics of water jug problem.

Relevant CO: CO1,CO2

Objectives: The water jug problem, also known as the "water pouring problem" or "die hard
problem," is a classic puzzle in which the objective is to find a sequence of actions to measure a
specific volume of water using two jugs of known capacities. The problem involves critical
thinking and can be used to practice problem-solving skills.

Equipment/Instruments: Personal Computer, PROLOG software

Theory:
The water jug problem, also known as the "water pouring problem" or "die hard problem," is a
classic puzzle that involves finding a sequence of actions to measure or obtain a specific
volume of water using two jugs of known capacities. The problem can vary in complexity
depending on the specific constraints provided. Here is the theoretical background and the key
elements of the water jug problem:

Problem Statement:
- The problem typically involves two jugs with known capacities, often referred to as Jug A
and Jug B.
- There is usually a target volume of water that you need to measure or achieve using the jugs.

Elements of the Problem:


1. Jug Capacities: Each jug has a known capacity, which is the maximum amount of water it
can hold. The capacities of Jug A and Jug B are usually given.
2. Initial State: The problem starts with the jugs in a certain initial state, which includes the
amounts of water in each jug (possibly zero).
3. Goal State: The objective is to reach a goal state where a specific volume of water (the
target) is present in one of the jugs.

Constraints and Rules:


1. Pouring: You can pour water from one jug to another or pour water into or out of the jugs.
Pouring water is typically allowed in discrete amounts and follows certain rules:
- You can fill a jug completely.
- You can empty a jug completely.
- You can pour water from one jug into another until the receiving jug is full or the pouring
jug is empty.

2. Wastage: Some variations of the problem may allow for, or restrict, wastage of water
during the pouring process. Wastage occurs when water is poured out and not used in the
target measurement.

Objectives and Solutions:


The primary objective of the water jug problem is to find a sequence of pouring actions that
will result in the desired volume of water being present in one of the jugs. The problem can be
Artificial Intelligence (3161608) Meet Chikani(210130116011)

solved through various approaches:

1. Systematic Search: This approach involves systematically trying different combinations of


pouring actions to find a solution. It may use algorithms such as breadth-first search,
depth-first search, or heuristic methods to minimize the number of steps.

2. Mathematical Analysis: In some cases, the problem can be solved through mathematical
modeling and equations. The mathematical approach may aim to find the optimal sequence of
actions.

3. Optimization: Once a solution is found, it can be further optimized to minimize the


number of steps or the amount of water wastage.

Variations:
The water jug problem has multiple variations, including different jug capacities, additional
constraints (e.g., limited pouring steps), and variations that involve more than two jugs. Each
variation presents a unique challenge and may require a different approach.
Applications:
While the water jug problem is a classic puzzle, it also has practical applications, such as
modeling fluid transfers, understanding capacity constraints in logistics, and demonstrating
problem-solving techniques in artificial intelligence and computer science.

Solving the water jug problem serves as an excellent exercise in critical thinking,
problem-solving, and algorithm design, making it a valuable educational tool and a fascinating
logic puzzle.

Safety and necessary Precautions:

Procedure:
% Water Jug problem using DFS in Prolog

% Define the initial state


start(jug(0,0)).

% Define the goal state


goal(jug(_,2)).

% Define the actions that can be taken


action(fill1, jug(_,Y), jug(4,Y)).
action(fill2, jug(X,_), jug(X,3)).
action(empty1, jug(_,Y), jug(0,Y)).
action(empty2, jug(X,_), jug(X,0)).
action(pour1to2, jug(X,Y), jug(X1,Y1)) :-
X > 0, Y < 3, Y1 is min(3, X + Y), X1 is X - (Y1 - Y).
action(pour2to1, jug(X,Y), jug(X1,Y1)) :-
Y > 0, X < 4, X1 is min(4, X + Y), Y1 is Y - (X1 - X).

% Define the DFS algorithm


dfs(State, [], _) :- goal(State).
dfs(State, [Action|Actions], Visited) :-
action(Action, State, State1),
State1 \= State,
Artificial Intelligence (3161608) Meet Chikani(210130116011)

\+ member(State1, Visited),
dfs(State1, Actions, [State1|Visited]).

% Run the program


solve(Actions) :-
start(State),
dfs(State, Actions, [State]).

Output:
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 6
Implement the Minimax algorithm for a simple tic-tac-toe game using Python Language.

Competency and Practical Skills:


Basic knowledge of Python programming language, Familiarity with the rules of tic-tac-toe game,
including the board layout and winning conditions.
Understanding of the Minimax algorithm, which is a decision-making algorithm.

Relevant CO: CO3

Objectives: To illustrate how to recursively apply the Minimax algorithm to build a game tree
and determine the optimal move for the computer player.

Equipment/Instruments: Personal Computer, Python3, Jupytor Notebook

Theory:
● The Minimax Algorithm is a popular decision-making algorithm used in game
theory, which allows a player to determine the best possible move to make, given
that the opponent will also make the best possible move.
● Here's a general implementation of the Minimax algorithm:
● Define the game state: The game state should be defined in terms of the current
state of the board or game, including the position of all pieces, scores, and any other
relevant information.
● Define the game tree: The game tree represents all the possible moves that can be
made from the current game state, and the resulting game states that will arise from
each move. The game tree can be constructed recursively, with the root node
representing the current game state, and the child nodes representing the possible
moves that can be made from that state.
● Assign scores to each game state: At the bottom of the game tree, assign a score to
each game state based on the outcome of the game from that state. For example, if
the game is won by the player who reached that state, assign a positive score, and
if the game is lost, assign a negative score.
● Determine the best move: Starting from the root node, alternate between selecting
the move that maximizes the score for the player and selecting the move that
minimizes the score for the opponent until you reach a leaf node. The score of that
leaf node will then be propagated back up the tree to the root node, and the best
move will be the one that leads to the highest score.

Safety and necessary Precautions:

Handle edge cases such as invalid moves, repeated moves, and game-ending conditions to avoid
program crashes or incorrect results.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Procedure:
1. Define an evaluation function to evaluate the game state and return a score.
2. Define a recursive function to search for the best move using the Minimax
algorithm.
3. Create a function to get the best move for the current player.

Observation/Program:
import math

def print_board(board):
for row in board:
print(" ".join(row))

def check_win(board, player):


for row in board:
if all([cell == player for cell in row]):
return True
for col in range(3):
if all([board[row][col] == player for row in range(3)]):
return True
if all([board[i][i] == player for i in range(3)]) or all([board[i][2 - i] == player for i in range(3)]):
return True
return False

def is_full(board):
return all(all(cell != ' ' for cell in row) for row in board)

def evaluate(board):
if check_win(board, 'X'):
return 10
elif check_win(board, 'O'):
return -10
elif is_full(board):
return 0
else:
return None

def minimax(board, depth, maximizing_player):


if evaluate(board) is not None:
return evaluate(board)

if maximizing_player:
max_eval = -math.inf
for row in range(3):
for col in range(3):
if board[row][col] == ' ':
board[row][col] = 'O'
eval = minimax(board, depth - 1, False)
board[row][col] = ' '
max_eval = max(max_eval, eval)
return max_eval
else:
Artificial Intelligence (3161608) Meet Chikani(210130116011)

min_eval = math.inf
for row in range(3):
for col in range(3):
if board[row][col] == ' ':
board[row][col] = 'X'
eval = minimax(board, depth - 1, True)
board[row][col] = ' '
min_eval = min(min_eval, eval)
return min_eval

def find_best_move(board):
best_score = -math.inf
move = (-1, -1)
for row in range(3):
for col in range(3):
if board[row][col] == ' ':
board[row][col] = 'O'
score = minimax(board, 3, False)
board[row][col] = ' '
if score > best_score:
best_score = score
move = (row, col)
return move

def tic_tac_toe():
board = [[' ' for _ in range(3)] for _ in range(3)]
while True:
print_board(board)
print("Player X, enter your move (row and column separated by a space):")
row, col = map(int, input().split())
if board[row - 1][col - 1] == ' ':
board[row - 1][col - 1] = 'X'
if not check_win(board, 'X') and not is_full(board):
move = find_best_move(board)
board[move[0]][move[1]] = 'O'
if check_win(board, 'X'):
print_board(board)
print("Player X wins!")
break
elif is_full(board):
print_board(board)
print("It's a draw!")
break
else:
continue
else:
print("That cell is already occupied. Try again.")
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Output:

Conclusion:-
The Minimax algorithm is a powerful method for decision-making in games,
considering all possible moves and outcomes to find the optimal strategy. It's
widely applicable and can be optimized for efficiency, making it a key tool
for developing AI opponents in various games.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 7
Implement Bayesian Networks algorithm for the Monty Hall Problem using any
programming Language.

Competency and Practical Skills: Understanding of Bayesian Networks.


Familiarity with the Monty Hall problem, which is a classic probability puzzle that involves three
doors and a prize.
Knowledge of probability theory, including conditional probability and Bayes' theorem.
Familiarity with a programming language

Relevant CO: CO4

Objectives:To understand how Bayesian Networks can be used to represent and reason about
uncertain knowledge.

Equipment/Instruments: Personal Computer, Programming Language

Theory:
Bayesian Networks is a probabilistic graphical model used for representing and reasoning about
uncertain knowledge. It consists of a directed acyclic graph (DAG) where nodes represent random
variables and edges represent dependencies between them. Each node has a conditional probability
distribution (CPD) that describes the probability of that node given its parents. Bayesian Networks
can be used for a wide range of tasks including prediction, classification, diagnosis, and decision-
making.
The algorithm for constructing a Bayesian Network involves the following steps:
● Identify the random variables: The first step is to identify the random variables that are
relevant to the problem. These variables can be discrete or continuous, and can represent
events, states, or properties.
● Define the dependencies: The next step is to define the dependencies between the variables.
This is done by specifying the causal relationships between the variables, and determining
which variables are parents and which are children.
● Assign probabilities: The next step is to assign probabilities to the variables. This involves
specifying the prior probabilities for each variable, as well as the conditional probabilities
for each node given its parents.
● Construct the graph: The final step is to construct the DAG by connecting the nodes
according to their dependencies, and specifying the CPDs for each node.

The Monty Hall problem

It is a famous probability puzzle based on a game show scenario. The problem is named after
Monty Hall, the host of the game show "Let's Make a Deal".
The scenario goes as follows:
● There are three doors, behind one of which is a prize, and behind the other two are goats.
The player chooses one door, and then the host, who knows what is behind each door,
Artificial Intelligence (3161608) Meet Chikani(210130116011)

opens one of the other two doors to reveal a goat. The player is then given the option to
switch their choice to the other unopened door or stick with their original choice.
● The question is: should the player switch their choice, or stick with their original choice?
● The answer is that the player should always switch their choice.
● To understand why this is the case, consider the following:
● When the player initially chooses a door, there is a 1/3 chance that they have chosen the
door with the prize, and a 2/3 chance that they have chosen a door with a goat. When the
host then opens one of the other doors to reveal a goat, the probability that the player's initial
choice was correct remains at 1/3. However, the probability that the prize is behind the other
unopened door is now 2/3.
● Therefore, when given the option to switch, the player should always switch because the
probability of winning the prize increases from 1/3 to 2/3. This may seem counterintuitive,
as it goes against our initial intuition that the probability of winning should be equally
distributed among the three doors. However, this is a classic example of how probabilities
can be counterintuitive, and why it is important to understand the underlying mathematics.

● Safety and necessary Precautions:

Ensure that the algorithm produces accurate results, it is important to validate the input
data to ensure that it is consistent and complete.

Procedure:
1. Define an evaluation function to evaluate the game state and return a score.
2. Define a recursive function to search for the best move using the Minimax
algorithm.
3. Create a function to get the best move for the current player.

Observation/Program:
from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import VariableElimination

model = BayesianModel([('Player', 'Host'), ('Prize', 'Host')])

cpd_player = TabularCPD(variable='Player', variable_card=3, values=[[1/3], [1/3], [1/3]])


cpd_prize = TabularCPD(variable='Prize', variable_card=3, values=[[1/3], [1/3], [1/3]])

cpd_host = TabularCPD(variable='Host', variable_card=3,


values=[[0, 0, 0, 1/2, 0, 1, 1/2, 1, 0],
[1/2, 1/2, 1, 0, 1/2, 0, 0, 0, 1/2],
[1/2, 1/2, 0, 1/2, 1/2, 0, 1/2, 0, 1/2]],
evidence=['Player', 'Prize'],
evidence_card=[3, 3])

model.add_cpds(cpd_player, cpd_prize, cpd_host)

inference = VariableElimination(model)

# Assuming the player initially chooses door 0, and the host opens door 1
result = inference.query(variables=['Prize'], evidence={'Player': 0, 'Host': 1})

print(result)
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Output:-

Conclusion:

In the Monty Hall problem, switching doors after one is revealed to be empty increases the
probability of winning from 1/3 to 2/3, while staying with the original choice maintains a 1/3
probability. This counterintuitive result demonstrates the importance of understanding
conditional probabilities in decision-making scenarios.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 8
Demonstrate Connectionist Model using Tool.

Competency and Practical Skills:

Familiarity with neural networks, which are computational models inspired by the structure and
function of the brain.
Familiarity with a neural network tool.

Relevant CO: CO3.CO4

Objectives:Learn a tool should be selected that provides an easy-to-use interface for designing,
training, and deploying Connectionist Model.

Equipment/Instruments: Personal Computer, Connectionist Models Tool

Theory:

Connectionist Models

● In contrast to the symbolist architectures in which the mind is assumed to be a physical


symbol-processing system, connectionist systems are networks of large numbers of
interconnected “units.” Each unit can have associated with it a certain amount of
activation. Connections to other units are given explicit weights (including negative
weights).
● Activation spreads from one unit to another as a function of the weighted links. For
example, the function of a typical link might be to multiply the input activation by its
weight and then apply a threshold function. A typical unit would sum all of its input
activations, then divide this among all its links. The weights on the links are adjustable
with experience.
● Some of the links may represent sensory inputs from the outside world; some may
represent output to effectors to the outside world. Units in connectionist models are
usually taken to be below the level of a symbol. For example, different units may
represent visual features of a letter such as verticalness or roundedness.

Neural networks are by far the most commonly used connectionist model today.

● Though there are a large variety of neural network models, they almost always follow two
basic principles regarding the mind:
● Any mental state can be described as an (N)-dimensional vector of numeric activation
values over neural units in a network.
● Memory is created by modifying the strength of the connections between neural units. The
connection strengths, or "weights", are generally represented as an N×N matrix.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Some Examples of popular tools:

● TensorFlow: An open-source platform developed by Google for building and training


machine learning models, including neural networks. It provides a high-level API that
makes it easy to build complex models with multiple layers and customizable activation
functions.
● PyTorch: An open-source machine learning library developed by Facebook that provides a
dynamic computational graph for building neural networks. It is highly optimized for GPU
acceleration and provides a Pythonic interface for building and training models.
● Keras: A high-level neural networks API developed in Python that can run on top of
TensorFlow, CNTK, or Theano. It provides a simple and intuitive interface for designing
and training neural networks, and supports both convolutional and recurrent networks.
● Caffe: A deep learning framework developed by Berkeley AI Research (BAIR) that is
optimized for speed and memory efficiency. It provides a C++ API for building and training
neural networks and supports a variety of pre-trained models for image recognition and other
tasks.
● FastAI: A Python library that provides tools for building and training deep learning models,
including neural networks, with a focus on ease of use and fast prototyping.

Safety and necessary Precautions:


Different tools are designed for different tasks, and it's crucial to use a tool that is
appropriate for the task at hand.
Procedure:
● Choose a connectionist modeling tool
● Define the problem
● Design the architecture of the
● Implement the model
● Test the model
● Deploy the model

Observation/Program:
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical

(x_train, y_train), (x_test, y_test) = mnist.load_data()


Artificial Intelligence (3161608) Meet Chikani(210130116011)
train_filter = np.where((y_train == 0 ) | (y_train == 1))
test_filter = np.where((y_test == 0) | (y_test == 1))
x_train, y_train = x_train[train_filter], y_train[train_filter]
x_test, y_test = x_test[test_filter], y_test[test_filter]

x_train = x_train.reshape(x_train.shape[0], -1) / 255.0


x_test = x_test.reshape(x_test.shape[0], -1) / 255.0

y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dense(512, activation='relu'))
model.add(Dense(2, activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test))

test_loss, test_acc = model.evaluate(x_test, y_test)

print('Test accuracy:', test_acc)

model.save('mnist_binary_classification.h5')

Output:
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 9
Implement Genetic Algorithm in any Programming Language.

Competency and Practical Skills:

Understanding of genetic algorithms, which are a class of optimization algorithms that are
inspired by the principles of natural selection and genetics.
Knowledge of a programming language

Relevant CO: CO4

Objectives:To use a computational approach that mimics the process of natural selection to solve
optimization problems

Equipment/InstrumentsProgramming language

Theory:

Genetic Algorithm (GA) is a popular meta heuristic optimization algorithm in the field of artificial
intelligence (AI).Genetic Algorithms are based on the theory of natural selection and work on
generating a set of random solutions and making them compete in an arena where only the fittest
survive. It is often used to solve complex optimization problems where other traditional methods
may not work well.

GA works by maintaining a population of candidate solutions (also called chromosomes) and


applies genetic operators such as selection, crossover, and mutation to create new and hopefully
better solutions. The basic idea is to mimic the natural process of evolution and survival of the fittest
in order to find the optimal solution to a problem.

The first step in using GA for an AI problem is to define the problem as an optimization problem.
This involves identifying the objective function that needs to be optimized and the constraints (if
any) that need to be satisfied.

Once the problem is defined, the next step is to create an initial population of candidate solutions.
The population is typically generated randomly or using some heuristics depending on the problem.

The fitness function is then defined, which evaluates each chromosome in the population based on
how well it satisfies the objective function and constraints.

Next, the GA applies selection, crossover, and mutation operators to create new and hopefully better
solutions. Selection involves choosing the top-performing chromosomes to be carried over to the
next generation. Crossover involves combining two chromosomes to create new offspring. Mutation
involves randomly changing some genes in a chromosome to introduce diversity into the population.

The GA then repeats the process of selection, crossover, and mutation for a number of generations
Artificial Intelligence (3161608) Meet Chikani(210130116011)

or until a stopping criterion is met (such as reaching a maximum number of generations or finding
an optimal solution).

Safety and necessary Precautions:

It is important to define clear objectives and constraints for the optimization problem.
It is crucial to validate the fitness function.

Procedure:
1. Define the problem
2. Define the representation
3. Initialize the population.
4. Evaluate the fitness
5. Select parents.
6. Create offspring: Use genetic operators such as crossover and mutation to create offspring
from the selected parents.
7. Evaluate the offspring.
8. Select survivor
9. Check stopping criteria

Observation/Program:
import random

# Define the fitness function


def fitness(individual):
return sum(individual)

# Define the crossover function


def crossover(parent1, parent2):
crossover_point = random.randint(0, len(parent1)
- 1)
child = parent1[:crossover_point] +
parent2[crossover_point:]
return child

# Define the mutation function


def mutation(individual):
for i in range(len(individual)):
if random.random() < 0.01:
individual[i] = 1 - individual[i]
return individual

# Define the initialization function


def initialize_population(pop_size, n):
population = []
for i in range(pop_size):
individual = [random.randint(0, 1) for _ in
range(n)]
population.append(individual)
return population
Artificial Intelligence (3161608) Meet Chikani(210130116011)

# Define the genetic algorithm


def genetic_algorithm(pop_size, n,
num_generations):
population = initialize_population(pop_size, n)
for generation in range(num_generations):

# Evaluate the fitness of the population


fitnesses = [fitness(individual) for individual in
population]

# Select the top individuals


top_individuals = [individual for _, individual
in sorted(zip(fitnesses, population), reverse=True)]

# Create the next generation through crossover and


mutation
next_generation = []
for i in range(pop_size // 2):
parent1, parent2 =
random.sample(top_individuals, 2)
child = crossover(parent1, parent2)
child = mutation(child)
next_generation.append(child)

# Replace the current population with the next


generation
population = next_generation

# Return the best individual


best_individual = max(population, key=fitness)
return best_individual

# Define the problem parameters


pop_size = 100
n = 100
num_generations = 100

# Run the genetic algorithm


best_individual = genetic_algorithm(pop_size, n,
num_generations)

# Print the result


print("Best individual:", best_individual)
print("Fitness:", fitness(best_individual))
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Output:

Conclusion:

In conclusion, genetic algorithms offer an effective heuristic approach for optimization and search
problems, leveraging principles of natural selection and genetics. By iteratively evolving populations of
candidate solutions through selection, crossover, and mutation, genetic algorithms efficiently explore
solution spaces and converge towards optimal or near-optimal solutions, making them valuable in a wide
range of problem domains where traditional methods may be impractical or insufficient.
Artificial Intelligence (3161608) Meet Chikani(210130116011)

Experiment No: 10
Write a prolog program to solve Tower of Hanoi problem.

Competency and Practical Skills:

Knowledge of basic PROLOG syntax

Relevant CO: CO3,CO4

Objectives: The Tower of Hanoi problem is a classic mathematical puzzle that involves moving
a stack of disks from one peg to another while adhering to specific rules. The primary objective is
to find a sequence of moves that allows you to transfer the entire stack to a different peg.

Equipment/Instruments: Personal Computer, SWI-Prolog Interpreter

Theory:

The Tower of Hanoi is a classic mathematical puzzle that was invented by the French mathematician
Édouard Lucas in 1883. It consists of three pegs and a number of disks of different sizes, which can
be slid onto any peg. The puzzle's objective is to move the entire stack of disks from one peg to
another, subject to the following rules:

1. Pegs: There are three pegs: A, B, and C.

2. Initial Configuration: The puzzle begins with all the disks stacked in decreasing order of size
on one peg, typically peg A. The smallest disk is on top, and the largest disk is at the bottom.

3. Goal Configuration: The goal is to move the entire stack of disks to another peg, typically peg
C. The disks should be stacked in the same order (smallest on top, largest on the bottom) on the
destination peg.

4. Intermediate Peg: You can use peg B as an intermediate peg to move the disks. This means
that you can only move one disk at a time from the top of one peg to the top of another peg.

5. Larger Disk on Top: A disk can never be placed on top of a smaller disk.

Theoretical Aspects of the Tower of Hanoi:

1. Recursion: The Tower of Hanoi problem is inherently recursive in nature. To solve a problem
with n disks, you can break it down into smaller subproblems, such as moving the top n-1 disks to
an intermediate peg, moving the largest disk to the destination peg, and then moving the n-1 disks
from the intermediate peg to the destination peg. This recursive decomposition is a fundamental
aspect of the problem.
Artificial Intelligence (3161608) Meet Chikani(210130116011)
2. Minimum Number of Moves: The minimum number of moves required to solve the Tower of
Hanoi problem with n disks is 2^n - 1. This is a well-established theoretical result and is used as a
basis for understanding the problem's complexity.

3. Recursive Formula: The number of moves required to solve the Tower of Hanoi problem for n
disks can be described by the recursive formula: `H(n) = 2 * H(n-1) + 1`, with the base case `H(1)
= 1`.

4. Mathematical Induction: Mathematical induction can be used to prove the minimum number of
moves required to solve the Tower of Hanoi problem for any number of disks.

5. Generalizations: The Tower of Hanoi problem can be generalized to include more than three
pegs, leading to variations like the Tower of Hanoi with four or more pegs. These generalizations
introduce new challenges and require different strategies for solving the problem.

6. Educational Significance: The Tower of Hanoi is often used as an educational tool to teach
concepts of recursion, mathematical induction, and algorithm design. It serves as a classic example
of a problem that can be solved using recursive algorithms.

The Tower of Hanoi problem, with its elegant mathematical properties and recursive nature,
continues to be a fundamental puzzle in computer science, mathematics, and education. It
exemplifies the power of recursion in problem-solving and serves as a valuable teaching and
learning tool.

Safety and necessary Precautions:

The program should handle exceptions, such as input errors or invalid operations.

Observation/Program:

% Define the predicate to move disks

hanoi(1, Source, _, Destination) :-

write('Move disk from '),

write(Source), write(' to '),

write(Destination), nl.

hanoi(N, Source, Auxiliary,

Destination) :-

N > 1,

M is N - 1,

hanoi(M, Source, Destination,

Auxiliary),

hanoi(1, Source, _, Destination),


Artificial Intelligence (3161608) Meet Chikani(210130116011)

hanoi(M, Auxiliary, Source,

Destination).

Output:

Conclusion:

In conclusion, the Tower of Hanoi problem is elegantly solved using Prolog through recursive
backtracking. By defining a predicate `hanoi/4`, the program efficiently generates the sequence of moves
required to transfer a stack of disks from one peg to another while adhering to the rules of the puzzle.
Prolog's declarative nature and built-in backtracking mechanism simplify the implementation of recursive
algorithms, making it a suitable choice for solving such logical puzzles.

You might also like