Introduction
Iris is a specification language for structured text formats. A program in Iris is a reader spec. It describes one format: which values a file contains, how they are laid out, how they are collected into arrays, and which conditions they must satisfy. Given a reader spec and an input file, Iris either returns the file’s contents as named, typed data or rejects the file with the position and the statement that failed.
The formats Iris was built for are the benchmark and instance files of combinatorial problems, such as SAT formulas, travelling salesman instances and scheduling problems. Any line- and token-oriented text format is a candidate. The same reader spec works in the command-line tool, in a program that embeds an implementation, and in the playground.
A first example: DIMACS CNF
Section titled “A first example: DIMACS CNF”This small DIMACS CNF file describes a Boolean formula
with three variables and three clauses. A positive number names a variable;
a negative number negates it. Each clause ends with 0.
The reader spec for DIMACS CNF in the format library skips
comment lines beginning with c, captures the two counts from the p cnf
header, then reads one list per clause. The range on each literal checks that it refers to a
declared variable. The sentinel 0 ends each list and is consumed without being
stored. stop "%" handles the end marker used by SATLIB files.
To try this reader without installing anything,
open the example in the playground.
To run it locally, build the CLI, then run
this command from the repository root. The paths are the library’s actual
files. The --dzn option prints the data in MiniZinc’s data format:
iris read formats/dimacs-cnf/dimacs-cnf.iris formats/dimacs-cnf/cases/three-variables/input.txt --dznvars = 3;
clauses = 3;
% clause: array[int] of tuple(array[int] of int)
clause = [([1, -2],), ([2, 3, -1],), ([-3],)];
Read succeeded
The data has the two integer counts and clause, an array of integers with
one row per clause. Rows can have different lengths, so the array is ragged.
The CLI can also print JSON or a summary, and a
Rust program reads the same data through typed accessors.
Invalid input
Section titled “Invalid input”This file also declares three variables, but its second clause uses the
literal 4:
The range on each literal rejects it. Iris stops at the first failure and reports the input position, the value it found, and the line of the reader spec that rejected it:
iris read formats/dimacs-cnf/dimacs-cnf.iris formats/dimacs-cnf/cases/literal-out-of-range/input.txt --dznformats/dimacs-cnf/cases/literal-out-of-range/input.txt:2:3: expected an int in -3..3, found '4'
2 | 1 4 0
| ^
while reading: repeat [1 of 1] > clause
spec: formats/dimacs-cnf/dimacs-cnf.iris:7
Input rejected
A failed read prints no partial data, and the CLI exits with status 1. Every
failure also has a stable error code, here
E-EXPECTED-VALUE.
Iris and Gecode
Section titled “Iris and Gecode”Iris began as the instance reader in the constraint solver Gecode, which uses reader specs to load benchmark files for its examples. The Iris Language Specification defines the language independently of Gecode, and its appendix C lists the deliberate differences from Gecode’s reader. The reader specs in the format library are Gecode’s.
Rust is the reference implementation and the source of the command-line tool and the playground. A Python binding and native C++ and Java implementations are planned; see other implementations.
Where to go next
Section titled “Where to go next”- The tutorial builds three reader specs step by step.
- The guides explain one construct at a time, such as sections, records and checks, or parameters.
- The format library has complete reader specs, sample inputs, data, and rejected inputs.
- The Specification defines the language, including its data model and error codes.
- The tools check, read, format, and edit reader specs.