SWI-Prolog

Implementation of programming language Prolog

SWI-Prolog (abbreviation from Sociaal-Wetenschappelijke Informatica, Social Science Informatics) is an open-source implementation of Prolog, and one of the most widely-used ones. Its kernel is licensed under GNU LGPL, the libraries are distributed under GNU GPL, with permission to use in proprietary systems.

SWI-Prolog implements part 1 of ISO Prolog standard, as well as Edinburgh Prolog standard and important parts of Quintus and SICStus Prolog. It is compatible with other implementations, including GNU Prolog.

SWI-Prolog is written in C, of standard C99. Thus, it is portable to lots of platforms, including all main ones, both on 32-bit and 64-bit hardware.

Examples:

Hello, World!:

Example for versions B-Prolog 7.4 #3, Poplog 15.5 (Prolog), gprolog 1.3.0, swipl 5.6.x

This example doesn’t need any facts or rules to be evaluated. The query is executed in interactive mode, and results in the following output:

Hello, World!
yes

First line is the actual output of write predicate, and second line is the result of query evaluation.

Note that replacing single-quotes with double-quotes makes Prolog output the string as an array of ASCII-codes of individual characters:

| ?- write("Hello, World!").
[72,101,108,108,111,44,32,87,111,114,108,100,33]

yes

write('Hello, World!'), nl.

Quadratic equation:

Example for versions B-Prolog 7.4, gprolog 1.3.0, swipl 5.6.x

This is an ISO Prolog example, using standard read/1 predicate for reading input. Note that when using read/1, you have to put full stop . after each value you input.

q :- write('A = '),
     read(A),
     (   A = 0, write('Not a quadratic equation');
         write('B = '),
         read(B),
         write('C = '),
         read(C),
         D is B*B-4*A*C,
         (   D = 0, write('x = '), X is -B/2/A, write(X);
             D > 0, write('x1 = '), X1 is (-B+sqrt(D))/2/A, write(X1), nl, write('x2 = '), X2 is (-B-sqrt(D))/2/A, write(X2);
             R is -B/2/A, I is abs(sqrt(-D)/2/A), 
             write('x1 = ('), write(R), write(', '), write(I), write(')'), nl,
             write('x1 = ('), write(R), write(', -'), write(I), write(')')
         )
     ).

Factorial:

Example for versions B-Prolog 7.4 #3, gprolog 1.3.0, swipl 5.6.x

Almost identical to Poplog Prolog example, except for the syntax of compiling a file (doesn’t have a - before file name). However, the results of execution depend on the implementation. SWI-Prolog handles large numbers just fine, while in GNU Prolog and B-Prolog 12! overflows the numeric data type, so all values after 11! are incorrect.

| ?- [fact].
compiling /home/nickolas/Desktop/progopedia/prolog/fact.pl for byte code…
/home/nickolas/Desktop/progopedia/prolog/fact.pl compiled, 3 lines read — 1372 bytes written, 5 ms

yes
| ?- fact(16,X).
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = -57869312
13! = -215430144
14! = 205203456
15! = -143173632
16! = -143294464

X = -143294464 ?`

% fact.pl
fact(X, F) :- 
    ( X=0, F=1; 
      Y is X-1, fact(Y, Z), F is X*Z), 
    write(X), write('! = '), write(F), nl.

% interactive
[fact].
fact(16,X).

Fibonacci numbers:

Example for versions B-Prolog 7.4 #3, gprolog 1.3.0, swipl 5.6.x

Once again, the example is almost identical to Poplog Prolog one, except for the syntax of compiling/consulting a file.

% fibonacci.pl
:- dynamic(stored/1).

memo(Goal) :-
    stored(Goal) -> true;
    Goal, assertz(stored(Goal)).

fib(1,1) :- !, write('1, ').
fib(2,1) :- !, write('1, ').
fib(N,F) :-
    N1 is N-1, memo(fib(N1,F1)), 
    N2 is N-2, memo(fib(N2,F2)), 
    F is F1 + F2,
    write(F), write(', ').

% interactive
[fibonacci].
fib(16,X), write('...'), nl.