SWI – PROLOG PROGRAMS
1. Write a program in prolog to implement simple facts and Queries.
% Defining facts about family relationships
parent(john, mary).
parent(john, david).
parent(susan, mary).
parent(susan, david).
parent(david, lily).
parent(lily, sam).
% Defining facts about gender
male(john).
male(david).
male(sam).
female(susan).
female(mary).
female(lily).
% Defining a rule for a father
father(X, Y) :- parent(X, Y), male(X).
% Defining a rule for a mother
mother(X, Y) :- parent(X, Y), female(X).
% Defining a rule for a grandparent
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
% Defining a rule for a sibling
sibling(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y.
OUTPUT:
2. Write a program in prolog to implement simple arithmetic, Factorial, Fibonacci
2a. This program defines basic arithmetic operations like addition, subtraction,
multiplication, and division.
% Addition
add(X, Y, Result) :- Result is X + Y.
% Subtraction
subtract(X, Y, Result) :- Result is X - Y.
% Multiplication
multiply(X, Y, Result) :- Result is X * Y.
% Division (checks if Y is not zero to avoid errors)
divide(X, Y, Result) :- Y \= 0, Result is X / Y.
OUTPUT
2b. Factorial Calculation
% Base case: Factorial of 0 is 1
factorial(0, 1).
% Recursive case: N! = N * (N-1)!
factorial(N, Result) :-
N > 0,
N1 is N - 1,
factorial(N1, R1),
Result is N * R1.
OUTPUT
2c. Fibonacci sequence.
% Base cases: Fibonacci of 0 is 0, and Fibonacci of 1 is 1
fibonacci(0, 0).
fibonacci(1, 1).
% Recursive case: F(N) = F(N-1) + F(N-2)
fibonacci(N, Result) :-
N > 1,
N1 is N - 1,
N2 is N - 2,
fibonacci(N1, R1),
fibonacci(N2, R2),
Result is R1 + R2.
OUTPUT
3.Write a program in prolog to solve Tower of Hanoi
% Base case: Move one disk from Source to Destination
hanoi(1, Source, Destination, _) :-
write('Move disk from '), write(Source),
write(' to '), write(Destination), nl.
% Recursive case: Move N disks from Source to Destination using Auxiliary
hanoi(N, Source, Destination, Auxiliary) :-
N > 1,
M is N - 1,
hanoi(M, Source, Auxiliary, Destination), % Move N-1 disks to Auxiliary
hanoi(1, Source, Destination, _), % Move largest disk to Destination
hanoi(M, Auxiliary, Destination, Source). % Move N-1 disks to Destination
OUTPUT
4.Prolog Program to Solve the 8-Puzzle Problem
% Define goal state
goal([1,2,3,4,5,6,7,8,0]).
% Find possible moves for the empty tile (0)
move(State, NextState) :-
nth0(ZeroPos, State, 0),
swap_position(ZeroPos, SwapPos),
nth0(SwapPos, State, Tile),
replace(State, ZeroPos, Tile, Temp),
replace(Temp, SwapPos, 0, NextState).
% Define legal swap positions based on the index of 0
swap_position(0, 1). swap_position(0, 3).
swap_position(1, 0). swap_position(1, 2). swap_position(1, 4).
swap_position(2, 1). swap_position(2, 5).
swap_position(3, 0). swap_position(3, 4). swap_position(3, 6).
swap_position(4, 1). swap_position(4, 3). swap_position(4, 5). swap_position(4, 7).
swap_position(5, 2). swap_position(5, 4). swap_position(5, 8).
swap_position(6, 3). swap_position(6, 7).
swap_position(7, 4). swap_position(7, 6). swap_position(7, 8).
swap_position(8, 5). swap_position(8, 7).
% Replace element at Index in List with Elem → NewList
replace([_|T], 0, Elem, [Elem|T]).
replace([H|T], I, Elem, [H|R]) :-
I > 0, I1 is I - 1,
replace(T, I1, Elem, R).
% BFS to solve puzzle
solve_8_puzzle(Start, Solution) :-
bfs([[Start]], [], Solution).
bfs([[State | Path] | _], _, [State | Path]) :-
goal(State).
bfs([[State | Path] | Rest], Visited, Solution) :-
findall([Next, State | Path],
(move(State, Next), \+ member(Next, Visited), \+ member([Next | _], Rest)) NewPaths),
append(Rest, NewPaths, Queue),
bfs(Queue, [State | Visited], Solution).
OUTPUT
5. Prolog Program to Solve the N-Queens Problem
% Entry point: solve the N-Queens problem
n_queens(N, Solution) :-
range(1, N, Ns),
permutation(Ns, Solution),
safe(Solution).
% Generate a list of integers From to To
range(From, To, []) :- From > To.
range(From, To, [From | Rest]) :-
From =< To,
Next is From + 1,
range(Next, To, Rest).
% Check that no two queens attack each other diagonally
safe([]).
safe([Q | Others]) :-
safe(Q, Others, 1),
safe(Others).
% Check diagonals
safe(_, [], _).
safe(Q, [Q1 | Others], D) :-
abs(Q - Q1) =\= D,
D1 is D + 1,
safe(Q, Others, D1).
OUTPUT
6. Write a program in prolog to solve Traveling salesman problem
% Define distances between cities (Undirected Graph)
edge(a, b, 10).
edge(a, c, 15).
edge(a, d, 20).
edge(b, a, 10).
edge(b, c, 35).
edge(b, d, 25).
edge(c, a, 15).
edge(c, b, 35).
edge(c, d, 30).
edge(d, a, 20).
edge(d, b, 25).
edge(d, c, 30).
% Bidirectional edges (Optional: If not explicitly mentioned)
distance(X, Y, D) :- edge(X, Y, D).
distance(X, Y, D) :- edge(Y, X, D).
% Finding all paths from Start to other cities and returning to Start
tsp(Start, Path, Cost) :-
findall(City, distance(Start, City, _), Cities), % Get all cities
permutation(Cities, PermPath), % Generate all possible permutations of cities
append(PermPath, [Start], CompletePath), % Make it a cycle
calculate_cost(Start, CompletePath, Cost), % Compute total cost
Path = [Start | CompletePath]. % Store the full path
% Calculate cost of the given path
calculate_cost(_, [Last], 0). % Base case: last city
calculate_cost(Start, [A, B | Rest], Cost) :-
distance(A, B, D),
calculate_cost(Start, [B | Rest], Cost1),
Cost is Cost1 + D.
% Find the optimal (shortest) path
shortest_tsp(Start, ShortestPath, MinCost) :-
findall((Path, Cost), tsp(Start, Path, Cost), Paths),
min_member((ShortestPath, MinCost), Paths).
OUTPUT
7. Prolog Program to Solve the Water Jug Problem
% Define valid moves for the Water Jug Problem
% Fill Jug 1 completely
move(state(_, B), fill1, state(4, B)).
% Fill Jug 2 completely
move(state(A, _), fill2, state(A, 3)).
% Empty Jug 1
move(state(_, B), empty1, state(0, B)).
% Empty Jug 2
move(state(A, _), empty2, state(A, 0)).
% Pour water from Jug 1 to Jug 2
move(state(A, B), pour1to2, state(A1, B1)) :-
Total is A + B,
(Total =< 3 -> B1 = Total, A1 = 0 ; B1 = 3, A1 is Total - 3).
% Pour water from Jug 2 to Jug 1
move(state(A, B), pour2to1, state(A1, B1)) :-
Total is A + B,
(Total =< 4 -> A1 = Total, B1 = 0 ; A1 = 4, B1 is Total - 4).
% Goal state (We want exactly 2 liters in Jug 1)
goal(state(2, _)).
% Breadth-First Search (BFS) to find the optimal solution
solve_water_jug(Start, Solution) :-
bfs([[Start]], Solution).
bfs([[State | Path] | _], [State | Path]) :-
goal(State).
bfs([[State | Path] | Rest], Solution) :-
findall([NewState, State | Path],
(move(State, _, NewState), \+ member(NewState, [State | Path])),
NewPaths),
append(Rest, NewPaths, NewQueue),
bfs(NewQueue, Solution).
OUTPUT