Skip to main content
โšก Calmops

Introduction to Logic Programming

Introduction

Logic programming represents a fundamentally different approach to computation compared to imperative or functional programming. Rather than specifying how to solve a problem through explicit instructions, logic programming allows you to specify what the problem is, and let the system figure out how to solve it through logical inference.

In this article, we’ll explore the foundations of logic programming, understand how it differs from other programming paradigms, and see why it’s particularly powerful for certain classes of problems.

What is Logic Programming?

Logic programming is a programming paradigm based on formal logic. A logic program consists of:

  1. Facts: Statements that are unconditionally true
  2. Rules: Conditional statements that define relationships
  3. Queries: Questions we ask the system to answer

The system uses logical inference (typically resolution and unification) to derive answers from facts and rules.

Key Characteristics

Declarative Nature: You declare what is true, not how to compute it.

% Facts
parent(tom, bob).
parent(bob, ann).
parent(bob, pat).

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

% Query
?- grandparent(tom, ann).
% Answer: yes

Logical Inference: The system automatically derives conclusions from facts and rules.

Backtracking: When a solution path fails, the system automatically tries alternative paths.

Unification: Pattern matching mechanism that binds variables to values.

Logic Programming vs. Other Paradigms

Imperative Programming

Imperative: Specify step-by-step instructions

# Python (imperative)
def find_grandparent(person, target):
    for parent in get_parents(person):
        for grandparent in get_parents(parent):
            if grandparent == target:
                return True
    return False

Logic Programming: Specify relationships

% Prolog (declarative)
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

Functional Programming

Functional: Compute values through function composition

-- Haskell (functional)
grandparent x z = any (\y -> parent x y && parent y z) allPeople

Logic Programming: Query logical relationships

% Prolog (logical)
?- grandparent(tom, ann).

Key Differences

Aspect Imperative Functional Logic
Focus How to compute Function composition What is true
Control Explicit Implicit (recursion) Implicit (inference)
State Mutable Immutable Logical facts
Backtracking Manual Not typical Automatic
Queries Compute values Evaluate functions Prove statements

Core Concepts

Facts

Facts are the base knowledge in a logic program. They state unconditional truths.

% Simple facts
likes(mary, wine).
likes(john, mary).
likes(john, wine).

% Facts with multiple arguments
parent(tom, bob).
parent(bob, ann).
age(tom, 65).
age(bob, 40).

Rules

Rules define relationships and conditional truths. A rule has a head (conclusion) and a body (conditions).

% Rule: X is a parent of Z if X is a parent of Y and Y is a parent of Z
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

% Rule: X is a sibling of Y if they share a parent
sibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.

% Rule: X is an ancestor of Y if X is a parent of Y
ancestor(X, Y) :- parent(X, Y).

% Rule: X is an ancestor of Y if X is a parent of Z and Z is an ancestor of Y
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

Queries

Queries ask the system to find values that satisfy certain conditions.

% Simple query: Is tom a parent of bob?
?- parent(tom, bob).
% Answer: yes

% Query with variables: Who is a parent of bob?
?- parent(X, bob).
% Answer: X = tom

% Complex query: Who is a grandparent of ann?
?- grandparent(X, ann).
% Answer: X = tom

% Query with multiple solutions
?- likes(john, X).
% Answer: X = mary ;
%         X = wine

How Logic Programming Works

Unification

Unification is the process of making two terms identical by finding appropriate variable bindings.

% Unification examples
parent(tom, bob) unifies with parent(X, Y)
  โ†’ X = tom, Y = bob

parent(tom, bob) unifies with parent(tom, Z)
  โ†’ Z = bob

parent(tom, bob) does NOT unify with parent(X, X)
  โ†’ No solution (tom โ‰  bob)

Resolution and Backtracking

The system uses resolution to derive new facts from existing facts and rules. When a path fails, it backtracks and tries alternatives.

% Facts
parent(tom, bob).
parent(bob, ann).

% Rule
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

% Query: ?- grandparent(tom, ann).
% Resolution process:
% 1. Try to prove grandparent(tom, ann)
% 2. Use rule: need parent(tom, Y) and parent(Y, ann)
% 3. Find parent(tom, bob) โ†’ Y = bob
% 4. Find parent(bob, ann) โ†’ Success!
% Answer: yes

Backtracking Example

% Facts
likes(mary, wine).
likes(john, mary).
likes(john, wine).

% Query: ?- likes(john, X).
% Backtracking process:
% 1. Try first fact: likes(mary, wine) - doesn't match
% 2. Try second fact: likes(john, mary) - matches! X = mary
% 3. User asks for more solutions (;)
% 4. Backtrack and try next fact: likes(john, wine) - matches! X = wine
% 5. No more facts - done

Advantages of Logic Programming

1. Declarative Clarity

Express problems naturally as logical relationships rather than procedural steps.

% Clear and concise
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

2. Automatic Backtracking

The system automatically explores alternative solutions without explicit code.

% Find all solutions automatically
?- parent(X, Y).
% Returns all parent-child pairs

3. Separation of Logic and Control

The same program can be used for different purposes without modification.

% Same rule, different queries
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

?- grandparent(tom, ann).      % Who is grandparent of ann?
?- grandparent(tom, X).        % Who are tom's grandchildren?
?- grandparent(X, ann).        % Who is ann's grandparent?

4. Rapid Prototyping

Quickly express complex relationships and test them.

% Easy to add new facts and rules
?- assert(parent(ann, bob)).   % Add new fact
?- retract(parent(tom, bob)).  % Remove fact

Disadvantages and Limitations

1. Performance

Logic programming can be slower than imperative code due to search overhead.

% Inefficient: searches all possibilities
?- member(X, [1,2,3,4,5]), X > 3.
% Better: use built-in predicates
?- between(4, 5, X).

2. Counterintuitive Behavior

Backtracking and unification can produce unexpected results.

% Surprising: X unifies with X
?- X = X.
% Answer: yes (always true)

% Surprising: order matters
?- parent(X, bob), parent(tom, X).  % May be slower
?- parent(tom, X), parent(X, bob).  % May be faster

3. Limited Imperative Features

Some problems are naturally imperative and awkward in logic programming.

% Awkward: updating state
% Logic programming prefers immutable facts
% Imperative: state = state + 1
% Logic: new_state(S1, S2) :- S2 is S1 + 1

Applications of Logic Programming

1. Knowledge Representation

Store and query complex knowledge bases.

% Medical diagnosis system
symptom(patient1, fever).
symptom(patient1, cough).
disease(flu) :- symptom(X, fever), symptom(X, cough).

2. Expert Systems

Encode expert knowledge as rules.

% Legal reasoning
eligible_for_loan(Person) :-
    age(Person, Age), Age >= 18,
    income(Person, Income), Income >= 20000,
    credit_score(Person, Score), Score >= 600.

3. Natural Language Processing

Parse and understand natural language.

% Simple grammar
sentence --> noun_phrase, verb_phrase.
noun_phrase --> article, noun.
verb_phrase --> verb, noun_phrase.

4. Constraint Solving

Find solutions satisfying multiple constraints.

% Sudoku, scheduling, resource allocation
valid_schedule(Schedule) :-
    no_conflicts(Schedule),
    all_resources_available(Schedule),
    meets_constraints(Schedule).

5. Database Queries

Express complex queries naturally.

% Find all employees earning more than their manager
higher_paid(E1, E2) :-
    salary(E1, S1),
    salary(E2, S2),
    S1 > S2,
    manages(E2, E1).

Logic Programming Languages

Prolog

The most popular logic programming language, used in AI, databases, and expert systems.

% Prolog example
parent(tom, bob).
parent(bob, ann).
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
?- grandparent(tom, ann).

Datalog

A subset of Prolog used for databases and knowledge representation.

% Datalog example
parent(tom, bob).
parent(bob, ann).
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
?- grandparent(tom, ann).

Answer Set Programming (ASP)

Used for knowledge representation and reasoning.

% ASP example
parent(tom, bob).
parent(bob, ann).
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
#query grandparent(tom, ann).

Getting Started with Logic Programming

Basic Structure

% 1. Define facts
parent(tom, bob).
parent(bob, ann).

% 2. Define rules
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

% 3. Query the system
?- grandparent(tom, ann).

Common Patterns

Finding all solutions:

?- parent(X, Y).

Checking existence:

?- parent(tom, bob).

Conditional logic:

?- parent(X, Y), age(X, A), A > 50.

Glossary

  • Fact: An unconditional statement that is true
  • Rule: A conditional statement defining relationships
  • Query: A question asked to the system
  • Unification: Pattern matching that binds variables to values
  • Backtracking: Automatic exploration of alternative solutions
  • Resolution: Logical inference mechanism
  • Head: The conclusion part of a rule
  • Body: The conditions part of a rule
  • Predicate: A relation or property (e.g., parent/2)
  • Clause: A fact or rule
  • Atom: A basic logical element (e.g., tom, bob)
  • Variable: A placeholder that can be bound to values (e.g., X, Y)

Practice Problems

Problem 1: Family Relationships

Given the facts:

parent(tom, bob).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).

Write rules for:

  1. grandparent(X, Y) - X is a grandparent of Y
  2. ancestor(X, Y) - X is an ancestor of Y
  3. sibling(X, Y) - X and Y are siblings

Solution:

grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

sibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.

Problem 2: Queries

Using the facts and rules from Problem 1, answer:

  1. Who is a grandparent of jim?
  2. Who are the ancestors of jim?
  3. Who are the siblings of ann?

Solution:

?- grandparent(X, jim).
% Answer: X = bob

?- ancestor(X, jim).
% Answer: X = bob ; X = pat ; X = tom

?- sibling(ann, X).
% Answer: X = pat

Problem 3: Logic Programming Concepts

Explain what happens when the system processes this query:

?- parent(X, bob), parent(tom, X).

Solution: The system:

  1. Tries to find parent(X, bob) - finds X = tom
  2. Then tries parent(tom, tom) - fails
  3. Backtracks and tries next solution for parent(X, bob) - no more solutions
  4. Returns: no

Problem 4: Unification

Which of the following unify? For those that do, show the bindings.

  1. parent(tom, bob) with parent(X, Y)
  2. parent(tom, bob) with parent(tom, tom)
  3. parent(tom, bob) with parent(X, X)
  4. age(tom, 65) with age(X, Y)

Solution:

  1. โœ“ Unifies: X = tom, Y = bob
  2. โœ— Does not unify (bob โ‰  tom)
  3. โœ— Does not unify (tom โ‰  bob)
  4. โœ“ Unifies: X = tom, Y = 65

Online Platforms

Interactive Tools

  • “Programming in Prolog” by Clocksin & Mellish - Classic introduction
  • “The Art of Prolog” by Sterling & Shapiro - Advanced techniques
  • “Logic Programming: The 1st and 2nd Conferences” - Historical perspective
  • “Prolog and Natural Language Analysis” by Pereira & Shieber - NLP applications
  • “Constraint Logic Programming” by Jaffar & Maher - CLP overview

Academic Journals

Software Tools

Conclusion

Logic programming offers a unique and powerful approach to computation based on formal logic. By specifying what is true rather than how to compute it, logic programming enables:

  • Clearer expression of complex relationships
  • Automatic exploration of solution spaces
  • Rapid prototyping of knowledge-based systems
  • Flexible querying of logical facts and rules

While logic programming has limitations in performance and is not suitable for all problems, it excels in knowledge representation, expert systems, constraint solving, and natural language processing.

In the next article, we’ll explore the core building blocks of logic programs: facts, rules, and queries, and learn how to construct effective logic programs.


Next Article: Facts, Rules, and Queries

Previous Article: Proof by Cases

Comments