
| CREATOR | Mark Raynsford |
| DATE | 2026-07-21T14:19:38+00:00 |
| DESCRIPTION | Specification for the Zeniro file format. |
| IDENTIFIER | 0c311fbd-c9a7-4ef5-ba1e-fc69b0bb47fa |
| LANGUAGE | en |
| RIGHTS | Public Domain |
| TITLE | Zeniro 1.0 |
The fixed-size file header indicating the type and version of the file:
Format major version 1, minor version 0
|- Zeniro identifier -| |---------| |---------|
00000000 89 5a 4e 52 0d 0a 1a 0a 00 00 00 01 00 00 00 00 |.ZNR............|
The info section containing JSON-encoded information about the contents of
the file:
|-Identifier ZNR_INFO-| |-Section size (510) -|
00000010 5a 4e 52 5f 49 4e 46 4f 00 00 00 00 00 00 01 fe |ZNR_INFO........|
Text length (506)
|---------|
00000020 00 00 01 fa 7b 22 24 53 63 68 65 6d 61 22 3a 22 |....{"$Schema":"|
00000030 75 72 6e 3a 63 6f 6d 2e 69 6f 37 6d 2e 7a 65 6e |urn:com.io7m.zen|
00000040 69 72 6f 3a 69 6e 66 6f 3a 31 2e 30 22 2c 22 53 |iro:info:1.0","S|
00000050 68 61 70 65 22 3a 7b 22 40 53 68 61 70 65 22 3a |hape":{"@Shape":|
00000060 22 4d 65 73 68 22 2c 22 4c 65 6e 67 74 68 22 3a |"Mesh","Length":|
00000070 31 30 30 2c 22 49 6e 64 65 78 22 3a 7b 22 43 6f |100,"Index":{"Co|
00000080 75 6e 74 22 3a 31 30 30 2c 22 54 79 70 65 22 3a |unt":100,"Type":|
00000090 22 49 4e 44 45 58 5f 31 36 22 7d 2c 22 42 6f 75 |"INDEX_16"},"Bou|
000000a0 6e 64 73 22 3a 7b 22 58 4d 69 6e 69 6d 75 6d 22 |nds":{"XMinimum"|
000000b0 3a 30 2e 30 2c 22 58 4d 61 78 69 6d 75 6d 22 3a |:0.0,"XMaximum":|
000000c0 31 30 30 30 30 2e 30 2c 22 59 4d 69 6e 69 6d 75 |10000.0,"YMinimu|
000000d0 6d 22 3a 30 2e 30 2c 22 59 4d 61 78 69 6d 75 6d |m":0.0,"YMaximum|
000000e0 22 3a 31 30 30 30 30 2e 31 2c 22 5a 4d 69 6e 69 |":10000.1,"ZMini|
000000f0 6d 75 6d 22 3a 30 2e 30 2c 22 5a 4d 61 78 69 6d |mum":0.0,"ZMaxim|
00000100 75 6d 22 3a 31 30 30 30 30 2e 32 7d 7d 2c 22 53 |um":10000.2}},"S|
00000110 74 72 75 63 74 75 72 65 22 3a 7b 22 43 6f 6d 70 |tructure":{"Comp|
00000120 6f 6e 65 6e 74 73 22 3a 5b 7b 22 4e 61 6d 65 22 |onents":[{"Name"|
00000130 3a 22 70 6f 73 69 74 69 6f 6e 22 2c 22 54 79 70 |:"position","Typ|
00000140 65 22 3a 22 46 4c 4f 41 54 5f 33 32 5f 56 45 43 |e":"FLOAT_32_VEC|
00000150 33 22 2c 22 53 65 6d 61 6e 74 69 63 22 3a 22 63 |3","Semantic":"c|
00000160 6f 6d 2e 69 6f 37 6d 2e 7a 65 6e 69 72 6f 2e 70 |om.io7m.zeniro.p|
00000170 6f 73 69 74 69 6f 6e 22 7d 2c 7b 22 4e 61 6d 65 |osition"},{"Name|
00000180 22 3a 22 6e 6f 72 6d 61 6c 22 2c 22 54 79 70 65 |":"normal","Type|
00000190 22 3a 22 46 4c 4f 41 54 5f 31 36 5f 56 45 43 33 |":"FLOAT_16_VEC3|
000001a0 22 2c 22 53 65 6d 61 6e 74 69 63 22 3a 22 63 6f |","Semantic":"co|
000001b0 6d 2e 69 6f 37 6d 2e 7a 65 6e 69 72 6f 2e 6e 6f |m.io7m.zeniro.no|
000001c0 72 6d 61 6c 22 7d 2c 7b 22 4e 61 6d 65 22 3a 22 |rmal"},{"Name":"|
000001d0 75 76 22 2c 22 54 79 70 65 22 3a 22 46 4c 4f 41 |uv","Type":"FLOA|
000001e0 54 5f 31 36 5f 56 45 43 32 22 2c 22 53 65 6d 61 |T_16_VEC2","Sema|
000001f0 6e 74 69 63 22 3a 22 63 6f 6d 2e 69 6f 37 6d 2e |ntic":"com.io7m.|
00000200 7a 65 6e 69 72 6f 2e 74 65 78 74 75 72 65 5f 63 |zeniro.texture_c|
00000210 6f 6f 72 64 69 6e 61 74 65 22 7d 5d 7d 7d 00 00 |oordinate"}]}}..|
|---|
Padding
The component data:
|-Identifier ZNR_DATA-| |-Section size (2200)-|
00000220 5a 4e 52 5f 44 41 54 41 00 00 00 00 00 00 08 98 |ZNR_DATA........|
00000230 00 00 00 00 3f 80 00 00 40 00 00 00 00 00 2e 66 |....?...@......f|
00000240 32 66 00 00 21 1f 42 c8 00 00 42 ca 00 00 42 cc |2f..!.B...B...B.|
00000250 00 00 21 1f 2f 0a 32 b8 21 1f 25 1f 43 48 00 00 |..!./.2.!.%.CH..|
00000260 43 49 00 00 43 4a 00 00 25 1f 2f ae 33 0a 25 1f |CI..CJ..%./.3.%.|
..............................................................................
00000aa0 46 19 24 00 46 19 28 00 3b d7 3c 52 3c b8 3b d7 |F.$.F.(.;.<R<.;.|
00000ab0 3b ec 46 1a b0 00 46 1a b4 00 46 1a b8 00 3b ec |;.F...F...F...;.|
00000ac0 3c 5c 3c c3 3b ec 3c 00 00 00 00 00 00 00 00 00 |<\<.;.<.........|
|-------Padding-------|
The (optional) index data:
|-Identifier ZNR_INDX-| |- Section size (200)-|
00000ad0 5a 4e 52 5f 49 4e 44 58 00 00 00 00 00 00 00 c8 |ZNR_INDX........|
00000ae0 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 |................|
00000af0 00 08 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 0f |................|
..............................................................................
00000b90 00 58 00 59 00 5a 00 5b 00 5c 00 5d 00 5e 00 5f |.X.Y.Z.[.\.].^._|
00000ba0 00 60 00 61 00 62 00 63 00 00 00 00 00 00 00 00 |.`.a.b.c........|
|-------Padding-------|
The metadata section containing arbitrary application-provided text:
|-Identifier ZNR_META-| |- Section size (92) -|
00000bb0 5a 4e 52 5f 4d 45 54 41 00 00 00 00 00 00 00 5c |ZNR_META.......\|
00000bc0 00 00 00 58 7b 22 64 63 2e 69 64 65 6e 74 69 66 |...X{"dc.identif|
00000bd0 69 65 72 22 3a 5b 22 36 31 35 61 36 31 35 38 2d |ier":["615a6158-|
00000be0 39 63 32 39 2d 34 35 61 61 2d 38 36 33 61 2d 31 |9c29-45aa-863a-1|
00000bf0 62 36 61 62 63 31 33 37 30 30 61 22 5d 2c 22 64 |b6abc13700a"],"d|
00000c00 63 2e 72 69 67 68 74 73 22 3a 5b 22 50 75 62 6c |c.rights":["Publ|
00000c10 69 63 20 44 6f 6d 61 69 6e 22 5d 7d 00 00 00 00 |ic Domain"]}....|
00000c20 10 10 10 10 20 20 20 20 00 00 00 00 00 00 00 06 |.... ........|
An application-specific private section:
|-Identifier HELLO! -| |- Section size (0) -|
00000c30 48 45 4c 4c 4f 21 00 00 00 00 00 00 00 00 00 00 |HELLO!..........|
The end section:
|-Identifier ZNR_END!-| |- Section size (0) -|
00000c40 5a 4e 52 5f 45 4e 44 21 00 00 00 00 00 00 00 00 |ZNR_END!........|
00000c50
{
"$Schema": "urn:com.io7m.zeniro:info:1.0",
"Shape": {
"@Shape": "Mesh",
"Length": 100,
"Index": {
"Count": 100,
"Type": "INDEX_16"
},
"Bounds": {
"XMinimum": 0.0,
"XMaximum": 10000.0,
"YMinimum": 0.0,
"YMaximum": 10000.1,
"ZMinimum": 0.0,
"ZMaximum": 10000.2
}
},
"Structure": {
"Components": [
{
"Name": "position",
"Type": "FLOAT_32_VEC3",
"Semantic": "com.io7m.zeniro.position"
},
{
"Name": "normal",
"Type": "FLOAT_16_VEC3",
"Semantic": "com.io7m.zeniro.normal"
},
{
"Name": "uv",
"Type": "FLOAT_16_VEC2",
"Semantic": "com.io7m.zeniro.texture_coordinate"
}
]
}
}
| Notation | Description |
|---|---|
| e ∈ A | e is an element of the set A |
| e ∉ A | e is not an element of the set A |
| { x₀, x₁, ... xₙ } | A set consisting of values from x₀ to xₙ |
| { e ∈ A | p(e) } | A set consisting of the elements of A for which the proposition p holds |
| |A| | The cardinality of the set A; a measure of the number of elements in A |
| ∅ | The empty set |
| 𝔹 | The booleans |
| ℕ | The natural numbers |
| ℝ | The real numbers |
| ℤ | The integers |
| [a, b] | A closed interval in a set (given separately or implicit from the types of a and b), from a to b, including a and b |
| (a, b] | A closed interval in a set (given separately or implicit from the types of a and b), from a to b, excluding a but including b |
| [a, b) | A closed interval in a set (given separately or implicit from the types of a and b), from a to b, including a but excluding b |
| (a, b) | A closed interval in a set (given separately or implicit from the types of a and b), from a to b, excluding a and b |
| A ⊂ B | A is a subset of, and is not equal to, B |
| A ⊆ B | A is a subset of, or is equal to, B |
| A ∩ B | The smallest set of elements that appear in both A and B (intersection). |
Inductive fileT := FileT {
(** The file info. *)
fileInfo : infoT;
(** The file data; the array of structure values. *)
fileData : list structureValueT;
(** The file index data. *)
fileIndexData : option (list Z);
(** The metadata. *)
fileMetadata : metadataT
}.
Inductive infoT : Set := Info {
(** The shape of the data. *)
infoShape : shapeT;
(** The structure of the data. *)
infoStructure : structureT;
(** The list of extensions. *)
infoExtensions : list extensionT
}.
Definition infoWF (i : infoT) : Prop := structureWF (infoStructure i).
Inductive metadataT := MetadataT {
metaValues : MetadataStringMap.t (list string)
}.
Definition fileWFIndexDataPresentIf0 (file : fileT) : Prop := shapeIndexInfo (infoShape (fileInfo file)) <> None -> fileIndexData file <> None.
Definition fileWFIndexDataPresentIf1 (file : fileT) : Prop := fileIndexData file <> None -> shapeIndexInfo (infoShape (fileInfo file)) <> None.
Definition fileWFIndexDataPresentIff (file : fileT) : Prop := shapeIndexInfo (infoShape (fileInfo file)) <> None <-> fileIndexData file <> None.
Definition fileWFIndexData (file : fileT) : Prop :=
let info := fileInfo file in
let shape := infoShape info in
match shapeIndexInfo shape with
| Some indexInfo =>
let indexType := indexType indexInfo in
match fileIndexData file with
| Some indexData => indexArrayWF (Z.of_N (shapeElementCount shape)) (IndexArray indexType indexData)
| None => True
end
| None => True
end.
Definition fileWFDataLength (f : fileT) : Prop := length (fileData f) = N.to_nat (shapeElementCount (infoShape (fileInfo f))).
Definition fileWFDataTyped (f : fileT) : Prop :=
let type := infoStructure (fileInfo f) in
Forall (fun e => structureValueHasStructureType e type) (fileData f).
Definition fileWF (file : fileT) : Prop :=
fileWFIndexDataPresentIff file
/\ fileWFIndexData file
/\ fileWFDataLength file
/\ fileWFDataTyped file
/\ infoWF (fileInfo file).
Inductive shapeT : Set := | SArray1D : shapeArray1DT -> shapeT | SArray2D : shapeArray2DT -> shapeT | SArray3D : shapeArray3DT -> shapeT | SMesh : shapeMeshT -> shapeT.
Inductive shapeArray1DT : Set := ShapeArray1D {
shapeArray1DLength : N;
}.
Inductive shapeArray2DT : Set := ShapeArray2D {
shapeArray2DSizeX : N;
shapeArray2DSizeY : N;
}.
Inductive shapeArray3DT : Set := ShapeArray3D {
shapeArray3DSizeX : N;
shapeArray3DSizeY : N;
shapeArray3DSizeZ : N;
}.
Inductive shapeMeshT : Set := ShapeMeshT {
shapeMeshLength : N;
shapeMeshBounds : option boundsT;
shapeMeshIndex : option indexInfoT;
}.
Definition shapeElementCount (shape : shapeT) : N := match shape with | SArray1D a => shapeArray1DLength a | SArray2D a => (shapeArray2DSizeX a) * (shapeArray2DSizeY a) | SArray3D a => (shapeArray3DSizeX a) * (shapeArray3DSizeY a) * (shapeArray3DSizeZ a) | SMesh a => shapeMeshLength a end.
Inductive boundsT : Set := Bounds {
(** The minimum inclusive value on the X axis. *)
boundsXMinimum : R;
(** The maximum inclusive value on the X axis. *)
boundsXMaximum : R;
(** The minimum inclusive value on the Y axis. *)
boundsYMinimum : R;
(** The maximum inclusive value on the Y axis. *)
boundsYMaximum : R;
(** The minimum inclusive value on the Z axis. *)
boundsZMinimum : R;
(** The maximum inclusive value on the Z axis. *)
boundsZMaximum : R
}.
Definition boundsXOrder (b : boundsT) : Prop := (boundsXMinimum b) <= (boundsXMaximum b).
Definition boundsYOrder (b : boundsT) : Prop := (boundsYMinimum b) <= (boundsYMaximum b).
Definition boundsZOrder (b : boundsT) : Prop := (boundsZMinimum b) <= (boundsZMaximum b).
Definition boundsWellFormed (b : boundsT) : Prop :=
(boundsXOrder b)
/\ (boundsYOrder b)
/\ (boundsZOrder b)
.
Inductive indexInfoT : Set := IndexInfo {
(** The index type. *)
indexType: indexTypeT;
(** The number of indices. *)
indexCount: Z;
(** The semantics of indices. *)
indexSemantic: indexSemanticT
}.
Inductive indexTypeT : Set := (** Index values are 8-bit unsigned integers. *) | INDEX_8 (** Index values are 16-bit unsigned integers. *) | INDEX_16 (** Index values are 32-bit unsigned integers. *) | INDEX_32 .
Inductive indexSemanticT : Set := (** Indices represent a list of line segments. *) | INDEX_SEMANTIC_LINE_LIST (** Indices represent a list of line segments (strips). *) | INDEX_SEMANTIC_LINE_STRIP (** Indices represent a list of triangles. *) | INDEX_SEMANTIC_TRIANGLE_LIST (** Indices represent a list of triangles (strips). *) | INDEX_SEMANTIC_TRIANGLE_STRIP (** Indices represent a list of triangles (fan). *) | INDEX_SEMANTIC_TRIANGLE_FAN .
| Value | Meaning |
|---|---|
| INDEX_SEMANTIC_LINE_LIST | Indices represent a series of separate line primitives. |
| INDEX_SEMANTIC_LINE_STRIP | Indices represent a series of connected line primitives with consecutive lines sharing a vertex. |
| INDEX_SEMANTIC_TRIANGLE_LIST | Indices represent a list of separate triangle primitives. |
| INDEX_SEMANTIC_TRIANGLE_STRIP | Indices represent a strip of triangles with consecutive triangles sharing an edge. |
| INDEX_SEMANTIC_TRIANGLE_FAN | Indices represent a series of connected triangle primitives with all triangles sharing a common vertex. |
Definition shapeIndexInfo (shape : shapeT) : option indexInfoT := match shape with | SArray1D _ => None | SArray2D _ => None | SArray3D _ => None | SMesh a => shapeMeshIndex a end.
Definition indexInfoWF (i : indexInfoT) : Prop := 0 < indexCount i.
Inductive indexArrayT := IndexArray {
indexElementType : indexTypeT;
indexElements : list Z
}.
Definition indexWithinBitRange (i : Z) (t : indexTypeT) : Prop := match t with | INDEX_8 => 0 <= i /\ i < (2 ^ 8) | INDEX_16 => 0 <= i /\ i < (2 ^ 16) | INDEX_32 => 0 <= i /\ i < (2 ^ 32) end.
Definition indexArrayWFElementsBitRange (i : indexArrayT) : Prop := Forall (fun e => indexWithinBitRange e (indexElementType i)) (indexElements i).
Definition indexArrayWFElementsLtDataSize (dataSize : Z) (i : indexArrayT) : Prop := Forall (fun e => 0 <= e /\ e < dataSize) (indexElements i).
Definition indexArrayWFElementsNonEmpty (i : indexArrayT) : Prop := (indexElements i) <> nil.
Definition indexArrayWF (dataSize : Z) (i : indexArrayT) : Prop :=
indexArrayWFElementsNonEmpty i
/\ indexArrayWFElementsLtDataSize dataSize i
/\ indexArrayWFElementsBitRange i.
Inductive structureT : Set := StructureT {
(** The list of components in declaration order. *)
structureComponents : list componentT;
}.
Inductive componentT : Set := ComponentT {
(** The type of the component. *)
componentType : componentTypeT;
(** The name of the component. *)
componentName : string;
(** The semantic of the component. *)
componentSemantic : componentSemanticT;
}.
Inductive componentSemanticT : Set := (** The component represents position data such as the positions of vertices in a 3D mesh. *) | POSITION (** The component represents normal vectors. *) | NORMAL (** The component represents the primary texture coordinates. *) | TEXTURE_COORDINATE (** The component represents tangent vectors. *) | TANGENT (** The component represents bitangent vectors. *) | BITANGENT (** The component represents the primary colors of vertices in a 3D mesh. *) | COLOR (** A custom component semantic unknown to this specification. *) | CUSTOM : string -> componentSemanticT.
Inductive componentTypeT : Set := (** Signed 8-bit integer scalar. Size: 1 octet. *) | INTEGER_SIGNED_8 (** Vector of two signed 8-bit integers. Size: 2 octets. *) | INTEGER_SIGNED_8_VEC2 (** Vector of three signed 8-bit integers. Size: 3 octets. *) | INTEGER_SIGNED_8_VEC3 (** Vector of four signed 8-bit integers. Size: 4 octets. *) | INTEGER_SIGNED_8_VEC4 (** Unsigned 8-bit integer scalar. Size: 1 octet. *) | INTEGER_UNSIGNED_8 (** Vector of two unsigned 8-bit integers. Size: 2 octets. *) | INTEGER_UNSIGNED_8_VEC2 (** Vector of three unsigned 8-bit integers. Size: 3 octets. *) | INTEGER_UNSIGNED_8_VEC3 (** Vector of four unsigned 8-bit integers. Size: 4 octets. *) | INTEGER_UNSIGNED_8_VEC4 (** Signed 16-bit integer scalar. Size: 2 octets. *) | INTEGER_SIGNED_16 (** Vector of two signed 16-bit integers. Size: 4 octets. *) | INTEGER_SIGNED_16_VEC2 (** Vector of three signed 16-bit integers. Size: 6 octets. *) | INTEGER_SIGNED_16_VEC3 (** Vector of four signed 16-bit integers. Size: 8 octets. *) | INTEGER_SIGNED_16_VEC4 (** Unsigned 16-bit integer scalar. Size: 2 octets. *) | INTEGER_UNSIGNED_16 (** Vector of two unsigned 16-bit integers. Size: 4 octets. *) | INTEGER_UNSIGNED_16_VEC2 (** Vector of three unsigned 16-bit integers. Size: 6 octets. *) | INTEGER_UNSIGNED_16_VEC3 (** Vector of four unsigned 16-bit integers. Size: 8 octets. *) | INTEGER_UNSIGNED_16_VEC4 (** Signed 32-bit integer scalar. Size: 4 octets. *) | INTEGER_SIGNED_32 (** Vector of two signed 32-bit integers. Size: 8 octets. *) | INTEGER_SIGNED_32_VEC2 (** Vector of three signed 32-bit integers. Size: 12 octets. *) | INTEGER_SIGNED_32_VEC3 (** Vector of four signed 32-bit integers. Size: 16 octets. *) | INTEGER_SIGNED_32_VEC4 (** Unsigned 32-bit integer scalar. Size: 4 octets. *) | INTEGER_UNSIGNED_32 (** Vector of two unsigned 32-bit integers. Size: 8 octets. *) | INTEGER_UNSIGNED_32_VEC2 (** Vector of three unsigned 32-bit integers. Size: 12 octets. *) | INTEGER_UNSIGNED_32_VEC3 (** Vector of four unsigned 32-bit integers. Size: 16 octets. *) | INTEGER_UNSIGNED_32_VEC4 (** Signed 64-bit integer scalar. Size: 8 octets. *) | INTEGER_SIGNED_64 (** Vector of two signed 64-bit integers. Size: 16 octets. *) | INTEGER_SIGNED_64_VEC2 (** Vector of three signed 64-bit integers. Size: 24 octets. *) | INTEGER_SIGNED_64_VEC3 (** Vector of four signed 64-bit integers. Size: 32 octets. *) | INTEGER_SIGNED_64_VEC4 (** Unsigned 64-bit integer scalar. Size: 8 octets. *) | INTEGER_UNSIGNED_64 (** Vector of two unsigned 64-bit integers. Size: 16 octets. *) | INTEGER_UNSIGNED_64_VEC2 (** Vector of three unsigned 64-bit integers. Size: 24 octets. *) | INTEGER_UNSIGNED_64_VEC3 (** Vector of four unsigned 64-bit integers. Size: 32 octets. *) | INTEGER_UNSIGNED_64_VEC4 (** IEEE-754 half-precision floating point scalar. Size: 2 octets. *) | FLOAT_16 (** Vector of two IEEE-754 half-precision floating point values. Size: 4 octets. *) | FLOAT_16_VEC2 (** Vector of three IEEE-754 half-precision floating point values. Size: 6 octets. *) | FLOAT_16_VEC3 (** Vector of four IEEE-754 half-precision floating point values. Size: 8 octets. *) | FLOAT_16_VEC4 (** IEEE-754 single-precision floating point scalar. Size: 4 octets. *) | FLOAT_32 (** Vector of two IEEE-754 single-precision floating point values. Size: 8 octets. *) | FLOAT_32_VEC2 (** Vector of three IEEE-754 single-precision floating point values. Size: 12 octets. *) | FLOAT_32_VEC3 (** Vector of four IEEE-754 single-precision floating point values. Size: 16 octets. *) | FLOAT_32_VEC4 (** IEEE-754 double-precision floating point scalar. Size: 8 octets. *) | FLOAT_64 (** Vector of two IEEE-754 double-precision floating point values. Size: 16 octets. *) | FLOAT_64_VEC2 (** Vector of three IEEE-754 double-precision floating point values. Size: 24 octets. *) | FLOAT_64_VEC3 (** Vector of four IEEE-754 double-precision floating point values. Size: 32 octets. *) | FLOAT_64_VEC4 .
Definition componentTypeCount(t : componentTypeT): nat := match t with | INTEGER_SIGNED_8 | INTEGER_UNSIGNED_8 | INTEGER_SIGNED_16 | INTEGER_UNSIGNED_16 | INTEGER_SIGNED_32 | INTEGER_UNSIGNED_32 | INTEGER_SIGNED_64 | INTEGER_UNSIGNED_64 | FLOAT_16 | FLOAT_32 | FLOAT_64 => 1 | INTEGER_SIGNED_8_VEC2 | INTEGER_UNSIGNED_8_VEC2 | INTEGER_SIGNED_16_VEC2 | INTEGER_UNSIGNED_16_VEC2 | INTEGER_SIGNED_32_VEC2 | INTEGER_UNSIGNED_32_VEC2 | INTEGER_SIGNED_64_VEC2 | INTEGER_UNSIGNED_64_VEC2 | FLOAT_16_VEC2 | FLOAT_32_VEC2 | FLOAT_64_VEC2 => 2 | INTEGER_SIGNED_8_VEC3 | INTEGER_UNSIGNED_8_VEC3 | INTEGER_SIGNED_16_VEC3 | INTEGER_UNSIGNED_16_VEC3 | INTEGER_SIGNED_32_VEC3 | INTEGER_UNSIGNED_32_VEC3 | INTEGER_SIGNED_64_VEC3 | INTEGER_UNSIGNED_64_VEC3 | FLOAT_16_VEC3 | FLOAT_32_VEC3 | FLOAT_64_VEC3 => 3 | INTEGER_SIGNED_8_VEC4 | INTEGER_UNSIGNED_8_VEC4 | INTEGER_SIGNED_16_VEC4 | INTEGER_UNSIGNED_16_VEC4 | INTEGER_SIGNED_32_VEC4 | INTEGER_UNSIGNED_32_VEC4 | INTEGER_SIGNED_64_VEC4 | INTEGER_UNSIGNED_64_VEC4 | FLOAT_16_VEC4 | FLOAT_32_VEC4 | FLOAT_64_VEC4 => 4 end.
Definition componentTypeIsFloatingPoint(t : componentTypeT): bool := match t with | INTEGER_SIGNED_8 => false | INTEGER_SIGNED_8_VEC2 => false | INTEGER_SIGNED_8_VEC3 => false | INTEGER_SIGNED_8_VEC4 => false | INTEGER_UNSIGNED_8 => false | INTEGER_UNSIGNED_8_VEC2 => false | INTEGER_UNSIGNED_8_VEC3 => false | INTEGER_UNSIGNED_8_VEC4 => false | INTEGER_SIGNED_16 => false | INTEGER_SIGNED_16_VEC2 => false | INTEGER_SIGNED_16_VEC3 => false | INTEGER_SIGNED_16_VEC4 => false | INTEGER_UNSIGNED_16 => false | INTEGER_UNSIGNED_16_VEC2 => false | INTEGER_UNSIGNED_16_VEC3 => false | INTEGER_UNSIGNED_16_VEC4 => false | INTEGER_SIGNED_32 => false | INTEGER_SIGNED_32_VEC2 => false | INTEGER_SIGNED_32_VEC3 => false | INTEGER_SIGNED_32_VEC4 => false | INTEGER_UNSIGNED_32 => false | INTEGER_UNSIGNED_32_VEC2 => false | INTEGER_UNSIGNED_32_VEC3 => false | INTEGER_UNSIGNED_32_VEC4 => false | INTEGER_SIGNED_64 => false | INTEGER_SIGNED_64_VEC2 => false | INTEGER_SIGNED_64_VEC3 => false | INTEGER_SIGNED_64_VEC4 => false | INTEGER_UNSIGNED_64 => false | INTEGER_UNSIGNED_64_VEC2 => false | INTEGER_UNSIGNED_64_VEC3 => false | INTEGER_UNSIGNED_64_VEC4 => false | FLOAT_16 => true | FLOAT_16_VEC2 => true | FLOAT_16_VEC3 => true | FLOAT_16_VEC4 => true | FLOAT_32 => true | FLOAT_32_VEC2 => true | FLOAT_32_VEC3 => true | FLOAT_32_VEC4 => true | FLOAT_64 => true | FLOAT_64_VEC2 => true | FLOAT_64_VEC3 => true | FLOAT_64_VEC4 => true end.
Definition structureWFComponentNamesUnique (s : structureT) : Prop := List.NoDup (List.map componentName (structureComponents s)).
Definition structureWF (s : structureT) : Prop := structureWFComponentNamesUnique s.
Inductive componentValueT : Set := | ValueIntegerS8 (v : integerS8T) | ValueIntegerS8Vec2 (v : integerS8Vec2T) | ValueIntegerS8Vec3 (v : integerS8Vec3T) | ValueIntegerS8Vec4 (v : integerS8Vec4T) | ValueIntegerU8 (v : integerU8T) | ValueIntegerU8Vec2 (v : integerU8Vec2T) | ValueIntegerU8Vec3 (v : integerU8Vec3T) | ValueIntegerU8Vec4 (v : integerU8Vec4T) | ValueIntegerS16 (v : integerS16T) | ValueIntegerS16Vec2 (v : integerS16Vec2T) | ValueIntegerS16Vec3 (v : integerS16Vec3T) | ValueIntegerS16Vec4 (v : integerS16Vec4T) | ValueIntegerU16 (v : integerU16T) | ValueIntegerU16Vec2 (v : integerU16Vec2T) | ValueIntegerU16Vec3 (v : integerU16Vec3T) | ValueIntegerU16Vec4 (v : integerU16Vec4T) | ValueIntegerS32 (v : integerS32T) | ValueIntegerS32Vec2 (v : integerS32Vec2T) | ValueIntegerS32Vec3 (v : integerS32Vec3T) | ValueIntegerS32Vec4 (v : integerS32Vec4T) | ValueIntegerU32 (v : integerU32T) | ValueIntegerU32Vec2 (v : integerU32Vec2T) | ValueIntegerU32Vec3 (v : integerU32Vec3T) | ValueIntegerU32Vec4 (v : integerU32Vec4T) | ValueIntegerS64 (v : integerS64T) | ValueIntegerS64Vec2 (v : integerS64Vec2T) | ValueIntegerS64Vec3 (v : integerS64Vec3T) | ValueIntegerS64Vec4 (v : integerS64Vec4T) | ValueIntegerU64 (v : integerU64T) | ValueIntegerU64Vec2 (v : integerU64Vec2T) | ValueIntegerU64Vec3 (v : integerU64Vec3T) | ValueIntegerU64Vec4 (v : integerU64Vec4T) | ValueFloat16 (v : float16T) | ValueFloat16Vec2 (v : float16Vec2T) | ValueFloat16Vec3 (v : float16Vec3T) | ValueFloat16Vec4 (v : float16Vec4T) | ValueFloat32 (v : float32T) | ValueFloat32Vec2 (v : float32Vec2T) | ValueFloat32Vec3 (v : float32Vec3T) | ValueFloat32Vec4 (v : float32Vec4T) | ValueFloat64 (v : float64T) | ValueFloat64Vec2 (v : float64Vec2T) | ValueFloat64Vec3 (v : float64Vec3T) | ValueFloat64Vec4 (v : float64Vec4T) .
Inductive float16T : Set := Float16 {
f16 : R
}.
Inductive float16Vec2T : Set := Float16Vec2 {
f16vec2_0 : R;
f16vec2_1 : R
}.
Inductive float16Vec3T : Set := Float16Vec3 {
f16vec3_0 : R;
f16vec3_1 : R;
f16vec3_2 : R
}.
Inductive float16Vec4T : Set := Float16Vec4 {
f16vec4_0 : R;
f16vec4_1 : R;
f16vec4_2 : R;
f16vec4_3 : R
}.
Inductive float32T : Set := Float32 {
f32 : R
}.
Inductive float32Vec2T : Set := Float32Vec2 {
f32vec2_0 : R;
f32vec2_1 : R
}.
Inductive float32Vec3T : Set := Float32Vec3 {
f32vec3_0 : R;
f32vec3_1 : R;
f32vec3_2 : R
}.
Inductive float32Vec4T : Set := Float32Vec4 {
f32vec4_0 : R;
f32vec4_1 : R;
f32vec4_2 : R;
f32vec4_3 : R
}.
Inductive float64T : Set := Float64 {
f64 : R
}.
Inductive float64Vec2T : Set := Float64Vec2 {
f64vec2_0 : R;
f64vec2_1 : R
}.
Inductive float64Vec3T : Set := Float64Vec3 {
f64vec3_0 : R;
f64vec3_1 : R;
f64vec3_2 : R
}.
Inductive float64Vec4T : Set := Float64Vec4 {
f64vec4_0 : R;
f64vec4_1 : R;
f64vec4_2 : R;
f64vec4_3 : R
}.
Inductive integerS8T : Set := IntegerS8 {
s8 : Z
}.
Inductive integerS8Vec2T : Set := IntegerS8Vec2 {
s8vec2_0 : Z;
s8vec2_1 : Z
}.
Inductive integerS8Vec3T : Set := IntegerS8Vec3 {
s8vec3_0 : Z;
s8vec3_1 : Z;
s8vec3_2 : Z
}.
Inductive integerS8Vec4T : Set := IntegerS8Vec4 {
s8vec4_0 : Z;
s8vec4_1 : Z;
s8vec4_2 : Z;
s8vec4_3 : Z
}.
Inductive integerS16T : Set := IntegerS16 {
s16 : Z
}.
Inductive integerS16Vec2T : Set := IntegerS16Vec2 {
s16vec2_0 : Z;
s16vec2_1 : Z
}.
Inductive integerS16Vec3T : Set := IntegerS16Vec3 {
s16vec3_0 : Z;
s16vec3_1 : Z;
s16vec3_2 : Z
}.
Inductive integerS16Vec4T : Set := IntegerS16Vec4 {
s16vec4_0 : Z;
s16vec4_1 : Z;
s16vec4_2 : Z;
s16vec4_3 : Z
}.
Inductive integerS32T : Set := IntegerS32 {
s32 : Z
}.
Inductive integerS32Vec2T : Set := IntegerS32Vec2 {
s32vec2_0 : Z;
s32vec2_1 : Z
}.
Inductive integerS32Vec3T : Set := IntegerS32Vec3 {
s32vec3_0 : Z;
s32vec3_1 : Z;
s32vec3_2 : Z
}.
Inductive integerS32Vec4T : Set := IntegerS32Vec4 {
s32vec4_0 : Z;
s32vec4_1 : Z;
s32vec4_2 : Z;
s32vec4_3 : Z
}.
Inductive integerS64T : Set := IntegerS64 {
s64 : Z
}.
Inductive integerS64Vec2T : Set := IntegerS64Vec2 {
s64vec2_0 : Z;
s64vec2_1 : Z
}.
Inductive integerS64Vec3T : Set := IntegerS64Vec3 {
s64vec3_0 : Z;
s64vec3_1 : Z;
s64vec3_2 : Z
}.
Inductive integerS64Vec4T : Set := IntegerS64Vec4 {
s64vec4_0 : Z;
s64vec4_1 : Z;
s64vec4_2 : Z;
s64vec4_3 : Z
}.
Inductive integerU8T : Set := IntegerU8 {
u8 : Z
}.
Inductive integerU8Vec2T : Set := IntegerU8Vec2 {
u8vec2_0 : Z;
u8vec2_1 : Z
}.
Inductive integerU8Vec3T : Set := IntegerU8Vec3 {
u8vec3_0 : Z;
u8vec3_1 : Z;
u8vec3_2 : Z
}.
Inductive integerU8Vec4T : Set := IntegerU8Vec4 {
u8vec4_0 : Z;
u8vec4_1 : Z;
u8vec4_2 : Z;
u8vec4_3 : Z
}.
Inductive integerU16T : Set := IntegerU16 {
u16 : Z
}.
Inductive integerU16Vec2T : Set := IntegerU16Vec2 {
u16vec2_0 : Z;
u16vec2_1 : Z
}.
Inductive integerU16Vec3T : Set := IntegerU16Vec3 {
u16vec3_0 : Z;
u16vec3_1 : Z;
u16vec3_2 : Z
}.
Inductive integerU16Vec4T : Set := IntegerU16Vec4 {
u16vec4_0 : Z;
u16vec4_1 : Z;
u16vec4_2 : Z;
u16vec4_3 : Z
}.
Inductive integerU32T : Set := IntegerU32 {
u32 : Z
}.
Inductive integerU32Vec2T : Set := IntegerU32Vec2 {
u32vec2_0 : Z;
u32vec2_1 : Z
}.
Inductive integerU32Vec3T : Set := IntegerU32Vec3 {
u32vec3_0 : Z;
u32vec3_1 : Z;
u32vec3_2 : Z
}.
Inductive integerU32Vec4T : Set := IntegerU32Vec4 {
u32vec4_0 : Z;
u32vec4_1 : Z;
u32vec4_2 : Z;
u32vec4_3 : Z
}.
Inductive integerU64T : Set := IntegerU64 {
u64 : Z
}.
Inductive integerU64Vec2T : Set := IntegerU64Vec2 {
u64vec2_0 : Z;
u64vec2_1 : Z
}.
Inductive integerU64Vec3T : Set := IntegerU64Vec3 {
u64vec3_0 : Z;
u64vec3_1 : Z;
u64vec3_2 : Z
}.
Inductive integerU64Vec4T : Set := IntegerU64Vec4 {
u64vec4_0 : Z;
u64vec4_1 : Z;
u64vec4_2 : Z;
u64vec4_3 : Z
}.
Definition componentValueWF (v : componentValueT) : Prop := match v with | ValueIntegerS8 v => integerS8TWF v | ValueIntegerS8Vec2 v => integerS8Vec2TWF v | ValueIntegerS8Vec3 v => integerS8Vec3TWF v | ValueIntegerS8Vec4 v => integerS8Vec4TWF v | ValueIntegerU8 v => integerU8TWF v | ValueIntegerU8Vec2 v => integerU8Vec2TWF v | ValueIntegerU8Vec3 v => integerU8Vec3TWF v | ValueIntegerU8Vec4 v => integerU8Vec4TWF v | ValueIntegerS16 v => integerS16TWF v | ValueIntegerS16Vec2 v => integerS16Vec2TWF v | ValueIntegerS16Vec3 v => integerS16Vec3TWF v | ValueIntegerS16Vec4 v => integerS16Vec4TWF v | ValueIntegerU16 v => integerU16TWF v | ValueIntegerU16Vec2 v => integerU16Vec2TWF v | ValueIntegerU16Vec3 v => integerU16Vec3TWF v | ValueIntegerU16Vec4 v => integerU16Vec4TWF v | ValueIntegerS32 v => integerS32TWF v | ValueIntegerS32Vec2 v => integerS32Vec2TWF v | ValueIntegerS32Vec3 v => integerS32Vec3TWF v | ValueIntegerS32Vec4 v => integerS32Vec4TWF v | ValueIntegerU32 v => integerU32TWF v | ValueIntegerU32Vec2 v => integerU32Vec2TWF v | ValueIntegerU32Vec3 v => integerU32Vec3TWF v | ValueIntegerU32Vec4 v => integerU32Vec4TWF v | ValueIntegerS64 v => integerS64TWF v | ValueIntegerS64Vec2 v => integerS64Vec2TWF v | ValueIntegerS64Vec3 v => integerS64Vec3TWF v | ValueIntegerS64Vec4 v => integerS64Vec4TWF v | ValueIntegerU64 v => integerU64TWF v | ValueIntegerU64Vec2 v => integerU64Vec2TWF v | ValueIntegerU64Vec3 v => integerU64Vec3TWF v | ValueIntegerU64Vec4 v => integerU64Vec4TWF v | ValueFloat16 v => float16TWF v | ValueFloat16Vec2 v => float16Vec2TWF v | ValueFloat16Vec3 v => float16Vec3TWF v | ValueFloat16Vec4 v => float16Vec4TWF v | ValueFloat32 v => float32TWF v | ValueFloat32Vec2 v => float32Vec2TWF v | ValueFloat32Vec3 v => float32Vec3TWF v | ValueFloat32Vec4 v => float32Vec4TWF v | ValueFloat64 v => float64TWF v | ValueFloat64Vec2 v => float64Vec2TWF v | ValueFloat64Vec3 v => float64Vec3TWF v | ValueFloat64Vec4 v => float64Vec4TWF v end.
Definition s8Min : Z := -(2 ^ 7).
Definition s8Max : Z := (2 ^ 7) - 1.
Definition s16Min : Z := -(2 ^ 15).
Definition s16Max : Z := (2 ^ 15) - 1.
Definition s32Min : Z := -(2 ^ 31).
Definition s32Max : Z := (2 ^ 31) - 1.
Definition s64Min : Z := -(2 ^ 63).
Definition s64Max : Z := (2 ^ 63) - 1.
Definition u8Min : Z := 0.
Definition u8Max : Z := (2 ^ 8) - 1.
Definition u16Min : Z := 0.
Definition u16Max : Z := (2 ^ 16) - 1.
Definition u32Min : Z := 0.
Definition u32Max : Z := (2 ^ 32) - 1.
Definition u64Min : Z := 0.
Definition u64Max : Z := (2 ^ 64) - 1.
Definition isS8 (z : Z) : Prop := (s8Min <= z) /\ (z <= s8Max).
Definition isS16 (z : Z) : Prop := (s16Min <= z) /\ (z <= s16Max).
Definition isS32 (z : Z) : Prop := (s32Min <= z) /\ (z <= s32Max).
Definition isS64 (z : Z) : Prop := (s64Min <= z) /\ (z <= s64Max).
Definition isU8 (z : Z) : Prop := (u8Min <= z) /\ (z <= u8Max).
Definition isU16 (z : Z) : Prop := (u16Min <= z) /\ (z <= u16Max).
Definition isU32 (z : Z) : Prop := (u32Min <= z) /\ (z <= u32Max).
Definition isU64 (z : Z) : Prop := (u64Min <= z) /\ (z <= u64Max).
Definition integerS8TWF (t : integerS8T) : Prop := isS8 (s8 t).
Definition integerS8Vec2TWF (t : integerS8Vec2T) : Prop := isS8 (s8vec2_0 t) /\ isS8 (s8vec2_1 t).
Definition integerS8Vec3TWF (t : integerS8Vec3T) : Prop :=
isS8 (s8vec3_0 t)
/\ isS8 (s8vec3_1 t)
/\ isS8 (s8vec3_2 t).
Definition integerS8Vec4TWF (t : integerS8Vec4T) : Prop :=
isS8 (s8vec4_0 t)
/\ isS8 (s8vec4_1 t)
/\ isS8 (s8vec4_2 t)
/\ isS8 (s8vec4_3 t).
Definition integerS16TWF (t : integerS16T) : Prop := isS16 (s16 t).
Definition integerS16Vec2TWF (t : integerS16Vec2T) : Prop :=
isS16 (s16vec2_0 t)
/\ isS16 (s16vec2_1 t).
Definition integerS16Vec3TWF (t : integerS16Vec3T) : Prop :=
isS16 (s16vec3_0 t)
/\ isS16 (s16vec3_1 t)
/\ isS16 (s16vec3_2 t).
Definition integerS16Vec4TWF (t : integerS16Vec4T) : Prop :=
isS16 (s16vec4_0 t)
/\ isS16 (s16vec4_1 t)
/\ isS16 (s16vec4_2 t)
/\ isS16 (s16vec4_3 t).
Definition integerS32TWF (t : integerS32T) : Prop := isS32 (s32 t).
Definition integerS32Vec2TWF (t : integerS32Vec2T) : Prop :=
isS32 (s32vec2_0 t)
/\ isS32 (s32vec2_1 t).
Definition integerS32Vec3TWF (t : integerS32Vec3T) : Prop :=
isS32 (s32vec3_0 t)
/\ isS32 (s32vec3_1 t)
/\ isS32 (s32vec3_2 t).
Definition integerS32Vec4TWF (t : integerS32Vec4T) : Prop :=
isS32 (s32vec4_0 t)
/\ isS32 (s32vec4_1 t)
/\ isS32 (s32vec4_2 t)
/\ isS32 (s32vec4_3 t).
Definition integerS64TWF (t : integerS64T) : Prop := isS64 (s64 t).
Definition integerS64Vec2TWF (t : integerS64Vec2T) : Prop :=
isS64 (s64vec2_0 t)
/\ isS64 (s64vec2_1 t).
Definition integerS64Vec3TWF (t : integerS64Vec3T) : Prop :=
isS64 (s64vec3_0 t)
/\ isS64 (s64vec3_1 t)
/\ isS64 (s64vec3_2 t).
Definition integerS64Vec4TWF (t : integerS64Vec4T) : Prop :=
isS64 (s64vec4_0 t)
/\ isS64 (s64vec4_1 t)
/\ isS64 (s64vec4_2 t)
/\ isS64 (s64vec4_3 t).
Definition integerU8TWF (t : integerU8T) : Prop := isU8 (u8 t).
Definition integerU8Vec2TWF (t : integerU8Vec2T) : Prop :=
isU8 (u8vec2_0 t)
/\ isU8 (u8vec2_1 t).
Definition integerU8Vec3TWF (t : integerU8Vec3T) : Prop :=
isU8 (u8vec3_0 t)
/\ isU8 (u8vec3_1 t)
/\ isU8 (u8vec3_2 t).
Definition integerU8Vec4TWF (t : integerU8Vec4T) : Prop :=
isU8 (u8vec4_0 t)
/\ isU8 (u8vec4_1 t)
/\ isU8 (u8vec4_2 t)
/\ isU8 (u8vec4_3 t).
Definition integerU16TWF (t : integerU16T) : Prop := isU16 (u16 t).
Definition integerU16Vec2TWF (t : integerU16Vec2T) : Prop :=
isU16 (u16vec2_0 t)
/\ isU16 (u16vec2_1 t).
Definition integerU16Vec3TWF (t : integerU16Vec3T) : Prop :=
isU16 (u16vec3_0 t)
/\ isU16 (u16vec3_1 t)
/\ isU16 (u16vec3_2 t).
Definition integerU16Vec4TWF (t : integerU16Vec4T) : Prop :=
isU16 (u16vec4_0 t)
/\ isU16 (u16vec4_1 t)
/\ isU16 (u16vec4_2 t)
/\ isU16 (u16vec4_3 t).
Definition integerU32TWF (t : integerU32T) : Prop := isU32 (u32 t).
Definition integerU32Vec2TWF (t : integerU32Vec2T) : Prop :=
isU32 (u32vec2_0 t)
/\ isU32 (u32vec2_1 t).
Definition integerU32Vec3TWF (t : integerU32Vec3T) : Prop :=
isU32 (u32vec3_0 t)
/\ isU32 (u32vec3_1 t)
/\ isU32 (u32vec3_2 t).
Definition integerU32Vec4TWF (t : integerU32Vec4T) : Prop :=
isU32 (u32vec4_0 t)
/\ isU32 (u32vec4_1 t)
/\ isU32 (u32vec4_2 t)
/\ isU32 (u32vec4_3 t).
Definition integerU64TWF (t : integerU64T) : Prop := isU64 (u64 t).
Definition integerU64Vec2TWF (t : integerU64Vec2T) : Prop :=
isU64 (u64vec2_0 t)
/\ isU64 (u64vec2_1 t).
Definition integerU64Vec3TWF (t : integerU64Vec3T) : Prop :=
isU64 (u64vec3_0 t)
/\ isU64 (u64vec3_1 t)
/\ isU64 (u64vec3_2 t).
Definition integerU64Vec4TWF (t : integerU64Vec4T) : Prop :=
isU64 (u64vec4_0 t)
/\ isU64 (u64vec4_1 t)
/\ isU64 (u64vec4_2 t)
/\ isU64 (u64vec4_3 t).
Axiom isNaN : R -> Prop.
Axiom isInfinite : R -> Prop.
Definition isValidFloat (r : R) : Prop := (~isNaN r) /\ (~isInfinite r).
Definition float16TWF (t : float16T) : Prop := isValidFloat (f16 t).
Definition float16Vec2TWF (t : float16Vec2T) : Prop :=
isValidFloat (f16vec2_0 t)
/\ isValidFloat (f16vec2_1 t).
Definition float16Vec3TWF (t : float16Vec3T) : Prop :=
isValidFloat (f16vec3_0 t)
/\ isValidFloat (f16vec3_1 t)
/\ isValidFloat (f16vec3_2 t).
Definition float16Vec4TWF (t : float16Vec4T) : Prop :=
isValidFloat (f16vec4_0 t)
/\ isValidFloat (f16vec4_1 t)
/\ isValidFloat (f16vec4_2 t)
/\ isValidFloat (f16vec4_3 t).
Definition float32TWF (t : float32T) : Prop := isValidFloat (f32 t).
Definition float32Vec2TWF (t : float32Vec2T) : Prop :=
isValidFloat (f32vec2_0 t)
/\ isValidFloat (f32vec2_1 t).
Definition float32Vec3TWF (t : float32Vec3T) : Prop :=
isValidFloat (f32vec3_0 t)
/\ isValidFloat (f32vec3_1 t)
/\ isValidFloat (f32vec3_2 t).
Definition float32Vec4TWF (t : float32Vec4T) : Prop :=
isValidFloat (f32vec4_0 t)
/\ isValidFloat (f32vec4_1 t)
/\ isValidFloat (f32vec4_2 t)
/\ isValidFloat (f32vec4_3 t).
Definition float64TWF (t : float64T) : Prop := isValidFloat (f64 t).
Definition float64Vec2TWF (t : float64Vec2T) : Prop :=
isValidFloat (f64vec2_0 t)
/\ isValidFloat (f64vec2_1 t).
Definition float64Vec3TWF (t : float64Vec3T) : Prop :=
isValidFloat (f64vec3_0 t)
/\ isValidFloat (f64vec3_1 t)
/\ isValidFloat (f64vec3_2 t).
Definition float64Vec4TWF (t : float64Vec4T) : Prop :=
isValidFloat (f64vec4_0 t)
/\ isValidFloat (f64vec4_1 t)
/\ isValidFloat (f64vec4_2 t)
/\ isValidFloat (f64vec4_3 t).
Inductive structureValueT : Set := StructureValue {
structureComponentValues : list componentValueT;
}.
Inductive valueHasType : componentValueT -> componentTypeT -> Prop :=
| VTS8 :
forall (v : integerS8T)
(wf : componentValueWF (ValueIntegerS8 v)),
valueHasType (ValueIntegerS8 v) INTEGER_SIGNED_8
| VTS8_VEC2 :
forall (v : integerS8Vec2T)
(wf : componentValueWF (ValueIntegerS8Vec2 v)),
valueHasType (ValueIntegerS8Vec2 v) INTEGER_SIGNED_8_VEC2
| VTS8_VEC3 :
forall (v : integerS8Vec3T)
(wf : componentValueWF (ValueIntegerS8Vec3 v)),
valueHasType (ValueIntegerS8Vec3 v) INTEGER_SIGNED_8_VEC3
| VTS8_VEC4 :
forall (v : integerS8Vec4T)
(wf : componentValueWF (ValueIntegerS8Vec4 v)),
valueHasType (ValueIntegerS8Vec4 v) INTEGER_SIGNED_8_VEC4
| VTU8 :
forall (v : integerU8T)
(wf : componentValueWF (ValueIntegerU8 v)),
valueHasType (ValueIntegerU8 v) INTEGER_UNSIGNED_8
| VTU8_VEC2 :
forall (v : integerU8Vec2T)
(wf : componentValueWF (ValueIntegerU8Vec2 v)),
valueHasType (ValueIntegerU8Vec2 v) INTEGER_UNSIGNED_8_VEC2
| VTU8_VEC3 :
forall (v : integerU8Vec3T)
(wf : componentValueWF (ValueIntegerU8Vec3 v)),
valueHasType (ValueIntegerU8Vec3 v) INTEGER_UNSIGNED_8_VEC3
| VTU8_VEC4 :
forall (v : integerU8Vec4T)
(wf : componentValueWF (ValueIntegerU8Vec4 v)),
valueHasType (ValueIntegerU8Vec4 v) INTEGER_UNSIGNED_8_VEC4
| VTS16 :
forall (v : integerS16T)
(wf : componentValueWF (ValueIntegerS16 v)),
valueHasType (ValueIntegerS16 v) INTEGER_SIGNED_16
| VTS16_VEC2 :
forall (v : integerS16Vec2T)
(wf : componentValueWF (ValueIntegerS16Vec2 v)),
valueHasType (ValueIntegerS16Vec2 v) INTEGER_SIGNED_16_VEC2
| VTS16_VEC3 :
forall (v : integerS16Vec3T)
(wf : componentValueWF (ValueIntegerS16Vec3 v)),
valueHasType (ValueIntegerS16Vec3 v) INTEGER_SIGNED_16_VEC3
| VTS16_VEC4 :
forall (v : integerS16Vec4T)
(wf : componentValueWF (ValueIntegerS16Vec4 v)),
valueHasType (ValueIntegerS16Vec4 v) INTEGER_SIGNED_16_VEC4
| VTU16 :
forall (v : integerU16T)
(wf : componentValueWF (ValueIntegerU16 v)),
valueHasType (ValueIntegerU16 v) INTEGER_UNSIGNED_16
| VTU16_VEC2 :
forall (v : integerU16Vec2T)
(wf : componentValueWF (ValueIntegerU16Vec2 v)),
valueHasType (ValueIntegerU16Vec2 v) INTEGER_UNSIGNED_16_VEC2
| VTU16_VEC3 :
forall (v : integerU16Vec3T)
(wf : componentValueWF (ValueIntegerU16Vec3 v)),
valueHasType (ValueIntegerU16Vec3 v) INTEGER_UNSIGNED_16_VEC3
| VTU16_VEC4 :
forall (v : integerU16Vec4T)
(wf : componentValueWF (ValueIntegerU16Vec4 v)),
valueHasType (ValueIntegerU16Vec4 v) INTEGER_UNSIGNED_16_VEC4
| VTS32 :
forall (v : integerS32T)
(wf : componentValueWF (ValueIntegerS32 v)),
valueHasType (ValueIntegerS32 v) INTEGER_SIGNED_32
| VTS32_VEC2 :
forall (v : integerS32Vec2T)
(wf : componentValueWF (ValueIntegerS32Vec2 v)),
valueHasType (ValueIntegerS32Vec2 v) INTEGER_SIGNED_32_VEC2
| VTS32_VEC3 :
forall (v : integerS32Vec3T)
(wf : componentValueWF (ValueIntegerS32Vec3 v)),
valueHasType (ValueIntegerS32Vec3 v) INTEGER_SIGNED_32_VEC3
| VTS32_VEC4 :
forall (v : integerS32Vec4T)
(wf : componentValueWF (ValueIntegerS32Vec4 v)),
valueHasType (ValueIntegerS32Vec4 v) INTEGER_SIGNED_32_VEC4
| VTU32 :
forall (v : integerU32T)
(wf : componentValueWF (ValueIntegerU32 v)),
valueHasType (ValueIntegerU32 v) INTEGER_UNSIGNED_32
| VTU32_VEC2 :
forall (v : integerU32Vec2T)
(wf : componentValueWF (ValueIntegerU32Vec2 v)),
valueHasType (ValueIntegerU32Vec2 v) INTEGER_UNSIGNED_32_VEC2
| VTU32_VEC3 :
forall (v : integerU32Vec3T)
(wf : componentValueWF (ValueIntegerU32Vec3 v)),
valueHasType (ValueIntegerU32Vec3 v) INTEGER_UNSIGNED_32_VEC3
| VTU32_VEC4 :
forall (v : integerU32Vec4T)
(wf : componentValueWF (ValueIntegerU32Vec4 v)),
valueHasType (ValueIntegerU32Vec4 v) INTEGER_UNSIGNED_32_VEC4
| VTS64 :
forall (v : integerS64T)
(wf : componentValueWF (ValueIntegerS64 v)),
valueHasType (ValueIntegerS64 v) INTEGER_SIGNED_64
| VTS64_VEC2 :
forall (v : integerS64Vec2T)
(wf : componentValueWF (ValueIntegerS64Vec2 v)),
valueHasType (ValueIntegerS64Vec2 v) INTEGER_SIGNED_64_VEC2
| VTS64_VEC3 :
forall (v : integerS64Vec3T)
(wf : componentValueWF (ValueIntegerS64Vec3 v)),
valueHasType (ValueIntegerS64Vec3 v) INTEGER_SIGNED_64_VEC3
| VTS64_VEC4 :
forall (v : integerS64Vec4T)
(wf : componentValueWF (ValueIntegerS64Vec4 v)),
valueHasType (ValueIntegerS64Vec4 v) INTEGER_SIGNED_64_VEC4
| VTU64 :
forall (v : integerU64T)
(wf : componentValueWF (ValueIntegerU64 v)),
valueHasType (ValueIntegerU64 v) INTEGER_UNSIGNED_64
| VTU64_VEC2 :
forall (v : integerU64Vec2T)
(wf : componentValueWF (ValueIntegerU64Vec2 v)),
valueHasType (ValueIntegerU64Vec2 v) INTEGER_UNSIGNED_64_VEC2
| VTU64_VEC3 :
forall (v : integerU64Vec3T)
(wf : componentValueWF (ValueIntegerU64Vec3 v)),
valueHasType (ValueIntegerU64Vec3 v) INTEGER_UNSIGNED_64_VEC3
| VTU64_VEC4 :
forall (v : integerU64Vec4T)
(wf : componentValueWF (ValueIntegerU64Vec4 v)),
valueHasType (ValueIntegerU64Vec4 v) INTEGER_UNSIGNED_64_VEC4
| VTF16 :
forall (v : float16T)
(wf : componentValueWF (ValueFloat16 v)),
valueHasType (ValueFloat16 v) FLOAT_16
| VTF16_VEC2 :
forall (v : float16Vec2T)
(wf : componentValueWF (ValueFloat16Vec2 v)),
valueHasType (ValueFloat16Vec2 v) FLOAT_16_VEC2
| VTF16_VEC3 :
forall (v : float16Vec3T)
(wf : componentValueWF (ValueFloat16Vec3 v)),
valueHasType (ValueFloat16Vec3 v) FLOAT_16_VEC3
| VTF16_VEC4 :
forall (v : float16Vec4T)
(wf : componentValueWF (ValueFloat16Vec4 v)),
valueHasType (ValueFloat16Vec4 v) FLOAT_16_VEC4
| VTF32 :
forall (v : float32T)
(wf : componentValueWF (ValueFloat32 v)),
valueHasType (ValueFloat32 v) FLOAT_32
| VTF32_VEC2 :
forall (v : float32Vec2T)
(wf : componentValueWF (ValueFloat32Vec2 v)),
valueHasType (ValueFloat32Vec2 v) FLOAT_32_VEC2
| VTF32_VEC3 :
forall (v : float32Vec3T)
(wf : componentValueWF (ValueFloat32Vec3 v)),
valueHasType (ValueFloat32Vec3 v) FLOAT_32_VEC3
| VTF32_VEC4 :
forall (v : float32Vec4T)
(wf : componentValueWF (ValueFloat32Vec4 v)),
valueHasType (ValueFloat32Vec4 v) FLOAT_32_VEC4
| VTF64 :
forall (v : float64T)
(wf : componentValueWF (ValueFloat64 v)),
valueHasType (ValueFloat64 v) FLOAT_64
| VTF64_VEC2 :
forall (v : float64Vec2T)
(wf : componentValueWF (ValueFloat64Vec2 v)),
valueHasType (ValueFloat64Vec2 v) FLOAT_64_VEC2
| VTF64_VEC3 :
forall (v : float64Vec3T)
(wf : componentValueWF (ValueFloat64Vec3 v)),
valueHasType (ValueFloat64Vec3 v) FLOAT_64_VEC3
| VTF64_VEC4 :
forall (v : float64Vec4T)
(wf : componentValueWF (ValueFloat64Vec4 v)),
valueHasType (ValueFloat64Vec4 v) FLOAT_64_VEC4
.
Inductive componentValuesHaveTypes : list (componentValueT * componentT) -> Prop :=
| CVHST_Null : componentValuesHaveTypes []
| CVHST_Cons : forall p ps,
valueHasType (fst p) (componentType (snd p))
-> componentValuesHaveTypes ps
-> componentValuesHaveTypes (p :: ps).
Definition structureValueHasStructureType
(structVal : structureValueT)
(structType : structureT)
: Prop :=
let fValues := structureComponentValues structVal in
let fTypes := structureComponents structType in
length fValues = length fTypes /\ componentValuesHaveTypes (combine fValues fTypes).
Inductive extensionT : Set := Extension {
(** The unique ID of the extension. *)
extensionId : string;
(** The major version of the extension. *)
extensionVersionMajor : Z;
(** The minor version of the extension. *)
extensionVersionMinor : Z;
(** The list of section identifiers covered by the extension. *)
extensionSections : list Z;
(** The humanly-readable extension name. *)
extensionName : string;
(** The humanly-readable extension description. *)
extensionDescription : string;
(** The URI of the specification. *)
extensionSpecificationURI : string
}.
| 1 |
Due to limitations in the Rocq standard library, names are currently expressed in
the specification as simple string
values.
References to this footnote:
1
|
| 2 |
The propositions here are exhaustive but should simply be intuitively understood to
assert that values are within
the acceptable ranges of 8-bit, 16-bit, 32-bit, and 64-bit signed and unsigned integers,
and that floating-point
values are "acceptable" to the degree that the specification language is capable of
describing.
References to this footnote:
1
|
Inductive bit : Set := | B0 | B1.
Inductive octet : Set := | OctExact : bit -> bit -> bit -> bit -> bit -> bit -> bit -> bit -> octet | OctRemain : bit -> bit -> bit -> bit -> bit -> bit -> bit -> bit -> octet.
Definition bitOf (n position : Z) : bit := match Z.testbit n position with | true => B1 | false => B0 end.
Definition zero8 : octet := OctExact B0 B0 B0 B0 B0 B0 B0 B0.
Definition octets8 (z : Z) : list octet := [
OctExact
(bitOf z 7)
(bitOf z 6)
(bitOf z 5)
(bitOf z 4)
(bitOf z 3)
(bitOf z 2)
(bitOf z 1)
(bitOf z 0)
].
Definition octets16BE (n : Z) : list octet := [
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Definition octets32BE (n : Z) : list octet := [
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Definition octets64BE (n : Z) : list octet := [
OctExact
(bitOf n 63)
(bitOf n 62)
(bitOf n 61)
(bitOf n 60)
(bitOf n 59)
(bitOf n 58)
(bitOf n 57)
(bitOf n 56);
OctExact
(bitOf n 55)
(bitOf n 54)
(bitOf n 53)
(bitOf n 52)
(bitOf n 51)
(bitOf n 50)
(bitOf n 49)
(bitOf n 48);
OctExact
(bitOf n 47)
(bitOf n 46)
(bitOf n 45)
(bitOf n 44)
(bitOf n 43)
(bitOf n 42)
(bitOf n 41)
(bitOf n 40);
OctExact
(bitOf n 39)
(bitOf n 38)
(bitOf n 37)
(bitOf n 36)
(bitOf n 35)
(bitOf n 34)
(bitOf n 33)
(bitOf n 32);
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Inductive binaryExp : Set := | U32 : N -> binaryExp | U64 : N -> binaryExp | UTF8 : string -> binaryExp | Pad : N -> binaryExp | Octets : list octet -> binaryExp .
Definition octetByte (b : Byte.byte): octet :=
let n := Byte.to_N b in
let z := Z.of_N n in
match octets8 z with
| [] => zero8
| x :: _ => x
end.
Definition stringUTF8Bytes (s : string) : list octet :=
let bs := list_byte_of_string s in
map octetByte bs.
Definition binaryExpOctets (b : binaryExp) : list octet :=
match b with
| U32 x => octets32BE (Z.of_N x)
| U64 x => octets64BE (Z.of_N x)
| UTF8 s =>
let text := stringUTF8Bytes s in
let size := octets32BE (Z.of_nat (List.length text)) in
size ++ text
| Pad x => repeat zero8 (N.to_nat x)
| Octets o => o
end.
Inductive json : Set := (** A boolean constant. *) | JsonBoolean : bool -> json (** An integer constant. *) | JsonInteger : Z -> json (** A floating point constant. *) | JsonFloat : R -> json (** A string constant. *) | JsonString : string -> json (** An object. *) | JsonObject : list (string * json) -> json (** An array. *) | JsonArray : list json -> json .
Inductive jsonToken : Set := | JTTrue : jsonToken | JTFalse : jsonToken | JTInteger : Z -> jsonToken | JTFloat : R -> jsonToken | JTString : string -> jsonToken | JTObjectStart : jsonToken | JTObjectEnd : jsonToken | JTColon : jsonToken | JTComma : jsonToken | JTArrayStart : jsonToken | JTArrayEnd : jsonToken .
Axiom stringOfR : R -> string.
Definition string_of_Z (n : Z) : string := match n with | 0%Z => "0" | Z.pos _ => NilZero.string_of_uint (Nat.to_uint (Z.to_nat n)) | Z.neg _ => "-" ++ NilZero.string_of_uint (Nat.to_uint (Z.to_nat (Z.abs n))) end.
Definition jsonStringOne (t : jsonToken) : string :=
match t with
| JTTrue => "true"
| JTFalse => "false"
| JTInteger n => string_of_Z n
| JTFloat r => stringOfR r
| JTString s => """" ++ s ++ """"
| JTObjectStart => "{"
| JTObjectEnd => "}"
| JTColon => ":"
| JTComma => ","
| JTArrayStart => "["
| JTArrayEnd => "]"
end.
Fixpoint jsonComma (ss : list (list jsonToken)) : list jsonToken := match ss with | [] => [] | (x :: []) => x | (x :: xs) => x ++ JTComma :: (jsonComma xs) end.
Fixpoint jsonSerialize (j : json) : list jsonToken :=
match j with
| JsonBoolean true => [JTTrue]
| JsonBoolean false => [JTFalse]
| JsonInteger n => [JTInteger n]
| JsonFloat r => [JTFloat r]
| JsonString s => [JTString s]
| JsonObject o =>
let props := map (fun p => JTString (fst p) :: JTColon :: jsonSerialize (snd p)) o in
JTObjectStart :: (jsonComma props) ++ [JTObjectEnd]
| JsonArray a =>
let values := map jsonSerialize a in
JTArrayStart :: (jsonComma values) ++ [JTArrayEnd]
end.
Definition jsonSerializeString (j : json) : string :=
let tokens := jsonSerialize j in
let texts := map jsonStringOne tokens in
fold_left append texts "".
Definition jsonInfo (i : infoT) : json :=
let schema := [("$Schema", JsonString "urn:com.io7m.zeniro:info:1.0")] in
let shape := [("Shape", jsonShape (infoShape i))] in
let structure := [("Structure", jsonStructure (infoStructure i))] in
let extensions := [("Extensions", jsonExtensions (infoExtensions i))] in
JsonObject (schema ++ shape ++ structure ++ extensions).
Definition jsonShape (s : shapeT) : json :=
match s with
| SArray1D a => JsonObject [
("@Shape", JsonString "Array1D");
("Length", JsonInteger (Z.of_N (shapeArray1DLength a)))
]
| SArray2D a => JsonObject [
("@Shape", JsonString "Array2D");
("SizeX", JsonInteger (Z.of_N (shapeArray2DSizeX a)));
("SizeY", JsonInteger (Z.of_N (shapeArray2DSizeY a)))
]
| SArray3D a => JsonObject [
("@Shape", JsonString "Array3D");
("SizeX", JsonInteger (Z.of_N (shapeArray3DSizeX a)));
("SizeY", JsonInteger (Z.of_N (shapeArray3DSizeY a)));
("SizeZ", JsonInteger (Z.of_N (shapeArray3DSizeZ a)))
]
| SMesh a =>
let index := jsonIndexOptional (shapeMeshIndex a) in
let bounds := jsonBoundsOptional (shapeMeshBounds a) in
let properties := [
("@Shape", JsonString "Mesh");
("Length", JsonInteger (Z.of_N (shapeMeshLength a)))
] in
JsonObject (properties ++ index ++ bounds)
end.
Definition jsonIndex (i : indexInfoT) : json :=
JsonObject [
("Type", jsonIndexType (indexType i));
("Count", JsonInteger (indexCount i));
("Semantic", jsonIndexSemantic (indexSemantic i))
].
Definition jsonIndexType (i : indexTypeT) : json := JsonString match i with | INDEX_8 => "INDEX_8" | INDEX_16 => "INDEX_16" | INDEX_32 => "INDEX_32" end.
Definition jsonIndexSemantic (i : indexSemanticT) : json := JsonString match i with | INDEX_SEMANTIC_LINE_LIST => "INDEX_SEMANTIC_LINE_LIST" | INDEX_SEMANTIC_LINE_STRIP => "INDEX_SEMANTIC_LINE_STRIP" | INDEX_SEMANTIC_TRIANGLE_LIST => "INDEX_SEMANTIC_TRIANGLE_LIST" | INDEX_SEMANTIC_TRIANGLE_STRIP => "INDEX_SEMANTIC_TRIANGLE_STRIP" | INDEX_SEMANTIC_TRIANGLE_FAN => "INDEX_SEMANTIC_TRIANGLE_FAN" end.
Definition jsonIndexOptional (b : option indexInfoT) : list (string * json) :=
match b with
| Some k => [("Index", jsonIndex k)]
| None => []
end.
Definition jsonBounds (b : boundsT) : json :=
JsonObject [
("XMinimum", JsonFloat (boundsXMinimum b));
("XMaximum", JsonFloat (boundsXMaximum b));
("YMinimum", JsonFloat (boundsYMinimum b));
("YMaximum", JsonFloat (boundsYMaximum b));
("ZMinimum", JsonFloat (boundsZMinimum b));
("ZMaximum", JsonFloat (boundsZMaximum b))
].
Definition jsonBoundsOptional (b : option boundsT) : list (string * json) :=
match b with
| Some k => [("Bounds", jsonBounds k)]
| None => []
end.
Definition jsonStructure (s : structureT) : json :=
JsonObject [
("Components", jsonComponents (structureComponents s))
].
Definition jsonComponents (c : list componentT) : json := JsonArray (map jsonComponent c).
Definition jsonComponent (c : componentT) : json :=
JsonObject [
("Name", JsonString (componentName c));
("Type", jsonComponentType (componentType c));
("Semantic", JsonString (componentSemanticDescriptor (componentSemantic c)))
].
Definition jsonComponentType (t : componentTypeT) : json := JsonString match t with | INTEGER_SIGNED_8 => "INTEGER_SIGNED_8" | INTEGER_SIGNED_8_VEC2 => "INTEGER_SIGNED_8_VEC2" | INTEGER_SIGNED_8_VEC3 => "INTEGER_SIGNED_8_VEC3" | INTEGER_SIGNED_8_VEC4 => "INTEGER_SIGNED_8_VEC4" | INTEGER_UNSIGNED_8 => "INTEGER_UNSIGNED_8" | INTEGER_UNSIGNED_8_VEC2 => "INTEGER_UNSIGNED_8_VEC2" | INTEGER_UNSIGNED_8_VEC3 => "INTEGER_UNSIGNED_8_VEC3" | INTEGER_UNSIGNED_8_VEC4 => "INTEGER_UNSIGNED_8_VEC4" | INTEGER_SIGNED_16 => "INTEGER_SIGNED_16" | INTEGER_SIGNED_16_VEC2 => "INTEGER_SIGNED_16_VEC2" | INTEGER_SIGNED_16_VEC3 => "INTEGER_SIGNED_16_VEC3" | INTEGER_SIGNED_16_VEC4 => "INTEGER_SIGNED_16_VEC4" | INTEGER_UNSIGNED_16 => "INTEGER_UNSIGNED_16" | INTEGER_UNSIGNED_16_VEC2 => "INTEGER_UNSIGNED_16_VEC2" | INTEGER_UNSIGNED_16_VEC3 => "INTEGER_UNSIGNED_16_VEC3" | INTEGER_UNSIGNED_16_VEC4 => "INTEGER_UNSIGNED_16_VEC4" | INTEGER_SIGNED_32 => "INTEGER_SIGNED_32" | INTEGER_SIGNED_32_VEC2 => "INTEGER_SIGNED_32_VEC2" | INTEGER_SIGNED_32_VEC3 => "INTEGER_SIGNED_32_VEC3" | INTEGER_SIGNED_32_VEC4 => "INTEGER_SIGNED_32_VEC4" | INTEGER_UNSIGNED_32 => "INTEGER_UNSIGNED_32" | INTEGER_UNSIGNED_32_VEC2 => "INTEGER_UNSIGNED_32_VEC2" | INTEGER_UNSIGNED_32_VEC3 => "INTEGER_UNSIGNED_32_VEC3" | INTEGER_UNSIGNED_32_VEC4 => "INTEGER_UNSIGNED_32_VEC4" | INTEGER_SIGNED_64 => "INTEGER_SIGNED_64" | INTEGER_SIGNED_64_VEC2 => "INTEGER_SIGNED_64_VEC2" | INTEGER_SIGNED_64_VEC3 => "INTEGER_SIGNED_64_VEC3" | INTEGER_SIGNED_64_VEC4 => "INTEGER_SIGNED_64_VEC4" | INTEGER_UNSIGNED_64 => "INTEGER_UNSIGNED_64" | INTEGER_UNSIGNED_64_VEC2 => "INTEGER_UNSIGNED_64_VEC2" | INTEGER_UNSIGNED_64_VEC3 => "INTEGER_UNSIGNED_64_VEC3" | INTEGER_UNSIGNED_64_VEC4 => "INTEGER_UNSIGNED_64_VEC4" | FLOAT_16 => "FLOAT_16" | FLOAT_16_VEC2 => "FLOAT_16_VEC2" | FLOAT_16_VEC3 => "FLOAT_16_VEC3" | FLOAT_16_VEC4 => "FLOAT_16_VEC4" | FLOAT_32 => "FLOAT_32" | FLOAT_32_VEC2 => "FLOAT_32_VEC2" | FLOAT_32_VEC3 => "FLOAT_32_VEC3" | FLOAT_32_VEC4 => "FLOAT_32_VEC4" | FLOAT_64 => "FLOAT_64" | FLOAT_64_VEC2 => "FLOAT_64_VEC2" | FLOAT_64_VEC3 => "FLOAT_64_VEC3" | FLOAT_64_VEC4 => "FLOAT_64_VEC4" end.
Definition componentSemanticDescriptor (t : componentSemanticT) : string := match t with | POSITION => "com.io7m.zeniro.position" | NORMAL => "com.io7m.zeniro.normal" | TEXTURE_COORDINATE => "com.io7m.zeniro.texture_coordinate" | TANGENT => "com.io7m.zeniro.tangent" | BITANGENT => "com.io7m.zeniro.bitangent" | COLOR => "com.io7m.zeniro.color" | CUSTOM d => d end.
Definition jsonSectionID (i : Z) : json := JsonString (HexString.of_Z i).
Definition jsonExtension (e : extensionT) : json :=
JsonObject [
("ID", JsonString (extensionId e));
("VersionMajor", JsonInteger (extensionVersionMajor e));
("VersionMinor", JsonInteger (extensionVersionMinor e));
("Name", JsonString (extensionName e));
("Description", JsonString (extensionDescription e));
("Specification", JsonString (extensionSpecificationURI e));
("Sections", JsonArray (map jsonSectionID (extensionSections e)))
].
Definition jsonExtensions (es : list extensionT) : json := JsonArray (map jsonExtension es).
Axiom float16BitsOf : forall (r : R), Z.
Axiom float16BitsRange : forall (r : R), u16Min <= float16BitsOf r /\ float16BitsOf r <= u16Max.
Axiom float32BitsOf : forall (r : R), Z.
Axiom float32BitsRange : forall (r : R), u32Min <= float32BitsOf r /\ float32BitsOf r <= u32Max.
Axiom float64BitsOf : forall (r : R), Z.
Axiom float64BitsRange : forall (r : R), u64Min <= float64BitsOf r /\ float64BitsOf r <= u64Max.
Definition serializeValue (v : componentValueT) : list octet := match v with | ValueIntegerS8 v => octets8 (s8 v) | ValueIntegerS8Vec2 v => octets8 (s8vec2_0 v) ++ octets8 (s8vec2_1 v) | ValueIntegerS8Vec3 v => octets8 (s8vec3_0 v) ++ octets8 (s8vec3_1 v) ++ octets8 (s8vec3_2 v) | ValueIntegerS8Vec4 v => octets8 (s8vec4_0 v) ++ octets8 (s8vec4_1 v) ++ octets8 (s8vec4_2 v) ++ octets8 (s8vec4_3 v) | ValueIntegerU8 v => octets8 (u8 v) | ValueIntegerU8Vec2 v => octets8 (u8vec2_0 v) ++ octets8 (u8vec2_1 v) | ValueIntegerU8Vec3 v => octets8 (u8vec3_0 v) ++ octets8 (u8vec3_1 v) ++ octets8 (u8vec3_2 v) | ValueIntegerU8Vec4 v => octets8 (u8vec4_0 v) ++ octets8 (u8vec4_1 v) ++ octets8 (u8vec4_2 v) ++ octets8 (u8vec4_3 v) | ValueIntegerS16 v => octets16BE (s16 v) | ValueIntegerS16Vec2 v => octets16BE (s16vec2_0 v) ++ octets16BE (s16vec2_1 v) | ValueIntegerS16Vec3 v => octets16BE (s16vec3_0 v) ++ octets16BE (s16vec3_1 v) ++ octets16BE (s16vec3_2 v) | ValueIntegerS16Vec4 v => octets16BE (s16vec4_0 v) ++ octets16BE (s16vec4_1 v) ++ octets16BE (s16vec4_2 v) ++ octets16BE (s16vec4_3 v) | ValueIntegerU16 v => octets16BE (u16 v) | ValueIntegerU16Vec2 v => octets16BE (u16vec2_0 v) ++ octets16BE (u16vec2_1 v) | ValueIntegerU16Vec3 v => octets16BE (u16vec3_0 v) ++ octets16BE (u16vec3_1 v) ++ octets16BE (u16vec3_2 v) | ValueIntegerU16Vec4 v => octets16BE (u16vec4_0 v) ++ octets16BE (u16vec4_1 v) ++ octets16BE (u16vec4_2 v) ++ octets16BE (u16vec4_3 v) | ValueIntegerS32 v => octets32BE (s32 v) | ValueIntegerS32Vec2 v => octets32BE (s32vec2_0 v) ++ octets32BE (s32vec2_1 v) | ValueIntegerS32Vec3 v => octets32BE (s32vec3_0 v) ++ octets32BE (s32vec3_1 v) ++ octets32BE (s32vec3_2 v) | ValueIntegerS32Vec4 v => octets32BE (s32vec4_0 v) ++ octets32BE (s32vec4_1 v) ++ octets32BE (s32vec4_2 v) ++ octets32BE (s32vec4_3 v) | ValueIntegerU32 v => octets32BE (u32 v) | ValueIntegerU32Vec2 v => octets32BE (u32vec2_0 v) ++ octets32BE (u32vec2_1 v) | ValueIntegerU32Vec3 v => octets32BE (u32vec3_0 v) ++ octets32BE (u32vec3_1 v) ++ octets32BE (u32vec3_2 v) | ValueIntegerU32Vec4 v => octets32BE (u32vec4_0 v) ++ octets32BE (u32vec4_1 v) ++ octets32BE (u32vec4_2 v) ++ octets32BE (u32vec4_3 v) | ValueIntegerS64 v => octets64BE (s64 v) | ValueIntegerS64Vec2 v => octets64BE (s64vec2_0 v) ++ octets64BE (s64vec2_1 v) | ValueIntegerS64Vec3 v => octets64BE (s64vec3_0 v) ++ octets64BE (s64vec3_1 v) ++ octets64BE (s64vec3_2 v) | ValueIntegerS64Vec4 v => octets64BE (s64vec4_0 v) ++ octets64BE (s64vec4_1 v) ++ octets64BE (s64vec4_2 v) ++ octets64BE (s64vec4_3 v) | ValueIntegerU64 v => octets64BE (u64 v) | ValueIntegerU64Vec2 v => octets64BE (u64vec2_0 v) ++ octets64BE (u64vec2_1 v) | ValueIntegerU64Vec3 v => octets64BE (u64vec3_0 v) ++ octets64BE (u64vec3_1 v) ++ octets64BE (u64vec3_2 v) | ValueIntegerU64Vec4 v => octets64BE (u64vec4_0 v) ++ octets64BE (u64vec4_1 v) ++ octets64BE (u64vec4_2 v) ++ octets64BE (u64vec4_3 v) | ValueFloat16 v => octets16BE (float16BitsOf (f16 v)) | ValueFloat16Vec2 v => octets16BE (float16BitsOf (f16vec2_0 v)) ++ octets16BE (float16BitsOf (f16vec2_1 v)) | ValueFloat16Vec3 v => octets16BE (float16BitsOf (f16vec3_0 v)) ++ octets16BE (float16BitsOf (f16vec3_1 v)) ++ octets16BE (float16BitsOf (f16vec3_2 v)) | ValueFloat16Vec4 v => octets16BE (float16BitsOf (f16vec4_0 v)) ++ octets16BE (float16BitsOf (f16vec4_1 v)) ++ octets16BE (float16BitsOf (f16vec4_2 v)) ++ octets16BE (float16BitsOf (f16vec4_3 v)) | ValueFloat32 v => octets32BE (float32BitsOf (f32 v)) | ValueFloat32Vec2 v => octets32BE (float32BitsOf (f32vec2_0 v)) ++ octets32BE (float32BitsOf (f32vec2_1 v)) | ValueFloat32Vec3 v => octets32BE (float32BitsOf (f32vec3_0 v)) ++ octets32BE (float32BitsOf (f32vec3_1 v)) ++ octets32BE (float32BitsOf (f32vec3_2 v)) | ValueFloat32Vec4 v => octets32BE (float32BitsOf (f32vec4_0 v)) ++ octets32BE (float32BitsOf (f32vec4_1 v)) ++ octets32BE (float32BitsOf (f32vec4_2 v)) ++ octets32BE (float32BitsOf (f32vec4_3 v)) | ValueFloat64 v => octets64BE (float64BitsOf (f64 v)) | ValueFloat64Vec2 v => octets64BE (float64BitsOf (f64vec2_0 v)) ++ octets64BE (float64BitsOf (f64vec2_1 v)) | ValueFloat64Vec3 v => octets64BE (float64BitsOf (f64vec3_0 v)) ++ octets64BE (float64BitsOf (f64vec3_1 v)) ++ octets64BE (float64BitsOf (f64vec3_2 v)) | ValueFloat64Vec4 v => octets64BE (float64BitsOf (f64vec4_0 v)) ++ octets64BE (float64BitsOf (f64vec4_1 v)) ++ octets64BE (float64BitsOf (f64vec4_2 v)) ++ octets64BE (float64BitsOf (f64vec4_3 v)) end.
Definition componentTypeSizeOctets(t : componentTypeT): nat := match t with | INTEGER_SIGNED_8 => 1 | INTEGER_SIGNED_8_VEC2 => 2 | INTEGER_SIGNED_8_VEC3 => 3 | INTEGER_SIGNED_8_VEC4 => 4 | INTEGER_UNSIGNED_8 => 1 | INTEGER_UNSIGNED_8_VEC2 => 2 | INTEGER_UNSIGNED_8_VEC3 => 3 | INTEGER_UNSIGNED_8_VEC4 => 4 | INTEGER_SIGNED_16 => 2 | INTEGER_SIGNED_16_VEC2 => 4 | INTEGER_SIGNED_16_VEC3 => 6 | INTEGER_SIGNED_16_VEC4 => 8 | INTEGER_UNSIGNED_16 => 2 | INTEGER_UNSIGNED_16_VEC2 => 4 | INTEGER_UNSIGNED_16_VEC3 => 6 | INTEGER_UNSIGNED_16_VEC4 => 8 | INTEGER_SIGNED_32 => 4 | INTEGER_SIGNED_32_VEC2 => 8 | INTEGER_SIGNED_32_VEC3 => 12 | INTEGER_SIGNED_32_VEC4 => 16 | INTEGER_UNSIGNED_32 => 4 | INTEGER_UNSIGNED_32_VEC2 => 8 | INTEGER_UNSIGNED_32_VEC3 => 12 | INTEGER_UNSIGNED_32_VEC4 => 16 | INTEGER_SIGNED_64 => 8 | INTEGER_SIGNED_64_VEC2 => 16 | INTEGER_SIGNED_64_VEC3 => 24 | INTEGER_SIGNED_64_VEC4 => 32 | INTEGER_UNSIGNED_64 => 8 | INTEGER_UNSIGNED_64_VEC2 => 16 | INTEGER_UNSIGNED_64_VEC3 => 24 | INTEGER_UNSIGNED_64_VEC4 => 32 | FLOAT_16 => 2 | FLOAT_16_VEC2 => 4 | FLOAT_16_VEC3 => 6 | FLOAT_16_VEC4 => 8 | FLOAT_32 => 4 | FLOAT_32_VEC2 => 8 | FLOAT_32_VEC3 => 12 | FLOAT_32_VEC4 => 16 | FLOAT_64 => 8 | FLOAT_64_VEC2 => 16 | FLOAT_64_VEC3 => 24 | FLOAT_64_VEC4 => 32 end.
Fixpoint serializeComponentValues (vs : list componentValueT) : list octet := match vs with | [] => [] | (x :: xs) => serializeValue x ++ serializeComponentValues xs end.
Definition serializeStructureValue (s : structureValueT) : list octet := serializeComponentValues (structureComponentValues s).
Fixpoint serializeStructureValues (vs : list structureValueT) : list octet := match vs with | [] => [] | (s :: ss) => serializeStructureValue s ++ serializeStructureValues ss end.
Theorem serializedValueSizeCorrect : forall v t, valueHasType v t -> length (serializeValue v) = componentTypeSizeOctets t. Proof. (** Proof omitted for brevity. *) Qed.
Theorem serializedStructureValueSizeCorrect : forall sv st,
structureValueHasStructureType sv st ->
length (serializeStructureValue sv) = structureSizeOctets st.
Proof.
(** Proof omitted for brevity. *)
Qed.
Definition structureSizeOctets (s : structureT) : nat :=
let types := map componentType (structureComponents s) in
let sizes := map componentTypeSizeOctets types in
List.fold_right (fun x y => x + y) 0 sizes.
Definition sizePad n := (16 - (n mod 16)) mod 16.
Definition fileHeader := [
("ID", U64 fileIdentifier);
("VersionMajor", U32 1);
("VersionMinor", U32 0)
].
Definition infoSection (info: infoT) : list (string * binaryExp) :=
let jsonText := jsonSerializeString (jsonInfo info) in
let jsonExp := UTF8 jsonText in
let jsonOctets := binaryExpOctets jsonExp in
let textSize := lengthN jsonOctets in
let sizeSum := 16 + textSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 infoSectionIdentifier);
("DataSize", U64 textSize);
("JsonData", jsonExp);
("Padding", pad)
].
Definition dataSection (data : list structureValueT) : list (string * binaryExp) :=
let outData := serializeStructureValues data in
let outDataSize := lengthN outData in
let sizeSum := 16 + outDataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 dataSectionIdentifier);
("DataSize", U64 outDataSize);
("Data", Octets outData);
("Padding", pad)
].
Definition indexSection (data : indexArrayT) : list (string * binaryExp) :=
let outData := serializeIndex data in
let outDataSize := lengthN outData in
let sizeSum := 16 + outDataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 indexSectionIdentifier);
("DataSize", U64 outDataSize);
("Data", Octets outData);
("Padding", pad)
].
Definition metadataSection (m : metadataT) : list (string * binaryExp) :=
let json := metadataToJsonString m in
let jsonOctets := stringUTF8Bytes json in
let textSize := lengthN jsonOctets in
let dataSize := textSize in
let sizeSum := 16 + dataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 metadataSectionIdentifier);
("DataSize", U64 dataSize);
("JsonData", Octets jsonOctets);
("Padding", pad)
].
Definition endSection : list (string * binaryExp) := [
("ID", U64 endSectionIdentifier);
("DataSize", U64 0)
].
| 1 |
Note that, due to 8 bits being the exact size of one octet, the resulting list is
always exactly one octet, and the
produced sequence cannot actually be said to be in either big or little endian ordering.
References to this footnote:
1
|
| 2 |
Rocq's standard string is actually limited to ASCII characters. The specification assumes
that real implementations of the zeniro format will use arrays of UTF-8 encoded octets.
References to this footnote:
1
|
| 3 |
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Strings.String.
Require Import com.io7m.octetorder.OctetOrder.
Import ListNotations.
Definition zero8 : octet :=
OctExact B0 B0 B0 B0 B0 B0 B0 B0.
Definition bitOf (n position : Z) : bit :=
match Z.testbit n position with
| true => B1
| false => B0
end.
Definition octets8 (z : Z) : list octet := [
OctExact
(bitOf z 7)
(bitOf z 6)
(bitOf z 5)
(bitOf z 4)
(bitOf z 3)
(bitOf z 2)
(bitOf z 1)
(bitOf z 0)
].
Definition octets16BE (n : Z) : list octet := [
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Definition octets16LE (n : Z) : list octet := [
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8)
].
Definition octets32BE (n : Z) : list octet := [
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Definition octets32LE (n : Z) : list octet := [
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24)
].
Definition octets64BE (n : Z) : list octet := [
OctExact
(bitOf n 63)
(bitOf n 62)
(bitOf n 61)
(bitOf n 60)
(bitOf n 59)
(bitOf n 58)
(bitOf n 57)
(bitOf n 56);
OctExact
(bitOf n 55)
(bitOf n 54)
(bitOf n 53)
(bitOf n 52)
(bitOf n 51)
(bitOf n 50)
(bitOf n 49)
(bitOf n 48);
OctExact
(bitOf n 47)
(bitOf n 46)
(bitOf n 45)
(bitOf n 44)
(bitOf n 43)
(bitOf n 42)
(bitOf n 41)
(bitOf n 40);
OctExact
(bitOf n 39)
(bitOf n 38)
(bitOf n 37)
(bitOf n 36)
(bitOf n 35)
(bitOf n 34)
(bitOf n 33)
(bitOf n 32);
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0)
].
Definition octets64LE (n : Z) : list octet := [
OctExact
(bitOf n 7)
(bitOf n 6)
(bitOf n 5)
(bitOf n 4)
(bitOf n 3)
(bitOf n 2)
(bitOf n 1)
(bitOf n 0);
OctExact
(bitOf n 15)
(bitOf n 14)
(bitOf n 13)
(bitOf n 12)
(bitOf n 11)
(bitOf n 10)
(bitOf n 9)
(bitOf n 8);
OctExact
(bitOf n 23)
(bitOf n 22)
(bitOf n 21)
(bitOf n 20)
(bitOf n 19)
(bitOf n 18)
(bitOf n 17)
(bitOf n 16);
OctExact
(bitOf n 31)
(bitOf n 30)
(bitOf n 29)
(bitOf n 28)
(bitOf n 27)
(bitOf n 26)
(bitOf n 25)
(bitOf n 24);
OctExact
(bitOf n 39)
(bitOf n 38)
(bitOf n 37)
(bitOf n 36)
(bitOf n 35)
(bitOf n 34)
(bitOf n 33)
(bitOf n 32);
OctExact
(bitOf n 47)
(bitOf n 46)
(bitOf n 45)
(bitOf n 44)
(bitOf n 43)
(bitOf n 42)
(bitOf n 41)
(bitOf n 40);
OctExact
(bitOf n 55)
(bitOf n 54)
(bitOf n 53)
(bitOf n 52)
(bitOf n 51)
(bitOf n 50)
(bitOf n 49)
(bitOf n 48);
OctExact
(bitOf n 63)
(bitOf n 62)
(bitOf n 61)
(bitOf n 60)
(bitOf n 59)
(bitOf n 58)
(bitOf n 57)
(bitOf n 56)
].
Theorem octets8Count : forall (z : Z),
List.length (octets8 z) = 1.
Proof. intros. reflexivity. Qed.
Theorem octet16BECount : forall (z : Z),
List.length (octets16BE z) = 2.
Proof. intros. reflexivity. Qed.
Theorem octet16LECount : forall (z : Z),
List.length (octets16LE z) = 2.
Proof. intros. reflexivity. Qed.
Theorem octet32BECount : forall (z : Z),
List.length (octets32BE z) = 4.
Proof. intros. reflexivity. Qed.
Theorem octet32LECount : forall (z : Z),
List.length (octets32LE z) = 4.
Proof. intros. reflexivity. Qed.
Theorem octet64BECount : forall (z : Z),
List.length (octets64BE z) = 8.
Proof. intros. reflexivity. Qed.
Theorem octet64LECount : forall (z : Z),
List.length (octets64LE z) = 8.
Proof. intros. reflexivity. Qed.
Theorem octet16LEtoBE : forall (z : Z),
(octets16BE z) = List.rev (octets16LE z).
Proof. intros. reflexivity. Qed.
Theorem octet16BEtoLE : forall (z : Z),
(octets16LE z) = List.rev (octets16BE z).
Proof. intros. reflexivity. Qed.
Theorem octet32LEtoBE : forall (z : Z),
(octets32BE z) = List.rev (octets32LE z).
Proof. intros. reflexivity. Qed.
Theorem octet32BEtoLE : forall (z : Z),
(octets32LE z) = List.rev (octets32BE z).
Proof. intros. reflexivity. Qed.
Theorem octet64LEtoBE : forall (z : Z),
(octets64BE z) = List.rev (octets64LE z).
Proof. intros. reflexivity. Qed.
Theorem octet64BEtoLE : forall (z : Z),
(octets64LE z) = List.rev (octets64BE z).
Proof. intros. reflexivity. Qed.
Open Scope Z_scope.
Definition octetByte (b : Byte.byte): octet :=
let n := Byte.to_N b in
let z := Z.of_N n in
match octets8 z with
| [] => zero8
| x :: _ => x
end.
Definition stringUTF8Bytes (s : string) : list octet :=
let bs := list_byte_of_string s in
map octetByte bs.
Inductive binaryExp : Set :=
| U32 : N -> binaryExp
| U64 : N -> binaryExp
| UTF8 : string -> binaryExp
| Pad : N -> binaryExp
| Octets : list octet -> binaryExp
.
Definition binaryExpOctets (b : binaryExp) : list octet :=
match b with
| U32 x => octets32BE (Z.of_N x)
| U64 x => octets64BE (Z.of_N x)
| UTF8 s =>
let text := stringUTF8Bytes s in
let size := octets32BE (Z.of_nat (List.length text)) in
size ++ text
| Pad x => repeat zero8 (N.to_nat x)
| Octets o => o
end.
Fixpoint binaryExpsOctets (bs : list binaryExp) : list octet :=
match bs with
| [] => []
| (c :: cs) => (binaryExpOctets c) ++ (binaryExpsOctets cs)
end.
Definition binaryExpsNamedOctets (bs : list (string * binaryExp)) : list octet :=
binaryExpsOctets (map snd bs).
Lemma binaryExpsOctetsAppend : forall (xs ys : list binaryExp),
binaryExpsOctets xs ++ binaryExpsOctets ys = binaryExpsOctets (xs ++ ys).
Proof.
induction xs as [|z zs].
- intros ys.
reflexivity.
- intros ys.
simpl.
rewrite <- (IHzs ys).
rewrite app_assoc.
reflexivity.
Qed.
Lemma binaryExpOctetsSum0 : forall (xs ys : list binaryExp),
List.length (binaryExpsOctets xs ++ binaryExpsOctets ys) = List.length (binaryExpsOctets (xs ++ ys)).
Proof.
induction xs as [|z zs].
- intros ys.
reflexivity.
- intros ys.
simpl.
rewrite <- binaryExpsOctetsAppend.
rewrite app_assoc.
reflexivity.
Qed.
Open Scope nat_scope.
Lemma binaryExpOctetsSum1 : forall (xs ys : list binaryExp),
List.length (binaryExpsOctets xs) + List.length (binaryExpsOctets ys) = List.length (binaryExpsOctets (xs ++ ys)).
Proof.
induction xs as [|z zs].
- intros ys.
reflexivity.
- intros ys.
simpl.
rewrite length_app.
rewrite length_app.
rewrite <- IHzs.
rewrite Nat.add_assoc.
reflexivity.
Qed.
Lemma binaryExpOctetsSum2 : forall (x y : binaryExp),
List.length (binaryExpOctets x ++ binaryExpOctets y) =
List.length (binaryExpOctets x) + List.length (binaryExpOctets y).
Proof.
intros x y.
rewrite length_app.
reflexivity.
Qed.
Lemma binaryExpOctetsU32 : forall x, List.length (binaryExpOctets (U32 x)) = 4.
Proof. reflexivity. Qed.
Lemma binaryExpOctetsU64 : forall x, List.length (binaryExpOctets (U64 x)) = 8.
Proof. reflexivity. Qed.
Lemma binaryExpOctetsUTF8 : forall x, List.length (binaryExpOctets (UTF8 x)) = 4 + List.length (stringUTF8Bytes x).
Proof. reflexivity. Qed.
Lemma binaryExpOctetsPad : forall x, List.length (binaryExpOctets (Pad x)) = N.to_nat x.
Proof.
intro x.
simpl.
rewrite repeat_length.
reflexivity.
Qed.
Lemma binaryExpOctetsOctets : forall x, List.length (binaryExpOctets (Octets x)) = List.length x.
Proof. reflexivity. Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Reals.
From Stdlib Require Import Lra.
(** @annospec d56b85c9-f887-4861-a686-7e59fb0c056a *)
(** A set of inclusive bounds for 3D data. *)
Inductive boundsT : Set := Bounds {
(** The minimum inclusive value on the X axis. *)
boundsXMinimum : R;
(** The maximum inclusive value on the X axis. *)
boundsXMaximum : R;
(** The minimum inclusive value on the Y axis. *)
boundsYMinimum : R;
(** The maximum inclusive value on the Y axis. *)
boundsYMaximum : R;
(** The minimum inclusive value on the Z axis. *)
boundsZMinimum : R;
(** The maximum inclusive value on the Z axis. *)
boundsZMaximum : R
}.
Open Scope R_scope.
(** @annospec c4043b21-74a6-4e2c-bd0a-0ac48f6ea869 *)
(** The minimum bound must be less than or equal to the maximum bound on X. *)
Definition boundsXOrder (b : boundsT) : Prop :=
(boundsXMinimum b) <= (boundsXMaximum b).
(** @annospec d7182aaa-7588-424d-8ee8-947274f4873e *)
(** The minimum bound must be less than or equal to the maximum bound on Y. *)
Definition boundsYOrder (b : boundsT) : Prop :=
(boundsYMinimum b) <= (boundsYMaximum b).
(** @annospec fa17b827-70e1-471e-9f38-873c259bbeff *)
(** The minimum bound must be less than or equal to the maximum bound on Z. *)
Definition boundsZOrder (b : boundsT) : Prop :=
(boundsZMinimum b) <= (boundsZMaximum b).
(** @annospec 77f44990-5ade-4273-a837-c35ff683cf0b *)
(** The conjunction of propositions that denote a well-formed set of bounds. *)
Definition boundsWellFormed (b : boundsT) : Prop :=
(boundsXOrder b)
/\ (boundsYOrder b)
/\ (boundsZOrder b)
.
Example exampleBoundsUnitCube :=
Bounds (-0.5) 0.5 (-0.5) 0.5 (-0.5) 0.5.
Lemma exampleBoundsUnitCubeOrderX : boundsXOrder exampleBoundsUnitCube.
Proof. unfold boundsXOrder. simpl. lra. Qed.
Lemma exampleBoundsUnitCubeOrderY : boundsYOrder exampleBoundsUnitCube.
Proof. unfold boundsYOrder. simpl. lra. Qed.
Lemma exampleBoundsUnitCubeOrderZ : boundsZOrder exampleBoundsUnitCube.
Proof. unfold boundsZOrder. simpl. lra. Qed.
Theorem exampleBoundsUnitCubeWellFormed : boundsWellFormed exampleBoundsUnitCube.
Proof.
constructor.
exact exampleBoundsUnitCubeOrderX.
constructor.
exact exampleBoundsUnitCubeOrderY.
exact exampleBoundsUnitCubeOrderZ.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import Strings.String.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Reals.
From Stdlib Require Import Lra.
(**
* Structure component types.
*
* Each constructor represents a scalar or vector storage type.
* Integer types have integer components, while FLOAT_* types have
* IEEE-754 floating point components.
*)
(** @annospec cab5bd61-d9c4-4165-b6b7-ca3db30cce98 *)
Inductive componentTypeT : Set :=
(** Signed 8-bit integer scalar. Size: 1 octet. *)
| INTEGER_SIGNED_8
(** Vector of two signed 8-bit integers. Size: 2 octets. *)
| INTEGER_SIGNED_8_VEC2
(** Vector of three signed 8-bit integers. Size: 3 octets. *)
| INTEGER_SIGNED_8_VEC3
(** Vector of four signed 8-bit integers. Size: 4 octets. *)
| INTEGER_SIGNED_8_VEC4
(** Unsigned 8-bit integer scalar. Size: 1 octet. *)
| INTEGER_UNSIGNED_8
(** Vector of two unsigned 8-bit integers. Size: 2 octets. *)
| INTEGER_UNSIGNED_8_VEC2
(** Vector of three unsigned 8-bit integers. Size: 3 octets. *)
| INTEGER_UNSIGNED_8_VEC3
(** Vector of four unsigned 8-bit integers. Size: 4 octets. *)
| INTEGER_UNSIGNED_8_VEC4
(** Signed 16-bit integer scalar. Size: 2 octets. *)
| INTEGER_SIGNED_16
(** Vector of two signed 16-bit integers. Size: 4 octets. *)
| INTEGER_SIGNED_16_VEC2
(** Vector of three signed 16-bit integers. Size: 6 octets. *)
| INTEGER_SIGNED_16_VEC3
(** Vector of four signed 16-bit integers. Size: 8 octets. *)
| INTEGER_SIGNED_16_VEC4
(** Unsigned 16-bit integer scalar. Size: 2 octets. *)
| INTEGER_UNSIGNED_16
(** Vector of two unsigned 16-bit integers. Size: 4 octets. *)
| INTEGER_UNSIGNED_16_VEC2
(** Vector of three unsigned 16-bit integers. Size: 6 octets. *)
| INTEGER_UNSIGNED_16_VEC3
(** Vector of four unsigned 16-bit integers. Size: 8 octets. *)
| INTEGER_UNSIGNED_16_VEC4
(** Signed 32-bit integer scalar. Size: 4 octets. *)
| INTEGER_SIGNED_32
(** Vector of two signed 32-bit integers. Size: 8 octets. *)
| INTEGER_SIGNED_32_VEC2
(** Vector of three signed 32-bit integers. Size: 12 octets. *)
| INTEGER_SIGNED_32_VEC3
(** Vector of four signed 32-bit integers. Size: 16 octets. *)
| INTEGER_SIGNED_32_VEC4
(** Unsigned 32-bit integer scalar. Size: 4 octets. *)
| INTEGER_UNSIGNED_32
(** Vector of two unsigned 32-bit integers. Size: 8 octets. *)
| INTEGER_UNSIGNED_32_VEC2
(** Vector of three unsigned 32-bit integers. Size: 12 octets. *)
| INTEGER_UNSIGNED_32_VEC3
(** Vector of four unsigned 32-bit integers. Size: 16 octets. *)
| INTEGER_UNSIGNED_32_VEC4
(** Signed 64-bit integer scalar. Size: 8 octets. *)
| INTEGER_SIGNED_64
(** Vector of two signed 64-bit integers. Size: 16 octets. *)
| INTEGER_SIGNED_64_VEC2
(** Vector of three signed 64-bit integers. Size: 24 octets. *)
| INTEGER_SIGNED_64_VEC3
(** Vector of four signed 64-bit integers. Size: 32 octets. *)
| INTEGER_SIGNED_64_VEC4
(** Unsigned 64-bit integer scalar. Size: 8 octets. *)
| INTEGER_UNSIGNED_64
(** Vector of two unsigned 64-bit integers. Size: 16 octets. *)
| INTEGER_UNSIGNED_64_VEC2
(** Vector of three unsigned 64-bit integers. Size: 24 octets. *)
| INTEGER_UNSIGNED_64_VEC3
(** Vector of four unsigned 64-bit integers. Size: 32 octets. *)
| INTEGER_UNSIGNED_64_VEC4
(** IEEE-754 half-precision floating point scalar. Size: 2 octets. *)
| FLOAT_16
(** Vector of two IEEE-754 half-precision floating point values. Size: 4 octets. *)
| FLOAT_16_VEC2
(** Vector of three IEEE-754 half-precision floating point values. Size: 6 octets. *)
| FLOAT_16_VEC3
(** Vector of four IEEE-754 half-precision floating point values. Size: 8 octets. *)
| FLOAT_16_VEC4
(** IEEE-754 single-precision floating point scalar. Size: 4 octets. *)
| FLOAT_32
(** Vector of two IEEE-754 single-precision floating point values. Size: 8 octets. *)
| FLOAT_32_VEC2
(** Vector of three IEEE-754 single-precision floating point values. Size: 12 octets. *)
| FLOAT_32_VEC3
(** Vector of four IEEE-754 single-precision floating point values. Size: 16 octets. *)
| FLOAT_32_VEC4
(** IEEE-754 double-precision floating point scalar. Size: 8 octets. *)
| FLOAT_64
(** Vector of two IEEE-754 double-precision floating point values. Size: 16 octets. *)
| FLOAT_64_VEC2
(** Vector of three IEEE-754 double-precision floating point values. Size: 24 octets. *)
| FLOAT_64_VEC3
(** Vector of four IEEE-754 double-precision floating point values. Size: 32 octets. *)
| FLOAT_64_VEC4
.
(** @annospec 708e33e5-9a1c-4e42-880a-08ac4fc27b52 *)
(** Storage size of a component type in octets. *)
Definition componentTypeSizeOctets(t : componentTypeT): nat :=
match t with
| INTEGER_SIGNED_8 => 1
| INTEGER_SIGNED_8_VEC2 => 2
| INTEGER_SIGNED_8_VEC3 => 3
| INTEGER_SIGNED_8_VEC4 => 4
| INTEGER_UNSIGNED_8 => 1
| INTEGER_UNSIGNED_8_VEC2 => 2
| INTEGER_UNSIGNED_8_VEC3 => 3
| INTEGER_UNSIGNED_8_VEC4 => 4
| INTEGER_SIGNED_16 => 2
| INTEGER_SIGNED_16_VEC2 => 4
| INTEGER_SIGNED_16_VEC3 => 6
| INTEGER_SIGNED_16_VEC4 => 8
| INTEGER_UNSIGNED_16 => 2
| INTEGER_UNSIGNED_16_VEC2 => 4
| INTEGER_UNSIGNED_16_VEC3 => 6
| INTEGER_UNSIGNED_16_VEC4 => 8
| INTEGER_SIGNED_32 => 4
| INTEGER_SIGNED_32_VEC2 => 8
| INTEGER_SIGNED_32_VEC3 => 12
| INTEGER_SIGNED_32_VEC4 => 16
| INTEGER_UNSIGNED_32 => 4
| INTEGER_UNSIGNED_32_VEC2 => 8
| INTEGER_UNSIGNED_32_VEC3 => 12
| INTEGER_UNSIGNED_32_VEC4 => 16
| INTEGER_SIGNED_64 => 8
| INTEGER_SIGNED_64_VEC2 => 16
| INTEGER_SIGNED_64_VEC3 => 24
| INTEGER_SIGNED_64_VEC4 => 32
| INTEGER_UNSIGNED_64 => 8
| INTEGER_UNSIGNED_64_VEC2 => 16
| INTEGER_UNSIGNED_64_VEC3 => 24
| INTEGER_UNSIGNED_64_VEC4 => 32
| FLOAT_16 => 2
| FLOAT_16_VEC2 => 4
| FLOAT_16_VEC3 => 6
| FLOAT_16_VEC4 => 8
| FLOAT_32 => 4
| FLOAT_32_VEC2 => 8
| FLOAT_32_VEC3 => 12
| FLOAT_32_VEC4 => 16
| FLOAT_64 => 8
| FLOAT_64_VEC2 => 16
| FLOAT_64_VEC3 => 24
| FLOAT_64_VEC4 => 32
end.
(** @annospec fdf6fc95-3332-450e-a9b9-7e5e58bd2ab5 *)
(** Number of scalar components in a component type. *)
Definition componentTypeCount(t : componentTypeT): nat :=
match t with
| INTEGER_SIGNED_8
| INTEGER_UNSIGNED_8
| INTEGER_SIGNED_16
| INTEGER_UNSIGNED_16
| INTEGER_SIGNED_32
| INTEGER_UNSIGNED_32
| INTEGER_SIGNED_64
| INTEGER_UNSIGNED_64
| FLOAT_16
| FLOAT_32
| FLOAT_64 => 1
| INTEGER_SIGNED_8_VEC2
| INTEGER_UNSIGNED_8_VEC2
| INTEGER_SIGNED_16_VEC2
| INTEGER_UNSIGNED_16_VEC2
| INTEGER_SIGNED_32_VEC2
| INTEGER_UNSIGNED_32_VEC2
| INTEGER_SIGNED_64_VEC2
| INTEGER_UNSIGNED_64_VEC2
| FLOAT_16_VEC2
| FLOAT_32_VEC2
| FLOAT_64_VEC2 => 2
| INTEGER_SIGNED_8_VEC3
| INTEGER_UNSIGNED_8_VEC3
| INTEGER_SIGNED_16_VEC3
| INTEGER_UNSIGNED_16_VEC3
| INTEGER_SIGNED_32_VEC3
| INTEGER_UNSIGNED_32_VEC3
| INTEGER_SIGNED_64_VEC3
| INTEGER_UNSIGNED_64_VEC3
| FLOAT_16_VEC3
| FLOAT_32_VEC3
| FLOAT_64_VEC3 => 3
| INTEGER_SIGNED_8_VEC4
| INTEGER_UNSIGNED_8_VEC4
| INTEGER_SIGNED_16_VEC4
| INTEGER_UNSIGNED_16_VEC4
| INTEGER_SIGNED_32_VEC4
| INTEGER_UNSIGNED_32_VEC4
| INTEGER_SIGNED_64_VEC4
| INTEGER_UNSIGNED_64_VEC4
| FLOAT_16_VEC4
| FLOAT_32_VEC4
| FLOAT_64_VEC4 => 4
end.
(** @annospec 74ca7ef6-6caf-4eae-a5e7-cc72f94c5748 *)
(** Whether this type has IEEE-754 floating point components. *)
Definition componentTypeIsFloatingPoint(t : componentTypeT): bool :=
match t with
| INTEGER_SIGNED_8 => false
| INTEGER_SIGNED_8_VEC2 => false
| INTEGER_SIGNED_8_VEC3 => false
| INTEGER_SIGNED_8_VEC4 => false
| INTEGER_UNSIGNED_8 => false
| INTEGER_UNSIGNED_8_VEC2 => false
| INTEGER_UNSIGNED_8_VEC3 => false
| INTEGER_UNSIGNED_8_VEC4 => false
| INTEGER_SIGNED_16 => false
| INTEGER_SIGNED_16_VEC2 => false
| INTEGER_SIGNED_16_VEC3 => false
| INTEGER_SIGNED_16_VEC4 => false
| INTEGER_UNSIGNED_16 => false
| INTEGER_UNSIGNED_16_VEC2 => false
| INTEGER_UNSIGNED_16_VEC3 => false
| INTEGER_UNSIGNED_16_VEC4 => false
| INTEGER_SIGNED_32 => false
| INTEGER_SIGNED_32_VEC2 => false
| INTEGER_SIGNED_32_VEC3 => false
| INTEGER_SIGNED_32_VEC4 => false
| INTEGER_UNSIGNED_32 => false
| INTEGER_UNSIGNED_32_VEC2 => false
| INTEGER_UNSIGNED_32_VEC3 => false
| INTEGER_UNSIGNED_32_VEC4 => false
| INTEGER_SIGNED_64 => false
| INTEGER_SIGNED_64_VEC2 => false
| INTEGER_SIGNED_64_VEC3 => false
| INTEGER_SIGNED_64_VEC4 => false
| INTEGER_UNSIGNED_64 => false
| INTEGER_UNSIGNED_64_VEC2 => false
| INTEGER_UNSIGNED_64_VEC3 => false
| INTEGER_UNSIGNED_64_VEC4 => false
| FLOAT_16 => true
| FLOAT_16_VEC2 => true
| FLOAT_16_VEC3 => true
| FLOAT_16_VEC4 => true
| FLOAT_32 => true
| FLOAT_32_VEC2 => true
| FLOAT_32_VEC3 => true
| FLOAT_32_VEC4 => true
| FLOAT_64 => true
| FLOAT_64_VEC2 => true
| FLOAT_64_VEC3 => true
| FLOAT_64_VEC4 => true
end.
(** @annospec bf2dbdd6-ab6b-48d4-bc55-ad712f899488 *)
(** The semantic of a component. *)
Inductive componentSemanticT : Set :=
(** The component represents position data such as the positions of vertices in a 3D mesh. *)
| POSITION
(** The component represents normal vectors. *)
| NORMAL
(** The component represents the primary texture coordinates. *)
| TEXTURE_COORDINATE
(** The component represents tangent vectors. *)
| TANGENT
(** The component represents bitangent vectors. *)
| BITANGENT
(** The component represents the primary colors of vertices in a 3D mesh. *)
| COLOR
(** A custom component semantic unknown to this specification. *)
| CUSTOM : string -> componentSemanticT.
(** The descriptor for each type of component semantic. *)
Definition componentSemanticDescriptor (t : componentSemanticT) : string :=
match t with
| POSITION => "com.io7m.zeniro.position"
| NORMAL => "com.io7m.zeniro.normal"
| TEXTURE_COORDINATE => "com.io7m.zeniro.texture_coordinate"
| TANGENT => "com.io7m.zeniro.tangent"
| BITANGENT => "com.io7m.zeniro.bitangent"
| COLOR => "com.io7m.zeniro.color"
| CUSTOM d => d
end.
(** @annospec 51a7c67d-3be7-499b-9179-c4300d0db890 *)
(** The type of components. *)
Inductive componentT : Set := ComponentT {
(** The type of the component. *)
componentType : componentTypeT;
(** The name of the component. *)
componentName : string;
(** The semantic of the component. *)
componentSemantic : componentSemanticT;
}.
(** @annospec 2e0d1dd9-cb55-4b3c-97b7-fe5422fcf808 *)
(** A description of the set of components in the data. *)
Inductive structureT : Set := StructureT {
(** The list of components in declaration order. *)
structureComponents : list componentT;
}.
(** @annospec fb7167fd-c236-4afa-b227-ff78072116ba *)
(** The names of components must be unique. *)
Definition structureWFComponentNamesUnique (s : structureT) : Prop :=
List.NoDup (List.map componentName (structureComponents s)).
(** Whether names of components are unique is decidable. *)
Lemma structureWFComponentNamesUniqueDecidable : forall s,
{structureWFComponentNamesUnique s}+{~structureWFComponentNamesUnique s}.
Proof.
intros s.
unfold structureWFComponentNamesUnique.
induction (structureComponents s) as [|x xs].
- left; constructor.
- destruct IHxs as [IHL|IHR].
-- simpl in *.
destruct (List.in_dec string_dec (componentName x) (map componentName xs)) as [HinL|HinR].
--- right.
intro Hfalse.
rewrite NoDup_cons_iff in Hfalse.
intuition.
--- left.
apply NoDup_cons; auto.
-- right.
intro Hfalse.
simpl in Hfalse.
rewrite NoDup_cons_iff in Hfalse.
intuition.
Qed.
(** @annospec 43d5223e-99aa-428b-a01b-b0586a318b26 *)
(** The conjunction of propositions that denote a well-defined structure. *)
Definition structureWF (s : structureT) : Prop :=
structureWFComponentNamesUnique s.
(** Well-formedness is decidable. *)
Lemma structureWFDecidable : forall s,
{structureWF s}+{~structureWF s}.
Proof.
intros s.
destruct (structureWFComponentNamesUniqueDecidable s) as [HnuL|HnuR].
- left; auto.
- right; auto.
Qed.
(** @annospec 9277dc14-73bf-47e8-bd6f-0bc4703eb8a7 *)
Definition structureSizeOctets (s : structureT) : nat :=
let types := map componentType (structureComponents s) in
let sizes := map componentTypeSizeOctets types in
List.fold_right (fun x y => x + y) 0 sizes.
Import ListNotations.
Section Examples.
Example exampleStandardVertex :=
StructureT [
ComponentT FLOAT_32_VEC3 "position" POSITION;
ComponentT FLOAT_32_VEC3 "normal" NORMAL;
ComponentT FLOAT_32_VEC2 "uv" TEXTURE_COORDINATE
].
Lemma exampleStandardVertexNamesUnique : structureWFComponentNamesUnique exampleStandardVertex.
Proof.
unfold structureWFComponentNamesUnique.
simpl.
rewrite NoDup_cons_iff.
constructor.
- rewrite not_in_cons.
constructor.
-- congruence.
-- rewrite not_in_cons.
constructor.
--- congruence.
--- apply in_nil.
- rewrite NoDup_cons_iff.
constructor.
-- rewrite not_in_cons.
constructor.
--- congruence.
--- apply in_nil.
-- rewrite NoDup_cons_iff.
constructor.
--- apply in_nil.
--- constructor.
Qed.
End Examples.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.ComponentValues.
(** @annospec c297494b-b16a-4eb6-9ee9-ef4b70dc72b9 *)
(** The relation that maps values to types. *)
Inductive valueHasType : componentValueT -> componentTypeT -> Prop :=
| VTS8 :
forall (v : integerS8T)
(wf : componentValueWF (ValueIntegerS8 v)),
valueHasType (ValueIntegerS8 v) INTEGER_SIGNED_8
| VTS8_VEC2 :
forall (v : integerS8Vec2T)
(wf : componentValueWF (ValueIntegerS8Vec2 v)),
valueHasType (ValueIntegerS8Vec2 v) INTEGER_SIGNED_8_VEC2
| VTS8_VEC3 :
forall (v : integerS8Vec3T)
(wf : componentValueWF (ValueIntegerS8Vec3 v)),
valueHasType (ValueIntegerS8Vec3 v) INTEGER_SIGNED_8_VEC3
| VTS8_VEC4 :
forall (v : integerS8Vec4T)
(wf : componentValueWF (ValueIntegerS8Vec4 v)),
valueHasType (ValueIntegerS8Vec4 v) INTEGER_SIGNED_8_VEC4
| VTU8 :
forall (v : integerU8T)
(wf : componentValueWF (ValueIntegerU8 v)),
valueHasType (ValueIntegerU8 v) INTEGER_UNSIGNED_8
| VTU8_VEC2 :
forall (v : integerU8Vec2T)
(wf : componentValueWF (ValueIntegerU8Vec2 v)),
valueHasType (ValueIntegerU8Vec2 v) INTEGER_UNSIGNED_8_VEC2
| VTU8_VEC3 :
forall (v : integerU8Vec3T)
(wf : componentValueWF (ValueIntegerU8Vec3 v)),
valueHasType (ValueIntegerU8Vec3 v) INTEGER_UNSIGNED_8_VEC3
| VTU8_VEC4 :
forall (v : integerU8Vec4T)
(wf : componentValueWF (ValueIntegerU8Vec4 v)),
valueHasType (ValueIntegerU8Vec4 v) INTEGER_UNSIGNED_8_VEC4
| VTS16 :
forall (v : integerS16T)
(wf : componentValueWF (ValueIntegerS16 v)),
valueHasType (ValueIntegerS16 v) INTEGER_SIGNED_16
| VTS16_VEC2 :
forall (v : integerS16Vec2T)
(wf : componentValueWF (ValueIntegerS16Vec2 v)),
valueHasType (ValueIntegerS16Vec2 v) INTEGER_SIGNED_16_VEC2
| VTS16_VEC3 :
forall (v : integerS16Vec3T)
(wf : componentValueWF (ValueIntegerS16Vec3 v)),
valueHasType (ValueIntegerS16Vec3 v) INTEGER_SIGNED_16_VEC3
| VTS16_VEC4 :
forall (v : integerS16Vec4T)
(wf : componentValueWF (ValueIntegerS16Vec4 v)),
valueHasType (ValueIntegerS16Vec4 v) INTEGER_SIGNED_16_VEC4
| VTU16 :
forall (v : integerU16T)
(wf : componentValueWF (ValueIntegerU16 v)),
valueHasType (ValueIntegerU16 v) INTEGER_UNSIGNED_16
| VTU16_VEC2 :
forall (v : integerU16Vec2T)
(wf : componentValueWF (ValueIntegerU16Vec2 v)),
valueHasType (ValueIntegerU16Vec2 v) INTEGER_UNSIGNED_16_VEC2
| VTU16_VEC3 :
forall (v : integerU16Vec3T)
(wf : componentValueWF (ValueIntegerU16Vec3 v)),
valueHasType (ValueIntegerU16Vec3 v) INTEGER_UNSIGNED_16_VEC3
| VTU16_VEC4 :
forall (v : integerU16Vec4T)
(wf : componentValueWF (ValueIntegerU16Vec4 v)),
valueHasType (ValueIntegerU16Vec4 v) INTEGER_UNSIGNED_16_VEC4
| VTS32 :
forall (v : integerS32T)
(wf : componentValueWF (ValueIntegerS32 v)),
valueHasType (ValueIntegerS32 v) INTEGER_SIGNED_32
| VTS32_VEC2 :
forall (v : integerS32Vec2T)
(wf : componentValueWF (ValueIntegerS32Vec2 v)),
valueHasType (ValueIntegerS32Vec2 v) INTEGER_SIGNED_32_VEC2
| VTS32_VEC3 :
forall (v : integerS32Vec3T)
(wf : componentValueWF (ValueIntegerS32Vec3 v)),
valueHasType (ValueIntegerS32Vec3 v) INTEGER_SIGNED_32_VEC3
| VTS32_VEC4 :
forall (v : integerS32Vec4T)
(wf : componentValueWF (ValueIntegerS32Vec4 v)),
valueHasType (ValueIntegerS32Vec4 v) INTEGER_SIGNED_32_VEC4
| VTU32 :
forall (v : integerU32T)
(wf : componentValueWF (ValueIntegerU32 v)),
valueHasType (ValueIntegerU32 v) INTEGER_UNSIGNED_32
| VTU32_VEC2 :
forall (v : integerU32Vec2T)
(wf : componentValueWF (ValueIntegerU32Vec2 v)),
valueHasType (ValueIntegerU32Vec2 v) INTEGER_UNSIGNED_32_VEC2
| VTU32_VEC3 :
forall (v : integerU32Vec3T)
(wf : componentValueWF (ValueIntegerU32Vec3 v)),
valueHasType (ValueIntegerU32Vec3 v) INTEGER_UNSIGNED_32_VEC3
| VTU32_VEC4 :
forall (v : integerU32Vec4T)
(wf : componentValueWF (ValueIntegerU32Vec4 v)),
valueHasType (ValueIntegerU32Vec4 v) INTEGER_UNSIGNED_32_VEC4
| VTS64 :
forall (v : integerS64T)
(wf : componentValueWF (ValueIntegerS64 v)),
valueHasType (ValueIntegerS64 v) INTEGER_SIGNED_64
| VTS64_VEC2 :
forall (v : integerS64Vec2T)
(wf : componentValueWF (ValueIntegerS64Vec2 v)),
valueHasType (ValueIntegerS64Vec2 v) INTEGER_SIGNED_64_VEC2
| VTS64_VEC3 :
forall (v : integerS64Vec3T)
(wf : componentValueWF (ValueIntegerS64Vec3 v)),
valueHasType (ValueIntegerS64Vec3 v) INTEGER_SIGNED_64_VEC3
| VTS64_VEC4 :
forall (v : integerS64Vec4T)
(wf : componentValueWF (ValueIntegerS64Vec4 v)),
valueHasType (ValueIntegerS64Vec4 v) INTEGER_SIGNED_64_VEC4
| VTU64 :
forall (v : integerU64T)
(wf : componentValueWF (ValueIntegerU64 v)),
valueHasType (ValueIntegerU64 v) INTEGER_UNSIGNED_64
| VTU64_VEC2 :
forall (v : integerU64Vec2T)
(wf : componentValueWF (ValueIntegerU64Vec2 v)),
valueHasType (ValueIntegerU64Vec2 v) INTEGER_UNSIGNED_64_VEC2
| VTU64_VEC3 :
forall (v : integerU64Vec3T)
(wf : componentValueWF (ValueIntegerU64Vec3 v)),
valueHasType (ValueIntegerU64Vec3 v) INTEGER_UNSIGNED_64_VEC3
| VTU64_VEC4 :
forall (v : integerU64Vec4T)
(wf : componentValueWF (ValueIntegerU64Vec4 v)),
valueHasType (ValueIntegerU64Vec4 v) INTEGER_UNSIGNED_64_VEC4
| VTF16 :
forall (v : float16T)
(wf : componentValueWF (ValueFloat16 v)),
valueHasType (ValueFloat16 v) FLOAT_16
| VTF16_VEC2 :
forall (v : float16Vec2T)
(wf : componentValueWF (ValueFloat16Vec2 v)),
valueHasType (ValueFloat16Vec2 v) FLOAT_16_VEC2
| VTF16_VEC3 :
forall (v : float16Vec3T)
(wf : componentValueWF (ValueFloat16Vec3 v)),
valueHasType (ValueFloat16Vec3 v) FLOAT_16_VEC3
| VTF16_VEC4 :
forall (v : float16Vec4T)
(wf : componentValueWF (ValueFloat16Vec4 v)),
valueHasType (ValueFloat16Vec4 v) FLOAT_16_VEC4
| VTF32 :
forall (v : float32T)
(wf : componentValueWF (ValueFloat32 v)),
valueHasType (ValueFloat32 v) FLOAT_32
| VTF32_VEC2 :
forall (v : float32Vec2T)
(wf : componentValueWF (ValueFloat32Vec2 v)),
valueHasType (ValueFloat32Vec2 v) FLOAT_32_VEC2
| VTF32_VEC3 :
forall (v : float32Vec3T)
(wf : componentValueWF (ValueFloat32Vec3 v)),
valueHasType (ValueFloat32Vec3 v) FLOAT_32_VEC3
| VTF32_VEC4 :
forall (v : float32Vec4T)
(wf : componentValueWF (ValueFloat32Vec4 v)),
valueHasType (ValueFloat32Vec4 v) FLOAT_32_VEC4
| VTF64 :
forall (v : float64T)
(wf : componentValueWF (ValueFloat64 v)),
valueHasType (ValueFloat64 v) FLOAT_64
| VTF64_VEC2 :
forall (v : float64Vec2T)
(wf : componentValueWF (ValueFloat64Vec2 v)),
valueHasType (ValueFloat64Vec2 v) FLOAT_64_VEC2
| VTF64_VEC3 :
forall (v : float64Vec3T)
(wf : componentValueWF (ValueFloat64Vec3 v)),
valueHasType (ValueFloat64Vec3 v) FLOAT_64_VEC3
| VTF64_VEC4 :
forall (v : float64Vec4T)
(wf : componentValueWF (ValueFloat64Vec4 v)),
valueHasType (ValueFloat64Vec4 v) FLOAT_64_VEC4
.
Ltac solveValueHasTypeDecidable value :=
intros t;
destruct t;
try (right; unfold not; intro H; inversion H; contradiction);
destruct (componentValueWFDecidable value);
[ left; constructor; auto
| right; unfold not; intro H; inversion H; contradiction ].
(** Whether a component value has a given type is decidable. *)
Theorem valueHasTypeDecidable : forall (v : componentValueT) t,
{valueHasType v t}+{~valueHasType v t}.
Proof.
destruct v.
- solveValueHasTypeDecidable (ValueIntegerS8 v).
- solveValueHasTypeDecidable (ValueIntegerS8Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerS8Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerS8Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerU8 v).
- solveValueHasTypeDecidable (ValueIntegerU8Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerU8Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerU8Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerS16 v).
- solveValueHasTypeDecidable (ValueIntegerS16Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerS16Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerS16Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerU16 v).
- solveValueHasTypeDecidable (ValueIntegerU16Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerU16Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerU16Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerS32 v).
- solveValueHasTypeDecidable (ValueIntegerS32Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerS32Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerS32Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerU32 v).
- solveValueHasTypeDecidable (ValueIntegerU32Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerU32Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerU32Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerS64 v).
- solveValueHasTypeDecidable (ValueIntegerS64Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerS64Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerS64Vec4 v).
- solveValueHasTypeDecidable (ValueIntegerU64 v).
- solveValueHasTypeDecidable (ValueIntegerU64Vec2 v).
- solveValueHasTypeDecidable (ValueIntegerU64Vec3 v).
- solveValueHasTypeDecidable (ValueIntegerU64Vec4 v).
- solveValueHasTypeDecidable (ValueFloat16 v).
- solveValueHasTypeDecidable (ValueFloat16Vec2 v).
- solveValueHasTypeDecidable (ValueFloat16Vec3 v).
- solveValueHasTypeDecidable (ValueFloat16Vec4 v).
- solveValueHasTypeDecidable (ValueFloat32 v).
- solveValueHasTypeDecidable (ValueFloat32Vec2 v).
- solveValueHasTypeDecidable (ValueFloat32Vec3 v).
- solveValueHasTypeDecidable (ValueFloat32Vec4 v).
- solveValueHasTypeDecidable (ValueFloat64 v).
- solveValueHasTypeDecidable (ValueFloat64Vec2 v).
- solveValueHasTypeDecidable (ValueFloat64Vec3 v).
- solveValueHasTypeDecidable (ValueFloat64Vec4 v).
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import Lia.
From Stdlib Require Import Reals.
From Stdlib Require Import Lra.
Require Import com.io7m.zeniro.Component.
Open Scope Z_scope.
Axiom isNaN : R -> Prop.
Axiom isNaNDecidable : forall r, {isNaN r}+{~isNaN r}.
Axiom isInfinite : R -> Prop.
Axiom isInfiniteDecidable : forall r, {isInfinite r}+{~isInfinite r}.
(** @annospec cf058828-6cd7-4004-bedb-db9bcab53e62 *)
Definition isValidFloat (r : R) : Prop :=
(~isNaN r) /\ (~isInfinite r).
Lemma isValidFloatDecidable : forall r,
{isValidFloat r}+{~isValidFloat r}.
Proof.
intro r.
unfold isValidFloat.
destruct (isNaNDecidable r) as [HnL|HnR].
- destruct (isInfiniteDecidable r) as [HiL|HiR].
-- right; intuition.
-- right; intuition.
- destruct (isInfiniteDecidable r) as [HiL|HiR].
-- right; intuition.
-- left; intuition.
Qed.
Definition u8Min : Z := 0.
Definition u8Max : Z := (2 ^ 8) - 1.
Definition u16Min : Z := 0.
Definition u16Max : Z := (2 ^ 16) - 1.
Definition u32Min : Z := 0.
Definition u32Max : Z := (2 ^ 32) - 1.
Definition u64Min : Z := 0.
Definition u64Max : Z := (2 ^ 64) - 1.
Definition s8Min : Z := -(2 ^ 7).
Definition s8Max : Z := (2 ^ 7) - 1.
Definition s16Min : Z := -(2 ^ 15).
Definition s16Max : Z := (2 ^ 15) - 1.
Definition s32Min : Z := -(2 ^ 31).
Definition s32Max : Z := (2 ^ 31) - 1.
Definition s64Min : Z := -(2 ^ 63).
Definition s64Max : Z := (2 ^ 63) - 1.
(** A value is in the range appropriate for an 8-bit unsigned integer. *)
Definition isU8 (z : Z) : Prop :=
(u8Min <= z) /\ (z <= u8Max).
(** A value is in the range appropriate for an 16-bit unsigned integer. *)
Definition isU16 (z : Z) : Prop :=
(u16Min <= z) /\ (z <= u16Max).
(** A value is in the range appropriate for an 32-bit unsigned integer. *)
Definition isU32 (z : Z) : Prop :=
(u32Min <= z) /\ (z <= u32Max).
(** A value is in the range appropriate for an 64-bit unsigned integer. *)
Definition isU64 (z : Z) : Prop :=
(u64Min <= z) /\ (z <= u64Max).
(** A value is in the range appropriate for an 8-bit signed integer. *)
Definition isS8 (z : Z) : Prop :=
(s8Min <= z) /\ (z <= s8Max).
(** A value is in the range appropriate for a 16-bit signed integer. *)
Definition isS16 (z : Z) : Prop :=
(s16Min <= z) /\ (z <= s16Max).
(** A value is in the range appropriate for a 32-bit signed integer. *)
Definition isS32 (z : Z) : Prop :=
(s32Min <= z) /\ (z <= s32Max).
(** A value is in the range appropriate for a 64-bit signed integer. *)
Definition isS64 (z : Z) : Prop :=
(s64Min <= z) /\ (z <= s64Max).
(** Signed 8-bit integer scalar. Size: 1 octet. *)
Inductive integerS8T : Set := IntegerS8 {
s8 : Z
}.
Definition integerS8TWF (t : integerS8T) : Prop :=
isS8 (s8 t).
(** Vector of two signed 8-bit integers. Size: 2 octets. *)
Inductive integerS8Vec2T : Set := IntegerS8Vec2 {
s8vec2_0 : Z;
s8vec2_1 : Z
}.
Definition integerS8Vec2TWF (t : integerS8Vec2T) : Prop :=
isS8 (s8vec2_0 t) /\ isS8 (s8vec2_1 t).
(** Vector of three signed 8-bit integers. Size: 3 octets. *)
Inductive integerS8Vec3T : Set := IntegerS8Vec3 {
s8vec3_0 : Z;
s8vec3_1 : Z;
s8vec3_2 : Z
}.
Definition integerS8Vec3TWF (t : integerS8Vec3T) : Prop :=
isS8 (s8vec3_0 t)
/\ isS8 (s8vec3_1 t)
/\ isS8 (s8vec3_2 t).
(** Vector of four signed 8-bit integers. Size: 4 octets. *)
Inductive integerS8Vec4T : Set := IntegerS8Vec4 {
s8vec4_0 : Z;
s8vec4_1 : Z;
s8vec4_2 : Z;
s8vec4_3 : Z
}.
Definition integerS8Vec4TWF (t : integerS8Vec4T) : Prop :=
isS8 (s8vec4_0 t)
/\ isS8 (s8vec4_1 t)
/\ isS8 (s8vec4_2 t)
/\ isS8 (s8vec4_3 t).
(** Unsigned 8-bit integer scalar. Size: 1 octet. *)
Inductive integerU8T : Set := IntegerU8 {
u8 : Z
}.
Definition integerU8TWF (t : integerU8T) : Prop :=
isU8 (u8 t).
(** Vector of two unsigned 8-bit integers. Size: 2 octets. *)
Inductive integerU8Vec2T : Set := IntegerU8Vec2 {
u8vec2_0 : Z;
u8vec2_1 : Z
}.
Definition integerU8Vec2TWF (t : integerU8Vec2T) : Prop :=
isU8 (u8vec2_0 t)
/\ isU8 (u8vec2_1 t).
(** Vector of three unsigned 8-bit integers. Size: 3 octets. *)
Inductive integerU8Vec3T : Set := IntegerU8Vec3 {
u8vec3_0 : Z;
u8vec3_1 : Z;
u8vec3_2 : Z
}.
Definition integerU8Vec3TWF (t : integerU8Vec3T) : Prop :=
isU8 (u8vec3_0 t)
/\ isU8 (u8vec3_1 t)
/\ isU8 (u8vec3_2 t).
(** Vector of four unsigned 8-bit integers. Size: 4 octets. *)
Inductive integerU8Vec4T : Set := IntegerU8Vec4 {
u8vec4_0 : Z;
u8vec4_1 : Z;
u8vec4_2 : Z;
u8vec4_3 : Z
}.
Definition integerU8Vec4TWF (t : integerU8Vec4T) : Prop :=
isU8 (u8vec4_0 t)
/\ isU8 (u8vec4_1 t)
/\ isU8 (u8vec4_2 t)
/\ isU8 (u8vec4_3 t).
(** Signed 16-bit integer scalar. Size: 2 octets. *)
Inductive integerS16T : Set := IntegerS16 {
s16 : Z
}.
Definition integerS16TWF (t : integerS16T) : Prop :=
isS16 (s16 t).
(** Vector of two signed 16-bit integers. Size: 4 octets. *)
Inductive integerS16Vec2T : Set := IntegerS16Vec2 {
s16vec2_0 : Z;
s16vec2_1 : Z
}.
Definition integerS16Vec2TWF (t : integerS16Vec2T) : Prop :=
isS16 (s16vec2_0 t)
/\ isS16 (s16vec2_1 t).
(** Vector of three signed 16-bit integers. Size: 6 octets. *)
Inductive integerS16Vec3T : Set := IntegerS16Vec3 {
s16vec3_0 : Z;
s16vec3_1 : Z;
s16vec3_2 : Z
}.
Definition integerS16Vec3TWF (t : integerS16Vec3T) : Prop :=
isS16 (s16vec3_0 t)
/\ isS16 (s16vec3_1 t)
/\ isS16 (s16vec3_2 t).
(** Vector of four signed 16-bit integers. Size: 8 octets. *)
Inductive integerS16Vec4T : Set := IntegerS16Vec4 {
s16vec4_0 : Z;
s16vec4_1 : Z;
s16vec4_2 : Z;
s16vec4_3 : Z
}.
Definition integerS16Vec4TWF (t : integerS16Vec4T) : Prop :=
isS16 (s16vec4_0 t)
/\ isS16 (s16vec4_1 t)
/\ isS16 (s16vec4_2 t)
/\ isS16 (s16vec4_3 t).
(** Unsigned 16-bit integer scalar. Size: 2 octets. *)
Inductive integerU16T : Set := IntegerU16 {
u16 : Z
}.
Definition integerU16TWF (t : integerU16T) : Prop :=
isU16 (u16 t).
(** Vector of two unsigned 16-bit integers. Size: 4 octets. *)
Inductive integerU16Vec2T : Set := IntegerU16Vec2 {
u16vec2_0 : Z;
u16vec2_1 : Z
}.
Definition integerU16Vec2TWF (t : integerU16Vec2T) : Prop :=
isU16 (u16vec2_0 t)
/\ isU16 (u16vec2_1 t).
(** Vector of three unsigned 16-bit integers. Size: 6 octets. *)
Inductive integerU16Vec3T : Set := IntegerU16Vec3 {
u16vec3_0 : Z;
u16vec3_1 : Z;
u16vec3_2 : Z
}.
Definition integerU16Vec3TWF (t : integerU16Vec3T) : Prop :=
isU16 (u16vec3_0 t)
/\ isU16 (u16vec3_1 t)
/\ isU16 (u16vec3_2 t).
(** Vector of four unsigned 16-bit integers. Size: 8 octets. *)
Inductive integerU16Vec4T : Set := IntegerU16Vec4 {
u16vec4_0 : Z;
u16vec4_1 : Z;
u16vec4_2 : Z;
u16vec4_3 : Z
}.
Definition integerU16Vec4TWF (t : integerU16Vec4T) : Prop :=
isU16 (u16vec4_0 t)
/\ isU16 (u16vec4_1 t)
/\ isU16 (u16vec4_2 t)
/\ isU16 (u16vec4_3 t).
(** Signed 32-bit integer scalar. Size: 4 octets. *)
Inductive integerS32T : Set := IntegerS32 {
s32 : Z
}.
Definition integerS32TWF (t : integerS32T) : Prop :=
isS32 (s32 t).
(** Vector of two signed 32-bit integers. Size: 8 octets. *)
Inductive integerS32Vec2T : Set := IntegerS32Vec2 {
s32vec2_0 : Z;
s32vec2_1 : Z
}.
Definition integerS32Vec2TWF (t : integerS32Vec2T) : Prop :=
isS32 (s32vec2_0 t)
/\ isS32 (s32vec2_1 t).
(** Vector of three signed 32-bit integers. Size: 12 octets. *)
Inductive integerS32Vec3T : Set := IntegerS32Vec3 {
s32vec3_0 : Z;
s32vec3_1 : Z;
s32vec3_2 : Z
}.
Definition integerS32Vec3TWF (t : integerS32Vec3T) : Prop :=
isS32 (s32vec3_0 t)
/\ isS32 (s32vec3_1 t)
/\ isS32 (s32vec3_2 t).
(** Vector of four signed 32-bit integers. Size: 16 octets. *)
Inductive integerS32Vec4T : Set := IntegerS32Vec4 {
s32vec4_0 : Z;
s32vec4_1 : Z;
s32vec4_2 : Z;
s32vec4_3 : Z
}.
Definition integerS32Vec4TWF (t : integerS32Vec4T) : Prop :=
isS32 (s32vec4_0 t)
/\ isS32 (s32vec4_1 t)
/\ isS32 (s32vec4_2 t)
/\ isS32 (s32vec4_3 t).
(** Unsigned 32-bit integer scalar. Size: 4 octets. *)
Inductive integerU32T : Set := IntegerU32 {
u32 : Z
}.
Definition integerU32TWF (t : integerU32T) : Prop :=
isU32 (u32 t).
(** Vector of two unsigned 32-bit integers. Size: 8 octets. *)
Inductive integerU32Vec2T : Set := IntegerU32Vec2 {
u32vec2_0 : Z;
u32vec2_1 : Z
}.
Definition integerU32Vec2TWF (t : integerU32Vec2T) : Prop :=
isU32 (u32vec2_0 t)
/\ isU32 (u32vec2_1 t).
(** Vector of three unsigned 32-bit integers. Size: 12 octets. *)
Inductive integerU32Vec3T : Set := IntegerU32Vec3 {
u32vec3_0 : Z;
u32vec3_1 : Z;
u32vec3_2 : Z
}.
Definition integerU32Vec3TWF (t : integerU32Vec3T) : Prop :=
isU32 (u32vec3_0 t)
/\ isU32 (u32vec3_1 t)
/\ isU32 (u32vec3_2 t).
(** Vector of four unsigned 32-bit integers. Size: 16 octets. *)
Inductive integerU32Vec4T : Set := IntegerU32Vec4 {
u32vec4_0 : Z;
u32vec4_1 : Z;
u32vec4_2 : Z;
u32vec4_3 : Z
}.
Definition integerU32Vec4TWF (t : integerU32Vec4T) : Prop :=
isU32 (u32vec4_0 t)
/\ isU32 (u32vec4_1 t)
/\ isU32 (u32vec4_2 t)
/\ isU32 (u32vec4_3 t).
(** Signed 64-bit integer scalar. Size: 8 octets. *)
Inductive integerS64T : Set := IntegerS64 {
s64 : Z
}.
Definition integerS64TWF (t : integerS64T) : Prop :=
isS64 (s64 t).
(** Vector of two signed 64-bit integers. Size: 16 octets. *)
Inductive integerS64Vec2T : Set := IntegerS64Vec2 {
s64vec2_0 : Z;
s64vec2_1 : Z
}.
Definition integerS64Vec2TWF (t : integerS64Vec2T) : Prop :=
isS64 (s64vec2_0 t)
/\ isS64 (s64vec2_1 t).
(** Vector of three signed 64-bit integers. Size: 24 octets. *)
Inductive integerS64Vec3T : Set := IntegerS64Vec3 {
s64vec3_0 : Z;
s64vec3_1 : Z;
s64vec3_2 : Z
}.
Definition integerS64Vec3TWF (t : integerS64Vec3T) : Prop :=
isS64 (s64vec3_0 t)
/\ isS64 (s64vec3_1 t)
/\ isS64 (s64vec3_2 t).
(** Vector of four signed 64-bit integers. Size: 32 octets. *)
Inductive integerS64Vec4T : Set := IntegerS64Vec4 {
s64vec4_0 : Z;
s64vec4_1 : Z;
s64vec4_2 : Z;
s64vec4_3 : Z
}.
Definition integerS64Vec4TWF (t : integerS64Vec4T) : Prop :=
isS64 (s64vec4_0 t)
/\ isS64 (s64vec4_1 t)
/\ isS64 (s64vec4_2 t)
/\ isS64 (s64vec4_3 t).
(** Unsigned 64-bit integer scalar. Size: 8 octets. *)
Inductive integerU64T : Set := IntegerU64 {
u64 : Z
}.
Definition integerU64TWF (t : integerU64T) : Prop :=
isU64 (u64 t).
(** Vector of two unsigned 64-bit integers. Size: 16 octets. *)
Inductive integerU64Vec2T : Set := IntegerU64Vec2 {
u64vec2_0 : Z;
u64vec2_1 : Z
}.
Definition integerU64Vec2TWF (t : integerU64Vec2T) : Prop :=
isU64 (u64vec2_0 t)
/\ isU64 (u64vec2_1 t).
(** Vector of three unsigned 64-bit integers. Size: 24 octets. *)
Inductive integerU64Vec3T : Set := IntegerU64Vec3 {
u64vec3_0 : Z;
u64vec3_1 : Z;
u64vec3_2 : Z
}.
Definition integerU64Vec3TWF (t : integerU64Vec3T) : Prop :=
isU64 (u64vec3_0 t)
/\ isU64 (u64vec3_1 t)
/\ isU64 (u64vec3_2 t).
(** Vector of four unsigned 64-bit integers. Size: 32 octets. *)
Inductive integerU64Vec4T : Set := IntegerU64Vec4 {
u64vec4_0 : Z;
u64vec4_1 : Z;
u64vec4_2 : Z;
u64vec4_3 : Z
}.
Definition integerU64Vec4TWF (t : integerU64Vec4T) : Prop :=
isU64 (u64vec4_0 t)
/\ isU64 (u64vec4_1 t)
/\ isU64 (u64vec4_2 t)
/\ isU64 (u64vec4_3 t).
(** IEEE-754 half-precision floating point scalar. Size: 2 octets. *)
Inductive float16T : Set := Float16 {
f16 : R
}.
Definition float16TWF (t : float16T) : Prop :=
isValidFloat (f16 t).
(** Vector of two IEEE-754 half-precision floating point values. Size: 4 octets. *)
Inductive float16Vec2T : Set := Float16Vec2 {
f16vec2_0 : R;
f16vec2_1 : R
}.
Definition float16Vec2TWF (t : float16Vec2T) : Prop :=
isValidFloat (f16vec2_0 t)
/\ isValidFloat (f16vec2_1 t).
(** Vector of three IEEE-754 half-precision floating point values. Size: 6 octets. *)
Inductive float16Vec3T : Set := Float16Vec3 {
f16vec3_0 : R;
f16vec3_1 : R;
f16vec3_2 : R
}.
Definition float16Vec3TWF (t : float16Vec3T) : Prop :=
isValidFloat (f16vec3_0 t)
/\ isValidFloat (f16vec3_1 t)
/\ isValidFloat (f16vec3_2 t).
(** Vector of four IEEE-754 half-precision floating point values. Size: 8 octets. *)
Inductive float16Vec4T : Set := Float16Vec4 {
f16vec4_0 : R;
f16vec4_1 : R;
f16vec4_2 : R;
f16vec4_3 : R
}.
Definition float16Vec4TWF (t : float16Vec4T) : Prop :=
isValidFloat (f16vec4_0 t)
/\ isValidFloat (f16vec4_1 t)
/\ isValidFloat (f16vec4_2 t)
/\ isValidFloat (f16vec4_3 t).
(** IEEE-754 single-precision floating point scalar. Size: 4 octets. *)
Inductive float32T : Set := Float32 {
f32 : R
}.
Definition float32TWF (t : float32T) : Prop :=
isValidFloat (f32 t).
(** Vector of two IEEE-754 single-precision floating point values. Size: 8 octets. *)
Inductive float32Vec2T : Set := Float32Vec2 {
f32vec2_0 : R;
f32vec2_1 : R
}.
Definition float32Vec2TWF (t : float32Vec2T) : Prop :=
isValidFloat (f32vec2_0 t)
/\ isValidFloat (f32vec2_1 t).
(** Vector of three IEEE-754 single-precision floating point values. Size: 12 octets. *)
Inductive float32Vec3T : Set := Float32Vec3 {
f32vec3_0 : R;
f32vec3_1 : R;
f32vec3_2 : R
}.
Definition float32Vec3TWF (t : float32Vec3T) : Prop :=
isValidFloat (f32vec3_0 t)
/\ isValidFloat (f32vec3_1 t)
/\ isValidFloat (f32vec3_2 t).
(** Vector of four IEEE-754 single-precision floating point values. Size: 16 octets. *)
Inductive float32Vec4T : Set := Float32Vec4 {
f32vec4_0 : R;
f32vec4_1 : R;
f32vec4_2 : R;
f32vec4_3 : R
}.
Definition float32Vec4TWF (t : float32Vec4T) : Prop :=
isValidFloat (f32vec4_0 t)
/\ isValidFloat (f32vec4_1 t)
/\ isValidFloat (f32vec4_2 t)
/\ isValidFloat (f32vec4_3 t).
(** IEEE-754 double-precision floating point scalar. Size: 8 octets. *)
Inductive float64T : Set := Float64 {
f64 : R
}.
Definition float64TWF (t : float64T) : Prop :=
isValidFloat (f64 t).
(** Vector of two IEEE-754 double-precision floating point values. Size: 16 octets. *)
Inductive float64Vec2T : Set := Float64Vec2 {
f64vec2_0 : R;
f64vec2_1 : R
}.
Definition float64Vec2TWF (t : float64Vec2T) : Prop :=
isValidFloat (f64vec2_0 t)
/\ isValidFloat (f64vec2_1 t).
(** Vector of three IEEE-754 double-precision floating point values. Size: 24 octets. *)
Inductive float64Vec3T : Set := Float64Vec3 {
f64vec3_0 : R;
f64vec3_1 : R;
f64vec3_2 : R
}.
Definition float64Vec3TWF (t : float64Vec3T) : Prop :=
isValidFloat (f64vec3_0 t)
/\ isValidFloat (f64vec3_1 t)
/\ isValidFloat (f64vec3_2 t).
(** Vector of four IEEE-754 double-precision floating point values. Size: 32 octets. *)
Inductive float64Vec4T : Set := Float64Vec4 {
f64vec4_0 : R;
f64vec4_1 : R;
f64vec4_2 : R;
f64vec4_3 : R
}.
Definition float64Vec4TWF (t : float64Vec4T) : Prop :=
isValidFloat (f64vec4_0 t)
/\ isValidFloat (f64vec4_1 t)
/\ isValidFloat (f64vec4_2 t)
/\ isValidFloat (f64vec4_3 t).
(** @annospec 849eba9f-1bdd-4846-b25e-371b564030fe *)
Inductive componentValueT : Set :=
| ValueIntegerS8 (v : integerS8T)
| ValueIntegerS8Vec2 (v : integerS8Vec2T)
| ValueIntegerS8Vec3 (v : integerS8Vec3T)
| ValueIntegerS8Vec4 (v : integerS8Vec4T)
| ValueIntegerU8 (v : integerU8T)
| ValueIntegerU8Vec2 (v : integerU8Vec2T)
| ValueIntegerU8Vec3 (v : integerU8Vec3T)
| ValueIntegerU8Vec4 (v : integerU8Vec4T)
| ValueIntegerS16 (v : integerS16T)
| ValueIntegerS16Vec2 (v : integerS16Vec2T)
| ValueIntegerS16Vec3 (v : integerS16Vec3T)
| ValueIntegerS16Vec4 (v : integerS16Vec4T)
| ValueIntegerU16 (v : integerU16T)
| ValueIntegerU16Vec2 (v : integerU16Vec2T)
| ValueIntegerU16Vec3 (v : integerU16Vec3T)
| ValueIntegerU16Vec4 (v : integerU16Vec4T)
| ValueIntegerS32 (v : integerS32T)
| ValueIntegerS32Vec2 (v : integerS32Vec2T)
| ValueIntegerS32Vec3 (v : integerS32Vec3T)
| ValueIntegerS32Vec4 (v : integerS32Vec4T)
| ValueIntegerU32 (v : integerU32T)
| ValueIntegerU32Vec2 (v : integerU32Vec2T)
| ValueIntegerU32Vec3 (v : integerU32Vec3T)
| ValueIntegerU32Vec4 (v : integerU32Vec4T)
| ValueIntegerS64 (v : integerS64T)
| ValueIntegerS64Vec2 (v : integerS64Vec2T)
| ValueIntegerS64Vec3 (v : integerS64Vec3T)
| ValueIntegerS64Vec4 (v : integerS64Vec4T)
| ValueIntegerU64 (v : integerU64T)
| ValueIntegerU64Vec2 (v : integerU64Vec2T)
| ValueIntegerU64Vec3 (v : integerU64Vec3T)
| ValueIntegerU64Vec4 (v : integerU64Vec4T)
| ValueFloat16 (v : float16T)
| ValueFloat16Vec2 (v : float16Vec2T)
| ValueFloat16Vec3 (v : float16Vec3T)
| ValueFloat16Vec4 (v : float16Vec4T)
| ValueFloat32 (v : float32T)
| ValueFloat32Vec2 (v : float32Vec2T)
| ValueFloat32Vec3 (v : float32Vec3T)
| ValueFloat32Vec4 (v : float32Vec4T)
| ValueFloat64 (v : float64T)
| ValueFloat64Vec2 (v : float64Vec2T)
| ValueFloat64Vec3 (v : float64Vec3T)
| ValueFloat64Vec4 (v : float64Vec4T)
.
(** @annospec 732226a7-0e97-427b-ac0a-1e5d359641c1 *)
Definition componentValueWF (v : componentValueT) : Prop :=
match v with
| ValueIntegerS8 v => integerS8TWF v
| ValueIntegerS8Vec2 v => integerS8Vec2TWF v
| ValueIntegerS8Vec3 v => integerS8Vec3TWF v
| ValueIntegerS8Vec4 v => integerS8Vec4TWF v
| ValueIntegerU8 v => integerU8TWF v
| ValueIntegerU8Vec2 v => integerU8Vec2TWF v
| ValueIntegerU8Vec3 v => integerU8Vec3TWF v
| ValueIntegerU8Vec4 v => integerU8Vec4TWF v
| ValueIntegerS16 v => integerS16TWF v
| ValueIntegerS16Vec2 v => integerS16Vec2TWF v
| ValueIntegerS16Vec3 v => integerS16Vec3TWF v
| ValueIntegerS16Vec4 v => integerS16Vec4TWF v
| ValueIntegerU16 v => integerU16TWF v
| ValueIntegerU16Vec2 v => integerU16Vec2TWF v
| ValueIntegerU16Vec3 v => integerU16Vec3TWF v
| ValueIntegerU16Vec4 v => integerU16Vec4TWF v
| ValueIntegerS32 v => integerS32TWF v
| ValueIntegerS32Vec2 v => integerS32Vec2TWF v
| ValueIntegerS32Vec3 v => integerS32Vec3TWF v
| ValueIntegerS32Vec4 v => integerS32Vec4TWF v
| ValueIntegerU32 v => integerU32TWF v
| ValueIntegerU32Vec2 v => integerU32Vec2TWF v
| ValueIntegerU32Vec3 v => integerU32Vec3TWF v
| ValueIntegerU32Vec4 v => integerU32Vec4TWF v
| ValueIntegerS64 v => integerS64TWF v
| ValueIntegerS64Vec2 v => integerS64Vec2TWF v
| ValueIntegerS64Vec3 v => integerS64Vec3TWF v
| ValueIntegerS64Vec4 v => integerS64Vec4TWF v
| ValueIntegerU64 v => integerU64TWF v
| ValueIntegerU64Vec2 v => integerU64Vec2TWF v
| ValueIntegerU64Vec3 v => integerU64Vec3TWF v
| ValueIntegerU64Vec4 v => integerU64Vec4TWF v
| ValueFloat16 v => float16TWF v
| ValueFloat16Vec2 v => float16Vec2TWF v
| ValueFloat16Vec3 v => float16Vec3TWF v
| ValueFloat16Vec4 v => float16Vec4TWF v
| ValueFloat32 v => float32TWF v
| ValueFloat32Vec2 v => float32Vec2TWF v
| ValueFloat32Vec3 v => float32Vec3TWF v
| ValueFloat32Vec4 v => float32Vec4TWF v
| ValueFloat64 v => float64TWF v
| ValueFloat64Vec2 v => float64Vec2TWF v
| ValueFloat64Vec3 v => float64Vec3TWF v
| ValueFloat64Vec4 v => float64Vec4TWF v
end.
Lemma inRangeDecidable : forall (x low high : Z), {low <= x /\ x <= high}+{~(low <= x /\ x <= high)}.
Proof.
intros x low high.
destruct (Z_le_dec low x) as [H0|H1].
- destruct (Z_le_dec x high) as [H2|H3].
-- left. intuition.
-- right. intuition.
- right; intuition.
Qed.
Definition integerS8TWFDecidable (t : integerS8T) : {integerS8TWF t}+{~integerS8TWF t} :=
inRangeDecidable (s8 t) s8Min s8Max.
Lemma integerS8Vec4TWFDecidable : forall (t : integerS8Vec4T), {integerS8Vec4TWF t}+{~integerS8Vec4TWF t}.
Proof.
intros t.
unfold integerS8Vec4TWF.
unfold isS8.
destruct (inRangeDecidable (s8vec4_0 t) s8Min s8Max).
- destruct (inRangeDecidable (s8vec4_1 t) s8Min s8Max).
-- destruct (inRangeDecidable (s8vec4_2 t) s8Min s8Max).
--- destruct (inRangeDecidable (s8vec4_3 t) s8Min s8Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS8Vec3TWFDecidable : forall (t : integerS8Vec3T), {integerS8Vec3TWF t}+{~integerS8Vec3TWF t}.
Proof.
intros t.
unfold integerS8Vec3TWF.
unfold isS8.
destruct (inRangeDecidable (s8vec3_0 t) s8Min s8Max).
- destruct (inRangeDecidable (s8vec3_1 t) s8Min s8Max).
-- destruct (inRangeDecidable (s8vec3_2 t) s8Min s8Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS8Vec2TWFDecidable : forall (t : integerS8Vec2T), {integerS8Vec2TWF t}+{~integerS8Vec2TWF t}.
Proof.
intros t.
unfold integerS8Vec2TWF.
unfold isS8.
destruct (inRangeDecidable (s8vec2_0 t) s8Min s8Max).
- destruct (inRangeDecidable (s8vec2_1 t) s8Min s8Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerU8TWFDecidable (t : integerU8T) : {integerU8TWF t}+{~integerU8TWF t} :=
inRangeDecidable (u8 t) u8Min u8Max.
Lemma integerU8Vec4TWFDecidable : forall (t : integerU8Vec4T), {integerU8Vec4TWF t}+{~integerU8Vec4TWF t}.
Proof.
intros t.
unfold integerU8Vec4TWF.
unfold isU8.
destruct (inRangeDecidable (u8vec4_0 t) u8Min u8Max).
- destruct (inRangeDecidable (u8vec4_1 t) u8Min u8Max).
-- destruct (inRangeDecidable (u8vec4_2 t) u8Min u8Max).
--- destruct (inRangeDecidable (u8vec4_3 t) u8Min u8Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU8Vec3TWFDecidable : forall (t : integerU8Vec3T), {integerU8Vec3TWF t}+{~integerU8Vec3TWF t}.
Proof.
intros t.
unfold integerU8Vec3TWF.
unfold isU8.
destruct (inRangeDecidable (u8vec3_0 t) u8Min u8Max).
- destruct (inRangeDecidable (u8vec3_1 t) u8Min u8Max).
-- destruct (inRangeDecidable (u8vec3_2 t) u8Min u8Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU8Vec2TWFDecidable : forall (t : integerU8Vec2T), {integerU8Vec2TWF t}+{~integerU8Vec2TWF t}.
Proof.
intros t.
unfold integerU8Vec2TWF.
unfold isU8.
destruct (inRangeDecidable (u8vec2_0 t) u8Min u8Max).
- destruct (inRangeDecidable (u8vec2_1 t) u8Min u8Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerS16TWFDecidable (t : integerS16T) : {integerS16TWF t}+{~integerS16TWF t} :=
inRangeDecidable (s16 t) s16Min s16Max.
Lemma integerS16Vec4TWFDecidable : forall (t : integerS16Vec4T), {integerS16Vec4TWF t}+{~integerS16Vec4TWF t}.
Proof.
intros t.
unfold integerS16Vec4TWF.
unfold isS16.
destruct (inRangeDecidable (s16vec4_0 t) s16Min s16Max).
- destruct (inRangeDecidable (s16vec4_1 t) s16Min s16Max).
-- destruct (inRangeDecidable (s16vec4_2 t) s16Min s16Max).
--- destruct (inRangeDecidable (s16vec4_3 t) s16Min s16Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS16Vec3TWFDecidable : forall (t : integerS16Vec3T), {integerS16Vec3TWF t}+{~integerS16Vec3TWF t}.
Proof.
intros t.
unfold integerS16Vec3TWF.
unfold isS16.
destruct (inRangeDecidable (s16vec3_0 t) s16Min s16Max).
- destruct (inRangeDecidable (s16vec3_1 t) s16Min s16Max).
-- destruct (inRangeDecidable (s16vec3_2 t) s16Min s16Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS16Vec2TWFDecidable : forall (t : integerS16Vec2T), {integerS16Vec2TWF t}+{~integerS16Vec2TWF t}.
Proof.
intros t.
unfold integerS16Vec2TWF.
unfold isS16.
destruct (inRangeDecidable (s16vec2_0 t) s16Min s16Max).
- destruct (inRangeDecidable (s16vec2_1 t) s16Min s16Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerU16TWFDecidable (t : integerU16T) : {integerU16TWF t}+{~integerU16TWF t} :=
inRangeDecidable (u16 t) u16Min u16Max.
Lemma integerU16Vec4TWFDecidable : forall (t : integerU16Vec4T), {integerU16Vec4TWF t}+{~integerU16Vec4TWF t}.
Proof.
intros t.
unfold integerU16Vec4TWF.
unfold isU16.
destruct (inRangeDecidable (u16vec4_0 t) u16Min u16Max).
- destruct (inRangeDecidable (u16vec4_1 t) u16Min u16Max).
-- destruct (inRangeDecidable (u16vec4_2 t) u16Min u16Max).
--- destruct (inRangeDecidable (u16vec4_3 t) u16Min u16Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU16Vec3TWFDecidable : forall (t : integerU16Vec3T), {integerU16Vec3TWF t}+{~integerU16Vec3TWF t}.
Proof.
intros t.
unfold integerU16Vec3TWF.
unfold isU16.
destruct (inRangeDecidable (u16vec3_0 t) u16Min u16Max).
- destruct (inRangeDecidable (u16vec3_1 t) u16Min u16Max).
-- destruct (inRangeDecidable (u16vec3_2 t) u16Min u16Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU16Vec2TWFDecidable : forall (t : integerU16Vec2T), {integerU16Vec2TWF t}+{~integerU16Vec2TWF t}.
Proof.
intros t.
unfold integerU16Vec2TWF.
unfold isU16.
destruct (inRangeDecidable (u16vec2_0 t) u16Min u16Max).
- destruct (inRangeDecidable (u16vec2_1 t) u16Min u16Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerS32TWFDecidable (t : integerS32T) : {integerS32TWF t}+{~integerS32TWF t} :=
inRangeDecidable (s32 t) s32Min s32Max.
Lemma integerS32Vec4TWFDecidable : forall (t : integerS32Vec4T), {integerS32Vec4TWF t}+{~integerS32Vec4TWF t}.
Proof.
intros t.
unfold integerS32Vec4TWF.
unfold isS32.
destruct (inRangeDecidable (s32vec4_0 t) s32Min s32Max).
- destruct (inRangeDecidable (s32vec4_1 t) s32Min s32Max).
-- destruct (inRangeDecidable (s32vec4_2 t) s32Min s32Max).
--- destruct (inRangeDecidable (s32vec4_3 t) s32Min s32Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS32Vec3TWFDecidable : forall (t : integerS32Vec3T), {integerS32Vec3TWF t}+{~integerS32Vec3TWF t}.
Proof.
intros t.
unfold integerS32Vec3TWF.
unfold isS32.
destruct (inRangeDecidable (s32vec3_0 t) s32Min s32Max).
- destruct (inRangeDecidable (s32vec3_1 t) s32Min s32Max).
-- destruct (inRangeDecidable (s32vec3_2 t) s32Min s32Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS32Vec2TWFDecidable : forall (t : integerS32Vec2T), {integerS32Vec2TWF t}+{~integerS32Vec2TWF t}.
Proof.
intros t.
unfold integerS32Vec2TWF.
unfold isS32.
destruct (inRangeDecidable (s32vec2_0 t) s32Min s32Max).
- destruct (inRangeDecidable (s32vec2_1 t) s32Min s32Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerU32TWFDecidable (t : integerU32T) : {integerU32TWF t}+{~integerU32TWF t} :=
inRangeDecidable (u32 t) u32Min u32Max.
Lemma integerU32Vec4TWFDecidable : forall (t : integerU32Vec4T), {integerU32Vec4TWF t}+{~integerU32Vec4TWF t}.
Proof.
intros t.
unfold integerU32Vec4TWF.
unfold isU32.
destruct (inRangeDecidable (u32vec4_0 t) u32Min u32Max).
- destruct (inRangeDecidable (u32vec4_1 t) u32Min u32Max).
-- destruct (inRangeDecidable (u32vec4_2 t) u32Min u32Max).
--- destruct (inRangeDecidable (u32vec4_3 t) u32Min u32Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU32Vec3TWFDecidable : forall (t : integerU32Vec3T), {integerU32Vec3TWF t}+{~integerU32Vec3TWF t}.
Proof.
intros t.
unfold integerU32Vec3TWF.
unfold isU32.
destruct (inRangeDecidable (u32vec3_0 t) u32Min u32Max).
- destruct (inRangeDecidable (u32vec3_1 t) u32Min u32Max).
-- destruct (inRangeDecidable (u32vec3_2 t) u32Min u32Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU32Vec2TWFDecidable : forall (t : integerU32Vec2T), {integerU32Vec2TWF t}+{~integerU32Vec2TWF t}.
Proof.
intros t.
unfold integerU32Vec2TWF.
unfold isU32.
destruct (inRangeDecidable (u32vec2_0 t) u32Min u32Max).
- destruct (inRangeDecidable (u32vec2_1 t) u32Min u32Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerS64TWFDecidable (t : integerS64T) : {integerS64TWF t}+{~integerS64TWF t} :=
inRangeDecidable (s64 t) s64Min s64Max.
Lemma integerS64Vec4TWFDecidable : forall (t : integerS64Vec4T), {integerS64Vec4TWF t}+{~integerS64Vec4TWF t}.
Proof.
intros t.
unfold integerS64Vec4TWF.
unfold isS64.
destruct (inRangeDecidable (s64vec4_0 t) s64Min s64Max).
- destruct (inRangeDecidable (s64vec4_1 t) s64Min s64Max).
-- destruct (inRangeDecidable (s64vec4_2 t) s64Min s64Max).
--- destruct (inRangeDecidable (s64vec4_3 t) s64Min s64Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS64Vec3TWFDecidable : forall (t : integerS64Vec3T), {integerS64Vec3TWF t}+{~integerS64Vec3TWF t}.
Proof.
intros t.
unfold integerS64Vec3TWF.
unfold isS64.
destruct (inRangeDecidable (s64vec3_0 t) s64Min s64Max).
- destruct (inRangeDecidable (s64vec3_1 t) s64Min s64Max).
-- destruct (inRangeDecidable (s64vec3_2 t) s64Min s64Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerS64Vec2TWFDecidable : forall (t : integerS64Vec2T), {integerS64Vec2TWF t}+{~integerS64Vec2TWF t}.
Proof.
intros t.
unfold integerS64Vec2TWF.
unfold isS64.
destruct (inRangeDecidable (s64vec2_0 t) s64Min s64Max).
- destruct (inRangeDecidable (s64vec2_1 t) s64Min s64Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Definition integerU64TWFDecidable (t : integerU64T) : {integerU64TWF t}+{~integerU64TWF t} :=
inRangeDecidable (u64 t) u64Min u64Max.
Lemma integerU64Vec4TWFDecidable : forall (t : integerU64Vec4T), {integerU64Vec4TWF t}+{~integerU64Vec4TWF t}.
Proof.
intros t.
unfold integerU64Vec4TWF.
unfold isU64.
destruct (inRangeDecidable (u64vec4_0 t) u64Min u64Max).
- destruct (inRangeDecidable (u64vec4_1 t) u64Min u64Max).
-- destruct (inRangeDecidable (u64vec4_2 t) u64Min u64Max).
--- destruct (inRangeDecidable (u64vec4_3 t) u64Min u64Max).
---- left; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU64Vec3TWFDecidable : forall (t : integerU64Vec3T), {integerU64Vec3TWF t}+{~integerU64Vec3TWF t}.
Proof.
intros t.
unfold integerU64Vec3TWF.
unfold isU64.
destruct (inRangeDecidable (u64vec3_0 t) u64Min u64Max).
- destruct (inRangeDecidable (u64vec3_1 t) u64Min u64Max).
-- destruct (inRangeDecidable (u64vec3_2 t) u64Min u64Max).
--- left; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma integerU64Vec2TWFDecidable : forall (t : integerU64Vec2T), {integerU64Vec2TWF t}+{~integerU64Vec2TWF t}.
Proof.
intros t.
unfold integerU64Vec2TWF.
unfold isU64.
destruct (inRangeDecidable (u64vec2_0 t) u64Min u64Max).
- destruct (inRangeDecidable (u64vec2_1 t) u64Min u64Max).
-- left; intuition.
-- right; intuition.
- right; intuition.
Qed.
Lemma float16TWFDecidable (t : float16T) : {float16TWF t}+{~float16TWF t}.
Proof.
unfold float16TWF.
apply isValidFloatDecidable.
Qed.
Lemma float16Vec4TWFDecidable (t : float16Vec4T) : {float16Vec4TWF t}+{~float16Vec4TWF t}.
Proof.
unfold float16Vec4TWF.
destruct (isValidFloatDecidable (f16vec4_0 t)).
destruct (isValidFloatDecidable (f16vec4_1 t)).
destruct (isValidFloatDecidable (f16vec4_2 t)).
destruct (isValidFloatDecidable (f16vec4_3 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float16Vec3TWFDecidable (t : float16Vec3T) : {float16Vec3TWF t}+{~float16Vec3TWF t}.
Proof.
unfold float16Vec3TWF.
destruct (isValidFloatDecidable (f16vec3_0 t)).
destruct (isValidFloatDecidable (f16vec3_1 t)).
destruct (isValidFloatDecidable (f16vec3_2 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float16Vec2TWFDecidable (t : float16Vec2T) : {float16Vec2TWF t}+{~float16Vec2TWF t}.
Proof.
unfold float16Vec2TWF.
destruct (isValidFloatDecidable (f16vec2_0 t)).
destruct (isValidFloatDecidable (f16vec2_1 t)).
left; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float32TWFDecidable (t : float32T) : {float32TWF t}+{~float32TWF t}.
Proof.
unfold float32TWF.
apply isValidFloatDecidable.
Qed.
Lemma float32Vec4TWFDecidable (t : float32Vec4T) : {float32Vec4TWF t}+{~float32Vec4TWF t}.
Proof.
unfold float32Vec4TWF.
destruct (isValidFloatDecidable (f32vec4_0 t)).
destruct (isValidFloatDecidable (f32vec4_1 t)).
destruct (isValidFloatDecidable (f32vec4_2 t)).
destruct (isValidFloatDecidable (f32vec4_3 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float32Vec3TWFDecidable (t : float32Vec3T) : {float32Vec3TWF t}+{~float32Vec3TWF t}.
Proof.
unfold float32Vec3TWF.
destruct (isValidFloatDecidable (f32vec3_0 t)).
destruct (isValidFloatDecidable (f32vec3_1 t)).
destruct (isValidFloatDecidable (f32vec3_2 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float32Vec2TWFDecidable (t : float32Vec2T) : {float32Vec2TWF t}+{~float32Vec2TWF t}.
Proof.
unfold float32Vec2TWF.
destruct (isValidFloatDecidable (f32vec2_0 t)).
destruct (isValidFloatDecidable (f32vec2_1 t)).
left; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float64TWFDecidable (t : float64T) : {float64TWF t}+{~float64TWF t}.
Proof.
unfold float64TWF.
apply isValidFloatDecidable.
Qed.
Lemma float64Vec4TWFDecidable (t : float64Vec4T) : {float64Vec4TWF t}+{~float64Vec4TWF t}.
Proof.
unfold float64Vec4TWF.
destruct (isValidFloatDecidable (f64vec4_0 t)).
destruct (isValidFloatDecidable (f64vec4_1 t)).
destruct (isValidFloatDecidable (f64vec4_2 t)).
destruct (isValidFloatDecidable (f64vec4_3 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float64Vec3TWFDecidable (t : float64Vec3T) : {float64Vec3TWF t}+{~float64Vec3TWF t}.
Proof.
unfold float64Vec3TWF.
destruct (isValidFloatDecidable (f64vec3_0 t)).
destruct (isValidFloatDecidable (f64vec3_1 t)).
destruct (isValidFloatDecidable (f64vec3_2 t)).
left; intuition.
right; intuition.
right; intuition.
right; intuition.
Qed.
Lemma float64Vec2TWFDecidable (t : float64Vec2T) : {float64Vec2TWF t}+{~float64Vec2TWF t}.
Proof.
unfold float64Vec2TWF.
destruct (isValidFloatDecidable (f64vec2_0 t)).
destruct (isValidFloatDecidable (f64vec2_1 t)).
left; intuition.
right; intuition.
right; intuition.
Qed.
Theorem componentValueWFDecidable : forall (v : componentValueT), {componentValueWF v}+{~componentValueWF v}.
Proof.
intros v.
destruct v.
- apply integerS8TWFDecidable.
- apply integerS8Vec2TWFDecidable.
- apply integerS8Vec3TWFDecidable.
- apply integerS8Vec4TWFDecidable.
- apply integerU8TWFDecidable.
- apply integerU8Vec2TWFDecidable.
- apply integerU8Vec3TWFDecidable.
- apply integerU8Vec4TWFDecidable.
- apply integerS16TWFDecidable.
- apply integerS16Vec2TWFDecidable.
- apply integerS16Vec3TWFDecidable.
- apply integerS16Vec4TWFDecidable.
- apply integerU16TWFDecidable.
- apply integerU16Vec2TWFDecidable.
- apply integerU16Vec3TWFDecidable.
- apply integerU16Vec4TWFDecidable.
- apply integerS32TWFDecidable.
- apply integerS32Vec2TWFDecidable.
- apply integerS32Vec3TWFDecidable.
- apply integerS32Vec4TWFDecidable.
- apply integerU32TWFDecidable.
- apply integerU32Vec2TWFDecidable.
- apply integerU32Vec3TWFDecidable.
- apply integerU32Vec4TWFDecidable.
- apply integerS64TWFDecidable.
- apply integerS64Vec2TWFDecidable.
- apply integerS64Vec3TWFDecidable.
- apply integerS64Vec4TWFDecidable.
- apply integerU64TWFDecidable.
- apply integerU64Vec2TWFDecidable.
- apply integerU64Vec3TWFDecidable.
- apply integerU64Vec4TWFDecidable.
- apply float16TWFDecidable.
- apply float16Vec2TWFDecidable.
- apply float16Vec3TWFDecidable.
- apply float16Vec4TWFDecidable.
- apply float32TWFDecidable.
- apply float32Vec2TWFDecidable.
- apply float32Vec3TWFDecidable.
- apply float32Vec4TWFDecidable.
- apply float64TWFDecidable.
- apply float64Vec2TWFDecidable.
- apply float64Vec3TWFDecidable.
- apply float64Vec4TWFDecidable.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import List.
Require Import com.io7m.zeniro.Metadata.
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.ComponentValueTyping.
Require Import com.io7m.zeniro.ComponentValues.
Require Import com.io7m.zeniro.Info.
Require Import com.io7m.zeniro.Index.
Require Import com.io7m.zeniro.StructureTyping.
(** @annospec da2dc6bc-c6a4-434d-806f-2aa4de0c6c7c *)
(** The top-level model of a data file. *)
Inductive fileT := FileT {
(** The file info. *)
fileInfo : infoT;
(** The file data; the array of structure values. *)
fileData : list structureValueT;
(** The file index data. *)
fileIndexData : option (list Z);
(** The metadata. *)
fileMetadata : metadataT
}.
(** @annospec 94d56116-a342-44ef-89cd-258546db4055 *)
(** If index info is present, index data is present. *)
Definition fileWFIndexDataPresentIf0 (file : fileT) : Prop :=
shapeIndexInfo (infoShape (fileInfo file)) <> None -> fileIndexData file <> None.
(** Well-formedness is decidable. *)
Lemma fileWFIndexDataPresentIf0Decidable : forall f,
{fileWFIndexDataPresentIf0 f}+{~fileWFIndexDataPresentIf0 f}.
Proof.
intro f.
unfold fileWFIndexDataPresentIf0.
destruct (shapeIndexInfo (infoShape (fileInfo f))) as [i|] eqn:Hi.
destruct (fileIndexData f) as [d|] eqn:Hd.
- left; discriminate.
- right.
intro H.
assert (Some i <> None) as Hobvious by discriminate.
pose proof (H Hobvious) as Hcontra.
contradict Hcontra.
reflexivity.
- left.
intro Hcontra.
contradict Hcontra.
reflexivity.
Qed.
(** @annospec 5c56ce59-c3f5-4a06-a5aa-f541dd706c7b *)
(** If index data is present, index info is present. *)
Definition fileWFIndexDataPresentIf1 (file : fileT) : Prop :=
fileIndexData file <> None -> shapeIndexInfo (infoShape (fileInfo file)) <> None.
(** Well-formedness is decidable. *)
Lemma fileWFIndexDataPresentIf1Decidable : forall f,
{fileWFIndexDataPresentIf1 f}+{~fileWFIndexDataPresentIf1 f}.
Proof.
intro f.
unfold fileWFIndexDataPresentIf1.
destruct (fileIndexData f) as [d|] eqn:Hd.
destruct (shapeIndexInfo (infoShape (fileInfo f))) as [i|] eqn:Hi.
- left; discriminate.
- right.
intro H.
assert (Some d <> None) as Hobvious by discriminate.
pose proof (H Hobvious) as Hcontra.
contradict Hcontra.
reflexivity.
- left.
intro Hcontra.
contradict Hcontra.
reflexivity.
Qed.
(** @annospec 76bc2391-2457-4b13-af0e-243d6f1b8d02 *)
(** Iff index data is present, index info is present. *)
Definition fileWFIndexDataPresentIff (file : fileT) : Prop :=
shapeIndexInfo (infoShape (fileInfo file)) <> None <-> fileIndexData file <> None.
(** Well-formedness is decidable. *)
Lemma fileWFIndexDataPresentIffDecidable : forall f,
{fileWFIndexDataPresentIff f}+{~fileWFIndexDataPresentIff f}.
Proof.
intro f.
unfold fileWFIndexDataPresentIff.
destruct (fileWFIndexDataPresentIf0Decidable f) as [H0L|H0R].
unfold fileWFIndexDataPresentIf0 in H0L.
destruct (fileWFIndexDataPresentIf1Decidable f) as [H1L|H1R].
unfold fileWFIndexDataPresentIf1 in H1L.
- intuition.
- intuition.
- intuition.
Qed.
(** @annospec 24aa463a-1d09-4d0b-9b1f-09f91f5cb0c3 *)
(** If index data is present, it must be well-formed. *)
Definition fileWFIndexData (file : fileT) : Prop :=
let info := fileInfo file in
let shape := infoShape info in
match shapeIndexInfo shape with
| Some indexInfo =>
let indexType := indexType indexInfo in
match fileIndexData file with
| Some indexData => indexArrayWF (Z.of_N (shapeElementCount shape)) (IndexArray indexType indexData)
| None => True
end
| None => True
end.
(** Well-formedness is decidable. *)
Lemma fileWFIndexDataDecidable : forall f,
{fileWFIndexData f}+{~fileWFIndexData f}.
Proof.
unfold fileWFIndexData.
intros f.
destruct (shapeIndexInfo (infoShape (fileInfo f))) as [i|] eqn:Hi.
destruct (fileIndexData f) as [d|] eqn:Hd.
remember (IndexArray (indexType i) d) as ia.
remember (Z.of_N (shapeElementCount (infoShape (fileInfo f)))) as dataSize.
- apply indexArrayWFDecidable.
- left; auto.
- left; auto.
Qed.
(** @annospec 8ebd0fb0-fc84-4656-8d4e-1a8ebc5dd2d4 *)
(** The number of structure values must match the declared count. *)
Definition fileWFDataLength (f : fileT) : Prop :=
length (fileData f) = N.to_nat (shapeElementCount (infoShape (fileInfo f))).
(** Well-formedness is decidable. *)
Lemma fileWFDataLengthDecidable : forall f,
{fileWFDataLength f}+{~fileWFDataLength f}.
Proof.
intros f.
unfold fileWFDataLength.
remember (length (fileData f)) as x.
remember (N.to_nat (shapeElementCount (infoShape (fileInfo f)))).
apply Nat.eq_dec.
Qed.
(** @annospec ac966206-0a19-45c8-9775-eaf0600a1972 *)
(** The type of structure values must match the declared type. *)
Definition fileWFDataTyped (f : fileT) : Prop :=
let type := infoStructure (fileInfo f) in
Forall (fun e => structureValueHasStructureType e type) (fileData f).
(** Well-formedness is decidable. *)
Lemma fileWFDataTypedDecidable : forall f,
{fileWFDataTyped f}+{~fileWFDataTyped f}.
Proof.
intros f.
unfold fileWFDataTyped.
remember (infoStructure (fileInfo f)) as type.
induction (fileData f) as [|e es].
- left; constructor.
- destruct IHes as [IHL|IHR].
-- destruct (structureValueHasStructureTypeDecidable e type) as [H0|H1].
--- left; constructor; auto.
--- right.
intros Hfalse.
pose proof (Forall_inv Hfalse) as HK.
intuition.
-- right.
intros Hfalse.
pose proof (Forall_inv_tail Hfalse) as HK.
contradiction.
Qed.
(** @annospec 7fdb3658-d3ac-4a3e-8f80-beff5133a1c3 *)
(** The conjunction of properties that must hold for a well-formed file. *)
Definition fileWF (file : fileT) : Prop :=
fileWFIndexDataPresentIff file
/\ fileWFIndexData file
/\ fileWFDataLength file
/\ fileWFDataTyped file
/\ infoWF (fileInfo file).
(** Well-formedness is decidable. *)
Theorem fileWFDecidable : forall f,
{fileWF f}+{~fileWF f}.
Proof.
intros f.
unfold fileWF.
destruct (fileWFIndexDataPresentIffDecidable f).
- destruct (fileWFIndexDataDecidable f).
-- destruct (fileWFDataLengthDecidable f).
--- destruct (fileWFDataTypedDecidable f).
---- destruct (infoWFDecidable (fileInfo f)).
----- left; constructor; auto.
----- right; intuition.
---- right; intuition.
--- right; intuition.
-- right; intuition.
- right; intuition.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Strings.Byte.
From Stdlib Require Import BinNat.
From Stdlib Require Import Strings.String.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Reals.
From Stdlib Require Import Lia.
Require Import com.io7m.zeniro.ComponentValues.
Require Import com.io7m.zeniro.Binary.
Require Import com.io7m.zeniro.Info.
Require Import com.io7m.zeniro.Index.
Require Import com.io7m.zeniro.Metadata.
Require Import com.io7m.zeniro.Json.
Require Import com.io7m.zeniro.JsonData.
Require Import com.io7m.zeniro.StructureTyping.
Require Import com.io7m.zeniro.Serialization.
Require Import com.io7m.entomos.FileFormat.
Require Import com.io7m.entomos.Tags.
Open Scope string_scope.
Open Scope N_scope.
Import ListNotations.
(** @annospec d98c8760-4d39-43a7-bd79-2238f9afa35a *)
Definition sizePad n :=
(16 - (n mod 16)) mod 16.
(** @annospec f5360e22-6021-4e60-8e8e-a617ee90c243 *)
Lemma sizePadRange : forall n,
0 <= (sizePad n) < 16.
Proof.
intros n.
unfold sizePad.
apply N.mod_bound_pos.
assert ((n mod 16) < 16) as Hlt.
- apply (N.mod_upper_bound n 16).
discriminate.
- lia.
- lia.
Qed.
(** @annospec 1d9e827f-9ced-4297-814f-67a6ab916e8b *)
Lemma sizePadModulo : forall n,
((sizePad n) + n) mod 16 = 0.
Proof.
intro n.
unfold sizePad.
remember (n mod 16) as r.
assert (r < 16) as Hrlt. {
subst r.
apply (N.mod_lt n 16).
discriminate.
}
destruct r as [|m].
- simpl. rewrite Heqr. reflexivity.
- remember (N.pos m) as r.
assert (16 - r < 16) as H0 by (lia).
rewrite (N.mod_small _ _ H0).
rewrite N.Div0.add_mod.
rewrite <- Heqr.
rewrite (N.mod_small _ _ H0).
rewrite (N.sub_add r 16).
apply N.Div0.mod_same.
lia.
Qed.
Definition lengthN {A : Type} (xs : list A) : N :=
N.of_nat (length xs).
(** @annospec 9a701194-f693-40d1-8428-6ccda2d7a445 *)
Definition fileIdentifier : N :=
0x895A4E520D0A1A0A.
(** @annospec 7add872d-07d9-4991-9e06-eaf299fc6706 *)
Definition fileHeader := [
("ID", U64 fileIdentifier);
("VersionMajor", U32 1);
("VersionMinor", U32 0)
].
(** @annospec 5ba15780-b782-45fd-9a74-d81d92396465 *)
Definition infoSectionIdentifier : N :=
0x5A4E525F494E464F.
(** @annospec d5142af6-6e28-4e20-af94-2ad65f7a4359 *)
Definition infoSection (info: infoT) : list (string * binaryExp) :=
let jsonText := jsonSerializeString (jsonInfo info) in
let jsonExp := UTF8 jsonText in
let jsonOctets := binaryExpOctets jsonExp in
let textSize := lengthN jsonOctets in
let sizeSum := 16 + textSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 infoSectionIdentifier);
("DataSize", U64 textSize);
("JsonData", jsonExp);
("Padding", pad)
].
(** @annospec 7c7bede8-0a6c-4202-b763-a52b1744cdab *)
Definition dataSectionIdentifier : N :=
0x5A4E525F44415441.
(** @annospec 87b219f1-aee5-4e2a-b829-ffc773b02e5f *)
Definition dataSection (data : list structureValueT) : list (string * binaryExp) :=
let outData := serializeStructureValues data in
let outDataSize := lengthN outData in
let sizeSum := 16 + outDataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 dataSectionIdentifier);
("DataSize", U64 outDataSize);
("Data", Octets outData);
("Padding", pad)
].
(** @annospec a056bfb8-c44d-4161-b393-904b3691c429 *)
Definition indexSectionIdentifier : N :=
0x5A4E525F494E4458.
(** @annospec 51269e24-1e0d-4c98-9617-f4522f08841f *)
Definition indexSection (data : indexArrayT) : list (string * binaryExp) :=
let outData := serializeIndex data in
let outDataSize := lengthN outData in
let sizeSum := 16 + outDataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 indexSectionIdentifier);
("DataSize", U64 outDataSize);
("Data", Octets outData);
("Padding", pad)
].
Definition metadataToJsonString (m: metadataT) : string :=
jsonSerializeString (jsonMetadata m).
(** @annospec 95d923c8-650d-4ce4-b6c9-085bb73935e8 *)
Definition metadataSectionIdentifier : N :=
0x5A4E525F4D455441.
(** @annospec 428dfdd1-ee29-42eb-bfa3-47a51c12d776 *)
Definition metadataSection (m : metadataT) : list (string * binaryExp) :=
let json := metadataToJsonString m in
let jsonOctets := stringUTF8Bytes json in
let textSize := lengthN jsonOctets in
let dataSize := textSize in
let sizeSum := 16 + dataSize in
let pad := Pad (sizePad sizeSum) in
[
("ID", U64 metadataSectionIdentifier);
("DataSize", U64 dataSize);
("JsonData", Octets jsonOctets);
("Padding", pad)
].
(** @annospec f033f187-16cb-43ef-90ce-6eb9002f854a *)
Definition endSectionIdentifier : N :=
0x5A4E525F454E4421.
(** @annospec 7241925c-91b2-4541-9032-2a19c1947edd *)
Definition endSection : list (string * binaryExp) := [
("ID", U64 endSectionIdentifier);
("DataSize", U64 0)
].
(** @annospec 1b0ddfeb-8cd4-4422-b2c7-fd2b98856e81 *)
Lemma fileHeaderSize : lengthN (binaryExpsNamedOctets fileHeader) = 16.
Proof. reflexivity. Qed.
(** @annospec 4ca78091-96b6-465f-bbc1-da7cdfb77fe4 *)
Lemma infoSectionSize : forall i,
lengthN (binaryExpsNamedOctets (infoSection i)) mod 16 = 0.
Proof.
intros i.
unfold infoSection.
remember (U64 infoSectionIdentifier) as ID.
remember (jsonSerializeString (jsonInfo i)) as JsonText.
remember (UTF8 JsonText) as JSONUTF8.
remember (binaryExpOctets JSONUTF8) as JSONOctets.
remember (U64 (lengthN JSONOctets)) as DataSize.
remember (Pad (sizePad (16 + (lengthN JSONOctets)))) as Padding.
unfold binaryExpsNamedOctets.
simpl.
rewrite List.app_assoc.
rewrite List.app_assoc.
rewrite List.app_assoc.
unfold lengthN.
rewrite length_app.
rewrite length_app.
rewrite length_app.
rewrite length_app.
simpl.
rewrite Nat.add_0_r.
subst ID.
rewrite binaryExpOctetsU64.
subst DataSize.
rewrite binaryExpOctetsU64.
subst JSONUTF8.
rewrite binaryExpOctetsUTF8.
subst Padding.
rewrite binaryExpOctetsPad.
subst JSONOctets.
unfold lengthN.
rewrite binaryExpOctetsUTF8.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
unfold stringUTF8Bytes.
rewrite length_map.
change (N.of_nat 8) with 8%N.
change (N.of_nat 4) with 4%N.
rewrite Nnat.N2Nat.id.
change (8 + 8) with 16%N.
remember (N.of_nat (Datatypes.length (list_byte_of_string JsonText))) as k.
rewrite N.add_comm.
apply sizePadModulo.
Qed.
(** @annospec aa273758-6011-48c3-83f6-ddb3b5a665ab *)
Lemma dataSectionSize : forall s,
lengthN (binaryExpsNamedOctets (dataSection s)) mod 16 = 0.
Proof.
intros s.
unfold dataSection.
remember (U64 dataSectionIdentifier) as SID.
remember (serializeStructureValues s) as SOutData.
remember (lengthN SOutData) as SOutDataSize.
remember (U64 SOutDataSize) as SDataSize.
remember (Octets SOutData) as SOctets.
remember (Pad (sizePad (16 + SOutDataSize))) as SPad.
unfold binaryExpsNamedOctets.
simpl.
rewrite List.app_assoc.
rewrite List.app_assoc.
rewrite List.app_assoc.
unfold lengthN.
rewrite length_app.
rewrite length_app.
rewrite length_app.
rewrite length_app.
simpl.
rewrite Nat.add_0_r.
subst SID.
subst SDataSize.
subst SOctets.
subst SPad.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsOctets.
rewrite binaryExpOctetsPad.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.N2Nat.id.
assert ((lengthN SOutData) = (N.of_nat (Datatypes.length SOutData))) as H0
by (reflexivity).
rewrite <- HeqSOutDataSize in H0.
rewrite <- H0.
change (N.of_nat 8) with 8%N.
change (8 + 8) with 16%N.
rewrite N.add_comm.
apply sizePadModulo.
Qed.
(** @annospec 0b4d5693-41f9-4300-acd1-fdf0a8452a30 *)
Lemma indexSectionSize : forall i,
lengthN (binaryExpsNamedOctets (indexSection i)) mod 16 = 0.
Proof.
intros i.
unfold indexSection.
remember (U64 indexSectionIdentifier) as SID.
remember (serializeIndex i) as SOutData.
remember (lengthN SOutData) as SOutDataSize.
remember (U64 SOutDataSize) as SDataSize.
remember (Octets SOutData) as SOctets.
remember (Pad (sizePad (16 + SOutDataSize))) as SPad.
unfold binaryExpsNamedOctets.
simpl.
rewrite List.app_assoc.
rewrite List.app_assoc.
rewrite List.app_assoc.
unfold lengthN.
rewrite length_app.
rewrite length_app.
rewrite length_app.
rewrite length_app.
simpl.
rewrite Nat.add_0_r.
subst SID.
subst SDataSize.
subst SOctets.
subst SPad.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsOctets.
rewrite binaryExpOctetsPad.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.N2Nat.id.
assert ((lengthN SOutData) = (N.of_nat (Datatypes.length SOutData))) as H0
by (reflexivity).
rewrite <- HeqSOutDataSize in H0.
rewrite <- H0.
change (N.of_nat 8) with 8%N.
change (8 + 8) with 16%N.
rewrite N.add_comm.
apply sizePadModulo.
Qed.
(** @annospec 3f81e79d-7bd4-4249-b98e-49d3b4b20082 *)
Lemma metadataSectionSize : forall s,
lengthN (binaryExpsNamedOctets (metadataSection s)) mod 16 = 0.
Proof.
intros s.
unfold metadataSection.
remember (U64 metadataSectionIdentifier) as SID.
remember (stringUTF8Bytes (metadataToJsonString s)) as SOutData.
remember (lengthN SOutData) as SOutDataSize.
remember (U64 SOutDataSize) as SDataSize.
remember (Octets SOutData) as SOctets.
remember (Pad (sizePad (16 + SOutDataSize))) as SPad.
unfold binaryExpsNamedOctets.
simpl.
rewrite List.app_assoc.
rewrite List.app_assoc.
rewrite List.app_assoc.
unfold lengthN.
rewrite length_app.
rewrite length_app.
rewrite length_app.
rewrite length_app.
simpl.
rewrite Nat.add_0_r.
subst SID.
subst SDataSize.
subst SOctets.
subst SPad.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsU64.
rewrite binaryExpOctetsOctets.
rewrite binaryExpOctetsPad.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.Nat2N.inj_add.
rewrite Nnat.N2Nat.id.
assert ((lengthN SOutData) = (N.of_nat (Datatypes.length SOutData))) as H0
by (reflexivity).
rewrite <- HeqSOutDataSize in H0.
rewrite <- H0.
change (N.of_nat 8) with 8%N.
change (8 + 8) with 16%N.
rewrite N.add_comm.
apply sizePadModulo.
Qed.
(** @annospec 56594614-58eb-483b-860a-18ac60869351 *)
Lemma endSectionSize : length (binaryExpsNamedOctets endSection) = 16%nat.
Proof. reflexivity. Qed.
Definition tagFileIdentifier : TagT :=
tagOfZ (Z.of_N fileIdentifier).
Definition tagSectionEndIdentifier : TagT :=
tagOfZ (Z.of_N endSectionIdentifier).
Definition fileSectionInfo : FileSectionDescriptionT :=
FileSectionDescription
(tagOfZ (Z.of_N infoSectionIdentifier))
FSO_MustBeFirst
FSC_One.
Definition fileSectionIndex : FileSectionDescriptionT :=
FileSectionDescription
(tagOfZ (Z.of_N indexSectionIdentifier))
FSO_AnyOrder
FSC_ZeroToOne.
Definition fileSectionData : FileSectionDescriptionT :=
FileSectionDescription
(tagOfZ (Z.of_N dataSectionIdentifier))
FSO_AnyOrder
FSC_One.
Definition fileSectionMetadata : FileSectionDescriptionT :=
FileSectionDescription
(tagOfZ (Z.of_N metadataSectionIdentifier))
FSO_AnyOrder
FSC_ZeroToOne.
Definition fileDescription1 : FileDescriptionT :=
FileDescription
tagFileIdentifier
1
0
[fileSectionInfo; fileSectionIndex; fileSectionData; fileSectionMetadata]
tagSectionEndIdentifier
UnknownSectionsPermitted
.
Lemma fileDescription1InvariantsAtMostOneFirst : fileSectionAtMostOneFirst (fileSections fileDescription1).
Proof. unfold fileSectionAtMostOneFirst; simpl; auto. Qed.
Lemma fileDescription1InvariantsAtMostOneLast : fileSectionAtMostOneLast (fileSections fileDescription1).
Proof. unfold fileSectionAtMostOneLast; simpl; auto. Qed.
Lemma fileDescription1InvariantsTagsUnique : fileSectionTagsUnique (fileSections fileDescription1).
Proof.
unfold fileSectionTagsUnique; simpl; auto.
set (tag3 := tagOfZ 6507229080868705345).
set (tag2 := tagOfZ 6507229080717448257).
set (tag1 := tagOfZ 6507229080802182232).
set (tag0 := tagOfZ 6507229080802182735).
constructor.
intro Hin0.
inversion Hin0.
contradict H; discriminate.
inversion H.
contradict H0; discriminate.
inversion H0.
contradict H1; discriminate.
auto.
constructor.
intro Hin1.
inversion Hin1.
contradict H; discriminate.
inversion H.
contradict H0; discriminate.
auto.
constructor.
intro Hin2.
inversion Hin2.
contradict H; discriminate.
auto.
constructor.
auto.
constructor.
Qed.
Lemma fileDescription1InvariantsFileNotSection : fileSectionFileNotSection fileDescription1.
Proof.
unfold fileSectionFileNotSection; simpl; auto.
unfold tagFileIdentifier.
unfold fileIdentifier.
intuition.
contradict H0; discriminate.
contradict H; discriminate.
contradict H0; discriminate.
contradict H; discriminate.
Qed.
Lemma fileDescription1InvariantsEndNotSection : endSectionFileNotSection fileDescription1.
Proof.
unfold endSectionFileNotSection; simpl; auto.
unfold tagFileIdentifier.
unfold tagSectionEndIdentifier.
intuition.
contradict H0; discriminate.
contradict H; discriminate.
contradict H0; discriminate.
contradict H; discriminate.
Qed.
Theorem fileDescription1Invariants : fileDescriptionInvariants fileDescription1.
Proof.
constructor.
exact fileDescription1InvariantsAtMostOneFirst.
constructor.
exact fileDescription1InvariantsAtMostOneLast.
constructor.
exact fileDescription1InvariantsTagsUnique.
constructor.
exact fileDescription1InvariantsFileNotSection.
exact fileDescription1InvariantsEndNotSection.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import List.
Require Import com.io7m.zeniro.ComponentValues.
(** @annospec 7543898e-1e15-441c-91c9-5ce52551654f *)
(** The type of indices. *)
Inductive indexTypeT : Set :=
(** Index values are 8-bit unsigned integers. *)
| INDEX_8
(** Index values are 16-bit unsigned integers. *)
| INDEX_16
(** Index values are 32-bit unsigned integers. *)
| INDEX_32
.
(** @annospec 0e6c6bec-0902-411e-bf3d-893a564a5f24 *)
(** The semantics of indices. *)
Inductive indexSemanticT : Set :=
(** Indices represent a list of line segments. *)
| INDEX_SEMANTIC_LINE_LIST
(** Indices represent a list of line segments (strips). *)
| INDEX_SEMANTIC_LINE_STRIP
(** Indices represent a list of triangles. *)
| INDEX_SEMANTIC_TRIANGLE_LIST
(** Indices represent a list of triangles (strips). *)
| INDEX_SEMANTIC_TRIANGLE_STRIP
(** Indices represent a list of triangles (fan). *)
| INDEX_SEMANTIC_TRIANGLE_FAN
.
(** @annospec 069601fd-0b10-4118-a4be-1f1f73c174d1 *)
(** Information about indices. *)
Inductive indexInfoT : Set := IndexInfo {
(** The index type. *)
indexType: indexTypeT;
(** The number of indices. *)
indexCount: Z;
(** The semantics of indices. *)
indexSemantic: indexSemanticT
}.
(** @annospec ad722e8a-42a8-4c42-a94f-e184155b56bd *)
(** A proposition that states if index info is well-formed. *)
Definition indexInfoWF (i : indexInfoT) : Prop :=
0 < indexCount i.
(** Well-formedness is decidable. *)
Theorem indexInfoWFDecidable : forall i,
{indexInfoWF i}+{~indexInfoWF i}.
Proof.
destruct i as [t c].
destruct (Z_lt_dec 0 c) as [HL|HR].
- left; auto.
- right; auto.
Qed.
(** @annospec baacf6b3-a50c-4100-a678-51e49fd04062 *)
(** An index array. *)
Inductive indexArrayT := IndexArray {
indexElementType : indexTypeT;
indexElements : list Z
}.
(** @annospec 2b084426-2f92-48bf-a513-b440fcad5915 *)
(** The proposition that describes whether an index is in range for its type. *)
Definition indexWithinBitRange (i : Z) (t : indexTypeT) : Prop :=
match t with
| INDEX_8 => 0 <= i /\ i < (2 ^ 8)
| INDEX_16 => 0 <= i /\ i < (2 ^ 16)
| INDEX_32 => 0 <= i /\ i < (2 ^ 32)
end.
(** Whether an index is in range is decidable. *)
Theorem indexWithinBitRangeDecidable : forall i t,
{indexWithinBitRange i t}+{~indexWithinBitRange i t}.
Proof.
intros i t.
unfold indexWithinBitRange.
destruct t.
- destruct (Z_le_dec 0 i) as [HLL|HLR].
-- destruct (Z_lt_dec i (2 ^ 8)) as [HUL|HUR].
--- left; auto.
--- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
-- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
- destruct (Z_le_dec 0 i) as [HLL|HLR].
-- destruct (Z_lt_dec i (2 ^ 16)) as [HUL|HUR].
--- left; auto.
--- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
-- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
- destruct (Z_le_dec 0 i) as [HLL|HLR].
-- destruct (Z_lt_dec i (2 ^ 32)) as [HUL|HUR].
--- left; auto.
--- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
-- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
Qed.
(** @annospec 06cde4b2-6e70-441f-a17e-4f30c57de3df *)
(** Whether an index is within range, is decidable. *)
Theorem indexWithinRangeDecidable : forall e s,
{0 <= e /\ e < s}+{~(0 <= e /\ e < s)}.
Proof.
intros e s.
destruct (Z_le_dec 0 e) as [HLeL|HLeR].
- destruct (Z_lt_dec e s) as [HltL|HltR].
-- left; auto.
-- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
- right. unfold not. intro Hfalse. inversion Hfalse. contradiction.
Qed.
(** @annospec 06cde4b2-6e70-441f-a17e-4f30c57de3df *)
(**
An index array is well-formed if: element of the array is non-negative and < dataSize.
This ensures indices do not refer to nonexistent data elements.
*)
Definition indexArrayWFElementsLtDataSize (dataSize : Z) (i : indexArrayT) : Prop :=
Forall (fun e => 0 <= e /\ e < dataSize) (indexElements i).
(** Whether an index array is well-formed (data size) is decidable. *)
Lemma indexArrayWFElementsLtDataSizeDecidable : forall dataSize i,
{indexArrayWFElementsLtDataSize dataSize i}+{~indexArrayWFElementsLtDataSize dataSize i}.
Proof.
intros dataSize i.
unfold indexArrayWFElementsLtDataSize.
induction (indexElements i) as [|x xs].
- left.
constructor.
- destruct IHxs as [IHL|IHR].
-- destruct (indexWithinRangeDecidable x dataSize) as [HsL|HsR].
--- left.
auto.
--- right.
unfold not.
intros Hfalse.
pose proof (Forall_inv Hfalse) as HP.
auto.
-- right.
unfold not.
intros Hfalse.
pose proof (Forall_inv_tail Hfalse) as HP.
auto.
Qed.
(** @annospec de4fb77d-3c46-441f-b146-3744a0e9096e *)
(**
An index array is well-formed if every element of the array is < m, where m = 2 ^ t,
where t is the declared size of the indices.
*)
Definition indexArrayWFElementsBitRange (i : indexArrayT) : Prop :=
Forall (fun e => indexWithinBitRange e (indexElementType i)) (indexElements i).
(** Whether an index array is well-formed (bit range) is decidable. *)
Lemma indexArrayWFElementsBitRangeDecidable : forall i,
{indexArrayWFElementsBitRange i}+{~indexArrayWFElementsBitRange i}.
Proof.
intros i.
unfold indexArrayWFElementsBitRange.
induction (indexElements i) as [|x xs].
- left.
constructor.
- destruct IHxs as [IHL|IHR].
-- destruct (indexWithinBitRangeDecidable x (indexElementType i)) as [HsL|HsR].
--- left.
auto.
--- right.
unfold not.
intros Hfalse.
pose proof (Forall_inv Hfalse) as HP.
auto.
-- right.
unfold not.
intros Hfalse.
pose proof (Forall_inv_tail Hfalse) as HP.
auto.
Qed.
(** @annospec df1af83a-9d74-428f-8142-1f98afed6e11 *)
(** An index array is well-formed if the array is non-empty. *)
Definition indexArrayWFElementsNonEmpty (i : indexArrayT) : Prop :=
(indexElements i) <> nil.
(** Whether an index array is non-empty is decidable. *)
Lemma indexArrayWFElementsNonEmptyDecidable : forall i,
{indexArrayWFElementsNonEmpty i}+{~indexArrayWFElementsNonEmpty i}.
Proof.
intros i.
unfold indexArrayWFElementsNonEmpty.
induction (indexElements i) as [|y ys].
- right; auto.
- left; discriminate.
Qed.
(** @annospec d7a661cf-7bdf-4ea8-b07b-e7f5cef6a98e *)
(**
The conjunction of the properties that must be true of a well-formed index array.
*)
Definition indexArrayWF (dataSize : Z) (i : indexArrayT) : Prop :=
indexArrayWFElementsNonEmpty i
/\ indexArrayWFElementsLtDataSize dataSize i
/\ indexArrayWFElementsBitRange i.
(** Whether an index array is well-formed is decidable. *)
Theorem indexArrayWFDecidable : forall dataSize i,
{indexArrayWF dataSize i}+{~indexArrayWF dataSize i}.
Proof.
intros dataSize i.
destruct (indexArrayWFElementsNonEmptyDecidable i) as [HneL|HneR].
- destruct (indexArrayWFElementsLtDataSizeDecidable dataSize i) as [HdsL|HdsR].
-- destruct (indexArrayWFElementsBitRangeDecidable i) as [HbrL|HbrR].
--- left; constructor; auto.
--- right.
unfold not.
intros [HF0 [HF1 HF2]].
contradiction.
-- right.
unfold not.
intros [HF0 [HF1 HF2]].
contradiction.
- right.
unfold not.
intros [HF0 [HF1 HF2]].
contradiction.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Strings.String.
From Stdlib Require Import NArith.
Require Import com.io7m.zeniro.Bounds.
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.Index.
(** @annospec e5fc2b6b-bb48-46cf-9f16-5540737c5f25 *)
(** The data is a 1D array. *)
Inductive shapeArray1DT : Set := ShapeArray1D {
shapeArray1DLength : N;
}.
(** @annospec aa1133fe-1354-447c-86c3-fa75ee0e01be *)
(** The data is a 2D array. *)
Inductive shapeArray2DT : Set := ShapeArray2D {
shapeArray2DSizeX : N;
shapeArray2DSizeY : N;
}.
(** @annospec 16bbaa10-5949-4a71-8b54-c0d41d952cbb *)
(** The data is a 3D array. *)
Inductive shapeArray3DT : Set := ShapeArray3D {
shapeArray3DSizeX : N;
shapeArray3DSizeY : N;
shapeArray3DSizeZ : N;
}.
(** @annospec be9f4378-d319-4ae2-9c86-fbd181ea76e3 *)
(** The data is a polygon mesh. *)
Inductive shapeMeshT : Set := ShapeMeshT {
shapeMeshLength : N;
shapeMeshBounds : option boundsT;
shapeMeshIndex : option indexInfoT;
}.
(** @annospec 95816788-e524-4661-8339-34da7913e42f *)
(** The shape of the data. *)
Inductive shapeT : Set :=
| SArray1D : shapeArray1DT -> shapeT
| SArray2D : shapeArray2DT -> shapeT
| SArray3D : shapeArray3DT -> shapeT
| SMesh : shapeMeshT -> shapeT.
(** @annospec d5cbac8d-1a3e-4a41-a7cd-3ed8a1cab466 *)
(** The number of elements that make up the data. *)
Definition shapeElementCount (shape : shapeT) : N :=
match shape with
| SArray1D a => shapeArray1DLength a
| SArray2D a => (shapeArray2DSizeX a) * (shapeArray2DSizeY a)
| SArray3D a => (shapeArray3DSizeX a) * (shapeArray3DSizeY a) * (shapeArray3DSizeZ a)
| SMesh a => shapeMeshLength a
end.
(** The index info associated with the shape. *)
Definition shapeIndexInfo (shape : shapeT) : option indexInfoT :=
match shape with
| SArray1D _ => None
| SArray2D _ => None
| SArray3D _ => None
| SMesh a => shapeMeshIndex a
end.
(** @annospec 21a1cfc6-b59b-4cd6-b968-fb7dcbc95ce1 *)
(** Information about extensions to the file. *)
Inductive extensionT : Set := Extension {
(** The unique ID of the extension. *)
extensionId : string;
(** The major version of the extension. *)
extensionVersionMajor : Z;
(** The minor version of the extension. *)
extensionVersionMinor : Z;
(** The list of section identifiers covered by the extension. *)
extensionSections : list Z;
(** The humanly-readable extension name. *)
extensionName : string;
(** The humanly-readable extension description. *)
extensionDescription : string;
(** The URI of the specification. *)
extensionSpecificationURI : string
}.
(** @annospec cad2a248-8a48-483d-b6b2-f70043588672 *)
(** Information about the data in the file. *)
Inductive infoT : Set := Info {
(** The shape of the data. *)
infoShape : shapeT;
(** The structure of the data. *)
infoStructure : structureT;
(** The list of extensions. *)
infoExtensions : list extensionT
}.
(** The propositions that indicate if info is well-formed. *)
Definition infoWF (i : infoT) : Prop :=
structureWF (infoStructure i).
(** Well-formedness is decidable. *)
Theorem infoWFDecidable : forall i,
{infoWF i}+{~infoWF i}.
Proof.
intros i.
destruct (structureWFDecidable (infoStructure i)).
- left; auto.
- right; auto.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Reals.
From Stdlib Require Import ZArith.
From Stdlib Require Import Strings.String.
From Stdlib Require Import Numbers.DecimalString.
From Stdlib Require Import Lists.List.
Local Open Scope string_scope.
Import ListNotations.
(** A JSON expression. *)
Inductive json : Set :=
(** A boolean constant. *)
| JsonBoolean : bool -> json
(** An integer constant. *)
| JsonInteger : Z -> json
(** A floating point constant. *)
| JsonFloat : R -> json
(** A string constant. *)
| JsonString : string -> json
(** An object. *)
| JsonObject : list (string * json) -> json
(** An array. *)
| JsonArray : list json -> json
.
(** The string representation of a floating-point value. *)
Axiom stringOfR : R -> string.
(** The string representation of an integer. *)
Definition string_of_Z (n : Z) : string :=
match n with
| 0%Z => "0"
| Z.pos _ => NilZero.string_of_uint (Nat.to_uint (Z.to_nat n))
| Z.neg _ => "-" ++ NilZero.string_of_uint (Nat.to_uint (Z.to_nat (Z.abs n)))
end.
(** The tokens that make up a serialized JSON expression. *)
Inductive jsonToken : Set :=
| JTTrue : jsonToken
| JTFalse : jsonToken
| JTInteger : Z -> jsonToken
| JTFloat : R -> jsonToken
| JTString : string -> jsonToken
| JTObjectStart : jsonToken
| JTObjectEnd : jsonToken
| JTColon : jsonToken
| JTComma : jsonToken
| JTArrayStart : jsonToken
| JTArrayEnd : jsonToken
.
(** Insert comma tokens between each element of the list. *)
Fixpoint jsonComma (ss : list (list jsonToken)) : list jsonToken :=
match ss with
| [] => []
| (x :: []) => x
| (x :: xs) => x ++ JTComma :: (jsonComma xs)
end.
(** An example empty object. *)
Example objectEmpty0 :=
JsonObject [
].
(** An example simple object. *)
Example objectSimple0 :=
JsonObject [
("x", JsonInteger 23);
("y", JsonInteger 24);
("z", JsonInteger 25)
].
(** An example simple array. *)
Example arraySimple0 :=
JsonArray [
(JsonInteger 23);
(JsonInteger 24);
(JsonInteger 25)
].
(** Serialize a JSON expression to a list of JSON tokens. *)
Fixpoint jsonSerialize (j : json) : list jsonToken :=
match j with
| JsonBoolean true => [JTTrue]
| JsonBoolean false => [JTFalse]
| JsonInteger n => [JTInteger n]
| JsonFloat r => [JTFloat r]
| JsonString s => [JTString s]
| JsonObject o =>
let props := map (fun p => JTString (fst p) :: JTColon :: jsonSerialize (snd p)) o in
JTObjectStart :: (jsonComma props) ++ [JTObjectEnd]
| JsonArray a =>
let values := map jsonSerialize a in
JTArrayStart :: (jsonComma values) ++ [JTArrayEnd]
end.
(** Convert a JSON token to a string. *)
Definition jsonStringOne (t : jsonToken) : string :=
match t with
| JTTrue => "true"
| JTFalse => "false"
| JTInteger n => string_of_Z n
| JTFloat r => stringOfR r
| JTString s => """" ++ s ++ """"
| JTObjectStart => "{"
| JTObjectEnd => "}"
| JTColon => ":"
| JTComma => ","
| JTArrayStart => "["
| JTArrayEnd => "]"
end.
(** Serialize a JSON expression to a string. *)
Definition jsonSerializeString (j : json) : string :=
let tokens := jsonSerialize j in
let texts := map jsonStringOne tokens in
fold_left append texts "".
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
Require Import com.io7m.zeniro.Bounds.
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.Index.
Require Import com.io7m.zeniro.Info.
Require Import com.io7m.zeniro.Json.
Require Import com.io7m.zeniro.Metadata.
From Stdlib Require Import Strings.String.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Reals.
From Stdlib Require Import Strings.HexString.
Import ListNotations.
Open Scope string_scope.
Definition jsonIndexType (i : indexTypeT) : json :=
JsonString match i with
| INDEX_8 => "INDEX_8"
| INDEX_16 => "INDEX_16"
| INDEX_32 => "INDEX_32"
end.
Definition jsonIndexSemantic (i : indexSemanticT) : json :=
JsonString match i with
| INDEX_SEMANTIC_LINE_LIST => "INDEX_SEMANTIC_LINE_LIST"
| INDEX_SEMANTIC_LINE_STRIP => "INDEX_SEMANTIC_LINE_STRIP"
| INDEX_SEMANTIC_TRIANGLE_LIST => "INDEX_SEMANTIC_TRIANGLE_LIST"
| INDEX_SEMANTIC_TRIANGLE_STRIP => "INDEX_SEMANTIC_TRIANGLE_STRIP"
| INDEX_SEMANTIC_TRIANGLE_FAN => "INDEX_SEMANTIC_TRIANGLE_FAN"
end.
Definition jsonIndex (i : indexInfoT) : json :=
JsonObject [
("Type", jsonIndexType (indexType i));
("Count", JsonInteger (indexCount i));
("Semantic", jsonIndexSemantic (indexSemantic i))
].
Definition jsonIndexOptional (b : option indexInfoT) : list (string * json) :=
match b with
| Some k => [("Index", jsonIndex k)]
| None => []
end.
Definition jsonBounds (b : boundsT) : json :=
JsonObject [
("XMinimum", JsonFloat (boundsXMinimum b));
("XMaximum", JsonFloat (boundsXMaximum b));
("YMinimum", JsonFloat (boundsYMinimum b));
("YMaximum", JsonFloat (boundsYMaximum b));
("ZMinimum", JsonFloat (boundsZMinimum b));
("ZMaximum", JsonFloat (boundsZMaximum b))
].
Definition jsonBoundsOptional (b : option boundsT) : list (string * json) :=
match b with
| Some k => [("Bounds", jsonBounds k)]
| None => []
end.
Definition jsonComponentType (t : componentTypeT) : json :=
JsonString match t with
| INTEGER_SIGNED_8 => "INTEGER_SIGNED_8"
| INTEGER_SIGNED_8_VEC2 => "INTEGER_SIGNED_8_VEC2"
| INTEGER_SIGNED_8_VEC3 => "INTEGER_SIGNED_8_VEC3"
| INTEGER_SIGNED_8_VEC4 => "INTEGER_SIGNED_8_VEC4"
| INTEGER_UNSIGNED_8 => "INTEGER_UNSIGNED_8"
| INTEGER_UNSIGNED_8_VEC2 => "INTEGER_UNSIGNED_8_VEC2"
| INTEGER_UNSIGNED_8_VEC3 => "INTEGER_UNSIGNED_8_VEC3"
| INTEGER_UNSIGNED_8_VEC4 => "INTEGER_UNSIGNED_8_VEC4"
| INTEGER_SIGNED_16 => "INTEGER_SIGNED_16"
| INTEGER_SIGNED_16_VEC2 => "INTEGER_SIGNED_16_VEC2"
| INTEGER_SIGNED_16_VEC3 => "INTEGER_SIGNED_16_VEC3"
| INTEGER_SIGNED_16_VEC4 => "INTEGER_SIGNED_16_VEC4"
| INTEGER_UNSIGNED_16 => "INTEGER_UNSIGNED_16"
| INTEGER_UNSIGNED_16_VEC2 => "INTEGER_UNSIGNED_16_VEC2"
| INTEGER_UNSIGNED_16_VEC3 => "INTEGER_UNSIGNED_16_VEC3"
| INTEGER_UNSIGNED_16_VEC4 => "INTEGER_UNSIGNED_16_VEC4"
| INTEGER_SIGNED_32 => "INTEGER_SIGNED_32"
| INTEGER_SIGNED_32_VEC2 => "INTEGER_SIGNED_32_VEC2"
| INTEGER_SIGNED_32_VEC3 => "INTEGER_SIGNED_32_VEC3"
| INTEGER_SIGNED_32_VEC4 => "INTEGER_SIGNED_32_VEC4"
| INTEGER_UNSIGNED_32 => "INTEGER_UNSIGNED_32"
| INTEGER_UNSIGNED_32_VEC2 => "INTEGER_UNSIGNED_32_VEC2"
| INTEGER_UNSIGNED_32_VEC3 => "INTEGER_UNSIGNED_32_VEC3"
| INTEGER_UNSIGNED_32_VEC4 => "INTEGER_UNSIGNED_32_VEC4"
| INTEGER_SIGNED_64 => "INTEGER_SIGNED_64"
| INTEGER_SIGNED_64_VEC2 => "INTEGER_SIGNED_64_VEC2"
| INTEGER_SIGNED_64_VEC3 => "INTEGER_SIGNED_64_VEC3"
| INTEGER_SIGNED_64_VEC4 => "INTEGER_SIGNED_64_VEC4"
| INTEGER_UNSIGNED_64 => "INTEGER_UNSIGNED_64"
| INTEGER_UNSIGNED_64_VEC2 => "INTEGER_UNSIGNED_64_VEC2"
| INTEGER_UNSIGNED_64_VEC3 => "INTEGER_UNSIGNED_64_VEC3"
| INTEGER_UNSIGNED_64_VEC4 => "INTEGER_UNSIGNED_64_VEC4"
| FLOAT_16 => "FLOAT_16"
| FLOAT_16_VEC2 => "FLOAT_16_VEC2"
| FLOAT_16_VEC3 => "FLOAT_16_VEC3"
| FLOAT_16_VEC4 => "FLOAT_16_VEC4"
| FLOAT_32 => "FLOAT_32"
| FLOAT_32_VEC2 => "FLOAT_32_VEC2"
| FLOAT_32_VEC3 => "FLOAT_32_VEC3"
| FLOAT_32_VEC4 => "FLOAT_32_VEC4"
| FLOAT_64 => "FLOAT_64"
| FLOAT_64_VEC2 => "FLOAT_64_VEC2"
| FLOAT_64_VEC3 => "FLOAT_64_VEC3"
| FLOAT_64_VEC4 => "FLOAT_64_VEC4"
end.
Definition jsonComponent (c : componentT) : json :=
JsonObject [
("Name", JsonString (componentName c));
("Type", jsonComponentType (componentType c));
("Semantic", JsonString (componentSemanticDescriptor (componentSemantic c)))
].
Definition jsonComponents (c : list componentT) : json :=
JsonArray (map jsonComponent c).
Definition jsonStructure (s : structureT) : json :=
JsonObject [
("Components", jsonComponents (structureComponents s))
].
Definition jsonShape (s : shapeT) : json :=
match s with
| SArray1D a => JsonObject [
("@Shape", JsonString "Array1D");
("Length", JsonInteger (Z.of_N (shapeArray1DLength a)))
]
| SArray2D a => JsonObject [
("@Shape", JsonString "Array2D");
("SizeX", JsonInteger (Z.of_N (shapeArray2DSizeX a)));
("SizeY", JsonInteger (Z.of_N (shapeArray2DSizeY a)))
]
| SArray3D a => JsonObject [
("@Shape", JsonString "Array3D");
("SizeX", JsonInteger (Z.of_N (shapeArray3DSizeX a)));
("SizeY", JsonInteger (Z.of_N (shapeArray3DSizeY a)));
("SizeZ", JsonInteger (Z.of_N (shapeArray3DSizeZ a)))
]
| SMesh a =>
let index := jsonIndexOptional (shapeMeshIndex a) in
let bounds := jsonBoundsOptional (shapeMeshBounds a) in
let properties := [
("@Shape", JsonString "Mesh");
("Length", JsonInteger (Z.of_N (shapeMeshLength a)))
] in
JsonObject (properties ++ index ++ bounds)
end.
Definition jsonSectionID (i : Z) : json :=
JsonString (HexString.of_Z i).
Definition jsonExtension (e : extensionT) : json :=
JsonObject [
("ID", JsonString (extensionId e));
("VersionMajor", JsonInteger (extensionVersionMajor e));
("VersionMinor", JsonInteger (extensionVersionMinor e));
("Name", JsonString (extensionName e));
("Description", JsonString (extensionDescription e));
("Specification", JsonString (extensionSpecificationURI e));
("Sections", JsonArray (map jsonSectionID (extensionSections e)))
].
Definition jsonExtensions (es : list extensionT) : json :=
JsonArray (map jsonExtension es).
Definition jsonInfo (i : infoT) : json :=
let schema := [("$Schema", JsonString "urn:com.io7m.zeniro:info:1.0")] in
let shape := [("Shape", jsonShape (infoShape i))] in
let structure := [("Structure", jsonStructure (infoStructure i))] in
let extensions := [("Extensions", jsonExtensions (infoExtensions i))] in
JsonObject (schema ++ shape ++ structure ++ extensions).
Definition jsonMetadata (m : metadataT) : json :=
let elements := MetadataStringMap.elements (metaValues m) in
let properties := map (fun p => (fst p, JsonArray (map JsonString (snd p)))) elements in
JsonObject properties.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Strings.String.
From Stdlib Require Import Lists.List.
From Stdlib Require Import FSets.FMapAVL.
From Stdlib Require Import Structures.OrderedTypeEx.
Module MetadataStringMap :=
FMapAVL.Make(String_as_OT).
(** @annospec a7edef0e-6ef3-4383-97c6-7ac42fe084a9 *)
(** A map of metadata. *)
Inductive metadataT := MetadataT {
metaValues : MetadataStringMap.t (list string)
}.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import ZArith.
From Stdlib Require Import Reals.
From Stdlib Require Import Lia.
From Stdlib Require Import Lists.List.
Require Import com.io7m.zeniro.Index.
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.ComponentValues.
Require Import com.io7m.zeniro.ComponentValueTyping.
Require Import com.io7m.zeniro.StructureTyping.
Require Import com.io7m.zeniro.Binary.
Require Import com.io7m.octetorder.OctetOrder.
Import ListNotations.
Open Scope Z_scope.
(** The bits of the given value assuming that R is IEEE754 Binary16 value. *)
Axiom float16BitsOf : forall (r : R), Z.
(** The bits of the given value assuming that R is IEEE754 Binary32 value. *)
Axiom float32BitsOf : forall (r : R), Z.
(** The bits of the given value assuming that R is IEEE754 Binary64 value. *)
Axiom float64BitsOf : forall (r : R), Z.
(** The bits of a 16-bit float satisfy the range for a 16 bit integer. *)
Axiom float16BitsRange : forall (r : R),
u16Min <= float16BitsOf r /\ float16BitsOf r <= u16Max.
(** The bits of a 32-bit float satisfy the range for a 32 bit integer. *)
Axiom float32BitsRange : forall (r : R),
u32Min <= float32BitsOf r /\ float32BitsOf r <= u32Max.
(** The bits of a 64-bit float satisfy the range for a 64 bit integer. *)
Axiom float64BitsRange : forall (r : R),
u64Min <= float64BitsOf r /\ float64BitsOf r <= u64Max.
(** Serialize a component value to a list of octets. *)
Definition serializeValue (v : componentValueT) : list octet :=
match v with
| ValueIntegerS8 v => octets8 (s8 v)
| ValueIntegerS8Vec2 v => octets8 (s8vec2_0 v) ++ octets8 (s8vec2_1 v)
| ValueIntegerS8Vec3 v => octets8 (s8vec3_0 v) ++ octets8 (s8vec3_1 v) ++ octets8 (s8vec3_2 v)
| ValueIntegerS8Vec4 v => octets8 (s8vec4_0 v) ++ octets8 (s8vec4_1 v) ++ octets8 (s8vec4_2 v) ++ octets8 (s8vec4_3 v)
| ValueIntegerU8 v => octets8 (u8 v)
| ValueIntegerU8Vec2 v => octets8 (u8vec2_0 v) ++ octets8 (u8vec2_1 v)
| ValueIntegerU8Vec3 v => octets8 (u8vec3_0 v) ++ octets8 (u8vec3_1 v) ++ octets8 (u8vec3_2 v)
| ValueIntegerU8Vec4 v => octets8 (u8vec4_0 v) ++ octets8 (u8vec4_1 v) ++ octets8 (u8vec4_2 v) ++ octets8 (u8vec4_3 v)
| ValueIntegerS16 v => octets16BE (s16 v)
| ValueIntegerS16Vec2 v => octets16BE (s16vec2_0 v) ++ octets16BE (s16vec2_1 v)
| ValueIntegerS16Vec3 v => octets16BE (s16vec3_0 v) ++ octets16BE (s16vec3_1 v) ++ octets16BE (s16vec3_2 v)
| ValueIntegerS16Vec4 v => octets16BE (s16vec4_0 v) ++ octets16BE (s16vec4_1 v) ++ octets16BE (s16vec4_2 v) ++ octets16BE (s16vec4_3 v)
| ValueIntegerU16 v => octets16BE (u16 v)
| ValueIntegerU16Vec2 v => octets16BE (u16vec2_0 v) ++ octets16BE (u16vec2_1 v)
| ValueIntegerU16Vec3 v => octets16BE (u16vec3_0 v) ++ octets16BE (u16vec3_1 v) ++ octets16BE (u16vec3_2 v)
| ValueIntegerU16Vec4 v => octets16BE (u16vec4_0 v) ++ octets16BE (u16vec4_1 v) ++ octets16BE (u16vec4_2 v) ++ octets16BE (u16vec4_3 v)
| ValueIntegerS32 v => octets32BE (s32 v)
| ValueIntegerS32Vec2 v => octets32BE (s32vec2_0 v) ++ octets32BE (s32vec2_1 v)
| ValueIntegerS32Vec3 v => octets32BE (s32vec3_0 v) ++ octets32BE (s32vec3_1 v) ++ octets32BE (s32vec3_2 v)
| ValueIntegerS32Vec4 v => octets32BE (s32vec4_0 v) ++ octets32BE (s32vec4_1 v) ++ octets32BE (s32vec4_2 v) ++ octets32BE (s32vec4_3 v)
| ValueIntegerU32 v => octets32BE (u32 v)
| ValueIntegerU32Vec2 v => octets32BE (u32vec2_0 v) ++ octets32BE (u32vec2_1 v)
| ValueIntegerU32Vec3 v => octets32BE (u32vec3_0 v) ++ octets32BE (u32vec3_1 v) ++ octets32BE (u32vec3_2 v)
| ValueIntegerU32Vec4 v => octets32BE (u32vec4_0 v) ++ octets32BE (u32vec4_1 v) ++ octets32BE (u32vec4_2 v) ++ octets32BE (u32vec4_3 v)
| ValueIntegerS64 v => octets64BE (s64 v)
| ValueIntegerS64Vec2 v => octets64BE (s64vec2_0 v) ++ octets64BE (s64vec2_1 v)
| ValueIntegerS64Vec3 v => octets64BE (s64vec3_0 v) ++ octets64BE (s64vec3_1 v) ++ octets64BE (s64vec3_2 v)
| ValueIntegerS64Vec4 v => octets64BE (s64vec4_0 v) ++ octets64BE (s64vec4_1 v) ++ octets64BE (s64vec4_2 v) ++ octets64BE (s64vec4_3 v)
| ValueIntegerU64 v => octets64BE (u64 v)
| ValueIntegerU64Vec2 v => octets64BE (u64vec2_0 v) ++ octets64BE (u64vec2_1 v)
| ValueIntegerU64Vec3 v => octets64BE (u64vec3_0 v) ++ octets64BE (u64vec3_1 v) ++ octets64BE (u64vec3_2 v)
| ValueIntegerU64Vec4 v => octets64BE (u64vec4_0 v) ++ octets64BE (u64vec4_1 v) ++ octets64BE (u64vec4_2 v) ++ octets64BE (u64vec4_3 v)
| ValueFloat16 v => octets16BE (float16BitsOf (f16 v))
| ValueFloat16Vec2 v => octets16BE (float16BitsOf (f16vec2_0 v)) ++ octets16BE (float16BitsOf (f16vec2_1 v))
| ValueFloat16Vec3 v => octets16BE (float16BitsOf (f16vec3_0 v)) ++ octets16BE (float16BitsOf (f16vec3_1 v)) ++ octets16BE (float16BitsOf (f16vec3_2 v))
| ValueFloat16Vec4 v => octets16BE (float16BitsOf (f16vec4_0 v)) ++ octets16BE (float16BitsOf (f16vec4_1 v)) ++ octets16BE (float16BitsOf (f16vec4_2 v)) ++ octets16BE (float16BitsOf (f16vec4_3 v))
| ValueFloat32 v => octets32BE (float32BitsOf (f32 v))
| ValueFloat32Vec2 v => octets32BE (float32BitsOf (f32vec2_0 v)) ++ octets32BE (float32BitsOf (f32vec2_1 v))
| ValueFloat32Vec3 v => octets32BE (float32BitsOf (f32vec3_0 v)) ++ octets32BE (float32BitsOf (f32vec3_1 v)) ++ octets32BE (float32BitsOf (f32vec3_2 v))
| ValueFloat32Vec4 v => octets32BE (float32BitsOf (f32vec4_0 v)) ++ octets32BE (float32BitsOf (f32vec4_1 v)) ++ octets32BE (float32BitsOf (f32vec4_2 v)) ++ octets32BE (float32BitsOf (f32vec4_3 v))
| ValueFloat64 v => octets64BE (float64BitsOf (f64 v))
| ValueFloat64Vec2 v => octets64BE (float64BitsOf (f64vec2_0 v)) ++ octets64BE (float64BitsOf (f64vec2_1 v))
| ValueFloat64Vec3 v => octets64BE (float64BitsOf (f64vec3_0 v)) ++ octets64BE (float64BitsOf (f64vec3_1 v)) ++ octets64BE (float64BitsOf (f64vec3_2 v))
| ValueFloat64Vec4 v => octets64BE (float64BitsOf (f64vec4_0 v)) ++ octets64BE (float64BitsOf (f64vec4_1 v)) ++ octets64BE (float64BitsOf (f64vec4_2 v)) ++ octets64BE (float64BitsOf (f64vec4_3 v))
end.
Lemma s8Size1 : forall v, length (serializeValue (ValueIntegerS8 v)) = 1%nat.
Proof. reflexivity. Qed.
Lemma s8Size2 : forall v, length (serializeValue (ValueIntegerS8Vec2 v)) = 2%nat.
Proof. reflexivity. Qed.
Lemma s8Size3 : forall v, length (serializeValue (ValueIntegerS8Vec3 v)) = 3%nat.
Proof. reflexivity. Qed.
Lemma s8Size4 : forall v, length (serializeValue (ValueIntegerS8Vec4 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma u8Size1 : forall v, length (serializeValue (ValueIntegerU8 v)) = 1%nat.
Proof. reflexivity. Qed.
Lemma u8Size2 : forall v, length (serializeValue (ValueIntegerU8Vec2 v)) = 2%nat.
Proof. reflexivity. Qed.
Lemma u8Size3 : forall v, length (serializeValue (ValueIntegerU8Vec3 v)) = 3%nat.
Proof. reflexivity. Qed.
Lemma u8Size4 : forall v, length (serializeValue (ValueIntegerU8Vec4 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma s16Size1 : forall v, length (serializeValue (ValueIntegerS16 v)) = 2%nat.
Proof. reflexivity. Qed.
Lemma s16Size2 : forall v, length (serializeValue (ValueIntegerS16Vec2 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma s16Size3 : forall v, length (serializeValue (ValueIntegerS16Vec3 v)) = 6%nat.
Proof. reflexivity. Qed.
Lemma s16Size4 : forall v, length (serializeValue (ValueIntegerS16Vec4 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma u16Size1 : forall v, length (serializeValue (ValueIntegerU16 v)) = 2%nat.
Proof. reflexivity. Qed.
Lemma u16Size2 : forall v, length (serializeValue (ValueIntegerU16Vec2 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma u16Size3 : forall v, length (serializeValue (ValueIntegerU16Vec3 v)) = 6%nat.
Proof. reflexivity. Qed.
Lemma u16Size4 : forall v, length (serializeValue (ValueIntegerU16Vec4 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma s32Size1 : forall v, length (serializeValue (ValueIntegerS32 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma s32Size2 : forall v, length (serializeValue (ValueIntegerS32Vec2 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma s32Size3 : forall v, length (serializeValue (ValueIntegerS32Vec3 v)) = 12%nat.
Proof. reflexivity. Qed.
Lemma s32Size4 : forall v, length (serializeValue (ValueIntegerS32Vec4 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma u32Size1 : forall v, length (serializeValue (ValueIntegerU32 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma u32Size2 : forall v, length (serializeValue (ValueIntegerU32Vec2 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma u32Size3 : forall v, length (serializeValue (ValueIntegerU32Vec3 v)) = 12%nat.
Proof. reflexivity. Qed.
Lemma u32Size4 : forall v, length (serializeValue (ValueIntegerU32Vec4 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma s64Size1 : forall v, length (serializeValue (ValueIntegerS64 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma s64Size2 : forall v, length (serializeValue (ValueIntegerS64Vec2 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma s64Size3 : forall v, length (serializeValue (ValueIntegerS64Vec3 v)) = 24%nat.
Proof. reflexivity. Qed.
Lemma s64Size4 : forall v, length (serializeValue (ValueIntegerS64Vec4 v)) = 32%nat.
Proof. reflexivity. Qed.
Lemma u64Size1 : forall v, length (serializeValue (ValueIntegerU64 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma u64Size2 : forall v, length (serializeValue (ValueIntegerU64Vec2 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma u64Size3 : forall v, length (serializeValue (ValueIntegerU64Vec3 v)) = 24%nat.
Proof. reflexivity. Qed.
Lemma u64Size4 : forall v, length (serializeValue (ValueIntegerU64Vec4 v)) = 32%nat.
Proof. reflexivity. Qed.
Lemma f16Size1 : forall v, length (serializeValue (ValueFloat16 v)) = 2%nat.
Proof. reflexivity. Qed.
Lemma f16Size2 : forall v, length (serializeValue (ValueFloat16Vec2 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma f16Size3 : forall v, length (serializeValue (ValueFloat16Vec3 v)) = 6%nat.
Proof. reflexivity. Qed.
Lemma f16Size4 : forall v, length (serializeValue (ValueFloat16Vec4 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma f32Size1 : forall v, length (serializeValue (ValueFloat32 v)) = 4%nat.
Proof. reflexivity. Qed.
Lemma f32Size2 : forall v, length (serializeValue (ValueFloat32Vec2 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma f32Size3 : forall v, length (serializeValue (ValueFloat32Vec3 v)) = 12%nat.
Proof. reflexivity. Qed.
Lemma f32Size4 : forall v, length (serializeValue (ValueFloat32Vec4 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma f64Size1 : forall v, length (serializeValue (ValueFloat64 v)) = 8%nat.
Proof. reflexivity. Qed.
Lemma f64Size2 : forall v, length (serializeValue (ValueFloat64Vec2 v)) = 16%nat.
Proof. reflexivity. Qed.
Lemma f64Size3 : forall v, length (serializeValue (ValueFloat64Vec3 v)) = 24%nat.
Proof. reflexivity. Qed.
Lemma f64Size4 : forall v, length (serializeValue (ValueFloat64Vec4 v)) = 32%nat.
Proof. reflexivity. Qed.
(** The serialization function. Converts a list of component values into a list of octets. *)
Fixpoint serializeComponentValues (vs : list componentValueT) : list octet :=
match vs with
| [] => []
| (x :: xs) => serializeValue x ++ serializeComponentValues xs
end.
Definition serializeStructureValue (s : structureValueT) : list octet :=
serializeComponentValues (structureComponentValues s).
(** The serialization function. Converts a list of structure values into a list of octets. *)
Fixpoint serializeStructureValues (vs : list structureValueT) : list octet :=
match vs with
| [] => []
| (s :: ss) => serializeStructureValue s ++ serializeStructureValues ss
end.
(** The serialization function for an index. *)
Definition serializeIndexValue (t : indexTypeT) (v : Z) : list octet :=
match t with
| INDEX_8 => octets8 v
| INDEX_16 => octets16BE v
| INDEX_32 => octets32BE v
end.
(** The serialization function for an index array. *)
Fixpoint serializeIndexAux (i : list Z) (t : indexTypeT) : list octet :=
match i with
| [] => []
| x :: xs => (serializeIndexValue t x) ++ serializeIndexAux xs t
end.
(** The serialization function for an index array. *)
Definition serializeIndex (i : indexArrayT) : list octet :=
serializeIndexAux (indexElements i) (indexElementType i).
Open Scope nat_scope.
(** @annospec 0962747d-eb5f-4906-9305-092a335bc09e *)
Theorem serializedValueSizeCorrect : forall v t,
valueHasType v t -> length (serializeValue v) = componentTypeSizeOctets t.
Proof.
intros v t Hvt.
destruct Hvt; reflexivity.
Qed.
Lemma lengthSerializeComponentsFold : forall vs,
length (serializeComponentValues vs) = fold_right (fun v acc => length (serializeValue v) + acc) 0 vs.
Proof.
induction vs.
- reflexivity.
- simpl.
rewrite length_app.
rewrite IHvs.
reflexivity.
Qed.
Lemma componentValuesHaveTypesConsCombine0 : forall xs ys x y,
componentValuesHaveTypes ((x,y) :: (combine xs ys))
-> componentValuesHaveTypes (combine xs ys).
Proof.
induction xs as [|n ns].
- intros.
constructor.
- intros ys.
destruct ys as [|m ms].
-- constructor.
-- intros x y Hvt.
simpl.
inversion Hvt; auto.
Qed.
Lemma componentValuesHaveTypesConsCombine1 : forall xs x ys y,
componentValuesHaveTypes (combine (x :: xs) (y :: ys))
-> componentValuesHaveTypes (combine xs ys).
Proof.
induction xs as [|n ns].
- intros x ys y Hcvt.
constructor.
- intros x ys y Hcvt.
destruct ys as [|m ms].
-- constructor.
-- simpl.
inversion Hcvt; auto.
Qed.
Lemma mapSerializeSizeFromCombine : forall (vs : list componentValueT) (cs : list componentT),
length vs = length cs ->
componentValuesHaveTypes (combine vs cs) ->
map (fun v => length (serializeValue v)) vs = map componentTypeSizeOctets (map componentType cs).
Proof.
intros vs.
induction vs as [|y ys].
- intros cs Hlen Hvt.
assert (cs = nil) as Hcnil. {
rewrite length_nil in Hlen.
symmetry in Hlen.
rewrite length_zero_iff_nil in Hlen.
auto.
}
subst cs.
reflexivity.
- intros cs Hlen Hvt.
destruct cs as [|d ds].
-- contradict Hlen.
discriminate.
-- assert (length ys = length ds) as HlenT by (intuition).
assert (componentValuesHaveTypes (combine ys ds)) as HvtC. {
apply (componentValuesHaveTypesConsCombine1 _ _ _ _ Hvt).
}
pose proof (IHys _ HlenT HvtC) as Hcc.
inversion Hvt.
simpl.
rewrite Hcc.
simpl in *.
rewrite (serializedValueSizeCorrect _ _ H1).
reflexivity.
Qed.
Lemma foldMapAdd : forall (A : Type) (vs : list A) (f : A -> nat),
fold_right (fun v acc => f v + acc) 0 vs = fold_right (fun x y => x + y) 0 (map f vs).
Proof.
induction vs as [|x xs].
- reflexivity.
- simpl.
intros f.
rewrite IHxs.
reflexivity.
Qed.
(** @annospec b7852d62-80ad-462d-9473-0d57cac4cc02 *)
Theorem serializedStructureValueSizeCorrect : forall sv st,
structureValueHasStructureType sv st ->
length (serializeStructureValue sv) = structureSizeOctets st.
Proof.
intros sv st Hsvt.
unfold serializeStructureValue.
unfold structureValueHasStructureType in Hsvt.
unfold structureSizeOctets.
destruct Hsvt as [Hlen Htypes].
set (vs := structureComponentValues sv).
set (cs := structureComponents st).
rewrite lengthSerializeComponentsFold.
rewrite foldMapAdd.
rewrite (mapSerializeSizeFromCombine vs cs Hlen Htypes).
reflexivity.
Qed.
Section Examples.
Example standardVertex0Position := ValueIntegerS32Vec3 (IntegerS32Vec3 0 3 0).
Lemma standardVertex0PositionWF : componentValueWF standardVertex0Position.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Example standardVertex0Normal := ValueIntegerS32Vec3 (IntegerS32Vec3 0 1 0).
Lemma standardVertex0NormalWF : componentValueWF standardVertex0Normal.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Example standardVertex1Position := ValueIntegerS32Vec3 (IntegerS32Vec3 3 3 0).
Lemma standardVertex1PositionWF : componentValueWF standardVertex1Position.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Example standardVertex1Normal := ValueIntegerS32Vec3 (IntegerS32Vec3 0 1 0).
Lemma standardVertex1NormalWF : componentValueWF standardVertex1Normal.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Example standardVertex2Position := ValueIntegerS32Vec3 (IntegerS32Vec3 3 0 0).
Lemma standardVertex2PositionWF : componentValueWF standardVertex2Position.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Example standardVertex2Normal := ValueIntegerS32Vec3 (IntegerS32Vec3 0 1 0).
Lemma standardVertex2NormalWF : componentValueWF standardVertex2Normal.
Proof.
constructor.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
unfold isS32. unfold s32Min. unfold s32Max. simpl. lia.
Qed.
Lemma standardVertex0PositionTyped : valueHasType standardVertex0Position INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex0PositionWF. Qed.
Lemma standardVertex1PositionTyped : valueHasType standardVertex1Position INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex1PositionWF. Qed.
Lemma standardVertex2PositionTyped : valueHasType standardVertex2Position INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex2PositionWF. Qed.
Lemma standardVertex0NormalTyped : valueHasType standardVertex0Normal INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex0NormalWF. Qed.
Lemma standardVertex1NormalTyped : valueHasType standardVertex1Normal INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex1NormalWF. Qed.
Lemma standardVertex2NormalTyped : valueHasType standardVertex2Normal INTEGER_SIGNED_32_VEC3.
Proof. constructor. exact standardVertex2NormalWF. Qed.
Example standardVertexArray := [
standardVertex0Position;
standardVertex0Normal;
standardVertex1Position;
standardVertex1Normal;
standardVertex2Position;
standardVertex2Normal
].
Lemma standardVertexSerialSize : length (serializeComponentValues standardVertexArray) = 72%nat.
Proof. reflexivity. Qed.
End Examples.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
Require Import com.io7m.zeniro.Component.
Require Import com.io7m.zeniro.ComponentValues.
Require Import com.io7m.zeniro.ComponentValueTyping.
From Stdlib Require Import ZArith.
From Stdlib Require Import Reals.
From Stdlib Require Import Lia.
From Stdlib Require Import Lists.List.
Import ListNotations.
(** @annospec 8848d6e7-53d5-4607-898e-79bfb75be336 *)
Inductive structureValueT : Set := StructureValue {
structureComponentValues : list componentValueT;
}.
(** @annospec 768fbc59-458f-475c-9c24-ef5816993ee9 *)
Inductive componentValuesHaveTypes : list (componentValueT * componentT) -> Prop :=
| CVHST_Null : componentValuesHaveTypes []
| CVHST_Cons : forall p ps,
valueHasType (fst p) (componentType (snd p))
-> componentValuesHaveTypes ps
-> componentValuesHaveTypes (p :: ps).
Theorem componentValuesHaveTypesDecidable : forall ps,
{componentValuesHaveTypes ps}+{~componentValuesHaveTypes ps}.
Proof.
intros ps.
induction ps as [|p ps].
- left; constructor.
- destruct p as [v c].
destruct IHps as [IHL|IHR].
-- destruct (valueHasTypeDecidable v (componentType c)) as [HL|HR].
--- left; constructor; auto.
--- right.
unfold not.
intro Hfalse.
inversion Hfalse.
simpl in *.
contradiction.
-- right.
unfold not.
intro Hfalse.
inversion Hfalse.
simpl in *.
contradiction.
Qed.
(** @annospec ef43b73c-e3db-4fa1-abd5-e4aee2bdd91d *)
Definition structureValueHasStructureType
(structVal : structureValueT)
(structType : structureT)
: Prop :=
let fValues := structureComponentValues structVal in
let fTypes := structureComponents structType in
length fValues = length fTypes /\ componentValuesHaveTypes (combine fValues fTypes).
Lemma length_eq_dec : forall {A B : Type} (xs : list A) (ys : list B),
{length xs = length ys}+{~(length xs = length ys)}.
Proof.
intros A B xs.
induction xs.
- destruct ys.
-- left; reflexivity.
-- right; discriminate.
- destruct ys.
-- right; discriminate.
-- pose proof (IHxs ys) as H.
destruct H as [HL|HR].
--- simpl.
rewrite HL.
left; reflexivity.
--- simpl.
right; lia.
Qed.
Theorem structureValueHasStructureTypeDecidable : forall sv st,
{structureValueHasStructureType sv st}+{~structureValueHasStructureType sv st}.
Proof.
intros sv st.
unfold structureValueHasStructureType.
remember (structureComponentValues sv) as svv.
remember (structureComponents st) as stt.
destruct (length_eq_dec svv stt) as [HlenL|HlenR].
- destruct (componentValuesHaveTypesDecidable (combine svv stt)) as [HsL|HsR].
-- left; auto.
-- right; unfold not; intro Hfalse; destruct Hfalse; contradiction.
- right; unfold not; intro Hfalse; destruct Hfalse; contradiction.
Qed.
(*
* Copyright © 2025 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
Require Import Stdlib.Arith.PeanoNat.
(** * Alignment *)
(** Return _size_ scaled such that it is a multiple of _q_. *)
Definition asMultipleOf (size q : nat) (Hnz : 0 <> q) : nat :=
let r := size / q in
match Nat.ltb_spec0 r q with
| ReflectT _ _ => (r + 1) * q
| ReflectF _ _ => r * q
end.
#[local]
Lemma p0not4 : 0 <> 4.
Proof. discriminate. Qed.
#[local]
Lemma p0not16 : 0 <> 16.
Proof. discriminate. Qed.
(** Return _size_ scaled such that it is a multiple of 4. *)
Definition asMultipleOf4 (size : nat) : nat :=
asMultipleOf size 4 p0not4.
(** Return _size_ scaled such that it is a multiple of 6. *)
Definition asMultipleOf16 (size : nat) : nat :=
asMultipleOf size 16 p0not16.
(** If _n_ is a multiple of _m_, then _n mod m = 0_. *)
Lemma asMultipleOfMod : forall s q (Hneq : 0 <> q), (asMultipleOf s q Hneq) mod q = 0.
Proof.
intros s q Hneq.
unfold asMultipleOf.
destruct (Nat.ltb_spec0 (s / q) q) as [Hlt|H1].
- apply (Nat.Div0.mod_mul (s / q + 1) q).
- apply (Nat.Div0.mod_mul (s / q) q).
Qed.
(*
* Copyright © 2025 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Reals.
From Stdlib Require Import Strings.String.
From Stdlib Require Import Strings.Byte.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Program.Basics.
From Stdlib Require Import Init.Nat.
From Stdlib Require Import Psatz.
Import ListNotations.
Local Open Scope string_scope.
Require Import com.io7m.entomos.Alignment.
Require Import com.io7m.entomos.Divisible.
(** The type of stream elements. *)
Inductive streamE : Set :=
(** A 64-bit IEEE754 binary64 value. *)
| Vf64 : R -> streamE
(** A 64-bit unsigned integer. *)
| Vu64 : nat -> streamE
(** A 32-bit unsigned integer. *)
| Vu32 : nat -> streamE
(** An 8-bit unsigned integer. *)
| Vu8 : nat -> streamE.
Definition u8byte (b : byte) : streamE :=
Vu8 (Byte.to_nat b).
Definition streamEIsU8 (e : streamE) : Prop :=
match e with
| Vf64 _ => False
| Vu64 _ => False
| Vu32 _ => False
| Vu8 _ => True
end.
(** A proposition that describes a well-formed stream. *)
Inductive streamWellFormed : list streamE -> Prop :=
(** An empty stream is well-formed. *)
| BEPEmpty : streamWellFormed []
(** A stream consisting of a single 64-bit float is well-formed. *)
| BEPVf64 : forall k, streamWellFormed [Vf64 k]
(** A stream consisting of a single 64-bit integer is well-formed. *)
| BEPVu64 : forall k, streamWellFormed [Vu64 k]
(** A stream consisting of a single 32-bit integer is well-formed. *)
| BEPVu32 : forall k, streamWellFormed [Vu32 k]
(** A stream consisting of a number of 8-bit values of a length divisible by 4 is well-formed. *)
| BEPVu8s : forall es, Forall streamEIsU8 es -> length (es) mod 4 = 0 -> streamWellFormed es
(** The concatenation of two well-formed streams is well-formed. *)
| BEPAppend : forall xs ys, streamWellFormed xs -> streamWellFormed ys -> streamWellFormed (xs ++ ys).
(** The size in octets of a stream element. *)
Definition streamElementSize (s : streamE) : nat :=
match s with
| Vf64 _ => 8
| Vu64 _ => 8
| Vu32 _ => 4
| Vu8 _ => 1
end.
(** The size of a stream is the sum of the size of its elements. *)
Definition streamSize (s : list streamE) : nat :=
fold_right plus 0 (map streamElementSize s).
Section binaryExpressions.
Local Unset Elimination Schemes.
(** The binary expression type. *)
Inductive binaryExp : Set :=
(** A 32-bit unsigned integer. *)
| BiU32 : nat -> binaryExp
(** A 64-bit unsigned integer. *)
| BiU64 : nat -> binaryExp
(** A 64-bit IEEE754 binary64 value. *)
| BiF64 : R -> binaryExp
(** A sequence of bytes. *)
| BiBytes : list byte -> binaryExp
(** A sequence of bytes describing UTF-8 encoded text. *)
| BiUTF8 : list byte -> binaryExp
(** An array of binary expressions. *)
| BiArray : list binaryExp -> binaryExp
(** A section of reserved space. *)
| BiReserve : nat -> binaryExp
(** A record with named binary expression members. *)
| BiRecord : list (string * binaryExp) -> binaryExp.
Section binaryExp_rect.
Variable P : binaryExp -> Type.
Variable P_list : list binaryExp -> Type.
Hypothesis P_nil : P_list [].
Hypothesis P_cons : forall x xs, P x -> P_list xs -> P_list (x :: xs).
Hypothesis P_BiU32 : forall x, P (BiU32 x).
Hypothesis P_BiU64 : forall x, P (BiU64 x).
Hypothesis P_BiF64 : forall x, P (BiF64 x).
Hypothesis P_BiBytes : forall bs, P (BiBytes bs).
Hypothesis P_BiUTF8 : forall bs, P (BiUTF8 bs).
Hypothesis P_BiArray : forall bs, P_list bs -> P (BiArray bs).
Hypothesis P_BiReserve : forall x, P (BiReserve x).
Hypothesis P_BiRecord : forall fs, P_list (map snd fs) -> P (BiRecord fs).
Fixpoint binaryExp_rect (b : binaryExp) : P b :=
let
fix expForAll (xs : list binaryExp) : P_list xs :=
match xs as rxs return (P_list rxs) with
| [] => @P_nil
| (y :: ys) => @P_cons y ys (binaryExp_rect y) (expForAll ys)
end
in let
fix forAllSnd (fs : list (string * binaryExp)) : P_list (map snd fs) :=
match fs as rf return P_list (map snd rf) with
| [] => @P_nil
| ((_, y) :: ys) => @P_cons y (map snd ys) (binaryExp_rect y) (forAllSnd ys)
end
in
match b with
| BiU32 c => P_BiU32 c
| BiU64 c => P_BiU64 c
| BiF64 c => P_BiF64 c
| BiBytes bs => P_BiBytes bs
| BiUTF8 bs => P_BiUTF8 bs
| BiArray es => P_BiArray es (expForAll es)
| BiReserve c => P_BiReserve c
| BiRecord fs => P_BiRecord fs (forAllSnd fs)
end.
End binaryExp_rect.
Section binaryExp_ind.
Variable P : binaryExp -> Prop.
Hypothesis P_BiU32 : forall x, P (BiU32 x).
Hypothesis P_BiU64 : forall x, P (BiU64 x).
Hypothesis P_BiF64 : forall x, P (BiF64 x).
Hypothesis P_BiBytes : forall bs, P (BiBytes bs).
Hypothesis P_BiUTF8 : forall bs, P (BiUTF8 bs).
Hypothesis P_BiArray : forall bs, Forall P bs -> P (BiArray bs).
Hypothesis P_BiReserve : forall x, P (BiReserve x).
Hypothesis P_BiRecord : forall fs, Forall P (map snd fs) -> P (BiRecord fs).
Definition binaryExp_ind (b : binaryExp) : P b :=
binaryExp_rect
P
(Forall P)
(Forall_nil P)
(Forall_cons (P:=P))
P_BiU32
P_BiU64
P_BiF64
P_BiBytes
P_BiUTF8
P_BiArray
P_BiReserve
P_BiRecord
b.
End binaryExp_ind.
End binaryExpressions.
(** The size of a binary expression in octets. *)
Fixpoint binarySize (b : binaryExp) : nat :=
match b with
| BiU32 _ => 4
| BiU64 _ => 8
| BiF64 _ => 8
| BiBytes s => 4 + asMultipleOf4 (length s)
| BiUTF8 s => 4 + asMultipleOf4 (length s)
| BiArray f => 4 + fold_right plus 0 (map binarySize f)
| BiReserve s => asMultipleOf4 s
| BiRecord f => fold_right plus 0 (map (compose binarySize snd) f)
end.
Definition binaryEvalPaddedBytes
(b : list byte)
(align : nat)
(Hneq : 0 <> align)
: list streamE :=
let vremaining := length b mod align in
match vremaining with
| 0 => map u8byte b
| _ => map u8byte (b ++ repeat x00 (align - vremaining))
end.
(** The binary evaluation function; produces a stream from an expression. *)
Fixpoint binaryEval (b : binaryExp) : list streamE :=
match b with
| BiU32 k => [Vu32 k]
| BiU64 k => [Vu64 k]
| BiF64 k => [Vf64 k]
| BiBytes s => (Vu32 (length s)) :: (binaryEvalPaddedBytes s 4 Alignment.p0not4)
| BiUTF8 s => (Vu32 (length s)) :: (binaryEvalPaddedBytes s 4 Alignment.p0not4)
| BiArray f => (Vu32 (length f)) :: concat (map binaryEval f)
| BiReserve s => repeat (Vu8 0) (asMultipleOf4 s)
| BiRecord f => concat (map (compose binaryEval snd) f)
end.
(** The size of a binary expression padded to 16 octet alignment. *)
Definition binarySizePadded16 (b : binaryExp) : nat :=
asMultipleOf16 (binarySize b).
(** Shorthand for UTF-8 strings. *)
Definition utf8 (s : string) : binaryExp :=
BiUTF8 (list_byte_of_string s).
(** Shorthand for integer types. *)
Definition u32 := BiU32.
(** Shorthand for integer types. *)
Definition u64 := BiU64.
(** Shorthand for real types. *)
Definition f64 := BiF64.
#[local]
Lemma fold_right_add_cons : forall x xs,
x + fold_right plus 0 xs = fold_right plus 0 (x :: xs).
Proof. reflexivity. Qed.
#[local]
Lemma forall_map_binarySize : forall es,
Forall (fun b : binaryExp => binarySize b mod 4 = 0) es
<-> Forall (fun n => n mod 4 = 0) (map binarySize es).
Proof.
intros es.
induction es.
constructor.
- rewrite Forall_map.
intros H. trivial.
- rewrite Forall_map.
intros H. trivial.
- rewrite Forall_map.
constructor.
intros H; trivial.
intros H; trivial.
Qed.
(** The size of a binary expression is always divisible by 4. *)
Theorem binarySizeMultiple4 : forall b, binarySize (b) mod 4 = 0.
Proof.
intros b.
induction b as [Hbu32|Hbu64|Hbf64|Hbbyte|Hbutf|xs HFA|Hbuns|xs HFF] using binaryExp_ind.
(* U32 values are of size 4 *)
- reflexivity.
(* U64 values are of size 8 *)
- reflexivity.
(* F64 values are of size 8 *)
- reflexivity.
(* Byte array values are rounded up to a multiple of 4 and prefixed with 4 *)
- unfold binarySize.
unfold asMultipleOf4.
remember (asMultipleOf (Datatypes.length Hbbyte) 4 Alignment.p0not4) as size eqn:Heqsize.
rewrite Nat.add_comm.
rewrite <- (Nat.Div0.add_mod_idemp_l size 4 4).
assert (size mod 4 = 0) as Hm0. {
rewrite Heqsize.
apply (asMultipleOfMod (Datatypes.length Hbbyte) 4 (Alignment.p0not4)).
}
rewrite Hm0.
reflexivity.
(* UTF-8 values are rounded up to a multiple of 4 and prefixed with 4 *)
- unfold binarySize.
unfold asMultipleOf4.
remember (asMultipleOf (Datatypes.length Hbutf) 4 Alignment.p0not4) as size eqn:Heqsize.
rewrite Nat.add_comm.
rewrite <- (Nat.Div0.add_mod_idemp_l size 4 4).
assert (size mod 4 = 0) as Hm0. {
rewrite Heqsize.
apply (asMultipleOfMod (Datatypes.length Hbutf) 4 (Alignment.p0not4)).
}
rewrite Hm0.
reflexivity.
(* Each element of an array is a multiple of 4, so the entire array is too. *)
- unfold binarySize.
fold binarySize.
induction xs as [|y ys HforAllInd].
-- reflexivity.
-- assert (fold_right Init.Nat.add 0 (map binarySize (y :: ys)) mod 4 = 0) as HfoldEq. {
apply (@divisibilityNFoldPlus 4 (map binarySize (y :: ys))).
discriminate.
rewrite <- forall_map_binarySize.
exact HFA.
}
rewrite map_cons.
rewrite map_cons in HfoldEq.
assert (4 mod 4 = 0) as H4mod40 by (reflexivity).
assert (0 <> 4) as H0n4 by (discriminate).
apply (divisiblityNAdd 4 (fold_right add 0 (binarySize y :: map binarySize ys)) 4 H0n4 H4mod40 HfoldEq).
(* Unspecified values are rounded up. *)
- unfold binarySize.
unfold asMultipleOf4.
rewrite asMultipleOfMod.
reflexivity.
(* Each element of an record is a multiple of 4, so the entire record is too. *)
- unfold binarySize.
fold binarySize.
induction xs as [|y ys HforAllInd].
-- reflexivity.
-- rewrite map_cons.
rewrite map_cons in HFF.
rewrite <- fold_right_add_cons.
apply divisiblityNAdd.
discriminate.
apply (Forall_inv HFF).
apply HforAllInd.
apply (Forall_inv_tail HFF).
Qed.
#[local]
Lemma sub_0_lt_ymx : forall x y,
0 <= x -> x < y -> 0 < y - x.
Proof.
intros x y Hle Hlt.
destruct x as [|a].
- rewrite Nat.sub_0_r.
exact Hlt.
- rewrite <- Nat.lt_add_lt_sub_l.
rewrite Nat.add_0_r.
exact Hlt.
Qed.
#[local]
Lemma mod_sub : forall x m,
0 < m -> 0 < m - (x mod m) <= m.
Proof.
intros x m Hlt.
constructor.
- assert (0 <= x mod m < m) as HmRange. {
apply Nat.mod_bound_pos.
apply Nat.le_0_l.
exact Hlt.
}
destruct HmRange as [HA HB].
remember (x mod m) as y.
apply (sub_0_lt_ymx y m HA HB).
- assert (x mod m < m) as HmRange. {
apply Nat.mod_upper_bound.
apply Nat.neq_sym.
apply Nat.lt_neq.
exact Hlt.
}
apply Nat.le_sub_l.
Qed.
#[local]
Lemma mod_opposition : forall x a,
0 <> a -> x mod a + (a - x mod a) = a.
Proof.
intros x a Hnz.
assert (x mod a < a) as Hxma. {
apply (Nat.mod_upper_bound).
apply Nat.neq_sym.
exact Hnz.
}
remember (x mod a) as y eqn:Heqy.
lia.
Qed.
(** The length of an evaluated binary expression padded to _a_ is always divisible by _a_. *)
Theorem binaryEvalPaddedBytesAligned : forall bs a (Hnz : 0 <> a),
length (binaryEvalPaddedBytes bs a Hnz) mod a = 0.
Proof.
intros bs a Hnz.
unfold binaryEvalPaddedBytes.
destruct (Datatypes.length bs mod a) eqn:Hlen.
- rewrite length_map.
exact Hlen.
- rewrite length_map.
rewrite length_app.
rewrite repeat_length.
rewrite <- Hlen.
remember (Datatypes.length bs) as x.
rewrite <- (Nat.Div0.add_mod_idemp_l x (a - x mod a) a).
assert ((x mod a + (a - x mod a)) = a) as Heqa. {
rewrite (mod_opposition x a Hnz).
reflexivity.
}
rewrite Heqa.
apply Nat.Div0.mod_same.
Qed.
#[local]
Lemma repeat_eq : forall (A : Type) (P : A -> Prop) (n : nat) (x : A),
Forall (eq x) (repeat x n).
Proof.
intros A P n x.
induction n as [|m Hm].
- constructor.
- simpl.
constructor.
reflexivity.
exact Hm.
Qed.
#[local]
Lemma Forall_implies : forall (A : Type) (P : A -> Prop) (Q : A -> Prop) (xs : list A) (H : forall x, P x -> Q x),
Forall P xs -> Forall Q xs.
Proof.
intros A P Q xs Ht HforAll.
induction HforAll as [|y ys Hpy HfaP HfaQ].
- constructor.
- constructor.
apply (Ht y Hpy).
exact HfaQ.
Qed.
(** Evaluating a binary expression results in a series of u8 values. *)
Theorem binaryEvalPaddedBytesU8 : forall bs a (Hnz : 0 <> a),
Forall streamEIsU8 (binaryEvalPaddedBytes bs a Hnz).
Proof.
intros bs a Hnz.
unfold binaryEvalPaddedBytes.
destruct (Datatypes.length bs mod a) as [|HB].
- rewrite Forall_map.
induction bs as [|r rs Hrs].
-- constructor.
-- constructor.
reflexivity.
exact Hrs.
- rewrite map_app.
assert (Forall streamEIsU8 (map u8byte bs)) as Hmap. {
rewrite Forall_map.
induction bs as [|r rs Hrs].
- constructor.
- constructor.
reflexivity.
exact Hrs.
}
assert (Forall streamEIsU8 (map u8byte (repeat "000"%byte (a - S HB)))) as HmapR. {
rewrite Forall_map.
assert (Forall (eq "000"%byte) (repeat "000"%byte (a - S HB))) as Hfeq
by (apply (repeat_eq byte (fun _ : byte => True) (a - S HB) "000"%byte)).
simpl.
apply (@Forall_implies byte (eq "000"%byte) (fun _ : byte => True) (repeat "000"%byte (a - S HB))). {
intros. exact I.
}
exact Hfeq.
}
apply Forall_app.
constructor.
exact Hmap.
exact HmapR.
Qed.
#[local]
Lemma app_cons : forall (A : Type) (x : A) (xs : list A),
x :: xs = app (cons x nil) xs.
Proof.
intros A x xs.
reflexivity.
Qed.
(** Streams produced by the _binaryEval_ function are well-formed. *)
Theorem binaryEvalStreamsWellFormed : forall b,
streamWellFormed (binaryEval b).
Proof.
intros b.
induction b as [a0|a1|a2|a3|a4|a5 Hfa|a6|a7 Hfa].
(* U32 *)
- apply BEPVu32.
(* U64 *)
- apply BEPVu64.
(* F64 *)
- apply BEPVf64.
(* Bytes *)
- unfold binaryEval.
rewrite app_cons.
apply BEPAppend.
apply BEPVu32.
assert (length (binaryEvalPaddedBytes a3 4 Alignment.p0not4) mod 4 = 0) as Hlm
by (apply (binaryEvalPaddedBytesAligned)).
apply BEPVu8s.
apply binaryEvalPaddedBytesU8.
exact Hlm.
(* UTF-8 *)
- unfold binaryEval.
rewrite app_cons.
apply BEPAppend.
apply BEPVu32.
assert (length (binaryEvalPaddedBytes a4 4 Alignment.p0not4) mod 4 = 0) as Hlm
by (apply (binaryEvalPaddedBytesAligned)).
assert (Forall streamEIsU8 (binaryEvalPaddedBytes a4 4 Alignment.p0not4)) as Hu8
by (apply (binaryEvalPaddedBytesU8)).
apply (BEPVu8s _ Hu8 Hlm).
(* Array *)
- simpl.
rewrite app_cons.
apply BEPAppend.
apply BEPVu32.
induction a5 as [|q qs IHqs].
-- constructor.
-- assert (streamWellFormed (concat (map binaryEval qs))) as HqsWF
by (apply (IHqs (Forall_inv_tail Hfa))).
assert (streamWellFormed (binaryEval q)) as HqWF
by (apply (Forall_inv Hfa)).
simpl.
apply BEPAppend.
exact HqWF.
exact HqsWF.
(* Reserve *)
- simpl.
unfold asMultipleOf4.
remember (asMultipleOf a6 4 Alignment.p0not4) as size eqn:Heqsize.
assert (size mod 4 = 0) as Heqm. {
rewrite Heqsize.
apply (asMultipleOfMod).
}
assert ((compose Vu8 Byte.to_nat) "000"%byte = (Vu8 0)) as HbyteEq by reflexivity.
apply BEPVu8s.
assert (Forall (eq (Vu8 0)) (repeat (Vu8 0) size)) as Hfeq
by (apply (@repeat_eq streamE streamEIsU8 size (Vu8 0))).
apply (@Forall_implies streamE (eq (Vu8 0)) streamEIsU8 (repeat (Vu8 0) size)). {
intros x Hxeq.
unfold streamEIsU8.
rewrite <- Hxeq.
exact I.
}
exact Hfeq.
rewrite repeat_length.
exact Heqm.
(* Record *)
- simpl.
induction a7 as [|q qs IHqs].
-- constructor.
-- assert (Forall (fun b : binaryExp => streamWellFormed (binaryEval b)) (map snd qs)) as Hfqs. {
apply (@Forall_inv_tail binaryExp (fun b : binaryExp => streamWellFormed (binaryEval b)) (snd q) (map snd qs)). {
assert ((map snd (q :: qs)) = (snd q :: map snd qs)) as Hmc by reflexivity.
rewrite <- Hmc.
exact Hfa.
}
}
assert (streamWellFormed (concat (map (compose binaryEval snd) qs))) as Hconqs by (apply (IHqs Hfqs)).
rewrite map_cons.
rewrite concat_cons.
apply BEPAppend.
rewrite map_cons in Hfa.
apply (Forall_inv Hfa).
exact Hconqs.
Qed.
#[local]
Lemma fold_right_1_length : forall xs,
Forall (eq 1) xs -> fold_right add 0 xs = length xs.
Proof.
intros xs Hfa.
induction xs as [|y ys IHxs].
- reflexivity.
- rewrite <- fold_right_add_cons.
assert (length (y :: ys) = 1 + length (ys)) as HlenYs by reflexivity.
rewrite HlenYs.
assert (1 = y) as Hy1 by (apply (Forall_inv Hfa)).
rewrite <- Hy1.
f_equal.
apply IHxs.
apply (Forall_inv_tail Hfa).
Qed.
#[local]
Theorem fold_right_add_app : forall xs ys,
fold_right add 0 xs + fold_right add 0 ys = fold_right add 0 (xs ++ ys).
Proof.
intros xs ys.
rewrite fold_right_app.
generalize dependent ys.
induction xs as [|q qs IHqs].
- reflexivity.
- intros ys.
simpl.
rewrite <- (IHqs ys).
rewrite Nat.add_assoc.
reflexivity.
Qed.
Theorem streamSizeApp : forall xs ys,
streamSize xs + streamSize ys = streamSize (xs ++ ys).
Proof.
intros xs ys.
unfold streamSize.
rewrite map_app.
rewrite fold_right_add_app.
reflexivity.
Qed.
(** All well-formed streams have a size divisible by 4. *)
Theorem streamsWellFormedDivisible4 : forall es,
streamWellFormed es -> streamSize es mod 4 = 0.
Proof.
intros es Hwf.
induction Hwf as [|H1|H2|H3|es Hfa Hsize|xs ys Hxswf Hxsize Hyswf Hysize].
- reflexivity.
- reflexivity.
- reflexivity.
- reflexivity.
- unfold streamSize.
assert (Forall (fun e => 1 = streamElementSize e) es) as HFaSize. {
apply (@Forall_implies streamE streamEIsU8 (fun e : streamE => 1 = streamElementSize e) es). {
intros x His.
destruct x as [f64|u64|u32|u8].
- contradiction.
- contradiction.
- contradiction.
- reflexivity.
}
exact Hfa.
}
assert (Forall (eq 1) (map streamElementSize es)) as Hall1. {
apply (@Forall_map _ _ _ _ es).
exact HFaSize.
}
assert (fold_right add 0 (map streamElementSize es) = length es) as HlenEq. {
assert (length es = length (map streamElementSize es)) as HmapLen. {
rewrite length_map.
reflexivity.
}
rewrite HmapLen.
apply (fold_right_1_length (map streamElementSize es) Hall1).
}
rewrite HlenEq.
exact Hsize.
- rewrite <- streamSizeApp.
apply divisiblityNAdd.
discriminate.
exact Hxsize.
exact Hysize.
Qed.
(*
* Copyright © 2025 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Arith.PeanoNat.
From Stdlib Require Import Lists.List.
From Stdlib Require Import Init.Nat.
(** If _x_ and _y_ are divisible by _z_, then _x + y_ is also divisible by _z_. *)
Theorem divisiblityNAdd : forall (x y z : nat),
0 <> z -> x mod z = 0 -> y mod z = 0 -> (x + y) mod z = 0.
Proof.
intros x y z Hz Hx Hy.
destruct y as [|y].
(* If y = 0, then this matches one of our assumptions already. *)
rewrite Nat.add_0_r; exact Hx.
(* Otherwise, the following property always holds given that the divisor is ≠ 0. *)
assert ((x mod z + S y) mod z = (x + S y) mod z) as Heq.
apply (Nat.Div0.add_mod_idemp_l x (S y) z).
(* x mod z = 0 *)
rewrite Hx in Heq.
(* 0 + S y = S y *)
rewrite Nat.add_0_l in Heq.
rewrite <- Heq.
exact Hy.
Qed.
(** Divisibility is preserved over addition. *)
Theorem divisibilityNFoldPlus : forall z xs,
0 <> z ->
Forall (fun n => n mod z = 0) xs ->
(fold_right plus 0 xs) mod z = 0.
Proof.
intros z xs Hnz HforAll.
induction xs as [|y ys].
- apply (Nat.Div0.mod_0_l z).
- assert (fold_right add 0 (y :: ys) = y + fold_right add 0 ys) as Hfoldeq by reflexivity.
rewrite Hfoldeq.
assert (fold_right add 0 ys mod z = 0) as Hfoldeq2. {
apply IHys.
apply (@Forall_inv_tail nat (fun n : nat => n mod z = 0) y ys HforAll).
}
rewrite divisiblityNAdd.
reflexivity.
exact Hnz.
apply (@Forall_inv nat (fun n : nat => n mod z = 0) y ys HforAll).
exact Hfoldeq2.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Strings.Byte.
From Stdlib Require Import Lists.List.
Require Import com.io7m.entomos.Tags.
Require Import com.io7m.entomos.FileFormat.
Import ListNotations.
Example fileIdentifier : TagT :=
Tag x89 x4d x54 x50 x0d x0a x1a x0a.
Example sectionEndIdentifier : TagT :=
Tag x4d x54 x50 x5f x45 x4e x44 x21.
Example sectionManifestIdentifier : TagT :=
Tag x4d x54 x50 x5f x4d x41 x4e x49.
Example sectionFileIdentifier : TagT :=
Tag x4d x54 x50 x5f x46 x49 x4c x45.
Example sectionManifest : FileSectionDescriptionT :=
FileSectionDescription sectionManifestIdentifier FSO_MustBeFirst FSC_One.
Example sectionFile : FileSectionDescriptionT :=
FileSectionDescription sectionFileIdentifier FSO_AnyOrder FSC_ZeroToN.
Example fileDescriptionExample : FileDescriptionT :=
FileDescription
fileIdentifier
1
0
[sectionManifest; sectionFile]
sectionEndIdentifier
UnknownSectionsPermitted
.
Lemma fileSectionAtMostOneFirstExample : fileSectionAtMostOneFirst (fileSections fileDescriptionExample).
Proof.
unfold fileSectionAtMostOneFirst.
simpl; auto.
Qed.
Lemma fileSectionAtMostOneLastExample : fileSectionAtMostOneLast (fileSections fileDescriptionExample).
Proof.
unfold fileSectionAtMostOneLast.
simpl; auto.
Qed.
Lemma fileSectionTagsUniqueExample : fileSectionTagsUnique (fileSections fileDescriptionExample).
Proof.
unfold fileSectionTagsUnique.
simpl; auto.
constructor.
- unfold not.
intro H.
inversion H.
contradict H0.
discriminate.
inversion H0.
- constructor.
unfold not.
intro H.
inversion H.
constructor.
Qed.
Lemma fileSectionFileNotSectionExample : fileSectionFileNotSection fileDescriptionExample.
Proof.
unfold fileSectionFileNotSection.
simpl.
unfold not.
intro H.
destruct H.
- contradict H.
discriminate.
- destruct H.
contradict H.
discriminate.
auto.
Qed.
Lemma endSectionFileNotSectionExample : endSectionFileNotSection fileDescriptionExample.
Proof.
unfold endSectionFileNotSection.
simpl.
unfold not.
intro H.
destruct H.
- contradict H.
discriminate.
- destruct H.
contradict H.
discriminate.
auto.
Qed.
Theorem fileDescriptionInvariantsExample : fileDescriptionInvariants fileDescriptionExample.
Proof.
constructor.
apply fileSectionAtMostOneFirstExample.
constructor.
apply fileSectionAtMostOneLastExample.
constructor.
apply fileSectionTagsUniqueExample.
constructor.
apply fileSectionFileNotSectionExample.
apply endSectionFileNotSectionExample.
Qed.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Lists.List.
Require Import com.io7m.entomos.Tags.
Import ListNotations.
(** The ordering constraints on a file section. *)
Inductive FileSectionOrderingT :=
(** The section must be the first in the file. *)
FSO_MustBeFirst
| (** The section must be the last in the file. *)
FSO_MustBeLast
| (** The section can appear anywhere in the file. *)
FSO_AnyOrder
.
(** The cardinality of a file section. *)
Inductive FileSectionCardinalityT :=
(** The section must appear exactly once. *)
FSC_One
| (** The section can appear at most once. *)
FSC_ZeroToOne
| (** The section can appear any number of times, including not at all. *)
FSC_ZeroToN
| (** The section must appear at least once. *)
FSC_OneToN
.
(** The constraints on unknown sections. *)
Inductive FileSectionsUnknownT :=
| (** Unknown sections are permitted. *)
UnknownSectionsPermitted
| (** Unknown sections are not permitted. *)
UnknownSectionsNotPermitted
.
(** A description of a file section. *)
Inductive FileSectionDescriptionT := FileSectionDescription {
(** The file section tag. *)
fileSectionTag : TagT;
(** The file section ordering constraint. *)
fileSectionOrdering : FileSectionOrderingT;
(** The file section cardinality constraint. *)
fileSectionCardinality : FileSectionCardinalityT
}.
(** The description of a file format version. *)
Inductive FileDescriptionT := FileDescription {
(** The file tag. *)
fileTag : TagT;
(** The major file format version. *)
fileVersionMajor : nat;
(** The minor file format version. *)
fileVersionMinor : nat;
(** The file sections. *)
fileSections : list FileSectionDescriptionT;
(** The file end tag. *)
fileEndTag : TagT;
(** The constraints on unknown file sections. *)
fileSectionsUnknown : FileSectionsUnknownT
}.
(** The number of sections with _FSO_MustBeFirst_. *)
Fixpoint fileSectionOrderingCountFirst
(xs : list FileSectionDescriptionT)
(n : nat)
: nat :=
match xs with
| nil => 0
| cons y ys =>
match (fileSectionOrdering y) with
| FSO_MustBeFirst => fileSectionOrderingCountFirst ys (S n)
| _ => fileSectionOrderingCountFirst ys n
end
end.
(** The number of sections with _FSO_MustBeLast_. *)
Fixpoint fileSectionOrderingCountLast
(xs : list FileSectionDescriptionT)
(n : nat)
: nat :=
match xs with
| nil => 0
| cons y ys =>
match (fileSectionOrdering y) with
| FSO_MustBeLast => fileSectionOrderingCountLast ys (S n)
| _ => fileSectionOrderingCountLast ys n
end
end.
(** At most one section can be _FSO_MustBeFirst_. *)
Definition fileSectionAtMostOneFirst (xs : list FileSectionDescriptionT) : Prop :=
fileSectionOrderingCountFirst xs 0 <= 1.
(** At most one section can be _FSO_MustBeLast_. *)
Definition fileSectionAtMostOneLast (xs : list FileSectionDescriptionT) : Prop :=
fileSectionOrderingCountLast xs 0 <= 1.
(** The file sections must have unique tags. *)
Definition fileSectionTagsUnique (xs : list FileSectionDescriptionT) : Prop :=
NoDup (map (fun s => fileSectionTag s) xs).
(** The file sections cannot contain the file tag. *)
Definition fileSectionFileNotSection (f : FileDescriptionT) : Prop :=
~In (fileTag f) (map (fun s => fileSectionTag s) (fileSections f)).
(** The file sections cannot contain the end tag. *)
Definition endSectionFileNotSection (f : FileDescriptionT) : Prop :=
~In (fileEndTag f) (map (fun s => fileSectionTag s) (fileSections f)).
(** The file format description invariants. *)
Definition fileDescriptionInvariants (f : FileDescriptionT) : Prop :=
fileSectionAtMostOneFirst (fileSections f)
/\ fileSectionAtMostOneLast (fileSections f)
/\ fileSectionTagsUnique (fileSections f)
/\ fileSectionFileNotSection f
/\ endSectionFileNotSection f.
(*
* Copyright © 2026 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
From Stdlib Require Import Lia.
From Stdlib Require Import ZArith.
From Stdlib Require Import Init.Nat.
From Stdlib Require Import Strings.Byte.
From Stdlib Require Import ZArith.Zbitwise.
(** A 64-bit section identifier. *)
Inductive TagT : Set := Tag {
tag_byte0 : byte;
tag_byte1 : byte;
tag_byte2 : byte;
tag_byte3 : byte;
tag_byte4 : byte;
tag_byte5 : byte;
tag_byte6 : byte;
tag_byte7 : byte
}.
(** The example PNG file format identifier. *)
Example tagPNG :=
Tag x89 x50 x4e x47 x0d x0a x1a x0a.
Open Scope Z_scope.
Definition byteOfZ (z : Z) : byte :=
match of_N (Z.to_N z) with
| None => x00
| Some b => b
end.
Definition byteToZ (b : byte) : Z :=
Z.of_N (to_N b).
Theorem byteZIdentity0 : forall b,
byteOfZ (byteToZ b) = b.
Proof.
unfold byteToZ.
unfold byteOfZ.
intros b.
rewrite N2Z.id.
rewrite of_to_N.
reflexivity.
Qed.
Theorem byteZIdentity1 : forall z,
0 <= z < 256 -> byteToZ (byteOfZ z) = z.
Proof.
unfold byteToZ.
unfold byteOfZ.
intros z [Hrange0 Hrange1].
remember (of_N (Z.to_N z)) as b.
destruct b.
- symmetry in Heqb.
rewrite (to_of_N _ Heqb).
rewrite Z2N.id.
reflexivity.
auto.
- symmetry in Heqb.
rewrite (of_N_None_iff (Z.to_N z)) in Heqb.
contradict Heqb.
lia.
Qed.
(** Define a file tag from a single 64-bit integer. *)
Definition tagOfZ (z : Z) : TagT :=
let t0 := Z.shiftr (Z.land z 0xff00000000000000) 56 in
let t1 := Z.shiftr (Z.land z 0x00ff000000000000) 48 in
let t2 := Z.shiftr (Z.land z 0x0000ff0000000000) 40 in
let t3 := Z.shiftr (Z.land z 0x000000ff00000000) 32 in
let t4 := Z.shiftr (Z.land z 0x00000000ff000000) 24 in
let t5 := Z.shiftr (Z.land z 0x0000000000ff0000) 16 in
let t6 := Z.shiftr (Z.land z 0x000000000000ff00) 8 in
let t7 := Z.shiftr (Z.land z 0x00000000000000ff) 0 in
let b0 := byteOfZ t0 in
let b1 := byteOfZ t1 in
let b2 := byteOfZ t2 in
let b3 := byteOfZ t3 in
let b4 := byteOfZ t4 in
let b5 := byteOfZ t5 in
let b6 := byteOfZ t6 in
let b7 := byteOfZ t7 in
Tag b0 b1 b2 b3 b4 b5 b6 b7.
(** Convert a file tag to a single 64-bit integer. *)
Definition tagToZ (t : TagT) : Z :=
let z0 := Z.shiftl (byteToZ (tag_byte0 t)) 56 in
let z1 := Z.shiftl (byteToZ (tag_byte1 t)) 48 in
let z2 := Z.shiftl (byteToZ (tag_byte2 t)) 40 in
let z3 := Z.shiftl (byteToZ (tag_byte3 t)) 32 in
let z4 := Z.shiftl (byteToZ (tag_byte4 t)) 24 in
let z5 := Z.shiftl (byteToZ (tag_byte5 t)) 16 in
let z6 := Z.shiftl (byteToZ (tag_byte6 t)) 8 in
let z7 := Z.shiftl (byteToZ (tag_byte7 t)) 0 in
Z.lor z0 (Z.lor z1 (Z.lor z2 (Z.lor z3 (Z.lor z4 (Z.lor z5 (Z.lor z6 z7)))))).
Lemma byteInRange : forall z shift,
0 <= z < 2^64 ->
0 <= shift ->
0 <= Z.shiftr (Z.land z (Z.shiftl 0xff shift)) shift < 256.
Proof.
intros z shift [Hrange0 Hrange1] HshiftRange.
split.
- rewrite Z.shiftr_nonneg.
rewrite (Z.land_nonneg z (Z.shiftl 255 shift)).
lia.
- rewrite Z.shiftr_land.
rewrite Z.shiftr_shiftl_r.
assert (Hs: shift - shift = 0) by (lia).
rewrite Hs.
rewrite Z.shiftr_0_r.
set (m := Z.shiftr z shift).
assert (Hone: 255 = Z.ones 8) by (reflexivity).
rewrite Hone.
rewrite Z.land_ones.
apply (Z.mod_pos_bound m (2 ^ 8)).
lia. lia. lia.
Qed.
Lemma byteShiftZeros : forall shift,
0 <= shift ->
Z.land (Z.shiftl 255 shift) (Z.ones shift) = 0.
Proof.
intros shift Hrange.
rewrite (Z.land_ones (Z.shiftl 255 shift) shift).
rewrite Z.shiftl_mul_pow2.
rewrite Z.mod_mul.
reflexivity.
apply Z.pow_nonzero.
discriminate.
auto.
auto.
auto.
Qed.
Lemma byteShiftId : forall z shift,
0 <= shift ->
(Z.shiftl (Z.shiftr (Z.land z (Z.shiftl 255 shift)) shift) shift) = Z.land z (Z.shiftl 255 shift).
Proof.
intros z shift Hrange.
apply Z.bits_inj'.
intros n Hn.
set (mask := Z.shiftl 255 shift).
set (masked := Z.land z mask).
assert (HmaskLow : forall k, 0 <= k < shift -> Z.testbit mask k = false). {
intros k [Hrange0 Hrange1].
unfold mask.
apply Z.shiftl_spec_low; auto.
}
assert (HmaskedLow : forall k, 0 <= k < shift -> Z.testbit masked k = false). {
intros k [Hrange0 Hrange1].
unfold masked.
rewrite Z.land_spec.
destruct (Z.testbit z k).
- rewrite HmaskLow.
reflexivity.
auto.
- reflexivity.
}
destruct (Z_ge_lt_dec n shift) as [Hge|Hlt].
- set (k := n - shift).
assert (Hk : 0 <= k) by (unfold k; lia).
rewrite Z.shiftl_spec_high.
rewrite Z.shiftr_spec by exact Hk.
replace (n - shift + shift) with n by lia.
reflexivity.
auto.
lia.
- rewrite HmaskedLow.
rewrite Z.shiftl_spec_low.
auto.
auto.
auto.
Qed.
Lemma byteExtract : forall z shift,
0 <= shift ->
Z.shiftr (Z.land z (Z.shiftl 255 shift)) shift = (z / 2 ^ shift) mod 2 ^ 8.
Proof.
intros z shift Hshift.
rewrite Z.shiftr_land.
rewrite (Z.shiftr_shiftl_r 255 shift shift Hshift).
assert (Hss: shift - shift = 0) by (lia).
rewrite Hss.
rewrite Z.shiftr_0_r.
assert (H255: 255 = Z.pred (2 ^ 8)) by (reflexivity).
rewrite H255.
rewrite <- Z.ones_equiv.
rewrite Z.land_ones.
rewrite Z.shiftr_div_pow2.
reflexivity.
auto.
lia.
Qed.
Lemma byteReconstruct : forall z shift,
0 <= shift ->
Z.lor (Z.shiftl (Z.shiftr z shift) shift) (Z.land z (Z.ones shift)) = z.
Proof.
intros z shift Hshift.
rewrite <- Z.ldiff_ones_r.
apply Z.lor_ldiff_and.
auto.
Qed.
Lemma bitRangeMask : forall z n mask,
0 <= z < (2 ^ mask) ->
0 <= n < mask ->
Z.testbit z n = Z.testbit (Z.land z (Z.ones mask)) n.
Proof.
intros z n mask [Hzr0 Hzr1] [Hnr0 Hnr1].
rewrite Z.land_ones_low.
reflexivity.
auto.
destruct (Z.eq_dec z 0) as [Heq|Hneq].
- subst z.
simpl.
lia.
- apply Z.log2_lt_pow2; lia.
Qed.
Lemma bitMaskDisjoint
(mask : Z)
(Hmask : 0 <= mask)
: Z.land (Z.ones mask) (Z.shiftl (Z.ones mask) mask) = 0.
Proof.
apply Z.bits_inj'.
intros n Hnr.
rewrite Z.land_comm.
rewrite Z.land_spec.
destruct (Z_lt_ge_dec n mask) as [Hnlt|Hnge].
- rewrite Z.ones_spec_low.
rewrite Bool.andb_true_r.
rewrite Z.shiftl_spec_low.
rewrite Z.bits_0.
reflexivity.
auto.
auto.
- rewrite Z.ones_spec_high.
rewrite Bool.andb_false_r.
rewrite Z.bits_0.
reflexivity.
lia.
Qed.
Lemma bitMaskCombine
(mask : Z)
(Hmask : 0 <= mask)
: Z.lor (Z.ones mask) (Z.shiftl (Z.ones mask) mask) = Z.ones (mask + mask).
Proof.
apply Z.bits_inj'.
intros n Hnr.
rewrite Z.lor_spec.
destruct (Z_lt_ge_dec n (mask + mask)) as [Hnltmm|Hngemm].
- rewrite (Z.ones_spec_low (mask + mask) n) by lia.
rewrite (Z.shiftl_spec (Z.ones mask) mask n) by lia.
destruct (Z_lt_ge_dec n mask) as [Hnltm|Hngem].
-- rewrite Z.ones_spec_low by lia.
reflexivity.
-- rewrite Z.ones_spec_high by lia.
simpl.
rewrite (Z.testbit_ones mask (n - mask) Hmask).
lia.
- rewrite (Z.ones_spec_high (mask + mask) n).
destruct (Z_lt_ge_dec n mask) as [Hnltm|Hngem].
-- contradict Hnltm; lia.
-- rewrite (Z.ones_spec_high mask n) by lia.
simpl.
rewrite (Z.shiftl_spec_high (Z.ones mask) mask n) by lia.
apply Z.ones_spec_high.
lia.
-- lia.
Qed.
Lemma bitRangeMaskOr
(z mask : Z)
(Hmask : 0 <= mask)
(Hz : 0 <= z)
(Hzb : z < 2 ^ (mask + mask))
: Z.lor (Z.land z (Z.ones mask))
(Z.land z (Z.shiftl (Z.ones mask) mask)) = z.
Proof.
apply Z.bits_inj'.
intros n Hn.
pose proof (bitMaskCombine _ Hmask) as Hmcomb.
rewrite <- Z.land_lor_distr_r.
rewrite Hmcomb.
assert (Z.land z (Z.ones (mask + mask)) = z) as Hzeq. {
rewrite (Z.land_ones z (mask + mask)) by lia.
apply Z.mod_small.
lia.
}
rewrite Hzeq.
reflexivity.
Qed.
(** Tag conversion is an identity for all unsigned 64-bit integers. *)
Theorem tagIdentity : forall z,
0 <= z < 2^64 -> tagToZ (tagOfZ z) = z.
Proof.
intros z [Hrange0 Hrange1].
unfold tagToZ.
unfold tagOfZ.
assert (HS56: 0xff00000000000000 = Z.shiftl 0xff 56) by (reflexivity).
rewrite HS56.
assert (HS48: 0x00ff000000000000 = Z.shiftl 0xff 48) by (reflexivity).
rewrite HS48.
assert (HS40: 0x0000ff0000000000 = Z.shiftl 0xff 40) by (reflexivity).
rewrite HS40.
assert (HS32: 0x000000ff00000000 = Z.shiftl 0xff 32) by (reflexivity).
rewrite HS32.
assert (HS24: 0x00000000ff000000 = Z.shiftl 0xff 24) by (reflexivity).
rewrite HS24.
assert (HS16: 0x0000000000ff0000 = Z.shiftl 0xff 16) by (reflexivity).
rewrite HS16.
assert (HS8: 0x000000000000ff00 = Z.shiftl 0xff 8) by (reflexivity).
rewrite HS8.
assert (HS0: 0x00000000000000ff = Z.shiftl 0xff 0) by (reflexivity).
rewrite HS0.
rewrite Z.shiftl_0_r.
assert (Hzle56: 0 <= 56) by (lia).
assert (Hzle48: 0 <= 48) by (lia).
assert (Hzle40: 0 <= 40) by (lia).
assert (Hzle32: 0 <= 32) by (lia).
assert (Hzle24: 0 <= 24) by (lia).
assert (Hzle16: 0 <= 16) by (lia).
assert (Hzle8: 0 <= 8) by (lia).
pose proof (byteInRange z 56 (conj Hrange0 Hrange1) Hzle56) as Hr56.
pose proof (byteInRange z 48 (conj Hrange0 Hrange1) Hzle48) as Hr48.
pose proof (byteInRange z 40 (conj Hrange0 Hrange1) Hzle40) as Hr40.
pose proof (byteInRange z 32 (conj Hrange0 Hrange1) Hzle32) as Hr32.
pose proof (byteInRange z 24 (conj Hrange0 Hrange1) Hzle24) as Hr24.
pose proof (byteInRange z 16 (conj Hrange0 Hrange1) Hzle16) as Hr16.
pose proof (byteInRange z 8 (conj Hrange0 Hrange1) Hzle8) as Hr8.
set (z0 := Z.shiftr (Z.land z (Z.shiftl 255 56)) 56).
set (z1 := Z.shiftr (Z.land z (Z.shiftl 255 48)) 48).
set (z2 := Z.shiftr (Z.land z (Z.shiftl 255 40)) 40).
set (z3 := Z.shiftr (Z.land z (Z.shiftl 255 32)) 32).
set (z4 := Z.shiftr (Z.land z (Z.shiftl 255 24)) 24).
set (z5 := Z.shiftr (Z.land z (Z.shiftl 255 16)) 16).
set (z6 := Z.shiftr (Z.land z (Z.shiftl 255 8)) 8).
set (z7 := Z.shiftr (Z.land z 255) 0).
set (r := {|
tag_byte0 := byteOfZ z0;
tag_byte1 := byteOfZ z1;
tag_byte2 := byteOfZ z2;
tag_byte3 := byteOfZ z3;
tag_byte4 := byteOfZ z4;
tag_byte5 := byteOfZ z5;
tag_byte6 := byteOfZ z6;
tag_byte7 := byteOfZ z7
|}).
assert (Htb0: tag_byte0 r = byteOfZ z0) by (reflexivity).
rewrite Htb0.
assert (Htb1: tag_byte1 r = byteOfZ z1) by (reflexivity).
rewrite Htb1.
assert (Htb2: tag_byte2 r = byteOfZ z2) by (reflexivity).
rewrite Htb2.
assert (Htb3: tag_byte3 r = byteOfZ z3) by (reflexivity).
rewrite Htb3.
assert (Htb4: tag_byte4 r = byteOfZ z4) by (reflexivity).
rewrite Htb4.
assert (Htb5: tag_byte5 r = byteOfZ z5) by (reflexivity).
rewrite Htb5.
assert (Htb6: tag_byte6 r = byteOfZ z6) by (reflexivity).
rewrite Htb6.
assert (Htb7: tag_byte7 r = byteOfZ z7) by (reflexivity).
rewrite Htb7.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
rewrite byteZIdentity1.
subst z0.
rewrite (byteShiftId z 56).
subst z1.
rewrite (byteShiftId z 48).
subst z2.
rewrite (byteShiftId z 40).
subst z3.
rewrite (byteShiftId z 32).
subst z4.
rewrite (byteShiftId z 24).
subst z5.
rewrite (byteShiftId z 16).
subst z6.
rewrite (byteShiftId z 8).
subst z7.
clear Htb0 Htb1 Htb2 Htb3 Htb4 Htb5 Htb6 Htb7.
clear r.
clear Hr56 Hr48 Hr40 Hr32 Hr24 Hr16 Hr8.
clear HS56 HS48 HS40 HS32 HS24 HS16 HS8 HS0.
assert (H255: 255 = Z.pred (2 ^ 8)) by (reflexivity).
rewrite H255. clear H255.
rewrite <- Z.ones_equiv.
rewrite Z.shiftr_0_r.
rewrite Z.shiftl_0_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
rewrite <- Z.land_lor_distr_r.
assert (Hm0: Z.lor (Z.shiftl (Z.ones 8) 8) (Z.ones 8) = Z.ones 16). {
apply (bitMaskCombine 8).
lia.
}
rewrite Hm0. clear Hm0.
assert (Hm1: Z.lor (Z.shiftl (Z.ones 8) 16) (Z.ones 16) = Z.ones 24). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm1. clear Hm1.
assert (Hm2: Z.lor (Z.shiftl (Z.ones 8) 24) (Z.ones 24) = Z.ones 32). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm2. clear Hm2.
assert (Hm3: Z.lor (Z.shiftl (Z.ones 8) 32) (Z.ones 32) = Z.ones 40). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm3. clear Hm3.
assert (Hm4: Z.lor (Z.shiftl (Z.ones 8) 40) (Z.ones 40) = Z.ones 48). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm4. clear Hm4.
assert (Hm5: Z.lor (Z.shiftl (Z.ones 8) 48) (Z.ones 48) = Z.ones 56). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm5. clear Hm5.
assert (Hm6: Z.lor (Z.shiftl (Z.ones 8) 56) (Z.ones 56) = Z.ones 64). {
simpl.
rewrite Z.ones_equiv.
lia.
}
rewrite Hm6. clear Hm6.
apply Z.bits_inj'.
intros n Hn.
rewrite Z.land_spec.
destruct (Z_lt_ge_dec n 64) as [Hnlt|Hnge]. {
rewrite Z.ones_spec_low by lia.
rewrite Bool.andb_true_r.
reflexivity.
} {
rewrite Z.ones_spec_high by lia.
rewrite Bool.andb_false_r.
assert (z < 2 ^ n) as Hzn. {
rewrite Z.ge_le_iff in Hnge.
apply Z.lt_le_trans with (2 ^ 64).
auto.
apply (Z.pow_le_mono 2 64 2 n).
lia.
auto.
}
symmetry.
apply (Z.testbit_unique z n false z 0).
lia.
simpl.
lia.
}
- auto.
- auto.
- auto.
- auto.
- auto.
- auto.
- auto.
- subst z7.
apply (byteInRange z 0 (conj Hrange0 Hrange1)).
lia.
- subst z6; auto.
- subst z5; auto.
- subst z4; auto.
- subst z3; auto.
- subst z2; auto.
- subst z1; auto.
- subst z0; auto.
Qed.
(*
* Copyright © 2025 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
Require Import Stdlib.PArith.PArith.
Require Import Stdlib.Init.Nat.
Require Import Stdlib.Arith.PeanoNat.
Require Import Stdlib.Lists.List.
Import ListNotations.
(** The property of _x_ being divisible by 8. *)
Definition divisible8 (x : nat) : Prop :=
modulo x 8 = 0.
(** An octet is either in big or little endian order. *)
Inductive octetOrder : Set :=
| OctetOrderBig
| OctetOrderLittle.
(** A single bit. *)
Inductive bit : Set :=
| B0
| B1.
(** A sequence of bits may be divided into groups of eight bits known as octets.
We avoid the use of the term byte because a byte hasn't consistently been
equivalent to eight bits throughout all of computing history. An octet may
either be exact or a remainder. An octet may be a remainder if the length
of the sequence of bits used to produce it was not evenly divisible by 8.
The first n groups of 8 bits consumed from a sequence of bits s will produce
octets that are exact, with the remaining k bits (where k < 8) will produce
at most one remainder octet. The remainder octet, if any, has it's least
significant 8 - k bits set to 0. *)
Inductive octet : Set :=
| OctExact : bit -> bit -> bit -> bit -> bit -> bit -> bit -> bit -> octet
| OctRemain : bit -> bit -> bit -> bit -> bit -> bit -> bit -> bit -> octet.
#[local]
Definition listInduction8 :
forall (A : Type),
forall (P : list A -> Prop),
P [] ->
(forall (b0 : A), P (b0 :: [])) ->
(forall (b1 b0 : A), P (b1 :: b0 :: [])) ->
(forall (b2 b1 b0 : A), P (b2 :: b1 :: b0 :: [])) ->
(forall (b3 b2 b1 b0 : A), P (b3 :: b2 :: b1 :: b0 :: [])) ->
(forall (b4 b3 b2 b1 b0 : A), P (b4 :: b3 :: b2 :: b1 :: b0 :: [])) ->
(forall (b5 b4 b3 b2 b1 b0 : A), P (b5 :: b4 :: b3 :: b2 :: b1 :: b0 :: [])) ->
(forall (b6 b5 b4 b3 b2 b1 b0 : A), P (b6 :: b5 :: b4 :: b3 :: b2 :: b1 :: b0 :: [])) ->
(forall (b7 b6 b5 b4 b3 b2 b1 b0 : A) (rest : list A), P rest -> P (b7 :: b6 :: b5 :: b4 :: b3 :: b2 :: b1 :: b0 :: rest)) ->
forall (L : list A), P L :=
(fun A P P0 P1 P2 P3 P4 P5 P6 P7 P8 =>
fix f (l : list A) :=
match l with
| [] => P0
| x0 :: [] => P1 x0
| (x0 :: x1 :: []) => P2 x0 x1
| (x0 :: x1 :: x2 :: []) => P3 x0 x1 x2
| (x0 :: x1 :: x2 :: x3 :: []) => P4 x0 x1 x2 x3
| (x0 :: x1 :: x2 :: x3 :: x4 :: []) => P5 x0 x1 x2 x3 x4
| (x0 :: x1 :: x2 :: x3 :: x4 :: x5 :: []) => P6 x0 x1 x2 x3 x4 x5
| (x0 :: x1 :: x2 :: x3 :: x4 :: x5 :: x6 :: []) => P7 x0 x1 x2 x3 x4 x5 x6
| (x0 :: x1 :: x2 :: x3 :: x4 :: x5 :: x6 :: x7 :: rest) => P8 x0 x1 x2 x3 x4 x5 x6 x7 rest (f rest)
end).
#[local]
Lemma app_non_empty : forall (A : Type) (xs : list A) (y : A),
xs ++ [y] <> [].
Proof.
intros A xs y.
unfold not.
destruct xs as [|z zs].
intros Hfalse; inversion Hfalse.
intros Hfalse; inversion Hfalse.
Qed.
#[local]
Lemma app_list_implies_eq : forall (A : Type) (x y : A) (xs : list A),
xs ++ [x] = [y] -> xs = [] /\ x = y.
Proof.
intros A x y xs Happ.
induction xs as [|z zs] eqn:Hxe.
- constructor. reflexivity.
rewrite (app_nil_l [x]) in Happ.
injection Happ as Heq; exact Heq.
- inversion Happ.
assert (zs ++ [x] <> []) by (apply app_non_empty).
contradiction.
Qed.
#[local]
Lemma p8notZ : 8 <> 0.
Proof. discriminate. Qed.
#[local]
Lemma list_mod8_0 : forall (A : Type) (xs : list A) (n7 n6 n5 n4 n3 n2 n1 n0 : A),
divisible8 (length xs) -> divisible8 (length (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: xs)).
Proof.
intros A xs n7 n6 n5 n4 n3 n2 n1 n0 Hlen8.
unfold divisible8 in *.
assert (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: xs
= (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: []) ++ xs) as HlistEq
by reflexivity.
rewrite HlistEq.
rewrite length_app.
assert (length [n7; n6; n5; n4; n3; n2; n1; n0] = 8) as Hprefix8 by reflexivity.
rewrite Hprefix8.
rewrite <- (Nat.Div0.add_mod_idemp_l 8 (length xs) 8).
rewrite (Nat.Div0.mod_same 8).
rewrite (Nat.add_0_l).
exact Hlen8.
Qed.
#[local]
Lemma list_mod8_1 : forall (A : Type) (xs : list A) (n7 n6 n5 n4 n3 n2 n1 n0 : A),
divisible8 (length (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: xs)) -> divisible8 (length xs).
Proof.
intros A xs n7 n6 n5 n4 n3 n2 n1 n0 Hlen8.
unfold divisible8 in *.
assert (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: xs
= (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: []) ++ xs) as HlistEq
by reflexivity.
rewrite HlistEq in Hlen8.
rewrite length_app in Hlen8.
assert (length [n7; n6; n5; n4; n3; n2; n1; n0] = 8) as Hprefix8 by reflexivity.
rewrite Hprefix8 in Hlen8.
rewrite <- (Nat.Div0.add_mod_idemp_l 8 (length xs) 8) in Hlen8.
rewrite (Nat.Div0.mod_same 8) in Hlen8.
rewrite (Nat.add_0_l) in Hlen8.
exact Hlen8.
Qed.
#[local]
Theorem list_mod8 : forall (A : Type) (xs : list A) (n7 n6 n5 n4 n3 n2 n1 n0 : A),
divisible8 (length xs) <-> divisible8 (length (n7 :: n6 :: n5 :: n4 :: n3 :: n2 :: n1 :: n0 :: xs)).
Proof.
intros A xs n7 n6 n5 n4 n3 n2 n1 n0.
constructor.
- apply list_mod8_0.
- apply list_mod8_1.
Qed.
#[local]
Lemma mod_8_lt_0 : forall (m : nat),
0 < m mod 8 -> 0 < (m + 8) mod 8.
Proof.
intros m Hlt.
rewrite (Nat.Div0.add_mod m 8 8).
rewrite (Nat.Div0.mod_same).
rewrite (Nat.add_0_r).
rewrite (Nat.Div0.mod_mod).
exact Hlt.
Qed.
#[local]
Lemma mod_8_lt_1 : forall (m : nat),
0 < (m + 8) mod 8 -> 0 < m mod 8.
Proof.
intros m Hlt.
rewrite (Nat.Div0.add_mod m 8 8) in Hlt.
rewrite (Nat.Div0.mod_same) in Hlt.
rewrite (Nat.add_0_r) in Hlt.
rewrite (Nat.Div0.mod_mod) in Hlt.
exact Hlt.
Qed.
#[local]
Lemma mod_8_lt : forall (m : nat),
0 < (m + 8) mod 8 <-> 0 < m mod 8.
Proof.
constructor.
apply mod_8_lt_1.
apply mod_8_lt_0.
Qed.
Definition octetIsRemainder (o : octet): Prop :=
match o with
| OctExact _ _ _ _ _ _ _ _ => False
| OctRemain _ _ _ _ _ _ _ _ => True
end.
Definition octetIsExact (o : octet): Prop :=
match o with
| OctExact _ _ _ _ _ _ _ _ => True
| OctRemain _ _ _ _ _ _ _ _ => False
end.
Lemma octetIsRemainderNotExact : forall (o : octet), octetIsRemainder o -> ~octetIsExact o.
Proof.
intros o Hrem Hfalse.
destruct o; contradiction.
Qed.
Lemma octetIsExactNotRemainder : forall (o : octet), octetIsExact o -> ~octetIsRemainder o.
Proof.
intros o Hrem Hfalse.
destruct o; contradiction.
Qed.
Inductive bitsOctetsHasRemainder : list octet -> Prop :=
| BOHasRemainder : forall (prefix : list octet) (o : octet),
Forall octetIsExact prefix ->
octetIsRemainder o ->
bitsOctetsHasRemainder (prefix ++ o :: []).
(** If the sequence of octets o produced is arranged such that the first bit of s
appears as the most significant bit of the first octet in o, then o is said to
be in big-endian order. *)
Fixpoint octetsBigEndianAux
(bits : list bit)
(octets : list octet)
: list octet :=
match bits with
| (b7 :: b6 :: b5 :: b4 :: b3 :: b2 :: b1 :: b0 :: rest) =>
octets ++ [OctExact b7 b6 b5 b4 b3 b2 b1 b0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: b5 :: b4 :: b3 :: b2 :: b1 :: rest) =>
octets ++ [OctRemain b7 b6 b5 b4 b3 b2 b1 B0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: b5 :: b4 :: b3 :: b2 :: rest) =>
octets ++ [OctRemain b7 b6 b5 b4 b3 b2 B0 B0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: b5 :: b4 :: b3 :: rest) =>
octets ++ [OctRemain b7 b6 b5 b4 b3 B0 B0 B0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: b5 :: b4 :: rest) =>
octets ++ [OctRemain b7 b6 b5 b4 B0 B0 B0 B0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: b5 :: rest) =>
octets ++ [OctRemain b7 b6 b5 B0 B0 B0 B0 B0] ++ octetsBigEndianAux rest []
| (b7 :: b6 :: rest) =>
octets ++ [OctRemain b7 b6 B0 B0 B0 B0 B0 B0] ++ octetsBigEndianAux rest []
| (b7 :: rest) =>
octets ++ [OctRemain b7 B0 B0 B0 B0 B0 B0 B0] ++ octetsBigEndianAux rest []
| [] =>
octets
end.
Definition octetsBigEndian (bits : list bit) : list octet :=
octetsBigEndianAux bits [].
(** If the sequence of octets o produced is arranged such that the first bit of
s appears as the most significant bit of the last octet in o, then o is said
to be in little-endian order. *)
Definition octetsLittleEndian (bits : list bit) : list octet :=
rev (octetsBigEndianAux bits []).
(** A sequence of bits s such that divisible8 (length s) will produce a sequence
consisting of entirely exact octets. *)
Theorem octetsBigEndianLengthDivisibleAllExact : forall (b : list bit),
divisible8 (length b) -> Forall octetIsExact (octetsBigEndian b).
Proof.
intros b Hlen8.
unfold octetsBigEndian.
induction b using listInduction8.
- constructor.
- inversion Hlen8.
- inversion Hlen8.
- inversion Hlen8.
- inversion Hlen8.
- inversion Hlen8.
- inversion Hlen8.
- inversion Hlen8.
- simpl.
rewrite <- list_mod8 in Hlen8.
assert (Forall octetIsExact (octetsBigEndianAux b [])) as HallExact by (apply (IHb Hlen8)).
assert (octetIsExact (OctExact b7 b6 b5 b4 b3 b2 b1 b0)) as Hexact by constructor.
apply (@Forall_cons octet octetIsExact (OctExact b7 b6 b5 b4 b3 b2 b1 b0) (octetsBigEndianAux b []) Hexact HallExact).
Qed.
(** A sequence of bits s such that divisible8 (length s) will produce a sequence
consisting of entirely exact octets. *)
Theorem octetsLittleEndianLengthDivisibleAllExact : forall (b : list bit),
divisible8 (length b) -> Forall octetIsExact (octetsLittleEndian b).
Proof.
intros b Hlen8.
apply (Forall_rev (octetsBigEndianLengthDivisibleAllExact b Hlen8)).
Qed.
Theorem octetsBigEndianLengthDivisibleNoRemainder : forall (b : list bit),
Forall octetIsExact (octetsBigEndian b) -> ~bitsOctetsHasRemainder (octetsBigEndian b).
Proof.
intros b HallExact.
unfold octetsBigEndian.
intro Hfalse.
inversion Hfalse as [prefix o HprefixAllExact HoIsRemainder HprefixEq].
unfold octetsBigEndian in HallExact.
(* We know that everything in the list is exact. *)
(* We can show that o must be in this list according to HprefixEq. *)
assert (In o (octetsBigEndianAux b [])) as HoInB. {
assert (In o (prefix ++ [o])) as HoInPrefix by (apply (in_elt o prefix [])).
rewrite HprefixEq in HoInPrefix.
exact HoInPrefix.
}
(* And because o is in the list, it must be exact. *)
assert (octetIsExact o) as HoIsExact. {
rewrite Forall_forall in HallExact.
apply (HallExact o HoInB).
}
(* There is a contradiction; o cannot be both exact and a remainder. *)
apply (octetIsExactNotRemainder o HoIsExact HoIsRemainder).
Qed.
(** A sequence of bits s such that ¬ divisible8 (length s) will produce a remainder octet. *)
Theorem octetsBigEndianLengthIndivisibleRemainder : forall (b : list bit),
0 < length b mod 8 -> exists o, In o (octetsBigEndian b) /\ octetIsRemainder o.
Proof.
intros b Hlength.
induction b using listInduction8.
- inversion Hlength.
- exists (OctRemain b0 B0 B0 B0 B0 B0 B0 B0).
constructor.
left. reflexivity.
constructor.
- exists (OctRemain b1 b0 B0 B0 B0 B0 B0 B0).
constructor.
left.
constructor.
constructor.
- exists (OctRemain b2 b1 b0 B0 B0 B0 B0 B0).
constructor.
left.
constructor.
constructor.
- exists (OctRemain b3 b2 b1 b0 B0 B0 B0 B0).
constructor.
left.
constructor.
constructor.
- exists (OctRemain b4 b3 b2 b1 b0 B0 B0 B0).
constructor.
left.
constructor.
constructor.
- exists (OctRemain b5 b4 b3 b2 b1 b0 B0 B0).
constructor.
left.
constructor.
constructor.
- exists (OctRemain b6 b5 b4 b3 b2 b1 b0 B0).
constructor.
left.
constructor.
constructor.
- assert (0 < length b mod 8) as Hlt. {
assert (length (b7 :: b6 :: b5 :: b4 :: b3 :: b2 :: b1 :: b0 :: b) = length b + 8) as Heq
by (rewrite Nat.add_comm; reflexivity).
rewrite Heq in Hlength.
rewrite <- (mod_8_lt (length b)).
exact Hlength.
}
assert (exists o : octet, In o (octetsBigEndian b) /\ octetIsRemainder o) as HEx
by (apply (IHb Hlt)).
destruct HEx as [ox [HoxIn HoxRem]].
simpl.
exists ox.
constructor.
right.
exact HoxIn.
exact HoxRem.
Qed.
(** A sequence of bits s such that ¬ divisible8 (length s) will produce a remainder octet. *)
Theorem octetsLittleEndianLengthIndivisibleRemainder : forall (b : list bit),
0 < length b mod 8 -> exists o, In o (octetsLittleEndian b) /\ octetIsRemainder o.
Proof.
unfold octetsLittleEndian.
intros b Hlen.
assert (exists o, In o (octetsBigEndian b) /\ octetIsRemainder o) as Hexists
by (apply (octetsBigEndianLengthIndivisibleRemainder b Hlen)).
destruct Hexists as [ox [HoxIn HoxRem]].
exists ox.
rewrite <- (in_rev (octetsBigEndianAux b [])).
constructor.
exact HoxIn.
exact HoxRem.
Qed.
float f; int i = Float.floatToRawIntBits(f);
double d; long i = Double.doubleToRawLongBits(f);
final char k = Binary16.packDouble(32.0); final double r = Binary16.unpackDouble(k);
float32_t f; uint32_t i; memcpy(&i, &f, sizeof i);
double f; uint64_t i; assert (sizeof(double) == 8); memcpy(&i, &f, sizeof i);
{
"$schema" : "https://json-schema.org/draft/2020-12/schema",
"$id" : "urn:com.io7m.zeniro:info:1.0",
"title" : "Zeniro 1.0",
"oneOf" : [ {
"$ref" : "#/$defs/Z1Info"
} ],
"$defs" : {
"List<Z1Extension>" : {
"type" : "array",
"items" : {
"$ref" : "#/$defs/Z1Extension"
}
},
"List<Z1StructureComponent>" : {
"type" : "array",
"items" : {
"$ref" : "#/$defs/Z1StructureComponent"
}
},
"List<ZSectionID>" : {
"type" : "array",
"items" : {
"$ref" : "#/$defs/ZSectionID"
}
},
"OffsetDateTime" : {
"description" : "An ISO 8601 timestamp.",
"type" : "string",
"format" : "date-time"
},
"Optional<Z1Bounds>" : {
"$ref" : "#/$defs/Z1Bounds"
},
"Optional<Z1IndexInfo>" : {
"$ref" : "#/$defs/Z1IndexInfo"
},
"RDottedName" : {
"type" : "string",
"description" : "A Lanark dotted name.",
"pattern" : "([a-z][a-z0-9_-]{0,63})(\\.[a-z][a-z0-9_-]{0,62}){0,15}"
},
"String" : {
"type" : "string"
},
"URI" : {
"description" : "An RFC 3986 URI string.",
"type" : "string",
"format" : "uri"
},
"Z1Bounds" : {
"type" : "object",
"properties" : {
"XMaximum" : {
"description" : "The maximum X value (inclusive).",
"$ref" : "#/$defs/double"
},
"XMinimum" : {
"description" : "The minimum X value (inclusive).",
"$ref" : "#/$defs/double"
},
"YMaximum" : {
"description" : "The maximum Y value (inclusive).",
"$ref" : "#/$defs/double"
},
"YMinimum" : {
"description" : "The minimum Y value (inclusive).",
"$ref" : "#/$defs/double"
},
"ZMaximum" : {
"description" : "The maximum Z value (inclusive).",
"$ref" : "#/$defs/double"
},
"ZMinimum" : {
"description" : "The minimum Z value (inclusive).",
"$ref" : "#/$defs/double"
}
},
"required" : [ "XMaximum", "XMinimum", "YMaximum", "YMinimum", "ZMaximum", "ZMinimum" ],
"additionalProperties" : false
},
"Z1Extension" : {
"type" : "object",
"properties" : {
"Description" : {
"description" : "The extension description.",
"$ref" : "#/$defs/String"
},
"ID" : {
"description" : "The extension ID.",
"$ref" : "#/$defs/RDottedName"
},
"Name" : {
"description" : "The extension name.",
"$ref" : "#/$defs/String"
},
"Sections" : {
"description" : "The extension section IDs.",
"$ref" : "#/$defs/List<ZSectionID>"
},
"Specification" : {
"description" : "The extension specification documentation.",
"$ref" : "#/$defs/URI"
},
"VersionMajor" : {
"description" : "The major version of the extension.",
"$ref" : "#/$defs/int"
},
"VersionMinor" : {
"description" : "The minor version of the extension.",
"$ref" : "#/$defs/int"
}
},
"required" : [ "Description", "ID", "Name", "Sections", "Specification", "VersionMajor", "VersionMinor" ],
"additionalProperties" : false
},
"Z1IndexInfo" : {
"type" : "object",
"properties" : {
"Count" : {
"description" : "The index count.",
"$ref" : "#/$defs/long"
},
"Semantic" : {
"description" : "The index semantic.",
"$ref" : "#/$defs/Z1IndexSemantic"
},
"Type" : {
"description" : "The index type.",
"$ref" : "#/$defs/Z1IndexType"
}
},
"required" : [ "Count", "Semantic", "Type" ],
"additionalProperties" : false
},
"Z1IndexSemantic" : {
"type" : "string",
"enum" : [ "INDEX_SEMANTIC_LINE_LIST", "INDEX_SEMANTIC_LINE_STRIP", "INDEX_SEMANTIC_TRIANGLE_LIST", "INDEX_SEMANTIC_TRIANGLE_STRIP", "INDEX_SEMANTIC_TRIANGLE_FAN" ]
},
"Z1IndexType" : {
"type" : "string",
"enum" : [ "INDEX_8", "INDEX_16", "INDEX_32" ]
},
"Z1Info" : {
"type" : "object",
"properties" : {
"$Schema" : {
"description" : "The schema identifier.",
"$ref" : "#/$defs/String"
},
"Extensions" : {
"description" : "The extension descriptions",
"$ref" : "#/$defs/List<Z1Extension>"
},
"Shape" : {
"description" : "The shape of the file data.",
"$ref" : "#/$defs/Z1ShapeType"
},
"Structure" : {
"description" : "The structure of the file data.",
"$ref" : "#/$defs/Z1Structure"
}
},
"required" : [ "$Schema", "Shape", "Structure" ],
"additionalProperties" : false
},
"Z1ShapeArray1D" : {
"type" : "object",
"properties" : {
"Length" : {
"description" : "The length of the array.",
"$ref" : "#/$defs/long"
},
"@Shape" : {
"type" : "string",
"const" : "Array1D"
}
},
"required" : [ "@Shape", "Length" ],
"additionalProperties" : false
},
"Z1ShapeArray2D" : {
"type" : "object",
"properties" : {
"SizeX" : {
"description" : "The size of the array on the X axis.",
"$ref" : "#/$defs/long"
},
"SizeY" : {
"description" : "The size of the array on the Y axis.",
"$ref" : "#/$defs/long"
},
"@Shape" : {
"type" : "string",
"const" : "Array2D"
}
},
"required" : [ "@Shape", "SizeX", "SizeY" ],
"additionalProperties" : false
},
"Z1ShapeArray3D" : {
"type" : "object",
"properties" : {
"SizeX" : {
"description" : "The size of the array on the X axis.",
"$ref" : "#/$defs/long"
},
"SizeY" : {
"description" : "The size of the array on the Y axis.",
"$ref" : "#/$defs/long"
},
"SizeZ" : {
"description" : "The size of the array on the Z axis.",
"$ref" : "#/$defs/long"
},
"@Shape" : {
"type" : "string",
"const" : "Array3D"
}
},
"required" : [ "@Shape", "SizeX", "SizeY", "SizeZ" ],
"additionalProperties" : false
},
"Z1ShapeMesh" : {
"type" : "object",
"properties" : {
"Bounds" : {
"description" : "The optional bounds information.",
"$ref" : "#/$defs/Optional<Z1Bounds>"
},
"Index" : {
"description" : "Information about the index data.",
"$ref" : "#/$defs/Optional<Z1IndexInfo>"
},
"Length" : {
"description" : "The length of the array.",
"$ref" : "#/$defs/long"
},
"@Shape" : {
"type" : "string",
"const" : "Mesh"
}
},
"required" : [ "@Shape", "Index", "Length" ],
"additionalProperties" : false
},
"Z1ShapeType" : {
"oneOf" : [ {
"$ref" : "#/$defs/Z1ShapeArray1D"
}, {
"$ref" : "#/$defs/Z1ShapeArray2D"
}, {
"$ref" : "#/$defs/Z1ShapeArray3D"
}, {
"$ref" : "#/$defs/Z1ShapeMesh"
} ]
},
"Z1Structure" : {
"type" : "object",
"properties" : {
"Components" : {
"description" : "The structure components.",
"$ref" : "#/$defs/List<Z1StructureComponent>"
}
},
"required" : [ ],
"additionalProperties" : false
},
"Z1StructureComponent" : {
"type" : "object",
"properties" : {
"Name" : {
"description" : "The component name.",
"$ref" : "#/$defs/String"
},
"Semantic" : {
"description" : "The component semantic.",
"$ref" : "#/$defs/String"
},
"Type" : {
"description" : "The component type.",
"$ref" : "#/$defs/Z1StructureComponentType"
}
},
"required" : [ "Name", "Semantic", "Type" ],
"additionalProperties" : false
},
"Z1StructureComponentType" : {
"type" : "string",
"enum" : [ "INTEGER_SIGNED_8", "INTEGER_SIGNED_8_VEC2", "INTEGER_SIGNED_8_VEC3", "INTEGER_SIGNED_8_VEC4", "INTEGER_UNSIGNED_8", "INTEGER_UNSIGNED_8_VEC2", "INTEGER_UNSIGNED_8_VEC3", "INTEGER_UNSIGNED_8_VEC4", "INTEGER_SIGNED_16", "INTEGER_SIGNED_16_VEC2", "INTEGER_SIGNED_16_VEC3", "INTEGER_SIGNED_16_VEC4", "INTEGER_UNSIGNED_16", "INTEGER_UNSIGNED_16_VEC2", "INTEGER_UNSIGNED_16_VEC3", "INTEGER_UNSIGNED_16_VEC4", "INTEGER_SIGNED_32", "INTEGER_SIGNED_32_VEC2", "INTEGER_SIGNED_32_VEC3", "INTEGER_SIGNED_32_VEC4", "INTEGER_UNSIGNED_32", "INTEGER_UNSIGNED_32_VEC2", "INTEGER_UNSIGNED_32_VEC3", "INTEGER_UNSIGNED_32_VEC4", "INTEGER_SIGNED_64", "INTEGER_SIGNED_64_VEC2", "INTEGER_SIGNED_64_VEC3", "INTEGER_SIGNED_64_VEC4", "INTEGER_UNSIGNED_64", "INTEGER_UNSIGNED_64_VEC2", "INTEGER_UNSIGNED_64_VEC3", "INTEGER_UNSIGNED_64_VEC4", "FLOAT_16", "FLOAT_16_VEC2", "FLOAT_16_VEC3", "FLOAT_16_VEC4", "FLOAT_32", "FLOAT_32_VEC2", "FLOAT_32_VEC3", "FLOAT_32_VEC4", "FLOAT_64", "FLOAT_64_VEC2", "FLOAT_64_VEC3", "FLOAT_64_VEC4" ]
},
"ZSectionID" : {
"description" : "A hex string.",
"type" : "string",
"pattern" : "0x[0-9a-f]+"
},
"boolean" : {
"type" : "boolean",
"description" : "A boolean value."
},
"byte" : {
"type" : "integer",
"description" : "A primitive byte.",
"minimum" : -128,
"maximum" : 127
},
"char" : {
"type" : "integer",
"description" : "A primitive char.",
"minimum" : 0,
"maximum" : 65535
},
"double" : {
"type" : "number",
"minimum" : -1.7976931348623157E308,
"maximum" : 1.7976931348623157E308,
"description" : "An IEEE764 64-bit floating point value."
},
"float" : {
"type" : "number",
"minimum" : -3.4028235E38,
"maximum" : 3.4028235E38,
"description" : "An IEEE764 32-bit floating point value."
},
"int" : {
"type" : "integer",
"description" : "A primitive int.",
"minimum" : -2147483648,
"maximum" : 2147483647
},
"long" : {
"type" : "integer",
"description" : "A primitive long.",
"minimum" : -9223372036854775808,
"maximum" : 9223372036854775807
},
"short" : {
"type" : "integer",
"description" : "A primitive short.",
"minimum" : -32768,
"maximum" : 32767
}
}
}