e57eb8ac508bd8fc249eca91d496c58132fcbfe8607385dc743161a1a481d06d.tri (10830B)
1 !import prelude * 2 !import binary * 3 !import arboricx_common * 4 !export * 5 6 -- Indexed Arboricx node section reader. 7 -- 8 -- Node records in the indexed format are just length-prefixed payloads: 9 -- u32 payloadLength || payload 10 -- A payload is one of: 11 -- 0x00 12 -- 0x01 || childIndex:u32be 13 -- 0x02 || leftIndex:u32be || rightIndex:u32be 14 -- Child indices must point strictly backward in the node array. 15 16 readNodeRecord = (do bindParser 17 payloadLength <- readBytes 4 18 payload <- readBytes (u32BEBytesToNat payloadLength) 19 pureParser payload) 20 21 nodePayloadKind = (nodePayload : bytesHead nodePayload) 22 23 nodePayloadHasTag? tag nodePayload = case (nodePayloadKind nodePayload) of 24 (t actualTag) = equal? actualTag tag 25 _ = false 26 27 nodePayloadLeaf? = (nodePayload : 28 bytesEq? [(0)] nodePayload) 29 30 nodePayloadStem? = (nodePayload : 31 and? 32 (nodePayloadHasTag? nodePayloadStemTag nodePayload) 33 (equal? (bytesLength nodePayload) 5)) 34 35 nodePayloadFork? = (nodePayload : 36 and? 37 (nodePayloadHasTag? nodePayloadForkTag nodePayload) 38 (equal? (bytesLength nodePayload) 9)) 39 40 nodePayloadValid? = (nodePayload : 41 or? 42 (nodePayloadLeaf? nodePayload) 43 (or? 44 (nodePayloadStem? nodePayload) 45 (nodePayloadFork? nodePayload))) 46 47 nodeU32FromBytes4 = (b0 b1 b2 b3 : 48 u32BEBytesToNat 49 (pair b0 50 (pair b1 51 (pair b2 52 (pair b3 t))))) 53 54 withNodePayloadStemIndex = (nodePayload shortK indexK : 55 matchList 56 (shortK t) 57 (tag r0 : 58 matchList 59 (shortK t) 60 (b0 r1 : 61 matchList 62 (shortK t) 63 (b1 r2 : 64 matchList 65 (shortK t) 66 (b2 r3 : 67 matchList 68 (shortK t) 69 (b3 _ : 70 indexK (nodeU32FromBytes4 b0 b1 b2 b3)) 71 r3) r2) r1) r0) nodePayload) 72 73 withNodePayloadForkIndices = (nodePayload shortK indicesK : 74 matchList 75 (shortK t) 76 (tag r0 : 77 matchList 78 (shortK t) 79 (l0 r1 : 80 matchList 81 (shortK t) 82 (l1 r2 : 83 matchList 84 (shortK t) 85 (l2 r3 : 86 matchList 87 (shortK t) 88 (l3 r4 : 89 matchList 90 (shortK t) 91 (r0b r5 : 92 matchList 93 (shortK t) 94 (r1b r6 : 95 matchList 96 (shortK t) 97 (r2b r7 : 98 matchList 99 (shortK t) 100 (r3b _ : 101 indicesK 102 (nodeU32FromBytes4 l0 l1 l2 l3) 103 (nodeU32FromBytes4 r0b r1b r2b r3b)) r7) r6) r5) r4) r3) r2) r1) r0) nodePayload) 104 105 nodePayloadStemChildIndex = (nodePayload : 106 withNodePayloadStemIndex nodePayload (_ : 0) (index : index)) 107 108 nodePayloadForkLeftIndex = (nodePayload : 109 withNodePayloadForkIndices nodePayload (_ : 0) (left right : left)) 110 111 nodePayloadForkRightIndex = (nodePayload : 112 withNodePayloadForkIndices nodePayload (_ : 0) (left right : right)) 113 114 nodeRecordsHaveInvalidPayload? nodeRecords = (matchList 115 false 116 (nodePayload rest : 117 or? 118 (not? (nodePayloadValid? nodePayload)) 119 (nodeRecordsHaveInvalidPayload? rest)) 120 nodeRecords) 121 122 nodePayloadChildIndices = (nodePayload : 123 matchList 124 t 125 (tag rest : 126 lazyBool 127 (_ : 128 withNodePayloadStemIndex 129 nodePayload 130 (_ : t) 131 (childIndex : pair childIndex t)) 132 (_ : 133 lazyBool 134 (_ : 135 withNodePayloadForkIndices 136 nodePayload 137 (_ : t) 138 (leftIndex rightIndex : 139 pair leftIndex (pair rightIndex t))) 140 (_ : t) 141 (equal? tag nodePayloadForkTag)) 142 (equal? tag nodePayloadStemTag)) 143 nodePayload) 144 145 -- True iff index n names an element before limit in records. 146 -- For topologically sorted indexed bundles, every child of record i must 147 -- satisfy childIndex < i, so searching only the prefix [0, i) validates both 148 -- bounds and acyclicity. 149 nodeIndexInPrefix? records n i limit = (matchList 150 false 151 (_ rest : 152 matchBool 153 false 154 (matchBool 155 true 156 (nodeIndexInPrefix? rest n (succ i) limit) 157 (equal? i n)) 158 (equal? i limit)) 159 records) 160 161 nodeChildIndicesInPrefix? childIndices records limit = (matchList 162 true 163 (childIndex rest : 164 matchBool 165 (nodeChildIndicesInPrefix? rest records limit) 166 false 167 (nodeIndexInPrefix? records childIndex 0 limit)) 168 childIndices) 169 170 nodePayloadIndicesValid? = (nodePayload i records : 171 nodeChildIndicesInPrefix? 172 (nodePayloadChildIndices nodePayload) 173 records 174 i) 175 176 nodeRecordsValidIndicesFrom? allRecords remainingRecords i = (matchList 177 true 178 (nodePayload rest : 179 matchBool 180 (nodeRecordsValidIndicesFrom? allRecords rest (succ i)) 181 false 182 (nodePayloadIndicesValid? nodePayload i allRecords)) 183 remainingRecords) 184 185 nodeRecordsValidIndices? = (nodeRecords i : 186 nodeRecordsValidIndicesFrom? nodeRecords nodeRecords i) 187 188 validateNodeRecords = (nodeRecords rest : 189 matchBool 190 (err errInvalidNodePayload rest) 191 (matchBool 192 (ok nodeRecords rest) 193 (err errMissingNode rest) 194 (nodeRecordsValidIndices? nodeRecords 0)) 195 (nodeRecordsHaveInvalidPayload? nodeRecords)) 196 197 readNodeRecords_ bs nodeCount i acc = (matchBool 198 (ok (reverse acc) bs) 199 (bindResult (readNodeRecord bs) 200 (nodeRecord afterNodeRecord : 201 readNodeRecords_ afterNodeRecord nodeCount (succ i) (pair nodeRecord acc))) 202 (equal? i nodeCount)) 203 204 readNodeRecords = (nodeCount bs : 205 readNodeRecords_ bs nodeCount 0 t) 206 207 readNodesSection = (bs : 208 bindResult (readBytes 8 bs) 209 (nodeCount afterNodeCount : 210 bindResult (readNodeRecords (u64BEBytesToNat nodeCount) afterNodeCount) 211 (nodeRecords afterNodeRecords : 212 bindResult (validateNodeRecords nodeRecords afterNodeRecords) 213 (validNodeRecords afterValidNodeRecords : 214 ok (pair nodeCount validNodeRecords) afterValidNodeRecords)))) 215 216 readNodesSectionComplete = (bs : 217 bindResult (readNodesSection bs) 218 (nodesSection afterNodesSection : 219 matchBool 220 (ok nodesSection afterNodesSection) 221 (err errUnexpectedBytes afterNodesSection) 222 (bytesNil? afterNodesSection))) 223 224 readArboricxNodesSection = (bs : 225 bindResult (readArboricxContainer bs) 226 (container afterContainer : 227 matchPair 228 (_ directory : 229 bindResult (sectionBytesOrErr arboricxNodesSectionId directory bs afterContainer) 230 (nodesBytes _ : 231 bindResult (readNodesSectionComplete nodesBytes) 232 (nodesSection _ : ok nodesSection afterContainer))) 233 container)) 234 235 nodesSectionCount = (nodesSection : 236 matchPair 237 (nodeCount _ : nodeCount) 238 nodesSection) 239 240 nodesSectionRecords = (nodesSection : 241 matchPair 242 (_ nodeRecords : nodeRecords) 243 nodesSection) 244 245 nodeBuiltTreeIndex = (entry : 246 matchPair 247 (index _ : index) 248 entry) 249 250 nodeBuiltTreeValue = (entry : 251 matchPair 252 (_ tree : tree) 253 entry) 254 255 nodeTreeByIndex_ = (self builtTrees targetIndex : 256 lazyList 257 (_ : err errMissingNode t) 258 (entry rest : 259 lazyBool 260 (_ : ok (nodeBuiltTreeValue entry) t) 261 (_ : self rest targetIndex) 262 (equal? (nodeBuiltTreeIndex entry) targetIndex)) 263 builtTrees) 264 265 nodeTreeByIndex = (builtTrees targetIndex : 266 y nodeTreeByIndex_ builtTrees targetIndex) 267 268 nodePayloadToTreeFromBuilt = (builtTrees nodePayload : 269 matchList 270 (err errInvalidNodePayload t) 271 (tag rest : 272 lazyBool 273 (_ : ok t t) 274 (_ : 275 lazyBool 276 (_ : 277 withNodePayloadStemIndex 278 nodePayload 279 (_ : err errInvalidNodePayload t) 280 (childIndex : 281 lazyResult 282 (code after : err code after) 283 (child _ : ok (t child) t) 284 (nodeTreeByIndex builtTrees childIndex))) 285 (_ : 286 lazyBool 287 (_ : 288 withNodePayloadForkIndices 289 nodePayload 290 (_ : err errInvalidNodePayload t) 291 (leftIndex rightIndex : 292 lazyResult 293 (code after : err code after) 294 (left _ : 295 lazyResult 296 (code after : err code after) 297 (right _ : ok (pair left right) t) 298 (nodeTreeByIndex builtTrees rightIndex)) 299 (nodeTreeByIndex builtTrees leftIndex))) 300 (_ : err errInvalidNodePayload t) 301 (equal? tag nodePayloadForkTag)) 302 (equal? tag nodePayloadStemTag)) 303 (equal? tag 0)) 304 nodePayload) 305 306 nodeBuildState = (targetIndex i builtTrees : 307 pair targetIndex (pair i builtTrees)) 308 309 nodeBuildStateTargetIndex = (state : 310 matchPair 311 (targetIndex _ : targetIndex) 312 state) 313 314 nodeBuildStateI = (state : 315 matchPair 316 (_ rest : 317 matchPair 318 (i _ : i) 319 rest) 320 state) 321 322 nodeBuildStateBuiltTrees = (state : 323 matchPair 324 (_ rest : 325 matchPair 326 (_ builtTrees : builtTrees) 327 rest) 328 state) 329 330 nodeIndexToTree_ = (self remainingRecords state : 331 ((nodeIndex : 332 ((i : 333 ((builtTrees : 334 lazyList 335 (_ : err errMissingNode t) 336 (nodePayload rest : 337 lazyResult 338 (code after : err code after) 339 (tree _ : 340 lazyBool 341 (_ : ok tree t) 342 (_ : 343 self 344 rest 345 (nodeBuildState 346 nodeIndex 347 (succ i) 348 (pair (pair i tree) builtTrees))) 349 (equal? i nodeIndex)) 350 (nodePayloadToTreeFromBuilt builtTrees nodePayload)) 351 remainingRecords) 352 (nodeBuildStateBuiltTrees state))) 353 (nodeBuildStateI state))) 354 (nodeBuildStateTargetIndex state))) 355 356 nodeIndexToTree = (nodeRecords nodeIndex : 357 y nodeIndexToTree_ nodeRecords (nodeBuildState nodeIndex 0 t)) 358 359 readArboricxTreeFromIndex = (rootIndexBytes bs : 360 bindResult (readArboricxNodesSection bs) 361 (nodesSection afterContainer : 362 bindResult (nodeIndexToTree (nodesSectionRecords nodesSection) (u32BEBytesToNat rootIndexBytes)) 363 (tree _ : ok tree afterContainer))) 364 365 readArboricxExecutableFromIndex = readArboricxTreeFromIndex