Compiling and linking overview
Once you have completed program development, you can compile the program to produce a fast, efficient stand-alone application. Depending on your program, a compiled application can run several times faster than the same application runs interpreted. This chapter describes all of the features of the Arity/Prolog32 compiler, as well as the compilation and link steps necessary to create a compiled application or add evaluable predicates to the interpreter.
Elements of a compiled program
All stand-alone Prolog applications, including the Arity/Prolog32 interpreter, are made up of at least two files – an executable file and one or more dynamic link library (.dll) files. In addition, they usually have an environment file and one or more internal database files All of these files together form your application and would be distributed together.
The executable file
The executable file is created in two stages. First, the source (.ari) files are compiled, producing standard object (.obj) modules. Then, the object modules are linked with a standard linker utility.
Not all of the modules of an application need to be written in Prolog. Modules written in assembly language, C, or other languages can be linked with Prolog modules. Arity/Prolog32 provides an interface from Prolog to other programming languages.
Dynamic link library files
Dynamic link libraries are libraries of code that an application uses, but have not been included in the applications executable (.exe) file. Arity/Prolog32 provides a dynamic link libraries (Arity32.dll) that contains the built-in evaluable predicates that are available to all applications.
In addition, Arity/Prolog32 allows you to build dynamic link libraries containing your own code. Individual dynamic linked libraries may be loaded at the time your application is initiated or may be loaded and unloaded during your programs execution.
Database files
The Arity/Prolog32 interpreter application (and the subset of features of the interpreter that you can build into compiled applications) let you load, edit, and invoke Prolog predicates. The area where interpreted Prolog predicates reside is the Prolog database. Arity/Prolog32 has built-in predicates such as asserta/1 and assertz/1, which allow you to add and remove clauses from the database while a program is running. The ability to access a program database at runtime in this way is a major difference between Prolog and other languages.
Additional database predicates, such as recorda/3 and recordz/3, give you the ability to store information in Arity/Prolog32 databases in the form of Prolog terms. Thus, Arity/Prolog32's database gives your application the features of a sophisticated database management system with all of the representational flexibility and power of Prolog terms.
Arity/Prolog32's database can grow to two gigabytes in size because it uses virtual memory. The actual limit is determined by the amount of disk space available on your system. Arity/Prolog32's virtual database makes Prolog well-suited for writing intelligent database applications, expert systems, and natural language systems, as well as conventional applications.
The environment file
The environment file specifies a number of configuration parameters, including the amount of space to be allocated for program stacks and specifies the names of control files for start-up and for the virtual database. It is not strictly necessary to include an environment file. Arity/Prolog32 uses default parameters for you when no environment file exists. However, if you want to maximize programming efficiency by defining environment parameters specific to an application, you can create an environment file.
You must include an environment file for the Arity/Prolog32 interpreter that includes:
VANILLA=YES
Specifying the main entry point of your program
A Prolog program or evaluable predicate is built from a set of predicates. The predicates can be collected into one or more files, or modules. For both programs and evaluable predicates, one of the predicates in the program is the main "entry point," which defines the name and the number of arguments with which it is called.
A stand-alone program is different from an evaluable predicate in that its entry point is a predicate called main/0. Within main, you call the other predicates in the program. For example:
main :- repeat, evaluate, fail.
In this example, the main predicate calls evaluate as part of a repeat-fail loop. Each time evaluate completes, it begins again. If you want the program to terminate when the evaluate predicate ends, you can write a main predicate like this:
main :- evaluate.
or
main :- evaluate, halt.
The action defined by the halt predicate is the default action that the program will take on completion, if none is defined. The main/0 predicate must be declared public.
The restart predicate
When an interpreted Prolog program is interrupted by Ctrl-Break, it returns to the interpreter. A stand-alone Prolog program tries to invoke a predicate called restart/0 with an arity of 0. If restart/0 is not defined, Arity/Prolog32 exits as if you had defined restart/0 as:
restart :- halt.
If you want the program to take another action on Ctrl-Break, you should define a restart/0 predicate at the beginning of the source file to specify that action and declare the predicate public
The embedded C compiler
The Arity/Prolog32 Compiler contains an embedded C compiler. This C compiler is used for compiling C elements within a Prolog source file and provides you with added flexibility in your programming tasks. Specifically, you are able to do the following:
- Declare C data and functions within a Prolog program exactly as you would within a C program. You may even #include your C header files.
- Using a modified syntax, you can embedded C expressions within a Prolog clause by placing the expressions within curly braces ({}). These expressions can access global data and they can call external C functions.
- Declare Prolog predicates so that they can be called from C. These predicates can be defined as functions that have a return value or functions that do not return a value and can be deterministic or non-deterministic. Functions are supplied for backtracking through and cutting choice points from these non-deterministic routines.
Note: the embedded C compiler supports the _cdecl and _pascal calling conventions supported by the Microsoft C compiler. This calling convention is supported by many other compilers and products, such as Microsoft Pascal or Fortran, Zortech C++, Borland C++ or Smalltalk. To these products, calls to or from Arity/Prolog32 must be treated exactly as if they were made to or from Microsoft C. For more information, consult your documentation for these products.