SWI-Prolog 3.2.6, Jan Wielemaker’s Prolog from the University of Amsterdam
(the January 1999 tree), running on my VAXstations under OpenVMS VAX 7.3:
Edinburgh syntax, the ISO-style built-ins of its day, modules, garbage
collection, DCG, assert/retract, format/2 and a standard library. It is
built with DEC C, installed for every user with an installer and an
uninstaller, and runs as an ordinary unprivileged user.
Claude Code did most of the hard work.
This one needed source changes: the 1999 sources have no VMS code at all.
Twelve small patches, about 140 changed lines, and the interesting part is
what a VAX does to a Prolog system that expects a Unix and an IEEE machine:
floating point overflow is a hardware fault, the C library’s getcwd answers
in VMS syntax, and the compiler’s optimiser breaks the interpreter’s recovery
from a stack overflow. The download folder has the upstream archive with its
hash, every patch with its reason, and a recipe to recreate the kit from
nothing.
Downloads, with SHA-256 sums in SHA256SUMS.TXT:
- PROLOG_VAX_326.BCK (2.9 MB): the
kit to install (a
BACKUPsaveset: the image, the boot state, the library, documentation, examples and the corresponding source). - PROLOG_INSTALL.COM, PROLOG_UNINSTALL.COM and PROLOG_SETUP.COM (each user runs it).
- README.TXT, the licence (LICENSE.TXT) and the provenance SOURCES.TXT.
- Source kit:
the upstream archive, the patches, the build, kit and test procedures and
RECREATE.md. - Examples: nine programs with their expected output and the test procedure.
- The file list of the saveset: PROLOG_VAX_326_LIST.LIS.
Licence
SWI-Prolog 3.2.6 is distributed under the SWI-Prolog LICENCE of 1990, a
GPL-like licence: copies must carry the licence, the complete source must
accompany or be offered with any executable, and derived works go under the
same terms. The full text is in LICENSE.TXT exactly as the author wrote it.
The kit therefore carries the complete corresponding source (the original
prolog-3_2_6.tgz, my patches and the build procedure) in [.SOURCE] and the
source kit above. The installer, uninstaller, setup procedure, patches and
examples are mine, under the same terms.
Which Prolog
I looked for the most capable, reasonably standard Prolog that builds on a VAX with DEC C 6.4 (no VAX C, no GCC here). Checked 14-OCT-2026:
| Version | Where | What I did |
|---|---|---|
| SWI-Prolog 3.2.6 (Jan Wielemaker, 1999) | DECUS VMSLT99A CD | built: portable C, malloc-based stacks with a stack shifter, no VMS code |
| C-Prolog 1.5 (Pereira, Damas and Byrd, Edinburgh, 1984) | Computer History Museum copy, SHA-256 6db9e4db921ba3758b4d7c0dbd40e5d5325fcb4b07e0f97265bd065bf534fdf5 | built with one changed line (below); installed on my machines, not in the download |
| SWI-Prolog 1.8.6 (1994) | DECUS LT93B CD | not built: its save/1 is GNU Emacs unexec(), which VMS has no equivalent of |
| GNU Prolog 1.0.0 and 1.2.8 | DECUS VMSLT99A, VMSLT02A | cannot be built: native code for mips, alpha, sparc, ix86 and powerpc only, and GCC global registers |
| YAP 4.2.0 | DECUS VMSLT99A | not built: sbrk/mmap/GCC-isms, no VMS code, more risk than SWI for nothing it adds here |
| Berkeley PLM (Aquarius, 1988) | DECUS LT91A | not built: its compiler is written in Quintus Prolog |
| SB-Prolog 2.3.2 (1988) | DECUS VAX88A1 | not built: LZW-compressed tar tapes and a csh installer |
prolog.exe (ENST Paris, 1988), a Pascal interpreter (York, 1983) | DECUS VAX90B1, VAX92B | not used: no source / far less than SWI |
SWI-Prolog 3.2.6 is the most capable of the ones that can be built; later SWI
needs 64-bit integers, GMP and a much newer C. There is also a Prolog on these
machines already, inside Poplog (PROLOG file.pl, from the Poplog kit); I
timed the two against each other below.
What was built
- Source:
prolog-3_2_6.tgz, 1,061,797 bytes, SHA-25615f02277431a735942a128e035bd2fde8a0004d9b8c4b8dd4c5c6aa01d3c1442. - Compiler: DEC C V6.4, a DCL procedure (
BUILD_PL.COM) instead of autoconf, a hand-writtenconfig.h;pl-wam.cis compiled/NOOPTIMIZE. - Measured on the VAXstation 4000/90 (71 MHz KA49), in a batch job, a clean
rebuild by the recipe in
RECREATE.md: unzip 24 seconds; 38 modules and 4 library modules, 0 failures, 6 minutes 23 seconds to compile, link 3 seconds, boot state (BOOT.PRC, 134 blocks) 5 seconds, library index 2 seconds; 6 minutes 33 seconds for the whole job.PL.EXEis 734 blocks. - The kit: 88 files, 5,101 blocks installed (the saveset is 2.9 MB). The lifecycle test (install, refuse a second install, uninstall with a changed file kept, reinstall, replace twice: 21 checks) takes 1 minute 48 seconds on the 4000/90 and each install about 15 seconds. On the VAXstation 4000/60 (about 2.3 times slower) the same lifecycle takes 2 minutes 53 seconds and the restore of the files about 28 seconds.
The source changes
SWI-Prolog’s src has code for Unix, MS-DOS, OS/2 and Windows; for VMS, only
config.sub. Twelve patches, each guarded for __VMS (the Unix build is
unchanged), most found by running something and looking at what came out:
- File names.
pl-os.ctreats names with a device or[dir]as absolute (12), does not expand$VARin a name (SYS$SCRATCH:would become the environment variableSYS$SYSDEVICE) (04), asksgetcwdfor the Unix form (06, the plain call answersSYS$DISK:[HOME.USER]), and makes temporary names,hasConsoleandokToExecwork (01).pl-main.cdoes not derive the home directory fromargv[0], which on VMS is a file specification (02).access_file(F, write)for a new file in an existing directory (09), and directory listings come back lower-cased without;versionso that'*.pl'findsLISTS.PL(10). shell/1. DCL says 1 for success; the Unix convention is 0 (11).- Floating point. The VAX has no infinity and no NaN. Overflow in
+ - * /is a hardware fault; the C library turns it into signal 10 and returning from the handler kills the process.pl-arith.crefuses an operation that would overflow, withevaluation_error(float_overflow), before executing it (07), and a float literal out of range is a syntax error (08). - Order of evaluation. Two places depended on the order in which a C
compiler evaluates arguments or a
PC + *PC++ + 1(03, 05): a Unix compiler and DEC C disagree. - The optimiser. With the DEC C 6.4 optimiser on,
pl-wam.cbuilds an interpreter that dies with an access violation when the local stack overflows instead of raisingresource_error. Compiled/NOOPTIMIZE, the stack overflow is caught three times in a row. I did not pin down which transformation does it.
Testing
- Examples, nine programs (
[.EXAMPLES], with expected output; the VMS-specific ones read and write files by VMS names and call DCL throughshell/1). As a freshUSER1over Telnet: 9 of 9 PASS in 54 seconds. LISTS, DCG, DERIV and EXPERT print byte for byte what the same sources print on Linux. - Robustness, in batch jobs with a
/CPUTIMEguard: a float overflow,1/0, an undefined procedure, an existence error on a file with a device that does not exist, and runaway recursion (resource_error(stack)) each caught, and each twice in a row, so the second occurrence is also an error and not a dead process. - Interactive as
USER1:X is 6*7, backtracking overappend/3with;,tell/consult/delete_fileonSYS$SCRATCH:names,shell('SHOW TIME'),halt.. - On the 4000/60, installed from the same saveset: the lifecycle 21 of 21;
as a fresh
USER1, the nine examples 9 of 9 PASS in 1 minute 57 seconds, and the float overflow,tell/consult/delete_fileonSYS$SCRATCH:andshellchecks pass.
Speed, and Poplog’s Prolog
One run of each, CPU time of a batch job on the 4000/90 (the machine had no
other user). SWI-Prolog 3.2.6 against the Prolog of Poplog 15.53 (the same
programs, PL file.pl against PROLOG file.pl); every program writes its
result to a file so I know it did the work. Both start-up times are included.
| Program | SWI-Prolog 3.2.6 | Poplog Prolog |
|---|---|---|
start-up only (:- halt.) | 0.8 s | 0.25 s |
| naive reverse of 30 elements, 100 times | 3.5 s | 0.83 s |
queens 6, all solutions (findall) | 1.05 s | 0.40 s |
| queens 8, all solutions (92) | 5.0 s | 0.84 s |
2000 x retract + assert of a counter | 1.7 s | stopped after 2.4 s: MEMORY LIMIT (pop_prolog_lim) EXCEEDED |
queens 4, 5, 6 counted with assert/retract | 1.1 s | did not finish in 5 minutes of CPU |
| queens 4..8 counted the same way, plus 100 naive reverses by recursion | 8.6 to 9.3 s | did not finish in 8 minutes of CPU |
On plain inference Poplog’s compiled Prolog is four to seven times faster than
SWI-Prolog’s interpreter (the two longer programs, with the start-up taken
off), and starts three times faster. Programs that keep state in the database
in a loop are another matter: Poplog’s default memory limit stops them or they
run for minutes, where SWI does them in seconds. I did not tune
pop_prolog_lim, so that last result is “with the defaults”, not “Poplog
cannot”.
On the 4000/60 (the slower machine) the same two show the same ratio: naive reverse 7.7 s against 2.0 s, queens 8 all solutions 11.7 s against 1.9 s, start-up 1.7 s against 0.5 s.
C-Prolog 1.5, the 1984 Edinburgh original, runs the DCG, DERIV and EXPERT
examples with the expected output (its top level adds a banner and a prompt);
the permutation count in LISTS did not finish in three minutes of CPU, and
QUEENS and ARITH do not match (** is not an operator in 1984).
What to know
- No bignums: integers are 32 bits and an overflowing result becomes a float; floats are VAX D_floating (about 17 digits, range 1.7E38, no infinity, no NaN).
- File names are VMS names or Unix-style names;
$is part of a name. pl-wam.cis compiled with the optimiser off: with it on, Compaq C 6.4 builds an interpreter that dies with an access violation when a stack overflows instead of raisingresource_error.- The image finds its library in
SYS$COMMON:[SYSLIB.PROLOG](compiled in);SWI_HOME_DIR(a Unix-style path) overrides it. - The kit is not relocatable and the source tree must be shallow: the compiler
makes
[.SRC.RC.CXX_REPOSITORY], and ODS-2 stops at eight directory levels (a build one level deeper failed, as%CC-E-CANTMKRPSTORY).
C-Prolog needed one line
The 1984 C-Prolog 1.5 already knew about VMS (makesys.com, #ifdef vms) and
compiled and linked unchanged in under a minute. Its bootstrap, though, gave a
syntax error on every clause and then looped at full speed on the end of its
input: the reader parses a number with sscanf(s, "%F", &d), the DEC C
run-time apparently reads %F as a single-precision float and fills only the
first four bytes of the eight-byte double, so every integer came out as a
float: the 76 in the clause that defines the op/3 built-in was stored as a
float, op/3 was never entered, no operator was ever defined, and :- op(...)
was a syntax error. %lf fixes it. (It was not
the optimiser; I tried that first.) It is installed beside SWI-Prolog on my
machines. Its source and binary are not in the download folder: the sources
carry a copyright notice and no licence, so I link the archive instead.
Installing and using
As SYSTEM, in a directory that holds the saveset and the two procedures
(no INSTALL, no startup-file edit, no privileged image, nothing outside
SYS$COMMON:[SYSLIB.PROLOG]):
$ @PROLOG_INSTALL ! install; "@PROLOG_INSTALL "" REPLACE" replaces
$ @PROLOG_UNINSTALL CHECK ! what would be removed
$ @PROLOG_UNINSTALL ! removes what the manifest recorded
Then each user, once per login or from LOGIN.COM:
$ @SYS$COMMON:[SYSLIB.PROLOG]PROLOG_SETUP
$ PL ! interactive; end with halt. or Ctrl/Z
$ PL "-q" "-f" FILE.PL "-t" "halt" ! run a program (quote the switches)
$ @PROLOG_EXAMPLES:RUN_EXAMPLES ! the nine examples against their expected output
An uploaded saveset arrives with the wrong record attributes; the installer sets them. The kit installs about 5,100 blocks (2.6 MB).
Measured results are from 14-15 October 2026 on a VAXstation 4000/90 and a VAXstation 4000/60 under OpenVMS VAX 7.3 with DEC C 6.4; the timings come from batch jobs of one run each, with the machine otherwise idle. Sources, logs and the recipe: the download folder.
