Prolog

wwww

  1. Complete Prolog Programming Guide
    1. Understanding Prolog and Its Industry Importance
      1. Why Prolog Matters
      2. Career Opportunities
  2. Environment Setup
    1. Installing SWI-Prolog
      1. On Ubuntu/Linux
      2. On Windows
      3. On macOS
    2. Starting the Prolog Interpreter
    3. Loading Programs
  3. Comments in Prolog
    1. Single-line Comments
    2. Multi-line Comments
  4. Atoms and Variables
    1. Case Sensitivity
    2. The Anonymous Variable
    3. Examples of Atoms and Variables
  5. Facts
    1. Reading Facts
    2. Examples of Facts
  6. Rules
    1. Rules with Multiple Conditions
    2. Examples of Rules
    3. Rules with Variables
  7. Queries
    1. Example Queries
    2. Variable Queries
  8. Connectives
    1. Logical AND (,)
    2. Logical OR (;)
    3. Negation (\+)
    4. Examples of Connectives
  9. Unification
    1. Matching vs Unification
    2. Occurs Check
    3. Examples of Unification
  10. Lists
    1. List Representation
    2. Head/Tail Notation
    3. List Matching Examples
  11. List Operations
    1. member/2 – Check List Membership
    2. append/3 – Concatenate Lists
    3. length/2 – List Length
    4. sort/2 – Sort a List
    5. reverse/2 – Reverse a List
    6. min_list/2 and max_list/2
    7. nth0/3 – Element at Index
    8. delete/3 – Remove Element
    9. last/2 – Last Element
  12. Recursion
    1. Basic Recursive Pattern
    2. ancestor_of/2 – Recursive Ancestor Relation
    3. descendant_of/2 – Recursive Descendant Relation
    4. member/2 – Recursive List Membership
    5. Recursion with Lists – Examples
    6. Recursion Using Accumulators (Tail Recursion)
  13. Cut (!) and Negation
    1. The Cut Operator (!)
    2. Negation as Failure (\+)
    3. findall/3 – Collect All Solutions
  14. Control Structures
    1. IF-THEN-ELSE
    2. Conditional with Cut
  15. Advanced Features
    1. Arithmetic in Prolog
    2. Constraint Logic Programming
    3. Difference Lists
  16. Real-World Projects
    1. 1. Family Tree System
    2. 2. Bird Knowledge Base
    3. 3. Expert System – Bird Identifier
    4. 4. Scheduling System
    5. 5. Maze Solver
  17. Testing & Professional Development
    1. Debugging Techniques
    2. SWI-Prolog Built-in Help
    3. Key Prolog Idioms
      1. Accumulator Pattern
      2. Generate and Test Pattern
      3. Definite Clause Grammar (DCG)
  18. Career Readiness
    1. Prolog Technical Interview Questions
      1. Common Questions
      2. Project Ideas for Portfolio
  19. Final Advice

Complete Prolog Programming Guide

Understanding Prolog and Its Industry Importance

Prolog (Programming in Logic) is a declarative programming language based on first-order logic. Unlike imperative languages where you tell the computer how to solve a problem, in Prolog you describe what the problem is and let the system derive the solution through logical inference .

A Prolog program is a collection of Horn clauses of the form:

H :- B1, B2, ..., Bn.

This is interpreted as: “If B1 and B2 and … Bn are true, then H is also true” .

Why Prolog Matters

Prolog is widely used in areas requiring symbolic reasoning and intelligent decision-making:

  • Artificial Intelligence – Expert systems, natural language processing
  • Knowledge Representation – Building semantic networks and ontologies
  • Logic Programming Research – Academic study of automated reasoning
  • Constraint Solving – Scheduling, planning, and optimization problems
  • Database Query Systems – Complex query formulation

Career Opportunities

  • AI Specialist – Developing intelligent systems and knowledge bases
  • Computational Linguist – Natural language processing applications
  • Knowledge Engineer – Building expert systems and decision support
  • Academic Researcher – Logic programming and automated reasoning
  • Game AI Programmer – Creating intelligent game agents

Environment Setup

Installing SWI-Prolog

On Ubuntu/Linux

# Update package list
sudo apt update

# Install SWI-Prolog
sudo apt install swi-prolog

# Verify installation
swipl --version

On Windows

  1. Download SWI-Prolog from https://www.swi-prolog.org/download/stable
  2. Run the installer (follow default settings)
  3. Add SWI-Prolog to your PATH (optional)
  4. Launch SWI-Prolog from Start Menu

On macOS

# Using Homebrew
brew install swi-prolog

# Verify installation
swipl --version

Starting the Prolog Interpreter

# Launch SWI-Prolog
swipl

# You will see the Prolog prompt
?-

# To exit
?- halt.

Loading Programs

# Load a Prolog file (replace filename.pl with actual file)
?- [filename].

# Alternative consult command
?- consult('filename.pl').

# If file loads successfully
true.

# Set working directory
?- cd('/path/to/your/working/directory').
true.

Important: Every fact and rule must end with a period .

Comments in Prolog

Single-line Comments

% This is a single-line comment
% Everything after % on the line is ignored

fact(argument).  % Inline comment after code

Multi-line Comments

/*
  This is a multi-line comment.
  It can span multiple lines.
  Useful for documentation and explaining code.
*/

% This is the preferred format for documentation
%
% @author Your Name
% @date 2024
% @version 1.0
% @description This program manages bird knowledge

Atoms and Variables

Case Sensitivity

Prolog is case-sensitive with an important rule:

  • Lowercase identifiers are atoms (constants or functor names)
  • Uppercase identifiers are variables
% Atoms (lowercase)
bird(sparrow).        % bird is the functor, sparrow is an atom
color(sky, blue).     % color, sky, blue are all atoms

% Variables (uppercase)
bird(X).              % X is a variable
parent(Child, Parent).  % Child and Parent are variables

The Anonymous Variable

The underscore _ is the anonymous variable. It matches anything but we don’t care about its value .

% Check if someone has a child without caring who the child is
has_child(Person) :- parent(Person, _).

% Check if anyone has a child at all
somebody_has_child :- parent(_, _).

Examples of Atoms and Variables

% Atoms (things that are specific values)
hot(sun).           % hot is functor, sun is atom
play(magnus, chess).  % play is functor, magnus and chess are atoms
gives(sarah, waldo, flower).  % gives is functor with 3 atom arguments

% Variables (things that can be bound to values)
% X is a variable that can be anything
% Person and Place are also variables
works_at(Person, Place) :- employee(Person), office(Place).

Facts

Facts are the simplest building blocks of a Prolog program. A fact is a clause without a body—a bare assertion that something is unconditionally true .

% Syntax: predicate(arguments).
% A fact ends with a period

color(sky, blue).     % The color of the sky is blue
bird(eagle).          % An eagle is a bird
parent(bob, alice).   % Bob is a parent of Alice
likes(mary, pizza).   % Mary likes pizza

Reading Facts

The order of arguments matters .

% Different meanings
color(sky, blue).     % "The color of the sky is blue"
color(blue, sky).     % "The color of blue is sky" (different meaning!)

% Consistency in argument order is important
enjoys(mary, brussels_sprouts).   % Mary enjoys brussels sprouts
% NOT: enjoys(brussels_sprouts, mary)  % Wrong order!

Examples of Facts

% Bird facts
bird(sparrow).
bird(eagle).
bird(hawk).
bird(penguin).

% Bird attributes
can_fly(sparrow).
can_fly(eagle).
can_fly(hawk).
cannot_fly(penguin).

% Habitat facts
habitat(sparrow, forest).
habitat(eagle, mountains).
habitat(hawk, plains).
habitat(penguin, antarctic).

% Color facts
color(sparrow, brown).
color(eagle, dark_brown).
color(hawk, grey).
color(penguin, black_white).

% Diet facts
eats(sparrow, seeds).
eats(eagle, meat).
eats(hawk, meat).
eats(penguin, fish).

Rules

Rules define derived truths using conditions. They consist of a head and a body, separated by :- which is read as “if” .

% Syntax: head :- body.
% head is true if all goals in body are true

can_swim(X) :- aquatic(X).   % X can swim if X is aquatic

Rules with Multiple Conditions

The comma , between goals represents logical AND .

% All conditions must be true
is_pumpkin(X) :-
    winter_squash(X),
    big(X),
    orange(X).

% Read as: X is a pumpkin IF
%   X is a winter squash
%   AND X is big
%   AND X is orange

Examples of Rules

% Rule: A bird of prey is a bird that eats meat
bird_of_prey(X) :-
    bird(X),
    eats(X, meat).

% Rule: A raptor is a bird of prey with sharp claws
raptor(X) :-
    bird_of_prey(X),
    has_sharp_claws(X).

% Rule: A flightless bird is a bird that cannot fly
flightless_bird(X) :-
    bird(X),
    cannot_fly(X).

% Rule: A bird can live in a place if it's its habitat
lives_in(X, Place) :-
    habitat(X, Place).

% Rule: Two birds are companions if they live in the same place
companions(X, Y) :-
    bird(X),
    bird(Y),
    X \= Y,
    habitat(X, Place),
    habitat(Y, Place).

Rules with Variables

% Rule with multiple variables
likes_bird(Person, Bird) :-
    person(Person),
    bird(Bird),
    likes(Person, Bird).

% Rule: Someone is a birdwatcher if they like birds
birdwatcher(Person) :-
    person(Person),
    likes(Person, Bird),
    bird(Bird).

% Rule: Two people are birdwatching buddies
birdwatching_buddies(Person1, Person2) :-
    person(Person1),
    person(Person2),
    Person1 \= Person2,
    birdwatcher(Person1),
    birdwatcher(Person2).

Queries

Queries are questions you ask Prolog about your knowledge base .

% Syntax: ?- query.
% Ask at the Prolog prompt (after ?-)

?- bird(sparrow).     % Is sparrow a bird?
?- bird(X).           % What are all the birds?

Example Queries

% Given these facts
bird(sparrow).
bird(eagle).
bird(hawk).
can_fly(sparrow).
can_fly(eagle).
habitat(sparrow, forest).
habitat(eagle, mountains).

% Basic queries
?- bird(sparrow).           % true
?- bird(penguin).           % false
?- can_fly(X).              % X = sparrow ; X = eagle
?- habitat(sparrow, forest). % true

Variable Queries

% Find all birds
?- bird(X).
X = sparrow ;
X = eagle ;
X = hawk ;
false.

% Find all birds that can fly
?- bird(X), can_fly(X).
X = sparrow ;
X = eagle ;
false.

% Find all habitats
?- habitat(Bird, Place).
Bird = sparrow, Place = forest ;
Bird = eagle, Place = mountains ;
false.

% Find all birds in a specific habitat
?- habitat(X, forest).
X = sparrow ;
false.

Connectives

Logical AND (,)

The comma , represents logical AND. All goals must be true .

% Bird X is a raptor if it's a bird AND it eats meat
raptor(X) :-
    bird(X),
    eats(X, meat).

% Query: Find all birds that are raptors
?- raptor(X).
X = eagle ;
X = hawk ;
false.

Logical OR (;)

The semicolon ; represents logical OR. At least one goal must be true.

% A creature is a bird OR a reptile
vertebrate(X) :-
    bird(X);
    reptile(X).

% Multiple conditions
% X can fly OR is a penguin
can_move(X) :-
    can_fly(X);
    species(X, penguin).

Negation (\+)

Negation is written as \+ (meaning “not”) .

% A flightless bird is a bird that cannot fly
flightless_bird(X) :-
    bird(X),
    \+ can_fly(X).

% Query: Find birds that cannot fly
?- flightless_bird(X).
X = penguin ;
false.

% Check if something is not a bird
?- \+ bird(sparrow).      % false
?- \+ bird(dog).          % true

Examples of Connectives

% Complex rule with multiple connectives
compatible_species(X, Y) :-
    bird(X),
    bird(Y),
    X \= Y,                               % X is not Y
    (habitat(X, H), habitat(Y, H)),       % Same habitat (AND)
    (eats(X, Food), eats(Y, Food)).       % Same diet (AND)

% The above reads as: X and Y are compatible species if they are different birds,
% share a habitat, and share a diet

Unification

Unification is the process of making two terms identical by binding variables to values .

% A variable can be unified with a value
?- X = 5.
X = 5.

% Multiple variables can be unified together
?- X = Y, Y = 5.
X = 5, Y = 5.

% Structure unification
?- bird(X) = bird(sparrow).
X = sparrow.

Matching vs Unification

Matching: Equating a variable to a term

% Matching (one side is a variable)
?- X = bird(eagle).
X = bird(eagle).

?- X = f(Y).
X = f(Y), Y = _.

Unification: Variables on both sides become bound

% Unification (variables on both sides)
?- (X = a, Y = f(b)), f(Y) = X.
X = f(b), Y = b.

% This binds X and Y together through the structure

Occurs Check

Occurs check prevents infinite unification .

% Without occurs check, this can loop
?- X = f(X).
X = f(X).

% With occurs check, it detects the problem
?- X = f(X), occurs_check.  % Error: cyclic term

Examples of Unification

% Unification in rule application
% Fact: parent(bob, alice).
% Query: parent(X, alice).
% Unification: X = bob

% Unification with rules
% Rule: grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
% Query: grandparent(X, Y).
% Prolog attempts to unify X, Y, and Z with facts

Lists

List Representation

Lists are the primary data structure for representing complex data in Prolog .

% List syntax: [element1, element2, element3]
[1, 2, 3, 4]

[bob, carol, ted, alice]

[3, ‘foo’, [x, [y]], 17] % Nested lists [] % Empty list

Head/Tail Notation

The head/tail notation [H|T] separates the first element (head) from the rest of the list (tail) .

% [1, 2, 3, 4]
% [X|Y] matches X=1, Y=[2,3,4]
% [X,Y|Z] matches X=1, Y=2, Z=[3,4]
% [X,Y,Z|W] matches X=1, Y=2, Z=3, W=[4]

% List with exactly 2 elements
% [X,Y|[]] matches [1,2]

List Matching Examples

% Matching with H|T notation
?- [X|Y] = [bob, carol, ted, alice].
X = bob, Y = [carol, ted, alice].

?- [X,Y|Z] = [bob, carol, ted, alice].
X = bob, Y = carol, Z = [ted, alice].

?- [X,Y,Z,W|V] = [bob, carol, ted, alice].
X = bob, Y = carol, Z = ted, W = alice, V = [].

% This won't match
?- [X,Y,Z,W,V|U] = [bob, carol, ted, alice].
false.

List Operations

member/2 – Check List Membership

% member(Element, List)
member(X, [X|_]).     % Base case: X is the head
member(X, [_|T]) :-   % Recursive case: check tail
    member(X, T).

How it works :

% Query: member(c, [a, b, c])
% 1. Try base case: c = a? No
% 2. Try recursive: member(c, [b, c])
% 3. Try base: c = b? No
% 4. Try recursive: member(c, [c])
% 5. Try base: c = c? Yes! Success.

append/3 – Concatenate Lists

% append(List1, List2, Result)
append([], L, L).              % Base case: empty list
append([H|T], L, [H|R]) :-     % Recursive case
    append(T, L, R).

% Examples
?- append([1,2], [3,4], X).
X = [1, 2, 3, 4].

?- append(X, [3,4], [1,2,3,4]).
X = [1, 2].

?- append([1,2], Y, [1,2,3,4]).
Y = [3, 4].

length/2 – List Length

% length(List, Length)
?- length([1,2,3,4], X).
X = 4.

?- length([], X).
X = 0.

sort/2 – Sort a List

% sort(List, Result)
?- sort([3,1,4,1,5,9,2,6], X).
X = [1, 2, 3, 4, 5, 6, 9].

% sort removes duplicates
?- sort([3,1,3,2], X).
X = [1, 2, 3].

reverse/2 – Reverse a List

% reverse(List, Result)
?- reverse([1,2,3,4], X).
X = [4, 3, 2, 1].

min_list/2 and max_list/2

% min_list(List, Min)
?- min_list([3,1,4,1,5,9], X).
X = 1.

% max_list(List, Max)
?- max_list([3,1,4,1,5,9], X).
X = 9.

nth0/3 – Element at Index

% nth0(Position, List, Element)  % 0-based indexing
?- nth0(2, [a,b,c,d], X).
X = c.

?- nth0(0, [a,b,c,d], X).
X = a.

delete/3 – Remove Element

% delete(List, Element, Result)
?- delete([a,b,c,a,d], a, X).
X = [b, c, d].

last/2 – Last Element

% last(List, Element)
?- last([a,b,c,d], X).
X = d.

Recursion

Recursion is the primary control mechanism in Prolog. A recursive rule calls itself with a smaller version of the problem .

Basic Recursive Pattern

% Recursive predicate pattern
predicate(X) :-
    base_case(X).        % Base case (stop condition)
predicate(X) :-
    reduction(X, Y),     % Reduce the problem
    predicate(Y).        % Recursive call

ancestor_of/2 – Recursive Ancestor Relation

% Facts: parent relationships
parent(bob, alice).
parent(alice, carol).
parent(carol, david).

% Base case: direct parent
ancestor_of(X, Y) :-
    parent(X, Y).

% Recursive case: parent of an ancestor
ancestor_of(X, Y) :-
    parent(X, Z),
    ancestor_of(Z, Y).

% Query: Is bob an ancestor of david?
?- ancestor_of(bob, david).
true.

descendant_of/2 – Recursive Descendant Relation

% Base case: direct child
descendant_of(X, Y) :-
    parent(Y, X).

% Recursive case: descendant of a descendant
descendant_of(X, Y) :-
    parent(Z, X),
    descendant_of(Z, Y).

member/2 – Recursive List Membership

member(X, [X|_]).              % Base case: found at head
member(X, [_|Tail]) :-         % Recursive case
    member(X, Tail).           % Check in tail

Recursion with Lists – Examples

% Count elements in a list
list_length([], 0).              % Base case: empty list
list_length([_|T], N) :-         % Recursive case
    list_length(T, N1),
    N is N1 + 1.

% Calculate sum of a list
list_sum([], 0).                 % Base case: empty list
list_sum([H|T], Sum) :-          % Recursive case
    list_sum(T, RestSum),
    Sum is H + RestSum.

% Find maximum element in a list
list_max([X], X).                % Base case: single element
list_max([H|T], Max) :-          % Recursive case
    list_max(T, MaxT),
    Max is max(H, MaxT).

Recursion Using Accumulators (Tail Recursion)

% More efficient version using an accumulator
list_length_acc(L, N) :-
    list_length_acc(L, 0, N).

list_length_acc([], Acc, Acc).   % Base case: all counted
list_length_acc([_|T], Acc, N) :- % Recursive case
    NewAcc is Acc + 1,
    list_length_acc(T, NewAcc, N).

% Usage: list_length_acc([1,2,3], N).
% N = 3

Cut (!) and Negation

The Cut Operator (!)

The cut operator ! commits to the current choices and prevents backtracking .

% Without cut
max(X, Y, X) :- X >= Y.
max(X, Y, Y) :- X < Y.

% With cut (more efficient)
max(X, Y, X) :- X >= Y, !.
max(X, Y, Y) :- X < Y.    % This is only reached if first rule failed

Negation as Failure (\+)

% Negation as failure means "cannot prove it's true"
not_bird(X) :-
    \+ bird(X).

% Query: not_bird(dog).  % true (if dog is not a bird)
% Query: not_bird(sparrow).  % false (if sparrow is a bird)

findall/3 – Collect All Solutions

findall collects all solutions to a query into a list .

% Syntax: findall(Template, Goal, List)
% Collects all values of Template for which Goal is true

% Example: collect all birds
?- findall(X, bird(X), BirdList).
BirdList = [sparrow, eagle, hawk, penguin].

% Example: collect all birds that can fly
?- findall(X, (bird(X), can_fly(X)), FlyingBirds).
FlyingBirds = [sparrow, eagle, hawk].

% Example: collect all habitats
?- findall(Place, habitat(_, Place), Habitats).
Habitats = [forest, mountains, plains, antarctic].

Control Structures

IF-THEN-ELSE

Prolog has an IF-THEN-ELSE construct:

% Syntax: (Condition -> ThenPart ; ElsePart)
can_swim(X) :-
    (bird(X) -> can_fly(X) ; aquatic(X)).
% Example: classify bird
classify(X) :-
    (can_fly(X) ->
        write('Flying bird');
        write('Flightless bird')
    ).

Conditional with Cut

% Using cut for conditional behavior
speed(X, fast) :-
    bird_of_prey(X), !.
speed(X, slow) :-
    bird(X).

Advanced Features

Arithmetic in Prolog

% Arithmetic evaluation with 'is'
?- X is 3 + 4.
X = 7.

?- X is 5 * 6.
X = 30.

% Comparison operators
?- 3 < 5.        % true
?- 10 >= 5.      % true
?- 2 + 3 =:= 5.  % true (equality of values)
?- 2 + 3 == 5.   % false (different structure)

Constraint Logic Programming

Prolog supports constraint solving for more complex problem-solving :

% Simple constraints
?- X #> 3, X #< 10.
X in 4..9.

% Scheduling problems can be expressed as constraints

Difference Lists

Difference lists provide efficient list operations :

% A difference list is a list represented as (List, Tail)
% Example: the difference list (L, Tail) represents L without Tail

Real-World Projects

1. Family Tree System

% Facts
parent(bob, alice).
parent(bob, charlie).
parent(alice, david).
parent(alice, eve).
parent(charlie, frank).
parent(david, grace).

% Rules
% X is a grandparent of Y
grandparent(X, Y) :-
    parent(X, Z),
    parent(Z, Y).

% X is a sibling of Y
sibling(X, Y) :-
    parent(Z, X),
    parent(Z, Y),
    X \= Y.

% X is an ancestor of Y
ancestor(X, Y) :-
    parent(X, Y).
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).

% X is a cousin of Y
cousin(X, Y) :-
    parent(P1, X),
    parent(P2, Y),
    sibling(P1, P2),
    X \= Y.

% Query examples
?- grandparent(bob, X).           % X = david, eve, frank
?- sibling(X, Y).                 % Find all siblings
?- ancestor(bob, X).              % X = alice, charlie, david, eve, frank, grace

2. Bird Knowledge Base

% Facts
% bird(Species, Color, Habitat, Diet, CanFly)
bird(sparrow, brown, forest, seeds, true).
bird(eagle, dark_brown, mountains, meat, true).
bird(hawk, grey, plains, meat, true).
bird(penguin, black_white, antarctic, fish, false).
bird(parrot, green, jungle, fruits, true).
bird(ostrich, grey, savannah, plants, false).

% Rules
% A bird is a predator if it eats meat
predator(X) :-
    bird(X, _, _, meat, _).

% A bird is suitable for a region based on habitat
suitable_for_region(X, Region) :-
    bird(X, _, Habitat, _, _),
    member(Habitat, RegionHabitats).

% Two birds are compatible if they share a habitat and diet
compatible(X, Y) :-
    bird(X, _, Habitat1, Diet1, _),
    bird(Y, _, Habitat2, Diet2, _),
    X \= Y,
    Habitat1 = Habitat2,
    Diet1 = Diet2.

% Query examples
?- predator(X).                   % X = eagle, hawk
?- compatible(sparrow, X).        % X = parrot (if habitat/diet match)
?- bird(X, _, _, _, false).       % X = penguin, ostrich

3. Expert System – Bird Identifier

% Rule-based bird identification
% bird(Species, Habitat, Color, Size, Diet, Flight)

bird(eagle, mountains, brown, large, meat, true).
bird(sparrow, forest, brown, small, seeds, true).
bird(penguin, antarctic, black_white, medium, fish, false).
bird(parrot, jungle, green, medium, fruits, true).

% Identification rules
identify(Species) :-
    bird(Species, Habitat, Color, Size, Diet, Flight),
    write('Species: '), write(Species), nl,
    write('Habitat: '), write(Habitat), nl,
    write('Color: '), write(Color), nl,
    write('Size: '), write(Size), nl,
    write('Diet: '), write(Diet), nl,
    write('Can Fly: '), write(Flight), nl.

% Ask user for characteristics and identify
ask_identify :-
    write('Enter habitat (mountains/forest/antarctic/jungle): '), read(Habitat),
    write('Enter color (brown/black_white/green): '), read(Color),
    write('Enter size (small/medium/large): '), read(Size),
    findall(Species, bird(Species, Habitat, Color, Size, _, _), Result),
    write('Possible species: '), write(Result), nl.

4. Scheduling System

% Simple scheduling example
% Appointment( Person, Day, Time )

% Availability
available(tom, monday, 10).
available(tom, monday, 11).
available(sarah, monday, 10).
available(sarah, tuesday, 14).

% Find a meeting time for two people
meeting_time(Person1, Person2, Day, Time) :-
    available(Person1, Day, Time),
    available(Person2, Day, Time),
    Person1 \= Person2.

% Find a meeting time for three people
meeting_time3(P1, P2, P3, Day, Time) :-
    available(P1, Day, Time),
    available(P2, Day, Time),
    available(P3, Day, Time),
    P1 \= P2,
    P1 \= P3,
    P2 \= P3.

5. Maze Solver

% Maze represented as connected rooms
connected(room1, room2).
connected(room1, room3).
connected(room2, room4).
connected(room3, room4).
connected(room4, room5).

% Path finding
path(X, Y, Path) :-
    path(X, Y, [X], Path).

path(X, X, Visited, Visited).
path(X, Y, Visited, Path) :-
    connected(X, Z),
    \+ member(Z, Visited),
    path(Z, Y, [Z|Visited], Path).

% Query: find a path from room1 to room5
?- path(room1, room5, Path).
% Path = [room1, room2, room4, room5] or [room1, room3, room4, room5]

Testing & Professional Development

Debugging Techniques

% Use trace to see what Prolog is doing
?- trace.
% Now every query shows the execution steps

% Use spy to watch specific predicates
?- spy(bird).
% Now every query to bird/1 will be traced
% Example trace output
?- trace, bird(X).
   Call: (8) bird(_) ? creep
   Exit: (8) bird(sparrow) ? creep
X = sparrow ;
   Redo: (8) bird(_) ? creep
   Exit: (8) bird(eagle) ? creep
X = eagle ;
...

SWI-Prolog Built-in Help

% Get help on a topic
?- help(bird).

% Search for a topic
?- apropos(list).

% Show documentation for a predicate
?- help(member/2).

Key Prolog Idioms

Accumulator Pattern

% Efficient list processing with accumulator
reverse_acc(L, R) :-
    reverse_acc(L, [], R).

reverse_acc([], Acc, Acc).
reverse_acc([H|T], Acc, R) :-
    reverse_acc(T, [H|Acc], R).

Generate and Test Pattern

% Generate possibilities and test constraints
valid_combination(X, Y, Z) :-
    generate(X, Y, Z),
    test_constraints(X, Y, Z).

Definite Clause Grammar (DCG)

% Natural language parsing
sentence --> noun_phrase, verb_phrase.
noun_phrase --> determiner, noun.
verb_phrase --> verb, noun_phrase.

determiner --> [the].
determiner --> [a].
noun --> [bird].
noun --> [eagle].
verb --> [flies].
verb --> [eats].

Career Readiness

Prolog Technical Interview Questions

Common Questions

  1. What is unification in Prolog?
    • Unification is the process of making two terms identical by binding variables to values. It is used when Prolog tries to match a query with a rule head or fact.
  2. Explain the difference between = and ==
    • = is for unification (making terms equal), == is for equality comparison (checking if terms are already identical).
  3. What is the cut operator (!) and when should you use it?
    • Cut commits to current choices and prevents backtracking. Use it for efficiency and to control execution flow.
  4. What is the difference between findall, bagof, and setof?
    • All collect solutions. findall collects all solutions in order, bagof respects variable bindings, setof sorts and removes duplicates.
  5. Explain recursion in Prolog with an example
    • Recursion is a predicate calling itself. Example: ancestor(X,Y) :- parent(X,Y); parent(X,Z), ancestor(Z,Y).
  6. What are difference lists and why are they useful?
    • Difference lists allow O(1) list concatenation operations, useful for parsing and efficient list handling.
  7. How does backtracking work in Prolog?
    • Prolog tries to prove a query by trying all possible paths. If a path fails, it backtracks to the previous choice point and tries another alternative.
  8. What is negation as failure?
    • In Prolog, \+ Goal succeeds when Prolog cannot prove the specified Goal. This behavior follows the closed-world assumption, where a statement that cannot be proven is treated as false.

Project Ideas for Portfolio

  • Family tree and genealogy systems
  • Expert systems for bird/animal identification
  • Scheduling and planning applications
  • Natural language processing systems
  • Maze and puzzle solvers
  • Knowledge bases for domain-specific reasoning
  • Constraint solving applications
  • Automated theorem provers
  • Game AI players

Final Advice

Prolog offers a fundamentally different perspective on programming compared to imperative languages. Instead of specifying step-by-step instructions, you describe relationships and constraints, and the system deduces the answers.

Key principles to remember:

  • Think in terms of facts, rules, and queries
  • Embrace recursion as the primary control mechanism
  • Let the system do the searching and backtracking
  • Use unification to your advantage
  • Understand the execution model (top-down, left-to-right)

Start simply: Write small knowledge bases. Add facts, rules, and run queries to understand what Prolog deduces. Experiment with recursion and list processing before tackling larger projects.

Practice with real problems: The best way to learn Prolog is to build applications – family trees, bird identification, schedules, and puzzles. Each challenge will deepen your understanding of logic programming.

Use the AI prompts provided for each concept. Work through the examples, modify them, and create your own queries.

Good luck, and welcome to the world of logic programming. The journey will change how you think about problem-solving.

Scroll to Top