0% found this document useful (0 votes)
41 views

Ai Lab

Uploaded by

kkrnkkrn8
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views

Ai Lab

Uploaded by

kkrnkkrn8
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 24

Tribhuvan University

Faculty of Humanities and Social Sciences

Artificial Intelligence

A LAB REPORT

Submitted to
Mr. Roshan Tandukar

Department of Computer Application


Patan Multiple Campus
Patan Dhoka, Lalitpur

Submitted by:
Kritagya niraula
Roll no: 30/076
Table of Contents
Lab 1:Write a program in Python to implement Water jug problem.........................................3

Lab 2:Write a program to implement Breadth First Search......................................................6

Lab 3:Write a program to implement Depth First Search.........................................................9

Lab 4:Write a program to implement A* search.....................................................................12

Lab5: Write a program in python using pyDatalog.................................................................15

Lab 6: Write a program in Python to implement OR gate using Neural network...................21

Lab 7: Write a program in Python to implement AND gate using Neural network................23

2
Lab 1:Write a program in Python to implement Water jug
problem
Introduction
The water jug problem is a classic puzzle in computer science and mathematics. The problem
involves two water jugs of known capacities (let's say jug A and jug B) and a desired target
amount of water. The objective is to measure out the desired amount of water using only
these two jugs.

Here are the rules:


You can fill a jug entirely from a tap or another jug.
You can empty a jug entirely, pouring all its contents down the drain.
You can pour water from one jug into another until either the pouring jug is empty or the
receiving jug is full.
The challenge is to find a sequence of these actions that result in the desired amount of water
being contained in one of the jugs.
The illustration of this program is written below

3
Source Code
print("kritagya niraula")
from collections import deque
def bfs(start, end, jug1_capacity, jug2_capacity, target):
visited = set()
queue = deque([(0, 0)])
parent = {}

while queue:
jug1, jug2 = queue.popleft()
if jug1 == target or jug2 == target:
path = []
while (jug1, jug2) != (0, 0):
path.append((jug1, jug2))
jug1, jug2 = parent[(jug1, jug2)]
path.append((0, 0))
return path[::-1]
next_moves = [
(jug1_capacity, jug2),
(jug1, jug2_capacity),
(0, jug2),
(jug1, 0),
(min(jug1 + jug2, jug1_capacity), max(0, jug1 + jug2 - jug1_capacity)),
(max(0, jug1 + jug2 - jug2_capacity), min(jug1 + jug2, jug2_capacity))
]
for move in next_moves:
if move not in visited:
queue.append(move)
visited.add(move)
parent[move] = (jug1, jug2)

4
return None

def water_jug_problem(jug1_capacity, jug2_capacity, target):


start_state = (0, 0)
end_state = (jug1_capacity, jug2_capacity)
solution = bfs(start_state, end_state, jug1_capacity, jug2_capacity, target)
if solution:
print("Solution found:")
for state in solution:
print("Jug 1:", state[0], "Jug 2:", state[1])
else:
print("Solution not possible.")

jug1_capacity = 4
jug2_capacity = 3
target = 2
water_jug_problem(jug1_capacity, jug2_capacity, target)
Output

5
Lab 2:Write a program to implement Breadth First Search.
Introduction
Breadth-first search (BFS) is an algorithm used for traversing or searching tree or graph data
structures. It starts at a given node (often referred to as the "root" node), explores all of the
neighbor nodes at the present depth before moving on to the nodes at the next depth level.

Here's how BFS works:

Initialization: BFS begins with the given starting node (or state) and initializes a queue to
keep track of the nodes to be visited. Initially, the queue contains only the starting node.

Exploration: BFS iteratively dequeues nodes from the front of the queue and explores all of
their neighboring nodes. It explores the neighboring nodes at the current depth level before
moving on to nodes at the next depth level.

Queuing: As BFS explores each node, it enqueues its unvisited neighboring nodes to the back
of the queue. This ensures that nodes are visited in the order of their distance from the
starting node.

Termination: BFS continues this process until the queue is empty, indicating that all
reachable nodes have been visited. If BFS is searching for a specific target node, it can
terminate as soon as the target node is found.

BFS guarantees that it will find the shortest path (in terms of the number of edges) from the
starting node to any other reachable node in an unweighted graph or tree.

6
Source Code
print("kritagya niraula")
from collections import deque
def bfs(graph, start, goal):
queue = deque([(start, [start])])
while queue:
(node, path) = queue.popleft()
if node == goal:
return path
for neighbor in graph.get(node, []):
if neighbor not in path:
queue.append((neighbor, path + [neighbor]))
return None

if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}

start_node = 'A'
goal_node = 'F'
path = bfs(graph, start_node, goal_node)

if path:
print("Path from", start_node, "to", goal_node, ":", path)
7
else:
print("Path from", start_node, "to", goal_node, "not found.")

Output

8
Lab 3:Write a program to implement Depth First Search.
Introduction
Depth-first search (DFS) is another algorithm used for traversing or searching tree or graph
data structures. DFS explores as far as possible along each branch before backtracking.

Here's how DFS works:


Initialization: DFS begins with the given starting node (or state) and initializes a stack (or
recursively called) to keep track of the nodes to be visited. Initially, the stack contains only
the starting node.
Exploration: DFS iteratively pops nodes from the top of the stack (or calls the function
recursively), exploring one branch as far as possible before backtracking. It continues this
process until all reachable nodes have been visited.
Pushing/Popping: As DFS explores each node, it pushes its unvisited neighboring nodes onto
the stack (or calls the function recursively). This allows DFS to explore deeper and deeper
along a particular branch before backtracking.
Termination: DFS continues this process until the stack is empty (or all nodes have been
visited). If DFS is searching for a specific target node, it can terminate as soon as the target
node is found.
DFS does not guarantee that it will find the shortest path (in terms of the number of edges)
from the starting node to any other reachable node. However, it is often more memory
efficient than BFS since it only needs to keep track of the current path being explored.

9
Source Code
print("kritagya niraula")
def dfs(graph, start, goal, path=None):
if path is None:
path = []
path = path + [start]

if start == goal:
return path

if start not in graph:


return None

for neighbor in graph[start]:


if neighbor not in path:
new_path = dfs(graph, neighbor, goal, path)
if new_path:
return new_path

return None

if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']

10
}

start_node = 'A'
goal_node = 'F'
path = dfs(graph, start_node, goal_node)

if path:
print("Path from", start_node, "to", goal_node, ":", path)
else:
print("Path from", start_node, "to", goal_node, "not found.")
Output

11
Lab 4:Write a program to implement A* search.
Introduction
A* search is an informed search algorithm that is used for pathfinding and graph traversal.
It's a combination of Dijkstra's algorithm and a heuristic function, which guides the search
towards the most promising nodes. A* is widely used in various applications, including route
planning in maps, robotics, and video games.

A* search works with initialization, evaluation, expansion, update, termination and


optimality.
Source Code
print("kritagya niraula")
import heapq

def astar(graph, start, goal, heuristic):


open_list = [(0, start)]
g_costs = {start: 0}
parents = {start: None}

while open_list:
_, current = heapq.heappop(open_list)

12
if current == goal:
path = []
while current is not None:
path.append(current)
current = parents[current]
return path[::-1]

for neighbor, cost in graph[current].items():


new_g_cost = g_costs[current] + cost
if neighbor not in g_costs or new_g_cost < g_costs[neighbor]:
g_costs[neighbor] = new_g_cost
priority = new_g_cost + heuristic[neighbor]
heapq.heappush(open_list, (priority, neighbor))
parents[neighbor] = current

return None

if __name__ == "__main__":
graph = {
'A': {'B': 4, 'C': 2},
'B': {'A': 4, 'D': 5, 'E': 2},
'C': {'A': 2, 'F': 3},
'D': {'B': 5},
'E': {'B': 2, 'F': 1},
'F': {'C': 3, 'E': 1}
}
heuristic = {'A': 3, 'B': 2, 'C': 4, 'D': 5, 'E': 1, 'F': 0}

start_node = 'A'
goal_node = 'F'

13
path = astar(graph, start_node, goal_node, heuristic)
if path:
print("Path from", start_node, "to", goal_node, ":", path)
else:
print("Path from", start_node, "to", goal_node, "not found.")
Output

14
Lab5: Write a program in python using pyDatalog.
Introduction
In the context of artificial intelligence and logical reasoning, "resolution" refers to a
fundamental inference rule used in automated theorem proving and logic programming. The
resolution rule is employed in the resolution refutation method, which aims to prove the
unsatisfiability (or contradiction) of a set of logical clauses.
Resolution is a fundamental inference rule used in automated reasoning systems, such as
SAT solvers, Prolog-based systems, and theorem provers. It forms the basis of many logical
reasoning algorithms and is essential for tasks such as logical deduction, knowledge
representation, and automated reasoning in artificial intelligence.
a. Ram is a man. If a person is man, then he is mortal. Find out who is mortal.
Source Code
from pyDatalog import pyDatalog
pyDatalog.create_terms('man, mortal, X')
+man('Ram')
# Rule:
mortal(X) <= man(X)
mortal_persons = mortal(X)
print("kritagya niraula ")
print("Mortal persons:", mortal_persons)
Output

b. Given the sentences:


Bear is big. Dog is small. Cat is small. Rabit is small.

15
Bear is brown in color. Cat is black colored. Dog is black colored. Rabit is white colored.
Rules: If animal is black colored, it is dark. If animal is brown colored, it is dark. If animal is
white in color, it is light colored.
Find the names of:
i. animal which is dark and big.
ii. animal which is dark and small.
iii. animal which is light colored.
iv. brown colored animal
v. animals which is big in size.
Source Code
print("kritagya niraula")
from pyDatalog import pyDatalog
pyDatalog.create_terms('size, color, dark, X')
# Facts
+size('bear', 'big')
+size('dog', 'small')
+size('cat', 'small')
+size('rabbit', 'small')
+color('bear', 'brown')
+color('cat', 'black')
+color('dog', 'black')
+color('rabbit', 'white')
# Rules
dark(X) <= (color(X, 'black'))
dark(X) <= (color(X, 'brown'))
# Queries
print("i. Animal which is dark and big:", dark(X) & size(X, 'big'))
print("ii. Animal which is dark and small:", dark(X) & size(X, 'small'))
print("iii. Animal which is light colored:", dark(X) & color(X, 'white'))
print("iv. Brown colored animal:", color(X, 'brown'))
print("v. Animals which are big in size:", size(X, 'big'))

16
Output

c. Ram is a boy. Sita is girl. Ram is husband of Sita. If a girl has a husband then she is
married. Prove that Sita is married.

Source Code
print("kritagya niraula")
from pyDatalog import pyDatalog
pyDatalog.create_terms('X, Y, boy, girl, husbandof, married')
# Facts
+boy('ram')
+girl('sita')
+husbandof('ram', 'sita')
married(X) <= (girl(X) & husbandof(Y, X))
print("Your name")
print(married(X))
Output

17
d. Pandu has five sons namely, Yudhisthir, Bhim, Arjun, Nakul and Sahadev. Kunti is
mother of Yudhisthir, Bhim, and Arjun. Madri is mother of Nakul and Sahadev.
Arjun is father and Subhadra is mother of Abhimanyu and Abhimanyu is father of
Parikshit. Write the rules of grandfather, grandson, wife and brother and find the
following:
i. sons of Pandu
ii. son of Arjun
iii. grandson of Pandu
iv. grandfather of Parikshit
v. wife of Pandu
vi. wife of Arjun
vii. brothers of Arjun
viii. mother of Arjun
ix. sons of Kunti and madri
x. grandmother of Parikshit and Abhimanyu.
Source Code
print("kritagya niraula")
from pyDatalog import pyDatalog

pyDatalog.create_terms('X, Y, Z, grandson, grandfather, wife, brother, mother, father')

# Facts
+father('Pandu', 'Yudhisthir')
+father('Pandu', 'Bhim')
+father('Pandu', 'Arjun')
+father('Pandu', 'Nakul')

18
+father('Pandu', 'Sahadev')
+father('Arjun', 'Abhimanyu')
+father('Abhimanyu', 'Parikshit')

+mother('Kunti', 'Yudhisthir')
+mother('Kunti', 'Bhim')
+mother('Kunti', 'Arjun')
+mother('Madri', 'Nakul')
+mother('Madri', 'Sahadev')
+mother('Subhadra', 'Abhimanyu')

# Rules
grandson(X, Y) <= father(Y, Z) & father(Z, X)
grandfather(X, Y) <= father(X, Z) & father(Z, Y)
wife(X, Y) <= mother(X, Z) & father(Y, Z)
wife(X, Y) <= mother(X, Z) & mother(Y, Z)
brother(X, Y) <= father(Z, X) & father(Z, Y) & (X != Y)
brother(X, Y) <= mother(Z, X) & mother(Z, Y) & (X != Y)

# i. Sons of Pandu
print("i. Sons of Pandu:", [Y for Y in father('Pandu', X)])

# ii. Son of Arjun


print("ii. Son of Arjun:", [Y for Y in father('Arjun', X)])

# iii. Grandson of Pandu


print("iii. Grandson of Pandu:", [X for X in grandson(X, 'Pandu')])

# iv. Grandfather of Parikshit


print("iv. Grandfather of Parikshit:", [X for X in grandfather(X, 'Parikshit')])

19
# v. Wife of Pandu
print("v. Wife of Pandu:", [Y for Y in wife(X, 'Pandu')])

# vi. Wife of Arjun


print("vi. Wife of Arjun:", [Y for Y in wife(X, 'Arjun')])

# vii. Brothers of Arjun


print("vii. Brothers of Arjun:", [Y for Y in brother(Y, 'Arjun')])

# viii. Mother of Arjun


print("viii. Mother of Arjun:", [Y for Y in mother(Y, 'Arjun')])

# ix. Sons of Kunti and Madri


sons_kunti = [Y for Y in father('Kunti', X)]
sons_madri = [Y for Y in father('Madri', X)]
sons_combined = sons_kunti + sons_madri
print("ix. Sons of Kunti and Madri:", sons_combined)

grandmothers = [X for X, Y in wife(X, Y) for Y in father('Abhimanyu', 'Parikshit').data +


father('Abhimanyu', 'Parikshit').data]
print("x. Grandmother of Parikshit and Abhimanyu:", grandmothers)
Output

20
Lab 6: Write a program in Python to implement OR gate using
Neural network.
Introduction
Implementing an OR gate using a neural network involves training a model to learn the logic
of the OR gate based on input-output pairs. In this process, the neural network is designed
with an appropriate architecture, typically consisting of an input layer, one or more hidden
layers, and an output layer. The input layer accommodates the input variables (in this case,
binary values representing the OR gate's inputs), while the output layer produces the
predicted output based on the learned patterns.

Source Code
print("kritagya niraula")
import numpy as np
import tensorflow as tf
X_train = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y_train = np.array([[0], [1], [1], [1]])
model = tf.keras.Sequential([
tf.keras.layers.Dense(1, input_shape=(2,), activation='sigmoid')
])

# Compile the model


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

# Train the model


model.fit(X_train, y_train, epochs=1000, verbose=0)

# Test the model


X_test = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
predictions = model.predict(X_test)

21
print("Input Predicted Output")
for i in range(len(X_test)):
print(X_test[i], " ", round(predictions[i][0]))
Output

22
Lab 7: Write a program in Python to implement AND gate using
Neural network.
Introduction
Implementing an AND gate using a neural network involves constructing a model that can
learn the logic of the AND gate from input-output pairs. This process begins by designing the
neural network architecture, typically comprising an input layer, one or more hidden layers,
and an output layer. The input layer accommodates the input variables, representing the
binary values of the AND gate's inputs, while the output layer produces the predicted output
based on the learned patterns.
Source Code
print("kritagya niraula")
import numpy as np
import tensorflow as tf

# Training data
X_train = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y_train = np.array([[0], [0], [0], [1]]) # AND gate truth table

# Neural network model


model = tf.keras.Sequential([
tf.keras.layers.Dense(1, input_shape=(2,), activation='sigmoid')
])

# Compile the model


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

# Train the model


model.fit(X_train, y_train, epochs=1000, verbose=0)

23
# Test the model
X_test = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
predictions = model.predict(X_test)
print("Input Predicted Output")
for i in range(len(X_test)):
print(X_test[i], " ", round(predictions[i][0]))
Output

24

You might also like