Context
A context Γ maps variable names to Simplicity types:
Γ = [ foo ↦ 𝟙, bar ↦ 𝟚^32?, baz ↦ 𝟚^32 × 𝟙 ]
We write Γ(v) = A to denote that variable v has type A in context Γ.
We handle free variables inside SimplicityHL expressions via contexts.
If all free variables are defined in a context, then the context assigns a type to the expression.
We write Γ ⊩ a: A to denote that expression a has type A in context Γ.
Note that contexts handle only the target type of an expression!
Source types are handled by environments and the translation of SimplicityHL to Simplicity.
We write Γ ⊎ Δ to denote the disjoint union of Γ and Δ.
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.
Unit literal
Γ ⊩ (): 𝟙
Product constructor
If Γ ⊩ b: B
If Γ ⊩ c: C
Then Γ ⊩ (b, c): B × C
Left constructor
If Γ ⊩ b: B
Then Γ ⊩ Left(b): B + C
For any C
Right constructor
If Γ ⊩ c: c
Then Γ ⊩ Right(c): B + C
For any B
Bit string literal
If s is a bit string of 2^n bits
Then Γ ⊩ 0bs: 𝟚^(2^n)
Byte string literal
If s is a hex string of 2^n digits
Then Γ ⊩ 0xs: 𝟚^(4 * 2^n)
Variable
If Γ(v) = B
Then Γ ⊩ v: B
Witness value
Γ ⊩ witness(name): B
For any B
Jet
If j is the name of a jet of type B → C
If Γ ⊩ b: B
Then Γ ⊩ jet::j b: C
Chaining
If Γ ⊩ b: 𝟙
If Γ ⊩ c: C
Then Γ ⊩ b; c: C
Patterns
Type A and pattern p create a context denoted by PCtx(A, p)
PCtx(A, v) := [v ↦ A]
PCtx(A, _) := []
If p1 and p2 map disjoint sets of variables
Then PCtx(A × B, (p1, p2)) := PCtx(A, p1) ⊎ PCtx(B, p2)
Let statement
If Γ ⊩ b: B
If Γ // PCtx(B, p) ⊩ c: C
Then Γ ⊩ let p: B = b; c: C
With alternative syntax
Then Γ ⊩ let p = b; c: C
Match statement
If Γ ⊩ a: B + C
If Γ // [x ↦ B] ⊩ b: D
If Γ // [y ↦ C] ⊩ c: D
Then Γ ⊩ match a { Left(x) => b, Right(y) => c, }: D
(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.)
Left unwrap
If Γ ⊩ b: B + C
Then Γ ⊩ b.unwrap_left(): B
Right unwrap
If Γ ⊩ c: B + C
Then Γ ⊩ c.unwrap_right(): C