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