------------------------------------------------------------------------------- |-- Module : Data.SBV.BitVectors.STree-- Copyright : (c) Levent Erkok-- License : BSD3-- Maintainer : erkokl@gmail.com-- Stability : experimental-- Portability : portable---- Implementation of full-binary symbolic trees, providing logarithmic-- time access to elements. Both reads and writes are supported.-----------------------------------------------------------------------------{-# LANGUAGE ScopedTypeVariables #-}{-# LANGUAGE TypeSynonymInstances #-}{-# LANGUAGE FlexibleContexts #-}{-# LANGUAGE FlexibleInstances #-}moduleData.SBV.BitVectors.STree(STree,readSTree,writeSTree,mkSTree)whereimportData.Bits(Bits(..))importData.SBV.BitVectors.DataimportData.SBV.BitVectors.Model-- | A symbolic tree containing values of type e, indexed by-- elements of type i. Note that these are full-trees, and their-- their shapes remain constant. There is no API provided that-- can change the shape of the tree. These structures are useful-- when dealing with data-structures that are indexed with symbolic-- values where access time is important. 'STree' structures provide-- logarithmic time reads and writes.typeSTreeie=STreeInternal(SBVi)(SBVe)-- Internal representation, not exposed to the userdataSTreeInternalie=SLeafe-- NB. parameter 'i' is phantom|SBin(STreeInternalie)(STreeInternalie)derivingShowinstance(SymWorde,Mergeable(SBVe))=>Mergeable(STreeie)wheresymbolicMergeb(SLeafi)(SLeafj)=SLeaf(itebij)symbolicMergeb(SBinlr)(SBinl'r')=SBin(itebll')(itebrr')symbolicMerge___=error"SBV.STree.symbolicMerge: Impossible happened while merging states"-- | Reading a value. We bit-blast the index and descend down the full tree-- according to bit-values.readSTree::(Bitsi,SymWordi,SymWorde)=>STreeie->SBVi->SBVereadSTreesi=walk(blastBEi)swherewalk[](SLeafv)=vwalk(b:bs)(SBinlr)=iteb(walkbsr)(walkbsl)walk__=error$"SBV.STree.readSTree: Impossible happened while reading: "++showi-- | Writing a value, similar to how reads are done. The important thing is that the tree-- representation keeps updates to a minimum.writeSTree::(Mergeable(SBVe),Bitsi,SymWordi,SymWorde)=>STreeie->SBVi->SBVe->STreeiewriteSTreesij=walk(blastBEi)swherewalk[]_=SLeafjwalk(b:bs)(SBinlr)=SBin(itebl(walkbsl))(iteb(walkbsr)r)walk__=error$"SBV.STree.writeSTree: Impossible happened while reading: "++showi-- | Construct the fully balanced initial tree using the given valuesmkSTree::forallie.HasSignAndSizei=>[SBVe]->STreeiemkSTreeivals|isInfPrec(undefined::i)=error"SBV.STree.mkSTree: Cannot build an infinitely large tree"|reqd/=given=error$"SBV.STree.mkSTree: Required "++showreqd++" elements, received: "++showgiven|True=goivalswherereqd=2^intSizeOf(undefined::i)given=lengthivalsgo[]=error"SBV.STree.mkSTree: Impossible happened, ran out of elements"go[l]=SLeaflgons=let(l,r)=splitAt(lengthns`div`2)nsinSBin(gol)(gor)