Skip to main content

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 .output or .printsize
  • Logic: rules derive new facts

Execution mode is chosen at compile time via --mode. Options are datalog-batch (default), datalog-inc, extend-batch, and extend-inc. 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: int32)
.decl Arc(x: int32, y: int32)
.decl Reach(id: int32)

// --- 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: int32, y: int32)

Here Arc is a binary relation with two int32 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.
Example Source.csv:

1

Example 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.