This book has been recovered from a crash of my previous blog. I have not as yet completed the recovery; Some of the formatting needs to be redone and a number of illustrations are missing. Also, some vestigial discussions relating to OS/2 will be excised and should be ignored. However, I am posting this in the hope that it will be of use in the interim.
Arity/Prolog32 was developed at Arity Corporation by Peter Gabel, Paul Weiss, and Jim Greene. For a number of years Arity provided binaries for Arity/Prolog32 at no charge.
This book is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 United States License with attribution to be given to Peter L. Gabel and to this site. Some portions of this book are adapted from previous documentation created by Arity which was distributed as a part of the Arity/Prolog32 product.
Zipped files containing Arity/Prolog32 source and Arity/Prolog32 executables are available at the Installing Arity/Prolog32 section of this book.
Prolog is a “logic programming language” which was designed to balance procedural and declarative styles of expression of code. Prolog programs are made up of a set of clauses that are either facts or rules. A fact expresses something that holds true about the information you give it. A rule, on the other hand, expresses how new facts may be inferred. Built-in procedures provide side-effects for performing operations such as I/O, arithmetic, and interaction with a database.
Prolog is relevant today because it embodies many of the characteristics that are desired for the management of linked data and the semantic Web. The structure of Prolog data (“terms”) is more general than JSON or XML structures and very well suited to the representation and manipulation of JSON, XML, RDF, OWL and other complex data formats. The ability to store Prolog terms in a large, indexed database enables the construction of efficient and highly advanced knowledge discovery applications.
Prolog's ability to infer solutions to problems differs from the computational model that most programmers are familiar with. In a procedural language such as C, for example, the programmer concentrates on specifying the process of the problem, building control constructs such as "for" and "while." A procedural program may be readily visualized as a flowchart. Procedural thinking centers on describing how an algorithm is to be carried out. An object oriented language such as C++ or Java extends this procedural style through better encapsulation of data and functions
Prolog, on the other hand admits both a procedural reading and a declarative reading. The declarative style of Prolog allows the programmer to concentrate primarily on how data may be derived from other data by expressing programs as sets of conditions as rules. Essentially, you as a Prolog programmer, can describe rules that generate true relationships when other relationships are found to be true. Declarative thinking centers on describing what relationships hold true under different patterns of input. This is why Prolog is considered to be a descriptive or relational programming language.
The mathematical formalization of logical reasoning initiated the study of the relationship between computation and machine intelligence. Many practical applications have been developed out of this tradition, often in Prolog and indeed, often in Arity/Prolog32.
One area with a rich history of development and use of Prolog is natural language understanding. In fact, Prolog was originally designed to perform natural language experimentation. The definite clause grammar formalism of Prolog parses simple natural language grammars easily and effectively. Current work in more sophisticated grammar formalisms continues to often use Prolog or be strongly influenced by Prolog technology. For example, Arity/Prolog32 is being successfully used commercially for large-scale construction grammar development based on feature logics and chart parsing technology.
Prolog's formal precision and power of interpretation makes it particularly well suited for knowledge representation. Some of the work being performed in this area includes semantic networks, frames and scripts, and production systems. Arity/Prolog32 has been used to create several description logic inference engines, including a sophisticated implementation of the description logic EL++.
The logic-based computational model that underlies Prolog is an extension of the model that underlies relational databases. SQL can be viewed as a declarative language where queries are processed as rules for computing tables. Prolog can be viewed, in part, as a declarative language where computation is initiated by a “goal” (akin to a query) which is processed by a set of rules for computing results. Generally, a Prolog program’s most important output is produced through side-effects rather than the bindings created as an answer to the goal. But much of what a Prolog program does may be viewed as a generalization of the operations within a relational database system. For this and other reasons, Prolog is useful for information management application.
The intention of this book is not to teach you to program in Prolog. For information on Prolog programming concepts, refer to the Suggested Readings section.
Many implementations of Prolog have been created by developers worldwide for different hardware and software platforms. Each implementation has a different emphasis on features and targeted application areas. Many implementations emphasize a particular set of features related to logic programming such as constraint handling or alternative control schemes (such as datalog). Other implementations provide significant extensions for user interface, program structure, or other application support functions.
As Prolog evolved, several informal and formal standards emerged. The core features of Prolog were most often identified as “Edinburgh Prolog” or “Clocksin-Mellish Prolog” (after the book, Programming in Prolog, by William F. Clocksin and Christopher S. Mellish, 3rd Edition. Berlin: Springer-Verlag, 1987). The ISO Prolog standard ISO/IEC 13211-1 was first published in 1995. Most implementations of Prolog were faithful to the spirit of these standards but deviated from them in significant ways.
Arity had a long history of implementing and using Prolog, releasing its first compiler and interpreter for Prolog for 16 bit MS-DOS. Subsequent versions supported OS/2 (both 16 and 32 bit), Windows NT, and was ported to specific platforms that were common in Japan. The version of Arity’s Prolog described in this book may be run on 32 and 64 bit versions of Microsoft Windows. It has also been successfully used on Linux using WINE.
Arity/Prolog32 encompasses all of the predicates and functionality of Prolog associated with “Clocksin-Mellish Prolog”. In addition, Arity/Prolog32 contains many predicates and features that make it ideal for constructing and deploying complex applications.
These features include:
- Expanded database support providing control over data persistence and including linked records, B-trees, hash tables and the ability to create specialized indexing structures;
- The ability of Arity/Prolog32 code to call and be called by code written in other languages, including ‘C’;
- Text support including an integrated approach to atoms and strings;
- File management including input and output to file handles;
- Multi-threaded programming support;
- Run-time loadable dynamic linked library support;
- Sophisticated arithmetic operations including an integrated approach to integer and floating point numbers; and
- Many other extensions.
Arity/Prolog32 provides a compiler which creates highly efficient static code, an interpreter for dynamic (run-time modifiable) code, and an extended interpreter with features that aid in the debugging of Prolog programs. The extended interpreter is itself extensible with the ability for compiled code to be added.
Compiled code is packaged in the form of DLLs (Dynamically Linked Libraries) which can be used to build self-standing applications or be used as extensions of larger applications.
Earlier versions of Arity/Prolog included a “DOS box” windowing system including menus and dialog boxes. This has now been deprecated.
There are two primary uses for interpreting Prolog code. First, Prolog has a different execution model than other languages which is complemented with a style of debugging called the “box model”. Arity/Prolog32 contains an extended interpreter that provides this debugging support. Thus, a key use of the Arity/Prolog32 interpreter is for the development of new applications.
Second, Arity/Prolog32 provides an interpreter that may be invoked from compiled code (and may call compiled code) for applications that require dynamically modifiable code or that load portions of an application as code that may be changed by users.
Usually, when we refer to the interpreter, we are referring to the first sense of the word – the extended Arity/Prolog32 interpreter with its debugging support.
The extended Arity/Prolog32 interpreter is an application called API32.exe. It has two modes of execution. The default mode provides a deprecated style of interaction that contains a small integrated development environment. This includes edit buffers and menu items to common operations. However, this mode depends on the old deprecated “DOS box” windowing system. We do not suggest using this mode.
The preferred mode of execution of API32.exe is called “vanilla”. Vanilla mode allows you to execute Prolog code in a “Command Prompt” window. You can use your favorite editor or IDE to create your application and to interact with the API32 window.
Code (structured as “predicates” containing “clauses”) is stored within the internal database of Arity/Prolog32. By default, the internal database of API32.exe is API.idb.
The Arity/Prolog32 compiler produces fast, efficient code as object modules. Object modules may be linked to produce executable images and to produce dynamic linked libraries. Code produced by other compilers may be linked with Arity/Prolog32 object code.
Typical application development begins with the Arity/Prolog32 interpreter since it allows you to run, debug, and change your program instantly. As selected portions of your program are completed, you can compile these portions and incorporate them into the interpreter by rebuilding the interpreter or by loading DLLs from interpreted code. When your application is complete the main entry point and associated code is compiled and the application is created as a new executable, independent of API32.exe. Or, you may build applications where your compiled code becomes incorporated into a larger system written in another language, such as 'C'.
This manual describes the elements which make up the Arity/Prolog32 language. The operators, data types, and built-in predicates provided by Arity/Prolog32 are described in detail.
The description of each predicate includes a format indicating how the predicate is used. A special notation is associated with each argument to the predicate. A symbol appears before each argument indicating whether or not the argument must be instantiated at the time the predicate is invoked. An instantiated argument is one in which the argument is bound to some value. The symbols are:
A plus sign in front of an argument indicates that it is used as an input argument. Generally, the argument is required to be instantiated. However, in a few cases, most notably the predicates used to classify terms such as nonvar/1, the argument may be uninstantiated upon input. In these cases, the argument is never instantiated at output to a new value by the predicate.
A minus sign in front of an argument indicates that it is used as an output argument. The predicate generally returns an instantiated value which is unified with the value given when the predicate is called. However, in a few cases, such as recorded/3 where the returned value from the database is a stored uninstantianted variable, the value returned is uninstantiated and will always unify with the value provided when the predicate is called.
A question mark in front of an argument indicates that the argument may be used either for input or output, depending on the context in which it is used. The predicate description will describe the effect of supplying both an instantiated and an uninstantiated argument.
Note that these conventions are similar to but are not the same as mode declarations which can be used to inform the compiler of possible optimizations that may be made for individual predicates.
The names of predicates are usually written in Functor/Arity notation. For example, the predicate which reads Prolog terms from standard input is referred to in the documentation as read/1.
Code examples in this documentation are written as they would be submitted to the interpreter or in a Prolog source file (as predicates formed from one or more clauses). Examples of goals input to the interpreter for execution have a ‘?-‘ command prompt pre-pended. This is meant to suggest the prompt for input used by the Arity/Prolog32 interpreter and not what you would enter.