UnifyWeaver

Chapter 3: Understanding Prolog Dialects

What are Prolog Dialects?

Prolog is not a single language, but a family of related implementations. Each implementation (or “dialect”) shares the core Prolog semantics but differs in:

UnifyWeaver currently supports two major dialects:

  1. SWI-Prolog: The most popular Prolog implementation
  2. GNU Prolog: A standards-compliant implementation with native compilation

SWI-Prolog

Overview

Website: https://www.swi-prolog.org/ License: BSD-2-Clause Primary Use: Development, research, web applications

Key Capabilities

dialect_capabilities(swi, Capabilities).
% Capabilities = [
%     name('SWI-Prolog'),
%     compilation(interpreted),
%     constraint_solver(clpfd),
%     module_system(full)
% ]

Strengths

1. Rich Module System

SWI-Prolog has a sophisticated module system with:

:- module(my_module, [exported_pred/2]).

:- use_module(library(lists)).
:- use_module(unifyweaver(core/partitioner)).

exported_pred(X, Y) :- ...

2. Comprehensive Libraries

3. Development Tools

4. Standards Compliance

Limitations

1. Interpreted Execution

2. Deployment

When to Use SWI-Prolog

Good for:

Not ideal for:

GNU Prolog

Overview

Website: http://www.gprolog.org/ License: GPL/LGPL Primary Use: Portable executables, embedded systems

Key Capabilities

dialect_capabilities(gnu, Capabilities).
% Capabilities = [
%     name('GNU Prolog'),
%     compilation(compiled),
%     constraint_solver(fd),
%     module_system(basic)
% ]

Strengths

1. Native Compilation

GNU Prolog includes gplc, a compiler that produces:

gplc --no-top-level factorial.pl -o factorial
./factorial
# Runs instantly, no interpreter needed

2. Portability

3. Performance

4. Standards Compliance

Limitations

1. Basic Module System

GNU Prolog has a minimal module system:

% GNU Prolog approach
:- include('library.pl').

2. Limited Libraries

3. Development Experience

4. Compilation Requirements

When to Use GNU Prolog

Good for:

Not ideal for:

Dialect Comparison Table

Feature SWI-Prolog GNU Prolog
Execution Interpreted Compiled
Startup Slower (load interpreter) Fast (native binary)
Distribution Requires runtime Single executable
Module System Full (use_module) Basic (include)
Constraint Solving CLP(FD), CLP(R), CLP(Q) FD
Tabling Yes No
HTTP Server Yes (library(http)) No
Database SQLite, ODBC Minimal
Debugging Rich (graphical) Basic
REPL Full-featured Basic
Standards ISO + extensions Strict ISO
Threading Yes Limited
Binary Size Large (with runtime) Small (standalone)
Development Speed Fast (interpreted) Slower (compile)
Production Deployment Requires installation Self-contained

Initialization Differences

One critical difference is how programs are initialized:

SWI-Prolog

% For scripts
:- initialization(main, main).

% For compiled applications
:- initialization(Goal).

Behavior:

GNU Prolog (Interpreted)

% For interpreted mode
:- main.

Behavior: Executes goal immediately when file is consulted

GNU Prolog (Compiled)

% For compiled binaries (gplc --no-top-level)
:- initialization(main).

Behavior: Sets entry point for binary execution

Critical: This is what UnifyWeaver’s fix addresses! The dialect generation must choose the right initialization based on compile mode.

Choosing the Right Dialect

Decision Matrix

┌─────────────────────────────────────────────────┐
│ Do you need standalone executables?            │
├─────────────────────────────────────────────────┤
│ YES → Use GNU Prolog (compile)                  │
│ NO  → Continue ↓                                │
└─────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────┐
│ Do you need advanced libraries (HTTP, DB)?     │
├─────────────────────────────────────────────────┤
│ YES → Use SWI-Prolog                            │
│ NO  → Continue ↓                                │
└─────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────┐
│ Do you need complex module structures?         │
├─────────────────────────────────────────────────┤
│ YES → Use SWI-Prolog                            │
│ NO  → Continue ↓                                │
└─────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────┐
│ Is startup time critical?                      │
├─────────────────────────────────────────────────┤
│ YES → Use GNU Prolog (compile)                  │
│ NO  → Either works, prefer SWI for development  │
└─────────────────────────────────────────────────┘

Common Patterns

Pattern 1: Develop with SWI, Deploy with GNU

% Development
swipl my_app.pl

% Generate GNU Prolog version for deployment
?- generate_prolog_script([my_app/0],
                         [dialect(gnu), compile(true)],
                         Code),
   write_prolog_script(Code, 'my_app_gnu.pl',
                      [dialect(gnu), compile(true)]).

% Result: my_app_gnu (standalone binary)

Pattern 2: SWI-Only (Web Application)

% Uses SWI-specific features
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).

% Generate for SWI deployment
?- generate_prolog_script([start_server/0],
                         [dialect(swi)],
                         Code).

Pattern 3: Multi-Target

% Generate both versions
generate_both(Predicates, BaseName) :-
    % SWI version (for development)
    generate_prolog_script(Predicates,
                          [dialect(swi)],
                          SwiCode),
    atom_concat(BaseName, '_swi.pl', SwiPath),
    write_prolog_script(SwiCode, SwiPath),

    % GNU version (for production)
    generate_prolog_script(Predicates,
                          [dialect(gnu), compile(true)],
                          GnuCode),
    atom_concat(BaseName, '_gnu.pl', GnuPath),
    write_prolog_script(GnuCode, GnuPath,
                       [dialect(gnu), compile(true)]).

Compatibility Considerations

Portable Subset

To maximize portability across dialects, stick to:

Core Prolog:

Standard I/O:

Avoid Dialect-Specific:

UnifyWeaver’s Validation

UnifyWeaver can detect incompatibilities:

validate_for_dialect(gnu, [my_predicate/2], Issues).
% Issues = [
%     unsupported_feature(tabling, 'GNU Prolog does not support tabling'),
%     missing_library(http, 'GNU Prolog lacks HTTP support')
% ]

What’s Next?

Chapter 4 shows practical usage of the Prolog target, starting with basic examples and building up to production scenarios.


Key Takeaways:


Previous: Chapter 2: Architecture Overview 📖 Book 11: Prolog Target Next: Chapter 7: The Firewall System →