Conditional formats
brendanzab opened this issue Β· comments
It would be useful to have format descriptions that are refine other formats with predicates:
{ x <- f | e }
For example, in OpenType we might see something like:
{ sfnt_version <- u32be | sfnt_version == 0x00010000 || sfnt_version == "OTTO" }
Rough specification
The typing rules for the core language could look something like:
f : Format x : Repr Format β’ e : Bool
ββββββββββββββββββββββββββββββββββββββββββββββ
{ x <- f | e } : Format
Repr { x <- f | e } = Repr f
s .. s' : f βΉ eβ x : Repr f = eβ β’ eβ = true : Bool
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
s .. s' : { x <- f | eβ } βΉ eβ
{ x <- f | e }
is aFormat
when:f
is aFormat
- assuming
x : Repr Format
,e
is aBool
- the representation of
{ x <- f | e }
isRepr f
- the bit sequence
s .. s'
is recognized with{ x <- f | eβ }
as an expressioneβ
when:- the bit sequence
s .. s'
is recognized withf
as an expressioneβ
- assuming
x : Repr f = eβ
,eβ
is the sameBool
astrue
- the bit sequence
Elaborated typing rules
Some might find it easier to read these rules with explicit typing contexts, Ξ
:
Ξ β’ f : Format Ξ, x : Repr Format β’ e : Bool
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Ξ β’ { x <- f | e } : Format
- under the context
Ξ
,{ x <- f | e }
is aFormat
when:- under the context
Ξ
,f
is aFormat
- under the context
Ξ, x : Repr Format
,e
is aBool
- under the context
Note: The binary interpretation uses a similar notation as Mark Brown in the prolog prototype.
Naming ideas
Some alternative names for these format descriptions could be:
- conditional formats
- refinement formats
- guard formats
Future extensions
Predicate preservation
Eventually we could preserve the guard condition in the representation types, using refinement types:
- f : Format x : Repr Format β’ e : Bool
+ f : Format x : Repr Format β’ e : Prop
ββββββββββββββββββββββββββββββββββββββββββββββ
{ x <- f | e } : Format
- Repr { x <- f | e } = Repr f
+ Repr { x <- f | e } = { x : Repr f | e }
Syntactic Sugar
We could eventually add some sugar for record formats:
{
sfnt_version <- u32be == 0x00010000 || "OTTO",
...
}
Or perhaps:
{
sfnt_version <- u32be if sfnt_version == 0x00010000 || sfnt_version == "OTTO",
...
}