Lab Manual 15B17CI574 Artificial Intelligence Lab PDF
Lab Manual 15B17CI574 Artificial Intelligence Lab PDF
INFORMATION TECHNOLOGY
LAB MANUAL
Course Name: Artificial Intelligence Lab
Course Code: 15B17CI574
B.Tech 3rd year (6th Sem)
EVEN2023
INSTRUCTIONS:
● The students have to use Python to implement the programs in this lab.
● The students must submit the solutions of the lab assignments before the deadline.
● There will be two lab tests of 20 marks each. Absence in Lab Test-2 means Fail in the lab
course.
● All students are required to attend at least 80% labs. 15 marks are reserved for attendance.
● The students have to do a mini project apart from the Lab Assignments.
COURSE OUTCOMES
C372.1 Construct problem solving agent using various Informed and uninformed search strategies
C372.2 Utilize evolutionary search algorithms to solve the real-world complex problems
Analyze and apply algorithms to solve problems requiring constraint satisfaction and game
C372.3
theory
C372.4 Demonstrate and understand the inference mechanisms using propositional and first order logic
WEEK 1 and 2
TOPIC: INTRODUCTION TO PROGRAMMING IN PYTHON
You invoke the interpreter by opening python in Windows or entering python at the Unix command
prompt.
Note: you may have to type python2.4 or python2.5 (or a more recent version), rather than python,
depending on your machine.
$ python
Python 2.5 (r25:51908, Sep 28 2008, 12:45:36)
[GCC 3.4.6] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>>
• int 105
• float 3.14159
• str “Selection:”, ‘a string’
• bool True, False
• list [‘apple’, ‘banana’, ‘orange’]
• tuple (3.2, 4.5, 6.3)
• dict {‘one’: 1, ‘two’: 2}
Operators:
The Python interpeter can be used to evaluate expressions, for example simple arithmetic expressions.
If you enter such expressions at the prompt (>>>) they will be evaluated and the result wil be returned
on the next line.
>>> 1 + 1
2
>>> 2 * 3
6
>>> 1==0
False
>>> not (1==0)
True
>>> (2==2) and (2==3)
False
>>> (2==2) or (2==3)
True
Strings:
Like Java, Python has a built in string type. The + operator is overloaded to do string concatenation on
string values.
There are many built-in methods which allow you to manipulate strings.
>>> 'artificial'.upper()
'ARTIFICIAL'
>>> 'HELP'.lower()
'help'
>>> len('Help')
4
Notice that we can use either single quotes ' ' or double quotes " " to surround string. This allows for
easy nesting of strings.
We can also store expressions into variables.
In Python, you do not have declare variables before you assign to them.
>>> s = 'abc'
>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__','__le__', '__len__',
'__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__','__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__',
'capitalize', 'center', 'count', 'decode', 'encode', 'endswith',
'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'replace', 'rfind','rindex', 'rjust', 'rsplit', 'rstrip', 'split',
'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate',
'upper', 'zfill']
>>> help(s.find)
find(...)
S.find(sub [,start [,end]]) -> int
Return -1 on failure.
>> s.find('b')
1
Python comes equipped with some useful built-in data structures, broadly similar to Java's collections
package.
Lists
Lists store a sequence of mutable items:
Python also allows negative-indexing from the back of the list. For instance, fruits[-1] will access the
last element 'banana':
>>> fruits[-2]
'pear'
>>> fruits.pop()
'banana'
>>> fruits
['apple', 'orange', 'pear']
>>> fruits.append('grapefruit')
>>> fruits
['apple', 'orange', 'pear', 'grapefruit']
>>> fruits[-1] = 'pineapple'
>>> fruits
['apple', 'orange', 'pear', 'pineapple']
>>> fruits[0:2]
['apple', 'orange']
>>> fruits[:3]
['apple', 'orange', 'pear']
>>> fruits[2:]
['pear', 'pineapple']
>>> len(fruits)
4
The items stored in lists can be any Python data type. So for instance we can have lists of lists:
Tuples
A data structure similar to the list is the tuple, which is like a list except that it is immutable once it is
created (i.e. you cannot change its content once created). Note that tuples are surrounded with
parentheses while lists have square brackets.
The attempt to modify an immutable structure raised an exception. Exceptions indicate errors: index
out of bounds errors, type errors, and so on will all report exceptions in this way.
Set
A set is another data structure that serves as an unordered list with no duplicate items. Below, we
show how to create a set, add things to the set, test if an item is in the set, and perform common set
operations (difference, intersection, union):
Dictionaries
The last built-in data structure is the dictionary which stores a map from one type of object (the key)
to another (the value). The key must be an immutable type (string, number, or tuple). The value can be
any Python data type.
Warning: In the example below, the printed order of the keys returned by Python could be different
than shown below. The reason is that unlike lists which have a fixed ordering, a dictionary is simply a
hash table for which there is no fixed ordering of the keys.
Writing Scripts
Now that you've got a handle on using Python interactively, let's write a simple Python script that
demonstrates Python's for loop. Open the file called foreach.py and update it with the following code:
# This is what a comment looks like
fruits = ['apples','oranges','pears','bananas']
for fruit in fruits:
print fruit + ' for sale'
At the command line, use the following command in the directory containing foreach.py:
Writing Functions
As in Scheme or Java, in Python you can define your own functions:
fruitPrices = {'apples':2.00, 'oranges': 1.50, 'pears': 1.75}
# Main Function
if __name__ == '__main__':
buyFruit('apples',2.4)
buyFruit('coconuts',2)
Defining Classes
Here's an example of defining a class named FruitShop:
class FruitShop:
def getName(self):
return self.name
The FruitShop class has some data, the name of the shop and the prices per pound of some fruit, and it
provides functions, or methods, on this data. What advantage is there to wrapping this data in a class?
Using Objects
We then import the code from the saved file (making it accessible to other scripts) using import shop,
since shop.py is the name of the file. Then, we can create FruitShop objects as follows:
import shop
The import shop statement told Python to load all of the functions and classes in shop.py. The
line berkeleyShop = shop.FruitShop(shopName, fruitPrices) constructs an instance of
the FruitShop class defined in shop.py, by calling the __init__ function in that class. Note that we only
passed two arguments in, while __init__ seems to take three arguments: (self, name, fruitPrices). The
reason for this is that all methods in a class have self as the first argument. The self variable's value is
automatically set to the object itself; when calling a method, you only supply the remaining
arguments. The self variable contains all the data (name and fruitPrices) for the current specific
instance (similar to this in Java).
Some Basics
Python's range() Parameters
The range() function has two sets of parameters, as follows:
range(stop)
● stop: Number of integers (whole numbers) to generate, starting from zero. eg. range(3) == [0,
1, 2].
range([start], stop[, step])
Iterating Lists
File Handling
Writing data to a file
>>>file.open('data.txt','w')
>>>file.close()
print line
EXERCISES
1. Define a function max() that takes two numbers as arguments and returns the largest of them. Use
the if-then-else construct available in Python.
2. Define a function max_of_three() that takes three numbers as arguments and returns the largest of
them.
4. Write a function that takes a character (i.e. a string of length 1) and returns True if it is a
vowel, False otherwise.
5. Write a function translate() that will translate a text into "rövarspråket" (Swedish for "robber's
language"). That is, double every consonant and place an occurrence of "o" in between. For
example, translate("this is fun")should return the string "tothohisos isos fofunon".
6. Define a function sum() and a function multiply() that sums and multiplies (respectively) all the
numbers in a list of numbers. For example, sum([1, 2, 3, 4]) should return 10, and multiply([1, 2, 3,
4]) should return 24.
8. Define a function is_palindrome() that recognizes palindromes (i.e. words that look the same
written backwards). For example, is_palindrome("radar") should return True.
9. Define a procedure histogram() that takes a list of integers and prints a histogram to the screen. For
example,histogram([4, 9, 7]) should print the following:
****
*********
*******
10. Write a program to compute the number of characters, words and lines in a file.
12. Find the sum of all the primes below 10000. Each new term in the Fibonacci sequence is
generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be: 1, 2,
3, 5, 8, 13, 21, 34, 55, 89,...
15. Write a function ball_collide that takes two balls as parameters and computes if they are
colliding. Your function should return a Boolean representing whether or not the balls are colliding.
Hint: Represent a ball on a plane as a tuple of (x, y, r), r being the radius If (distance between two
balls centers) <= (sum of their radii) then (they are colliding)
EVEN2023
COURSE NAME: ARTIFICIAL INTELLIGENCE LAB
COURSE CODE: 15B17CI574
WEEK 3
PROBLEM SOLVING- UNINFORMED SEARCH
A stack is a linear data structure that stores items in a Last-In/First-Out (LIFO) or First-In/Last-Out
(FILO) manner. In stack, a new element is added at one end and an element is removed from that end
only. The insert and delete operations are often called push and pop.
stack = []
# append() function to push
# element in the stack
stack.append('a')
stack.append('b')
stack.append('c')
print('Initial stack')
print(stack)
# pop() function to pop
# element from stack in
# LIFO order
print('\nElements popped from stack:')
print(stack.pop())
print(stack.pop())
print(stack.pop())
print('\nStack after elements are popped:')
print(stack)
Like stack, queue is a linear data structure that stores items in First In First Out (FIFO) manner. With a
queue the least recently added item is removed first. A good example of queue is any queue of
consumers for a resource where the consumer that came first is served first.
In Artificial Intelligence, Search techniques are universal problem-solving methods. Rational agents
or Problem-solving agents in AI mostly used these search strategies or algorithms to solve a specific
problem and provide the best result. Problem-solving agents are the goal-based agents and use atomic
representation. In this topic, we will learn various problem-solving search algorithms.
1. Uninformed/Blind Search:
The uninformed search does not contain any domain knowledge such as closeness, the location of the
goal. It operates in a brute-force way as it only includes information about how to traverse the tree and
how to identify leaf and goal nodes. Uninformed search applies a way in which search tree is searched
without any information about the search space like initial state operators and test for the goal, so it is
also called blind search. It examines each node of the tree until it achieves the goal node. Following
are few examples of such search strategies:
● Breadth-first search
● Uniform cost search
● Depth-first search
● Iterative deepening depth-first search
2. Informed Search
Informed search algorithms use domain knowledge. In an informed search, problem information is
available which can guide the search. Informed search strategies can find a solution more efficiently
than an uninformed search strategy. Informed search is also called a Heuristic search. A heuristic is a
way which might not always be guaranteed for best solutions but guaranteed to find a good solution in
reasonable time. Informed search can solve much complex problem which could not be solved in
another way. An example of informed search algorithms is a traveling salesman problem.
● Greedy Search
● A* Search
Breadth-First Search (BFS) is an algorithm used for traversing graphs or trees. Traversing means
visiting each node of the graph. Breadth-First Search is a recursive algorithm to search all the vertices
of a graph or a tree. BFS in python can be implemented by using data structures like a dictionary and
lists. Breadth-First Search in tree and graph is almost the same. The only difference is that the graph
may contain cycles, so we may traverse to the same node again.
create a queue Q
mark v as visited and put v into Q
while Q is non-empty
remove the head u of Q
mark and enqueue all (unvisited) neighbors of u
The Depth-First Search is a recursive algorithm that uses the concept of backtracking. It involves
thorough searches of all the nodes by going ahead if potential, else by backtracking. Here, the word
backtrack means once you are moving forward and there are not any more nodes along the present
path, you progress backward on an equivalent path to seek out nodes to traverse. All the nodes are
progressing to be visited on the current path until all the unvisited nodes are traversed after which
subsequent paths are going to be selected.
The pseudocode for Depth-First Search in python goes as below: In the init() function, notice that we
run the DFS function on every node because many times, a graph may contain two different
disconnected part and therefore to make sure that we have visited every vertex, we can also run the
DFS algorithm at every node.
DFS(G, u)
{
u.visited = true
for each v ∈ G.Adj[u]
if v.visited == false
DFS(G,v)
}
init() {
For each u ∈ G
u.visited = false
For each u ∈ G
DFS(G, u)
}
Uniform-Cost Search
UCS expands node with least path cost g so far. UCS is the modification of BFS. Instead of using the
First-In-First-Out queue, it uses a priority queue with path cost g(n) to order the nodes.
The iterative deepening algorithm is a combination of DFS and BFS algorithms. This search
algorithm finds out the best depth limit and does it by gradually increasing the limit until a goal is
found. This algorithm performs depth-first search up to a certain "depth limit", and it keeps increasing
the depth limit after each iteration until the goal node is found. This Search algorithm combines the
benefits of Breadth-first search's fast search and depth-first search's memory efficiency. The iterative
search algorithm is useful uninformed search when search space is large, and depth of goal node is
unknown.
8 Puzzle Problem
Given a 3×3 board with 8 tiles (every tile has one number from 1 to 8) and one empty space. The
objective is to place the numbers on tiles to match the final configuration using the empty space. We
can slide four adjacent (left, right, above, and below) tiles into the empty space.
We can perform a depth-first search on state-space (Set of all configurations of a given problem i.e. all
states that can be reached from the initial state) tree.
In this solution, successive moves can take us away from the goal rather than bringing us closer. The
search of state-space tree follows the leftmost path from the root regardless of the initial state.
EXERCISES:
1. Write a procedure that is analogous to list referencing, but for trees. This "tree_ref" procedure will
take a tree and an index, and return the part of the tree (a leaf or a subtree) at that index. For trees,
indices will have to be lists of integers. Consider the tree in Figure 1, represented by this Python tuple:
(((1, 2), 3), (4, (5, 6)), 7, (8, 9, 10)).To select the element 9 out of it, we'd normally need to do
something like tree[3][1]. Instead, we'd prefer to do tree_ref(tree, (3, 1)) (note that we're using
zero-based indexing, as in list-ref, and that the indices come in top-down order; so an index of (3, 1)
means you should take the fourth branch of the main tree, and then the second branch of that subtree).
As another example, the element 6 could be selected by tree_ref(tree, (1, 1, 1)). Note that it's okay for
the result to be a subtree, rather than a leaf. So tree_ref(tree, (0,)) should return ((1, 2), 3).
7. You are given a m litre jug and a n litre jug. Both the jugs are initially empty. The jugs don't have
markings to allow measuring smaller quantities. You have to use the jugs to measure d litres of water
where d is less than n. Provide a solution using BFS or DFS.
(Statel, State2) corresponds to a state where Statel refers to amount of water in Jugl and State2 refers
to amount of water in Jug2. Determine the path from initial state (Statel_initial, State2_initial) to final
state (Statel_final, State2_final), where
(Statel_initial, State2_initial ) is (0, 0) which indicates both Jugs are initially empty and (State1_final,
State2_final) indicates a state which could be (0, d) or (d, 0).
EVEN2023
COURSE NAME: ARTIFICIAL INTELLIGENCE LAB
COURSE CODE: 15B17CI574
WEEK 4
PROBLEM SOLVING- INFORMED SEARCH
Hill Climbing
Hill Climbing is a heuristic search used for mathematical optimization problems in the field of
Artificial Intelligence. Given a large set of inputs and a good heuristic function, it tries to find a
sufficiently good solution to the problem. This solution may not be the global optimal maximum. In
the above definition, mathematical optimization problems imply that hill-climbing solves the
problems where we need to maximize or minimize a given real function by choosing values from the
given inputs. Example-Travelling salesman problem where we need to minimize the distance traveled
by the salesman.
‘Heuristic search’ means that this search algorithm may not find the optimal solution to the problem.
However, it will give a good solution in a reasonable time. A heuristic function is a function that will
rank all the possible alternatives at any branching step in the search algorithm based on the available
information. It helps the algorithm to select the best route out of possible routes.
A* Algorithm
A* Algorithm is one of the best and popular techniques used for path finding and graph traversals. A
lot of games and web-based maps use this algorithm for finding the shortest path efficiently. It is
essentially a best first search algorithm. The implementation of A* Algorithm involves maintaining
two lists- OPEN and CLOSED. OPEN contains those nodes that have been evaluated by the heuristic
function but have not been expanded into successors yet. CLOSED contains those nodes that have
already been visited.
1: Define a list OPEN. Initially, OPEN consists solely of a single node, the start node S.
2: If the list is empty, return failure and exit.
3: Remove node n with the smallest value of f(n) from OPEN and move it to list CLOSED.
If node n is a goal state, return success and exit.
4: Expand node n.
5: If any successor to n is the goal node, return success and the solution by tracing the path from goal
node to S. Otherwise, go to Step-06.
6: For each successor node:
Apply the evaluation function f to the node.
If the node has not been in either list, add it to OPEN.
7: Go back to Step-02.
EXERCISES:
1. Develop an object for managing a game of Tic Tac Toe. Create a class called TTT Board that
defines the following functions:
a) _init__(self): Initialize a 3x3 tic tac toe board
b) _str__(self): Returns a string representation of the board
c) makeMove(self, player, pos): Places a move for player in the position pos (where the board squares
a numbered from left to right, starting in the top left square with 0, and beginning at the left in each
new row), if possible. 'player' is a character ("X" or "O") and pos is an integer. Returns True if the
move was made and False if not (because the spot was full, or outside the boundaries of the board).
d) hasWon(self,player): Returns True if player has won the game, and False if not
e) gameOver(self): Returns True if someone has won or if the board is full, False otherwise f)
clear(self): Clears the board to reset the game
You may represent the board however you like. You may define other functions as well. You may
wish also to define a function that allows two players to play the game to make sure your above
functions are working correctly.
2. Implement Hill Climbing algorithm for the given instance of 8 puzzle problem,
3. Implement A* algorithm
EVEN2023
COURSE NAME: ARTIFICIAL INTELLIGENCE LAB
COURSE CODE: 15B17CI574
WEEK 5 and 6
TOPIC: EVOLUTIONARY ALGORITHMS
The working of GA will be explained through finding a solution to the traveling salesman problem
(TSP). The TSP is described as follows:
“Given a list of cities and the distances between each pair of cities, what is the shortest possible route
that visits each city and returns to the origin city?”
Let’s start with a few definitions, rephrased in the context of the TSP:
1. Create Population
population_set = []
for i in range(n_population):
#Randomly generating a new solution
sol_i = city_list[np.random.choice(list(range(n_cities)),
n_cities, replace=False)]
population_set.append(sol_i)
return np.array(population_set)
2. Determine fitness
#individual solution
def fitness_eval(city_list, cities_dict):
total = 0
for i in range(n_cities-1):
a = city_list[i]
b = city_list[i+1]
total += compute_city_distance_names(a,b, cities_dict)
return total
#All solutions
def get_all_fitnes(population_set, cities_dict):
fitnes_list = np.zeros(n_population)
return fitnes_list
def progenitor_selection(population_set,fitnes_list):
total_fit = fitnes_list.sum()
prob_list = fitnes_list/total_fit
progenitor_list_a = population_set[progenitor_list_a]
progenitor_list_b = population_set[progenitor_list_b]
return np.array([progenitor_list_a,progenitor_list_b])
4. Crossover
return offspring
return new_population_set
5. Mutate
def mutate_offspring(offspring):
for q in range(int(n_cities*mutation_rate)):
a = np.random.randint(0,n_cities)
b = np.random.randint(0,n_cities)
return offspring
best_solution = [-1,np.inf,np.array([])]
for i in range(100000):
if i%100==0: print(i, fitnes_list.min(), fitnes_list.mean(),
datetime.now().strftime("%d/%m/%y %H:%M"))
fitnes_list = get_all_fitnes(mutated_pop,cities_dict)
progenitor_list =
progenitor_selection(population_set,fitnes_list)
new_population_set = mate_population(progenitor_list)
mutated_pop = mutate_population(new_population_set)
EXERCISES
1: Design a GA for travelling salesman problem. Your solution should contain different functions for:
● Initializing Population
● Fitness Computation
● Selection for reproduction
● Crossover
● Mutation.
2: Consider a card splitting exercise, which is as detailed here: You have 10 cards numbered 1 to 10
and have to divide them into two piles so that: The sum of the first pile is as close as possible to 36
and the product of all in the second pile is as close as possible to 360. Solve this logic problem using
GA.
3: Implement GA for coin change problem which is stated below: The change-making problem
addresses the question of finding the minimum number of coins (of certain denominations) that add
up to a given amount of money. Coin values can be modeled by a set of n distinct positive integer
values (whole numbers), arranged in increasing order as w1= 1 through n. The problem is: given an
amount W, also a positive integer, to find a set of non- negative (positive or zero) integers {x1; x2; ...,
xn}, with each xj representing how often the coin with value wj is used, which minimize the total
number of coins.
EVEN2023
COURSE NAME: ARTIFICIAL INTELLIGENCE LAB
COURSE CODE: 15B17CI574
WEEK 7 and 8
TOPIC: CONSTRAINT SATISFACTION PROBLEM
Cryptarithmetic Puzzle:
Cryptarithmetic Problem is a type of constraint satisfaction problem where the game is about digits
and its unique replacement either with alphabets or other symbols. In cryptarithmetic problems, the
digits (0-9) get substituted by some possible alphabets or symbols. The task in cryptarithmetic
problems is to substitute each digit with an alphabet to get the result arithmetically correct.
We can perform all the arithmetic operations on a given cryptarithmetic problem.
The rules or constraints on a cryptarithmetic problem are as follows:
● There should be a unique digit to be replaced with a unique alphabet.
● The result should satisfy the predefined arithmetic rules, i.e., 2+2 =4, nothing else.
● Digits should be from 0-9 only.
● There should be only one carry forward, while performing the addition operation on a
problem.
● The problem can be solved from both sides, i.e., lefthand side (L.H.S), or righthand side
(R.H.S)
Let’s understand the cryptarithmetic problem as well its constraints better with the help of an
example:
Note: When we will solve further, we will get one carry, so after applying it, the answer will be
satisfied.
● Further, adding the next two terms N and R we get,
But, we have already assigned E->5. Thus, the above result does not satisfy the values
because we are getting a different value for E. So, we need to think more.
Again, after solving the whole problem, we will get a carryover on this term, so our answer will be
satisfied.
EXERCISE
i.e., S E N D + M O R E = M O N E Y
Ques 2: You are a recruiter for a software firm and the task of hiring technical staff for the upcoming
project is assigned to you. Project requirement are mentioned as below
2 C# Programmers
2 Flash Designers
1 Photoshop Expert
1 Database Admin
1 Systems Engineer
You have selected the following people for the interview:
Palak C# and Flash
Jayant Photoshop and Flash
Jaideep Flash and Systems
Jaya C# and Database
Madhav Photoshop and Flash
Bhawna Systems and C#
Chandni Photoshop and Flash
Note that:
• If a person knows two languages/softwares, he or she can take on two roles in the company.
• You have already hired Anmol who knows C#.
• You can now hire only three more people to fulfill all the requirements of the project.
WEEK 9 and 10
TOPIC: ADVERSARIAL SEARCH
Adversarial search is a search, where we examine the problem which arises when we try to plan ahead
of the world and other agents are planning against us.
● In previous topics, we have studied the search strategies which are only associated with a
single agent that aims to find the solution which is often expressed in the form of a sequence
of actions.
● But, there might be some situations where more than one agent is searching for the solution in
the same search space, and this situation usually occurs in game playing.
● The environment with more than one agent is termed a multi-agent environment, in which
each agent is an opponent of another agent and playing against each other. Each agent needs
to consider the action of another agent and the effect of that action on their performance.
● So, Searches in which two or more players with conflicting goals are trying to explore the
same search space for the solution, are called adversarial searches, often known as Games.
● Games are modeled as a Search problem and heuristic evaluation function, and these are the
two main factors which help to model and solve games in AI.
Imperfect information Battleships, blind, tic-tac-toe Bridge, poker, scrabble, nuclear war
● Perfect information: A game with the perfect information is that in which agents can look
into the complete board. Agents have all the information about the game, and they can see
each other's moves also. Examples are Chess, Checkers, Go, etc.
● Imperfect information: If in a game agent do not have all information about the game and
are not aware of what's going on, such types of games are called the game with imperfect
information, such as tic-tac-toe, Battleship, blind, Bridge, etc.
● Deterministic games: Deterministic games are those games which follow a strict pattern and
set of rules for the games, and there is no randomness associated with them. Examples are
chess, Checkers, Go, tic-tac-toe, etc.
● Non-deterministic games: non-deterministic are those games which have various
unpredictable events and have a factor of chance or luck. This factor of chance or luck is
introduced by either dice or cards. These are random, and each action response is not fixed.
Such games are also called stochastic games.
Example: Backgammon, Monopoly, Poker, etc.
Zero-Sum Game
Game tree:
A game tree is a tree where nodes of the tree are the game states and Edges of the tree are the moves
by players. Game tree involves initial state, actions function, and result Function.
Example Explanation:
● From the initial state, MAX has 9 possible moves as he starts first. MAX place x and MIN
place o, and both players play alternatively until we reach a leaf node where one player has
three in a row or all squares are filled.
● Both players will compute each node, minimax, the minimax value which is the best
achievable utility against an optimal adversary.
● Suppose both the players are well aware of the tic-tac-toe and playing the best play. Each
player is doing his best to prevent another one from winning. MIN is acting against Max in
the game.
● So in the game tree, we have a layer of Max, a layer of MIN, and each layer is called as Ply.
Max places x, then MIN puts o to prevent Max from winning, and this game continues until
the terminal node.
● In this either MIN wins, MAX wins, or it's a draw. This game-tree is the whole search space
of possibilities that MIN and MAX are playing tic-tac-toe and taking turns alternately.
Hence adversarial Search for the minimax procedure works as follows:
● It aims to find the optimal strategy for MAX to win the game.
● It follows the approach of Depth-first search.
● In the game tree, optimal leaf nodes could appear at any depth of the tree.
● Propagate the minimax values up to the tree until the terminal node is discovered.
In a given game tree, the optimal strategy can be determined from the minimax value of each node,
which can be written as MINIMAX (n). MAX prefer to move to a state of maximum value and MIN
prefer to move to a state of minimum value then:
EXERCISE
Implement Tic-Tac-Toe game using MINIMAX and Alpha-Beta Pruning algorithm
EVEN2023
COURSE NAME: ARTIFICIAL INTELLIGENCE LAB
COURSE CODE: 15B17CI574
WEEK 11-13
TOPIC: KNOWLEDGE REPRESENTATION
Humans are best at understanding, reasoning, and interpreting knowledge. Humans know things,
which is knowledge and as per their knowledge they perform various actions in the real world. But
how machines do all these things comes under knowledge representation and reasoning. Hence, we
can describe Knowledge representation as following:
● Knowledge representation and reasoning (KR, KRR) is the part of Artificial intelligence
which is concerned with AI agents thinking and how thinking contributes to intelligent
behavior of agents.
● It is responsible for representing information about the real world so that a computer can
understand and can utilize this knowledge to solve complex real-world problems such as
diagnosing a medical condition or communicating with humans in natural language.
● It is also a way which describes how we can represent knowledge in artificial intelligence.
Knowledge representation is not just storing data into some database, but it also enables an
intelligent machine to learn from that knowledge and experiences so that it can behave
intelligently like a human.
Knowledge is awareness or familiarity gained by experiences of facts, data, and situations. Following
are the types of knowledge in artificial intelligence:
Types of knowledge
Following are the various types of knowledge:
1. Declarative Knowledge:
● Declarative knowledge is to know about something.
● It includes concepts, facts, and objects.
● It is also called descriptive knowledge and expressed in declarative sentences.
● It is simpler than procedural language.
2. Procedural Knowledge
● It is also known as imperative knowledge.
● Procedural knowledge is a type of knowledge which is responsible for knowing how to do
something.
● It can be directly applied to any task.
● It includes rules, strategies, procedures, agendas, etc.
● Procedural knowledge depends on the task on which it can be applied.
3. Meta-knowledge:
· Knowledge about the other types of knowledge is called Meta-knowledge.
4.Heuristic knowledge:
● Heuristic knowledge is representing knowledge of some experts in a field or subject.
● Heuristic knowledge is rules of thumb based on previous experiences, awareness of
approaches, and which are good to work but not guaranteed.
5.Structural knowledge:
● Structural knowledge is basic knowledge of problem-solving.
● It describes relationships between various concepts such as kind of, part of, and grouping of
something.
● It describes the relationship that exists between concepts or objects.
AI knowledge cycle:
An Artificial intelligence system has the following components for displaying intelligent behavior:
● Perception
● Learning
● Knowledge Representation and Reasoning
● Planning
● Execution
The diagram is showing how an AI system can interact with the real world and what components help
it to show intelligence.
● AI systems have a Perception component by which it retrieves information from its
environment.
● It can be visual, audio or another form of sensory input.
● The learning component is responsible for learning from data captured by the Perception
compartment.
● In the complete cycle, the main components are knowledge representation and Reasoning.
● These two components are involved in showing intelligence in machine-like humans.
● These two components are independent with each other but also coupled together.
● The planning and execution depend on analysis of Knowledge representation and reasoning.
man(Marcus)
∀x = man (x) ----------> mortal (x)s
4. Procedural knowledge:
● Procedural knowledge approach uses small programs and codes which describe how to do
specific things, and how to proceed.
● In this approach, one important rule is used which is the If-Then rule.
● In this knowledge, we can use various coding languages such as LISP language and Prolog
language.
● We can easily represent heuristic or domain-specific knowledge using this approach.
● But it is not necessary that we can represent all cases in this approach.
1. Representational Accuracy: The KR system should have the ability to represent all kinds of
required knowledge.
3. Inferential Efficiency: The ability to direct the inferential knowledge mechanism into the most
productive directions by storing appropriate guides.
4. Acquisitional efficiency- The ability to acquire new knowledge easily using automatic
methods.
Prolog, as the name itself suggests, is the short form of LOGical PROgramming. It is a logical and
declarative programming language. Before diving deep into the concepts of Prolog, let us first
understand what exactly logical programming is.
Logic Programming is one of the Computer Programming Paradigm, in which the program statements
express the facts and rules about different problems within a system of formal logic. Here, the rules
are written in the form of logical clauses, where head and body are present. For example, H is the
head and B1, B2, B3 are the elements of the body. Now if we state that “H is true, when B1, B2, B3
all are true”, this is a rule. On the other hand, facts are like the rules, but without any body. So, an
example of fact is “H is true”.
Some logic programming languages like Datalog or ASP (Answer Set Programming) are known as
purely declarative languages. These languages allow statements about what the program should
accomplish. There is no such step-by-step instruction on how to perform the task. However, other
languages like Prolog, have declarative and also imperative properties. This may also include
procedural statements like “To solve the problem H, perform B1, B2 and B3”.
Some logic programming languages are given below −
● ALF (algebraic logic functional programming language).
● ASP (Answer Set Programming)
● CycL
● Datalog
● FuzzyCLIPS
● Janus
● Parlog
● Prolog
● Prolog++
● ROOP
Inference engine:
The inference engine is the component of the intelligent system in artificial intelligence, which applies
logical rules to the knowledge base to infer new information from known facts. The first inference
engine was part of the expert system. Inference engine commonly proceeds in two modes, which are:
A. Forward Chaining
Forward chaining is also known as a forward deduction or forward reasoning method when using an
inference engine. Forward chaining is a form of reasoning which start with atomic sentences in the
knowledge base and applies inference rules (Modus Ponens) in the forward direction to extract more
data until a goal is reached.
The Forward-chaining algorithm starts from known facts, triggers all rules whose premises are
satisfied, and adds their conclusion to the known facts. This process repeats until the problem is
solved.
Properties of Forward-Chaining:
● It is a down-up approach, as it moves from bottom to top.
● It is a process of making a conclusion based on known facts or data, by starting from the
initial state and reaching the goal state.
● Forward-chaining approach is also called data-driven as we reach the goal using available
data.
● Forward -chaining approach is commonly used in the expert system, such as CLIPS, business,
and production rule systems.
Consider the following famous example which we will use in both approaches:
Example:
"As per the law, it is a crime for an American to sell weapons to hostile nations. Country A, an
enemy of America, has some missiles, and all the missiles were sold to it by Robert, who is an
American citizen."
Prove that "Robert is a criminal."
To solve the above problem, first, we will convert all the above facts into first-order definite clauses,
and then we will use a forward-chaining algorithm to reach the goal.
Facts Conversion into FOL:
● It is a crime for an American to sell weapons to hostile nations. (Let's say p, q, and r are
variables)
American (p) ∧ weapon(q) ∧ sells (p, q, r) ∧ hostile(r) → Criminal(p) ...(1)
● Country A has some missiles. ?p Owns(A, p) ∧ Missile(p). It can be written in two definite
clauses by using Existential Instantiation, introducing new Constant T1.
Owns(A, T1) ......(2)
Missile(T1) .......(3)
● All of the missiles were sold to country A by Robert.
?p Missiles(p) ∧ Owns (A, p) → Sells (Robert, p, A) ......(4)
● Missiles are weapons.
Missile(p) → Weapons (p) .......(5)
● Enemy of America is known as hostile.
Enemy(p, America) →Hostile(p) ........(6)
● Country A is an enemy of America.
Enemy (A, America) .........(7)
● Robert is American
American(Robert). ..........(8)
Step-1:
In the first step we will start with the known facts and will choose the sentences which do not have
implications, such as: American(Robert), Enemy(A, America), Owns(A, T1), and Missile(T1). All
these facts will be represented as below.
Step-2:
At the second step, we will see those facts which infer from available facts and with satisfied
premises.
Rule-(1) does not satisfy premises, so it will not be added in the first iteration.
Rule-(2) and (3) are already added.
Rule-(4) satisfy with the substitution {p/T1}, so Sells (Robert, T1, A) is added, which infers from the
conjunction of Rule (2) and (3).
Rule-(6) is satisfied with the substitution(p/A), so Hostile(A) is added and which infers from Rule-(7).
Step-3:
At step-3, as we can check Rule-(1) is satisfied with the substitution {p/Robert, q/T1, r/A}, so we
can add Criminal(Robert) which infers all the available facts. And hence we reached our goal
statement.
B. Backward Chaining:
Backward-Chaining proof:
In Backward chaining, we will start with our goal predicate, which is Criminal(Robert), and then
infer further rules.
Step-1:
At the first step, we will take the goal fact. And from the goal fact, we will infer other facts, and at
last, we will prove those facts true. So our goal fact is "Robert is Criminal," so following is the
predicate of it.
Step-2:
At the second step, we will infer other facts form goal fact which satisfies the rules. So as we can see
in Rule-1, the goal predicate Criminal (Robert) is present with substitution {Robert/P}. So we will add
all the conjunctive facts below the first level and will replace p with Robert.
Here we can see American (Robert) is a fact, so it is proved here.
Step-3:t At step-3, we will extract further fact Missile(q) which infer from Weapon(q), as it satisfies
Rule-(5). Weapon (q) is also true with the substitution of a constant T1 at q.
Step-4:
At step-4, we can infer facts Missile(T1) and Owns(A, T1) form Sells(Robert, T1, r) which satisfies
the Rule- 4, with the substitution of A in place of r. So these two statements are proved here.
Step-5:
At step-5, we can infer the fact Enemy(A, America) from Hostile(A) which satisfies Rule- 6. And
hence all the statements are proved true using backward chaining.
Prolog has a built in backward chaining inference engine which can be used to partially implement
some expert system. Prolog rules are used for the knowledge representation, and the Prolog inference
engine is used to derive conclusions. Other portions of the system, such as the user interface must be
coded using Prolog as a programming language.
The Prolog inference engine does simple backward chaining. Each rule has a goal and a number of ub
goals. The Prolog inference engine either proves or disproves each goal. There is no uncertainity
associated with the results.
You need to represent the knowledge base in online Prolog engine and analyse the inference results.
Try out the different problem statement and run your queries on the following engine:
https://swish.swi-prolog.org/example/prolog_tutorials.swinb
This program consists of two clauses. The first clause is a unit clause, having no body. The
second is a rule, because it does have a body. The body of the second clause is on the right
side of the ':-' which can be read as "if". The body consists of literals separated by commas ','
each of which can be read as "and". The head of a clause is the whole clause if the clause is
a unit clause, otherwise the head of a clause is the part appearing to the left of the colon in
':-'. A declarative reading of the first (unit) clause says that "the factorial of 0 is 1" and the
second clause declares that "the factorial of N is F if N>0 and N1 is N-1 and the factorial of
N1 is F1 and F is N*F1".
The Prolog goal to calculate the factorial of the number 3 responds with a value for W, the
goal variable:
Example 2:
A famous problem in mathematics concerns coloring adjacent planar regions. Like
cartographic maps, it is required that, whatever colors are actually used, no two adjacent
regions may not have the same color. Two regions are considered adjacent provided they
share some boundary line segment. Consider the following map.
EXERCISES
● Butch is a killer.
● Mia and Marsellus are married.
● Zed is dead.
● Marsellus kills everyone who gives Mia a foot massage.
● Mia loves everyone who is a good dancer.
● Jules eats anything that is nutritious or tasty.
wizard(ron).
has Wand(harry).
quidditchPlayer(harry).
wizard(X):- hasBroom(X), hasWand(X).
hasBroom(X):- quidditchPlayer(X).
wizard(ron).
witch(ron).
wizard(hermione).
witch(hermione).
wizard(harry).
wizard(Y).
witch(Y).
Zebra Puzzle: There are five houses, each painted in a unique color. Their inhabitants are from
different nations, own different pets, drink different beverages and smoke different brands of
cigarettes.
1. The Englishman lives in the red house.
2. The Spaniard owns the dog.
3. Coffee is drunk in the green house.
4. The Ukrainian drinks tea.
5. From your perspective, the green house is immediately to the right of the ivory house.
6. The Old Gold smoker owns snails.
7. Kools are smoked in the yellow house.
8. Milk is drunk in the middle house.
9. The Norwegian lives in the first house.
10. The man who smokes Chesterfields lives in the house next to the man with the fox.
11. Kools are smoked in the house next to the house where the horse is kept.
12. The Lucky Strike smoker drinks orange juice.
13. The Japanese smokes Parliaments.
14. The Norwegian lives next to the blue house.
Ques 4: Consider a group of ten friends who want to visit a new city somewhere in the world. They
vote on seven potential destinations: Cairo, London, Beijing, Moscow, Mumbai, Nairobi, Jakarta
One city received four votes, two cities received two votes each, two cities received one vote each,
and the remaining two cities received zero votes. How many votes did each of the cities receive?
● Beijing and Cairo got different numbers of votes.
● Moscow either got the most votes, or it got zero votes.
● Cairo got more votes than Jakarta did.
● In the list of cities above, each of the two cities that got two votes has a city that got no votes
immediately above it in the list.
● Either Jakarta got one fewer votes than London did, or it got one fewer vote than Beijing did.
Ques 5: There are 4 students: Carrie, Erma, Ora und Tracy. Each has one scholarship and one major
subject they study. The goal is to find out which student has which scholarship and studies which
subject (with all scholarships and majors being different from each other) from the hints provided.
The available scholarships are: 25000, 30000, 35000 and 40000 USD. The available majors are:
Astronomy, English, Philosophy, Physics. The following hints are given to solve the problem: The
student who studies Astronomy gets a smaller scholarship than Ora. Ora is either the one who studies
English or the one who studies Philosophy. Erna has a 10000 USD bigger scholarship than Carrie.
Tracy has a bigger scholarship than the student that studies English.