Skip to content

marcosh/crem

Repository files navigation

CI status

crem stands for compositional representable executable machines.

It allows defining state machines (Mealy machines in fact), composing them to build bigger machines out of smaller ones and then running them and drawing their flow and their state space.

What can you do with crem

Defining state machines

crem allows you to define state machines so that you can enforce which state transitions are actually allowed by your machine.

If you try to implement a machine by running a transition which is not allowed, you will get a compilation error.

More details on how to define a machine at How to create a machine.

Composing state machines

crem allows you to compose machines together to build more complex ones, proving a compositional language to implement state machines.

More details on how to compose machines at How to compose machines

Rendering a state machine

Thanks to the information on the allowed transitions crem collects when you define a machine, it is able to produce a graphical representation of the flow and the state space of your machine.

One example of such an output is

risk manager flow

More details on how to render a machine at How to render a machine

Running a machine

Last but not the least, you can also execute a machine, providing inputs to it and receiving the emitted outputs.

More details on how to run a machine at How to run a machine

Want to know more?

Further documentation can be found in the docs folder.

The examples folder contains a lot of examples, from simple machines to complex ones describing entire workflows.

I would recommend to check:

Be sure to check out also the spec folder, where all the tests of the application are included, to see in practice what you can do with crem.

Development

This is a Haskell Cabal project that uses Nix for development. Nix is optional but recommended.

environment

A Nix shell is available with all the required tools. To enter the shell, issue

# default GHC
nix develop

# custom GHC
nix develop .#ghc90
nix develop .#ghc92

Or, without flakes:

# default GHC
nix-shell

GHC version

The project has a default GHC version that is specified in the flake. At the moment that version is 9.0, because the HLS plugin Wingman currently only builds up to this version.

It is also possible to use other GHC versions to build the project and enter development shells. This allows us to easily test multiple versions.

Building

In a development shell, you can simply build the project with Cabal:

cabal build

This provides us fast incremental builds, ease of debugging, etc.

Inside the development shell, you can also use the commands

# just build the project
build-watch

# execute also the tests
test-watch

Haddock documentation

You can generate and see the [Haddock] documentation by running

cabal haddock --open

Code formatting

Code is formatted using fourmolu version 0.12.0.0.

Cabal flags

We have a cabal flag called errors which allows enabling -Werror. It has a default of False, so that warning are not turned into errors.

In development and CI we use the flag -f errors so that we can avoid any warning in the library code.

Changelog

All changes are tracked in the Changelog.

Project setup

You can find more details on the project setup on Setup.md.

Known limitations

The project is still in its early stage and not everything is crafted to perfection.

Some known limitations to the current state of the project are:

  • crem has not been tested on huge state machines. Compilation times might grow very rapidly.
  • the topologies which crem allows you to define need to be finite, and not particularly big, either. For example, it is not feasible to use Int as the type of vertices for a topology.
  • in its current state, the StateMachine type is not extensible. It has a predefined set of constructors, but maybe there are more which make sense and are not present yet.

Moreover, for current bugs and feature requests, you can check the open issues.

Credits

tweag logo

The initial development of crem was funded by Tweag.

Contributions

Contributions are extremely welcome. If you have any idea on how to improve the library, its code or its documentation, feel free to open an issue, create a pull request, or just contact directly one of the maintainers.

Logo

The crem logo was kindly generated by craiyon.

Resources

If you want to know a bit more of crem and some ideas behind it, here are some additional resources you can check out: