Step 1: Write a program
FlowLog programs are plain-text Datalog files. A program typically has:
- Schemas: declare relations with
.decl - Inputs (EDB): load facts with
.input - Outputs (IDB): export results with
.outputor.printsize - Logic: rules derive new facts
Execution mode (batch, incremental) is chosen later at runtime via parameter
--mode. In this step, we focus only on writing the program.
Example: reachability
This example computes graph reachability from a set of source nodes.
// --- Declarations ---
.decl Source(id: number)
.decl Arc(x: number, y: number)
.decl Reach(id: number)
// --- Inputs (EDB) ---
.input Source(IO="file", filename="Source.csv", delimiter=",")
.input Arc(IO="file", filename="Arc.csv", delimiter=",")
// --- Outputs (IDB) ---
.printsize Reach
// Alternatively, write tuples to a file:
// .output Reach
// --- Rules ---
// Base rule: all sources are reachable.
Reach(y) :- Source(y).
// Recursive rule: if x is reachable and there is an edge x -> y, then y is reachable.
Reach(y) :- Reach(x), Arc(x, y).
Declarations
Use .decl to define the schema of each relation: its name and attribute types.
.decl Arc(x: number, y: number)
Here Arc is a binary relation with two number attributes, x and y.
Input relations
A relation becomes an input relation when you add an .input directive:
.input Arc(IO="file", filename="Arc.csv", delimiter=",")
In batch mode, the runtime loads input facts from the specified CSV file (here, Arc.csv) using the given delimiter.
CSV format: one tuple per line, attributes separated by the delimiter.
ExampleSource.csv:1Example
Arc.csv:1,2
2,3
In incremental mode, input relations are updated through an interactive shell instead of loading from filename=.... The delimiter parameter is still used to parse tuple text you enter in the shell. We'll cover the interactive shell commands and workflow in the next step.
Output relations
To observe results, you can either write tuples to a file with .output
.output Reach
or print only the relation size with .printsize
.printsize Reach
In incremental mode, outputs are emitted as the computation advances, so FlowLog appends a timestamp suffix to the output filename to avoid overwriting previous snapshots (for example, Reach_<timestamp>.csv).
Rules
Rules derive new facts. They have the form:
Head :- Body1, Body2, ...
This program contains a base rule:
Reach(y) :- Source(y).
and a recursive rule:
Reach(y) :- Reach(x), Arc(x, y).
Together, they compute the transitive closure of the graph starting from Source.