]]> ]]>

GNU Prolog

Реализация языка программирования Prolog

GNU Prolog — компилятор языка Prolog, распространяющийся по лицензии GNU GPL. Производительность GNU Prolog сравнима с коммерческими компиляторами (по скорости совсем немного уступает SICStus Prolog).

Разработка GNU Prolog началась в январе 1996 года под названием Calypso. В марте 1999 года Calypso (beta 7) был переименован в gprolog 0.9.0.

Особенности GNU Prolog

Язык

  • соответствует стандарту ISO Prolog (целочисленная/плавающая арифметика, потоки, динамический код, исключения)
  • множество расширений (глобальные переменные, поддержка выражений DCG, поддержка сокетов, интерфейс операционной системы)
  • более 300 встроенных предикатов
  • отладчик и низкоуровневый WAM отладчик
  • возможность автозаполнения атомов при редактировании в интерактивном интерпретаторе
  • мощный двунаправленный интерфейс между Prolog и C

Компилятор

  • компилятор генерирует автономные исполняемые файлы, не требующие для выполнения отдельной среды
  • простой компилятор из командной строки, обрабатывающий большое количество файлов: файлы Prolog, C, WAM и другие
  • прямая генерация машинного кода в 15 раз быстрее, чем wamcc + gcc.
  • большинство неиспользуемых встроенных предикатов не линкуются (чтобы уменьшить размер исполняемых файлов)

Поддерживаемые платформы

  • ix86 / GNU/Linux
  • ix86 / Win32 использующий Cygwin
  • ix86 / Win32 использующий MinGW
  • ix86 / Win32 использующий MSVC++
  • ix86 / SCO
  • ix86 / Solaris
  • ix86 / FreeBSD
  • ix86 / OpenBSD
  • ix86 / NetBSD
  • ix86 / Darwin (Mac OS X)
  • x86_64 / GNU/Linux
  • PowerPC / GNU/Linux
  • PowerPC / Darwin (Mac OS X)
  • PowerPC / NetBSD
  • sparc / SunOS (4.1.3 or higher)
  • sparc / Solaris
  • sparc / NetBSD
  • alpha / GNU/Linux
  • alpha / OSF1
  • mips / irix

Примеры:

Hello, World!:

Пример для версий B-Prolog 7.4-3, ECLiPSe CLP 6.0 #188, Poplog 15.5 (Prolog), gprolog 1.3.0, swipl 5.6.x

Этот пример не требует загрузки фактов или правил. Запрос выполняется в интерактивном режиме, и его результат выглядит следующим образом:

Hello, World!
yes

Первая строка является собственно выводом предиката write, вторая — результат оценивания запроса.

Следует отметить, что замена одинарных кавычек на двойные выводит строку как массив ASCII-кодов отдельных символов:

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

yes

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

Факториал:

Пример для версий B-Prolog 7.4-3, gprolog 1.3.0, swipl 5.6.x

Как в GNU Prolog, так и в B-Prolog 12! не помещается в целочисленный тип данных, поэтому все значения после 11! неправильны. В SWI-Prolog переполнения не возникает.

| ?- [fact].

Результат для GNU Prolog: 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

Результат для B-Prolog: consulting::fact.pl

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

Числа Фибоначчи:

Пример для версий B-Prolog 7.4-3, gprolog 1.3.0, swipl 5.6.x

Пример почти идентичен примеру для Poplog Prolog, за исключением синтаксиса подключения файла.

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

Квадратное уравнение:

Пример для версий gprolog 1.3.0

read_integer — не стандартный предикат, а расширение GNU Prolog, поэтому этот пример не будет работать в других реализациях.

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

Квадратное уравнение:

Пример для версий B-Prolog 7.4-3, gprolog 1.3.0, swipl 5.6.x

Этот пример соответствует стандарту ISO Prolog и использует встроенный предикат read/1. Следует отметить, что при вводе термов этим способом после каждого терма следует ставить точку.

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

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам