Skip to content

Commit af0e6ae

Browse files
authored
Generate Haskell code from the Agda spec (#1315)
This PR resolves #1312 and #1343.
2 parents 4d73a1a + 5b1203d commit af0e6ae

58 files changed

Lines changed: 2733 additions & 898 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,5 +171,8 @@ We have several sources of documentation:
171171
does.
172172
([rendered](https://ouroboros-consensus.cardano.intersectmbo.org/pdfs/report.pdf))
173173

174+
- [Formal specification](./docs/agda-spec/): this directory contains the formal (Agda)
175+
specification of the Consensus layer.
176+
174177

175178
[webpage]: https://ouroboros-consensus.cardano.intersectmbo.org/

docs/agda-spec/README.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Agda specification of the Consensus Layer
2+
3+
This directory contains the Agda specification of the Consensus Layer. The current version of the specification only covers block header validation but, since this is work in progress, the specification will eventually cover other consensus-related features such as chain selection, HFC, mempools, etc.
4+
5+
The specification is both *formal* (meaning that is machine-checked and amenable to formal proofs of properties) and *executable* (meaning that can be used as a reference implementation for conformance testing against the real implementation).
6+
7+
## Directory structure
8+
9+
The project is comprised by the following subdirectories:
10+
11+
* `Axiom`: The Agda set theory library
12+
13+
* `Data`: Extensions to the Agda standard library
14+
15+
* `Foreign`: General utilities to automatically generate Haskell code from Agda code
16+
17+
* `Interface`: General-purpose type classes not included in the Agda standard library
18+
19+
* `InterfaceLibrary`: Interfaces exposed by other Cardano components, currently only for the Ledger Layer
20+
21+
- `Common`: Component-agnostic features (e.g. stake pool distributions)
22+
23+
* `Ledger`: Components borrowed from the Ledger specification, most of them actually not Ledger-specific (e.g. slots, epochs, cryptographic primitives)
24+
25+
* `Reflection`: Extensions to the reflection support in the Agda standard library
26+
27+
* `Tactic`: General-purpose tactics not included in the Agda standard library
28+
29+
* `latex`: Auxiliary $$\LaTeX$$-related files required to generate the PDF version of the specification (e.g. fonts, references and static content)
30+
31+
* `Spec`: Root directory of the specification
32+
33+
- `<STS>.lagda` (e.g. `TickNonce.lagda` for TICKN): The definition of `<STS>` in a human-readable format
34+
35+
- `<STS>/Properties.agda` (e.g. `TickNonce/Properties.agda` for TICKN): Proofs of properties about `<STS>`. In particular, this file contains a proof that `<STS>` can be 'computed' by a given function. This means that we have an executable version of `<STS>` which is guaranteed to be correct
36+
37+
- `PDF.lagda`: Source Agda file from which the corresponding PDF file is generated
38+
39+
- `Foreign`: Machinery required for the automatic generation of an executable (Haskell) version of the Agda specification
40+
41+
- `HSConsensus/<STS>.agda` (e.g. `HSConsensus/TickNonce.agda` for TICKN): Contains the code to automatically generate the Haskell types used by `<STS>` and a \*`Step` Haskell function to execute `<STS>`
42+
43+
- `ExternalFunctions.agda`: Automatically generates a Haskell record of 'external functions'. An external function is a function used by the Agda specification whose Haskell version should be provided by the calling environment. Dummy external functions are also available
44+
45+
- `HSTypes.agda`: Generates Haskell versions for common Agda types used in the specification, such as sets and maps
46+
47+
- `HSConsensus.agda`: Top-level Agda module from which the executable specification is generated
48+
49+
- `hs-src`: A Haskell test suite for the executable specification
50+
51+
- `test/<STS>Spec.hs` (e.g. `test/TickNonceSpec.hs` for TICKN): A Haskell program that tests the executable version of `<STS>`
52+
53+
## Generating the PDF file
54+
55+
To generate the specification in PDF format, one can use:
56+
57+
``` bash
58+
> nix build .#agda-spec.docs
59+
```
60+
61+
This command generates the `consensus-spec.pdf` file inside the resulting `pdfs` directory. Alternatively, one can enter the Nix shell:
62+
63+
``` bash
64+
> nix develop .#agda-spec
65+
```
66+
67+
and then use:
68+
69+
``` bash
70+
> make docs
71+
```
72+
73+
This command generates the `consensus-spec.pdf` file inside the resulting `src/dist/pdfs` directory. Also, temporary artifacts resulting from the build (such as `.aux` and `.bbl` files) are stored in `src/latex`. To remove these temporary files, one can use:
74+
75+
``` bash
76+
> make clean
77+
```
78+
79+
## Generating the executable specification
80+
81+
### Building
82+
83+
To build the executable (Haskell) specification, one can use:
84+
85+
``` bash
86+
> nix build .#agda-spec.hsSrc
87+
```
88+
89+
This command compiles the Agda code into Haskell code using the MAlonzo backend, placing the files in the resulting subdirectory `haskell/Spec/MAlonzo/Code`. In addition, it copies the contents of `src/Spec/hs-src` to `haskell/Spec` and completes the `library.other-modules` section of the `cardano-consensus-executable-spec.cabal` file with the names of the Haskell modules just generated.
90+
91+
Alternatively, one can enter the Nix shell:
92+
93+
``` bash
94+
> nix develop .#agda-spec
95+
```
96+
97+
and then use:
98+
99+
``` bash
100+
> make hs
101+
```
102+
103+
This command generates the same results as the previous alternative but using the directory `src/dist` as the temporary directory. As before, one can remove these temporary files by using:
104+
105+
``` bash
106+
> make clean
107+
```
108+
109+
### Testing
110+
111+
To run the test suite for the executable (Haskell) specification, one can use:
112+
113+
``` bash
114+
> nix build .#agda-spec.hsExe --rebuild --print-build-logs 2>&1
115+
```
116+
117+
The test results should show up near the end of the output. Alternatively, one can enter the Nix shell:
118+
119+
``` bash
120+
> nix develop .#agda-spec
121+
```
122+
123+
and then use:
124+
125+
``` bash
126+
> make hsTest
127+
```
128+
129+
## Setup without Nix
130+
131+
It is possible to perform the above-mentioned tasks without the use of Nix, using the instructions below:
132+
133+
- Install [latexmk](https://ctan.org/pkg/latexmk/) and [XeTeX](https://xetex.sourceforge.net/)
134+
135+
- Install Agda version `2.7.0` (e.g. follow the instructions in <https://agda.readthedocs.io/en/v2.7.0/getting-started/installation.html#step-1-install-agda>
136+
)
137+
138+
- In a folder `<LIB>`, clone the dependencies and checkout the respective commits/tags:
139+
140+
| *Dependency* | *Tag/commit* |
141+
|--------------------------------------------------------------------|--------------------------------------------|
142+
| [agda-stdlib](https://github.com/agda/agda-stdlib) | `v2.1.1` |
143+
| [agda-stdlib-classes](https://github.com/agda/agda-stdlib-classes) | `73f4da05aeea040fea4587629f9fd83a8f04e656` |
144+
| [agda-stdlib-meta](https://github.com/agda/agda-stdlib-meta) | `v2.1.1` |
145+
146+
- Create a file `<LIB>/libraries` with the following content:
147+
```
148+
<LIB>/agda-stdlib/standard-library.agda-lib
149+
<LIB>/agda-stdlib-classes/agda-stdlib-classes.agda-lib
150+
<LIB>/agda-stdlib-meta/agda-stdlib-meta.agda-lib
151+
```
152+
153+
- Instead of `agda` use `agda --library-file <LIB>/libraries`. For example, to typecheck `Everything.agda`:
154+
```
155+
cd src/
156+
agda --library-file <LIB>/libraries Everything.agda
157+
```
158+
159+
To build targets from the Makefile (e.g. `docs`), use:
160+
```
161+
AGDA="agda --library-file <LIB>/libraries" make <TARGET>
162+
```

docs/agda-spec/nix/sources.json

Lines changed: 0 additions & 27 deletions
This file was deleted.

docs/agda-spec/nix/sources.nix

Lines changed: 0 additions & 198 deletions
This file was deleted.

0 commit comments

Comments
 (0)