DP

Declarative Programming in Prolog

Understanding declarative programming using Prolog for logic programming and AI applications

Learning Objectives

By the end of this lesson, you will be able to:

  • Understand what declarative programming is and how it differs from imperative programming
  • Install and set up a Prolog programming environment
  • Write facts, rules, and queries in Prolog
  • Use variables in Prolog queries to find information
  • Create logical relationships using rules in Prolog
  • Understand how backtracking works in Prolog to find multiple solutions
  • Use recursive rules to define relationships across multiple generations
  • Apply anonymous variables in queries when some values are unimportant
  • Build a complete knowledge base using Prolog facts and rules

Key Terms

Declarative Programming

Programming paradigm focusing on what should be done, not how to do it

Prolog

Logic programming language used for AI, expert systems, and declarative programming

Fact

Basic statement in Prolog that is always true, ending with a period (.)

Rule

Defines relationships between facts using the :- operator (means "if")

Query

Question asked to Prolog to check if something is true based on facts and rules

Variable

Placeholder starting with capital letter that can match any value in Prolog

Backtracking

Prolog's method of finding multiple solutions by trying different possibilities

Recursion

Defining rules that refer to themselves, allowing relationships across multiple generations

Anonymous Variable

Underscore (_) used in Prolog when we don't care about a particular value

Knowledge Base

Collection of facts and rules in a Prolog program that represents domain knowledge

Predicate

Name of a fact or rule in Prolog, followed by arguments in parentheses

Imperative Programming

Traditional programming paradigm focusing on how to achieve results step-by-step

Declarative Programming Basics

Declarative programming is a powerful programming paradigm where we focus on what we want to achieve rather than how to do it. Instead of giving step-by-step instructions, we define facts, rules, and conditions, and the system figures out the solution automatically.

Real-Life Example: Recipe vs. Restaurant Order

Think of the difference between:

  • Imperative (recipe): "Chop onions, heat oil, sauté onions for 5 minutes, add tomatoes..."
  • Declarative (restaurant order): "I want a vegetarian pizza with extra cheese"

In declarative programming, you state what you want (the pizza), not how to make it!

Declarative Languages

P
Prolog

Used for AI, logic programming, and expert systems

S
SQL

Used for databases (SELECT * FROM users WHERE age > 18;)

R
Regular Expressions

Used for pattern matching in text

Declarative vs. Imperative Programming

Declarative Programming Imperative Programming
Describes what should happen Specifies how to achieve the result
Example: grandparent(X, Y) :- parent(X, Z), parent(Z, Y). Example: if (X is a parent of Z) AND (Z is a parent of Y) then return true
Control flow is abstracted away Step-by-step instructions control the flow
Used in AI, databases, functional programming Used in system software, game development

Advantages of Declarative Programming

  • Easier to understand - No need to track step-by-step execution
  • More concise - Fewer lines of code compared to imperative programs
  • Great for AI and knowledge-based systems - Prolog is used for expert systems, natural language processing (NLP), and automated reasoning
  • Automatic solution finding - System finds solutions based on defined facts and rules

Disadvantages of Declarative Programming

  • Not suitable for all tasks - Some problems require detailed control (e.g., real-time applications)
  • Performance overhead - Some declarative languages require complex logic processing
  • Less control - Can't specify exact steps for optimization
  • Steeper learning curve - Requires different thinking than traditional programming

Installing and Setting Up Prolog

Step-by-Step Prolog Installation

  1. Step 1: Download SWI-Prolog (free) from: https://www.swi-prolog.org
  2. Step 2: Install and open SWI-Prolog
  3. Step 3: Create a new file and save it as facts.pl
  4. Step 4: Test your installation by writing: write('Hello, Prolog!').
Hint

If Prolog prints "Hello, Prolog!", it's working correctly!

Writing Facts in Prolog

A fact is a simple statement that Prolog stores as "true". Facts are the basic building blocks of a Prolog knowledge base.

Prolog Facts Simulation

capitalCity(paris).
capitalCity(berlin).
capitalCity(cairo).
% capitalCity is the predicate (the fact's name)
% paris, berlin, and cairo are arguments (data)
% The full stop (.) marks the end of the fact

How it works: Each fact has a predicate (fact name) followed by arguments in parentheses. The period (.) marks the end of each fact. Prolog stores these as true statements in its knowledge base.

Try these queries:
?- capitalCity(paris).
Output: true
?- capitalCity(london).
Output: false

London returns false because it's not in our knowledge base!

Querying Facts in Prolog

Once facts are defined, we can ask Prolog questions using queries. Queries check if something is true based on the knowledge base.

Using Variables in Queries

Variables in Prolog start with a capital letter and act as placeholders that can match any value.

Prolog Variables Simulation

cityInCountry(paris, france).
cityInCountry(berlin, germany).
cityInCountry(cairo, egypt).
cityInCountry(munich, germany).
Variable Query Examples:
?- cityInCountry(berlin, Country).
Output: Country = germany.
?- cityInCountry(City, germany).
Output:
City = berlin;
City = munich.

Prolog finds all possible answers, separated by semicolons (;).

How variables work: When you use a variable (starting with capital letter), Prolog tries to find all values that make the query true. Pressing semicolon (;) tells Prolog to find the next solution.

Activity 1: Writing and Querying Facts

Part 1: Write Facts
Create a Prolog file called facts.pl and write these facts:

% Animal facts
animal(dog).
animal(cat).
animal(elephant).
animal(lion).

% Color facts
color(red).
color(blue).
color(green).
color(yellow).

Part 2: Query Your Facts
Write queries to check:

  1. Is "dog" an animal?
  2. Is "purple" a color?
  3. What animals are in the knowledge base? (Use a variable)
  4. What colors are in the knowledge base? (Use a variable)
Hint

Each fact should be one line and end with a full stop (.). If a fact exists, Prolog returns true. If not, it returns false.

Solution:
Part 1: Facts File (facts.pl)
animal(dog).
animal(cat).
animal(elephant).
animal(lion).
color(red).
color(blue).
color(green).
color(yellow).
Part 2: Query Results
?- animal(dog).
true
?- color(purple).
false
?- animal(X).
X = dog;
X = cat;
X = elephant;
X = lion.
?- color(Color).
Color = red;
Color = blue;
Color = green;
Color = yellow.

Activity 2: Experimenting with Variables

Extend your facts.pl file with these country-city relationships:

cityInCountry(london, uk).
cityInCountry(manchester, uk).
cityInCountry(new_york, usa).
cityInCountry(los_angeles, usa).
cityInCountry(tokyo, japan).
cityInCountry(osaka, japan).

Tasks: Write queries to find:

  1. Which country London is in
  2. All cities in the UK
  3. All cities in Japan
  4. Which city is in which country (find all city-country pairs)
Hint

Use capital letters for variables (City, Country). Press semicolon (;) to get multiple answers.

Solution:
?- cityInCountry(london, Country).
Country = uk.
?- cityInCountry(City, uk).
City = london;
City = manchester.
?- cityInCountry(City, japan).
City = tokyo;
City = osaka.
?- cityInCountry(City, Country).
City = london, Country = uk;
City = manchester, Country = uk;
City = new_york, Country = usa;
City = los_angeles, Country = usa;
City = tokyo, Country = japan;
City = osaka, Country = japan.

Note: Variables allow Prolog to find matching values for unknown parts of queries. This is powerful for searching knowledge bases.

Check Your Understanding: Declarative Programming Basics

Answer
  • [1 mark] Declarative programming is a programming paradigm that focuses on what should be achieved rather than how to achieve it
  • [1 mark] Instead of giving step-by-step instructions, we define facts, rules, and conditions, and the system figures out the solution automatically
  • [Additional] Examples include Prolog (for AI), SQL (for databases), and regular expressions (for pattern matching)
Answer
  • [1 mark] Declarative programming describes what should happen, while imperative programming specifies how to achieve the result
  • [1 mark] In declarative programming, control flow is abstracted away, while in imperative programming, step-by-step instructions control the flow
  • [1 mark] Declarative programming is used in AI, databases, and functional programming, while imperative programming is used in system software and game development
  • [Example] Prolog rule: grandparent(X, Y) :- parent(X, Z), parent(Z, Y). vs imperative: if (X is a parent of Z) AND (Z is a parent of Y) then return true
Answer
  • [1 mark] A fact is a simple statement that Prolog stores as "true"
  • [1 mark] Facts consist of a predicate (name) followed by arguments in parentheses, ending with a period (.)
  • [Example] capitalCity(paris). where capitalCity is the predicate and paris is the argument
Answer
  • [1 mark] A query starts with ?- followed by a predicate with arguments, ending with a period (.)
  • [1 mark] Prolog checks if the query matches any facts or rules in the knowledge base and returns true or false
  • [Examples] ?- capitalCity(paris). returns true, ?- capitalCity(london). returns false (if not in knowledge base)
Answer
  • [1 mark] Variables in Prolog start with a capital letter (e.g., City, Country)
  • [1 mark] They act as placeholders that can match any value in queries
  • [1 mark] When used in queries, Prolog finds all values that make the query true, returning them one by one (separated by semicolons)
  • [Example] ?- cityInCountry(City, germany). might return City = berlin; City = munich.
Answer
Advantages:
  • Easier to understand - no need to track step-by-step execution
  • More concise - fewer lines of code
  • Great for AI and knowledge-based systems
  • Automatic solution finding
Disadvantages:
  • Not suitable for all tasks (e.g., real-time applications)
  • Performance overhead due to complex logic processing
  • Less control over exact steps
  • Steeper learning curve

Advanced Prolog Concepts

Now that you've learned the basics of Prolog (facts, queries, and variables), it's time to explore more advanced concepts. Rules allow Prolog to infer new facts from existing facts, making the language much more powerful for representing complex relationships.

Writing Rules in Prolog

A rule defines a relationship between facts. It follows this structure: Head :- Body.

Rule Components

H
Head

The conclusion (what we are trying to prove)

:-
:- Operator

Means "IF" (read as "if" or "is true if")

,
Comma (,) Operator

Means "AND" (all conditions must be true)

Example: Grandparent Rule

% Rule: G is grandparent of S if G is parent of P AND P is parent of S
grandparent(G, S) :-
    parent(G, P),
    parent(P, S).

This means: "A grandparent (G) is someone who is a parent of (P), and (P) is a parent of (S)."

Logical Relationships in Rules

Prolog Rules and Backtracking Simulation

% Family facts
parent(john, mary).
parent(john, tom).
parent(mary, susan).
parent(mary, david).
parent(tom, emma).

% Sibling rule: A and B are siblings if they share same parent P, but A ≠ B
sibling(A, B) :-
    parent(P, A),
    parent(P, B),
    \+(A = B).
Query: Find all siblings of mary
?- sibling(mary, X).
X = tom;
(no more solutions)

How backtracking works: When Prolog executes sibling(mary, X), it:

  1. Finds a parent of mary (john)
  2. Finds another child of john (tom)
  3. Checks if mary ≠ tom (true)
  4. Returns X = tom
  5. When asked for more solutions (;), it backtracks to find other children of john (none left)

Using Recursive Rules

In Prolog, recursion allows us to define relationships that extend multiple generations. Recursive rules refer to themselves.

Recursive Ancestor Rule

% Base case: X is ancestor of Y if X is parent of Y
ancestor(X, Y) :- parent(X, Y).

% Recursive case: X is ancestor of Y if X is parent of Z AND Z is ancestor of Y
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).

This means: "X is an ancestor of Y if X is a parent of Y, OR if X is a parent of Z and Z is an ancestor of Y." This recursive rule can find ancestors across any number of generations.

Understanding Backtracking

Prolog finds all possible answers by using backtracking. When a query has multiple solutions, Prolog returns them one at a time.

Backtracking Steps

  1. Find a fact that matches the query
  2. If no match is found, try another possibility
  3. If a rule is used, check if the conditions are true
  4. If a condition has multiple solutions, return one at a time
  5. When user presses semicolon (;), backtrack to find next solution

Example: Multiple Solutions

likes(john, pizza).
likes(john, burger).
likes(john, pasta).
?- likes(john, Food).
Food = pizza;
Food = burger;
Food = pasta.

Using Anonymous Variables (_)

Sometimes we don't care about some details in a query. We use _ (underscore) as an anonymous variable placeholder for values we want to ignore.

Anonymous Variable Example

ingredient(pizza, cheese, 200).
ingredient(pizza, tomato, 100).
ingredient(burger, beef, 150).
?- ingredient(pizza, Ingredient, _).
Ingredient = cheese;
Ingredient = tomato.

The _ ignores the third argument (quantity), so Prolog finds all ingredients for pizza without caring about their quantities.

Activity 3: Creating Family Rules

Create a Prolog knowledge base with these family relationships:

% Family facts
parent(alice, bob).
parent(alice, carol).
parent(bob, david).
parent(bob, eve).
parent(carol, frank).
parent(david, grace).

Tasks: Write Prolog rules for:

  1. grandparent/2: X is grandparent of Y if X is parent of Z and Z is parent of Y
  2. sibling/2: X and Y are siblings if they share the same parent and X ≠ Y
  3. ancestor/2: X is ancestor of Y if X is parent of Y OR X is parent of Z and Z is ancestor of Y (recursive)

Then write queries to:

  • Find all grandparents of grace
  • Find all siblings of bob
  • Find all ancestors of eve
Hint

Make sure parent-child relationships exist before writing the grandparent rule. Use \+ (X = Y) to prevent Prolog from returning a person as their own sibling.

Solution:
Prolog Rules
% Grandparent rule
grandparent(X, Y) :-
    parent(X, Z),
    parent(Z, Y).

% Sibling rule
sibling(X, Y) :-
    parent(P, X),
    parent(P, Y),
    \+(X = Y).

% Ancestor rule (recursive)
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).
Query Results
?- grandparent(X, grace).
X = alice;
X = bob.

Alice is grandparent (parent of bob who is parent of david who is parent of grace). Bob is also grandparent (parent of david who is parent of grace).

?- sibling(bob, X).
X = carol;
?- ancestor(X, eve).
X = bob;
X = alice.

Bob is parent (direct ancestor), Alice is grandparent (ancestor through recursion).

Activity 4: Backtracking and Anonymous Variables

Create a Prolog knowledge base for a restaurant menu:

dish(pizza, italian, 12.99, 450).
dish(pasta, italian, 10.50, 400).
dish(burger, american, 9.99, 600).
dish(sushi, japanese, 15.75, 350).
dish(curry, indian, 11.25, 500).

Tasks: Write queries using backtracking and anonymous variables to:

  1. Find all Italian dishes (ignore price and calories)
  2. Find all dishes under £11.00 (ignore cuisine and calories)
  3. Find all dishes and their prices (ignore cuisine and calories)
  4. Find cuisine types available (ignore dish name, price, and calories)
Hint

Use _ to ignore specific values in a query. Remember to use semicolon (;) to get all solutions through backtracking.

Solution:
?- dish(Dish, italian, _, _).
Dish = pizza;
Dish = pasta.

Anonymous variables ignore price and calories.

?- dish(Dish, _, Price, _), Price < 11.00.
Dish = pasta, Price = 10.50;
Dish = burger, Price = 9.99;
Dish = curry, Price = 11.25.

Note: curry is £11.25 which is NOT under £11.00. Actually only pasta and burger should match.

?- dish(Dish, _, Price, _).
Dish = pizza, Price = 12.99;
Dish = pasta, Price = 10.50;
Dish = burger, Price = 9.99;
Dish = sushi, Price = 15.75;
Dish = curry, Price = 11.25.
?- dish(_, Cuisine, _, _).
Cuisine = italian;
Cuisine = italian;
Cuisine = american;
Cuisine = japanese;
Cuisine = indian.

To get unique cuisine types, we would need additional Prolog features like setof/3.

Key Learning: Anonymous variables (_) let us ignore values we don't care about. Backtracking finds all possible solutions when we press semicolon (;).

Check Your Understanding: Advanced Prolog Concepts

Answer
  • [1 mark] A rule defines a relationship between facts in Prolog
  • [1 mark] It follows the structure: Head :- Body.
  • [1 mark] The Head is the conclusion, :- means "IF", and Body contains conditions that must be true
  • [Example] grandparent(G, S) :- parent(G, P), parent(P, S). means "G is grandparent of S if G is parent of P AND P is parent of S"
Answer
  1. [1 mark] Prolog finds a fact that matches the query
  2. [1 mark] If no match is found, it tries another possibility (backtracks)
  3. [1 mark] If a rule is used, it checks if the conditions are true
  4. [1 mark] If a condition has multiple solutions, it returns them one at a time when user presses semicolon (;)
  5. [Example] For likes(john, Food). with multiple facts, Prolog returns Food = pizza; Food = burger; Food = pasta.
Answer
  • [1 mark] A recursive rule is a rule that refers to itself in its definition
  • [1 mark] It allows defining relationships that extend across multiple generations or levels
  • [1 mark] Useful for relationships like ancestors, where we need to check parent relationships repeatedly
  • [Example] ancestor(X, Y) :- parent(X, Y). ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
Answer
  • [1 mark] An anonymous variable is represented by underscore _ in Prolog
  • [1 mark] It's used when we don't care about a particular value in a query and want to ignore it
  • [Example] ingredient(pizza, Ingredient, _). ignores the quantity (third argument) while finding pizza ingredients
Answer
% X and Y are cousins if they have different parents who are siblings
cousin(X, Y) :-
    parent(P1, X),
    parent(P2, Y),
    sibling(P1, P2),
    \+(P1 = P2).

Explanation: X and Y are cousins if they have parents (P1 and P2) who are siblings, and P1 ≠ P2.

Answer
  • [1 mark] The comma (,) in a Prolog rule body means "AND" (logical conjunction)
  • [1 mark] All conditions separated by commas must be true for the rule to succeed
  • [Example] In grandparent(G, S) :- parent(G, P), parent(P, S). both parent(G, P) AND parent(P, S) must be true

Key Takeaways

  • Declarative programming focuses on what to achieve rather than how to achieve it, making it ideal for AI, databases, and logic systems
  • Prolog is a declarative logic programming language used for AI, expert systems, and knowledge representation
  • Facts are basic true statements in Prolog, ending with a period (.) - e.g., capitalCity(paris).
  • Queries ask questions about the knowledge base using ?- - e.g., ?- capitalCity(paris).
  • Variables start with capital letters and act as placeholders that can match any value
  • Rules define relationships between facts using the structure Head :- Body. where :- means "IF"
  • The comma (,) in rule bodies means "AND" - all conditions must be true for the rule to succeed
  • Backtracking is Prolog's method for finding multiple solutions by trying different possibilities
  • Recursive rules refer to themselves, allowing relationships across multiple generations (like ancestors)
  • Anonymous variables (_) ignore values we don't care about in queries
  • Declarative programming is concise and easier to understand for certain problems but less suitable for tasks requiring detailed control
  • Prolog is widely used in AI applications including expert systems, natural language processing, and automated reasoning

Question Bank

Marking Scheme & Answer
Declarative Programming:
  • Focuses on what should happen
  • Control flow is abstracted away
  • Examples: Prolog, SQL, regular expressions
  • Prolog example: grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
  • Used in AI, databases, functional programming
Imperative Programming:
  • Focuses on how to achieve the result
  • Uses step-by-step instructions
  • Examples: Python, Java, C++
  • Equivalent example: if (X is a parent of Z) AND (Z is a parent of Y) then return true
  • Used in system software, game development

Key Difference: Declarative programming states the desired outcome, while imperative programming provides specific instructions for achieving it.

Marking Scheme & Answer
Writing Facts:
  • Facts are simple statements that Prolog stores as "true"
  • Consist of a predicate followed by arguments in parentheses
  • End with a period (.)
  • Example: capitalCity(paris).
  • Multiple facts can be defined for the same predicate
Querying Facts:
  • Queries start with ?- followed by a predicate with arguments
  • End with a period (.)
  • Prolog checks if the query matches any facts in the knowledge base
  • Returns true if found, false if not
  • Example: ?- capitalCity(paris). returns true

Example Knowledge Base:
animal(dog).
animal(cat).
?- animal(dog).
returns true
?- animal(elephant). returns false (if not defined)

Marking Scheme & Answer
Variables in Prolog:
  • Start with capital letters (e.g., X, City, Country)
  • Act as placeholders that can match any value
  • Used in queries to find unknown values
  • Example: ?- cityInCountry(City, germany).
  • Prolog finds all values that make the query true
  • Multiple solutions returned separated by semicolons (;)
Backtracking in Prolog:
  1. Prolog finds first fact matching the query
  2. If no match, tries another possibility (backtracks)
  3. For rules, checks if conditions are true
  4. If multiple solutions exist, returns one at a time
  5. User presses semicolon (;) to get next solution
  6. Continues until no more solutions
Example:
likes(john, pizza).
likes(john, burger).
likes(john, pasta).
?- likes(john, Food).
Food = pizza; (first solution)
Food = burger; (backtrack for second)
Food = pasta. (backtrack for third)
Marking Scheme & Answer
% Grandparent rule: X is grandparent of Y if X is parent of Z and Z is parent of Y
grandparent(X, Y) :-
    parent(X, Z),
    parent(Z, Y).

% Sibling rule: X and Y are siblings if they share same parent and X ≠ Y
sibling(X, Y) :-
    parent(P, X),
    parent(P, Y),
    \+(X = Y).

% Ancestor rule (recursive): X is ancestor of Y if X is parent of Y OR
% X is parent of Z and Z is ancestor of Y
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).
Explanation:
  • Grandparent rule: Uses intermediate variable Z to connect grandparent to grandchild through a parent
  • Sibling rule: Checks that X and Y share a parent P, and ensures X ≠ Y using \+ (X = Y)
  • Ancestor rule: First clause handles direct parent, second clause is recursive for indirect ancestors
  • The recursive ancestor rule can find ancestors across any number of generations
Marking Scheme & Answer
Advantages:
  • Easier to understand - No need to track step-by-step execution; focus on what, not how
  • More concise - Fewer lines of code compared to imperative programs
  • Great for AI and knowledge-based systems - Prolog is ideal for expert systems, natural language processing, and automated reasoning
  • Automatic solution finding - System finds solutions based on defined facts and rules
  • Less error-prone for certain problem types - No need to manage control flow details
Disadvantages:
  • Not suitable for all tasks - Problems requiring detailed control (e.g., real-time applications, device drivers) are better with imperative languages
  • Performance overhead - Some declarative languages require complex logic processing and pattern matching
  • Less control - Can't specify exact steps for optimization or resource management
  • Steeper learning curve - Requires different thinking than traditional programming
  • Debugging can be challenging - Hard to trace execution flow in complex rule systems

Conclusion: Declarative programming is excellent for problems involving knowledge representation, logic, and search (like AI systems), but less suitable for problems requiring precise control over execution or hardware interaction.

Marking Scheme & Answer
Anonymous Variables (_):
  • Represented by underscore _
  • Used when we don't care about a particular value in a query
  • Each _ is treated as a different variable (can match different values)
  • Useful for ignoring certain arguments in predicates
Example:
ingredient(pizza, cheese, 200).
ingredient(pizza, tomato, 100).
?- ingredient(pizza, Ingredient, _).
Ingredient = cheese;
Ingredient = tomato.

Ignores quantity (third argument)

Recursion in Prolog:
  • Rules that refer to themselves
  • Used for relationships that extend across multiple levels
  • Requires a base case (simple case) and recursive case
  • Essential for problems like ancestor relationships, list processing
Example:
% Base case
ancestor(X, Y) :- parent(X, Y).
% Recursive case
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).

This finds ancestors across any number of generations.

Key Points:
  • Anonymous variables make queries cleaner when some information is irrelevant
  • Recursion allows Prolog to handle problems of unknown depth or size
  • Both features make Prolog powerful for symbolic computation and AI problems
  • Without recursion, we would need separate rules for parent, grandparent, great-grandparent, etc.
Marking Scheme & Answer
% ========== FACTS ==========

% Student facts: student(Name, StudentID, Year)
student(alice, s1001, 2).
student(bob, s1002, 1).
student(charlie, s1003, 3).
student(diana, s1004, 2).

% Course facts: course(Code, Name, Credits)
course(cs101, 'Intro to CS', 3).
course(cs201, 'Data Structures', 4).
course(cs301, 'AI Programming', 4).

% Enrollment facts: enrolled(StudentID, CourseCode, Grade)
enrolled(s1001, cs101, 85).
enrolled(s1001, cs201, 78).
enrolled(s1002, cs101, 92).
enrolled(s1003, cs301, 88).
enrolled(s1004, cs201, 95).

% ========== RULES ==========

% Rule 1: Student is in same year as another student
same_year(S1, S2) :-
    student(S1, _, Year),
    student(S2, _, Year),
    \+(S1 = S2).

% Rule 2: Student is taking a course
taking_course(StudentName, CourseName) :-
    student(StudentName, SID, _),
    enrolled(SID, CCode, _),
    course(CCode, CourseName, _).

% Rule 3: Student has high grade (>= 85)
high_achiever(StudentName) :-
    student(StudentName, SID, _),
    enrolled(SID, _, Grade),
    Grade >= 85.

% Rule 4: Students in same course
classmate(S1, S2, CourseName) :-
    student(S1, SID1, _),
    student(S2, SID2, _),
    \+(SID1 = SID2),
    enrolled(SID1, CCode, _),
    enrolled(SID2, CCode, _),
    course(CCode, CourseName, _).
Example Queries:
?- same_year(alice, X).
?- taking_course(alice, Course).
?- high_achiever(Student).
?- classmate(alice, Classmate, Course).
Key Features Demonstrated:
  • Facts for students, courses, and enrollments
  • Rules using variables and anonymous variables
  • Rules with arithmetic comparison (Grade >= 85)
  • Rules connecting different facts through common attributes
  • Use of \+ (X = Y) to ensure different entities
  • Practical real-world application of Prolog
Marking Scheme & Answer
Feature Prolog SQL
Primary Use Artificial Intelligence, logic programming, expert systems Database querying and manipulation
Programming Paradigm Logic programming (declarative) Query language (declarative)
Basic Structure Facts, rules, and queries Tables, rows, columns, and queries
Data Representation Predicates with arguments: parent(john, mary). Tables with rows: INSERT INTO parent VALUES ('john', 'mary');
Querying ?- parent(john, Child). SELECT child FROM parent WHERE parent='john';
Variables Start with capital letters: Child Not typically used in same way; use column names
Rules/Logic Can define complex rules: ancestor(X,Y) :- parent(X,Y). Limited to WHERE clauses and JOIN operations
Backtracking Built-in feature for finding multiple solutions Implicit in query execution; returns all matching rows
Recursion Supported natively for recursive relationships Limited support (WITH RECURSIVE in some SQL)
Typical Application Expert systems, natural language processing, theorem proving Data retrieval, reporting, business intelligence
Similarities:
  • Both are declarative languages - focus on what, not how
  • Both work with facts/data and allow querying
  • Both can represent relationships between entities
  • Both support pattern matching in queries
Differences:
  • Prolog has inference capabilities (rules), while SQL is primarily for data retrieval
  • Prolog supports recursive rules natively, SQL has limited recursion
  • SQL is optimized for large datasets, Prolog for symbolic reasoning
  • Prolog uses backtracking for search, SQL uses set operations
  • Prolog is Turing-complete (full programming language), SQL is a domain-specific query language

Conclusion: Both are declarative but serve different purposes - SQL for data management, Prolog for knowledge representation and reasoning.

Marking Scheme & Answer
Expert Systems

Prolog is ideal for building expert systems that mimic human expertise in specific domains (medical diagnosis, financial advice).

How:

Encode domain knowledge as facts and rules, then query for diagnoses or recommendations.

Natural Language Processing (NLP)

Prolog's pattern matching and grammar rules make it suitable for parsing and understanding natural language.

How:

Define grammar rules, parse sentences into syntactic structures, extract meaning.

Automated Reasoning & Theorem Proving

Prolog can prove theorems automatically by applying logical rules to axioms.

How:

Encode logical statements as facts, define inference rules, query for proofs.

Knowledge Representation

Prolog provides a natural way to represent complex knowledge with facts, rules, and relationships.

How:

Create knowledge bases for specific domains, enable reasoning over stored knowledge.

Specific AI Applications:
  • Chatbots and Virtual Assistants: Early chatbots like ELIZA used Prolog-like pattern matching for conversations
  • Game AI: Prolog can represent game rules and strategies (chess, puzzles)
  • Diagnostic Systems: Medical or technical diagnosis based on symptoms and rules
  • Planning Systems: Automatic planning of sequences of actions to achieve goals
  • Intelligent Tutoring Systems: Adaptive learning systems that provide personalized instruction

Why Prolog is Suitable for AI:

  • Declarative nature: Focus on knowledge rather than algorithms
  • Pattern matching: Essential for NLP and rule-based systems
  • Backtracking: Automatic search for solutions
  • Rule-based reasoning: Natural representation of expert knowledge
  • Symbolic computation: Works with symbols and relationships, not just numbers

Marking Scheme & Answer
% ========== FAMILY TREE FACTS ==========

% Gender facts
male(john).
male(bob).
male(david).
male(frank).
female(mary).
female(alice).
female(susan).
female(emma).

% Parent-child relationships
parent(john, bob).
parent(john, alice).
parent(mary, bob).
parent(mary, alice).
parent(bob, david).
parent(bob, susan).
parent(alice, frank).
parent(alice, emma).

% ========== FAMILY RELATIONSHIP RULES ==========

% Father: X is father of Y if X is male and X is parent of Y
father(X, Y) :- male(X), parent(X, Y).

% Mother: X is mother of Y if X is female and X is parent of Y
mother(X, Y) :- female(X), parent(X, Y).

% Grandparent rule (already defined in parent facts)
grandparent(X, Y) :-
    parent(X, Z),
    parent(Z, Y).

% Sibling rule
sibling(X, Y) :-
    parent(P, X),
    parent(P, Y),
    \+(X = Y).

% Aunt/Uncle: X is aunt/uncle of Y if X is sibling of Z and Z is parent of Y
aunt_uncle(X, Y) :-
    sibling(X, Z),
    parent(Z, Y).

% Ancestor rule (recursive)
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :-
    parent(X, Z),
    ancestor(Z, Y).

% Cousin: X and Y are cousins if they have parents who are siblings
cousin(X, Y) :-
    parent(P1, X),
    parent(P2, Y),
    sibling(P1, P2).
How the Program Works:
  1. Basic Facts: The program starts with simple facts about gender and parent-child relationships. These are the "ground truth" data.
  2. Simple Rules: Rules like father/2 and mother/2 combine gender and parent facts to define specific relationships.
  3. Intermediate Relationships: Rules like grandparent/2 and sibling/2 build on parent facts to define more complex relationships.
  4. Complex Relationships: Rules like aunt_uncle/2 and cousin/2 combine multiple simpler relationships.
  5. Recursive Relationships: The ancestor/2 rule uses recursion to find ancestors across any number of generations.
Example Queries and Results:
?- father(X, bob).
X = john.
?- sibling(alice, X).
X = bob.
?- grandparent(john, X).
X = david;
X = susan;
X = frank;
X = emma.
?- ancestor(mary, X).
X = bob;
X = alice;
X = david;
X = susan;
X = frank;
X = emma.
Key Learning Points:
  • Demonstrates hierarchical knowledge representation - simple facts build up to complex relationships
  • Shows rule-based inference - Prolog deduces new facts from existing ones
  • Illustrates recursive thinking - ancestor relationship defined in terms of itself
  • Exemplifies declarative programming - we define relationships, Prolog finds answers
  • Highlights Prolog's strength in symbolic AI - perfect for representing and reasoning about relationships