Skip to content

Commit b5f582d

Browse files
authored
Upgrade Zig version to 0.16.0 (#5)
1 parent c1bb2a3 commit b5f582d

30 files changed

Lines changed: 1576 additions & 1510 deletions

.editorconfig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,5 @@ max_line_length = 100
1717
max_line_length = 150
1818
trim_trailing_whitespace = false
1919

20-
[*.sh]
21-
indent_size = 2
22-
2320
[*.{yml,yaml}]
2421
indent_size = 2

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- name: Install Zig
2626
uses: goto-bus-stop/setup-zig@v2
2727
with:
28-
version: '0.15.2'
28+
version: '0.16.0'
2929

3030
- name: Install System Dependencies
3131
run: |

.github/workflows/tests.yml

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,54 @@ on:
44
workflow_dispatch:
55
push:
66
branches:
7-
- main
7+
- develop
88
tags:
99
- 'v*'
10-
paths-ignore:
11-
- '**.md'
12-
- 'docs/**'
1310
pull_request:
1411
branches:
1512
- main
16-
paths-ignore:
17-
- '**.md'
18-
- 'docs/**'
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
1917

2018
permissions:
2119
contents: read
2220

2321
jobs:
24-
test:
25-
runs-on: ubuntu-latest
22+
tests:
23+
runs-on: ${{ matrix.os }}
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
include:
28+
- os: ubuntu-latest
29+
zig-url: https://ziglang.org/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz
30+
zig-dir: zig-x86_64-linux-0.16.0
31+
- os: macos-latest
32+
zig-url: https://ziglang.org/download/0.16.0/zig-aarch64-macos-0.16.0.tar.xz
33+
zig-dir: zig-aarch64-macos-0.16.0
34+
- os: windows-latest
35+
zig-url: https://ziglang.org/download/0.16.0/zig-x86_64-windows-0.16.0.zip
36+
zig-dir: zig-x86_64-windows-0.16.0
2637

2738
steps:
28-
- name: Checkout Repository
39+
- name: Checkout repository
2940
uses: actions/checkout@v4
3041

31-
- name: Install Dependencies
42+
- name: Install Zig 0.16.0 (Unix)
43+
if: runner.os != 'Windows'
44+
run: |
45+
curl -sSfL ${{ matrix.zig-url }} | tar -xJ
46+
echo "$PWD/${{ matrix.zig-dir }}" >> "$GITHUB_PATH"
47+
48+
- name: Install Zig 0.16.0 (Windows)
49+
if: runner.os == 'Windows'
50+
shell: pwsh
3251
run: |
33-
sudo apt-get update
34-
sudo apt-get install -y make
35-
make install-deps
52+
Invoke-WebRequest -Uri "${{ matrix.zig-url }}" -OutFile zig.zip
53+
Expand-Archive zig.zip -DestinationPath .
54+
echo "$PWD\${{ matrix.zig-dir }}" | Out-File -Append -FilePath $env:GITHUB_PATH
3655
37-
- name: Run Tests
38-
run: make test
56+
- name: Run tests
57+
run: zig build test --summary all

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,6 @@ docs/api/
9898
POST.md
9999
site/
100100
core.*
101+
.claude/
102+
.codex
103+
zig-pkg/

AGENTS.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to coding agents collaborating on this repository.
4+
5+
## Mission
6+
7+
Zodd is a small, embeddable [Datalog](https://en.wikipedia.org/wiki/Datalog) engine written in pure Zig.
8+
It evaluates recursive rules over sets of tuples using semi-naive iteration, merge joins, and indexed extension primitives.
9+
Zodd is designed to be embedded in Zig projects as a library.
10+
Priorities, in order:
11+
12+
1. Correctness of relations, variables, joins, extensions, and fixed-point iteration.
13+
2. Minimal public API for use as a library from other Zig projects.
14+
3. Small dependency footprint and maintainable, well-tested code.
15+
4. Cross-platform support (Linux, macOS, and Windows).
16+
17+
## Core Rules
18+
19+
- Use English for code, comments, docs, and tests.
20+
- Prefer small, focused changes over large refactoring.
21+
- Add comments only when they clarify non-obvious behavior.
22+
- Do not add features, error handling, or abstractions beyond what is needed for the current task.
23+
- Keep the dependency set small: do not add new Zig packages or C libraries without prior discussion.
24+
25+
## Writing Style
26+
27+
- Use Oxford commas in inline lists: "a, b, and c" not "a, b, c".
28+
- Do not use em dashes. Restructure the sentence, or use a colon or semicolon instead.
29+
- Avoid colorful adjectives and adverbs. Write "Datalog engine" not "blazing-fast Datalog engine", "merge join" not "efficient merge join".
30+
- Use noun phrases for checklist items, not imperative verbs. Write "redundant index detection" not "detect redundant indexes".
31+
- Headings in Markdown files must be in the title case: "Build from Source" not "Build from source". Minor words (a, an, the, and, but, or, for, in,
32+
on, at, to, by, of, is, are, was, were, be) stay lowercase unless they are the first word.
33+
34+
## Repository Layout
35+
36+
- `src/lib.zig`: Public API entry point. Re-exports `Relation`, `Variable`, `Iteration`, `ExecutionContext`, join helpers, and extend primitives.
37+
- `src/zodd/relation.zig`: Immutable `Relation` type (sorted, deduplicated tuples).
38+
- `src/zodd/variable.zig`: Mutable `Variable` type for fixed-point iteration, plus the `gallop` search helper.
39+
- `src/zodd/iteration.zig`: `Iteration` driver for semi-naive evaluation.
40+
- `src/zodd/join.zig`: Merge-join algorithms (`joinHelper`, `joinInto`, `joinAnti`).
41+
- `src/zodd/extend.zig`: Leaper-based extension primitives (`ExtendWith`, `FilterAnti`, `ExtendAnti`, `extendInto`).
42+
- `src/zodd/index.zig`: Indexes for keyed lookups.
43+
- `src/zodd/aggregate.zig`: Group-by and aggregation operations.
44+
- `tests/`: Non-unit tests (`integration_tests.zig`, `regression_tests.zig`, `property_tests.zig`, `incremental_tests.zig`).
45+
- `examples/`: Self-contained example programs (`e1_network_reachability.zig` through `e6_dependency_resolution.zig`) built as executables via
46+
`build.zig`.
47+
- `.github/workflows/`: CI workflows (`tests.yml` for unit and integration tests, `docs.yml` for API doc deployment).
48+
- `build.zig` / `build.zig.zon`: Zig build configuration and package metadata.
49+
- `Makefile`: GNU Make wrapper around `zig build` targets.
50+
- `docs/`: Generated API docs land in `docs/api/` (produced by `make docs`).
51+
52+
## Architecture
53+
54+
### Evaluation Pipeline
55+
56+
A Datalog program flows through: base data is loaded into a `Relation` (`relation.zig`). Derived predicates use a `Variable` (`variable.zig`) driven
57+
by an `Iteration` (`iteration.zig`) loop that calls `changed()` until a fixed point. Each iteration extends tuples via `join` (`join.zig`) or `extend`
58+
(`extend.zig`), optionally using indexes (`index.zig`) or aggregates (`aggregate.zig`). Every primitive takes a `std.mem.Allocator` directly; there is
59+
no wrapper context type.
60+
61+
### Relations and Variables Split
62+
63+
- `relation.zig` is the immutable, sorted, deduplicated tuple container used for base facts and finalized results.
64+
- `variable.zig` is the mutable counterpart used inside fixed-point loops; it tracks stable, recent, and to-add tuple sets for semi-naive evaluation.
65+
- New join shapes go in `join.zig`. New leaper-style extensions go in `extend.zig`.
66+
67+
### Indexing and Aggregation
68+
69+
`index.zig` provides keyed lookups used by the extend primitives. `aggregate.zig` provides group-by reductions.
70+
When adding a new join or extension shape, consider whether it needs an index variant and add it alongside the existing ones.
71+
72+
### Public API Surface
73+
74+
Everything re-exported from `src/lib.zig` is part of the public API.
75+
Changes to names or signatures there are breaking.
76+
The rest of `src/zodd/` is internal and may be refactored freely as long as the public surface and its behavior are preserved.
77+
78+
### Dependencies
79+
80+
Zodd depends on two sibling Zig packages declared in `build.zig.zon`:
81+
82+
- `ordered`: sorted container primitives, linked into the `zodd` module for all builds.
83+
- `minish`: property-testing framework, used only by `tests/property_tests.zig` and lazy-loaded in `build.zig`.
84+
85+
Please do not add further dependencies without prior discussion.
86+
87+
## Zig Conventions
88+
89+
- Zig version: 0.16.0 (as declared in `build.zig.zon` and the Makefile's `ZIG_LOCAL` path). CI pins the version declared in `build.zig.zon`.
90+
- Formatting is enforced by `zig fmt`. Run `make format` before committing.
91+
- Naming follows Zig standard-library conventions: `camelCase` for functions (e.g. `joinInto`, `extendInto`, `fromSlice`), `snake_case` for local
92+
variables and struct fields, `PascalCase` for types and structs (e.g. `Relation`, `Variable`, `ExecutionContext`), and `SCREAMING_SNAKE_CASE` for
93+
top-level compile-time constants.
94+
95+
## Required Validation
96+
97+
Run the relevant targets for any change:
98+
99+
| Target | Command | What It Runs |
100+
|----------------|------------------------------------------------|-----------------------------------------------------------------------|
101+
| Unit tests | `make test` | Inline `test` blocks in `src/` plus every file under `tests/` |
102+
| Lint | `make lint` | Checks Zig formatting with `zig fmt --check` over `src/` and `tests/` |
103+
| Examples | `make example` | Builds and runs every example under `examples/` |
104+
| Single example | `make example EXAMPLE=e1_network_reachability` | Runs one example program |
105+
| Docs | `make docs` | Generates API docs into `docs/api` |
106+
| Everything | `make all` | Runs `build`, `test`, `lint`, and `docs` |
107+
108+
## First Contribution Flow
109+
110+
1. Read the relevant module under `src/zodd/` (often `relation.zig`, `variable.zig`, `join.zig`, or `extend.zig`).
111+
2. Implement the smallest change that covers the requirement.
112+
3. Add or update inline `test` blocks in the changed Zig module, or extend a test file under `tests/`, to cover the new behavior.
113+
4. Run `make test` and `make lint`.
114+
5. If public behavior changed, also run `make example` to ensure no example regresses.
115+
116+
Good first tasks:
117+
118+
- Add a new join or extension shape in `src/zodd/join.zig` or `src/zodd/extend.zig` (with an inline `test` block and, if appropriate, an integration
119+
test under `tests/`).
120+
- Improve an existing index strategy in `src/zodd/index.zig`.
121+
- Add a new aggregate operation in `src/zodd/aggregate.zig`.
122+
- Add a new example under `examples/` demonstrating a Datalog pattern, and list it in `examples/README.md`.
123+
124+
## Testing Expectations
125+
126+
- Unit tests live as inline `test` blocks in the module they cover (`src/lib.zig` and `src/zodd/*.zig`). They are discovered automatically via
127+
`std.testing.refAllDecls(@This())` in `src/lib.zig`.
128+
- Non-unit tests live under `tests/` (`integration_tests.zig`, `regression_tests.zig`, `property_tests.zig`, `incremental_tests.zig`) and are
129+
auto-discovered by `build.zig`.
130+
- Property tests use the `minish` dependency and should use fixed seeds so failures are reproducible in CI.
131+
- Every new relation, variable operation, join, extension, index, or aggregate must ship with at least one `test` block that exercises it.
132+
- No public API change is complete without a test covering the new or changed behavior.
133+
134+
## Change Design Checklist
135+
136+
Before coding:
137+
138+
1. Identify which module(s) the change touches (`relation`, `variable`, `iteration`, `join`, `extend`, `index`, `aggregate`, or `context`).
139+
2. Consider whether a new join or extension needs a matching index or anti-variant.
140+
3. Check whether the change is public-API-visible (i.e. re-exported from `src/lib.zig`); if so, treat it as a breaking or additive API change
141+
deliberately.
142+
4. Check cross-platform implications, especially for anything that touches the filesystem, timing, or OS-specific types.
143+
144+
Before submitting:
145+
146+
1. `make test` passes.
147+
2. `make lint` passes.
148+
3. `make example` still succeeds when touching relations, variables, joins, extensions, or iteration.
149+
4. Docs updated (`make docs`) if the public API surface changed, and `ROADMAP.md` ticked/updated if a listed item was implemented.
150+
151+
## Commit and PR Hygiene
152+
153+
- Keep commits scoped to one logical change.
154+
- PR descriptions should include:
155+
1. Behavioral change summary.
156+
2. Tests added or updated.
157+
3. Whether examples were run locally (yes/no), and on which OS.

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ would like to work on or if it has already been resolved.
2828
2929
### Development Workflow
3030

31+
> [!IMPORTANT]
32+
> If you're using an AI-assisted coding tool like Claude Code or Codex, make sure the AI follows the instructions in the [AGENTS.md](AGENTS.md) file.
33+
3134
#### Prerequisites
3235

3336
Install GNU Make on your system if it's not already installed.

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
################################################################################
22
# Configuration and Variables
33
################################################################################
4-
ZIG ?= $(shell which zig || echo ~/.local/share/zig/0.15.2/zig)
4+
ZIG_LOCAL := $(HOME)/.local/share/zig/0.16.0/zig
5+
ZIG ?= $(shell test -x $(ZIG_LOCAL) && echo $(ZIG_LOCAL) || which zig)
56
ZIG_VERSION := $(shell $(ZIG) version)
67
BUILD_TYPE ?= Debug
78
BUILD_OPTS = -Doptimize=$(BUILD_TYPE)

README.md

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[![License](https://img.shields.io/badge/license-MIT-007ec6?label=license&style=flat&labelColor=282c34&logo=open-source-initiative)](https://github.com/CogitatorTech/zodd/blob/main/LICENSE)
1111
[![Examples](https://img.shields.io/badge/examples-view-green?style=flat&labelColor=282c34&logo=zig)](https://github.com/CogitatorTech/zodd/tree/main/examples)
1212
[![Docs](https://img.shields.io/badge/docs-read-blue?style=flat&labelColor=282c34&logo=read-the-docs)](https://CogitatorTech.github.io/zodd/)
13-
[![Zig Version](https://img.shields.io/badge/Zig-0.15.2-orange?logo=zig&labelColor=282c34)](https://ziglang.org/download/)
13+
[![Zig](https://img.shields.io/badge/zig-0.16.0-F7A41D?style=flat&labelColor=282c34&logo=zig)](https://ziglang.org/download/)
1414
[![Release](https://img.shields.io/github/release/CogitatorTech/zodd.svg?label=release&style=flat&labelColor=282c34&logo=github)](https://github.com/CogitatorTech/zodd/releases/latest)
1515

1616
A small embeddable Datalog engine in Zig
@@ -78,7 +78,6 @@ For example:
7878
- Written in pure Zig with a simple API
7979
- Implements semi-naive evaluation for efficient recursive query processing
8080
- Uses immutable, sorted, and deduplicated relations as core data structures
81-
- Supports parallel execution for joins and variable updates
8281
- Provides primitives for multi-way joins, anti-joins, secondary indexes, and aggregation
8382

8483
See [ROADMAP.md](ROADMAP.md) for the list of implemented and planned features.
@@ -105,7 +104,7 @@ Replace `<branch_or_tag>` with the desired branch or release tag, like `main` (f
105104
This command will download Zodd and add it to Zig's global cache and update your project's `build.zig.zon` file.
106105

107106
> [!NOTE]
108-
> Zodd is developed and tested with Zig version 0.15.2.
107+
> Zodd is developed and tested with Zig version 0.16.0.
109108
110109
#### Adding to Build Script
111110

@@ -130,49 +129,42 @@ const std = @import("std");
130129
const zodd = @import("zodd");
131130
132131
pub fn main() !void {
133-
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
132+
var gpa = std.heap.DebugAllocator(.{}){};
134133
defer _ = gpa.deinit();
135134
const allocator = gpa.allocator();
136-
var ctx = try zodd.ExecutionContext.initWithThreads(allocator, 4);
137-
defer ctx.deinit();
138135
139136
const Edge = struct { u32, u32 };
140137
141-
// Create base relation: edges in a graph
142-
var edges = try zodd.Relation(Edge).fromSlice(&ctx, &[_]Edge{
138+
// Base relation: edges in a graph
139+
var edges = try zodd.Relation(Edge).fromSlice(allocator, &[_]Edge{
143140
.{ 1, 2 },
144141
.{ 2, 3 },
145142
.{ 3, 4 },
146143
});
147144
defer edges.deinit();
148145
149-
// Create variable for reachability (transitive closure)
150-
var reachable = zodd.Variable(Edge).init(&ctx);
146+
// Variable holding the reachability closure
147+
var reachable = zodd.Variable(Edge).init(allocator);
151148
defer reachable.deinit();
149+
try reachable.insertSlice(edges.elements);
152150
153-
// Initialize with base edges
154-
try reachable.insertSlice(&ctx, edges.elements);
155-
156-
// Fixed-point iteration: reachable(X,Z) :- reachable(X,Y), edge(Y,Z)
151+
// Fixed-point iteration: reachable(X, Z) :- reachable(X, Y), edge(Y, Z)
157152
while (try reachable.changed()) {
158-
var new_tuples = std.ArrayList(Edge).init(allocator);
159-
defer new_tuples.deinit();
153+
var batch: std.ArrayList(Edge) = .empty;
154+
defer batch.deinit(allocator);
160155
161156
for (reachable.recent.elements) |r| {
162157
for (edges.elements) |e| {
163-
if (e[0] == r[1]) {
164-
try new_tuples.append(.{ r[0], e[1] });
165-
}
158+
if (e[0] == r[1]) try batch.append(allocator, .{ r[0], e[1] });
166159
}
167160
}
168161
169-
if (new_tuples.items.len > 0) {
170-
const rel = try zodd.Relation(Edge).fromSlice(&ctx, new_tuples.items);
162+
if (batch.items.len > 0) {
163+
const rel = try zodd.Relation(Edge).fromSlice(allocator, batch.items);
171164
try reachable.insert(rel);
172165
}
173166
}
174167
175-
// Get final result
176168
var result = try reachable.complete();
177169
defer result.deinit();
178170

ROADMAP.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ This document outlines the features implemented in Zodd and the future goals for
2626
- [x] Persistence
2727
- [x] Secondary indices
2828
- [x] Incremental maintenance
29-
- [x] Parallel execution
30-
- [ ] CLI interface
29+
- [ ] Parallel execution
30+
- [ ] CLI
3131
- [ ] Streaming input
3232
- [ ] Rule DSL
3333
- [ ] Query planner

0 commit comments

Comments
 (0)