Skip to content

Commit 09ef349

Browse files
committed
1 parent d6bfeac commit 09ef349

File tree

8 files changed

+336
-9
lines changed

8 files changed

+336
-9
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Context
2+
3+
A context Γ maps variable names to Simplicity types:
4+
5+
Γ = [ `foo` ↦ 𝟙, `bar` ↦ 𝟚^32?, `baz` ↦ 𝟚^32 × 𝟙 ]
6+
7+
We write Γ(`v`) = A to denote that variable `v` has type A in context Γ.
8+
9+
We handle free variables inside SimplicityHL expressions via contexts.
10+
11+
If all free variables are defined in a context, then the context assigns a type to the expression.
12+
13+
We write Γ ⊩ `a`: A to denote that expression `a` has type A in context Γ.
14+
15+
Note that contexts handle only the **target type** of an expression!
16+
17+
Source types are handled by environments and the translation of SimplicityHL to Simplicity.
18+
19+
We write Γ ⊎ Δ to denote the **disjoint union** of Γ and Δ.
20+
21+
We write Γ // Δ to denote the **update** of Γ with Δ. The update contains mappings from both contexts. If a variable is present in both, then the mapping from Δ is taken.
22+
23+
## Unit literal
24+
25+
Γ ⊩ `()`: 𝟙
26+
27+
## Product constructor
28+
29+
If Γ ⊩ `b`: B
30+
31+
If Γ ⊩ `c`: C
32+
33+
Then Γ ⊩ `(b, c)`: B × C
34+
35+
## Left constructor
36+
37+
If Γ ⊩ `b`: B
38+
39+
Then Γ ⊩ `Left(b)`: B + C
40+
41+
For any C
42+
43+
## Right constructor
44+
45+
If Γ ⊩ `c`: c
46+
47+
Then Γ ⊩ `Right(c)`: B + C
48+
49+
For any B
50+
51+
## Bit string literal
52+
53+
If `s` is a bit string of 2^n bits
54+
55+
Then Γ ⊩ `0bs`: 𝟚^(2^n)
56+
57+
## Byte string literal
58+
59+
If `s` is a hex string of 2^n digits
60+
61+
Then Γ ⊩ `0xs`: 𝟚^(4 * 2^n)
62+
63+
## Variable
64+
65+
If Γ(`v`) = B
66+
67+
Then Γ ⊩ `v`: B
68+
69+
## Witness value
70+
71+
Γ ⊩ `witness(name)`: B
72+
73+
For any B
74+
75+
## Jet
76+
77+
If `j` is the name of a jet of type B → C
78+
79+
If Γ ⊩ `b`: B
80+
81+
Then Γ ⊩ `jet::j b`: C
82+
83+
## Chaining
84+
85+
If Γ ⊩ `b`: 𝟙
86+
87+
If Γ ⊩ `c`: C
88+
89+
Then Γ ⊩ `b; c`: C
90+
91+
## Patterns
92+
93+
Type A and pattern `p` create a context denoted by PCtx(A, `p`)
94+
95+
PCtx(A, `v`) := [`v` ↦ A]
96+
97+
PCtx(A, `_`) := []
98+
99+
If `p1` and `p2` map disjoint sets of variables
100+
101+
Then PCtx(A × B, `(p1, p2)`) := PCtx(A, `p1`) ⊎ PCtx(B, `p2`)
102+
103+
## Let statement
104+
105+
If Γ ⊩ `b`: B
106+
107+
If Γ // PCtx(B, `p`) ⊩ `c`: C
108+
109+
Then Γ ⊩ `let p: B = b; c`: C
110+
111+
With alternative syntax
112+
113+
Then Γ ⊩ `let p = b; c`: C
114+
115+
## Match statement
116+
117+
If Γ ⊩ `a`: B + C
118+
119+
If Γ // [`x` ↦ B]`b`: D
120+
121+
If Γ // [`y` ↦ C]`c`: D
122+
123+
Then Γ ⊩ `match a { Left(x) => b, Right(y) => c, }`: D
124+
125+
_(We do not enforce that `x` is used inside `b` or `y` inside `c`. Writing stupid programs is allowed, although there will be a compiler warning at some point.)_
126+
127+
## Left unwrap
128+
129+
If Γ ⊩ `b`: B + C
130+
131+
Then Γ ⊩ `b.unwrap_left()`: B
132+
133+
## Right unwrap
134+
135+
If Γ ⊩ `c`: B + C
136+
137+
Then Γ ⊩ `c.unwrap_right()`: C
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Environment
2+
3+
An environment Ξ maps variable names to Simplicity expressions.
4+
5+
All expressions inside an environment share the same source type A. We say the environment is "from type A".
6+
7+
```
8+
Ξ =
9+
[ foo ↦ unit: (𝟚^32? × 2^32) → 𝟙
10+
, bar ↦ take iden: (𝟚^32? × 𝟚^32) → 𝟚^32?
11+
, baz ↦ drop iden: (𝟚^32? × 𝟚^32) → 𝟚^32
12+
]
13+
```
14+
15+
We use environments to translate variables inside SimplicityHL expressions to Simplicity.
16+
17+
The environment tells us the Simplicity expression that returns the value of each variable.
18+
19+
We translate a SimplicityHL program "top to bottom". Each time a variable is defined, we update the environment to reflect this change.
20+
21+
During the translation, we can ignore the source type of Simplicity expressions (translated SimplicityHL expressions) entirely. We can focus on producing a Simplicity value of the expected target type. Environments ensure that we get input values for each variable that is in scope.
22+
23+
Target types are handled by contexts.
24+
25+
We obtain context Ctx(Ξ) from environment Ξ by mapping each variable `x` from Ξ to the target type of Ξ(`x`):
26+
27+
Ctx(Ξ)(`x`) = B if Ξ(`x`) = a: A → B
28+
29+
## Patterns
30+
31+
32+
Patterns occur in let statements `let p := s`.
33+
34+
Pattern `p` binds the output of SimplicityHL expression `s` to variables.
35+
36+
As we translate `s` to Simplicity, we need an environment that maps the variables from `p` to Simplicity expressions.
37+
38+
If `p` is just a variable `p = a`, then the environment is simply [`a` ↦ iden: A → A].
39+
40+
If `p` is a product of two variables `p = (a, b)`, then the environment is [`a` ↦ take iden: A × B → A, `b` ↦ drop iden: A × B → B].
41+
42+
"take" and "drop" are added as we go deeper in the product hierarchy. The pattern `_` is ignored.
43+
44+
PEnv'(t: A → B, `v`) := [`v` ↦ t]
45+
46+
PEnv'(t: A → B, `_`) := []
47+
48+
If `p1` and `p2` contain disjoint sets of variables
49+
50+
Then PEnv'(t: A → B × C, `(p1, p2)`) := PEnv'(take t: A → B, p1) ⊎ PEnv'(drop t: A → C, p2)
51+
52+
PEnv(A, `p`) := PEnv'(iden: A → A, `p`)
53+
54+
Pattern environments are compatible with pattern contexts:
55+
56+
Ctx(PEnv(A, `p`)) = PCtx(A, `p`)
57+
58+
## Product
59+
60+
We write Product(ΞA, ΞB) to denote the **product** of environment ΞA from A and environment ΞB from B.
61+
62+
The product is an environment from type A × B.
63+
64+
When two Simplicity expressions with environments are joined using the "pair" combinator, then the product of both environments gives us updated bindings for all variables.
65+
66+
If the same variable is bound in both environments, then the binding from the first environment is taken.
67+
68+
If ΞA maps `v` to Simplicity expression a: A → C
69+
70+
Then Product(ΞA, ΞB) maps `v` to take a: A × B → C
71+
72+
If ΞB maps `v` to Simplicity expression b: B → C
73+
74+
If ΞA doesn't map `v`
75+
76+
Then Product(ΞA, ΞB) maps `v` to drop b: A × B → C
77+
78+
Environment products are compatible with context updates:
79+
80+
Ctx(Product(ΞA, ΞB)) = Ctx(ΞB) // Ctx(ΞA)
81+
82+
The order of B and A is reversed: The context of ΞB is updated with the dominant context of ΞA.

docs/simplicityhl-reference/function.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The function then checks if the carry is true, signaling an overflow, in which c
2222
On the last line, the value of `sum` is returned.
2323

2424
The above function is called by writing its name `add` followed by a list of arguments `(40, 2)`.
25-
Each parameter needs an argument, so the list of arguments is as long as the list of arguments.
25+
Each parameter needs an argument, so the list of arguments is as long as the list of parameters.
2626
Here, `x` is assigned the value `40` and `y` is assigned the value `2`.
2727

2828
```rust
@@ -54,7 +54,7 @@ fn level_1() -> u32 {
5454
}
5555

5656
fn level_2() -> u32 {
57-
let (_, next) = jet::increment_32(level_1));
57+
let (_, next) = jet::increment_32(level_1());
5858
next
5959
}
6060
```
@@ -91,7 +91,7 @@ There is no support for "libraries".
9191

9292
## Jets
9393

94-
Jets are predefined and optimized functions for common usecases.
94+
Jets are predefined and optimized functions for common use cases.
9595

9696
```rust
9797
jet::add_32(40, 2)

docs/simplicityhl-reference/let_statement.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ let z: u32 = {
4848
assert!(jet::eq_32(y, 2)); // y == 2
4949
x
5050
};
51-
assert!(jet::eq_32(x, 3)); // z == 3
51+
assert!(jet::eq_32(z, 3)); // z == 3
5252
```
5353

5454
## Pattern matching
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Translation
2+
3+
We write ⟦`e`⟧Ξ to denote the translation of SimplicityHL expression `e` using environment Ξ from A.
4+
5+
The translation produces a Simplicity expression with source type A.
6+
7+
The target type depends on the SimplicityHL expression `e`.
8+
9+
## Unit literal
10+
11+
`()`⟧Ξ = unit: A → 𝟙
12+
13+
## Product constructor
14+
15+
If Ctx(Ξ) ⊩ `b`: B
16+
17+
If Ctx(Ξ) ⊩ `c`: C
18+
19+
Then ⟦`(b, c)`⟧Ξ = pair ⟦`b`⟧Ξ ⟦`c`⟧Ξ: A → B × C
20+
21+
## Left constructor
22+
23+
If Ctx(Ξ) ⊩ `b`: B
24+
25+
Then ⟦`Left(b)`⟧Ξ = injl ⟦`b`⟧Ξ: A → B + C
26+
27+
For any C
28+
29+
## Right constructor
30+
31+
If Ctx(Ξ) ⊩ `c`: C
32+
33+
Then ⟦`Right(c)`⟧Ξ = injr ⟦`c`⟧Ξ: A → B + C
34+
35+
For any B
36+
37+
## Bit string literal
38+
39+
If `s` is a bit string of 2^n bits
40+
41+
Then ⟦`0bs`⟧Ξ = comp unit const 0bs: A → 𝟚^(2^n)
42+
43+
## Byte string literal
44+
45+
If `s` is a hex string of 2^n digits
46+
47+
Then ⟦`0xs`⟧Ξ = comp unit const 0xs: A → 𝟚^(4 * 2^n)
48+
49+
## Variable
50+
51+
If Ctx(Ξ)(`v`) = B
52+
53+
Then ⟦`v`⟧Ξ = Ξ(`v`): A → B
54+
55+
## Witness value
56+
57+
Ctx(Ξ) ⊩ `witness(name)`: B
58+
59+
Then ⟦`witness(name)`⟧Ξ = witness: A → B
60+
61+
## Jet
62+
63+
If `j` is the name of a jet of type B → C
64+
65+
If Ctx(Ξ) ⊩ `b`: B
66+
67+
Then ⟦`jet::j b`⟧Ξ = comp ⟦`b`⟧Ξ j: A → C
68+
69+
## Chaining
70+
71+
If Ctx(Ξ) ⊩ `b`: 𝟙
72+
73+
If Ctx(Ξ) ⊩ `c`: C
74+
75+
Then ⟦`b; c`⟧Ξ = comp (pair ⟦`b`⟧Ξ ⟦`c`⟧Ξ) (drop iden): A → C
76+
77+
## Let statement
78+
79+
If Ctx(Ξ) ⊩ `b`: B
80+
81+
If Product(PEnv(B, `p`), Ξ) ⊩ `c`: C
82+
83+
Then ⟦`let p: B = b; c`⟧Ξ = comp (pair ⟦`b`⟧Ξ iden) ⟦`c`⟧Product(PEnv(B, `p`), Ξ): A → C
84+
85+
## Match statement
86+
87+
If Ctx(Ξ) ⊩ `a`: B + C
88+
89+
If Product(PEnv(B, `x`), Ξ) ⊩ `b`: D
90+
91+
If Product(PEnv(C, `y`), Ξ) ⊩ `c`: D
92+
93+
Then ⟦`match a { Left(x) => b, Right(y) => c, }`⟧Ξ = comp (pair ⟦`a`⟧Ξ iden) (case ⟦`b`⟧Product(PEnv(B, `x`), Ξ) ⟦`c`⟧Product(PEnv(C, `y`), Ξ)): A → D
94+
95+
## Left unwrap
96+
97+
If Ctx(Ξ) ⊩ `b`: B + C
98+
99+
Then ⟦`b.unwrap_left()`⟧Ξ = comp (pair ⟦`b`⟧Ξ unit) (assertl iden #{fail 0}): A → B
100+
101+
## Right unwrap
102+
103+
If Ctx(Ξ) ⊩ `c`: B + C
104+
105+
Then ⟦`c.unwrap_right()`⟧Ξ = comp (pair ⟦`c`⟧Ξ unit) (assertr #{fail 0} iden): A → C

docs/simplicityhl-reference/type.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ Arrays are always of finite length.
100100
| `List<A, 256>` | <256-list | `list![]`, …, `list![a1, …, a255]` |
101101
| `List<A, 512>` | <512-list | `list![]`, …, `list![a1, …, a511]` |
102102
||||
103-
| `List<A,`2<sup>N</sup>`>` | <2<sup>N</sup>-list | `list![]`, …, `list![a1, …, a`(2<sup>N</sup> - 1)`]` |
103+
| `List<A, 2^N>` | <2^N-list | `list![]`, …, `list![a1, …, a_{2^N - 1}]` |
104104

105105
Lists hold a variable number of elements of the same type.
106106
This is similar to [Rust vectors](https://doc.rust-lang.org/std/vec/struct.Vec.html), but SimplicityHL doesn't have a heap.
107-
In SimplicityHL, lists exists on the stack, which is why the maximum list length is bounded.
107+
In SimplicityHL, lists exist on the stack, which is why the maximum list length is bounded.
108108

109109
<2-lists hold fewer than 2 elements, so zero or one element.
110110
<4-lists hold fewer than 4 elements, so zero to three elements.
@@ -156,7 +156,7 @@ Sum types represent values that are of some "left" type in some cases and that a
156156
[They work just like in the either crate](https://docs.rs/either/latest/either/enum.Either.html).
157157
[The Result type from Rust is very similar, too](https://doc.rust-lang.org/std/result/index.html).
158158

159-
A sum type type is generic over two types, `A` and `B`.
159+
A sum type is generic over two types, `A` and `B`.
160160
The value `Left(a)` contains an inner value `a` of type `A`.
161161
The value `Right(b)` contains an inner value `b` of type `B`.
162162

0 commit comments

Comments
 (0)