gprolog 1.3.0

Version of implementation GNU Prolog of programming language Prolog

An official release of GNU Prolog, released on January 4th, 2007.

Changes:

Ports to:

  • ix86/darwin (Mac OS X)
  • improve Win32 ports (cygwin, MinGW, MSVC 6.0 and 2005 Express Edition) (MSVC port uses MinGW as.exe instead of nasm.exe — named mingw-as.exe provided in the setup.exe)
  • fix problems in various ports: alpha/linux, powerpc/darwin (Mac OS X), sparc/solaris, ix86/OpenBSD

Bugfixes:

  • fix a bug with Prolog floats in x86_64/linux (bad stack alignment)
  • fix various problems when compiling with gcc 4 (gcc 4.1.1)

New features and improvements:

  • change error messages emitted by the compiler to follow GNU standards
  • modify doc (mainly rename manual.xxx to gprolog.xxx)
  • add DESTDIR variable support in main Makefile for staged installs
  • add check target to main Makefile
  • rename call/2 to call_det/2
  • implement call/2-11 as will be defined in the next standard
  • emit .note.GNU-stack to mark the stack as no executable in x86_any.c, x86_64_any.c and powerpc_any.c
  • change the way objects are found (obj_chain.c) using gcc ctors
  • use Doug Lea malloc for OpenBSD (problem with malloc using mmap)

Examples:

Hello, World! - Prolog (49):

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 - Prolog (240):

Conditional branching in Prolog is done via ; and , predicates, which correspond to “or” and “and” logical operations. Evaluation starts with first branch (for example, check for A being 0 in line 3); all predicates separated with , are evaluated in row; if all of them evaluate to true, the whole program evaluates to true as well (and further evaluation stops), otherwise the next branch is evaluated.

read_integer is GNU Prolog extension, other implementations don’t have this predicate built-in.

q :- write('A = '),
     read_integer(A),
     (   A = 0, write('Not a quadratic equation');
         write('B = '),
         read_integer(B),
         write('C = '),
         read_integer(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(')')
         )
     ).

q.

Fibonacci numbers - Prolog (239):

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.

Factorial - Prolog (238):

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).

Quadratic equation - Prolog (241):

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(')')
         )
     ).