SLP-PROLOG LANGUAGE REFERENCE

ISO Core Subset Logic Programming - PROLOG

Phone: 555-0330

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:

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

  1. Dial 555-0330 to connect to SLP-PROLOG
  2. At the ?- prompt, enter facts directly (one per line):
likes(mary, pizza).
likes(john, pizza).
  1. 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"

"Undefined procedure"

"Arguments are not sufficiently instantiated"

% 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"

Query Returns false Unexpectedly

  1. Check spelling of atoms and predicates
  2. Verify all required facts exist
  3. Test simpler queries to isolate the problem
  4. Check that rule variables are used consistently

Query Never Finishes

  1. Your program may have infinite recursion
  2. Press Ctrl+C to interrupt (implementation dependent)
  3. Review recursive rules for missing base cases
  4. 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:

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