tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

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