Skip to content

Your First Program

This page walks you through the basic workflow of the Fixen compiler: writing a .fix source file, compiling it to Haskell, and inspecting the output.

The fixen compiler takes a Fixen source file (.fix) and generates a Haskell source file (.hs).

The basic invocation is:

Terminal
~ $ fixen --output <output.hs> <input.fix>
ArgumentDescription
<input.fix>The Fixen source file to compile (positional argument)
--output <output.hs>The output Haskell source file path (required)

The output file must have a .hs extension, and the input file must have a .fix extension. The compiler validates these and exits with an error message if they do not match.

The compiler includes several flags for inspecting intermediate representations:

FlagShortDescription
--show-ast-aPrint the parsed Abstract Syntax Tree
--show-forest-fPrint the rule forest (the internal IR)
--show-db-dPrint the inferred database representation
--no-color-cSuppress colored output
--no-unicode-uSuppress Unicode characters in output

These are useful when debugging a Fixen program or understanding how the compiler processes your code.

Let us create a simple project that incorporates Fixen programs.

Download: my-project.tar.gz

SHA-256: 9eab6e0ea0994846d4ab4c1c716caa6562acdc7a39a0c73f5b5c40884aa7db09

To start, create a cabal project called, say, my-project. The project structure is as follows:

  • Directorymy-project
    • my-project.cabal
    • Directoryapp
      • Main.hs
    • Directoryfix
      • Simple.fix

Configure the project to have the following dependencies that are used by Fixen-generated modules:

  • base (present in virtually every Haskell project)
  • pqueue (for work queues)
  • unordered-containers (facts of a program are stored in HashMaps and HashSets)

For example, we can let my-project.cabal be the following:

my-project.cabal
cabal-version: 3.0
name: my-project
version: 0.1.0.0
build-type: Simple
common warnings
ghc-options: -Wall
executable my-project
import: warnings
main-is: Main.hs
other-modules: Simple
build-depends: base
, pqueue
, unordered-containers
hs-source-dirs: app
default-language: GHC2021

We are going to write a simple Fixen program in fix/Simple.fix, then make use of it to perform fixed-point computation in app/Main.hs. Populate these files with the following content:

fix/Simple.fix
module Simple where
rel SimpleRel: String, Int
rule: |- SimpleRel "start" 0
query facts: SimpleRel - -

This Fixen program defines a single relation SimpleRel consisting of a String and an Int. The only inference rule in this program concludes SimpleRel "start" 0. Finally, the facts query obtains all facts of SimpleRel from the solved fact database.

Before we run cabal build or cabal run to build/run the Cabal project, we must first get the Fixen compiler to generate the Haskell source that implements the work-queue algorithm that we have specified in fix/Simple.fix. To do so, run the following from the root of the project directory:

Compiling the Fixen program
~/my-project $ fixen -o app/Simple.hs fix/Simple.fix

This generates a valid Haskell module app/Simple.hs using the definitions in fix/Simple.fix. You can inspect it to see how Fixen translates your relational declarations into Haskell code — including the database layout, the fact type, and the inference rules.

Once this file has been generated, we can proceed to build and run the project:

Building and Running the Project
~/my-project $ cabal run
[SimpleRel "start" 0]