UnifyWeaver

Chapter 1: Introduction to the Prolog Target

What is the Prolog Target?

The Prolog target is one of UnifyWeaver’s transpilation backends that converts Prolog source code into executable Prolog scripts. While this might seem circular (transpiling Prolog to Prolog), it serves several important purposes.

Why Transpile Prolog to Prolog?

At first glance, transpiling Prolog code to Prolog might seem unnecessary. However, the Prolog target provides several valuable capabilities:

1. Dialect Translation

Different Prolog implementations (dialects) have varying syntax, capabilities, and execution models:

The Prolog target can generate code optimized for a specific dialect, handling differences in:

2. Dependency Injection

UnifyWeaver analyzes your code to detect dependencies on:

The generated script automatically includes the necessary imports and initialization code.

3. Compilation Support

The Prolog target can generate:

This allows you to:

4. Security and Validation

Integration with UnifyWeaver’s firewall system allows:

Use Cases

Standalone Executables

Generate self-contained Prolog scripts or binaries that can run without UnifyWeaver:

% Input: factorial.pl
factorial(0, 1) :- !.
factorial(N, R) :- N > 0, N1 is N - 1, factorial(N1, R1), R is N * R1.

% Generate standalone script
?- generate_prolog_script([factorial/2],
                         [dialect(gnu), compile(true)],
                         Code),
   write_prolog_script(Code, 'factorial', [dialect(gnu), compile(true)]).

% Result: factorial (native binary)
$ ./factorial

Cross-Dialect Compatibility

Write once in SWI-Prolog, deploy to GNU Prolog:

% Developed and tested with SWI-Prolog
my_predicate(...) :- ...

% Generate GNU Prolog version with automatic adjustments
?- generate_prolog_script([my_predicate/2],
                         [dialect(gnu)],
                         GnuCode).

Dependency Bundling

Automatically include UnifyWeaver modules your code depends on:

% Your code uses partitioning
process_data(Data, Results) :-
    partitioner_init(fixed_size(rows(100)), [], Handle),
    partitioner_partition(Handle, Data, Partitions),
    % ... process partitions
    Results = Partitions.

% Generated script includes:
% :- use_module(unifyweaver(core/partitioner)).
% :- ensure_loaded(unifyweaver(core/partitioners/fixed_size)).
% Plus plugin registration

Development Workflow

  1. Develop with SWI-Prolog (rich debugging, REPL)
  2. Test with interpreted mode (fast iteration)
  3. Deploy as GNU Prolog binary (standalone, fast startup)
  4. Fallback to interpreted if target platform lacks compiler

Benefits

For Users

For Implementers

The UnifyWeaver Pipeline

┌─────────────────┐
│  Source Prolog  │
│   (your code)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   UnifyWeaver   │
│    Analysis     │ ◄─── Detect dependencies
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Prolog Target  │
│   Generation    │ ◄─── Select dialect
└────────┬────────┘      Apply policies
         │               Generate code
         ▼
┌─────────────────┐
│ Generated Script│
│  (.pl file)     │
└────────┬────────┘
         │
         ├─── compile(false) ───► Executable script
         │
         └─── compile(true) ────► gplc ───► Native binary

What’s Next?

In the next chapter, we’ll dive into the architecture of the Prolog target, exploring how it transforms your code through the transpilation pipeline.


Key Takeaways:


Previous: The Prolog Target: Implementation and Usage Guide 📖 Book 11: Prolog Target Next: Chapter 2: Architecture Overview →