Welcome to the AWK target! This chapter introduces you to compiling Prolog predicates into self-contained AWK scripts.
The AWK target transforms Prolog predicates into portable AWK scripts. AWK is a text-processing language designed for:
Unlike SQL or Go targets that work with databases or compiled binaries, AWK scripts process text streams, making them perfect for log analysis, CSV transformation, and Unix pipelines.
Before starting, verify you have:
Check AWK availability:
awk --version
# or
gawk --version
Most Unix-like systems (Linux, macOS, BSD) have AWK pre-installed. On Windows, install via WSL, Cygwin, or Git Bash.
The AWK target exports two main predicates:
% Compile a predicate to AWK code
compile_predicate_to_awk(Predicate/Arity, Options, AWKCode)
% Write AWK code to a file
write_awk_script(Filename, AWKCode)
:- use_module('src/unifyweaver/targets/awk_target').
Let’s compile a simple predicate that filters employees by department.
% file: first_awk.pl
:- use_module('src/unifyweaver/targets/awk_target').
% Define a simple filter predicate
% Assumes input: Name<TAB>Department<TAB>Salary
engineering_staff(Name, Dept) :-
employee(Name, Dept, _),
Dept = "Engineering".
?- compile_predicate_to_awk(engineering_staff/2, [], AWK),
write_awk_script('engineering.awk', AWK).
Create a file employees.tsv:
Alice Engineering 75000
Bob Sales 65000
Carol Engineering 80000
Dave Marketing 70000
Eve Engineering 72000
awk -f engineering.awk employees.tsv
Output:
Alice Engineering
Carol Engineering
Eve Engineering
The generated script follows this structure:
#!/usr/bin/awk -f
BEGIN {
# Initialization
FS = "\t" # Field separator (tab by default)
}
{
# Main processing block
# Runs for each input line
# Extract fields
Name = $1
Dept = $2
Salary = $3
# Apply constraints
if (Dept == "Engineering") {
# Output matching records
print Name "\t" Dept
}
}
END {
# Cleanup (if needed)
}
The compile_predicate_to_awk/3 predicate accepts various options:
% Tab-separated (default)
compile_predicate_to_awk(pred/2, [record_format(tsv)], AWK)
% Comma-separated
compile_predicate_to_awk(pred/2, [record_format(csv)], AWK)
% JSON Lines
compile_predicate_to_awk(pred/2, [record_format(jsonl)], AWK)
% Use colon as separator
compile_predicate_to_awk(pred/2, [field_separator(':')], AWK)
% Use pipe
compile_predicate_to_awk(pred/2, [field_separator('|')], AWK)
% Skip first line (header row)
compile_predicate_to_awk(pred/2, [include_header(true)], AWK)
% Remove duplicates from output
compile_predicate_to_awk(pred/2, [unique(true)], AWK)
Here’s a complete example demonstrating the full workflow:
% file: salary_filter.pl
:- encoding(utf8).
:- use_module('src/unifyweaver/targets/awk_target').
% Employees earning above a threshold
high_earners(Name, Salary) :-
employee(Name, _, Salary),
Salary > 70000.
% Run this to generate the AWK script
generate :-
compile_predicate_to_awk(high_earners/2, [
record_format(tsv),
include_header(true)
], AWK),
write_awk_script('high_earners.awk', AWK),
format('Generated high_earners.awk~n').
:- initialization(generate, main).
Run it:
swipl salary_filter.pl
awk -f high_earners.awk employees.tsv
The generated AWK scripts are:
You can distribute just the .awk file without needing Prolog or UnifyWeaver at runtime.
active_users(Name) :-
user(Name, Status),
Status = "active".
name_and_email(Name, Email) :-
contact(Name, _, Email, _).
with_bonus(Name, Total) :-
employee(Name, _, Salary),
Total is Salary * 1.1.
Basic Filter: Create a predicate that filters products with price > 100 and compile it to AWK.
Department Report: Write a predicate that selects employees from the “Sales” department, showing name and salary.
Custom Separator: Compile a predicate to process colon-separated data (like /etc/passwd).
Multiple Conditions: Create a predicate that filters employees who are in “Engineering” AND earn more than 70000.
In this chapter, you learned:
compile_predicate_to_awk/3 and write_awk_script/2record_format, field_separator, include_header, uniqueIn Chapter 2, we’ll explore facts and filtering in detail, learning how Prolog facts compile to AWK associative arrays.