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

ai lab final

The document outlines various Python programs for algorithms and games, including BFS, DFS, A*, Tic-Tac-Toe using Minimax, Sudoku Solver, and an 8-Puzzle Solver. Each section provides code snippets and explanations for implementing these algorithms. The intended audience appears to be students in a B. Tech. program, specifically in the CSE department.

Uploaded by

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

ai lab final

The document outlines various Python programs for algorithms and games, including BFS, DFS, A*, Tic-Tac-Toe using Minimax, Sudoku Solver, and an 8-Puzzle Solver. Each section provides code snippets and explanations for implementing these algorithms. The intended audience appears to be students in a B. Tech. program, specifically in the CSE department.

Uploaded by

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

NAME: Sohini Ghosh

PROGRAM: B. Tech.

DEPARTMENT: CSE (IoT, Cybersecurity & Blockchain technology)

SECTION: 7

SEMESTER: 5th

YEAR: 3rd

SESSION: 2022-26

ENROLLMENT NO.: 2212200011045

REGISTRATION NO.: 220110456535

SUBJECT: AI Lab
Programs to be executed in Python

1. Breadth-First Search (BFS) Algorithm


Write a Python program to find the shortest path in an unweighted graph using BFS.

from collections import deque


def bfs(graph, start):
visited = set()
queue = deque([start])

while queue:
vertex = queue.popleft()
if vertex not in visited:
print(vertex)
visited.add(vertex)
for neighbor in graph[vertex]:
if neighbor not in visited:
queue.append(neighbor)
if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("BFS traversal starting from node A:")
bfs(graph, 'A')

OUTPUT:

2. Depth-First Search (DFS) Algorithm


Implement DFS in Python to explore a graph and find paths or cycles.

def dfs(graph, start, visited=None):


if visited is None:
visited = set()
visited.add(start)
print(start)
for neighbor in graph[start]:
if neighbor not in visited:
dfs(graph, neighbor, visited)
if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("DFS traversal starting from node A:")
dfs(graph, 'A')

OUTPUT:

3. A Search Algorithm*
Develop a Python program to solve the shortest path problem using the A* algorithm with
heuristics.

from heapq import heappop, heappush


def a_star(graph, start, goal, h):
# Priority queue to store nodes to explore, ordered by f-score (lowest first)
open_list = []
heappush(open_list, (0, start)) # Add start node with f-score of 0

# Dictionary to track the path taken to reach each node


came_from = {}

# g_score dictionary to store the cost of the shortest path from start to each node
g_score = {node: float('inf') for node in graph}
g_score[start] = 0 # Cost to reach start node is 0

# f_score dictionary to store the estimated cost from start to goal through each node
f_score = {node: float('inf') for node in graph}
f_score[start] = h[start] # Start node's f-score is its heuristic estimate

# Main loop to explore the nodes in the open_list


while open_list:
# Pop the node with the lowest f-score
_, current = heappop(open_list)

# Check if the current node is the goal


if current == goal:
return reconstruct_path(came_from, current) # Path is found

# Iterate through each neighbor of the current node


for neighbor, cost in graph[current].items():
# Calculate the tentative g-score (cost) to reach this neighbor
tentative_g_score = g_score[current] + cost

# If the tentative path is better than any previously recorded path


if tentative_g_score < g_score[neighbor]:
# Update the path to reach neighbor (came_from) and its scores
came_from[neighbor] = current
g_score[neighbor] = tentative_g_score
f_score[neighbor] = g_score[neighbor] + h[neighbor] # Update f-score

# Add neighbor to the open list to explore, with its updated f-score
heappush(open_list, (f_score[neighbor], neighbor))

return None
# Helper function to reconstruct the path from start to goal
def reconstruct_path(came_from, current):
path = [current] # Start with the goal node
# Traverse back from the goal to the start using came_from
while current in came_from:
current = came_from[current]
path.append(current)
path.reverse() # Reverse the path to get it from start to goal
return path
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1, 'E': 3},
'E': {'D': 3}
}

# Define heuristic function (h) as a dictionary


# These values represent the estimated cost from each node to the goal (E)
h={
'A': 7,
'B': 6,
'C': 2,
'D': 1,
'E': 0 # Goal node has a heuristic of 0
}

# Run the A* algorithm from start node 'A' to goal node 'E'
start_node = 'A'
goal_node = 'E'
path = a_star(graph, start_node, goal_node, h)

# Output the result


if path:
print("Shortest path from {} to {}: {}".format(start_node, goal_node, path))
else:
print("No path found from {} to {}".format(start_node, goal_node))

OUTPUT:

4. Tic-Tac-Toe Game (AI vs Player using Minimax)


Build a Tic-Tac-Toe game where the AI uses the Minimax algorithm to play against a human
player.
import math

# Function to print the Tic-Tac-Toe board


def print_board(board):
for i, row in enumerate(board):
print(" " + " | ".join(row))
if i < 2:
print("---+---+---")
print("\n")

# Function to check for a win


def check_winner(board, player):
# Check rows, columns, and diagonals
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 board[0][0] == board[1][1] == board[2][2] == player:
return True
if board[0][2] == board[1][1] == board[2][0] == player:
return True
return False

# Function to check if the board is full (draw condition)


def is_draw(board):
for row in board:
if " " in row:
return False
return True

# Minimax algorithm to calculate the optimal move for AI


def minimax(board, depth, is_maximizing):
if check_winner(board, "O"): # AI wins
return 1
elif check_winner(board, "X"): # Human wins
return -1
elif is_draw(board): # Draw
return 0

if is_maximizing:
best_score = -math.inf
for i in range(3):
for j in range(3):
if board[i][j] == " ":
board[i][j] = "O" # AI move
score = minimax(board, depth + 1, False)
board[i][j] = " " # Undo move
best_score = max(score, best_score)
return best_score
else:
best_score = math.inf
for i in range(3):
for j in range(3):
if board[i][j] == " ":
board[i][j] = "X" # Human move
score = minimax(board, depth + 1, True)
board[i][j] = " " # Undo move
best_score = min(score, best_score)
return best_score
# Function to get the best move for AI
def best_move(board):
best_score = -math.inf
move = None
for i in range(3):
for j in range(3):
if board[i][j] == " ":
board[i][j] = "O" # AI move
score = minimax(board, 0, False)
board[i][j] = " " # Undo move
if score > best_score:
best_score = score
move = (i, j)
return move

# Function for the human player to make a move


def player_move(board):
while True:
try:
move = int(input("Enter your move (1-9): ")) - 1
row, col = divmod(move, 3)
if board[row][col] == " ":
board[row][col] = "X"
break
else:
print("That spot is already taken. Try again.")
except (ValueError, IndexError):
print("Invalid move. Enter a number between 1 and 9.")

# Main function to play the game


def play_game():
board = [[" " for _ in range(3)] for _ in range(3)]
print("Welcome to Tic-Tac-Toe! You are 'X' and the AI is 'O'.")
print_board(board)

while True:
# Human player's turn
player_move(board)
print_board(board)

if check_winner(board, "X"):
print("Congratulations! You win!")
break
elif is_draw(board):
print("It's a draw!")
break

# AI's turn
ai_move = best_move(board)
if ai_move:
row, col = ai_move
board[row][col] = "O"
print("AI's move:")
print_board(board)

if check_winner(board, "O"):
print("AI wins! Better luck next time.")
break
elif is_draw(board):
print("It's a draw!")
break

if __name__ == "__main__":
play_game()
OUTPUT:

5. Sudoku Solver Using Backtracking


Write a Python program that solves a Sudoku puzzle using a backtracking algorithm.

N = 4 # Size of the board for a 4x4 Sudoku

def print_board(board):
for row in board:
print(" ".join(str(cell) for cell in row))
print("\n")

def find_empty_location(board):
for row in range(N):
for col in range(N):
if board[row][col] == 0:
return (row, col)
return None

def is_valid(board, row, col, num):


# Check row and column
if any(board[row][i] == num for i in range(N)) or any(board[i][col] == num for i in range(N)):
return False
# Check 2x2 sub-grid
start_row, start_col = 2 * (row // 2), 2 * (col // 2)
return all(board[start_row + i][start_col + j] != num for i in range(2) for j in range(2))

def solve_sudoku(board):
empty_location = find_empty_location(board)
if not empty_location:
return True
row, col = empty_location

for num in range(1, N + 1):


if is_valid(board, row, col, num):
board[row][col] = num# Define the size of the Sudoku grid
N=9

# Function to print the Sudoku board


def print_board(board):
for row in board:
print(" ".join(str(cell) for cell in row))
print("\n")

# Function to find an empty cell (denoted by 0)


def find_empty_location(board):
for row in range(N):
for col in range(N):
if board[row][col] == 0:
return (row, col)
return None

# Function to check if placing a number is valid in the row, column, and 3x3 sub-grid
def is_valid(board, row, col, num):
# Check if the number is not in the row
for i in range(N):
if board[row][i] == num:
return False

# Check if the number is not in the column


for i in range(N):
if board[i][col] == num:
return False

# Check if the number is not in the 3x3 sub-grid


start_row, start_col = 3 * (row // 3), 3 * (col // 3)
for i in range(3):
for j in range(3):
if board[start_row + i][start_col + j] == num:
return False

return True

# Function to solve the Sudoku using backtracking


def solve_sudoku(board):
# Find an empty location
empty_location = find_empty_location(board)
if not empty_location:
return True # Puzzle solved
row, col = empty_location

# Try placing numbers 1 to 9 in the cell


for num in range(1, N + 1):
if is_valid(board, row, col, num):
board[row][col] = num # Place the number

# Recursively attempt to solve the rest of the board


if solve_sudoku(board):
return True

# If not solvable, backtrack


board[row][col] = 0

return False

# Example Sudoku puzzle (0 represents an empty cell)


board = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]

if solve_sudoku(board):
print("Solved Sudoku:")
print_board(board)
else:
print("No solution exists.")

OUTPUT:
6. 8-Puzzle Solver Using A Algorithm*
Solve the 8-puzzle problem using A* algorithm with a heuristic function like Manhattan
distance.

import heapq

class Node:
def __init__(self, state, parent=None, move=None, depth=0):
self.state = state # Current state of the puzzle
self.parent = parent # Parent node
self.move = move # Move that led to this state
self.depth = depth # Depth of the node in the search tree
self.blank_pos = self.find_blank() # Position of the blank tile
self.heuristic = self.manhattan_distance() # Heuristic value

def find_blank(self):
"""Find the position of the blank tile (0)"""
for i, row in enumerate(self.state):
if 0 in row:
return i, row.index(0)

def manhattan_distance(self):
"""Calculate the Manhattan distance heuristic"""
distance = 0
goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]]
for r in range(3):
for c in range(3):
if self.state[r][c] != 0:
goal_r, goal_c = divmod(self.state[r][c] - 1, 3)
distance += abs(goal_r - r) + abs(goal_c - c)
return distance

def f_score(self):
"""Calculate f(n) = g(n) + h(n)"""
return self.depth + self.heuristic

def get_possible_moves(self):
"""Generate possible moves for the blank tile"""
moves = []
x, y = self.blank_pos
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Up, Down, Left, Right

for dx, dy in directions:


new_x, new_y = x + dx, y + dy
if 0 <= new_x < 3 and 0 <= new_y < 3:
new_state = [list(row) for row in self.state] # Make a copy
new_state[x][y], new_state[new_x][new_y] = new_state[new_x][new_y], new_state[x][y]
moves.append(Node(new_state, self, (new_x, new_y), self.depth + 1))

return moves

def __lt__(self, other):


"""Define less than for priority queue"""
return self.f_score() < other.f_score()

def a_star(start):
"""Solve the 8-puzzle problem using the A* algorithm"""
open_set = []
heapq.heappush(open_set, start)
closed_set = set()

while open_set:
current = heapq.heappop(open_set)

# Check if we reached the goal state


if current.state == [[1, 2, 3], [4, 5, 6], [7, 8, 0]]:
return current # Return the goal node

closed_set.add(tuple(map(tuple, current.state)))

for neighbor in current.get_possible_moves():


if tuple(map(tuple, neighbor.state)) in closed_set:
continue # Ignore already evaluated states

if not any(neighbor.state == node.state for node in open_set):


heapq.heappush(open_set, neighbor)

return None # No solution found

def print_solution(node):
"""Print the solution path from the initial state to the goal"""
path = []
while node:
path.append(node.state)
node = node.parent
for step in path[::-1]: # Reverse the path to get from start to goal
for row in step:
print(row)
print() # Empty line between steps
# Example Usage
if __name__ == "__main__":
# Initial state of the puzzle
initial_state = [
[1, 2, 3],
[4, 0, 6],
[7, 5, 8]
]
start_node = Node(initial_state)
solution_node = a_star(start_node)
if solution_node:
print("Solution found:")
print_solution(solution_node)
else:
print("No solution exists.")
OUTPUT:
7. Hill Climbing Algorithm
Implement the Hill Climbing algorithm to solve an optimization problem, such as
maximizing a function.

import random

def function(x):
"""Objective function to maximize: f(x) = -x^2 + 4x"""
return -x**2 + 4*x

def hill_climbing(start, step_size, max_iterations):


"""Hill Climbing algorithm to find the maximum of the objective function."""
current_solution = start
current_value = function(current_solution)

for _ in range(max_iterations):
# Generate new candidate solutions
neighbors = [current_solution + step_size, current_solution - step_size]
# Evaluate the function at the new candidate solutions
neighbor_values = [function(neighbor) for neighbor in neighbors]

# Find the best neighbor


best_neighbor_index = neighbor_values.index(max(neighbor_values))
best_neighbor_value = neighbor_values[best_neighbor_index]
best_neighbor_solution = neighbors[best_neighbor_index]

# If the best neighbor is better than the current solution, move there
if best_neighbor_value > current_value:
current_solution = best_neighbor_solution
current_value = best_neighbor_value
else:
break # Exit if no improvement

return current_solution, current_value

# Example Usage
if __name__ == "__main__":
# Starting point
start = random.uniform(0, 4) # Random starting point between 0 and 4
step_size = 0.1 # Step size for exploring neighbors
max_iterations = 100 # Max iterations

best_solution, best_value = hill_climbing(start, step_size, max_iterations)

print(f"Best solution: x = {best_solution:.2f}, f(x) = {best_value:.2f}")

OUTPUT:

8. Genetic Algorithm for Optimization


Write a Python program to solve an optimization problem using Genetic Algorithms.
import random
import numpy as np

# Objective function to maximize


def objective_function(x):
return x * np.sin(10 * np.pi * x) + 1

# Create initial population


def create_population(size, lower_bound, upper_bound):
return [random.uniform(lower_bound, upper_bound) for _ in range(size)]

# Selection of parents using tournament selection


def select_parents(population):
tournament_size = 3
parents = []
for _ in range(2): # Select 2 parents
tournament = random.sample(population, tournament_size)
parents.append(max(tournament, key=objective_function))
return parents

# Crossover operation
def crossover(parents):
crossover_point = random.random()
child1 = parents[0] * crossover_point + parents[1] * (1 - crossover_point)
child2 = parents[1] * crossover_point + parents[0] * (1 - crossover_point)
return child1, child2

# Mutation operation
def mutate(child, mutation_rate, lower_bound, upper_bound):
if random.random() < mutation_rate:
return random.uniform(lower_bound, upper_bound)
return child

# Genetic Algorithm function


def genetic_algorithm(population_size, generations, mutation_rate, lower_bound, upper_bound):
population = create_population(population_size, lower_bound, upper_bound)

for generation in range(generations):


new_population = []

# Create a new population


while len(new_population) < population_size:
parents = select_parents(population)
children = crossover(parents)
new_population.extend([mutate(child, mutation_rate, lower_bound, upper_bound) for child in
children])

population = new_population

# Find the best solution in the final population


best_solution = max(population, key=objective_function)
return best_solution, objective_function(best_solution)

# Example Usage
if __name__ == "__main__":
population_size = 100
generations = 50
mutation_rate = 0.1
lower_bound = 0
upper_bound = 1

best_solution, best_value = genetic_algorithm(population_size, generations, mutation_rate,


lower_bound, upper_bound)
print(f"Best solution: x = {best_solution:.4f}, f(x) = {best_value:.4f}")

OUTPUT:

9. N-Queens Problem
Solve the N-Queens problem using a backtracking algorithm in Python.
def is_safe(board, row, col, N):
"""Check if placing a queen at board[row][col] is safe."""
# Check this row on the left side
for i in range(col):
if board[row][i] == 1:
return False

# Check upper diagonal on the left side


for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False

# Check lower diagonal on the left side


for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False

return True

def solve_n_queens_util(board, col, N):


"""Utilize backtracking to place queens."""
# Base case: If all queens are placed, return True
if col >= N:
return True

for i in range(N):
if is_safe(board, i, col, N):
# Place queen
board[i][col] = 1

# Recur to place rest of the queens


if solve_n_queens_util(board, col + 1, N):
return True

# Backtrack: Remove queen


board[i][col] = 0

return False

def solve_n_queens(N):
"""Main function to solve the N-Queens problem."""
board = [[0] * N for _ in range(N)] # Create N x N board

if not solve_n_queens_util(board, 0, N):


print("Solution does not exist")
return False

print("Solution:")
for row in board:
print(" ".join('Q' if col == 1 else '.' for col in row))
return True

# Example Usage
if __name__ == "__main__":
N = 8 # You can change N to any integer value
solve_n_queens(N)
OUTPUT:

10. Bayesian Inference for Probabilistic Reasoning


Implement Bayesian inference in Python to predict the probability of a condition, like
disease diagnosis.

Defbayesian_inference(prior_disease,likelihood_symptom_given_disease,
likelihood_symptom_given_no_disease):
# P(No Disease) = 1 - P(Disease)
prior_no_disease = 1 - prior_disease

# Calculate P(Symptom)
p_symptom = (likelihood_symptom_given_disease * prior_disease) + \
(likelihood_symptom_given_no_disease * prior_no_disease)

# Calculate P(Disease | Symptom) using Bayes' theorem


posterior_disease = (likelihood_symptom_given_disease * prior_disease) / p_symptom

return posterior_disease

# Example Usage
if __name__ == "__main__":
# Define the probabilities
prior_disease = 0.01 # P(Disease): Prior probability of having the disease (1%)
likelihood_symptom_given_disease = 0.9 # P(Symptom | Disease): Probability of having the
symptom if you have the disease (90%)
likelihood_symptom_given_no_disease = 0.2 # P(Symptom | No Disease): Probability of having the
symptom if you don't have the disease (20%)

# Perform Bayesian inference


posterior_probability = bayesian_inference(prior_disease, likelihood_symptom_given_disease,
likelihood_symptom_given_no_disease)
print(f"The probability of having the disease given the symptom is: {posterior_probability:.4f}")

OUTPUT:
11. Simple Chatbot Using Rule-Based Logic
Create a rule-based chatbot using Python that can respond to simple queries.
# Simple Rule-Based Chatbot

def chatbot_response(user_input):
user_input = user_input.lower()

# Define rule-based responses


if "hello" in user_input or "hi" in user_input:
return "Hello! How can I help you today?"
elif "how are you" in user_input:
return "I'm just a bot, but thanks for asking! How can I assist you?"
elif "name" in user_input:
return "I'm a simple chatbot created to help answer your questions."
elif "weather" in user_input:
return "I'm unable to provide weather updates. Try using a weather app!"
elif "bye" in user_input:
return "Goodbye! Have a great day!"
elif "help" in user_input:
return "Sure! You can ask me about general topics or type 'bye' to exit."
else:
return "I'm sorry, I don't understand that. Can you ask something else?"

# Main interaction loop


print("Welcome to the Simple Chatbot! Type 'bye' to exit.")
while True:
user_input = input("You: ")
if user_input.lower() == "bye":
print("Chatbot: Goodbye! Have a great day!")
break
response = chatbot_response(user_input)
print("Chatbot:", response)
OUTPUT:

12. Decision Tree Classifier (Using Scikit-learn)

# Import necessary libraries


from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

# Load the Iris dataset


iris = load_iris()
X = iris.data # Features
y = iris.target # Labels
# Split the dataset into training and testing sets (80% train, 20% test)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Initialize the Decision Tree Classifier


clf = DecisionTreeClassifier(random_state=42)

# Train the classifier


clf.fit(X_train, y_train)

# Make predictions on the test set


y_pred = clf.predict(X_test)

# Evaluate the model's performance


accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
print("Classification Report:\n", classification_report(y_test, y_pred))

# Visualize the Decision Tree


plt.figure(figsize=(12, 8))
plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names, filled=True)
plt.show()

OUTPUT:
Programs to be executed in Prolog

1 ) Write a Prolog program to represent a family tree and allow queries about relationships
(e.g., parent, sibling, cousin)
% Facts - Define family relationships
parent(john, mary).
parent(john, mike).
parent(susan, mary).
parent(susan, mike).
parent(mary, alice).
parent(mary, bob).
parent(mike, charlie).
parent(mike, david).
% Rules
% Sibling relationship: X and Y are siblings if they share a par
sibling(X, Y) :-
parent(P, X),
parent(P, Y),
X \= Y.
% Cousin relationship: X and Y are cousins if their parents are
cousin(X, Y) :-
parent(P1, X),
parent(P2, Y),
sibling(P1, P2).
% Grandparent relationship: X is a grandparent of Y if X is a pa
grandparent(X, Y) :-
parent(X, Z),
parent(Z, Y).
% Uncle/Aunt relationship: X is an uncle/aunt of Y if X is a sib
uncle_or_aunt(X, Y) :-
parent(P, Y),
sibling(X, P).
?- parent(mary, alice).
% Output: true

2 ) Develop a simple expert system in Prolog that diagnoses a disease based on symptoms
provided by the user.
% Facts: Define symptoms for each disease
symptom(flu, fever).
symptom(flu, cough).
symptom(flu, sore_throat).
symptom(flu, headache).
symptom(cold, cough).
symptom(cold, sneezing).
symptom(cold, sore_throat).
symptom(covid, fever).
symptom(covid, cough).
symptom(covid, loss_of_taste).
symptom(covid, shortness_of_breath).
symptom(malaria, fever).
symptom(malaria, chills).
symptom(malaria, sweating).
symptom(malaria, headache).
% Rule: Diagnose a disease if all symptoms for that disease are
diagnose(Disease) :-
symptom(Disease, Symptom1),
symptom(Disease, Symptom2),
symptom(Disease, Symptom3),
symptom(Disease, Symptom4),
ask(Symptom1),
ask(Symptom2),
ask(Symptom3),
ask(Symptom4).
% Helper rule to ask about a specific symptom
ask(Symptom) :-
format("Do you have ~w? (yes/no): ", [Symptom]),
read(Response),
Response == yes.
% Rule to start diagnosis
start :-
( diagnose(Disease) ->
format("You might have ~w.", [Disease])
;
write("No diagnosis could be made based on provided symp
).
?- start.
Do you have fever? (yes/no): yes
Do you have cough? (yes/no): yes
Do you have sore_throat? (yes/no): yes
Do you have headache? (yes/no): yes
% Output: You might have flu.

3 ) Implement the monkey and banana problem where the monkey needs to figure out how to
get the banana using Prolog's logical reasoning.
% Initial state:
% The monkey is at location 'a' on the floor.
% The banana is at location 'b' hanging from the ceiling.
% The box is at location 'c' on the floor.
% The monkey does not have the banana initially.
% state(MonkeyLocation, MonkeyOnBox, BoxLocation, HasBanana)
initial_state(state(a, false, c, false)).
goal_state(state(_, _, _, true)).
% Actions:
% 1. Monkey can walk to a new location.
move(state(Monkey, on_floor, Box, HasBanana),
walk(Monkey, NewLocation),
state(NewLocation, on_floor, Box, HasBanana)).
% 2. Monkey can push the box to a new location if it's at the sa
move(state(Location, on_floor, Location, HasBanana),
push_box(Location, NewLocation),
state(NewLocation, on_floor, NewLocation, HasBanana)).
% 3. Monkey can climb onto the box if it's at the same location
move(state(Location, on_floor, Location, HasBanana),
climb_box,
state(Location, on_box, Location, HasBanana)).
% 4. Monkey can grab the banana if it's on the box and directly
move(state(b, on_box, b, false),
grab_banana,
state(b, on_box, b, true)).
% Plan generation: finding the sequence of moves to reach the go
solve(State, [], _) :-
goal_state(State).
solve(State, [Action | RestActions], Visited) :-
move(State, Action, NewState),
\+ member(NewState, Visited), % Ensure we don't revisit sta
solve(NewState, RestActions, [NewState | Visited]).
% Start solving from the initial state.
plan(Solution) :-
initial_state(InitialState),
solve(InitialState, Solution, [InitialState]).
?- plan(Solution).
Solution = [walk(a, c), push_box(c, b), climb_box, grab_banana]

4 )Create a Prolog program that solves the 8-puzzle problem using a search strategy like
depth-first or breadth-first search.
% Goal state for the 8-puzzle.
goal_state([1, 2, 3, 4, 5, 6, 7, 8, 0]).
% Define valid moves: up, down, left, right
move([B, A, C, D, E, F, G, H, I], [A, B, C, D, E, F, G, H, I])
move([A, B, C, D, E, F, G, H, I], [D, B, C, A, E, F, G, H, I])
move([A, B, C, D, E, F, G, H, I], [A, B, C, G, E, F, D, H, I])
move([A, B, C, D, E, F, G, H, I], [A, C, B, D, E, F, G, H, I])
% Breadth-first search algorithm to solve the puzzle.
solve_bfs(Start, Solution) :-
bfs([[Start]], Solution).
% BFS helper function: Finds path from start to goal.
bfs([[State | Path] | _], [State | Path]) :-
goal_state(State).
bfs([[State | Path] | RestPaths], Solution) :-
findall([NextState, State | Path],
(move(State, NextState),
\+ member(NextState, [State | Path])), % Avoid rev
NewPaths),
append(RestPaths, NewPaths, PathsToExplore),
bfs(PathsToExplore, Solution).
% Predicate to start solving with a specified initial state.
solve_8_puzzle(Start, Solution) :-
solve_bfs(Start, Solution).
?- solve_8_puzzle([1, 2, 3, 4, 0, 5, 6, 7, 8], Solution).
#Output
[1, 2, 3, 4, 5, 6, 7, 8, 0]

5 )Write a Prolog program to solve the Towers of Hanoi puzzle with recursive logic.
% hanoi(N, Source, Target, Auxiliary) - Solve the Towers of Hano
% where N is the number of disks to move from Source to Target u
hanoi(1, Source, Target, _) :-
format("Move disk from ~w to ~w~n", [Source, Target]).
hanoi(N, Source, Target, Auxiliary) :-
N > 1,
M is N - 1,
hanoi(M, Source, Auxiliary, Target), % Move top N-1 disks f
hanoi(1, Source, Target, _), % Move the largest disk
hanoi(M, Auxiliary, Target, Source). % Move the N-1 disks f

6 ) Implement the Traveling Salesman Problem in Prolog using a brute-force search to find the
shortest path.
% Define distances between cities
distance(a, b, 10).
distance(a, c, 15).
distance(a, d, 20).
distance(b, c, 35).
distance(b, d, 25).
distance(c, d, 30).
% Symmetric distances (undirected graph)
distance(X, Y, D) :- distance(Y, X, D).
% path_cost(Path, Cost) - Calculates the total cost for a given
path_cost([_], 0). % Base case: single city, no cost.
path_cost([City1, City2 | Rest], Cost) :-
distance(City1, City2, D),
path_cost([City2 | Rest], RestCost),
Cost is D + RestCost.
% tsp(Start, Cities, ShortestPath, MinCost) - Solves the TSP sta
tsp(Start, Cities, ShortestPath, MinCost) :-
permutation(Cities, PathWithoutStart),
Path = [Start | PathWithoutStart],
append(Path, [Start], CompletePath), % Form a complete cycl
path_cost(CompletePath, Cost),
find_min_path([CompletePath-Cost], ShortestPath, MinCost).
% find_min_path(Paths, ShortestPath, MinCost) - Finds the path w
find_min_path([], [], inf).
find_min_path([Path-Cost | Rest], ShortestPath, MinCost) :-
find_min_path(Rest, TempPath, TempMinCost),
(Cost < TempMinCost ->
(ShortestPath = Path, MinCost = Cost)
;
(ShortestPath = TempPath, MinCost = TempMinCost)
).
% Example query to find the shortest path and minimum cost
?- tsp(a, [b, c, d], ShortestPath, MinCost).
% Output:
ShortestPath = [a, b, d, c, a]
MinCost = 80

7 )Solve the missionaries and cannibals problem in Prolog by ensuring that Missionaries are
never outnumbered by cannibals.
% valid state where missionaries are never outnumbered by
%cannibals on either side of the river.
valid_state(M, C, _, M2, C2) :-
M >= 0, C >= 0, M2 >= 0, C2 >= 0,
(M >= C ; M = 0),
(M2 >= C2 ; M2 = 0).
% Define possible moves: move 1 or 2 people
%(either missionaries or cannibals) across the river.
move(state(M, C, left), state(M2, C2, right), Move) :-
move_left(M, C, M2, C2, Move).
move(state(M, C, right), state(M2, C2, left), Move) :-
move_right(M, C, M2, C2, Move).
% Possible moves from left to right
move_left(M, C, M2, C, "One Missionary") :- M > 0, M2 is M - 1.
move_left(M, C, M2, C, "Two Missionaries") :- M > 1, M2 is M - 2
move_left(M, C, M, C2, "One Cannibal") :- C > 0, C2 is C - 1.
move_left(M, C, M, C2, "Two Cannibals") :- C > 1, C2 is C - 2.
move_left(M, C, M2, C2, "One Missionary and One Cannibal") :- M

% Possible moves from right to left


move_right(M, C, M2, C, "One Missionary") :- M2 is M + 1, M < 3
move_right(M, C, M2, C, "Two Missionaries") :- M2 is M + 2, M <
move_right(M, C, M, C2, "One Cannibal") :- C2 is C + 1, C < 3.
move_right(M, C, M, C2, "Two Cannibals") :- C2 is C + 2, C < 2.
move_right(M, C, M2, C2, "One Missionary and One Cannibal") :- M

% Solve the problem by searching for a path from the start state
solve :-
path(state(3, 3, left), state(0, 0, right), [state(3, 3, lef
write_moves(Moves).
% Define the path recursively to check if the goal state is reac
path(State, State, _, []).
path(State, Goal, Visited, [Move|Moves]) :-
move(State, NextState, Move),
valid_state(NextState),
\+ member(NextState, Visited),
path(NextState, Goal, [NextState|Visited], Moves).
% Display the moves in a readable format.
write_moves([]).
write_moves([Move|Moves]) :-
write(Move), nl,
write_moves(Moves).
?- solve.

8 ) Create a Prolog program to place N queens on an N×N chessboard such that no two queens
threaten each other.
% N-Queens Problem
% Define a predicate to place N queens on an N×N chessboard.
place_queens(N, Solution) :-
length(Solution, N),
place_queens(N, Solution, 1).
place_queens(_, [], _).
place_queens(N, [Q|Queens], Row) :-
between(1, N, Q), % Place queen in row Q
safe(Q, Queens, Row, 1), % Ensure no two queens threaten ea
NextRow is Row + 1,
place_queens(N, Queens, NextRow).
% Ensure queens are not in the same column or diagonal
safe(_, [], _, _).
safe(Q, [Q1|Queens], Row, Col) :-
Q =\= Q1, % Different columns
abs(Q - Q1) =\= Row - Col, % Different diagonals
NextCol is Col + 1,
safe(Q, Queens, Row, NextCol).
% Example query for N=4
?- place_queens(4, Solution).
% Expected Output:
Solution = [2, 4, 1, 3] ;
Solution = [3, 1, 4, 2].

9 )Write a Prolog program to solve the water jug problem where two jugs with different
capacities must measure a specific amount of water.
% Water Jug Problem
% Define a predicate to solve the water jug problem.
water_jug(X, Y, Goal) :-
solve(0, 0, X, Y, Goal).
solve(A, B, _, Y, Goal) :-
A = Goal ; B = Goal, !.
solve(A, B, X, Y, Goal) :-
A < X, % Fill jug X
NewA is X,
solve(NewA, B, X, Y, Goal).
solve(A, B, X, Y, Goal) :-
B < Y, % Fill jug Y
NewB is Y,
solve(A, NewB, X, Y, Goal).
solve(A, B, X, Y, Goal) :-
A > 0, % Empty jug X
solve(0, B, X, Y, Goal).
solve(A, B, X, Y, Goal) :-
B > 0, % Empty jug Y
solve(A, 0, X, Y, Goal).
solve(A, B, X, Y, Goal) :-
A > 0, B < Y, % Pour water from jug X to jug Y
NewA is max(A - (Y - B), 0),
NewB is min(Y, A + B),
solve(NewA, NewB, X, Y, Goal).
solve(A, B, X, Y, Goal) :-
B > 0, A < X, % Pour water from jug Y to jug X
NewB is max(B - (X - A), 0),
NewA is min(X, A + B),
solve(NewA, NewB, X, Y, Goal).
% Example query to measure 2 liters with jugs of 3 and 5 liters
?- water_jug(3, 5, 2).
% Expected Output:
true.
10 ) Develop a simple Prolog-based chatbot that can respond to user queries withpredefined
rule-based responses.
% Simple Rule-Based Chatbot
% Define responses for the chatbot
chatbot(hello, 'Hello! How can I help you today?').
chatbot('how are you?', 'I am just a program, but thanks for ask
chatbot('what is your name?', 'I am a simple Prolog chatbot.').
chatbot('bye', 'Goodbye! Have a nice day!').
% Respond to user input
respond(Input, Response) :-
chatbot(Input, Response), !.
respond(_, 'I am not sure how to respond to that.').
% Example interaction
?- respond(hello, Response).
% Expected Output:
Response = 'Hello! How can I help you today?'.

11 ) Create a Prolog program that can solve puzzles like Sudoku, magic squares, or other
arithmetic puzzles using constraint logic programming (CLP).
% Sudoku Solver using Constraint Logic Programming (CLP)
:- use_module(library(clpfd)).
sudoku(Puzzle) :-
Puzzle = [A1,A2,A3,A4,A5,A6,A7,A8,A9,
B1,B2,B3,B4,B5,B6,B7,B8,B9,
C1,C2,C3,C4,C5,C6,C7,C8,C9,
D1,D2,D3,D4,D5,D6,D7,D8,D9,
E1,E2,E3,E4,E5,E6,E7,E8,E9,
F1,F2,F3,F4,F5,F6,F7,F8,F9,
G1,G2,G3,G4,G5,G6,G7,G8,G9,
H1,H2,H3,H4,H5,H6,H7,H8,H9,
I1,I2,I3,I4,I5,I6,I7,I8,I9],
% Define the domain for the variables
Puzzle ins 1..9,
% Row constraints
Rows = [[A1,A2,A3,A4,A5,A6,A7,A8,A9],
[B1,B2,B3,B4,B5,B6,B7,B8,B9],
[C1,C2,C3,C4,C5,C6,C7,C8,C9],
[D1,D2,D3,D4,D5,D6,D7,D8,D9],
[E1,E2,E3,E4,E5,E6,E7,E8,E9],
[F1,F2,F3,F4,F5,F6,F7,F8,F9],
[G1,G2,G3,G4,G5,G6,G7,G8,G9],
[H1,H2,H3,H4,H5,H6,H7,H8,H9],
[I1,I2,I3,I4,I5,I6,I7,I8,I9]],
maplist(all_distinct, Rows),
% Column constraints
Columns = [[A1,B1,C1,D1,E1,F1,G1,H1,I1],
[A2,B2,C2,D2,E2,F2,G2,H2,I2],
[A3,B3,C3,D3,E3,F3,G3,H3,I3],
[A4,B4,C4,D4,E4,F4,G4,H4,I4],
[A5,B5,C5,D5,E5,F5,G5,H5,I5],
[A6,B6,C6,D6,E6,F6,G6,H6,I6],
[A7,B7,C7,D7,E7,F7,G7,H7,I7],
[A8,B8,C8,D8,E8,F8,G8,H8,I8],
[A9,B9,C9,D9,E9,F9,G9,H9,I9]],
maplist(all_distinct, Columns),
% 3x3 subgrid constraints
Squares = [[A1,A2,A3,B1,B2,B3,C1,C2,C3],
[A4,A5,A6,B4,B5,B6,C4,C5,C6],
[A7,A8,A9,B7,B8,B9,C7,C8,C9],
[D1,D2,D3,E1,E2,E3,F1,F2,F3],
[D4,D5,D6,E4,E5,E6,F4,F5,F6],
[D7,D8,D9,E7,E8,E9,F7,F8,F9],
[G1,G2,G3,H1,H2,H3,I1,I2,I3],
[G4,G5,G6,H4,H5,H6,I4,I5,I6],
[G7,G8,G9,H7,H8,H9,I7,I8,I9]],
maplist(all_distinct, Squares),
% Labeling the variables
label(Puzzle).
% Example Sudoku puzzle query:
?- sudoku([5,3,_,_,7,_,_,_,_,
6,_,_,1,9,5,_,_,_,
_,9,8,_,_,_,_,6,_,
Prolog Codes 14
8,_,_,_,6,_,_,_,3,
4,_,_,8,_,3,_,_,1,
7,_,_,_,2,_,_,_,6,
_,6,_,_,_,_,2,8,_,
_,_,_,4,1,9,_,_,5,
_,_,_,_,8,_,_,7,9]).
% Expected Output:
The completed Sudoku grid:
[[5,3,4,6,7,8,9,1,2],
[6,7,2,1,9,5,3,4,8],
[1,9,8,3,4,2,5,6,7],
[8,5,9,7,6,1,4,2,3],
[4,2,6,8,5,3,7,9,1],
[7,1,3,9,2,4,8,5,6],
[9,6,1,5,3,7,2,8,4],
[2,8,7,4,1,9,6,3,5],
[3,4,5,2,8,6,1,7,9]].

12 ) Write a Prolog program to simulate a basic logic circuit (e.g., AND, OR, NOT gates) and
verify its truth table.
% Basic Logic Circuit Simulation
% Define basic gates
and_gate(A, B, C) :- C is A * B.
or_gate(A, B, C) :- C is max(A, B).
not_gate(A, B) :- B is 1 - A.
% Example of generating a truth table for AND gate
truth_table_and :-
write('A B | A AND B'), nl,
forall(between(0, 1, A),
forall(between(0, 1, B),
(and_gate(A, B, C), write(A), write(' '), writ
% Example of generating a truth table for OR gate
truth_table_or :-
write('A B | A OR B'), nl,
forall(between(0, 1, A),
forall(between(0, 1, B),
(or_gate(A, B, C), write(A), write(' '), write
% Example of generating a truth table for NOT gate
truth_table_not :-
write('A | NOT A'), nl,
forall(between(0, 1, A),
(not_gate(A, B), write(A), write(' | '), write(B), nl
% Example query for truth table
?- truth_table_and.
% Expected Output:
A B | A AND B
00|0
01|0
10|0
11|1

13 )Create a Prolog system to find routes between cities (nodes) using depth-first or
breadth-first search algorithms.
% Route Finder between Cities using Depth-First Search
:- dynamic edge/2.
% Define edges between cities
edge(a, b).
edge(a, c).
edge(b, d).
edge(c, d).
edge(d, e).
edge(e, f).
edge(b, f).
% Depth-First Search algorithm
dfs(Start, Goal, Path) :-
dfs(Start, Goal, [Start], Path).
dfs(Goal, Goal, Visited, Path) :-
reverse(Visited, Path).
dfs(Current, Goal, Visited, Path) :-
edge(Current, Next),
\+ member(Next, Visited),
dfs(Next, Goal, [Next | Visited], Path).
% Example query to find a path from city a to city f
?- dfs(a, f, Path).
% Expected Output:
Path = [a, b, f] ;
Path = [a, c, d, b, f] ;
Path = [a, b, d, e, f] ;

14 )Implement a simple natural language processor in Prolog that can parse and understand
basic English sentences, focusing on grammar and syntax.
% Simple Natural Language Processor
:- dynamic rule/2.
% Define grammar rules
rule(sentence(subject(Subject), verb(Verb), object(Object)), 'S
rule(subject(noun(Noun)), 'NP').
rule(verb(Verb), 'VP').
rule(object(noun(Noun)), 'NP').
rule(noun(cat), 'cat').
rule(noun(dog), 'dog').
rule(verb(likes), 'likes').
rule(verb(hates), 'hates').
% Parsing a sentence
parse(Sentence, Tree) :-
phrase(Tree, Sentence).
% Example query to parse a sentence
?- parse([cat, likes, dog], Tree).
% Expected Output:
Tree = sentence(subject(noun(cat)), verb(likes), object(noun(dog

You might also like