Introduction
Welcome to SLP-PROLOG, the Logic Programming Language from Emulator.ca Systems.
In 1972, Alain Colmerauer and Philippe Roussel at the University of Aix-Marseille created a new kind of programming language. Instead of telling the computer how to solve a problem step by step, you could describe what the solution should look like, and let the computer figure out the rest. They called this language Prolog -- "Programming in Logic."
This was a profound shift in thinking about computation. Rather than writing procedures, you write facts and rules. Rather than looping through data, you ask questions and let Prolog search for answers. For problems involving relationships, pattern matching, and symbolic reasoning, Prolog offers an elegance that conventional languages cannot match.
SLP-PROLOG brings this distinctive approach to logic programming to your EC-TTY terminal. Whether you are exploring artificial intelligence concepts, building expert systems, or simply learning a different way to think about problems, Prolog will expand your understanding of what programming can be.
What Makes Prolog Different
In most programming languages, you write instructions: "First do this, then do that." In Prolog, you state facts: "Alex is Jamie's parent." You define rules: "X is a grandparent of Y if X is a parent of someone who is a parent of Y." Then you ask questions: "Who are Alex's grandchildren?"
Prolog searches through your facts and rules, trying different possibilities until it finds answers that satisfy your query. If there are multiple answers, it can find them all. This declarative style makes Prolog especially well-suited for:
- Database queries and relational reasoning - Ask questions about complex relationships
- Natural language processing - Parse and understand sentence structure
- Expert systems and decision support - Encode knowledge as rules, let Prolog draw conclusions
- Symbolic computation and theorem proving - Manipulate logical expressions
- Puzzles and constraint satisfaction problems - Describe the solution, let Prolog find it
Why Learn Prolog?
Even if you never use Prolog professionally, learning it will change how you think about programming. You will start to see problems differently - not as sequences of steps, but as relationships to be described. This perspective is valuable in any language.
And Prolog is fun. There is something deeply satisfying about describing a problem correctly and watching the computer deduce the answer. When your first recursive rule produces dozens of correct results from a handful of facts, you will understand why logicians and AI researchers fell in love with this language.
SLP-PROLOG aims toward ISO Prolog compatibility but currently implements a subset of the standard. See the "Current Implementation" section for details on what is supported. Programs may need adaptation when moving to other Prolog systems.
Current Implementation
SLP-PROLOG implements a core subset of Prolog suitable for learning logic programming fundamentals. This section clarifies what is currently supported.
SLP-PROLOG is a teaching implementation. Many standard Prolog predicates documented in textbooks are not yet available. Programs from other Prolog systems may need adaptation.
What Works
| Feature | Status | Notes |
|---|---|---|
| Facts and rules | Full support | Define with fact. or head :- body. |
| Queries | Full support | Interactive queries with ?- prompt |
| Unification | Full support | X = Y and pattern matching |
| Backtracking | Full support | All solutions enumerated automatically |
| Lists | Full support | [a, b, c] and `[H |
| Basic arithmetic | Supported | X is Expr with +, -, *, / |
| Conjunction | Supported | , (comma) for AND |
| Variables | Full support | Uppercase or _ for anonymous |
Not Yet Implemented
| Feature | Status | Workaround |
|---|---|---|
Cut (!) |
Not available | Restructure rules declaratively |
Comparison (<, >, =<, >=) |
Not available | None currently |
Inequality (\=, \==) |
Not available | None currently |
assert/1, retract/1 |
Not available | Enter facts directly at prompt |
Built-in append, member, length |
Not available | Define them yourself (examples below) |
I/O (write, nl, read) |
Not available | Results shown via query responses |
Type checking (atom, number, etc.) |
Not available | None currently |
findall, bagof, setof |
Not available | Backtracking shows all solutions |
Integer division (//), mod |
Not available | Use / for division |
Defining Common Predicates
Since member and append are not built-in, define them yourself:
member(X, [X|_]).
member(X, [_|T]) :- member(X, T).
append([], L, L).
append([H|T], L, [H|R]) :- append(T, L, R).
Once defined, they work as expected for queries.
Quick Start
This section will have you writing your first Prolog program within minutes of connecting.
Your First Session
- Dial
555-0330to connect to SLP-PROLOG - At the
?-prompt, enter facts directly (one per line):
likes(mary, pizza).
likes(john, pizza).
- Now ask a question -- who likes pizza?
?- likes(Who, pizza).
Who = mary.
Who = john.
Congratulations! You have just created a small database and queried it. Prolog found all the answers that matched your question.
Try These Examples
Family relationships:
parent(tom, mary).
parent(tom, james).
parent(mary, ann).
?- parent(tom, X).
X = mary.
X = james.
Simple arithmetic:
?- X is 3 + 4.
X = 7.
?- X is 10 * 5.
X = 50.
List operations (define predicates first):
member(X, [X|_]).
member(X, [_|T]) :- member(X, T).
append([], L, L).
append([H|T], L, [H|R]) :- append(T, L, R).
?- member(X, [red, green, blue]).
X = red.
X = green.
X = blue.
?- append([a,b], [c,d], Result).
Result = [a, b, c, d].
Every statement in Prolog must end with a period (.). Forgetting the period is the most common beginner mistake.
Getting Connected
Dial into the Prolog backend using your modem:
ATDT555-0330
After connection, the Prolog prompt appears:
CODE_FENCE_0
Use a monospaced terminal font and enable local echo if your modem or terminal software does not provide it.
Facts & Rules
Facts declare true statements about the world. Rules define relationships using :- (if) with a body of goals.
CODE_FENCE_0
Predicates and atoms begin with lowercase letters. Variables begin with uppercase letters or underscore.
| Form | Meaning |
|---|---|
atom |
Lowercase identifier, e.g., parent |
Variable |
Uppercase identifier, e.g., X, Person |
Functor(Args) |
Predicate with arguments, e.g., parent(alex, jamie) |
Queries
Queries ask Prolog to satisfy goals. Multiple answers are found through backtracking and displayed in sequence.
CODE_FENCE_0
CODE_FENCE_0
Queries must end with a period (.). All solutions are computed and displayed in sequence. If no solutions exist, false. is returned.
Lists
Lists are written using brackets. The bar | separates the head from the tail. This is the preferred ISO core subset representation.
CODE_FENCE_0
CODE_FENCE_0
CODE_FENCE_0
Arithmetic with is
Arithmetic is performed with is, which evaluates the right-hand side and unifies the result with the left-hand side.
CODE_FENCE_0
is requires the right-hand side to be fully instantiated. Use it after variables are bound by earlier goals.
Backtracking
Prolog searches for solutions depth-first. When a goal fails, it backtracks to the last choice-point and tries the next alternative.
CODE_FENCE_0
CODE_FENCE_0
The cut operator (!) is not yet implemented in SLP-PROLOG. This is actually beneficial for learning, as it encourages declarative thinking. When cut becomes available, use it sparingly - prefer declarative formulations when possible.
Implementation Summary
| Category | Support |
|---|---|
| Facts & Rules | Full support - Define facts and rules with :- |
| Queries | Full support - Interactive with all solutions displayed |
| Lists | Full support - Bracket notation and `[H |
| Unification | Full support - = and pattern matching |
| Backtracking | Full support - Depth-first search with choice-points |
| Arithmetic | Partial - is with +, -, *, / only |
| Comparison | Not yet - <, >, =<, >=, \= planned |
| Built-in predicates | Limited - Define member, append yourself |
Tips for Beginners
Learning Prolog requires thinking differently about programming. These tips will help you develop good habits from the start.
Think Declaratively
Instead of asking "What steps do I need to perform?", ask "What relationships exist?" and "What would a correct answer look like?"
% Procedural thinking (wrong approach):
% "Loop through the list, check each element..."
% Declarative thinking (Prolog way):
member(X, [X|_]). % X is a member if it's the head
member(X, [_|T]) :- member(X, T). % or if it's in the tail
Start with Facts
Before writing complex rules, build a solid foundation of facts. Test your facts with simple queries before adding rules that use them.
% Start here:
employee(alice, accounting, 50000).
employee(bob, engineering, 65000).
employee(carol, engineering, 70000).
% Test with simple queries:
?- employee(alice, Dept, _).
Dept = accounting.
% Then add rules:
department_employee(Dept, Name) :- employee(Name, Dept, _).
Use the Anonymous Variable
The underscore _ means "I don't care about this value." Use it to ignore parts of structures you don't need.
% Good: clearly shows we only care about the name
parent_name(Name) :- parent(Name, _).
% Wasteful: Child is never used
parent_name(Name) :- parent(Name, Child).
Name Variables Meaningfully
Variable names should describe what they represent. This makes your code readable and helps catch errors.
% Clear:
grandparent(Grandparent, Grandchild) :-
parent(Grandparent, Parent),
parent(Parent, Grandchild).
% Confusing:
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
Watch Your Recursion
Recursive rules must have a base case that stops the recursion. Without it, Prolog will search forever.
% CORRECT: Base case comes first
ancestor(X, Y) :- parent(X, Y). % Base case
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y). % Recursive case
% WRONG: No base case - infinite loop
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
Test Incrementally
Build your program piece by piece, testing each part before adding more. When something goes wrong, you will know exactly where to look.
If a query returns false unexpectedly, try simpler queries to isolate the problem. Often a typo in a fact or a missing base case is the culprit.
Solving Problems with Prolog
Once you understand the basics, Prolog becomes a powerful tool for solving real problems. Here are some patterns that demonstrate Prolog's strengths.
Family Tree Example
Build a complete family knowledge base:
% Facts - the basic family data
parent(alice, bob).
parent(alice, carol).
parent(bob, dave).
parent(bob, eve).
parent(carol, frank).
female(alice).
female(carol).
female(eve).
male(bob).
male(dave).
male(frank).
% Rules - derived relationships
mother(X, Y) :- parent(X, Y), female(X).
father(X, Y) :- parent(X, Y), male(X).
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
grandmother(X, Y) :- grandparent(X, Y), female(X).
Now ask questions:
?- grandmother(X, dave).
X = alice.
?- grandparent(alice, X).
X = dave.
X = eve.
X = frank.
A full sibling rule would require inequality (X \= Y) to prevent someone from being their own sibling. Since this operator is not yet implemented, such rules cannot be expressed in the current subset.
List Processing
Prolog excels at recursive list manipulation. First, define the basic predicates:
% Sum all elements in a list
sum([], 0).
sum([H|T], S) :- sum(T, Rest), S is H + Rest.
% Find the last element
last([X], X).
last([_|T], X) :- last(T, X).
Example queries:
?- sum([1, 2, 3, 4], Total).
Total = 10.
?- last([a, b, c], X).
X = c.
Predicates like count_positive that need comparison operators (>, <, =<, >=) cannot be implemented in the current subset. These operators are planned for future versions.
Classic Puzzle: Who Owns the Fish?
Prolog shines at logic puzzles. Here is a simplified version using only unification:
% Define possible values
color(red). color(blue). color(green).
pet(dog). pet(cat). pet(bird).
% Solve: Red house has dog, blue house has bird
% GreenPet must be the remaining pet (cat)
solve(RedPet, BluePet, GreenPet) :-
RedPet = dog,
BluePet = bird,
GreenPet = cat.
More complex puzzle solutions that require inequality constraints (\=) to eliminate duplicates are not currently supported. The example above uses direct assignment for simplicity.
For constraint puzzles: define the possible values, then express each constraint as a rule. Prolog finds assignments that satisfy all constraints simultaneously.
Built-in Predicates Reference
This section documents ISO Prolog core predicates. Note: SLP-PROLOG currently implements a subset of these. See the "Current Implementation" section for what is available.
Legend: Supported = works now | Planned = not yet implemented
Control Predicates
| Predicate | Description | Status |
|---|---|---|
true |
Always succeeds | Planned |
false or fail |
Always fails | Planned |
! |
Cut - commits to current choice, prevents backtracking | Planned |
, |
Conjunction - both goals must succeed | Supported |
; |
Disjunction - either goal may succeed | Planned |
-> |
If-then (used with ; for if-then-else) |
Planned |
call(Goal) |
Calls Goal as a goal | Planned |
Comparison Predicates
| Predicate | Description | Status |
|---|---|---|
X = Y |
Unification - X and Y can be made identical | Supported |
X \= Y |
Not unifiable - X and Y cannot unify | Planned |
X == Y |
Identical - X and Y are already identical | Planned |
X \== Y |
Not identical | Planned |
X @< Y |
Term X precedes Y in standard order | Planned |
X @> Y |
Term X follows Y in standard order | Planned |
X @=< Y |
X precedes or equals Y | Planned |
X @>= Y |
X follows or equals Y | Planned |
Arithmetic Predicates
| Predicate | Description | Status |
|---|---|---|
X is Expr |
Evaluate Expr and unify with X | Supported |
X < Y |
Arithmetic less than | Planned |
X > Y |
Arithmetic greater than | Planned |
X =< Y |
Arithmetic less than or equal | Planned |
X >= Y |
Arithmetic greater than or equal | Planned |
X =:= Y |
Arithmetic equality | Planned |
X =\= Y |
Arithmetic inequality | Planned |
Arithmetic Operators
| Operator | Description | Status |
|---|---|---|
+ |
Addition | Supported |
- |
Subtraction | Supported |
* |
Multiplication | Supported |
/ |
Division (floating point) | Supported |
// |
Integer division | Planned |
mod |
Modulo (remainder) | Planned |
abs(X) |
Absolute value | Planned |
min(X,Y) |
Minimum of X and Y | Planned |
max(X,Y) |
Maximum of X and Y | Planned |
List Predicates
These predicates are not built-in. You must define member and append yourself (see Quick Start section). List syntax [H|T] is fully supported for writing your own list predicates.
| Predicate | Description | Status |
|---|---|---|
append(L1, L2, L3) |
L3 is L1 followed by L2 | User-defined |
length(List, N) |
List has N elements | Planned |
member(X, List) |
X is an element of List | User-defined |
reverse(L1, L2) |
L2 is L1 reversed | User-defined |
sort(L1, L2) |
L2 is L1 sorted, duplicates removed | Planned |
msort(L1, L2) |
L2 is L1 sorted, duplicates kept | Planned |
Type Checking Predicates
| Predicate | Description | Status |
|---|---|---|
atom(X) |
X is an atom | Planned |
number(X) |
X is a number | Planned |
integer(X) |
X is an integer | Planned |
float(X) |
X is a floating-point number | Planned |
compound(X) |
X is a compound term | Planned |
var(X) |
X is an unbound variable | Planned |
nonvar(X) |
X is not an unbound variable | Planned |
is_list(X) |
X is a proper list | Planned |
Term Manipulation
| Predicate | Description | Status |
|---|---|---|
functor(T, F, A) |
Term T has functor F and arity A | Planned |
arg(N, T, A) |
A is the Nth argument of term T | Planned |
=..(T, L) |
Univ - T =.. [Functor | Args] |
copy_term(T1, T2) |
T2 is a copy of T1 with fresh variables | Planned |
Database Predicates
Facts and rules are added by entering them directly at the prompt, not via assert/1. Dynamic database modification during queries is not yet supported.
| Predicate | Description | Status |
|---|---|---|
assert(Clause) |
Add clause to database | Planned |
asserta(Clause) |
Add clause at beginning | Planned |
assertz(Clause) |
Add clause at end | Planned |
retract(Clause) |
Remove first matching clause | Planned |
abolish(Pred/Arity) |
Remove all clauses for predicate | Planned |
Input/Output Predicates
| Predicate | Description | Status |
|---|---|---|
write(X) |
Write term X to output | Planned |
writeln(X) |
Write X followed by newline | Planned |
nl |
Write a newline | Planned |
read(X) |
Read a term from input | Planned |
Finding All Solutions
Since SLP-PROLOG automatically displays all solutions via backtracking, findall and related predicates are less critical. The system shows each binding as it finds them.
| Predicate | Description | Status |
|---|---|---|
findall(T, G, L) |
L is list of all T satisfying goal G | Planned |
bagof(T, G, L) |
Like findall but fails if no solutions | Planned |
setof(T, G, L) |
Like bagof but sorted, no duplicates | Planned |
Troubleshooting
Common Error Messages
"Syntax error"
- Check that your statement ends with a period (
.) - Ensure atoms start with lowercase, variables with uppercase
- Verify matching parentheses and brackets
"Undefined procedure"
- The predicate you called does not exist
- Check spelling and arity (number of arguments)
- Remember to define facts/rules before querying them
"Arguments are not sufficiently instantiated"
- Arithmetic with
isrequires the right side to be fully known - Bind variables before using them in arithmetic
% WRONG:
?- X is Y + 1.
ERROR: Arguments are not sufficiently instantiated
% CORRECT:
?- Y = 5, X is Y + 1.
X = 6, Y = 5.
"Out of local stack"
- Your program has infinite recursion
- Check that recursive rules have proper base cases
- Ensure base cases are listed before recursive cases
Query Returns false Unexpectedly
- Check spelling of atoms and predicates
- Verify all required facts exist
- Test simpler queries to isolate the problem
- Check that rule variables are used consistently
Query Never Finishes
- Your program may have infinite recursion
- Press
Ctrl+Cto interrupt (implementation dependent) - Review recursive rules for missing base cases
- Check for circular dependencies in rules
Connection Issues
| Problem | Solution |
|---|---|
| No carrier | Verify phone number: 555-0330 |
| Garbled text | Set terminal to 8N1, match baud rate |
| No echo | Enable local echo in terminal settings |
| Dropped connection | Dial again; sessions are not persistent |
Glossary
Arity
: The number of arguments a predicate takes. parent(tom, mary) has arity 2.
Atom
: A constant value written in lowercase, like red, tom, or hello_world.
Backtracking : Prolog's method of finding alternative solutions by undoing choices and trying different possibilities.
Binding : The association of a variable with a value. When X is bound to 5, X equals 5.
Choice Point : A place in the computation where alternative solutions may exist. Prolog returns here when backtracking.
Clause : A fact or a rule. Facts are clauses with no body; rules have a head and body.
Compound Term
: A term with a functor and arguments, like parent(tom, mary) or point(3, 4).
Conjuction
: Combining goals with comma (,) -- all must succeed.
Cut
: The ! operator, which commits to the current choice and prevents backtracking past it.
Declarative : Describing what is true, rather than how to compute it. Prolog is a declarative language.
Disjunction
: Combining goals with semicolon (;) -- at least one must succeed.
Fact
: A statement that is unconditionally true, like parent(tom, mary).
Functor
: The name of a compound term. In likes(mary, pizza), the functor is likes.
Goal : A query or subgoal that Prolog attempts to satisfy.
Ground Term : A term with no unbound variables.
Head
: The left side of a rule, before :-. The conclusion that follows if the body is true.
Horn Clause : A logical statement with at most one positive literal. Facts and rules in Prolog are Horn clauses.
Instantiated : A variable that has been bound to a value.
List
: An ordered sequence of elements, written as [a, b, c] or [Head|Tail].
Predicate
: A named relation defined by facts and rules. parent and grandparent are predicates.
Query
: A goal submitted at the ?- prompt to find solutions.
Rule
: A conditional statement of the form head :- body. The head is true if the body can be satisfied.
Unification : The process of making two terms identical by finding appropriate variable bindings.
Variable
: A placeholder for values, written starting with uppercase or underscore. Examples: X, Person, _temp.
Quick Reference Card
+------------------------------------------------------------------+
| SLP-PROLOG QUICK REFERENCE |
| Emulator.ca Systems |
+------------------------------------------------------------------+
| |
| DIAL: 555-0330 PROMPT: ?- |
| |
+------------------------------------------------------------------+
| CURRENTLY SUPPORTED |
| |
| fact. State a truth |
| head :- body. Define a rule |
| ?- goal. Ask a query |
| [a, b, c] List |
| [H|T] Head/Tail pattern |
| _ Anonymous variable |
| X is Expr Arithmetic evaluation |
| , AND (conjunction) |
| = Unify |
| + - Add/subtract * / Multiply/divide |
| |
+------------------------------------------------------------------+
| NOT YET IMPLEMENTED |
| |
| ; OR (disjunction) ! Cut |
| \= Not unifiable == Identical |
| < > Less/greater =< >= Less-equal/greater-equal |
| // Integer division mod Modulo |
| assert(Fact) (enter facts directly instead) |
| retract(Fact) write(X) nl read(X) |
| findall bagof setof |
| |
+------------------------------------------------------------------+
| DEFINE THESE YOURSELF |
| |
| member(X, [X|_]). |
| member(X, [_|T]) :- member(X, T). |
| |
| append([], L, L). |
| append([H|T], L, [H|R]) :- append(T, L, R). |
| |
+------------------------------------------------------------------+
| EXAMPLES |
| |
| ?- X is 3 + 4. X = 7. |
| ?- member(X, [a,b,c]). X = a ; X = b ; X = c |
| ?- append([1,2], [3,4], X). X = [1,2,3,4]. |
| |
+------------------------------------------------------------------+
Further Exploration
You have learned the fundamentals of logic programming, but this is just the beginning. Prolog has been used to build expert systems that diagnose diseases, parse natural language, prove mathematical theorems, and solve scheduling problems that would take humans weeks to work through.
Some directions to explore:
- Definite Clause Grammars (DCGs) - Prolog's elegant notation for parsing languages
- Meta-programming - Programs that manipulate other programs
- Constraint Logic Programming - Solving optimization problems declaratively
- Natural Language Processing - Parsing and understanding human sentences
The Prolog community has a long tradition of sharing knowledge. Seek out "The Art of Prolog" by Sterling and Shapiro, or "Clause and Effect" by Clocksin, for deeper exploration.
Happy querying!
SLP-PROLOG Language Reference Emulator.ca Systems - DIAL: 555-0330