LPA - Version MacProlog32 - Combines Advanced AI Programming Software
LPA MacProlog32 combines advanced AI programming techniques with the user-friendly interface and enhanced graphics of the Apple Macintosh. By integrating a powerful Prolog compiler with the Macintosh philosophy of mice, menus, windows and graphics, LPA offers a rich and sophisticated programming environment, previously available only on expensive, dedicated workstations, combined with a compact, run-time delivery capability. To get the best overall performance on a 32-bit machine, MacProlog32 has been implemented completely from scratch in 32-bit assembler using the same engine as featured in LPA WIN-PROLOG. This guarantees a high degree of compatibility with both that product set, Quintus Prolog on Unix and the ISO Standard.
LPA MacProlog32 is not only an industrial strength Edinburgh syntax compiler system, but also boasts many special-purpose routines for constructing classical Macintosh-style applications without having to understand the inner workings of the Macintosh. Coupled with the rich range of add-on tools available, this helps makes MacProlog32 a powerful general purpose applications development system.
Basic components of MacProlog32
- a fast incremental compiler for rapid program development
- a powerful optimising compiler for efficient final applications
- easy-to-use declarative graphics system
- high-level ToolBox access for menus, windows and dialogs
Optional add-ons available for MacProlog32
- flex - portable frame-based expert system toolkit
- Prolog++ toolkit - for object-oriented programming
- MacDialog Editor - for drawing user-interfaces
- Portable Dialog Manager - for defining portable, abstract screens
- Saag/RG - run-time generator for stand-alone applications
Standard Prolog features
- support for Definite Clause Grammars (DCGs) and user-defined term expansion
- fast solution set routines (findall/3, bagof/3, setof/3)
- fast multi-key sorting and sublist indexing primitives
- 32-bit integer and 80-bit double-precision floating point arithmetic
- character, string, constant and term conversion routines
Advanced Prolog features
- fast extended double-indexed property management system for data values
- re-definable handlers for errors, debugger, interrupts, browser and loader
- efficient text manipulation through dedicated string data type
- advanced facilities for predicate meta-variables and condition meta-variables
Input/Output specific features
- HFS primitives for accessing files, folders, paths and disc traversal
- random access file, window and serial I/O primitives
- comprehensive set of formatted I/O primitives for accessing structured data
GUI specific features
- declarative graphics environment with versatile graphics primitives
- high-level window, menu and dialog management primitives
- program access to text edit routines (cut/1, copy/1, paste/1)
- structured file browser mechanism for building interactive help systems
- easy-to-program pop-up, pull-down and hierarchical menu system
Macintosh specific features
- time and date primitives, with access to system clock
- support for C and Pascal external functions through code resources
- direct access to resources on disc (pictures, icons, cursors, code, sound etc)
- program access to events in 'foreign' windows
- programmatic control over printing and page set-up
- integration with standard applications through Apple Events interface
- access to window details (font, colour, mode etc) through convenient dialogs
- comprehensive file loading and saving facilties
- fully integrated Macintosh text editor (with Undo & Clipboard support)
- various text-based menu options, including 'Find ...', 'Replace', 'Replace all' etc
- support for organising program, text and graphic windows on DeskTop
- 'Find definition...' facility to instantly locate source code programs
- ability to enter and execute any goal directly into a window
- ability to set spy points through convenient dialogs
- interactive configurable box-model source-level debugger
- on-line information on both user-programs and system primitives
- full and partial program cross-referencing
True 32-bit Implementation
A significant feature of MacProlog32 is that it is a true 32-bit implementation. All pointers and integers are 32 bits wide, giving MacProlog32 the ability directly to address up to 4 gigabytes (4096 megabytes) of memory. With all that memory available, it would be tempting simply to use it all, even if your application was a small Prolog program. Increasingly it is necessary to consider computers running more than one application at a time, and the 'hog-the-lot' approach to applications programming is no longer appropriate. Under MacProlog32, you have total control over your memory resources. Six main memory stacks and heaps can be configured to your choice, allowing you to tailor the system precisely to fit your needs.
Linear Garbage Collection
With all the memory available to the designers, it would have been tempting to skimp on the garbage collection features. However, the garbage collection and memory management within MacProlog32 is even more complete and advanced than in any of LPA's previous Prolog systems.
The evaluation stacks and heap are managed by a linear garbage collector: doubling the size of evaluation space roughly doubles the time taken to collect garbage on any one occasion, but garbage collection occurs only half as often. The result is no net degradation of performance, even when vastly different sizes of evaluation space are used. A fixed size cell allocation scheme avoids any risk of memory fragmentation.
Text space is used to store the bodies of atoms and strings, and is managed as a special heap. It too is fully garbage collectable. Program space is used to store clauses and optimised programs, and is totally reclaimable when these programs are abolished. Both text and program spaces use a special segmented heap format which guarantees that every last byte of memory can be used, with no fragmentation or degradation problems, however many times items have been added or removed.
The Incremental Compiler
MacProlog32 includes an incremental compiler, whereby all clauses in a program are compiled at all times. This combines the behaviour of an interpreter with the performance of a compiler. Because the compiler is incremental, individual clauses can still be added by programs - just as in a conventional interpreter. In fact, assert/1 is implemented as a call to the compiler. MacProlog32 supports dynamic first argument indexing (even into compound terms), which can result in considerable runtime performance improvements. Tail recursion and last-call optimisations are also built in by the incremental compiler to guarantee the efficient usage of memory. The fast compacting garbage collector is seldom needed but is automatically invoked whenever space becomes short. Programs can be incrementally decompiled too, allowing predicates like clause/1, retract/1 and listing/0 to be implemented. Both the incremental compilation and decompilation routines are written in assembler code. This enables the speed of compilation to match that of an interpreter - but with the resulting clauses running significantly faster.
The Optimising Compiler
For efficiency in use, the incremental compiler/decompiler does not perform multi-argument indexing and other optimisations - they would simply be too complex to change on the fly during assert/1 or retract/1. With this in mind, LPA provides an alternative optimising compiler.
The optimising compiler can perform all the optimisations just mentioned. As well as building multiple-argument index tables, which enable the very fast matching of clauses on any arbitary argument (as opposed to the single first-argument indexing of the incremental compiler and other Prolog systems), a complete variable usage analysis is performed on relations. Any variables which can be left in situ between calls are left so, substantially reducing the data traffic in most programs. The optimising compiler also performs style checking, which can be helpful when hunting for bugs, such as those introduced by the mis-spelling of a variable name for example.
Optimised programs run significantly quicker than incrementally compiled ones, and use less space during execution. Decompilation of these programs is not possible, so your source code will remain completely secure in delivered applications.
80-bit floating point and 32-bit integer arithmetic
A fully-featured, 80-bit double precision floating point arithmetic library is built in to MacProlog32. This is accessed directly by the is/2 predicate, which in turn is implemented entirely in 32-bit assembler. The library provides high-speed, high-precision arithmetic computations, and includes support for standard 'calculator' functions, trigonometric and logarithmic functions, floating point to integer conversion and truncation functions, maximum and minimum functions, and pseudo random numbers. The most common use of the is/2 predicate is for the simple adding or subtracting of two integers, and this case is specially optimised, being handled entirely in the integer domain wherever possible.
Powerful input and output features
A great stength of MacProlog32 is its powerful collection of input and output sub-systems. As well as the standard see/1, tell/1, read/1 and write/1 style predicates, support is given for formatted I/O, binary I/O, serial I/O and string I/O.
Formatted I/O primitives provide complete control of the output of atoms, terms, strings, numbers and other items. Fixed field display, with left or right justification, optional truncation, and free field formats are supported. Numbers can be output in fixed-point, signed or unsigned integer, and even non-decimal base formats. Matching formatted input allows structured records to be read in with automatic type checking. Combined with the powerful window manager, this feature makes it easy to provide readable, tabular output and structured input.
Text String Data Type
While the traditional Prolog 'string', namely a list of 8-bit integers, is the most powerful means by which to manipulate small pieces of text, it is extremely inefficient as a way of storing text. This inefficiency would be compounded in a 32-bit Prolog system, where each one-character element of the list would need 12 bytes of storage on the dynamic heap. To enable bulk text handling applications, MacProlog32 has introduced a true text string type. Any number of such strings may exist in Prolog terms, and each may contain up to 32K of text. Because of the way these strings are stored, garbage collection is still quick and efficient, and even string space cannot become fragmented.
Many built-in predicates use strings as a means of passing large amounts of text or binary data around, for example between a window buffer and a disk file. In addition, strings may be used as input and output streams: for example, the call:
?- listing ~> String.
would bind the variable String to a string containing the entire text of a program listing. This string could be manipulated, displayed in a scrolling window and processed in virtually any fashion. Strings also provide a data type with a high bandwidth for communications between MacProlog32 and low-level data types, such as files and screen buffers.
LZSS data compression
An interesting feature in MacProlog32 is the provision of a pair of routines for LZSS data compression and decompression. These are used internally by the system state save and restore predicates, but are also available for general use in user programs through two special I/O predicates.
As its name suggests, LZSS compression is based on Lempel-Ziv compression, and is an modification version of the original LZ77 algorithm. In this algorithm, a sliding window is maintained over recently output data, while a look-ahead buffer peeks into the stream of data yet to be compressed. The contents of the look-ahead are compared with all locations in the sliding window, and if a match of two or more characters is found, the address and length of the match within the window, rather than the characters themselves, is output. Depending upon the sizes of sliding window and look-ahead buffer, compression ratios of up to 64:1 are theoretically possible for highly patterned data; in practice, ratios of 2:1 to 4:1 are more usual.
The original LZ77 algorithm had two major faults. Firstly, for every symbol being encoded, the entire sliding window had to be searched, position by position, and so compression was very slow: furthermore, doubling the size of the window to achieve better compression also doubled the time taken to perform that compression. Secondly, the method used to encode single (unmatched) characters was very inefficient. LZSS employs fundamental improvements over LZ77 in both these areas, in that it uses a binary tree for string searching, and a more efficient code stream for representing matches and data bytes.
There are many potential applications of LZSS compression: these include the creation of stuffed archive files, which contain an accumulation of compressed files with their names, creation dates/times and attributes, the simple stuffing of individual files, such as bitmaps, which normally use large amounts of disk space, or the compacting of data which needs to be transmitted by modem or some other slow device. More advanced uses might include the creation of mixed database files consisting of uncompressed index information, and compressed data records.
Term and data management
There are many special features in MacProlog32 geared towards term and data management. An assembler-coded, high-speed list/merge sort algorithm gives truly stunning performance. Displaying ln2(x) performance characteristics, it is capable of sorting lists of 10,000 elements in around two seconds on a IIsi. The sort/3 predicate goes beyond the functionality of sort/2, by allowing you to define a sort key of arbitary depth. This powerful feature allows you, for example, to sort a list of names and addresses by surname, street name, town or postcode (zip code), simply by changing the search key parameter.
MacProlog32 Programming environment
MacProlog32 has a rich multi-file, multi-window programming environment which allows you to mix (incrementally) compiled and optimised code on a window basis, as well as source and object code on a file basis. Windows, which are the smallest unit of compilation, are only re-compiled if altered which speeds up program development and there are many program support options to help productivity. The environment permits up to 255 program edit windows to be open at any one time, and you can cut and paste text between them in the normal Macintosh manner. Standard search and replace edit facilities, together with special Prolog-related ones (such as 'Goto Definition' and 'Get Information') make the maintenance of large, complex systems more manageable.
Source Code Debugger
MacProlog32 includes an attractive and sophisticated source level debugger. This debugger enables you to single-step through an illustrated display of your code, line by line, using a series of simple and well-designed directives. Spy points can be set on individual routines, and in addition to the standard Creep option for single-stepping through a program, the debugger includes both a Skip option for skipping a given call without tracing it, and a Leap option for turning off the all debugger interaction until the next time a spypoint is reached. There are also Redo, Retry and Fail options for modifying the execution of the program being debugged. The debugger allows variables bindings to be displayed both as an enumerated list of bindings, or as in situ instantiations.in their respective clauses. Debugging graphical programs is made easier because the debugger screen is separate from the program output screen, and can be used in both monochrome or colour mode.
There are also other debuggers available, including the more traditional Box Model debugger which traces execution a step at a time. In this case, the debugger displays the run-time instantiations of goals, one at a time, rather than source code. There are also specialised debuggers to help find points at which your program is failing (Mismatch Monitor and Fail Monitor), and a simple Call Monitor.
Programmable Handlers and Hooks
In addition, there are several special 'hooks' in MacProlog32 to enable your programs to gain complete control during development and run-time.
A spypoint mechanism allows you to set interrupt traps on specific relations. The spypoint mechanism fires the interrupt whenever a spied relation is called. Control will pass to a special program which you can define to perform any special processing (such as recording information to disc, for example). Because the interrupted goal is passed to your handler program as a parameter, you can call the goal once your processing is complete, allowing your application to continue as if the interrupt never occured. There is also a programmable error handler, which intercepts all run-time errors except for exhaustion of space, passing control to a program you define. The error number and the guilty call are both passed as parameters, so your program can make suitable amends, and then execute the goal again - totally transparently to the rest of your application.
Call Graphs - towards visual programming
One use of the MacProlog32 graphics package within the development environment is the Call Graph facility which lets you to graphically display and browse your programs. This tool is a great aid to program productivity and maintenance.
A Prolog-coded programming environment
The MacProlog32 development environment is built entirely from regular MacProlog32 menu, dialog and graphics routines and serves as an good example of what can be achieved with MacProlog32 .
System 7 support: Apple Events, etc
MacProlog32 includes support for Apple Events so that MacProlog32 applications can interact with other Macintosh applications (e.g. HyperCard). This support includes the ability to define programs to send and receive outgoing and incoming events with support for various different data types, the ability to launch other applications, and the ability to browse through a list of currently connected applications. MacProlog32 also supports the use of balloon help in pull-down menus, Graphic Windows and Control Windows.
MacProlog32 uses full pathnames for specifying files and directories. File aliases are supported, as are stationery pads. Logical filenames and pathnames can be set up which can then be used in future routines, allowing simple portability of programs between different machines and disk configurations.
MacProlog32 has flexible C and Pascal interfaces which enable you to call external procedures written in these languages. You can pass lists, atoms or variables as arguments. The interfaces are pre-configured for THINK C and MPW C, Pascal.
Macintosh ToolBox integration - the ideal interface builder
In line with LPA's philosophy of easy access to GUIs, MacProlog32 provides high-level access to the Macintosh Toolbox and QuickDraw routines in a simple and efficient manner. For example, there are primitives to generate and monitor dialogs, install and manipulate menus, track the mouse, or draw and manage complex graphical objects.
Dialogs - a powerful built-in dialog manager
MacProlog32 supports two types of dialogs; modal and modeless, with three levels of availability; simple pre-defined dialogs, bespoke user-dialogs and extended dynamic dialogs. The range of pre-defined dialogs is comprehensive. Bespoke dialogs are implemented by you describing the configuration of the dialog as a list of dialog items, i.e buttons, check boxes, edit fields, scrollable menus, icons, text in any font format, pictures etc. A single call then displays and reads back from the dialog. Dynamic dialogs allow the dialog to be controlled and updated by a Prolog program attached to the dialog buttons. Dialogs can have multiple scrolling menus or text items in any font format.
The Graphics Package - a declarative approach
The MacProlog32 Graphics Package gives you full access to QuickDraw graphics in a high-level and declarative manner. This means you do not have to concern yourself with the inner workings of the Macintosh to build graphical interfaces. You simple define graphical objects in terms of an extendable Graphics Description Language (GDL), and then pass them as arguments to the many graphics primitives provided. The GDL is a recursive language, specially designed for manipulating graphical objects within a logic programming framework. The graphical objects are drawn in special graphic windows which support full RGB colour and can have a bespoke palette of Prolog tools which are automatically invoked when the user clicks or drags in a window's drawing area. There are also several graphics examples explained in the Graphics Manual. Also included are:
- a automatic viewer facility for panning and 'fast-scrolling' graphic windows
- built-in zoom facilities for graphic windows
- the ability to cut/paste pictures to/from other applications (MacDraw, PICT etc)
- the ability to load/save pictures on disc as resources
- a built-in library of popular graphical tools
- compiled pictures in graphic windows
Control Window provide a powerful and versatile means of I/O. Control Windows can contain any of the control items available in the MacProlog dialog system (i.e. menus, popups, text/edit fields, icons, lines, boxes, pictures, checkboxes, radios, buttons etc), and in addition, contain graphical objects. You can attach different Prolog processes to individual items which are then automatically invoked whenever the user selectes that item. Furthermore, items can be dynamically enabled, disabled or deleted as required. You can create any number of these windows and bring them to the front whenever you want.
Menus - automatic invocation of Prolog programs
Menus are installed, removed, extended, enabled, disabled or marked by a single call to a primitive. Individual menu-items, which can have command key equivalents, can be marked, unmarked, renamed, re-styled, toggled, enabled or disabled. User selections on a menu item automatically invoke a Prolog program associated with that menu and item.
Windows - full control over appearance, behaviour and content
Windows can be created, displayed, hidden, moved, printed, given a different font, re-sized, killed, or used as I/O channels with simple program calls. There is also a comprehensive set of window editing routines which allow you to control the cursor, search for arbitary text, select and highlight text, and invoke basic Macintosh text editing functions.
MacDBI for Oracle - for accessing SQL databases
This optional toolkit provides the ability to access Oracle databases seamlessly through a transparent interface. No previous knowledge of SQL is required.
MacPROLOG Dialog Editor - for drawing user interfaces
The MacPROLOG Dialog Editor uses the MacPROLOG graphics package to produce an interactive screen editor for rapidly prototyping sophisticated user-interfaces without having to write any program code.