Prolog Examples: A Comprehensive Guide to Logic Programming
Prolog, short for Programming in Logic, is a declarative programming language widely used in artificial intelligence, computational linguistics, and database systems. Unlike imperative languages that specify how to solve a problem, Prolog focuses on describing what the problem is. This makes it particularly well-suited for tasks involving symbolic reasoning, knowledge representation, and automated theorem proving. This article provides a comprehensive overview of Prolog examples, illustrating its syntax, core concepts, and practical applications.
Understanding Prolog Fundamentals
Before diving into specific Prolog examples, it’s crucial to understand the fundamental building blocks of the language. Prolog programs consist of facts, rules, and queries. Facts represent basic truths about the world, rules define relationships between facts, and queries ask questions about those relationships.
Facts
Facts are statements that are unconditionally true. They are written as predicates followed by arguments, terminated by a period. For example:
parent(john, mary).
father(john, mary).
male(john).
female(mary).
These facts state that John is a parent of Mary, John is the father of Mary, John is male, and Mary is female.
Rules
Rules define relationships between facts. They consist of a head (the conclusion) and a body (the conditions). The head is true if the body is true. Rules are written using the `:-` operator, which means “if”. For example:
grandfather(X, Y) :- father(X, Z), parent(Z, Y).
This rule states that X is the grandfather of Y if X is the father of Z and Z is a parent of Y.
Queries
Queries are questions asked to the Prolog system. The system attempts to find facts and rules that satisfy the query. Queries are written in the same format as facts, but they are entered at the Prolog prompt. For example:
?- parent(john, mary).
This query asks if John is a parent of Mary. Prolog will respond with `true.` if the fact exists in the database.
Basic Prolog Examples
Let’s explore some basic Prolog examples to illustrate these concepts.
Family Relationships
Consider a simple family tree represented in Prolog. We can define facts for parent-child relationships and rules for other relationships like sibling, ancestor, etc.
parent(john, mary).
parent(john, peter).
parent(jane, mary).
parent(jane, peter).
male(john).
male(peter).
female(jane).
female(mary).
father(john, mary) :- male(john), parent(john, mary).
mother(jane, mary) :- female(jane), parent(jane, mary).
sibling(X, Y) :- parent(Z, X), parent(Z, Y), X = Y.
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
Now, we can query the system to find out family relationships:
?- sibling(mary, peter).
true.
?- grandparent(john, Y).
Y = mary ;
Y = peter.
?- ancestor(john, mary).
true.
?- ancestor(john, sarah).
false.
These Prolog examples demonstrate how to define relationships and query the knowledge base.
List Processing
Prolog excels at list processing. Lists are represented using square brackets `[]`. The empty list is represented as `[]`. The `.` operator is used to construct lists, where `.(Head, Tail)` represents a list with `Head` as the first element and `Tail` as the rest of the list. A more common notation is `[Head | Tail]`. Here are some list processing Prolog examples:
Membership
Checking if an element is a member of a list:
member(X, [X | _]).
member(X, [_ | T]) :- member(X, T).
Example usage:
?- member(b, [a, b, c]).
true.
?- member(d, [a, b, c]).
false.
Appending Lists
Appending two lists:
append([], L, L).
append([H | T1], L, [H | T2]) :- append(T1, L, T2).
Example usage:
?- append([a, b], [c, d], L).
L = [a, b, c, d].
Reversing a List
Reversing a list:
reverse(L, R) :- reverse_helper(L, [], R).
reverse_helper([], Acc, Acc).
reverse_helper([H | T], Acc, R) :- reverse_helper(T, [H | Acc], R).
Example usage:
?- reverse([a, b, c], R).
R = [c, b, a].
These Prolog examples showcase the power and flexibility of list processing in Prolog.
Intermediate Prolog Examples
Moving beyond the basics, let’s consider more complex Prolog examples.
Graph Traversal
Prolog is often used for graph traversal problems. Consider a graph represented as a set of edges:
edge(a, b).
edge(b, c).
edge(c, d).
edge(a, e).
edge(e, f).
We can define a predicate to find a path between two nodes:
path(X, Y) :- edge(X, Y).
path(X, Y) :- edge(X, Z), path(Z, Y).
Example usage:
?- path(a, d).
true.
?- path(a, c).
true.
?- path(a, g).
false.
This Prolog example demonstrates how to perform graph traversal using Prolog’s backtracking capabilities.
Solving Sudoku
Sudoku is a classic constraint satisfaction problem that can be elegantly solved using Prolog. This involves defining the Sudoku grid as a list of variables and then defining constraints that ensure each row, column, and 3×3 block contains the digits 1-9 without repetition. [See also: Constraint Logic Programming]
A simplified example focuses on constraint definition:
valid_sudoku(Rows) :-
all_distinct(Rows), % Each row has distinct elements
transpose(Rows, Columns), % Transpose the rows to get columns
all_distinct(Columns), % Each column has distinct elements
blocks(Rows, Blocks), % Extract 3x3 blocks
all_distinct(Blocks). % Each block has distinct elements
all_distinct([]).
all_distinct([Row|Rest]) :-
distinct_elements(Row),
all_distinct(Rest).
distinct_elements([]).
distinct_elements([X|Rest]) :-
+ member(X, Rest),
distinct_elements(Rest).
transpose([], []).
transpose([[]|_], []).
transpose(Matrix, [FirstColumn|RestColumns]) :-
first_column(Matrix, FirstColumn, RemainingMatrix),
transpose(RemainingMatrix, RestColumns).
first_column([], [], []).
first_column([[H|T]|Rows], [H|FirstColumn], [T|RestRows]) :-
first_column(Rows, FirstColumn, RestRows).
blocks(Rows, Blocks) :-
blocks_helper(Rows, Blocks).
blocks_helper([], []).
blocks_helper([R1,R2,R3|RestRows], [B1,B2,B3|RestBlocks]) :-
block(R1, R2, R3, B1, B2, B3),
blocks_helper(RestRows, RestBlocks).
block([A1,A2,A3|R1], [B1,B2,B3|R2], [C1,C2,C3|R3], [A1,A2,A3], [B1,B2,B3], [C1,C2,C3]).
This Prolog example illustrates constraint satisfaction problems and utilizes built-in predicates for list manipulation.
Advanced Prolog Examples
For more advanced applications, Prolog can be used for tasks such as expert systems and natural language processing.
Expert Systems
An expert system is a computer program that emulates the decision-making ability of a human expert. Prolog’s rule-based nature makes it ideal for building expert systems. Consider a simple medical diagnosis system:
symptom(john, fever).
symptom(john, cough).
symptom(mary, headache).
symptom(mary, fatigue).
disease(flu) :- symptom(_, fever), symptom(_, cough).
disease(cold) :- symptom(_, headache), symptom(_, fatigue).
diagnose(Patient, Disease) :- symptom(Patient, _), disease(Disease).
Example usage:
?- diagnose(john, Disease).
Disease = flu.
?- diagnose(mary, Disease).
Disease = cold.
This Prolog example shows how to build a simple expert system using Prolog’s rule-based reasoning.
Natural Language Processing
Prolog is widely used in natural language processing (NLP) due to its ability to handle symbolic data and perform logical inference. Consider a simple grammar:
sentence(S) --> noun_phrase(NP), verb_phrase(VP), {S = sentence(NP, VP)}.
noun_phrase(NP) --> determiner(Det), noun(N), {NP = noun_phrase(Det, N)}.
verb_phrase(VP) --> verb(V), noun_phrase(NP), {VP = verb_phrase(V, NP)}.
determiner(the) --> [the].
noun(cat) --> [cat].
noun(dog) --> [dog].
verb(chases) --> [chases].
Example usage:
?- phrase(sentence(S), [the, cat, chases, the, dog]).
S = sentence(noun_phrase(the, cat), verb_phrase(chases, noun_phrase(the, dog))).
This Prolog example demonstrates how to parse simple sentences using Prolog’s Definite Clause Grammars (DCGs).
Conclusion
These Prolog examples provide a glimpse into the power and versatility of logic programming. From basic facts and rules to advanced applications like expert systems and natural language processing, Prolog offers a unique and powerful approach to solving complex problems. Understanding these examples is a great starting point for mastering Prolog and leveraging its capabilities in various domains. Further exploration of Prolog examples and practice will solidify your understanding and enable you to tackle more challenging tasks. The declarative nature of Prolog allows programmers to focus on what needs to be accomplished rather than how, leading to more concise and maintainable code. Whether you’re working on AI, data analysis, or system verification, Prolog offers a compelling toolkit for logic-based problem-solving. Remember to consult official documentation and online resources for more in-depth knowledge. [See also: Prolog Syntax Guide]