Skip to content

Commit 5bc6398

Browse files
committed
Add some sketches of Fathom’s core in Idris 2
1 parent 3ae5a29 commit 5bc6398

File tree

12 files changed

+724
-23
lines changed

12 files changed

+724
-23
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ jobs:
2323
uses: cachix/install-nix-action@v17
2424

2525
- name: cargo check
26-
run: nix develop .#${{ matrix.rust-toolchain }} --command cargo check
26+
run: nix develop .#rust-${{ matrix.rust-toolchain }} --command cargo check
2727
- name: cargo build
28-
run: nix develop .#${{ matrix.rust-toolchain }} --command cargo build
28+
run: nix develop .#rust-${{ matrix.rust-toolchain }} --command cargo build
2929
- name: cargo test
30-
run: nix develop .#${{ matrix.rust-toolchain }} --command cargo test
30+
run: nix develop .#rust-${{ matrix.rust-toolchain }} --command cargo test
3131

3232
cargo-fmt:
3333
runs-on: ubuntu-latest
@@ -42,7 +42,7 @@ jobs:
4242
uses: cachix/install-nix-action@v17
4343

4444
- name: Run cargo fmt
45-
run: nix develop .#${{ matrix.rust-toolchain }} --command cargo fmt
45+
run: nix develop .#rust-${{ matrix.rust-toolchain }} --command cargo fmt
4646

4747
cargo-clippy:
4848
runs-on: ubuntu-latest
@@ -62,7 +62,7 @@ jobs:
6262
run: rm --recursive --force --verbose ~/.cargo/bin
6363

6464
- name: Run cargo clippy
65-
run: nix develop .#${{ matrix.rust-toolchain }} --command cargo clippy -- --deny warnings
65+
run: nix develop .#rust-${{ matrix.rust-toolchain }} --command cargo clippy -- --deny warnings
6666

6767
nixpkgs-fmt:
6868
runs-on: ubuntu-latest
@@ -74,4 +74,4 @@ jobs:
7474
uses: cachix/install-nix-action@v17
7575

7676
- name: Run nixpkgs-fmt
77-
run: nix develop --command nixpkgs-fmt --check .
77+
run: nix develop .#nix --command nixpkgs-fmt --check .

experiments/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ In rough chronological order:
1313
5. [rust-prototype-v2](./rust-prototype-v2) (@brendanzab)
1414
6. [makam-spec](./makam-spec) (@brendanzab)
1515
7. [rust-prototype-v3](./rust-prototype-v3) (@brendanzab)
16+
8. [idris](./idris) (@brendanzab)
1617

1718
The following repositories also provided us with valuable experience along the way:
1819

experiments/idris/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build

experiments/idris/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Core language experiments in Idris 2
2+
3+
Some sketches of Fathom’s core language using Idris as a logical framework.
4+
5+
```command
6+
$ idris2 --repl experiments/idris/fathom.ipkg
7+
Main> :load "src/Playground.idr"
8+
```

experiments/idris/fathom.ipkg

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package fathom
2+
-- version =
3+
-- authors =
4+
-- maintainers =
5+
-- license =
6+
-- brief =
7+
-- readme =
8+
-- homepage =
9+
-- sourceloc =
10+
-- bugtracker =
11+
12+
-- packages to add to search path
13+
-- depends =
14+
15+
-- modules to install
16+
modules = Fathom
17+
, Fathom.Base
18+
, Fathom.Closed.InductiveRecursive
19+
, Fathom.Closed.IndexedInductive
20+
, Fathom.Open.Record
21+
22+
-- main file (i.e. file to load at REPL)
23+
-- main =
24+
25+
-- name of executable
26+
-- executable =
27+
-- opts =
28+
sourcedir = "src"
29+
builddir = "build"
30+
outputdir = "build/exec"
31+
32+
-- script to run before building
33+
-- prebuild =
34+
35+
-- script to run after building
36+
-- postbuild =
37+
38+
-- script to run after building, before installing
39+
-- preinstall =
40+
41+
-- script to run after installing
42+
-- postinstall =
43+
44+
-- script to run before cleaning
45+
-- preclean =
46+
47+
-- script to run after cleaning
48+
-- postclean =

experiments/idris/src/Fathom.idr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
||| A sketch of core Fathom in Idris 2

experiments/idris/src/Fathom/Base.idr

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
module Fathom.Base
2+
3+
4+
import Data.Colist
5+
import Data.List
6+
7+
8+
------------------
9+
-- USEFUL TYPES --
10+
------------------
11+
12+
13+
||| A value that is refined by a proposition.
14+
|||
15+
||| This is a bit like `(x : A ** B)`, but with the second element erased.
16+
public export
17+
record Refine (0 A : Type) (0 P : A -> Type) where
18+
constructor MkRefine
19+
||| The wrapped value
20+
value : A
21+
||| The proof of the proposition
22+
0 prf : P value
23+
24+
||| Refine a value with a proposition
25+
public export
26+
refine : {0 A : Type} -> {0 P : A -> Type} -> (value : A) -> {auto 0 prf : P value} -> Refine A P
27+
refine value {prf} = MkRefine { value, prf }
28+
29+
30+
||| Singleton types
31+
|||
32+
||| Inspired by [this type](https://agda.readthedocs.io/en/v2.5.4.1/language/with-abstraction.html#the-inspect-idiom)
33+
||| from the Agda docs.
34+
public export
35+
data Sing : {0 A : Type} -> (x : A) -> Type where
36+
MkSing : {0 A : Type} -> {0 x : A} -> (y : A) -> {auto prf : x = y} -> Sing x
37+
38+
||| Convert a singleton back to its underlying value
39+
public export
40+
value : {0 Val : Type} -> {0 x : Val} -> Sing x -> Val
41+
value (MkSing y) = y
42+
43+
44+
---------------------------
45+
-- ENCODER/DECODER PAIRS --
46+
---------------------------
47+
48+
-- Inspiration taken from Narcissus:
49+
--
50+
-- * [Narcissus: Correct-by-Construction Derivation of Decoders and Encoders from Binary Formats](https://dl.acm.org/doi/10.1145/3341686)
51+
-- by Delaware et. al.
52+
-- * [`Narcissus/Common/Specs.v`](https://github.com/mit-plv/fiat/blob/master/src/Narcissus/Common/Specs.v)
53+
--
54+
-- TODO: Add support for [Narcissus-style stores](https://github.com/mit-plv/fiat/tree/master/src/Narcissus/Stores)
55+
56+
parameters (Source : Type, Target : Type)
57+
58+
||| Decoders consume a _target value_ and produce either:
59+
|||
60+
||| - a _source value_ and _remaining target value_
61+
||| - or nothing if in error occurred
62+
|||
63+
||| @ Source The type of source values (usually an in-memory data structure)
64+
||| @ Target The type of target values (usually a byte-stream)
65+
public export
66+
Decode : Type
67+
Decode = Target -> Maybe (Source, Target)
68+
69+
||| Encoders take a _source value_ and _remaining target value_ and produce either:
70+
|||
71+
||| - an _updated target value_
72+
||| - or nothing if in error occurred
73+
|||
74+
||| @ Source The type of source values (usually an in-memory data structure)
75+
||| @ Target The type of target values (usually a byte-stream)
76+
public export
77+
Encode : Type
78+
Encode = Source -> Target -> Maybe Target
79+
80+
81+
----------------------
82+
-- ENCODING TARGETS --
83+
----------------------
84+
85+
86+
||| A possibly infinite stream of bits
87+
public export
88+
BitStream : Type
89+
BitStream = Colist Bool
90+
91+
92+
||| A possibly infinite stream of bytes
93+
public export
94+
ByteStream : Type
95+
ByteStream = Colist Bits8
96+
97+
98+
||| A finite bit buffer
99+
public export
100+
BitBuffer : Type
101+
BitBuffer = List Bool
102+
103+
104+
||| A finite byte buffer
105+
public export
106+
ByteBuffer : Type
107+
ByteBuffer = List Bits8
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
||| A closed universe of format descriptions as an inductive type, where the
2+
||| in-memory representation is tracked as an index on the type.
3+
4+
module Fathom.Closed.IndexedInductive
5+
6+
7+
import Data.Colist
8+
import Data.Vect
9+
10+
import Fathom.Base
11+
12+
13+
-------------------------
14+
-- FORMAT DESCRIPTIONS --
15+
-------------------------
16+
17+
18+
||| Universe of format descriptions indexed by their machine representations
19+
public export
20+
data FormatOf : (0 Rep : Type) -> Type where
21+
End : FormatOf Unit
22+
Fail : FormatOf Void
23+
Pure : {0 A : Type} -> (x : A) -> FormatOf (Sing x)
24+
Skip : {0 A : Type} -> (f : FormatOf A) -> (def : A) -> FormatOf Unit
25+
Repeat : {0 A : Type} -> (len : Nat) -> FormatOf A -> FormatOf (Vect len A)
26+
Bind : {0 A : Type} -> {0 B : A -> Type} -> (f : FormatOf A) -> ((x : A) -> FormatOf (B x)) -> FormatOf (x : A ** B x)
27+
28+
29+
30+
---------------------------
31+
-- ENCODER/DECODER PAIRS --
32+
---------------------------
33+
34+
export
35+
decode : {0 Rep : Type} -> (f : FormatOf Rep) -> Decode Rep (Colist a)
36+
decode End [] = Just ((), [])
37+
decode End (_::_) = Nothing
38+
decode Fail _ = Nothing
39+
decode (Pure x) buffer =
40+
Just (MkSing x, buffer)
41+
decode (Skip f _) buffer = do
42+
(x, buffer') <- decode f buffer
43+
Just ((), buffer')
44+
decode (Repeat 0 f) buffer =
45+
Just ([], buffer)
46+
decode (Repeat (S len) f) buffer = do
47+
(x, buffer') <- decode f buffer
48+
(xs, buffer'') <- decode (Repeat len f) buffer'
49+
Just (x :: xs, buffer'')
50+
decode (Bind f1 f2) buffer = do
51+
(x, buffer') <- decode f1 buffer
52+
(y, buffer'') <- decode (f2 x) buffer'
53+
Just ((x ** y), buffer'')
54+
55+
56+
export
57+
encode : {0 Rep : Type} -> (f : FormatOf Rep) -> Encode Rep (Colist a)
58+
encode End () _ = Just []
59+
encode (Pure x) (MkSing _) buffer = Just buffer
60+
encode (Skip f def) () buffer = do
61+
encode f def buffer
62+
encode (Repeat Z f) [] buffer = Just buffer
63+
encode (Repeat (S len) f) (x :: xs) buffer = do
64+
buffer' <- encode (Repeat len f) xs buffer
65+
encode f x buffer'
66+
encode (Bind f1 f2) (x ** y) buffer = do
67+
buffer' <- encode (f2 x) y buffer
68+
encode f1 x buffer'
69+
70+
71+
-----------------
72+
-- EXPERIMENTS --
73+
-----------------
74+
75+
76+
either : (cond : Bool) -> FormatOf a -> FormatOf b -> FormatOf (if cond then a else b)
77+
either True f1 _ = f1
78+
either False _ f2 = f2
79+
80+
orPure : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf (if cond then a else Sing def)
81+
orPure True f _ = f
82+
orPure False _ def = Pure def

0 commit comments

Comments
 (0)