packages feed

bv-sized 0.6.0 → 0.7.0

raw patch · 43 files changed

+142/−8119 lines, 43 filesdep ~containersdep ~parameterized-utils

Dependency ranges changed: containers, parameterized-utils

Files

bv-sized.cabal view
@@ -1,10 +1,11 @@ name:                bv-sized-version:             0.6.0+version:             0.7.0 category:            Bit Vectors synopsis:            a BitVector datatype that is parameterized by the vector width description:   This module defines a width-parameterized 'BitVector' type and various associated   operations that assume a 2's complement representation.+extra-source-files:  changelog.md homepage:            https://github.com/GaloisInc/bv-sized license:             BSD3 license-file:        LICENSE@@ -21,10 +22,10 @@                      , Data.BitVector.Sized.BitLayout   other-modules:       Data.BitVector.Sized.Internal   build-depends:       base >= 4.7 && < 5-                     , containers >= 0.5.10 && < 0.6+                     , containers >= 0.5.10 && < 0.7                      , lens >= 4 && < 5                      , mtl >= 2 && < 3-                     , parameterized-utils+                     , parameterized-utils >= 2.0 && < 3                      , pretty                      , random >= 1.1 && < 1.2                      , QuickCheck >= 2.11 && < 2.12
− cabal.project
@@ -1,2 +0,0 @@-packages: .-          submodules/parameterized-utils
changelog.md view
@@ -1,11 +1,17 @@ # Changelog for [`bv-sized` package](http://hackage.haskell.org/package/bv-sized) +## 0.7.0 *April 2019*+  * extractWithRepr now takes a NatRepr as an argument to specify the index, which it+    always should have.+  * Updated to recent parameterized-utils hackage release, which fixes the build+    failures in the previous bv-sized release.+ ## 0.6.0 *March 2019*-* changed WithRepr functions to '-* added Num, Bits instances-* bitVector now takes arbitrary Integral argument-* add 'bitLayoutAssignmentList' function (see haddocks for details-* Hid BV constructor, exposed BitVector as pattern+  * changed WithRepr functions to '+  * added Num, Bits instances+  * bitVector now takes arbitrary Integral argument+  * add 'bitLayoutAssignmentList' function (see haddocks for details+  * Hid BV constructor, exposed BitVector as pattern  ## 0.5.1 *August 2018*   * fixed github URL
src/Data/BitVector/Sized/App.hs view
@@ -33,9 +33,9 @@   ( BVApp(..)   , evalBVApp   , evalBVAppM+  , bvAppWidth   -- * Smart constructors   , BVExpr(..)-  , litBV   -- ** Bitwise   , andE   , orE@@ -70,7 +70,7 @@  import Control.Monad.Identity import Data.BitVector.Sized-import Data.Bits+-- import Data.Bits import Data.Parameterized import Data.Parameterized.TH.GADT import Foreign.Marshal.Utils (fromBool)@@ -79,31 +79,29 @@ -- | Represents the application of a 'BitVector' operation to one or more -- subexpressions. data BVApp (expr :: Nat -> *) (w :: Nat) where-  -- Literal BitVector-  LitBVApp :: BitVector w -> BVApp expr w    -- Bitwise operations-  AndApp :: !(expr w) -> !(expr w) -> BVApp expr w-  OrApp  :: !(expr w) -> !(expr w) -> BVApp expr w-  XorApp :: !(expr w) -> !(expr w) -> BVApp expr w-  NotApp :: !(expr w) -> BVApp expr w+  AndApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  OrApp  :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  XorApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  NotApp :: !(NatRepr w) -> !(expr w) -> BVApp expr w    -- Shifts-  SllApp :: !(expr w) -> !(expr w) -> BVApp expr w-  SrlApp :: !(expr w) -> !(expr w) -> BVApp expr w-  SraApp :: !(expr w) -> !(expr w) -> BVApp expr w+  SllApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  SrlApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  SraApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w    -- Arithmetic operations-  AddApp   :: !(expr w) -> !(expr w) -> BVApp expr w-  SubApp   :: !(expr w) -> !(expr w) -> BVApp expr w-  MulApp   :: !(expr w) -> !(expr w) -> BVApp expr w-  QuotUApp :: !(expr w) -> !(expr w) -> BVApp expr w-  QuotSApp :: !(expr w) -> !(expr w) -> BVApp expr w-  RemUApp  :: !(expr w) -> !(expr w) -> BVApp expr w-  RemSApp  :: !(expr w) -> !(expr w) -> BVApp expr w-  NegateApp :: !(expr w) -> BVApp expr w-  AbsApp   :: !(expr w) -> BVApp expr w-  SignumApp :: !(expr w) -> BVApp expr w+  AddApp   :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  SubApp   :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  MulApp   :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  QuotUApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  QuotSApp :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  RemUApp  :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  RemSApp  :: !(NatRepr w) -> !(expr w) -> !(expr w) -> BVApp expr w+  NegateApp :: !(NatRepr w) -> !(expr w) -> BVApp expr w+  AbsApp   :: !(NatRepr w) -> !(expr w) -> BVApp expr w+  SignumApp :: !(NatRepr w) -> !(expr w) -> BVApp expr w    -- Comparisons   EqApp  :: !(expr w) -> !(expr w) -> BVApp expr 1@@ -113,12 +111,44 @@   -- Width-changing   ZExtApp    :: NatRepr w' -> !(expr w) -> BVApp expr w'   SExtApp    :: NatRepr w' -> !(expr w) -> BVApp expr w'-  ExtractApp :: NatRepr w' -> Int -> !(expr w) -> BVApp expr w'-  ConcatApp  :: !(expr w) -> !(expr w') -> BVApp expr (w+w')+  ExtractApp :: NatRepr w' -> NatRepr ix -> !(expr w) -> BVApp expr w'+  ConcatApp  :: !(NatRepr (w+w')) -> !(expr w) -> !(expr w') -> BVApp expr (w+w')    -- Other operations-  IteApp :: !(expr 1) -> !(expr w) -> !(expr w) -> BVApp expr w+  IteApp :: !(NatRepr w) -> !(expr 1) -> !(expr w) -> !(expr w) -> BVApp expr w +bvAppWidth :: BVApp expr w -> NatRepr w+bvAppWidth (AndApp wRepr _ _) = wRepr+bvAppWidth (OrApp wRepr _ _) = wRepr+bvAppWidth (XorApp wRepr _ _) = wRepr+bvAppWidth (NotApp wRepr _) = wRepr++bvAppWidth (SllApp wRepr _ _) = wRepr+bvAppWidth (SrlApp wRepr _ _) = wRepr+bvAppWidth (SraApp wRepr _ _) = wRepr++bvAppWidth (AddApp wRepr _ _) = wRepr+bvAppWidth (SubApp wRepr _ _) = wRepr+bvAppWidth (MulApp wRepr _ _) = wRepr+bvAppWidth (QuotUApp wRepr _ _) = wRepr+bvAppWidth (QuotSApp wRepr _ _) = wRepr+bvAppWidth (RemUApp wRepr _ _) = wRepr+bvAppWidth (RemSApp wRepr _ _) = wRepr+bvAppWidth (NegateApp wRepr _) = wRepr+bvAppWidth (AbsApp wRepr _) = wRepr+bvAppWidth (SignumApp wRepr _) = wRepr++bvAppWidth (EqApp _ _) = knownNat+bvAppWidth (LtuApp _ _) = knownNat+bvAppWidth (LtsApp _ _) = knownNat++bvAppWidth (ZExtApp wRepr _) = wRepr+bvAppWidth (SExtApp wRepr _) = wRepr+bvAppWidth (ExtractApp wRepr _ _) = wRepr+bvAppWidth (ConcatApp wRepr _ _) = wRepr++bvAppWidth (IteApp wRepr _ _ _) = wRepr+ $(return [])  instance TestEquality expr => TestEquality (BVApp expr) where@@ -156,35 +186,35 @@            => (forall w' . expr w' -> m (BitVector w')) -- ^ expression evaluator            -> BVApp expr w                              -- ^ application            -> m (BitVector w)-evalBVAppM _ (LitBVApp bv) = return bv-evalBVAppM eval (AndApp e1 e2) = bvAnd <$> eval e1 <*> eval e2-evalBVAppM eval (OrApp  e1 e2) = bvOr  <$> eval e1 <*> eval e2-evalBVAppM eval (XorApp e1 e2) = bvXor <$> eval e1 <*> eval e2-evalBVAppM eval (NotApp e)     = bvComplement <$> eval e-evalBVAppM eval (AddApp e1 e2) = bvAdd <$> eval e1 <*> eval e2-evalBVAppM eval (SubApp e1 e2) = bvAdd <$> eval e1 <*> (bvNegate <$> eval e2)-evalBVAppM eval (SllApp e1 e2) = bvShiftL  <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)-evalBVAppM eval (SrlApp e1 e2) = bvShiftRL <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)-evalBVAppM eval (SraApp e1 e2) = bvShiftRA <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)-evalBVAppM eval (MulApp e1 e2) = bvMul <$> eval e1 <*> eval e2-evalBVAppM eval (QuotSApp e1 e2) = bvQuotS  <$> eval e1 <*> eval e2-evalBVAppM eval (QuotUApp e1 e2) = bvQuotU  <$> eval e1 <*> eval e2-evalBVAppM eval (RemSApp  e1 e2) = bvRemS   <$> eval e1 <*> eval e2-evalBVAppM eval (RemUApp  e1 e2) = bvRemU   <$> eval e1 <*> eval e2-evalBVAppM eval (NegateApp e) = bvNegate <$> eval e-evalBVAppM eval (AbsApp e) = bvAbs <$> eval e-evalBVAppM eval (SignumApp e) = bvSignum <$> eval e+evalBVAppM eval (AndApp _ e1 e2) = bvAnd <$> eval e1 <*> eval e2+evalBVAppM eval (OrApp  _ e1 e2) = bvOr  <$> eval e1 <*> eval e2+evalBVAppM eval (XorApp _ e1 e2) = bvXor <$> eval e1 <*> eval e2+evalBVAppM eval (NotApp _ e)     = bvComplement <$> eval e+evalBVAppM eval (AddApp _ e1 e2) = bvAdd <$> eval e1 <*> eval e2+evalBVAppM eval (SubApp _ e1 e2) = bvAdd <$> eval e1 <*> (bvNegate <$> eval e2)+evalBVAppM eval (SllApp _ e1 e2) = bvShiftL  <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)+evalBVAppM eval (SrlApp _ e1 e2) = bvShiftRL <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)+evalBVAppM eval (SraApp _ e1 e2) = bvShiftRA <$> eval e1 <*> (fromIntegral . bvIntegerU <$> eval e2)+evalBVAppM eval (MulApp _ e1 e2) = bvMul <$> eval e1 <*> eval e2+evalBVAppM eval (QuotSApp _ e1 e2) = bvQuotS  <$> eval e1 <*> eval e2+evalBVAppM eval (QuotUApp _ e1 e2) = bvQuotU  <$> eval e1 <*> eval e2+evalBVAppM eval (RemSApp  _ e1 e2) = bvRemS   <$> eval e1 <*> eval e2+evalBVAppM eval (RemUApp  _ e1 e2) = bvRemU   <$> eval e1 <*> eval e2+evalBVAppM eval (NegateApp _ e) = bvNegate <$> eval e+evalBVAppM eval (AbsApp _ e) = bvAbs <$> eval e+evalBVAppM eval (SignumApp _ e) = bvSignum <$> eval e evalBVAppM eval (EqApp  e1 e2) = fromBool <$> ((==)  <$> eval e1 <*> eval e2) evalBVAppM eval (LtuApp e1 e2) = fromBool <$> (bvLTU <$> eval e1 <*> eval e2) evalBVAppM eval (LtsApp e1 e2) = fromBool <$> (bvLTS <$> eval e1 <*> eval e2) evalBVAppM eval (ZExtApp wRepr e) = bvZext' wRepr <$> eval e evalBVAppM eval (SExtApp wRepr e) = bvSext' wRepr <$> eval e-evalBVAppM eval (ExtractApp wRepr base e) = bvExtract' wRepr base <$> eval e-evalBVAppM eval (ConcatApp e1 e2) = do+evalBVAppM eval (ExtractApp wRepr ixRepr e) =+  bvExtract' wRepr (fromIntegral $ intValue ixRepr) <$> eval e+evalBVAppM eval (ConcatApp _ e1 e2) = do   e1Val <- eval e1   e2Val <- eval e2   return $ e1Val `bvConcat` e2Val-evalBVAppM eval (IteApp eTest eT eF) = do+evalBVAppM eval (IteApp _ eTest eT eF) = do   testVal <- eval eTest   case testVal of     1 -> eval eT@@ -198,102 +228,101 @@  -- | Typeclass for embedding 'BVApp' constructors into larger expression types. class BVExpr (expr :: Nat -> *) where+  litBV :: BitVector w -> expr w+  exprWidth :: expr w -> NatRepr w   appExpr :: BVApp expr w -> expr w -instance (KnownNat w, BVExpr expr) => Num (BVApp expr w) where-  app1 + app2 = AddApp (appExpr app1) (appExpr app2)-  app1 * app2 = MulApp (appExpr app1) (appExpr app2)-  abs app = AbsApp (appExpr app)-  signum app = SignumApp (appExpr app)-  fromInteger x = LitBVApp (fromInteger x)-  negate app = NegateApp (appExpr app)-  app1 - app2 = SubApp (appExpr app1) (appExpr app2)---- TODO: finish-instance (KnownNat w, BVExpr expr, TestEquality expr) => Bits (BVApp expr w) where-  app1 .&. app2 = AndApp (appExpr app1) (appExpr app2)-  app1 .|. app2 = OrApp (appExpr app1) (appExpr app2)-  app1 `xor` app2 = XorApp (appExpr app1) (appExpr app2)-  complement app = NotApp (appExpr app)-  shiftL app x = SllApp (appExpr app) (litBV (bitVector x))-  shiftR app x = SraApp (appExpr app) (litBV (bitVector x))-  rotate = undefined-  bitSize = undefined-  bitSizeMaybe = undefined-  isSigned = undefined-  testBit = undefined-  bit = undefined-  popCount = undefined+-- -- TODO: finish+-- instance (BVExpr expr) => Num (BVApp expr w) where+--   app1 + app2 = AddApp (appExpr app1) (appExpr app2)+--   app1 * app2 = MulApp (appExpr app1) (appExpr app2)+--   abs app = AbsApp (appExpr app)+--   signum app = SignumApp (appExpr app)+--   fromInteger = undefined+--   negate app = NegateApp (appExpr app)+--   app1 - app2 = SubApp (appExpr app1) (appExpr app2) --- | Literal bit vector.-litBV :: BVExpr expr => BitVector w -> expr w-litBV = appExpr . LitBVApp+-- -- TODO: finish+-- instance (KnownNat w, BVExpr expr, TestEquality expr) => Bits (BVApp expr w) where+--   app1 .&. app2 = AndApp (appExpr app1) (appExpr app2)+--   app1 .|. app2 = OrApp (appExpr app1) (appExpr app2)+--   app1 `xor` app2 = XorApp (appExpr app1) (appExpr app2)+--   complement app = NotApp (appExpr app)+--   shiftL = undefined+--   shiftR = undefined+--   rotate = undefined+--   bitSize = undefined+--   bitSizeMaybe = undefined+--   isSigned = undefined+--   testBit = undefined+--   bit = undefined+--   popCount = undefined  -- | Bitwise and. andE :: BVExpr expr => expr w -> expr w -> expr w-andE e1 e2 = appExpr (AndApp e1 e2)+andE e1 e2 = appExpr (AndApp (exprWidth e1) e1 e2)  -- | Bitwise or. orE :: BVExpr expr => expr w -> expr w -> expr w-orE e1 e2 = appExpr (OrApp e1 e2)+orE e1 e2 = appExpr (OrApp (exprWidth e1) e1 e2)  -- | Bitwise xor. xorE :: BVExpr expr => expr w -> expr w -> expr w-xorE e1 e2 = appExpr (XorApp e1 e2)+xorE e1 e2 = appExpr (XorApp (exprWidth e1) e1 e2)  -- | Bitwise not. notE :: BVExpr expr => expr w -> expr w-notE e = appExpr (NotApp e)+notE e = appExpr (NotApp (exprWidth e) e)  -- | Add two expressions. addE :: BVExpr expr => expr w -> expr w -> expr w-addE e1 e2 = appExpr (AddApp e1 e2)+addE e1 e2 = appExpr (AddApp (exprWidth e1) e1 e2)  -- | Subtract the second expression from the first. subE :: BVExpr expr => expr w -> expr w -> expr w-subE e1 e2 = appExpr (SubApp e1 e2)+subE e1 e2 = appExpr (SubApp (exprWidth e1) e1 e2)  -- | Signed multiply two 'BitVector's, doubling the width of the result to hold all -- arithmetic overflow bits. mulE :: BVExpr expr => expr w -> expr w -> expr w-mulE e1 e2 = appExpr (MulApp e1 e2)+mulE e1 e2 = appExpr (MulApp (exprWidth e1) e1 e2)  -- | Signed divide two 'BitVector's, rounding to zero. quotsE :: BVExpr expr => expr w -> expr w -> expr w-quotsE e1 e2 = appExpr (QuotSApp e1 e2)+quotsE e1 e2 = appExpr (QuotSApp (exprWidth e1) e1 e2)  -- | Unsigned divide two 'BitVector's, rounding to zero. quotuE :: BVExpr expr => expr w -> expr w -> expr w-quotuE e1 e2 = appExpr (QuotUApp e1 e2)+quotuE e1 e2 = appExpr (QuotUApp (exprWidth e1) e1 e2)  -- | Remainder after signed division of two 'BitVector's, when rounded to zero. remsE :: BVExpr expr => expr w -> expr w -> expr w-remsE e1 e2 = appExpr (RemSApp e1 e2)+remsE e1 e2 = appExpr (RemSApp (exprWidth e1) e1 e2)  -- | Remainder after unsigned division of two 'BitVector's, when rounded to zero. remuE :: BVExpr expr => expr w -> expr w -> expr w-remuE e1 e2 = appExpr (RemUApp e1 e2)+remuE e1 e2 = appExpr (RemUApp (exprWidth e1) e1 e2)  negateE :: BVExpr expr => expr w -> expr w-negateE e = appExpr (NegateApp e)+negateE e = appExpr (NegateApp (exprWidth e) e)  absE :: BVExpr expr => expr w -> expr w-absE e = appExpr (AbsApp e)+absE e = appExpr (AbsApp (exprWidth e) e)  signumE :: BVExpr expr => expr w -> expr w-signumE e = appExpr (SignumApp e)+signumE e = appExpr (SignumApp (exprWidth e) e)  -- | Left logical shift the first expression by the second. sllE :: BVExpr expr => expr w -> expr w -> expr w-sllE e1 e2 = appExpr (SllApp e1 e2)+sllE e1 e2 = appExpr (SllApp (exprWidth e1) e1 e2)  -- | Left logical shift the first expression by the second. srlE :: BVExpr expr => expr w -> expr w -> expr w-srlE e1 e2 = appExpr (SrlApp e1 e2)+srlE e1 e2 = appExpr (SrlApp (exprWidth e1) e1 e2)  -- | Left logical shift the first expression by the second. sraE :: BVExpr expr => expr w -> expr w -> expr w-sraE e1 e2 = appExpr (SraApp e1 e2)+sraE e1 e2 = appExpr (SraApp (exprWidth e1) e1 e2)  -- | Test for equality of two expressions. eqE :: BVExpr expr => expr w -> expr w -> expr 1@@ -324,17 +353,17 @@ sextE' repr e = appExpr (SExtApp repr e)  -- | Extract bits-extractE :: (BVExpr expr, KnownNat w') => Int -> expr w -> expr w'-extractE base e = appExpr (ExtractApp knownNat base e)+extractE :: (BVExpr expr, KnownNat w') => NatRepr ix -> expr w -> expr w'+extractE ixRepr e = appExpr (ExtractApp knownNat ixRepr e)  -- | Extract bits with an explicit width argument-extractE' :: BVExpr expr => NatRepr w' -> Int -> expr w -> expr w'-extractE' wRepr base e = appExpr (ExtractApp wRepr base e)+extractE' :: BVExpr expr => NatRepr w' -> NatRepr ix -> expr w -> expr w'+extractE' wRepr ixRepr e = appExpr (ExtractApp wRepr ixRepr e)  -- | Concatenation concatE :: BVExpr expr => expr w -> expr w' -> expr (w+w')-concatE e1 e2 = appExpr (ConcatApp e1 e2)+concatE e1 e2 = appExpr (ConcatApp (exprWidth e1 `addNat` exprWidth e2) e1 e2)  -- | Conditional branch. iteE :: BVExpr expr => expr 1 -> expr w -> expr w -> expr w-iteE t e1 e2 = appExpr (IteApp t e1 e2)+iteE t e1 e2 = appExpr (IteApp (exprWidth e1) t e1 e2)
src/Data/BitVector/Sized/Internal.hs view
@@ -411,8 +411,9 @@  prettyHex :: (Integral a, PrintfArg a, Show a) => a -> Integer -> String prettyHex width val = printf format val width-  where numDigits = (width+3) `quot` 4-        format = "0x%." ++ show numDigits ++ "x<%d>"+  where -- numDigits = (width+3) `quot` 4+        -- format = "0x%." ++ show numDigits ++ "x<%d>"+        format = "0x%x<%d>"  instance Pretty (BitVector w) where   -- | Pretty print a bit vector (shows its width)
− submodules/parameterized-utils/.git
@@ -1,1 +0,0 @@-gitdir: ../../.git/modules/submodules/parameterized-utils
− submodules/parameterized-utils/.gitignore
@@ -1,23 +0,0 @@-/build/-/dependencies/-/dependencies-.cabal-sandbox-.stack-work-**/cabal.config-cabal.sandbox.config-dist-TAGS-unitTest.tix-hpc_report-stack.yaml-/dist-newstyle-.*.swp-.vagrant-graphmod-.hlint.yaml-cabal.project.local-dist-newstyle/-.boring-_darcs/-.cmd_history-*~
− submodules/parameterized-utils/.travis.yml
@@ -1,103 +0,0 @@-# This Travis job script has been generated by a script via-#-#   runghc make_travis_yml_2.hs 'parameterized-utils.cabal'-#-# For more information, see https://github.com/haskell-CI/haskell-ci-#-language: c-sudo: false--git:-  submodules: false  # whether to recursively clone submodules--cache:-  directories:-    - $HOME/.cabal/packages-    - $HOME/.cabal/store--before_cache:-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log-  # remove files that are regenerated by 'cabal update'-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx--  - rm -rfv $HOME/.cabal/packages/head.hackage--matrix:-  include:-    - compiler: "ghc-8.4.3"-    # env: TEST=--disable-tests BENCH=--disable-benchmarks-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}--before_install:-  - HC=${CC}-  - HCPKG=${HC/ghc/ghc-pkg}-  - unset CC-  - ROOTDIR=$(pwd)-  - mkdir -p $HOME/.local/bin-  - "PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$HOME/local/bin:$PATH"-  - HCNUMVER=$(( $(${HC} --numeric-version|sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 * 10000 + \2 * 100 + \3/') ))-  - echo $HCNUMVER--install:-  - cabal --version-  - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"-  - BENCH=${BENCH---enable-benchmarks}-  - TEST=${TEST---enable-tests}-  - HADDOCK=${HADDOCK-true}-  - UNCONSTRAINED=${UNCONSTRAINED-true}-  - NOINSTALLEDCONSTRAINTS=${NOINSTALLEDCONSTRAINTS-false}-  - GHCHEAD=${GHCHEAD-false}-  - travis_retry cabal update -v-  - "sed -i.bak 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config"-  - rm -fv cabal.project cabal.project.local-  - grep -Ev -- '^\s*--' ${HOME}/.cabal/config | grep -Ev '^\s*$'-  - "printf 'packages: \".\"\\n' > cabal.project"-  - touch cabal.project.local-  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg  | grep -vw -- parameterized-utils | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"-  - cat cabal.project || true-  - cat cabal.project.local || true-  - if [ -f "./configure.ac" ]; then-      (cd "." && autoreconf -i);-    fi-  - rm -f cabal.project.freeze-  - cabal new-build -w ${HC} ${TEST} ${BENCH} --project-file="cabal.project" --dep -j2 all-  - cabal new-build -w ${HC} --disable-tests --disable-benchmarks --project-file="cabal.project" --dep -j2 all-  - rm -rf .ghc.environment.* "."/dist-  - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)--# Here starts the actual work to be performed for the package under test;-# any command which exits with a non-zero exit code causes the build to fail.-script:-  # test that source-distributions can be generated-  - (cd "." && cabal sdist)-  - mv "."/dist/parameterized-utils-*.tar.gz ${DISTDIR}/-  - cd ${DISTDIR} || false-  - find . -maxdepth 1 -name '*.tar.gz' -exec tar -xvf '{}' \;-  - "printf 'packages: parameterized-utils-*/*.cabal\\n' > cabal.project"-  - touch cabal.project.local-  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg  | grep -vw -- parameterized-utils | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"-  - cat cabal.project || true-  - cat cabal.project.local || true-  # this builds all libraries and executables (without tests/benchmarks)-  - cabal new-build -w ${HC} --disable-tests --disable-benchmarks all--  # build & run tests, build benchmarks-  - cabal new-build -w ${HC} ${TEST} ${BENCH} all-  - if [ "x$TEST" = "x--enable-tests" ]; then cabal new-test -w ${HC} ${TEST} ${BENCH} all; fi--  # cabal check-  - (cd parameterized-utils-* && cabal check)--  # haddock-  - rm -rf ./dist-newstyle-  - if $HADDOCK; then cabal new-haddock -w ${HC} ${TEST} ${BENCH} all; else echo "Skipping haddock generation";fi--  # Build without installed constraints for packages in global-db-  - if $UNCONSTRAINED; then rm -f cabal.project.local; echo cabal new-build -w ${HC} --disable-tests --disable-benchmarks all; else echo "Not building without installed constraints"; fi--# REGENDATA ["parameterized-utils.cabal"]-# EOF
− submodules/parameterized-utils/LICENSE
@@ -1,30 +0,0 @@-Copyright (c) 2013-2016 Galois Inc.-All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions-are met:--  * Redistributions of source code must retain the above copyright-    notice, this list of conditions and the following disclaimer.--  * Redistributions in binary form must reproduce the above copyright-    notice, this list of conditions and the following disclaimer in-    the documentation and/or other materials provided with the-    distribution.--  * Neither the name of Galois, Inc. nor the names of its contributors-    may be used to endorse or promote products derived from this-    software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
− submodules/parameterized-utils/README.md
@@ -1,7 +0,0 @@-The parameterized-utils module contains a collection of typeclasses-and datatypes for working with parameterized types, that is types that-have a type argument.  One example would be a algebraic data type-for expressions, that use a type parameter to describe the type of the-expression.--This packaged provides collections classes for these parameterized types.
− submodules/parameterized-utils/parameterized-utils.cabal
@@ -1,109 +0,0 @@-Name:          parameterized-utils-Version:       1.0.8-Author:        Galois Inc.-Maintainer:    jhendrix@galois.com-Build-type:    Simple-Cabal-version: >= 1.9.2-license: BSD3-license-file: LICENSE-category: Data Structures, Dependent Types-Synopsis: Classes and data structures for working with data-kind indexed types-Description:-  This packages contains collection classes and type representations-  used for working with values that have a single parameter.  It's-  intended for things like expression libraries where one wishes-  to leverage the Haskell type-checker to improve type-safety by encoding-  the object language type system into data kinds.-tested-with: GHC==8.4.3, GHC==8.6.1---- Many (but not all, sadly) uses of unsafe operations are--- controlled by this compile flag.  When this flag is set--- to False, alternate implementations are used to avoid--- Unsafe.Coerce and Data.Coerce.  These alternate implementations--- impose a significant performance hit.-flag unsafe-operations-  Description: Use unsafe operations to improve performance-  Default: True--source-repository head-  type: git-  location: https://github.com/GaloisInc/parameterized-utils--library-  build-depends:-    base >= 4.7 && < 4.13,-    th-abstraction >=0.1 && <0.3,-    constraints >= 0.10 && < 0.11,-    containers,-    deepseq,-    ghc-prim,-    hashable,-    hashtables,-    lens,-    mtl,-    template-haskell,-    text,-    vector--  hs-source-dirs: src--  exposed-modules:-    Data.Parameterized-    Data.Parameterized.Classes-    Data.Parameterized.ClassesC-    Data.Parameterized.Compose-    Data.Parameterized.Context-    Data.Parameterized.Context.Safe-    Data.Parameterized.Context.Unsafe-    Data.Parameterized.Ctx-    Data.Parameterized.Ctx.Proofs-    Data.Parameterized.DecidableEq-    Data.Parameterized.HashTable-    Data.Parameterized.List-    Data.Parameterized.Map-    Data.Parameterized.NatRepr-    Data.Parameterized.Nonce-    Data.Parameterized.Nonce.Transformers-    Data.Parameterized.Nonce.Unsafe-    Data.Parameterized.Pair-    Data.Parameterized.Peano-    Data.Parameterized.Some-    Data.Parameterized.SymbolRepr-    Data.Parameterized.TH.GADT-    Data.Parameterized.TraversableF-    Data.Parameterized.TraversableFC-    Data.Parameterized.Utils.BinTree-    Data.Parameterized.Utils.Endian-    Data.Parameterized.Vector--  ghc-options: -Wall--  if flag(unsafe-operations)-    cpp-options: -DUNSAFE_OPS---test-suite parameterizedTests-  type: exitcode-stdio-1.0-  hs-source-dirs: test--  ghc-options: -Wall--  main-is:UnitTest.hs-  other-modules:-    Test.Context-    Test.NatRepr-    Test.Vector--  build-depends:-    base,-    hashable,-    hashtables,-    ghc-prim,-    lens,-    mtl,-    parameterized-utils,-    tasty,-    tasty-ant-xml >= 1.1.0,-    tasty-hunit,-    tasty-quickcheck >= 0.8.1,-    QuickCheck >= 2.7
− submodules/parameterized-utils/src/Data/Parameterized.hs
@@ -1,19 +0,0 @@-module Data.Parameterized-( module Data.Parameterized.Classes       -, module Data.Parameterized.Ctx           -, module Data.Parameterized.TraversableF  -, module Data.Parameterized.TraversableFC -, module Data.Parameterized.NatRepr       -, module Data.Parameterized.Pair          -, module Data.Parameterized.Some          -, module Data.Parameterized.SymbolRepr    -) where--import Data.Parameterized.Classes-import Data.Parameterized.Ctx-import Data.Parameterized.TraversableF-import Data.Parameterized.TraversableFC-import Data.Parameterized.NatRepr-import Data.Parameterized.Pair-import Data.Parameterized.Some-import Data.Parameterized.SymbolRepr    
− submodules/parameterized-utils/src/Data/Parameterized/Classes.hs
@@ -1,307 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2015-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This module declares classes for working with types with the kind-@k -> *@ for any kind @k@.  These are generalizations of the-"Data.Functor.Classes" types as they work with any kind @k@, and are-not restricted to '*'.--}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-#if MIN_VERSION_base(4,9,0)-{-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif-module Data.Parameterized.Classes-  ( -- * Equality exports-    Equality.TestEquality(..)-  , (Equality.:~:)(..)-  , EqF(..)-  , PolyEq(..)-    -- * Ordering generalization-  , OrdF(..)-  , lexCompareF-  , OrderingF(..)-  , joinOrderingF-  , orderingF_refl-  , toOrdering-  , fromOrdering-  , ordFCompose-    -- * Typeclass generalizations-  , ShowF(..)-  , showsF-  , HashableF(..)-  , CoercibleF(..)-    -- * Optics generalizations-  , IndexF-  , IxValueF-  , IxedF(..)-  , IxedF'(..)-  , AtF(..)-    -- * KnownRepr-  , KnownRepr(..)-    -- * Re-exports-  , Data.Maybe.isJust-  ) where--import Data.Functor.Const-import Data.Functor.Compose (Compose(..))-import Data.Hashable-import Data.Maybe (isJust)-import Data.Proxy-import Data.Type.Equality as Equality--import Data.Parameterized.Compose ()---- We define these type alias here to avoid importing Control.Lens--- modules, as this apparently causes problems with the safe Hasekll--- checking.-type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s-type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s----------------------------------------------------------------------------- CoercibleF---- | An instance of 'CoercibleF' gives a way to coerce between---   all the types of a family.  We generally use this to witness---   the fact that the type parameter to @rtp@ is a phantom type---   by giving an implementation in terms of Data.Coerce.coerce.-class CoercibleF (rtp :: k -> *) where-  coerceF :: rtp a -> rtp b--instance CoercibleF (Const x) where-  coerceF (Const x) = Const x----------------------------------------------------------------------------- EqF---- | @EqF@ provides a method @eqF@ for testing whether two parameterized--- types are equal.------ Unlike 'TestEquality', this only works when the type arguments are--- the same, and does not provide a proof that the types have the same--- type when they are equal. Thus this can be implemented over--- parameterized types that are unable to provide evidence that their--- type arguments are equal.-class EqF (f :: k -> *) where-  eqF :: f a -> f a -> Bool--instance Eq a => EqF (Const a) where-  eqF (Const x) (Const y) = x == y----------------------------------------------------------------------------- PolyEq---- | A polymorphic equality operator that generalizes 'TestEquality'.-class PolyEq u v where-  polyEqF :: u -> v -> Maybe (u :~: v)--  polyEq :: u -> v -> Bool-  polyEq x y = isJust (polyEqF x y)----------------------------------------------------------------------------- Ordering---- | Ordering over two distinct types with a proof they are equal.-data OrderingF x y where-  LTF :: OrderingF x y-  EQF :: OrderingF x x-  GTF :: OrderingF x y--orderingF_refl :: OrderingF x y -> Maybe (x :~: y)-orderingF_refl o =-  case o of-    LTF -> Nothing-    EQF -> Just Refl-    GTF -> Nothing---- | Convert 'OrderingF' to standard ordering.-toOrdering :: OrderingF x y -> Ordering-toOrdering LTF = LT-toOrdering EQF = EQ-toOrdering GTF = GT---- | Convert standard ordering to 'OrderingF'.-fromOrdering :: Ordering -> OrderingF x x-fromOrdering LT = LTF-fromOrdering EQ = EQF-fromOrdering GT = GTF---- | `joinOrderingF x y` first compares on x, returning an equivalent--- value if it is not `EQF`.  If it is EQF, it returns `y`.-joinOrderingF :: forall (a :: j) (b :: j) (c :: k) (d :: k)-              .  OrderingF a b-              -> (a ~ b => OrderingF c d)-              -> OrderingF c d-joinOrderingF EQF y = y-joinOrderingF LTF _ = LTF-joinOrderingF GTF _ = GTF----------------------------------------------------------------------------- OrdF---- | A parameterized type that can be compared on distinct instances.-class TestEquality ktp => OrdF (ktp :: k -> *) where-  {-# MINIMAL compareF #-}--  -- | compareF compares two keys with different type parameters.-  -- Instances must ensure that keys are only equal if the type-  -- parameters are equal.-  compareF :: ktp x -> ktp y -> OrderingF x y--  leqF :: ktp x -> ktp y -> Bool-  leqF x y =-    case compareF x y of-      LTF -> True-      EQF -> True-      GTF -> False--  ltF :: ktp x -> ktp y -> Bool-  ltF x y =-    case compareF x y of-      LTF -> True-      EQF -> False-      GTF -> False--  geqF :: ktp x -> ktp y -> Bool-  geqF x y =-    case compareF x y of-      LTF -> False-      EQF -> True-      GTF -> True--  gtF :: ktp x -> ktp y -> Bool-  gtF x y =-    case compareF x y of-      LTF -> False-      EQF -> False-      GTF -> True---- | Compare two values, and if they are equal compare the next values,--- otherwise return LTF or GTF-lexCompareF :: forall (f :: j -> *) (a :: j) (b :: j) (c :: k) (d :: k)-             .  OrdF f-            => f a-            -> f b-            -> (a ~ b => OrderingF c d)-            -> OrderingF c d-lexCompareF x y = joinOrderingF (compareF x y)---- | If the \"outer\" functor has an 'OrdF' instance, then one can be generated--- for the \"inner\" functor. The type-level evidence of equality is deduced--- via generativity of @g@, e.g. the inference @g x ~ g y@ implies @x ~ y@.-ordFCompose :: forall (f :: k -> *) (g :: l -> k) x y.-                (forall w z. f w -> f z -> OrderingF w z)-            -> Compose f g x-            -> Compose f g y-            -> OrderingF x y-ordFCompose ordF_ (Compose x) (Compose y) =-  case ordF_ x y of-    LTF -> LTF-    GTF -> GTF-    EQF -> EQF--instance OrdF f => OrdF (Compose f g) where-  compareF x y = ordFCompose compareF x y----------------------------------------------------------------------------- ShowF---- | A parameterized type that can be shown on all instances.------ To implement @'ShowF' g@, one should implement an instance @'Show'--- (g tp)@ for all argument types @tp@, then write an empty instance--- @instance 'ShowF' g@.-class ShowF (f :: k -> *) where-  -- | Provides a show instance for each type.-  withShow :: p f -> q tp -> (Show (f tp) => a) -> a--  default withShow :: Show (f tp) => p f -> q tp -> (Show (f tp) => a) -> a-  withShow _ _ x = x--  showF :: forall tp . f tp -> String-  showF x = withShow (Proxy :: Proxy f) (Proxy :: Proxy tp) (show x)--  -- | Like 'showsPrec', the precedence argument is /one more/ than the-  -- precedence of the enclosing context.-  showsPrecF :: forall tp. Int -> f tp -> String -> String-  showsPrecF p x = withShow (Proxy :: Proxy f) (Proxy :: Proxy tp) (showsPrec p x)--showsF :: ShowF f => f tp -> String -> String-showsF x = showsPrecF 0 x--instance Show x => ShowF (Const x)----------------------------------------------------------------------------- IxedF--type family IndexF       (m :: *) :: k -> *-type family IxValueF     (m :: *) :: k -> *---- | Parameterized generalization of the lens @Ixed@ class.-class IxedF k m where-  -- | Given an index into a container, build a traversal that visits-  --   the given element in the container, if it exists.-  ixF :: forall (x :: k). IndexF m x -> Traversal' m (IxValueF m x)---- | Parameterized generalization of the lens @Ixed@ class,---   but with the guarantee that indexes exist in the container.-class IxedF k m => IxedF' k m where-  -- | Given an index into a container, build a lens that-  --   points into the given element in the container.-  ixF' :: forall (x :: k). IndexF m x -> Lens' m (IxValueF m x)----------------------------------------------------------------------------- AtF---- | Parameterized generalization of the lens @At@ class.-class IxedF k m => AtF k m where-  -- | Given an index into a container, build a lens that points into-  --   the given position in the container, whether or not it currently-  --   exists.  Setting values of @atF@ to a @Just@ value will insert-  --   the value if it does not already exist.-  atF :: forall (x :: k). IndexF m x -> Lens' m (Maybe (IxValueF m x))----------------------------------------------------------------------------- HashableF---- | A default salt used in the implementation of 'hash'.-defaultSalt :: Int-#if WORD_SIZE_IN_BITS == 64-defaultSalt = 0xdc36d1615b7400a4-#else-defaultSalt = 0x087fc72c-#endif-{-# INLINE defaultSalt #-}---- | A parameterized type that is hashable on all instances.-class HashableF (f :: k -> *) where-  hashWithSaltF :: Int -> f tp -> Int--  -- | Hash with default salt.-  hashF :: f tp -> Int-  hashF = hashWithSaltF defaultSalt--instance Hashable a => HashableF (Const a) where-  hashWithSaltF s (Const x) = hashWithSalt s x----------------------------------------------------------------------------- KnownRepr---- | This class is parameterized by a kind @k@ (typically a data--- kind), a type constructor @f@ of kind @k -> *@ (typically a GADT of--- singleton types indexed by @k@), and an index parameter @ctx@ of--- kind @k@.-class KnownRepr (f :: k -> *) (ctx :: k) where-  knownRepr :: f ctx
− submodules/parameterized-utils/src/Data/Parameterized/ClassesC.hs
@@ -1,52 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2015-Maintainer       : Langston Barrett <langston@galois.com>--This module declares classes for working with types with the kind-@(k -> *) -> *@ for any kind @k@.--These classes generally require type-level evidence for operations-on their subterms, but don't actually provide it themselves (because-their types are not themselves parameterized, unlike those in-"Data.Parameterized.TraverableFC").--Note that there is still some ambiguity around naming conventions, see-<https://github.com/GaloisInc/parameterized-utils/issues/23 issue 23>.--}--{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE Safe #-}-{-# LANGUAGE TypeOperators #-}--module Data.Parameterized.ClassesC-  ( TestEqualityC(..)-  , OrdC(..)-  ) where--import Data.Type.Equality ((:~:)(..))-import Data.Maybe (isJust)-import Data.Parameterized.Classes (OrderingF, toOrdering)-import Data.Parameterized.Some (Some(..))--class TestEqualityC (t :: (k -> *) -> *) where-  testEqualityC :: (forall x y. f x -> f y -> Maybe (x :~: y))-                -> t f-                -> t f-                -> Bool--class TestEqualityC t => OrdC (t :: (k -> *) -> *) where-  compareC :: (forall x y. f x -> g y -> OrderingF x y)-           -> t f-           -> t g-           -> Ordering---- | This instance demonstrates where the above class is useful: namely, in--- types with existential quantification.-instance TestEqualityC Some where-  testEqualityC subterms (Some someone) (Some something) =-    isJust (subterms someone something)--instance OrdC Some where-  compareC subterms (Some someone) (Some something) =-    toOrdering (subterms someone something)
− submodules/parameterized-utils/src/Data/Parameterized/Compose.hs
@@ -1,45 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2018-Maintainer       : Langston Barrett <langston@galois.com--Utilities for working with "Data.Functor.Compose".--NB: This module contains an orphan instance. It will be included in GHC 8.10,-see https://gitlab.haskell.org/ghc/ghc/merge_requests/273.--}--{-# LANGUAGE GADTs #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE Safe #-}--module Data.Parameterized.Compose-  ( testEqualityComposeBare-  ) where--import Data.Functor.Compose-import Data.Type.Equality---- | The deduction (via generativity) that if @g x :~: g y@ then @x :~: y@.------ See https://gitlab.haskell.org/ghc/ghc/merge_requests/273.-testEqualityComposeBare :: forall (f :: k -> *) (g :: l -> k) x y.-                           (forall w z. f w -> f z -> Maybe (w :~: z))-                        -> Compose f g x-                        -> Compose f g y-                        -> Maybe (x :~: y)-testEqualityComposeBare testEquality_ (Compose x) (Compose y) =-  case (testEquality_ x y :: Maybe (g x :~: g y)) of-    Just Refl -> Just (Refl :: x :~: y)-    Nothing   -> Nothing--testEqualityCompose :: forall (f :: k -> *) (g :: l -> k) x y. (TestEquality f)-                    => Compose f g x-                    -> Compose f g y-                    -> Maybe (x :~: y)-testEqualityCompose = testEqualityComposeBare testEquality--instance (TestEquality f) => TestEquality (Compose f g) where-  testEquality = testEqualityCompose
− submodules/parameterized-utils/src/Data/Parameterized/Context.hs
@@ -1,463 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.Context--- Copyright        : (c) Galois, Inc 2014-16--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module reexports either "Data.Parameterized.Context.Safe"--- or "Data.Parameterized.Context.Unsafe" depending on the--- the unsafe-operations compile-time flag.------ It also defines some utility typeclasses for transforming--- between curried and uncurried versions of functions over contexts.---------------------------------------------------------------------------{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE ViewPatterns #-}-module Data.Parameterized.Context- (-#ifdef UNSAFE_OPS-    module Data.Parameterized.Context.Unsafe-#else-    module Data.Parameterized.Context.Safe-#endif-  , singleton-  , toVector-  , pattern (:>)-  , pattern Empty-  , decompose-  , Data.Parameterized.Context.null-  , Data.Parameterized.Context.init-  , Data.Parameterized.Context.last-  , Data.Parameterized.Context.view-  , Data.Parameterized.Context.take-  , forIndexM-  , generateSome-  , generateSomeM-  , fromList-  , traverseAndCollect--    -- * Context extension and embedding utilities-  , CtxEmbedding(..)-  , ExtendContext(..)-  , ExtendContext'(..)-  , ApplyEmbedding(..)-  , ApplyEmbedding'(..)-  , identityEmbedding-  , extendEmbeddingRightDiff-  , extendEmbeddingRight-  , extendEmbeddingBoth-  , appendEmbedding-  , ctxeSize-  , ctxeAssignment--    -- * Static indexing and lenses for assignments-  , Idx-  , field-  , natIndex-  , natIndexProxy-    -- * Currying and uncurrying for assignments-  , CurryAssignment-  , CurryAssignmentClass(..)-    -- * Size and Index values-  , size1, size2, size3, size4, size5, size6-  , i1of2, i2of2-  , i1of3, i2of3, i3of3-  , i1of4, i2of4, i3of4, i4of4-  , i1of5, i2of5, i3of5, i4of5, i5of5-  , i1of6, i2of6, i3of6, i4of6, i5of6, i6of6-  ) where--import           Control.Applicative (liftA2)-import           Control.Lens hiding (Index, (:>), Empty)-import qualified Data.Vector as V-import qualified Data.Vector.Mutable as MV-import           GHC.TypeLits (Nat, type (-))-import           Data.Monoid ((<>))--import           Data.Parameterized.Classes-import           Data.Parameterized.Some-import           Data.Parameterized.TraversableFC--#ifdef UNSAFE_OPS-import           Data.Parameterized.Context.Unsafe-#else-import           Data.Parameterized.Context.Safe-#endif----- | Create a single element context.-singleton :: f tp -> Assignment f (EmptyCtx ::> tp)-singleton = (empty :>)---- |'forIndexM sz f' calls 'f' on indices '[0..sz-1]'.-forIndexM :: forall ctx m-           . Applicative m-          => Size ctx-          -> (forall tp . Index ctx tp -> m ())-          -> m ()-forIndexM sz f = forIndexRange 0 sz (\i r -> f i *> r) (pure ())---- | Generate an assignment with some context type that is not known.-generateSome :: forall f-              . Int-             -> (Int -> Some f)-             -> Some (Assignment f)-generateSome n f = go n-  where go :: Int -> Some (Assignment f)-        go 0 = Some empty-        go i = (\(Some a) (Some e) -> Some (a `extend` e)) (go (i-1)) (f (i-1))---- | Generate an assignment with some context type that is not known.-generateSomeM :: forall m f-              .  Applicative m-              => Int-              -> (Int -> m (Some f))-              -> m (Some (Assignment f))-generateSomeM n f = go n-  where go :: Int -> m (Some (Assignment f))-        go 0 = pure (Some empty)-        go i = (\(Some a) (Some e) -> Some (a `extend` e)) <$> go (i-1) <*> f (i-1)---- | Convert the assignment to a vector.-toVector :: Assignment f tps -> (forall tp . f tp -> e) -> V.Vector e-toVector a f = V.create $ do-  vm <- MV.new (sizeInt (size a))-  forIndexM (size a) $ \i -> do-    MV.write vm (indexVal i) (f (a ! i))-  return vm-{-# INLINABLE toVector #-}------------------------------------------------------------------------------------- Patterns---- | Pattern synonym for the empty assignment-pattern Empty :: () => ctx ~ EmptyCtx => Assignment f ctx-pattern Empty <- (viewAssign -> AssignEmpty)-  where Empty = empty--infixl :>---- | Pattern synonym for extending an assignment on the right-pattern (:>) :: () => ctx' ~ (ctx ::> tp) => Assignment f ctx -> f tp -> Assignment f ctx'-pattern (:>) a v <- (viewAssign -> AssignExtend a v)-  where a :> v = extend a v---- The COMPLETE pragma was not defined until ghc 8.2.*-#if MIN_VERSION_base(4,10,0)-{-# COMPLETE (:>), Empty :: Assignment  #-}-#endif------------------------------------------------------------------------------------- Views---- | Return true if assignment is empty.-null :: Assignment f ctx -> Bool-null a =-  case viewAssign a of-    AssignEmpty -> True-    AssignExtend{} -> False--decompose :: Assignment f (ctx ::> tp) -> (Assignment f ctx, f tp)-decompose x = (Data.Parameterized.Context.init x, Data.Parameterized.Context.last x)---- | Return assignment with all but the last block.-init :: Assignment f (ctx '::> tp) -> Assignment f ctx-init x =-  case viewAssign x of-    AssignExtend t _ -> t---- | Return the last element in the assignment.-last :: Assignment f (ctx '::> tp) -> f tp-last x =-  case viewAssign x of-    AssignExtend _ e -> e--{-# DEPRECATED view "Use viewAssign or the Empty and :> patterns instead." #-}--- | View an assignment as either empty or an assignment with one appended.-view :: forall f ctx . Assignment f ctx -> AssignView f ctx-view = viewAssign--take :: forall f ctx ctx'. Size ctx -> Size ctx' -> Assignment f (ctx <+> ctx') -> Assignment f ctx-take sz sz' asgn =-  let diff = appendDiff sz' in-  generate sz (\i -> asgn ! extendIndex' diff i)------------------------------------------------------------------------------------- Context embedding.---- | This datastructure contains a proof that the first context is--- embeddable in the second.  This is useful if we want to add extend--- an existing term under a larger context.--data CtxEmbedding (ctx :: Ctx k) (ctx' :: Ctx k)-  = CtxEmbedding { _ctxeSize       :: Size ctx'-                 , _ctxeAssignment :: Assignment (Index ctx') ctx-                 }---- Alternate encoding?--- data CtxEmbedding ctx ctx' where---   EIdentity  :: CtxEmbedding ctx ctx---   ExtendBoth :: CtxEmbedding ctx ctx' -> CtxEmbedding (ctx ::> tp) (ctx' ::> tp)---   ExtendOne  :: CtxEmbedding ctx ctx' -> CtxEmbedding ctx (ctx' ::> tp)--ctxeSize :: Simple Lens (CtxEmbedding ctx ctx') (Size ctx')-ctxeSize = lens _ctxeSize (\s v -> s { _ctxeSize = v })--ctxeAssignment :: Lens (CtxEmbedding ctx1 ctx') (CtxEmbedding ctx2 ctx')-                       (Assignment (Index ctx') ctx1) (Assignment (Index ctx') ctx2)-ctxeAssignment = lens _ctxeAssignment (\s v -> s { _ctxeAssignment = v })--class ApplyEmbedding (f :: Ctx k -> *) where-  applyEmbedding :: CtxEmbedding ctx ctx' -> f ctx -> f ctx'--class ApplyEmbedding' (f :: Ctx k -> k' -> *) where-  applyEmbedding' :: CtxEmbedding ctx ctx' -> f ctx v -> f ctx' v--class ExtendContext (f :: Ctx k -> *) where-  extendContext :: Diff ctx ctx' -> f ctx -> f ctx'--class ExtendContext' (f :: Ctx k -> k' -> *) where-  extendContext' :: Diff ctx ctx' -> f ctx v -> f ctx' v--instance ApplyEmbedding' Index where-  applyEmbedding' ctxe idx = (ctxe ^. ctxeAssignment) ! idx--instance ExtendContext' Index where-  extendContext' = extendIndex'---- -- This is the inefficient way of doing things.  A better way is to--- -- just have a map between indices.--- applyEmbedding :: CtxEmbedding ctx ctx'---                -> Index ctx tp -> Index ctx' tp--- applyEmbedding ctxe idx = (ctxe ^. ctxeAssignment) ! idx--identityEmbedding :: Size ctx -> CtxEmbedding ctx ctx-identityEmbedding sz = CtxEmbedding sz (generate sz id)---- emptyEmbedding :: CtxEmbedding EmptyCtx EmptyCtx--- emptyEmbedding = identityEmbedding knownSize--extendEmbeddingRightDiff :: forall ctx ctx' ctx''.-                            Diff ctx' ctx''-                            -> CtxEmbedding ctx ctx'-                            -> CtxEmbedding ctx ctx''-extendEmbeddingRightDiff diff (CtxEmbedding sz' assgn) = CtxEmbedding (extSize sz' diff) updated-  where-    updated :: Assignment (Index ctx'') ctx-    updated = fmapFC (extendIndex' diff) assgn--extendEmbeddingRight :: CtxEmbedding ctx ctx' -> CtxEmbedding ctx (ctx' ::> tp)-extendEmbeddingRight = extendEmbeddingRightDiff knownDiff--appendEmbedding :: Size ctx -> Size ctx' -> CtxEmbedding ctx (ctx <+> ctx')-appendEmbedding sz sz' = CtxEmbedding (addSize sz sz') (generate sz (extendIndex' diff))-  where-  diff = appendDiff sz'--extendEmbeddingBoth :: forall ctx ctx' tp. CtxEmbedding ctx ctx' -> CtxEmbedding (ctx ::> tp) (ctx' ::> tp)-extendEmbeddingBoth ctxe = updated & ctxeAssignment %~ flip extend (nextIndex (ctxe ^. ctxeSize))-  where-    updated :: CtxEmbedding ctx (ctx' ::> tp)-    updated = extendEmbeddingRight ctxe------------------------------------------------------------------------------------- Static indexing based on type-level naturals---- | Get a lens for an position in an 'Assignment' by zero-based, left-to-right position.--- The position must be specified using @TypeApplications@ for the @n@ parameter.-field :: forall n ctx f r. Idx n ctx r => Lens' (Assignment f ctx) (f r)-field = ixF' (natIndex @n)---- | Constraint synonym used for getting an 'Index' into a 'Ctx'.--- @n@ is the zero-based, left-counted index into the list of types--- @ctx@ which has the type @r@.-type Idx n ctx r = (ValidIx n ctx, Idx' (FromLeft ctx n) ctx r)---- | Compute an 'Index' value for a particular position in a 'Ctx'. The--- @TypeApplications@ extension will be needed to disambiguate the choice--- of the type @n@.-natIndex :: forall n ctx r. Idx n ctx r => Index ctx r-natIndex = natIndex' @_ @(FromLeft ctx n)---- | This version of 'natIndex' is suitable for use without the @TypeApplications@--- extension.-natIndexProxy :: forall n ctx r proxy. Idx n ctx r => proxy n -> Index ctx r-natIndexProxy _ = natIndex @n----------------------------------------------------------------------------- Implementation----------------------------------------------------------------------------- | Class for computing 'Index' values for positions in a 'Ctx'.-class KnownContext ctx => Idx' (n :: Nat) (ctx :: Ctx k) (r :: k) | n ctx -> r where-  natIndex' :: Index ctx r---- | Base-case-instance KnownContext xs => Idx' 0 (xs '::> x) x where-  natIndex' = lastIndex knownSize---- | Inductive-step-instance {-# Overlaps #-} (KnownContext xs, Idx' (n-1) xs r) =>-  Idx' n (xs '::> x) r where--  natIndex' = skipIndex (natIndex' @_ @(n-1))-------------------------------------------------------------------------------------- CurryAssignment---- | This type family is used to define currying\/uncurrying operations--- on assignments.  It is best understood by seeing its evaluation on--- several examples:------ > CurryAssignment EmptyCtx f x = x--- > CurryAssignment (EmptyCtx ::> a) f x = f a -> x--- > CurryAssignment (EmptyCtx ::> a ::> b) f x = f a -> f b -> x--- > CurryAssignment (EmptyCtx ::> a ::> b ::> c) f x = f a -> f b -> f c -> x-type family CurryAssignment (ctx :: Ctx k) (f :: k -> *) (x :: *) :: * where-   CurryAssignment EmptyCtx    f x = x-   CurryAssignment (ctx ::> a) f x = CurryAssignment ctx f (f a -> x)---- | This class implements two methods that witness the isomorphism between---   curried and uncurried functions.-class CurryAssignmentClass (ctx :: Ctx k) where--  -- | Transform a function that accepts an assignment into one with a separate-  --   variable for each element of the assignment.-  curryAssignment   :: (Assignment f ctx -> x) -> CurryAssignment ctx f x--  -- | Transform a curried function into one that accepts an assignment value.-  uncurryAssignment :: CurryAssignment ctx f x -> (Assignment f ctx -> x)--instance CurryAssignmentClass EmptyCtx where-  curryAssignment k = k empty-  uncurryAssignment k _ = k--instance CurryAssignmentClass ctx => CurryAssignmentClass (ctx ::> a) where-  curryAssignment k = curryAssignment (\asgn a -> k (asgn :> a))-  uncurryAssignment k asgn =-    case viewAssign asgn of-      AssignExtend asgn' x -> uncurryAssignment k asgn' x---- | Create an assignment from a list of values.-fromList :: [Some f] -> Some (Assignment f)-fromList = go empty-  where go :: Assignment f ctx -> [Some f] -> Some (Assignment f)-        go prev [] = Some prev-        go prev (Some g:next) = (go $! prev `extend` g) next---newtype Collector m w a = Collector { runCollector :: m w }-instance Functor (Collector m w) where-  fmap _ (Collector x) = Collector x-instance (Applicative m, Monoid w) => Applicative (Collector m w) where-  pure _ = Collector (pure mempty)-  Collector x <*> Collector y = Collector (liftA2 (<>) x y)---- | Visit each of the elements in an @Assignment@ in order---   from left to right and collect the results using the provided @Monoid@.-traverseAndCollect ::-  (Monoid w, Applicative m) =>-  (forall tp. Index ctx tp -> f tp -> m w) ->-  Assignment f ctx ->-  m w-traverseAndCollect f =-  runCollector . traverseWithIndex (\i x -> Collector (f i x))------------------------------------------------------------------------------------- Size and Index values--size1 :: Size (EmptyCtx ::> a)-size1 = incSize zeroSize--size2 :: Size (EmptyCtx ::> a ::> b)-size2 = incSize size1--size3 :: Size (EmptyCtx ::> a ::> b ::> c)-size3 = incSize size2--size4 :: Size (EmptyCtx ::> a ::> b ::> c ::> d)-size4 = incSize size3--size5 :: Size (EmptyCtx ::> a ::> b ::> c ::> d ::> e)-size5 = incSize size4--size6 :: Size (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f)-size6 = incSize size5--i1of2 :: Index (EmptyCtx ::> a ::> b) a-i1of2 = skipIndex baseIndex--i2of2 :: Index (EmptyCtx ::> a ::> b) b-i2of2 = nextIndex size1--i1of3 :: Index (EmptyCtx ::> a ::> b ::> c) a-i1of3 = skipIndex i1of2--i2of3 :: Index (EmptyCtx ::> a ::> b ::> c) b-i2of3 = skipIndex i2of2--i3of3 :: Index (EmptyCtx ::> a ::> b ::> c) c-i3of3 = nextIndex size2--i1of4 :: Index (EmptyCtx ::> a ::> b ::> c ::> d) a-i1of4 = skipIndex i1of3--i2of4 :: Index (EmptyCtx ::> a ::> b ::> c ::> d) b-i2of4 = skipIndex i2of3--i3of4 :: Index (EmptyCtx ::> a ::> b ::> c ::> d) c-i3of4 = skipIndex i3of3--i4of4 :: Index (EmptyCtx ::> a ::> b ::> c ::> d) d-i4of4 = nextIndex size3--i1of5 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e) a-i1of5 = skipIndex i1of4--i2of5 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e) b-i2of5 = skipIndex i2of4--i3of5 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e) c-i3of5 = skipIndex i3of4--i4of5 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e) d-i4of5 = skipIndex i4of4--i5of5 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e) e-i5of5 = nextIndex size4--i1of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) a-i1of6 = skipIndex i1of5--i2of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) b-i2of6 = skipIndex i2of5--i3of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) c-i3of6 = skipIndex i3of5--i4of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) d-i4of6 = skipIndex i4of5--i5of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) e-i5of6 = skipIndex i5of5--i6of6 :: Index (EmptyCtx ::> a ::> b ::> c ::> d ::> e ::> f) f-i6of6 = nextIndex size5
− submodules/parameterized-utils/src/Data/Parameterized/Context/Safe.hs
@@ -1,994 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.Context.Safe--- Copyright        : (c) Galois, Inc 2014-2015--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module defines type contexts as a data-kind that consists of--- a list of types.  Indexes are defined with respect to these contexts.--- In addition, finite dependent products (Assignments) are defined over--- type contexts.  The elements of an assignment can be accessed using--- appropriately-typed indexes.------ This module is intended to export exactly the same API as module--- "Data.Parameterized.Context.Unsafe", so that they can be used--- interchangeably.------ This implementation is entirely typesafe, and provides a proof that--- the signature implemented by this module is consistent.  Contexts,--- indexes, and assignments are represented naively by linear sequences.------ Compared to the implementation in "Data.Parameterized.Context.Unsafe",--- this one suffers from the fact that the operation of extending an--- the context of an index is /not/ a no-op. We therefore cannot use--- 'Data.Coerce.coerce' to understand indexes in a new context without--- actually breaking things.----------------------------------------------------------------------------{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE IncoherentInstances #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeInType #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeInType #-}-module Data.Parameterized.Context.Safe-  ( module Data.Parameterized.Ctx-    -- * Size-  , Size-  , sizeInt-  , zeroSize-  , incSize-  , decSize-  , extSize-  , addSize-  , SizeView(..)-  , viewSize-  , KnownContext(..)-    -- * Diff-  , Diff-  , noDiff-  , extendRight-  , appendDiff-  , DiffView(..)-  , viewDiff-  , KnownDiff(..)-    -- * Indexing-  , Index-  , indexVal-  , baseIndex-  , skipIndex-  , lastIndex-  , nextIndex-  , extendIndex-  , extendIndex'-  , forIndex-  , forIndexRange-  , intIndex-    -- * Assignments-  , Assignment-  , size-  , Data.Parameterized.Context.Safe.replicate-  , generate-  , generateM-  , empty-  , extend-  , adjust-  , update-  , adjustM-  , AssignView(..)-  , viewAssign-  , (!)-  , (!^)-  , zipWith-  , zipWithM-  , (<++>)-  , traverseWithIndex-  ) where--import qualified Control.Category as Cat-import Control.DeepSeq-import qualified Control.Lens as Lens-import Control.Monad.Identity (Identity(..))-import Data.Hashable-import Data.List (intercalate)-import Data.Maybe (listToMaybe)-import Data.Type.Equality-import Prelude hiding (init, map, null, replicate, succ, zipWith)-import Data.Kind(Type)--#if !MIN_VERSION_base(4,8,0)-import Data.Functor-import Control.Applicative (Applicative(..))-#endif--import Data.Parameterized.Classes-import Data.Parameterized.Ctx-import Data.Parameterized.Some-import Data.Parameterized.TraversableFC----------------------------------------------------------------------------- Size---- | An indexed singleton type representing the size of a context.-data Size (ctx :: Ctx k) where-  SizeZero :: Size 'EmptyCtx-  SizeSucc :: !(Size ctx) -> Size (ctx '::> tp)---- | Convert a context size to an 'Int'.-sizeInt :: Size ctx -> Int-sizeInt SizeZero = 0-sizeInt (SizeSucc sz) = (+1) $! sizeInt sz---- | The size of an empty context.-zeroSize :: Size 'EmptyCtx-zeroSize = SizeZero---- | Increment the size to the next value.-incSize :: Size ctx -> Size (ctx '::> tp)-incSize sz = SizeSucc sz--decSize :: Size (ctx '::> tp) -> Size ctx-decSize (SizeSucc sz) = sz---- | The total size of two concatenated contexts.-addSize :: Size x -> Size y -> Size (x <+> y)-addSize sx SizeZero = sx-addSize sx (SizeSucc sy) = SizeSucc (addSize sx sy)---- | Allows interpreting a size.-data SizeView (ctx :: Ctx k) where-  ZeroSize :: SizeView 'EmptyCtx-  IncSize :: !(Size ctx) -> SizeView (ctx '::> tp)---- | View a size as either zero or a smaller size plus one.-viewSize :: Size ctx -> SizeView ctx-viewSize SizeZero = ZeroSize-viewSize (SizeSucc s) = IncSize s----------------------------------------------------------------------------- Size---- | A context that can be determined statically at compiler time.-class KnownContext (ctx :: Ctx k) where-  knownSize :: Size ctx--instance KnownContext 'EmptyCtx where-  knownSize = zeroSize--instance KnownContext ctx => KnownContext (ctx '::> tp) where-  knownSize = incSize knownSize----------------------------------------------------------------------------- Diff---- | Difference in number of elements between two contexts.--- The first context must be a sub-context of the other.-data Diff (l :: Ctx k) (r :: Ctx k) where-  DiffHere :: Diff ctx ctx-  DiffThere :: Diff ctx1 ctx2 -> Diff ctx1 (ctx2 '::> tp)---- | The identity difference.-noDiff :: Diff l l-noDiff = DiffHere---- | Extend the difference to a sub-context of the right side.-extendRight :: Diff l r -> Diff l (r '::> tp)-extendRight diff = DiffThere diff--appendDiff :: Size r -> Diff l (l <+> r)-appendDiff SizeZero = DiffHere-appendDiff (SizeSucc sz) = DiffThere (appendDiff sz)--composeDiff :: Diff a b -> Diff b c -> Diff a c-composeDiff x DiffHere = x-composeDiff x (DiffThere y) = DiffThere (composeDiff x y)--instance Cat.Category Diff where-  id = DiffHere-  d1 . d2 = composeDiff d2 d1---- | Extend the size by a given difference.-extSize :: Size l -> Diff l r -> Size r-extSize sz DiffHere = sz-extSize sz (DiffThere diff) = incSize (extSize sz diff)--data DiffView a b where-  NoDiff :: DiffView a a-  ExtendRightDiff :: Diff a b -> DiffView a (b ::> r)--viewDiff :: Diff a b -> DiffView a b-viewDiff DiffHere = NoDiff-viewDiff (DiffThere diff) = ExtendRightDiff diff----------------------------------------------------------------------------- KnownDiff---- | A difference that can be automatically inferred at compile time.-class KnownDiff (l :: Ctx k) (r :: Ctx k) where-  knownDiff :: Diff l r--instance KnownDiff l l where-  knownDiff = noDiff--instance KnownDiff l r => KnownDiff l (r '::> tp) where-  knownDiff = extendRight knownDiff----------------------------------------------------------------------------- Index---- | An index is a reference to a position with a particular type in a--- context.-data Index (ctx :: Ctx k) (tp :: k) where-  IndexHere :: Size ctx -> Index (ctx '::> tp) tp-  IndexThere :: !(Index ctx tp) -> Index (ctx '::> tp') tp---- | Convert an index to an 'Int', where the index of the left-most type in the context is 0.-indexVal :: Index ctx tp -> Int-indexVal (IndexHere sz) = sizeInt sz-indexVal (IndexThere idx) = indexVal idx--instance Eq (Index ctx tp) where-  idx1 == idx2 = isJust (testEquality idx1 idx2)--instance TestEquality (Index ctx) where-  testEquality (IndexHere _) (IndexHere _) = Just Refl-  testEquality (IndexHere _) (IndexThere _) = Nothing-  testEquality (IndexThere _) (IndexHere _) = Nothing-  testEquality (IndexThere idx1) (IndexThere idx2) =-     case testEquality idx1 idx2 of-         Just Refl -> Just Refl-         Nothing -> Nothing--instance Ord (Index ctx tp) where-  compare i j = toOrdering (compareF i j)--instance OrdF (Index ctx) where-  compareF (IndexHere _) (IndexHere _) = EQF-  compareF (IndexThere _) (IndexHere _) = LTF-  compareF (IndexHere _) (IndexThere _) = GTF-  compareF (IndexThere idx1) (IndexThere idx2) = lexCompareF idx1 idx2 $ EQF---- | Index for first element in context.-baseIndex :: Index ('EmptyCtx '::> tp) tp-baseIndex = IndexHere SizeZero---- | Increase context while staying at same index.-skipIndex :: Index ctx x -> Index (ctx '::> y) x-skipIndex idx = IndexThere idx---- | Return the index of an element one past the size.-nextIndex :: Size ctx -> Index (ctx '::> tp) tp-nextIndex sz = IndexHere sz---- | Return the last index of a element.-lastIndex :: Size (ctx ::> tp) -> Index (ctx ::> tp) tp-lastIndex (SizeSucc s) = IndexHere s--{-# INLINE extendIndex #-}-extendIndex :: KnownDiff l r => Index l tp -> Index r tp-extendIndex = extendIndex' knownDiff--{-# INLINE extendIndex' #-}-extendIndex' :: Diff l r -> Index l tp -> Index r tp-extendIndex' DiffHere idx = idx-extendIndex' (DiffThere diff) idx = IndexThere (extendIndex' diff idx)---- | Given a size @n@, an initial value @v0@, and a function @f@,--- @forIndex n v0 f@ calls @f@ on each index less than @n@ starting--- from @0@ and @v0@, with the value @v@ obtained from the last call.-forIndex :: forall ctx r-          . Size ctx-         -> (forall tp . r -> Index ctx tp -> r)-         -> r-         -> r-forIndex sz_top f = go id sz_top- where go :: forall ctx'. (forall tp. Index ctx' tp -> Index ctx tp) -> Size ctx' -> r -> r-       go _ SizeZero = id-       go g (SizeSucc sz) = \r -> go (\i -> g (IndexThere i)) sz  $ f r (g (IndexHere sz))--data LDiff (l :: Ctx k) (r :: Ctx k) where- LDiffHere :: LDiff a a- LDiffThere :: !(LDiff (a::>x) b) -> LDiff a b--ldiffIndex :: Index a tp -> LDiff a b -> Index b tp-ldiffIndex i LDiffHere = i-ldiffIndex i (LDiffThere d) = ldiffIndex (IndexThere i) d--forIndexLDiff :: Size a-              -> LDiff a b-              -> (forall tp . Index b tp -> r -> r)-              -> r-              -> r-forIndexLDiff _ LDiffHere _ r = r-forIndexLDiff sz (LDiffThere d) f r =-  forIndexLDiff (SizeSucc sz) d f (f (ldiffIndex (IndexHere sz) d) r)--forIndexRangeImpl :: Int-                  -> Size a-                  -> LDiff a b-                  -> (forall tp . Index b tp -> r -> r)-                  -> r-                  -> r-forIndexRangeImpl 0 sz d f r = forIndexLDiff sz d f r-forIndexRangeImpl _ SizeZero _ _ r = r-forIndexRangeImpl i (SizeSucc sz) d f r =-  forIndexRangeImpl (i-1) sz (LDiffThere d) f r---- | Given an index 'i', size 'n', a function 'f', value 'v', and a function 'f',--- 'forIndex i n f v' is equivalent to 'v' when 'i >= sizeInt n', and--- 'f i (forIndexRange (i+1) n v0)' otherwise.-forIndexRange :: Int-              -> Size ctx-              -> (forall tp . Index ctx tp -> r -> r)-              -> r-              -> r-forIndexRange i sz f r = forIndexRangeImpl i sz LDiffHere f r--indexList :: forall ctx. Size ctx -> [Some (Index ctx)]-indexList sz_top = go id [] sz_top- where go :: (forall tp. Index ctx' tp -> Index ctx tp)-          -> [Some (Index ctx)]-          -> Size ctx'-          -> [Some (Index ctx)]-       go _ ls SizeZero       = ls-       go g ls (SizeSucc sz)  = go (\i -> g (IndexThere i)) (Some (g (IndexHere sz)) : ls) sz---- | Return index at given integer or nothing if integer is out of bounds.-intIndex :: Int -> Size ctx -> Maybe (Some (Index ctx))-intIndex n sz = listToMaybe $ drop n $ indexList sz--instance Show (Index ctx tp) where-   show = show . indexVal--instance ShowF (Index ctx)----------------------------------------------------------------------------- Assignment---- | An assignment is a sequence that maps each index with type 'tp' to--- a value of type 'f tp'.-data Assignment (f :: k -> Type) (ctx :: Ctx k) where-  AssignmentEmpty :: Assignment f EmptyCtx-  AssignmentExtend :: Assignment f ctx -> f tp -> Assignment f (ctx ::> tp)---- | View an assignment as either empty or an assignment with one appended.-data AssignView (f :: k -> Type) (ctx :: Ctx k) where-  AssignEmpty :: AssignView f EmptyCtx-  AssignExtend :: Assignment f ctx -> f tp -> AssignView f (ctx::>tp)--viewAssign :: forall f ctx . Assignment f ctx -> AssignView f ctx-viewAssign AssignmentEmpty = AssignEmpty-viewAssign (AssignmentExtend asgn x) = AssignExtend asgn x--instance NFData (Assignment f ctx) where-  rnf AssignmentEmpty = ()-  rnf (AssignmentExtend asgn x) = rnf asgn `seq` x `seq` ()---- | Return number of elements in assignment.-size :: Assignment f ctx -> Size ctx-size AssignmentEmpty = SizeZero-size (AssignmentExtend asgn _) = SizeSucc (size asgn)---- | Generate an assignment-generate :: forall ctx f-          . Size ctx-         -> (forall tp . Index ctx tp -> f tp)-         -> Assignment f ctx-generate sz_top f = go id sz_top- where go :: forall ctx'-           . (forall tp. Index ctx' tp -> Index ctx tp)-          -> Size ctx'-          -> Assignment f ctx'-       go _ SizeZero = AssignmentEmpty-       go g (SizeSucc sz) =-            let ctx = go (\i -> g (IndexThere i)) sz-                x = f (g (IndexHere sz))-             in AssignmentExtend ctx x---- | Generate an assignment-generateM :: forall ctx m f-           . Applicative m-          => Size ctx-          -> (forall tp . Index ctx tp -> m (f tp))-          -> m (Assignment f ctx)-generateM sz_top f = go id sz_top- where go :: forall ctx'. (forall tp. Index ctx' tp -> Index ctx tp) -> Size ctx' -> m (Assignment f ctx')-       go _ SizeZero = pure AssignmentEmpty-       go g (SizeSucc sz) =-             AssignmentExtend <$> (go (\i -> g (IndexThere i)) sz) <*> f (g (IndexHere sz))---- | @replicate n@ make a context with different copies of the same--- polymorphic value.-replicate :: Size ctx -> (forall tp . f tp) -> Assignment f ctx-replicate n c = generate n (\_ -> c)---- | Create empty indexec vector.-empty :: Assignment f 'EmptyCtx-empty = AssignmentEmpty--extend :: Assignment f ctx -> f tp -> Assignment f (ctx '::> tp)-extend asgn e = AssignmentExtend asgn e--{-# DEPRECATED adjust "Replace 'adjust f i asgn' with 'Lens.over (ixF i) f asgn' instead." #-}-adjust :: forall f ctx tp. (f tp -> f tp) -> Index ctx tp -> Assignment f ctx -> Assignment f ctx-adjust f idx asgn = runIdentity (adjustM (Identity . f) idx asgn)--{-# DEPRECATED update "Replace 'update idx val asgn' with 'Lens.set (ixF idx) val asgn' instead." #-}-update :: forall f ctx tp. Index ctx tp -> f tp -> Assignment f ctx -> Assignment f ctx-update i v a = adjust (\_ -> v) i a--adjustM :: forall m f ctx tp. Functor m => (f tp -> m (f tp)) -> Index ctx tp -> Assignment f ctx -> m (Assignment f ctx)-adjustM f = go (\x -> x)- where-  go :: (forall tp'. g tp' -> f tp') -> Index ctx' tp -> Assignment g ctx' -> m (Assignment f ctx')-  go g (IndexHere _)     (AssignmentExtend asgn x) = AssignmentExtend (map g asgn) <$> f (g x)-  go g (IndexThere idx)  (AssignmentExtend asgn x) = flip AssignmentExtend (g x)   <$> go g idx asgn-#if !MIN_VERSION_base(4,9,0)--- GHC 7.10.3 and early does not recognize that the above definition is complete,--- and so need the equation below.  GHC 8.0.1 does not require the additional--- equation.-  go _ _ _ = error "SafeTypeContext.adjustM: impossible!"-#endif--type instance IndexF   (Assignment (f :: k -> Type) ctx) = Index ctx-type instance IxValueF (Assignment (f :: k -> Type) ctx) = f--instance forall (f :: k -> Type) ctx. IxedF k (Assignment f ctx) where-  ixF :: Index ctx x -> Lens.Lens' (Assignment f ctx) (f x)-  ixF idx f = adjustM f idx--instance forall (f :: k -> Type) ctx. IxedF' k (Assignment f ctx) where-  ixF' :: Index ctx x -> Lens.Lens' (Assignment f ctx) (f x)-  ixF' idx f = adjustM f idx--idxlookup :: (forall tp. a tp -> b tp) -> Assignment a ctx -> forall tp. Index ctx tp -> b tp-idxlookup f (AssignmentExtend _   x) (IndexHere _) = f x-idxlookup f (AssignmentExtend ctx _) (IndexThere idx) = idxlookup f ctx idx-idxlookup _ AssignmentEmpty _ = error "Data.Parameterized.Context.Safe.lookup: impossible case"---- | Return value of assignment.-(!) :: Assignment f ctx -> Index ctx tp -> f tp-(!) asgn idx = idxlookup id asgn idx---- | Return value of assignment, where the index is into an---   initial sequence of the assignment.-(!^) :: KnownDiff l r => Assignment f r -> Index l tp -> f tp-a !^ i = a ! extendIndex i--instance TestEquality f => Eq (Assignment f ctx) where-  x == y = isJust (testEquality x y)--testEq :: (forall x y. f x -> f y -> Maybe (x :~: y))-       -> Assignment f cxt1 -> Assignment f cxt2 -> Maybe (cxt1 :~: cxt2)-testEq _ AssignmentEmpty AssignmentEmpty = Just Refl-testEq test (AssignmentExtend ctx1 x1) (AssignmentExtend ctx2 x2) =-     case testEq test ctx1 ctx2 of-       Nothing -> Nothing-       Just Refl ->-          case test x1 x2 of-             Nothing -> Nothing-             Just Refl -> Just Refl-testEq _ AssignmentEmpty AssignmentExtend{} = Nothing-testEq _ AssignmentExtend{} AssignmentEmpty = Nothing--instance TestEqualityFC Assignment where-   testEqualityFC = testEq-instance TestEquality f => TestEquality (Assignment f) where-   testEquality x y = testEq testEquality x y-instance TestEquality f => PolyEq (Assignment f x) (Assignment f y) where-  polyEqF x y = fmap (\Refl -> Refl) $ testEquality x y--compareAsgn :: (forall x y. f x -> f y -> OrderingF x y)-            -> Assignment f ctx1 -> Assignment f ctx2 -> OrderingF ctx1 ctx2-compareAsgn _ AssignmentEmpty AssignmentEmpty = EQF-compareAsgn _ AssignmentEmpty _ = GTF-compareAsgn _ _ AssignmentEmpty = LTF-compareAsgn test (AssignmentExtend ctx1 x) (AssignmentExtend ctx2 y) =-  case compareAsgn test ctx1 ctx2 of-    LTF -> LTF-    GTF -> GTF-    EQF -> case test x y of-              LTF -> LTF-              GTF -> GTF-              EQF -> EQF--instance OrdFC Assignment where-  compareFC = compareAsgn--instance OrdF f => OrdF (Assignment f) where-  compareF = compareAsgn compareF--instance OrdF f => Ord (Assignment f ctx) where-  compare x y = toOrdering (compareF x y)---instance Hashable (Index ctx tp) where-  hashWithSalt = hashWithSaltF-instance HashableF (Index ctx) where-  hashWithSaltF s i = hashWithSalt s (indexVal i)--instance HashableF f => HashableF (Assignment f) where-  hashWithSaltF = hashWithSalt--instance HashableF f => Hashable (Assignment f ctx) where-  hashWithSalt s AssignmentEmpty = s-  hashWithSalt s (AssignmentExtend asgn x) = (s `hashWithSalt` asgn) `hashWithSaltF` x--instance ShowF f => Show (Assignment f ctx) where-  show a = "[" ++ intercalate ", " (toList showF a) ++ "]"--instance ShowF f => ShowF (Assignment f)--instance FunctorFC Assignment where-  fmapFC = fmapFCDefault--instance FoldableFC Assignment where-  foldMapFC = foldMapFCDefault--instance TraversableFC Assignment where-  traverseFC = traverseF---- | Map assignment-map :: (forall tp . f tp -> g tp) -> Assignment f c -> Assignment g c-map = fmapFC--traverseF :: forall (f:: k -> Type) (g::k -> Type) (m:: Type -> Type) (c::Ctx k)-           . Applicative m-          => (forall tp . f tp -> m (g tp))-          -> Assignment f c-          -> m (Assignment g c)-traverseF _ AssignmentEmpty = pure AssignmentEmpty-traverseF f (AssignmentExtend asgn x) = pure AssignmentExtend <*> traverseF f asgn <*> f x---- | Convert assignment to list.-toList :: (forall tp . f tp -> a)-       -> Assignment f c-       -> [a]-toList = toListFC--zipWithM :: Applicative m-         => (forall tp . f tp -> g tp -> m (h tp))-         -> Assignment f c-         -> Assignment g c-         -> m (Assignment h c)-zipWithM f x y = go x y- where go AssignmentEmpty AssignmentEmpty = pure AssignmentEmpty-       go (AssignmentExtend asgn1 x1) (AssignmentExtend asgn2 x2) =-             AssignmentExtend <$> (zipWithM f asgn1 asgn2) <*> (f x1 x2)--zipWith :: (forall x . f x -> g x -> h x)-        -> Assignment f a-        -> Assignment g a-        -> Assignment h a-zipWith f = \x y -> runIdentity $ zipWithM (\u v -> pure (f u v)) x y-{-# INLINE zipWith #-}--traverseWithIndex :: Applicative m-                  => (forall tp . Index ctx tp -> f tp -> m (g tp))-                  -> Assignment f ctx-                  -> m (Assignment g ctx)-traverseWithIndex f a = generateM (size a) $ \i -> f i (a ! i)--(<++>) :: Assignment f x -> Assignment f y -> Assignment f (x <+> y)-x <++> AssignmentEmpty = x-x <++> AssignmentExtend y t = AssignmentExtend (x <++> y) t----------------------------------------------------------------------------- KnownRepr instances--instance (KnownRepr (Assignment f) ctx, KnownRepr f bt)-      => KnownRepr (Assignment f) (ctx ::> bt) where-  knownRepr = knownRepr `extend` knownRepr--instance KnownRepr (Assignment f) EmptyCtx where-  knownRepr = empty------------------------------------------------------------------------------------------- lookups and update for lenses--data MyNat where-  MyZ :: MyNat-  MyS :: MyNat -> MyNat--type MyZ = 'MyZ-type MyS = 'MyS--data MyNatRepr :: MyNat -> Type where-  MyZR :: MyNatRepr MyZ-  MySR :: MyNatRepr n -> MyNatRepr (MyS n)--type family StrongCtxUpdate (n::MyNat) (ctx::Ctx k) (z::k) :: Ctx k where-  StrongCtxUpdate n       EmptyCtx     z = EmptyCtx-  StrongCtxUpdate MyZ     (ctx::>x)    z = ctx ::> z-  StrongCtxUpdate (MyS n) (ctx::>x)    z = (StrongCtxUpdate n ctx z) ::> x--type family MyNatLookup (n::MyNat) (ctx::Ctx k) (f::k -> Type) :: Type where-  MyNatLookup n       EmptyCtx  f = ()-  MyNatLookup MyZ     (ctx::>x) f = f x-  MyNatLookup (MyS n) (ctx::>x) f = MyNatLookup n ctx f--mynat_lookup :: MyNatRepr n -> Assignment f ctx -> MyNatLookup n ctx f-mynat_lookup _   AssignmentEmpty = ()-mynat_lookup MyZR     (AssignmentExtend _    x) = x-mynat_lookup (MySR n) (AssignmentExtend asgn _) = mynat_lookup n asgn--strong_ctx_update :: MyNatRepr n -> Assignment f ctx -> f tp -> Assignment f (StrongCtxUpdate n ctx tp)-strong_ctx_update _        AssignmentEmpty           _ = AssignmentEmpty-strong_ctx_update MyZR     (AssignmentExtend asgn _) z = AssignmentExtend asgn z-strong_ctx_update (MySR n) (AssignmentExtend asgn x) z = AssignmentExtend (strong_ctx_update n asgn z) x----------------------------------------------------------------------------- 1 field lens combinators--type Assignment1 f x1 = Assignment f ('EmptyCtx '::> x1)--instance Lens.Field1 (Assignment1 f t) (Assignment1 f u) (f t) (f u) where--  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 2 field lens combinators--type Assignment2 f x1 x2-   = Assignment f ('EmptyCtx '::> x1 '::> x2)--instance Lens.Field1 (Assignment2 f t x2) (Assignment2 f u x2) (f t) (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field2 (Assignment2 f x1 t) (Assignment2 f x1 u) (f t) (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR------------------------------------------------------------------------------ 3 field lens combinators--type Assignment3 f x1 x2 x3-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3)--instance Lens.Field1 (Assignment3 f t x2 x3)-                     (Assignment3 f u x2 x3)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment3 f x1 t x3)-                     (Assignment3 f x1 u x3)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field3 (Assignment3 f x1 x2 t)-                     (Assignment3 f x1 x2 u)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 4 field lens combinators--type Assignment4 f x1 x2 x3 x4-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4)--instance Lens.Field1 (Assignment4 f t x2 x3 x4)-                     (Assignment4 f u x2 x3 x4)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment4 f x1 t x3 x4)-                     (Assignment4 f x1 u x3 x4)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment4 f x1 x2 t x4)-                     (Assignment4 f x1 x2 u x4)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field4 (Assignment4 f x1 x2 x3 t)-                     (Assignment4 f x1 x2 x3 u)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR------------------------------------------------------------------------------ 5 field lens combinators--type Assignment5 f x1 x2 x3 x4 x5-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5)--instance Lens.Field1 (Assignment5 f t x2 x3 x4 x5)-                     (Assignment5 f u x2 x3 x4 x5)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment5 f x1 t x3 x4 x5)-                     (Assignment5 f x1 u x3 x4 x5)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment5 f x1 x2 t x4 x5)-                     (Assignment5 f x1 x2 u x4 x5)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field4 (Assignment5 f x1 x2 x3 t x5)-                     (Assignment5 f x1 x2 x3 u x5)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field5 (Assignment5 f x1 x2 x3 x4 t)-                     (Assignment5 f x1 x2 x3 x4 u)-                     (f t)-                     (f u) where-  _5 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 6 field lens combinators--type Assignment6 f x1 x2 x3 x4 x5 x6-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6)--instance Lens.Field1 (Assignment6 f t x2 x3 x4 x5 x6)-                     (Assignment6 f u x2 x3 x4 x5 x6)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment6 f x1 t x3 x4 x5 x6)-                     (Assignment6 f x1 u x3 x4 x5 x6)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment6 f x1 x2 t x4 x5 x6)-                     (Assignment6 f x1 x2 u x4 x5 x6)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field4 (Assignment6 f x1 x2 x3 t x5 x6)-                     (Assignment6 f x1 x2 x3 u x5 x6)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field5 (Assignment6 f x1 x2 x3 x4 t x6)-                     (Assignment6 f x1 x2 x3 x4 u x6)-                     (f t)-                     (f u) where-  _5 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field6 (Assignment6 f x1 x2 x3 x4 x5 t)-                     (Assignment6 f x1 x2 x3 x4 x5 u)-                     (f t)-                     (f u) where-  _6 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 7 field lens combinators--type Assignment7 f x1 x2 x3 x4 x5 x6 x7-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7)--instance Lens.Field1 (Assignment7 f t x2 x3 x4 x5 x6 x7)-                     (Assignment7 f u x2 x3 x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment7 f x1 t x3 x4 x5 x6 x7)-                     (Assignment7 f x1 u x3 x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment7 f x1 x2 t x4 x5 x6 x7)-                     (Assignment7 f x1 x2 u x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field4 (Assignment7 f x1 x2 x3 t x5 x6 x7)-                     (Assignment7 f x1 x2 x3 u x5 x6 x7)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field5 (Assignment7 f x1 x2 x3 x4 t x6 x7)-                     (Assignment7 f x1 x2 x3 x4 u x6 x7)-                     (f t)-                     (f u) where-  _5 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field6 (Assignment7 f x1 x2 x3 x4 x5 t x7)-                     (Assignment7 f x1 x2 x3 x4 x5 u x7)-                     (f t)-                     (f u) where-  _6 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field7 (Assignment7 f x1 x2 x3 x4 x5 x6 t)-                     (Assignment7 f x1 x2 x3 x4 x5 x6 u)-                     (f t)-                     (f u) where-  _7 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 8 field lens combinators--type Assignment8 f x1 x2 x3 x4 x5 x6 x7 x8-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8)--instance Lens.Field1 (Assignment8 f t x2 x3 x4 x5 x6 x7 x8)-                     (Assignment8 f u x2 x3 x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR---instance Lens.Field2 (Assignment8 f x1 t x3 x4 x5 x6 x7 x8)-                     (Assignment8 f x1 u x3 x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment8 f x1 x2 t x4 x5 x6 x7 x8)-                     (Assignment8 f x1 x2 u x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field4 (Assignment8 f x1 x2 x3 t x5 x6 x7 x8)-                     (Assignment8 f x1 x2 x3 u x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field5 (Assignment8 f x1 x2 x3 x4 t x6 x7 x8)-                     (Assignment8 f x1 x2 x3 x4 u x6 x7 x8)-                     (f t)-                     (f u) where-  _5 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field6 (Assignment8 f x1 x2 x3 x4 x5 t x7 x8)-                     (Assignment8 f x1 x2 x3 x4 x5 u x7 x8)-                     (f t)-                     (f u) where-  _6 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field7 (Assignment8 f x1 x2 x3 x4 x5 x6 t x8)-                     (Assignment8 f x1 x2 x3 x4 x5 x6 u x8)-                     (f t)-                     (f u) where-  _7 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field8 (Assignment8 f x1 x2 x3 x4 x5 x6 x7 t)-                     (Assignment8 f x1 x2 x3 x4 x5 x6 x7 u)-                     (f t)-                     (f u) where-  _8 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR----------------------------------------------------------------------------- 9 field lens combinators--type Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 x9-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8 '::> x9)---instance Lens.Field1 (Assignment9 f t x2 x3 x4 x5 x6 x7 x8 x9)-                     (Assignment9 f u x2 x3 x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _1 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field2 (Assignment9 f x1 t x3 x4 x5 x6 x7 x8 x9)-                     (Assignment9 f x1 u x3 x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _2 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field3 (Assignment9 f x1 x2 t x4 x5 x6 x7 x8 x9)-                     (Assignment9 f x1 x2 u x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _3 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field4 (Assignment9 f x1 x2 x3 t x5 x6 x7 x8 x9)-                     (Assignment9 f x1 x2 x3 u x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _4 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field5 (Assignment9 f x1 x2 x3 x4 t x6 x7 x8 x9)-                     (Assignment9 f x1 x2 x3 x4 u x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _5 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MySR $ MyZR--instance Lens.Field6 (Assignment9 f x1 x2 x3 x4 x5 t x7 x8 x9)-                     (Assignment9 f x1 x2 x3 x4 x5 u x7 x8 x9)-                     (f t)-                     (f u) where-  _6 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MySR $ MyZR--instance Lens.Field7 (Assignment9 f x1 x2 x3 x4 x5 x6 t x8 x9)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 u x8 x9)-                     (f t)-                     (f u) where-  _7 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MySR $ MyZR--instance Lens.Field8 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 t x9)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 x7 u x9)-                     (f t)-                     (f u) where-  _8 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MySR $ MyZR--instance Lens.Field9 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 t)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 u)-                     (f t)-                     (f u) where-  _9 = Lens.lens (mynat_lookup n) (strong_ctx_update n)-        where n = MyZR
− submodules/parameterized-utils/src/Data/Parameterized/Context/Unsafe.hs
@@ -1,1223 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeInType #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE TypeInType #-}-module Data.Parameterized.Context.Unsafe-  ( module Data.Parameterized.Ctx-  , KnownContext(..)-    -- * Size-  , Size-  , sizeInt-  , zeroSize-  , incSize-  , decSize-  , extSize-  , addSize-  , SizeView(..)-  , viewSize-    -- * Diff-  , Diff-  , noDiff-  , extendRight-  , appendDiff-  , DiffView(..)-  , viewDiff-  , KnownDiff(..)-    -- * Indexing-  , Index-  , indexVal-  , baseIndex-  , skipIndex-  , lastIndex-  , nextIndex-  , extendIndex-  , extendIndex'-  , forIndex-  , forIndexRange-  , intIndex-    -- ** IndexRange-  , IndexRange-  , allRange-  , indexOfRange-  , dropHeadRange-  , dropTailRange-    -- * Assignments-  , Assignment-  , size-  , Data.Parameterized.Context.Unsafe.replicate-  , generate-  , generateM-  , empty-  , extend-  , adjust-  , update-  , adjustM-  , AssignView(..)-  , viewAssign-  , (!)-  , (!^)-  , Data.Parameterized.Context.Unsafe.zipWith-  , zipWithM-  , (<++>)-  , traverseWithIndex-  ) where--import qualified Control.Category as Cat-import           Control.DeepSeq-import           Control.Exception-import qualified Control.Lens as Lens-import           Control.Monad.Identity (Identity(..))-import           Data.Bits-import           Data.Coerce-import           Data.Hashable-import           Data.List (intercalate)-import           Data.Proxy-import           Unsafe.Coerce-import           Data.Kind(Type)--import           Data.Parameterized.Classes-import           Data.Parameterized.Ctx-import           Data.Parameterized.Ctx.Proofs-import           Data.Parameterized.Some-import           Data.Parameterized.TraversableFC----------------------------------------------------------------------------- Size---- | Represents the size of a context.-newtype Size (ctx :: Ctx k) = Size Int--type role Size nominal---- | Convert a context size to an 'Int'.-sizeInt :: Size ctx -> Int-sizeInt (Size n) = n---- | The size of an empty context.-zeroSize :: Size 'EmptyCtx-zeroSize = Size 0---- | Increment the size to the next value.-incSize :: Size ctx -> Size (ctx '::> tp)-incSize (Size n) = Size (n+1)--decSize :: Size (ctx '::> tp) -> Size ctx-decSize (Size n) = assert (n > 0) (Size (n-1))---- | Allows interpreting a size.-data SizeView (ctx :: Ctx k) where-  ZeroSize :: SizeView 'EmptyCtx-  IncSize :: !(Size ctx) -> SizeView (ctx '::> tp)---- | Project a size-viewSize :: Size ctx -> SizeView ctx-viewSize (Size 0) = unsafeCoerce ZeroSize-viewSize (Size n) = assert (n > 0) (unsafeCoerce (IncSize (Size (n-1))))--instance Show (Size ctx) where-  show (Size i) = show i---- | A context that can be determined statically at compiler time.-class KnownContext (ctx :: Ctx k) where-  knownSize :: Size ctx--instance KnownContext 'EmptyCtx where-  knownSize = zeroSize--instance KnownContext ctx => KnownContext (ctx '::> tp) where-  knownSize = incSize knownSize----------------------------------------------------------------------------- Diff---- | Difference in number of elements between two contexts.--- The first context must be a sub-context of the other.-newtype Diff (l :: Ctx k) (r :: Ctx k)-      = Diff { _contextExtSize :: Int }--type role Diff nominal nominal---- | The identity difference.-noDiff :: Diff l l-noDiff = Diff 0---- | Extend the difference to a sub-context of the right side.-extendRight :: Diff l r -> Diff l (r '::> tp)-extendRight (Diff i) = Diff (i+1)--appendDiff :: Size r -> Diff l (l <+> r)-appendDiff (Size r) = Diff r--instance Cat.Category Diff where-  id = Diff 0-  Diff j . Diff i = Diff (i + j)---- | Extend the size by a given difference.-extSize :: Size l -> Diff l r -> Size r-extSize (Size i) (Diff j) = Size (i+j)---- | The total size of two concatenated contexts.-addSize :: Size x -> Size y -> Size (x <+> y)-addSize (Size x) (Size y) = Size (x + y)---data DiffView a b where-  NoDiff :: DiffView a a-  ExtendRightDiff :: Diff a b -> DiffView a (b ::> r)--viewDiff :: Diff a b -> DiffView a b-viewDiff (Diff i)-  | i == 0 = unsafeCoerce NoDiff-  | otherwise  = assert (i > 0) $ unsafeCoerce $ ExtendRightDiff (Diff (i-1))----------------------------------------------------------------------------- KnownDiff---- | A difference that can be automatically inferred at compile time.-class KnownDiff (l :: Ctx k) (r :: Ctx k) where-  knownDiff :: Diff l r--instance KnownDiff l l where-  knownDiff = noDiff--instance {-# INCOHERENT #-} KnownDiff l r => KnownDiff l (r '::> tp) where-  knownDiff = extendRight knownDiff----------------------------------------------------------------------------- Index---- | An index is a reference to a position with a particular type in a--- context.-newtype Index (ctx :: Ctx k) (tp :: k) = Index { indexVal :: Int }--type role Index nominal nominal--instance Eq (Index ctx tp) where-  Index i == Index j = i == j--instance TestEquality (Index ctx) where-  testEquality (Index i) (Index j)-    | i == j = Just (unsafeCoerce Refl)-    | otherwise = Nothing--instance Ord (Index ctx tp) where-  Index i `compare` Index j = compare i j--instance OrdF (Index ctx) where-  compareF (Index i) (Index j)-    | i < j = LTF-    | i == j = unsafeCoerce EQF-    | otherwise = GTF---- | Index for first element in context.-baseIndex :: Index ('EmptyCtx '::> tp) tp-baseIndex = Index 0---- | Increase context while staying at same index.-skipIndex :: Index ctx x -> Index (ctx '::> y) x-skipIndex (Index i) = Index i---- | Return the index of a element one past the size.-nextIndex :: Size ctx -> Index (ctx ::> tp) tp-nextIndex n = Index (sizeInt n)---- | Return the last index of a element.-lastIndex :: Size (ctx ::> tp) -> Index (ctx ::> tp) tp-lastIndex n = Index (sizeInt n - 1)--{-# INLINE extendIndex #-}-extendIndex :: KnownDiff l r => Index l tp -> Index r tp-extendIndex = extendIndex' knownDiff--{-# INLINE extendIndex' #-}-extendIndex' :: Diff l r -> Index l tp -> Index r tp-extendIndex' _ = unsafeCoerce---- | Given a size 'n', an initial value 'v0', and a function 'f', 'forIndex n v0 f'--- is equivalent to 'v0' when 'n' is zero, and 'f (forIndex (n-1) v0) (n-1)' otherwise.-forIndex :: forall ctx r-          . Size ctx-         -> (forall tp . r -> Index ctx tp -> r)-         -> r-         -> r-forIndex n f r =-  case viewSize n of-    ZeroSize -> r-    IncSize p -> f (forIndex p (coerce f) r) (nextIndex p)---- | Given an index 'i', size 'n', a function 'f', value 'v', and a function 'f',--- 'forIndex i n f v' is equivalent to 'v' when 'i >= sizeInt n', and--- 'f i (forIndexRange (i+1) n v0)' otherwise.-forIndexRange :: forall ctx r-               . Int-              -> Size ctx-              -> (forall tp . Index ctx tp -> r -> r)-              -> r-              -> r-forIndexRange i (Size n) f r-  | i >= n = r-  | otherwise = f (Index i) (forIndexRange (i+1) (Size n) f r)---- | Return index at given integer or nothing if integer is out of bounds.-intIndex :: Int -> Size ctx -> Maybe (Some (Index ctx))-intIndex i n | 0 <= i && i < sizeInt n = Just (Some (Index i))-             | otherwise = Nothing--instance Show (Index ctx tp) where-   show = show . indexVal--instance ShowF (Index ctx)----------------------------------------------------------------------------- IndexRange---- | This represents a contiguous range of indices.-data IndexRange (ctx :: Ctx k) (sub :: Ctx k)-   = IndexRange {-# UNPACK #-} !Int-                {-# UNPACK #-} !Int---- | Return a range containing all indices in the context.-allRange :: Size ctx -> IndexRange ctx ctx-allRange (Size n) = IndexRange 0 n---- | `indexOfRange` returns the only index in a range.-indexOfRange :: IndexRange ctx (EmptyCtx ::> e) -> Index ctx e-indexOfRange (IndexRange i n) = assert (n == 1) $ Index i---- | `dropTailRange r n` drops the last `n` elements in `r`.-dropTailRange :: IndexRange ctx (x <+> y) -> Size y -> IndexRange ctx x-dropTailRange (IndexRange i n) (Size j) = assert (n >= j) $ IndexRange i (n - j)---- | `dropHeadRange r n` drops the first `n` elements in `r`.-dropHeadRange :: IndexRange ctx (x <+> y) -> Size x -> IndexRange ctx y-dropHeadRange (IndexRange i n) (Size j) = assert (i' >= i && n >= j) $ IndexRange i' (n - j)-  where i' = i + j----------------------------------------------------------------------------- Height--data Height = Zero | Succ Height--type family Pred (k :: Height) :: Height-type instance Pred ('Succ h) = h----------------------------------------------------------------------------- BalancedTree---- | A balanced tree where all leaves are at the same height.------ The first parameter is the height of the tree.--- The second is the parameterized value.-data BalancedTree h (f :: k -> Type) (p :: Ctx k) where-  BalLeaf :: !(f x) -> BalancedTree 'Zero f (SingleCtx x)-  BalPair :: !(BalancedTree h f x)-          -> !(BalancedTree h f y)-          -> BalancedTree ('Succ h) f (x <+> y)--bal_size :: BalancedTree h f p -> Int-bal_size (BalLeaf _) = 1-bal_size (BalPair x y) = bal_size x + bal_size y---instance TestEqualityFC (BalancedTree h) where-  testEqualityFC test (BalLeaf x) (BalLeaf y) = do-    Refl <- test x y-    return Refl-  testEqualityFC test (BalPair x1 x2) (BalPair y1 y2) = do-    Refl <- testEqualityFC test x1 y1-    Refl <- testEqualityFC test x2 y2-    return Refl-#if !MIN_VERSION_base(4,9,0)-  testEqualityFC _ _ _ = Nothing-#endif--instance OrdFC (BalancedTree h) where-  compareFC test (BalLeaf x) (BalLeaf y) =-    joinOrderingF (test x y) $ EQF-#if !MIN_VERSION_base(4,9,0)-  compareFC _ BalLeaf{} _ = LTF-  compareFC _ _ BalLeaf{} = GTF-#endif-  compareFC test (BalPair x1 x2) (BalPair y1 y2) =-    joinOrderingF (compareFC test x1 y1) $-    joinOrderingF (compareFC test x2 y2) $-    EQF--instance HashableF f => HashableF (BalancedTree h f) where-  hashWithSaltF s t =-    case t of-      BalLeaf x -> s `hashWithSaltF` x-      BalPair x y -> s `hashWithSaltF` x `hashWithSaltF` y--fmap_bal :: (forall tp . f tp -> g tp)-         -> BalancedTree h f c-         -> BalancedTree h g c-fmap_bal = go-  where go :: (forall tp . f tp -> g tp)-              -> BalancedTree h f c-              -> BalancedTree h g c-        go f (BalLeaf x) = BalLeaf (f x)-        go f (BalPair x y) = BalPair (go f x) (go f y)-{-# INLINABLE fmap_bal #-}--traverse_bal :: Applicative m-             => (forall tp . f tp -> m (g tp))-             -> BalancedTree h f c-             -> m (BalancedTree h g c)-traverse_bal = go-  where go :: Applicative m-              => (forall tp . f tp -> m (g tp))-              -> BalancedTree h f c-              -> m (BalancedTree h g c)-        go f (BalLeaf x) = BalLeaf <$> f x-        go f (BalPair x y) = BalPair <$> go f x <*> go f y-{-# INLINABLE traverse_bal #-}--instance ShowF f => Show (BalancedTree h f tp) where-  show (BalLeaf x) = showF x-  show (BalPair x y) = "BalPair " Prelude.++ show x Prelude.++ " " Prelude.++ show y--instance ShowF f => ShowF (BalancedTree h f)--unsafe_bal_generate :: forall ctx h f t-                     . Int -- ^ Height of tree to generate-                    -> Int -- ^ Starting offset for entries.-                    -> (forall tp . Index ctx tp -> f tp)-                    -> BalancedTree h f t-unsafe_bal_generate h o f-  | h <  0 = error "unsafe_bal_generate given negative height"-  | h == 0 = unsafeCoerce $ BalLeaf (f (Index o))-  | otherwise =-    let l = unsafe_bal_generate (h-1) o f-        o' = o + 1 `shiftL` (h-1)-        u = assert (o + bal_size l == o') $ unsafe_bal_generate (h-1) o' f-     in unsafeCoerce $ BalPair l u--unsafe_bal_generateM :: forall m ctx h f t-                      . Applicative m-                     => Int -- ^ Height of tree to generate-                     -> Int -- ^ Starting offset for entries.-                     -> (forall x . Index ctx x -> m (f x))-                     -> m (BalancedTree h f t)-unsafe_bal_generateM h o f-  | h == 0 = unsafeCoerce . BalLeaf <$> f (Index o)-  | otherwise =-    let o' = o + 1 `shiftL` (h-1)-        g lv uv = assert (o' == o + bal_size lv) $-           unsafeCoerce (BalPair lv uv)-      in g <$> unsafe_bal_generateM (h-1) o  f-           <*> unsafe_bal_generateM (h-1) o' f---- | Lookup index in tree.-unsafe_bal_index :: BalancedTree h f a -- ^ Tree to lookup.-                 -> Int -- ^ Index to lookup.-                 -> Int  -- ^ Height of tree-                 -> f tp-unsafe_bal_index _ j i-  | seq j $ seq i $ False = error "bad unsafe_bal_index"-unsafe_bal_index (BalLeaf u) _ i = assert (i == 0) $ unsafeCoerce u-unsafe_bal_index (BalPair x y) j i-  | j `testBit` (i-1) = unsafe_bal_index y j $! (i-1)-  | otherwise         = unsafe_bal_index x j $! (i-1)---- | Update value at index in tree.-unsafe_bal_adjust :: Functor m-                  => (f x -> m (f y))-                  -> BalancedTree h f a -- ^ Tree to update-                  -> Int -- ^ Index to lookup.-                  -> Int  -- ^ Height of tree-                  -> m (BalancedTree h f b)-unsafe_bal_adjust f (BalLeaf u) _ i = assert (i == 0) $-  (unsafeCoerce . BalLeaf <$> (f (unsafeCoerce u)))-unsafe_bal_adjust f (BalPair x y) j i-  | j `testBit` (i-1) = (unsafeCoerce . BalPair x      <$> (unsafe_bal_adjust f y j (i-1)))-  | otherwise         = (unsafeCoerce . flip BalPair y <$> (unsafe_bal_adjust f x j (i-1)))--{-# SPECIALIZE unsafe_bal_adjust-     :: (f x -> Identity (f y))-     -> BalancedTree h f a-     -> Int-     -> Int-     -> Identity (BalancedTree h f b)-  #-}---- | Zip two balanced trees together.-bal_zipWithM :: Applicative m-             => (forall x . f x -> g x -> m (h x))-             -> BalancedTree u f a-             -> BalancedTree u g a-             -> m (BalancedTree u h a)-bal_zipWithM f (BalLeaf x) (BalLeaf y) = BalLeaf <$> f x y-bal_zipWithM f (BalPair x1 x2) (BalPair y1 y2) =-  BalPair <$> bal_zipWithM f x1 (unsafeCoerce y1)-          <*> bal_zipWithM f x2 (unsafeCoerce y2)-#if !MIN_VERSION_base(4,9,0)-bal_zipWithM _ _ _ = error "ilegal args to bal_zipWithM"-#endif-{-# INLINABLE bal_zipWithM #-}----------------------------------------------------------------------------- BinomialTree--data BinomialTree (h::Height) (f :: k -> Type) :: Ctx k -> Type where-  Empty :: BinomialTree h f EmptyCtx--  -- Contains size of the subtree, subtree, then element.-  PlusOne  :: !Int-           -> !(BinomialTree ('Succ h) f x)-           -> !(BalancedTree h f y)-           -> BinomialTree h f (x <+> y)--  -- Contains size of the subtree, subtree, then element.-  PlusZero  :: !Int-            -> !(BinomialTree ('Succ h) f x)-            -> BinomialTree h f x--tsize :: BinomialTree h f a -> Int-tsize Empty = 0-tsize (PlusOne s _ _) = 2*s+1-tsize (PlusZero  s _) = 2*s--t_cnt_size :: BinomialTree h f a -> Int-t_cnt_size Empty = 0-t_cnt_size (PlusOne _ l r) = t_cnt_size l + bal_size r-t_cnt_size (PlusZero  _ l) = t_cnt_size l---- | Concatenate a binomial tree and a balanced tree.-append :: BinomialTree h f x-       -> BalancedTree h f y-       -> BinomialTree h f (x <+> y)-append Empty y = PlusOne 0 Empty y-append (PlusOne _ t x) y =-  case assoc t x y of-    Refl ->-      let t' = append t (BalPair x y)-       in PlusZero (tsize t') t'-append (PlusZero s t) x = PlusOne s t x--instance TestEqualityFC (BinomialTree h) where-  testEqualityFC _ Empty Empty = return Refl-  testEqualityFC test (PlusZero _ x1) (PlusZero _ y1) = do-    Refl <- testEqualityFC test x1 y1-    return Refl-  testEqualityFC test (PlusOne _ x1 x2) (PlusOne _ y1 y2) = do-    Refl <- testEqualityFC test x1 y1-    Refl <- testEqualityFC test x2 y2-    return Refl-  testEqualityFC _ _ _ = Nothing--instance OrdFC (BinomialTree h) where-  compareFC _ Empty Empty = EQF-  compareFC _ Empty _ = LTF-  compareFC _ _ Empty = GTF--  compareFC test (PlusZero _ x1) (PlusZero _ y1) =-    joinOrderingF (compareFC test x1 y1) $ EQF-  compareFC _ PlusZero{} _ = LTF-  compareFC _ _ PlusZero{} = GTF--  compareFC test (PlusOne _ x1 x2) (PlusOne _ y1 y2) =-    joinOrderingF (compareFC test x1 y1) $-    joinOrderingF (compareFC test x2 y2) $-    EQF--instance HashableF f => HashableF (BinomialTree h f) where-  hashWithSaltF s t =-    case t of-      Empty -> s-      PlusZero _ x   -> s `hashWithSaltF` x-      PlusOne  _ x y -> s `hashWithSaltF` x `hashWithSaltF` y---- | Map over a binary tree.-fmap_bin :: (forall tp . f tp -> g tp)-         -> BinomialTree h f c-         -> BinomialTree h g c-fmap_bin _ Empty = Empty-fmap_bin f (PlusOne s t x) = PlusOne s (fmap_bin f t) (fmap_bal f x)-fmap_bin f (PlusZero s t)  = PlusZero s (fmap_bin f t)-{-# INLINABLE fmap_bin #-}--traverse_bin :: Applicative m-             => (forall tp . f tp -> m (g tp))-             -> BinomialTree h f c-             -> m (BinomialTree h g c)-traverse_bin _ Empty = pure Empty-traverse_bin f (PlusOne s t x) = PlusOne s  <$> traverse_bin f t <*> traverse_bal f x-traverse_bin f (PlusZero s t)  = PlusZero s <$> traverse_bin f t-{-# INLINABLE traverse_bin #-}--unsafe_bin_generate :: forall h f ctx t-                     . Int -- ^ Size of tree to generate-                    -> Int -- ^ Height of each element.-                    -> (forall x . Index ctx x -> f x)-                    -> BinomialTree h f t-unsafe_bin_generate sz h f-  | sz == 0 = unsafeCoerce Empty-  | sz `testBit` 0 =-    let s = sz `shiftR` 1-        t = unsafe_bin_generate s (h+1) f-        o = s * 2^(h+1)-        u = assert (o == t_cnt_size t) $ unsafe_bal_generate h o f-     in unsafeCoerce (PlusOne s t u)-  | otherwise =-    let s = sz `shiftR` 1-        t = unsafe_bin_generate (sz `shiftR` 1) (h+1) f-        r :: BinomialTree h f t-        r = PlusZero s t-    in r--unsafe_bin_generateM :: forall m h f ctx t-                      . Applicative m-                     => Int -- ^ Size of tree to generate-                     -> Int -- ^ Height of each element.-                     -> (forall x . Index ctx x -> m (f x))-                     -> m (BinomialTree h f t)-unsafe_bin_generateM sz h f-  | sz == 0 = pure (unsafeCoerce Empty)-  | sz `testBit` 0 =-    let s = sz `shiftR` 1-        t = unsafe_bin_generateM s (h+1) f-        -- Next offset-        o = s * 2^(h+1)-        u = unsafe_bal_generateM h o f-        r = unsafeCoerce (PlusOne s) <$> t <*> u-     in r-  | otherwise =-    let s = sz `shiftR` 1-        t = unsafe_bin_generateM s (h+1) f-        r :: m (BinomialTree h f t)-        r = PlusZero s <$> t-     in r----------------------------------------------------------------------------- Dropping--data DropResult f (ctx :: Ctx k) where-  DropEmpty :: DropResult f EmptyCtx-  DropExt   :: BinomialTree 'Zero f x-            -> f y-            -> DropResult f (x ::> y)---- | 'bal_drop x y' returns the tree formed 'append x (init y)'-bal_drop :: forall h f x y-          . BinomialTree h f x-            -- ^ Bina-         -> BalancedTree h f y-         -> DropResult f (x <+> y)-bal_drop t (BalLeaf e) = DropExt t e-bal_drop t (BalPair x y) =-  unsafeCoerce (bal_drop (PlusOne (tsize t) (unsafeCoerce t) x) y)--bin_drop :: forall h f ctx-          . BinomialTree h f ctx-         -> DropResult f ctx-bin_drop Empty = DropEmpty-bin_drop (PlusZero _ u) = bin_drop u-bin_drop (PlusOne s t u) =-  let m = case t of-            Empty -> Empty-            _ -> PlusZero s t-   in bal_drop m u----------------------------------------------------------------------------- Indexing---- | Lookup value in tree.-unsafe_bin_index :: BinomialTree h f a -- ^ Tree to lookup in.-                 -> Int-                 -> Int -- ^ Size of tree-                 -> f u-unsafe_bin_index _ _ i-  | seq i False = error "bad unsafe_bin_index"-unsafe_bin_index Empty _ _ = error "unsafe_bin_index reached end of list"-unsafe_bin_index (PlusOne sz t u) j i-  | sz == j `shiftR` (1+i) = unsafe_bal_index u j i-  | otherwise = unsafe_bin_index t j $! (1+i)-unsafe_bin_index (PlusZero sz t) j i-  | sz == j `shiftR` (1+i) = error "unsafe_bin_index stopped at PlusZero"-  | otherwise = unsafe_bin_index t j $! (1+i)---- | Lookup value in tree.-unsafe_bin_adjust :: forall m h f x y a b-                   . Functor m-                  => (f x -> m (f y))-                  -> BinomialTree h f a -- ^ Tree to lookup in.-                  -> Int-                  -> Int -- ^ Size of tree-                  -> m (BinomialTree h f b)-unsafe_bin_adjust _ Empty _ _ = error "unsafe_bin_adjust reached end of list"-unsafe_bin_adjust f (PlusOne sz t u) j i-  | sz == j `shiftR` (1+i) =-    unsafeCoerce . PlusOne sz t        <$> (unsafe_bal_adjust f u j i)-  | otherwise =-    unsafeCoerce . flip (PlusOne sz) u <$> (unsafe_bin_adjust f t j (i+1))-unsafe_bin_adjust f (PlusZero sz t) j i-  | sz == j `shiftR` (1+i) = error "unsafe_bin_adjust stopped at PlusZero"-  | otherwise = PlusZero sz <$> (unsafe_bin_adjust f t j (i+1))---{-# SPECIALIZE unsafe_bin_adjust-     :: (f x -> Identity (f y))-     -> BinomialTree h f a-     -> Int-     -> Int-     -> Identity (BinomialTree h f b)-  #-}--tree_zipWithM :: Applicative m-             => (forall x . f x -> g x -> m (h x))-             -> BinomialTree u f a-             -> BinomialTree u g a-             -> m (BinomialTree u h a)-tree_zipWithM _ Empty Empty = pure Empty-tree_zipWithM f (PlusOne s x1 x2) (PlusOne _ y1 y2) =-  PlusOne s <$> tree_zipWithM f x1 (unsafeCoerce y1)-            <*> bal_zipWithM  f x2 (unsafeCoerce y2)-tree_zipWithM f (PlusZero s x1) (PlusZero _ y1) =-  PlusZero s <$> tree_zipWithM f x1 y1-tree_zipWithM _ _ _ = error "ilegal args to tree_zipWithM"-{-# INLINABLE tree_zipWithM #-}----------------------------------------------------------------------------- Assignment---- | An assignment is a sequence that maps each index with type 'tp' to--- a value of type 'f tp'.------ This assignment implementation uses a binomial tree implementation--- that offers lookups and updates in time and space logarithmic with--- respect to the number of elements in the context.-newtype Assignment (f :: k -> Type) (ctx :: Ctx k)-      = Assignment (BinomialTree 'Zero f ctx)--type role Assignment nominal nominal--instance NFData (Assignment f ctx) where-  rnf a = seq a ()---- | Return number of elements in assignment.-size :: Assignment f ctx -> Size ctx-size (Assignment t) = Size (tsize t)---- | @replicate n@ make a context with different copies of the same--- polymorphic value.-replicate :: Size ctx -> (forall tp . f tp) -> Assignment f ctx-replicate n c = generate n (\_ -> c)---- | Generate an assignment-generate :: Size ctx-         -> (forall tp . Index ctx tp -> f tp)-         -> Assignment f ctx-generate n f  = Assignment r-  where r = unsafe_bin_generate (sizeInt n) 0 f-{-# NOINLINE generate #-}---- | Generate an assignment-generateM :: Applicative m-          => Size ctx-          -> (forall tp . Index ctx tp -> m (f tp))-          -> m (Assignment f ctx)-generateM n f = Assignment <$> unsafe_bin_generateM (sizeInt n) 0 f-{-# NOINLINE generateM #-}---- | Return empty assignment-empty :: Assignment f EmptyCtx-empty = Assignment Empty--extend :: Assignment f ctx -> f x -> Assignment f (ctx ::> x)-extend (Assignment x) y = Assignment $ append x (BalLeaf y)---- | Unexported index that returns an arbitrary type of expression.-unsafeIndex :: proxy u -> Int -> Assignment f ctx -> f u-unsafeIndex _ idx (Assignment t) = seq t $ unsafe_bin_index t idx 0---- | Return value of assignment.-(!) :: Assignment f ctx -> Index ctx tp -> f tp-a ! Index i = assert (0 <= i && i < sizeInt (size a)) $-              unsafeIndex Proxy i a---- | Return value of assignment, where the index is into an---   initial sequence of the assignment.-(!^) :: KnownDiff l r => Assignment f r -> Index l tp -> f tp-a !^ i = a ! extendIndex i--instance TestEqualityFC Assignment where-   testEqualityFC test (Assignment x) (Assignment y) = do-     Refl <- testEqualityFC test x y-     return Refl--instance TestEquality f => TestEquality (Assignment f) where-  testEquality = testEqualityFC testEquality--instance TestEquality f => Eq (Assignment f ctx) where-  x == y = isJust (testEquality x y)--instance OrdFC Assignment where-  compareFC test (Assignment x) (Assignment y) =-     joinOrderingF (compareFC test x y) $ EQF--instance OrdF f => OrdF (Assignment f) where-  compareF = compareFC compareF--instance OrdF f => Ord (Assignment f ctx) where-  compare x y = toOrdering (compareF x y)--instance HashableF (Index ctx) where-  hashWithSaltF s i = hashWithSalt s (indexVal i)--instance Hashable (Index ctx tp) where-  hashWithSalt = hashWithSaltF--instance HashableF f => Hashable (Assignment f ctx) where-  hashWithSalt s (Assignment a) = hashWithSaltF s a--instance HashableF f => HashableF (Assignment f) where-  hashWithSaltF = hashWithSalt--instance ShowF f => Show (Assignment f ctx) where-  show a = "[" Prelude.++ intercalate ", " (toListFC showF a) Prelude.++ "]"--instance ShowF f => ShowF (Assignment f)--{-# DEPRECATED adjust "Replace 'adjust f i asgn' with 'Lens.over (ixF i) f asgn' instead." #-}-adjust :: (f tp -> f tp) -> Index ctx tp -> Assignment f ctx -> Assignment f ctx-adjust f idx asgn = runIdentity (adjustM (Identity . f) idx asgn)--{-# DEPRECATED update "Replace 'update idx val asgn' with 'Lens.set (ixF idx) val asgn' instead." #-}-update :: Index ctx tp -> f tp -> Assignment f ctx -> Assignment f ctx-update i v a = adjust (\_ -> v) i a---- | Modify the value of an assignment at a particular index.-adjustM :: Functor m => (f tp -> m (f tp)) -> Index ctx tp -> Assignment f ctx -> m (Assignment f ctx)-adjustM f (Index i) (Assignment a) = Assignment <$> (unsafe_bin_adjust f a i 0)-{-# SPECIALIZE adjustM :: (f tp -> Identity (f tp)) -> Index ctx tp -> Assignment f ctx -> Identity (Assignment f ctx) #-}--type instance IndexF       (Assignment f ctx) = Index ctx-type instance IxValueF     (Assignment f ctx) = f--instance forall (f :: k -> Type) ctx. IxedF' k (Assignment (f :: k -> Type) ctx) where-  ixF' :: Index ctx x -> Lens.Lens' (Assignment f ctx) (f x)-  ixF' idx f = adjustM f idx--instance forall (f :: k -> Type) ctx. IxedF k (Assignment f ctx) where-  ixF = ixF'---- This is an unsafe version of update that changes the type of the expression.-unsafeUpdate :: Int -> Assignment f ctx -> f u -> Assignment f ctx'-unsafeUpdate i (Assignment a) e = Assignment (runIdentity (unsafe_bin_adjust (\_ -> Identity e) a i 0))---- | View an assignment as either empty or an assignment with one appended.-data AssignView f ctx where-  AssignEmpty :: AssignView f EmptyCtx-  AssignExtend :: Assignment f ctx-               -> f tp-               -> AssignView f (ctx::>tp)---- | View an assignment as either empty or an assignment with one appended.-viewAssign :: forall f ctx . Assignment f ctx -> AssignView f ctx-viewAssign (Assignment x) =-  case bin_drop x of-    DropEmpty -> AssignEmpty-    DropExt t v -> AssignExtend (Assignment t) v--zipWith :: (forall x . f x -> g x -> h x)-        -> Assignment f a-        -> Assignment g a-        -> Assignment h a-zipWith f = \x y -> runIdentity $ zipWithM (\u v -> pure (f u v)) x y-{-# INLINE zipWith #-}--zipWithM :: Applicative m-         => (forall x . f x -> g x -> m (h x))-         -> Assignment f a-         -> Assignment g a-         -> m (Assignment h a)-zipWithM f (Assignment x) (Assignment y) = Assignment <$> tree_zipWithM f x y-{-# INLINABLE zipWithM #-}--instance FunctorFC Assignment where-  fmapFC = \f (Assignment x) -> Assignment (fmap_bin f x)-  {-# INLINE fmapFC #-}--instance FoldableFC Assignment where-  foldMapFC = foldMapFCDefault-  {-# INLINE foldMapFC #-}--instance TraversableFC Assignment where-  traverseFC = \f (Assignment x) -> Assignment <$> traverse_bin f x-  {-# INLINE traverseFC #-}--traverseWithIndex :: Applicative m-                  => (forall tp . Index ctx tp -> f tp -> m (g tp))-                  -> Assignment f ctx-                  -> m (Assignment g ctx)-traverseWithIndex f a = generateM (size a) $ \i -> f i (a ! i)----------------------------------------------------------------------------- Appending--appendBal :: Assignment f x -> BalancedTree h f y -> Assignment f (x <+> y)-appendBal x (BalLeaf a) = x `extend` a-appendBal x (BalPair y z) =-  case assoc x y z of-    Refl -> x `appendBal` y `appendBal` z--appendBin :: Assignment f x -> BinomialTree h f y -> Assignment f (x <+> y)-appendBin x Empty = x-appendBin x (PlusOne _ y z) =-  case assoc x y z of-    Refl -> x `appendBin` y `appendBal` z-appendBin x (PlusZero _ y) = x `appendBin` y--(<++>) :: Assignment f x -> Assignment f y -> Assignment f (x <+> y)-x <++> Assignment y = x `appendBin` y----------------------------------------------------------------------------- KnownRepr instances--instance (KnownRepr (Assignment f) ctx, KnownRepr f bt)-      => KnownRepr (Assignment f) (ctx ::> bt) where-  knownRepr = knownRepr `extend` knownRepr--instance KnownRepr (Assignment f) EmptyCtx where-  knownRepr = empty----------------------------------------------------------------------------- Lens combinators--unsafeLens :: Int -> Lens.Lens (Assignment f ctx) (Assignment f ctx') (f tp) (f u)-unsafeLens idx =-  Lens.lens (unsafeIndex Proxy idx) (unsafeUpdate idx)----------------------------------------------------------------------------- 1 field lens combinators--type Assignment1 f x1 = Assignment f ('EmptyCtx '::> x1)--instance Lens.Field1 (Assignment1 f t) (Assignment1 f u) (f t) (f u) where-  _1 = unsafeLens 0----------------------------------------------------------------------------- 2 field lens combinators--type Assignment2 f x1 x2-   = Assignment f ('EmptyCtx '::> x1 '::> x2)--instance Lens.Field1 (Assignment2 f t x2) (Assignment2 f u x2) (f t) (f u) where-  _1 = unsafeLens 0--instance Lens.Field2 (Assignment2 f x1 t) (Assignment2 f x1 u) (f t) (f u) where-  _2 = unsafeLens 1----------------------------------------------------------------------------- 3 field lens combinators--type Assignment3 f x1 x2 x3-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3)--instance Lens.Field1 (Assignment3 f t x2 x3)-                     (Assignment3 f u x2 x3)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0---instance Lens.Field2 (Assignment3 f x1 t x3)-                     (Assignment3 f x1 u x3)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment3 f x1 x2 t)-                     (Assignment3 f x1 x2 u)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2----------------------------------------------------------------------------- 4 field lens combinators--type Assignment4 f x1 x2 x3 x4-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4)--instance Lens.Field1 (Assignment4 f t x2 x3 x4)-                     (Assignment4 f u x2 x3 x4)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0---instance Lens.Field2 (Assignment4 f x1 t x3 x4)-                     (Assignment4 f x1 u x3 x4)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment4 f x1 x2 t x4)-                     (Assignment4 f x1 x2 u x4)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment4 f x1 x2 x3 t)-                     (Assignment4 f x1 x2 x3 u)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3----------------------------------------------------------------------------- 5 field lens combinators--type Assignment5 f x1 x2 x3 x4 x5-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5)--instance Lens.Field1 (Assignment5 f t x2 x3 x4 x5)-                     (Assignment5 f u x2 x3 x4 x5)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0--instance Lens.Field2 (Assignment5 f x1 t x3 x4 x5)-                     (Assignment5 f x1 u x3 x4 x5)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment5 f x1 x2 t x4 x5)-                     (Assignment5 f x1 x2 u x4 x5)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment5 f x1 x2 x3 t x5)-                     (Assignment5 f x1 x2 x3 u x5)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3--instance Lens.Field5 (Assignment5 f x1 x2 x3 x4 t)-                     (Assignment5 f x1 x2 x3 x4 u)-                     (f t)-                     (f u) where-  _5 = unsafeLens 4----------------------------------------------------------------------------- 6 field lens combinators--type Assignment6 f x1 x2 x3 x4 x5 x6-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6)--instance Lens.Field1 (Assignment6 f t x2 x3 x4 x5 x6)-                     (Assignment6 f u x2 x3 x4 x5 x6)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0---instance Lens.Field2 (Assignment6 f x1 t x3 x4 x5 x6)-                     (Assignment6 f x1 u x3 x4 x5 x6)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment6 f x1 x2 t x4 x5 x6)-                     (Assignment6 f x1 x2 u x4 x5 x6)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment6 f x1 x2 x3 t x5 x6)-                     (Assignment6 f x1 x2 x3 u x5 x6)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3--instance Lens.Field5 (Assignment6 f x1 x2 x3 x4 t x6)-                     (Assignment6 f x1 x2 x3 x4 u x6)-                     (f t)-                     (f u) where-  _5 = unsafeLens 4--instance Lens.Field6 (Assignment6 f x1 x2 x3 x4 x5 t)-                     (Assignment6 f x1 x2 x3 x4 x5 u)-                     (f t)-                     (f u) where-  _6 = unsafeLens 5----------------------------------------------------------------------------- 7 field lens combinators--type Assignment7 f x1 x2 x3 x4 x5 x6 x7-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7)--instance Lens.Field1 (Assignment7 f t x2 x3 x4 x5 x6 x7)-                     (Assignment7 f u x2 x3 x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0---instance Lens.Field2 (Assignment7 f x1 t x3 x4 x5 x6 x7)-                     (Assignment7 f x1 u x3 x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment7 f x1 x2 t x4 x5 x6 x7)-                     (Assignment7 f x1 x2 u x4 x5 x6 x7)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment7 f x1 x2 x3 t x5 x6 x7)-                     (Assignment7 f x1 x2 x3 u x5 x6 x7)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3--instance Lens.Field5 (Assignment7 f x1 x2 x3 x4 t x6 x7)-                     (Assignment7 f x1 x2 x3 x4 u x6 x7)-                     (f t)-                     (f u) where-  _5 = unsafeLens 4--instance Lens.Field6 (Assignment7 f x1 x2 x3 x4 x5 t x7)-                     (Assignment7 f x1 x2 x3 x4 x5 u x7)-                     (f t)-                     (f u) where-  _6 = unsafeLens 5--instance Lens.Field7 (Assignment7 f x1 x2 x3 x4 x5 x6 t)-                     (Assignment7 f x1 x2 x3 x4 x5 x6 u)-                     (f t)-                     (f u) where-  _7 = unsafeLens 6----------------------------------------------------------------------------- 8 field lens combinators--type Assignment8 f x1 x2 x3 x4 x5 x6 x7 x8-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8)--instance Lens.Field1 (Assignment8 f t x2 x3 x4 x5 x6 x7 x8)-                     (Assignment8 f u x2 x3 x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0---instance Lens.Field2 (Assignment8 f x1 t x3 x4 x5 x6 x7 x8)-                     (Assignment8 f x1 u x3 x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment8 f x1 x2 t x4 x5 x6 x7 x8)-                     (Assignment8 f x1 x2 u x4 x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment8 f x1 x2 x3 t x5 x6 x7 x8)-                     (Assignment8 f x1 x2 x3 u x5 x6 x7 x8)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3--instance Lens.Field5 (Assignment8 f x1 x2 x3 x4 t x6 x7 x8)-                     (Assignment8 f x1 x2 x3 x4 u x6 x7 x8)-                     (f t)-                     (f u) where-  _5 = unsafeLens 4--instance Lens.Field6 (Assignment8 f x1 x2 x3 x4 x5 t x7 x8)-                     (Assignment8 f x1 x2 x3 x4 x5 u x7 x8)-                     (f t)-                     (f u) where-  _6 = unsafeLens 5--instance Lens.Field7 (Assignment8 f x1 x2 x3 x4 x5 x6 t x8)-                     (Assignment8 f x1 x2 x3 x4 x5 x6 u x8)-                     (f t)-                     (f u) where-  _7 = unsafeLens 6--instance Lens.Field8 (Assignment8 f x1 x2 x3 x4 x5 x6 x7 t)-                     (Assignment8 f x1 x2 x3 x4 x5 x6 x7 u)-                     (f t)-                     (f u) where-  _8 = unsafeLens 7----------------------------------------------------------------------------- 9 field lens combinators--type Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 x9-   = Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8 '::> x9)---instance Lens.Field1 (Assignment9 f t x2 x3 x4 x5 x6 x7 x8 x9)-                     (Assignment9 f u x2 x3 x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _1 = unsafeLens 0--instance Lens.Field2 (Assignment9 f x1 t x3 x4 x5 x6 x7 x8 x9)-                     (Assignment9 f x1 u x3 x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _2 = unsafeLens 1--instance Lens.Field3 (Assignment9 f x1 x2 t x4 x5 x6 x7 x8 x9)-                     (Assignment9 f x1 x2 u x4 x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _3 = unsafeLens 2--instance Lens.Field4 (Assignment9 f x1 x2 x3 t x5 x6 x7 x8 x9)-                     (Assignment9 f x1 x2 x3 u x5 x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _4 = unsafeLens 3--instance Lens.Field5 (Assignment9 f x1 x2 x3 x4 t x6 x7 x8 x9)-                     (Assignment9 f x1 x2 x3 x4 u x6 x7 x8 x9)-                     (f t)-                     (f u) where-  _5 = unsafeLens 4--instance Lens.Field6 (Assignment9 f x1 x2 x3 x4 x5 t x7 x8 x9)-                     (Assignment9 f x1 x2 x3 x4 x5 u x7 x8 x9)-                     (f t)-                     (f u) where-  _6 = unsafeLens 5--instance Lens.Field7 (Assignment9 f x1 x2 x3 x4 x5 x6 t x8 x9)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 u x8 x9)-                     (f t)-                     (f u) where-  _7 = unsafeLens 6--instance Lens.Field8 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 t x9)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 x7 u x9)-                     (f t)-                     (f u) where-  _8 = unsafeLens 7--instance Lens.Field9 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 t)-                     (Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 u)-                     (f t)-                     (f u) where-  _9 = unsafeLens 8
− submodules/parameterized-utils/src/Data/Parameterized/Ctx.hs
@@ -1,99 +0,0 @@-{-|-Description      : Type-level lists.-Copyright        : (c) Galois, Inc 2015-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This module defines type-level lists used for representing the type of-variables in a context.--}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE Safe #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}-module Data.Parameterized.Ctx-  ( type Ctx(..)-  , EmptyCtx-  , SingleCtx-  , (::>)-  , type (<+>)--    -- * Type context manipulation-  , CtxSize-  , CtxLookup-  , CtxUpdate-  , CtxLookupRight-  , CtxUpdateRight-  , CheckIx-  , ValidIx-  , FromLeft-  ) where--import Data.Kind (Constraint)-import GHC.TypeLits (Nat, type (+), type (-), type (<=?), TypeError, ErrorMessage(..))----------------------------------------------------------------------------- Ctx--type EmptyCtx = 'EmptyCtx-type (c :: Ctx k) ::> (a::k) = c '::> a--type SingleCtx x = EmptyCtx ::> x---- | Kind @'Ctx' k@ comprises lists of types of kind @k@.-data Ctx k-  = EmptyCtx-  | Ctx k ::> k---- | Append two type-level contexts.-type family (<+>) (x :: Ctx k) (y :: Ctx k) :: Ctx k where-  x <+> EmptyCtx = x-  x <+> (y ::> e) = (x <+> y) ::> e----- | This type family computes the number of elements in a 'Ctx'-type family CtxSize (a :: Ctx k) :: Nat where-  CtxSize 'EmptyCtx   = 0-  CtxSize (xs '::> x) = 1 + CtxSize xs---- | Helper type family used to generate descriptive error messages when--- an index is larger than the length of the 'Ctx' being indexed.-type family CheckIx (ctx :: Ctx k) (n :: Nat) (b :: Bool) :: Constraint where-  CheckIx ctx n 'True = ()-  CheckIx ctx n 'False = TypeError ('Text "Index "            ':<>: 'ShowType n-                              ':<>: 'Text " out of range in " ':<>: 'ShowType ctx)---- | A constraint that checks that the nat @n@ is a valid index into the---   context @ctx@, and raises a type error if not.-type ValidIx (n :: Nat) (ctx :: Ctx k)-  = CheckIx ctx n (n+1 <=? CtxSize ctx)---- | 'Ctx' is a snoc-list. In order to use the more intuitive left-to-right--- ordering of elements the desired index is subtracted from the total--- number of elements.-type FromLeft ctx n = CtxSize ctx - 1 - n---- | Lookup the value in a context by number, from the right-type family CtxLookupRight (n :: Nat) (ctx :: Ctx k) :: k where-  CtxLookupRight 0 (ctx '::> r) = r-  CtxLookupRight n (ctx '::> r) = CtxLookupRight (n-1) ctx---- | Update the value in a context by number, from the right.  If the index---   is out of range, the context is unchanged.-type family CtxUpdateRight (n :: Nat) (x::k) (ctx :: Ctx k) :: Ctx k where-  CtxUpdateRight n x 'EmptyCtx      = 'EmptyCtx-  CtxUpdateRight 0 x (ctx '::> old) = ctx '::> x-  CtxUpdateRight n x (ctx '::> y)   = CtxUpdateRight (n-1) x ctx '::> y---- | Lookup the value in a context by number, from the left.---   Produce a type error if the index is out of range.-type CtxLookup (n :: Nat) (ctx :: Ctx k)-  = CtxLookupRight (FromLeft ctx n) ctx---- | Update the value in a context by number, from the left.  If the index---   is out of range, the context is unchanged.-type CtxUpdate (n :: Nat) (x :: k) (ctx :: Ctx k)-  = CtxUpdateRight (FromLeft ctx n) x ctx
− submodules/parameterized-utils/src/Data/Parameterized/Ctx/Proofs.hs
@@ -1,23 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2015-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This reflects type level proofs involving contexts.--}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeOperators #-}-module Data.Parameterized.Ctx.Proofs-  ( leftId-  , assoc-  ) where--import Data.Type.Equality-import Unsafe.Coerce--import Data.Parameterized.Ctx--leftId :: p x -> (EmptyCtx <+> x) :~: x-leftId _ = unsafeCoerce Refl--assoc :: p x -> q y -> r z -> x <+> (y <+> z) :~: (x <+> y) <+> z-assoc _ _ _ = unsafeCoerce Refl
− submodules/parameterized-utils/src/Data/Parameterized/DecidableEq.hs
@@ -1,37 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2018-Maintainer       : Langston Barrett <langston@galois.com>--This defines a class @DecidableEq@, which represents decidable equality on a-type family.--This is different from GHC's @TestEquality@ in that it provides evidence-of non-equality. In fact, it is a superclass of @TestEquality@.--}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeInType #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE Safe #-}-module Data.Parameterized.DecidableEq-  ( DecidableEq(..)-  ) where--import Data.Void (Void)-import Data.Type.Equality ((:~:))---- | Decidable equality.-class DecidableEq f where-  decEq :: f a -> f b -> Either (a :~: b) ((a :~: b) -> Void)---- TODO: instances for sums, products of types with decidable equality---- import Data.Type.Equality ((:~:), TestEquality(..))--- instance (DecidableEq f) => TestEquality f where---   testEquality a b =---     case decEq a b of---       Left  prf -> Just prf---       Right _   -> Nothing
− submodules/parameterized-utils/src/Data/Parameterized/HashTable.hs
@@ -1,97 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.HashTable--- Copyright        : (c) Galois, Inc 2014--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module provides a ST-based hashtable for parameterized keys and values.------ NOTE: This API makes use of unsafeCoerce to implement the parameterized--- hashtable abstraction.  This should be typesafe provided the--- 'TestEquality' instance on the key type is implemented soundly.--------------------------------------------------------------------------{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE Trustworthy #-}-module Data.Parameterized.HashTable-  ( HashTable-  , new-  , newSized-  , clone-  , lookup-  , insert-  , member-  , delete-  , clear-  , Data.Parameterized.Classes.HashableF(..)-  , Control.Monad.ST.RealWorld-  ) where--import Control.Applicative-import Control.Monad.ST-import qualified Data.HashTable.ST.Cuckoo as H-import GHC.Exts (Any)-import Unsafe.Coerce--import Prelude hiding (lookup)--import Data.Parameterized.Classes-import Data.Parameterized.Some---- | A hash table mapping nonces to values.-newtype HashTable s (key :: k -> *) (val :: k -> *)-      = HashTable (H.HashTable s (Some key) Any)---- | Create a new empty table.-new :: ST s (HashTable s key val)-new = HashTable <$> H.new---- | Create a new empty table to hold 'n' elements.-newSized :: Int -> ST s (HashTable s k v)-newSized n = HashTable <$> H.newSized n---- | Create a hash table that is a copy of the current one.-clone :: (HashableF key, TestEquality key)-      => HashTable s key val-      -> ST s (HashTable s key val)-clone (HashTable tbl) = do-  -- Create a new table-  r <- H.new-  -- Insert existing elements in-  H.mapM_ (uncurry (H.insert r)) tbl-  -- Return table-  return $! HashTable r---- | Lookup value of key in table.-lookup :: (HashableF key, TestEquality key)-       => HashTable s key val-       -> key tp-       -> ST s (Maybe (val tp))-lookup (HashTable h) k = fmap unsafeCoerce <$> H.lookup h (Some k)-{-# INLINE lookup #-}---- | Insert new key and value mapping into table.-insert :: (HashableF key, TestEquality key)-       => HashTable s (key :: k -> *) (val :: k -> *)-       -> key tp-       -> val tp-       -> ST s ()-insert (HashTable h) k v = H.insert h (Some k) (unsafeCoerce v)---- | Return true if the key is in the hash table.-member :: (HashableF key, TestEquality key)-       => HashTable s (key :: k -> *) (val :: k -> *)-       -> key (tp :: k)-       -> ST s Bool-member (HashTable h) k = isJust <$> H.lookup h (Some k)---- | Delete an element from the hash table.-delete :: (HashableF key, TestEquality key)-       => HashTable s (key :: k -> *) (val :: k -> *)-       -> key (tp :: k)-       -> ST s ()-delete (HashTable h) k = H.delete h (Some k)--clear :: (HashableF key, TestEquality key)-      => HashTable s (key :: k -> *) (val :: k -> *) -> ST s ()-clear (HashTable h) = H.mapM_ (\(k,_) -> H.delete h k) h
− submodules/parameterized-utils/src/Data/Parameterized/List.hs
@@ -1,244 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2017-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This module defines a list over two parameters.  The first-is a fixed type-level function @k -> *@ for some kind @k@, and the-second is a list of types with kind k that provide the indices for-the values in the list.--This type is closely related to the @Context@ type in-@Data.Parameterized.Context@.--}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeOperators #-}-module Data.Parameterized.List-  ( List(..)-  , Index(..)-  , indexValue-  , (!!)-  , update-  , indexed-  , imap-  , ifoldr-  , izipWith-  , itraverse-    -- * Constants-  , index0-  , index1-  , index2-  , index3-  ) where--import qualified Control.Lens as Lens-import Prelude hiding ((!!))--import Data.Parameterized.Classes-import Data.Parameterized.TraversableFC---- | Parameterized list of elements.-data List :: (k -> *) -> [k] -> * where-  Nil  :: List f '[]-  (:<) :: f tp -> List f tps -> List f (tp : tps)--infixr 5 :<--instance ShowF f => Show (List f sh) where-  showsPrec _ Nil = showString "Nil"-  showsPrec p (elt :< rest) = showParen (p > precCons) $-    -- Unlike a derived 'Show' instance, we don't print parens implied-    -- by right associativity.-    showsPrecF (precCons+1) elt . showString " :< " . showsPrec 0 rest-    where-      precCons = 5--instance ShowF f => ShowF (List f)--instance FunctorFC List where-  fmapFC _ Nil = Nil-  fmapFC f (x :< xs) = f x :< fmapFC f xs--instance FoldableFC List where-  foldrFC _ z Nil = z-  foldrFC f z (x :< xs) = f x (foldrFC f z xs)--instance TraversableFC List where-  traverseFC _ Nil = pure Nil-  traverseFC f (h :< r) = (:<) <$> f h <*> traverseFC f r--instance TestEquality f => TestEquality (List f) where-  testEquality Nil Nil = Just Refl-  testEquality (xh :< xl) (yh :< yl) = do-    Refl <- testEquality xh yh-    Refl <- testEquality xl yl-    pure Refl-  testEquality _ _ = Nothing--instance OrdF f => OrdF (List f) where-  compareF Nil Nil = EQF-  compareF Nil _ = LTF-  compareF _ Nil = GTF-  compareF (xh :< xl) (yh :< yl) =-    lexCompareF xh yh $-    lexCompareF xl yl $-    EQF---instance KnownRepr (List f) '[] where-  knownRepr = Nil--instance (KnownRepr f s, KnownRepr (List f) sh) => KnownRepr (List f) (s ': sh) where-  knownRepr = knownRepr :< knownRepr------------------------------------------------------------------------------------- Indexed operations----- | Represents an index into a type-level list. Used in place of integers to---   1. ensure that the given index *does* exist in the list---   2. guarantee that it has the given kind-data Index :: [k] -> k -> *  where-  IndexHere :: Index (x:r) x-  IndexThere :: !(Index r y) -> Index (x:r) y--deriving instance Eq (Index l x)-deriving instance Show  (Index l x)--instance ShowF (Index l)--instance TestEquality (Index l) where-  testEquality IndexHere IndexHere = Just Refl-  testEquality (IndexThere x) (IndexThere y) = testEquality x y-  testEquality _ _ = Nothing--instance OrdF (Index l) where-  compareF IndexHere IndexHere = EQF-  compareF IndexHere IndexThere{} = LTF-  compareF IndexThere{} IndexHere = GTF-  compareF (IndexThere x) (IndexThere y) = compareF x y--instance Ord (Index sh x) where-  x `compare` y = toOrdering $ x `compareF` y---- | Return the index as an integer.-indexValue :: Index l tp -> Integer-indexValue = go 0-  where go :: Integer -> Index l tp -> Integer-        go i IndexHere = i-        go i (IndexThere x) = seq j $ go j x-          where j = i+1---- | Index 0-index0 :: Index (x:r) x-index0 = IndexHere---- | Index 1-index1 :: Index (x0:x1:r) x1-index1 = IndexThere index0---- | Index 2-index2 :: Index (x0:x1:x2:r) x2-index2 = IndexThere index1---- | Index 3-index3 :: Index (x0:x1:x2:x3:r) x3-index3 = IndexThere index2---- | Return the value in a list at a given index-(!!) :: List f l -> Index l x -> f x-l !! (IndexThere i) =-  case l of-    _ :< r -> r !! i-l !! IndexHere =-  case l of-    (h :< _) -> h---- | Update the 'List' at an index-update :: List f l -> Index l s -> (f s -> f s) -> List f l-update vals IndexHere upd =-  case vals of-    x :< rest -> upd x :< rest-update vals (IndexThere th) upd =-  case vals of-    x :< rest -> x :< update rest th upd---- | Provides a lens for manipulating the element at the given index.-indexed :: Index l x -> Lens.Simple Lens.Lens (List f l) (f x)-indexed IndexHere      f (x :< rest) = (:< rest) <$> f x-indexed (IndexThere i) f (x :< rest) = (x :<) <$> indexed i f rest------------------------------------------------------------------------------------- Indexed operations---- | Map over the elements in the list, and provide the index into--- each element along with the element itself.-imap :: forall f g l-     . (forall x . Index l x -> f x -> g x)-     -> List f l-     -> List g l-imap f = go id-  where-    go :: forall l'-        . (forall tp . Index l' tp -> Index l tp)-       -> List f l'-       -> List g l'-    go g l =-      case l of-        Nil -> Nil-        e :< rest -> f (g IndexHere) e :< go (g . IndexThere) rest---- | Right-fold with an additional index.-ifoldr :: forall sh a b . (forall tp . Index sh tp -> a tp -> b -> b) -> b -> List a sh -> b-ifoldr f seed0 l = go id l seed0-  where-    go :: forall tps-        . (forall tp . Index tps tp -> Index sh tp)-       -> List a tps-       -> b-       -> b-    go g ops b =-      case ops of-        Nil -> b-        a :< rest -> f (g IndexHere) a (go (\ix -> g (IndexThere ix)) rest b)---- | Zip up two lists with a zipper function, which can use the index.-izipWith :: forall a b c sh . (forall tp. Index sh tp -> a tp -> b tp -> c tp)-         -> List a sh-         -> List b sh-         -> List c sh-izipWith f = go id-  where-    go :: forall sh' .-          (forall tp . Index sh' tp -> Index sh tp)-       -> List a sh'-       -> List b sh'-       -> List c sh'-    go g as bs =-      case (as, bs) of-        (Nil, Nil) -> Nil-        (a :< as', b :< bs') ->-          f (g IndexHere) a b :< go (g . IndexThere) as' bs'---- | Traverse with an additional index.-itraverse :: forall a b sh t-          . Applicative t-          => (forall tp . Index sh tp -> a tp -> t (b tp))-          -> List a sh-          -> t (List b sh)-itraverse f = go id-  where-    go :: forall tps . (forall tp . Index tps tp -> Index sh tp)-       -> List a tps-       -> t (List b tps)-    go g l =-      case l of-        Nil -> pure Nil-        e :< rest -> (:<) <$> f (g IndexHere) e <*> go (\ix -> g (IndexThere ix)) rest
− submodules/parameterized-utils/src/Data/Parameterized/Map.hs
@@ -1,609 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2017--This module defines finite maps where the key and value types are-parameterized by an arbitrary kind.--Some code was adapted from containers.--}-{-# LANGUAGE CPP #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeInType #-}-module Data.Parameterized.Map-  ( MapF-    -- * Construction-  , Data.Parameterized.Map.empty-  , singleton-  , insert-  , insertWith-  , delete-  , union-    -- * Query-  , null-  , lookup-  , member-  , notMember-  , size-    -- * Conversion-  , keys-  , elems-  , fromList-  , toList-  , fromKeys-  , fromKeysM-   -- * Filter-  , filter-  , filterWithKey-  , filterGt-  , filterLt-    -- * Folds-  , foldlWithKey-  , foldlWithKey'-  , foldrWithKey-  , foldrWithKey'-  , foldMapWithKey-    -- * Traversal-  , map-  , mapWithKey-  , mapMaybe-  , mapMaybeWithKey-  , traverseWithKey-  , traverseWithKey_-    -- * Complex interface.-  , UpdateRequest(..)-  , Updated(..)-  , updatedValue-  , updateAtKey-  , mergeWithKeyM-  , module Data.Parameterized.Classes-    -- * Pair-  , Pair(..)-  ) where--import           Control.Applicative hiding (empty)-import           Control.Lens (Traversal', Lens')-import           Control.Monad.Identity-import           Data.Kind (Type)-import           Data.List (intercalate, foldl')-import           Data.Monoid--import           Data.Parameterized.Classes-import           Data.Parameterized.Some-import           Data.Parameterized.Pair ( Pair(..) )-import           Data.Parameterized.TraversableF-import           Data.Parameterized.Utils.BinTree-  ( MaybeS(..)-  , fromMaybeS-  , Updated(..)-  , updatedValue-  , TreeApp(..)-  , bin-  , IsBinTree(..)-  , balanceL-  , balanceR-  , glue-  )-import qualified Data.Parameterized.Utils.BinTree as Bin--#if MIN_VERSION_base(4,8,0)-import           Prelude hiding (filter, lookup, map, traverse, null)-#else-import           Prelude hiding (filter, lookup, map, null)-#endif----------------------------------------------------------------------------- Pair--comparePairKeys :: OrdF k => Pair k a -> Pair k a -> Ordering-comparePairKeys (Pair x _) (Pair y _) = toOrdering (compareF x y)-{-# INLINABLE comparePairKeys #-}----------------------------------------------------------------------------- MapF---- | A map from parameterized keys to values with the same parameter type.-data MapF (k :: v -> Type) (a :: v -> Type) where-  Bin :: {-# UNPACK #-}-         !Size -- Number of elements in tree.-      -> !(k x)-      -> !(a x)-      -> !(MapF k a)-      -> !(MapF k a)-      -> MapF k a-  Tip :: MapF k a--type Size = Int---- | Return empty map-empty :: MapF k a-empty = Tip---- | Return true if map is empty-null :: MapF k a -> Bool-null Tip = True-null Bin{} = False---- | Return map containing a single element-singleton :: k tp -> a tp -> MapF k a-singleton k x = Bin 1 k x Tip Tip--instance Bin.IsBinTree (MapF k a) (Pair k a) where-  asBin (Bin _ k v l r) = BinTree (Pair k v) l r-  asBin Tip = TipTree--  tip = Tip-  bin (Pair k v) l r = Bin (size l + size r + 1) k v l r--  size Tip              = 0-  size (Bin sz _ _ _ _) = sz--instance (TestEquality k, EqF a) => Eq (MapF k a) where-  x == y = size x == size y && toList x == toList y----------------------------------------------------------------------------- Traversals--#ifdef __GLASGOW_HASKELL__-{-# NOINLINE [1] map #-}-{-# NOINLINE [1] traverse #-}-{-# RULES-"map/map" forall (f :: (forall tp . f tp -> g tp)) (g :: (forall tp . g tp -> h tp)) xs-               . map g (map f xs) = map (g . f) xs-"map/traverse" forall (f :: (forall tp . f tp -> m (g tp))) (g :: (forall tp . g tp -> h tp)) xs-               . fmap (map g) (traverse f xs) = traverse (\v -> g <$> f v) xs-"traverse/map"-  forall (f :: (forall tp . f tp -> g tp)) (g :: (forall tp . g tp -> m (h tp))) xs-       . traverse g (map f xs) = traverse (\v -> g (f v)) xs-"traverse/traverse"-  forall (f :: (forall tp . f tp -> m (g tp))) (g :: (forall tp . g tp -> m (h tp))) xs-       . traverse f xs >>= traverse g = traverse (\v -> f v >>= g) xs- #-}-#endif----- | Apply function to all elements in map.-mapWithKey-  :: (forall tp . ktp tp -> f tp -> g tp)-  -> MapF ktp f-  -> MapF ktp g-mapWithKey _ Tip = Tip-mapWithKey f (Bin sx kx x l r) = Bin sx kx (f kx x) (mapWithKey f l) (mapWithKey f r)---- | Modify elements in a map-map :: (forall tp . f tp -> g tp) -> MapF ktp f -> MapF ktp g-map f = mapWithKey (\_ x -> f x)---- | Map keys and elements and collect `Just` results.-mapMaybeWithKey :: (forall tp . k tp -> f tp -> Maybe (g tp)) -> MapF k f -> MapF k g-mapMaybeWithKey _ Tip = Tip-mapMaybeWithKey f (Bin _ k x l r) =-  case f k x of-    Just y -> Bin.link (Pair k y) (mapMaybeWithKey f l) (mapMaybeWithKey f r)-    Nothing -> Bin.merge (mapMaybeWithKey f l) (mapMaybeWithKey f r)---- | Map elements and collect `Just` results.-mapMaybe :: (forall tp . f tp -> Maybe (g tp)) -> MapF ktp f -> MapF ktp g-mapMaybe f = mapMaybeWithKey (\_ x -> f x)---- | Traverse elements in a map-traverse :: Applicative m => (forall tp . f tp -> m (g tp)) -> MapF ktp f -> m (MapF ktp g)-traverse _ Tip = pure Tip-traverse f (Bin sx kx x l r) = Bin sx kx <$> f x <*> traverse f l <*> traverse f r---- | Traverse elements in a map-traverseWithKey-  :: Applicative m-  => (forall tp . ktp tp -> f tp -> m (g tp))-  -> MapF ktp f-  -> m (MapF ktp g)-traverseWithKey _ Tip = pure Tip-traverseWithKey f (Bin sx kx x l r) =-   Bin sx kx <$> f kx x <*> traverseWithKey f l <*> traverseWithKey f r---- | Traverse elements in a map without returning result.-traverseWithKey_-  :: Applicative m-  => (forall tp . ktp tp -> f tp -> m ())-  -> MapF ktp f-  -> m ()-traverseWithKey_ _ Tip = pure ()-traverseWithKey_ f (Bin _ kx x l r) = f kx x *> traverseWithKey_ f l *> traverseWithKey_ f r---type instance IndexF   (MapF k v) = k-type instance IxValueF (MapF k v) = v---- | Turn a map key into a traversal that visits the indicated element in the map, if it exists.-instance forall (k:: a -> Type) v. OrdF k => IxedF a (MapF k v) where-  ixF :: k x -> Traversal' (MapF k v) (v x)-  ixF i f m = updatedValue <$> updateAtKey i (pure Nothing) (\x -> Set <$> f x) m---- | Turn a map key into a lens that points into the indicated position in the map.-instance forall (k:: a -> Type) v. OrdF k => AtF a (MapF k v) where-  atF :: k x -> Lens' (MapF k v) (Maybe (v x))-  atF i f m = updatedValue <$> updateAtKey i (f Nothing) (\x -> maybe Delete Set <$> f (Just x)) m----- | Lookup value in map.-lookup :: OrdF k => k tp -> MapF k a -> Maybe (a tp)-lookup k0 = seq k0 (go k0)-  where-    go :: OrdF k => k tp -> MapF k a -> Maybe (a tp)-    go _ Tip = Nothing-    go k (Bin _ kx x l r) =-      case compareF k kx of-        LTF -> go k l-        GTF -> go k r-        EQF -> Just x-{-# INLINABLE lookup #-}---- | Return true if key is bound in map.-member :: OrdF k => k tp -> MapF k a -> Bool-member k0 = seq k0 (go k0)-  where-    go :: OrdF k => k tp -> MapF k a -> Bool-    go _ Tip = False-    go k (Bin _ kx _ l r) =-      case compareF k kx of-        LTF -> go k l-        GTF -> go k r-        EQF -> True-{-# INLINABLE member #-}---- | Return true if key is not bound in map.-notMember :: OrdF k => k tp -> MapF k a -> Bool-notMember k m = not $ member k m-{-# INLINABLE notMember #-}--instance FunctorF (MapF ktp) where-  fmapF = map--instance FoldableF (MapF ktp) where-  foldrF f z = go z-    where go z' Tip             = z'-          go z' (Bin _ _ x l r) = go (f x (go z' r)) l--instance TraversableF (MapF ktp) where-  traverseF = traverse--instance (ShowF ktp, ShowF rtp) => Show (MapF ktp rtp) where-  show m = showMap showF showF m---- | Return all keys of the map in ascending order.-keys :: MapF k a -> [Some k]-keys = foldrWithKey (\k _ l -> Some k : l) []---- | Return all elements of the map in the ascending order of their keys.-elems :: MapF k a -> [Some a]-elems = foldrF (\e l -> Some e : l) []---- | Perform a left fold with the key also provided.-foldlWithKey :: (forall s . b -> k s -> a s -> b) -> b -> MapF k a -> b-foldlWithKey _ z Tip = z-foldlWithKey f z (Bin _ kx x l r) =-  let lz = foldlWithKey f z l-      kz = f lz kx x-   in foldlWithKey f kz r---- | Perform a strict left fold with the key also provided.-foldlWithKey' :: (forall s . b -> k s -> a s -> b) -> b -> MapF k a -> b-foldlWithKey' _ z Tip = z-foldlWithKey' f z (Bin _ kx x l r) =-  let lz = foldlWithKey f z l-      kz = seq lz $ f lz kx x-   in seq kz $ foldlWithKey f kz r---- | Perform a right fold with the key also provided.-foldrWithKey :: (forall s . k s -> a s -> b -> b) -> b -> MapF k a -> b-foldrWithKey _ z Tip = z-foldrWithKey f z (Bin _ kx x l r) =-  let rz = foldrWithKey f z r-      kz = f kx x rz-   in foldrWithKey f kz l---- | Perform a strict right fold with the key also provided.-foldrWithKey' :: (forall s . k s -> a s -> b -> b) -> b -> MapF k a -> b-foldrWithKey' _ z Tip = z-foldrWithKey' f z (Bin _ kx x l r) =-  let rz = foldrWithKey f z r-      kz = seq rz $ f kx x rz-   in seq kz $ foldrWithKey f kz l---- | Fold the keys and values using the given monoid.-foldMapWithKey :: Monoid m => (forall s . k s -> a s -> m) -> MapF k a -> m-foldMapWithKey _ Tip = mempty-foldMapWithKey f (Bin _ kx x l r) = foldMapWithKey f l <> f kx x <> foldMapWithKey f r--showMap :: (forall tp . ktp tp -> String)-        -> (forall tp . rtp tp -> String)-        -> MapF ktp rtp-        -> String-showMap ppk ppv m = "{ " ++ intercalate ", " l ++ " }"-  where l = foldrWithKey (\k a l0 -> (ppk k ++ " -> " ++ ppv a) : l0) [] m----------------------------------------------------------------------------- filter---- | Return entries with values that satisfy predicate.-filter :: (forall tp . f tp -> Bool) -> MapF k f -> MapF k f-filter f = filterWithKey (\_ v -> f v)---- | Return key-value pairs that satisfy predicate.-filterWithKey :: (forall tp . k tp -> f tp -> Bool) -> MapF k f -> MapF k f-filterWithKey _ Tip = Tip-filterWithKey f (Bin _ k x l r)-  | f k x     = Bin.link (Pair k x) (filterWithKey f l) (filterWithKey f r)-  | otherwise = Bin.merge (filterWithKey f l) (filterWithKey f r)--compareKeyPair :: OrdF k => k tp -> Pair k a -> Ordering-compareKeyPair k = \(Pair x _) -> toOrdering (compareF k x)---- | @filterGt k m@ returns submap of @m@ that only contains entries--- that are larger than @k@.-filterGt :: OrdF k => k tp -> MapF k v -> MapF k v-filterGt k m = fromMaybeS m (Bin.filterGt (compareKeyPair k) m)-{-# INLINABLE filterGt #-}---- | @filterLt k m@ returns submap of @m@ that only contains entries--- that are smaller than @k@.-filterLt :: OrdF k => k tp -> MapF k v -> MapF k v-filterLt k m = fromMaybeS m (Bin.filterLt (compareKeyPair k) m)-{-# INLINABLE filterLt #-}----------------------------------------------------------------------------- User operations---- | Insert a binding into the map, replacing the existing binding if needed.-insert :: OrdF k => k tp -> a tp -> MapF k a -> MapF k a-insert = \k v m -> seq k $ updatedValue (Bin.insert comparePairKeys (Pair k v) m)-{-# INLINABLE insert #-}--- {-# SPECIALIZE Bin.insert :: OrdF k => Pair k a -> MapF k a -> Updated (MapF k a) #-}---- | Insert a binding into the map, replacing the existing binding if needed.-insertWithImpl :: OrdF k => (a tp -> a tp -> a tp) -> k tp -> a tp -> MapF k a -> Updated (MapF k a)-insertWithImpl f k v t = seq k $-  case t of-    Tip -> Bin.Updated (Bin 1 k v Tip Tip)-    Bin sz yk yv l r ->-      case compareF k yk of-        LTF ->-          case insertWithImpl f k v l of-            Bin.Updated l'   -> Bin.Updated   (Bin.balanceL (Pair yk yv) l' r)-            Bin.Unchanged l' -> Bin.Unchanged (Bin sz yk yv l' r)-        GTF ->-          case insertWithImpl f k v r of-            Bin.Updated r'   -> Bin.Updated   (Bin.balanceR (Pair yk yv) l r')-            Bin.Unchanged r' -> Bin.Unchanged (Bin sz yk yv l r')-        EQF -> Bin.Unchanged (Bin sz yk (f v yv) l r)-{-# INLINABLE insertWithImpl #-}---- | @insertWith f new m@ inserts the binding into @m@.------ It inserts @f new old@ if @m@ already contains an equivaltn value--- @old@, and @new@ otherwise.  It returns an Unchanged value if the--- map stays the same size and an updated value if a new entry was--- inserted.-insertWith :: OrdF k => (a tp -> a tp -> a tp) -> k tp -> a tp -> MapF k a -> MapF k a-insertWith = \f k v t -> seq k $ updatedValue (insertWithImpl f k v t)-{-# INLINABLE insertWith #-}---- | Delete a value from the map if present.-delete :: OrdF k => k tp -> MapF k a -> MapF k a-delete = \k m -> seq k $ fromMaybeS m $ Bin.delete (p k) m-  where p :: OrdF k => k tp -> Pair k a -> Ordering-        p k (Pair kx _) = toOrdering (compareF k kx)-{-# INLINABLE delete #-}-{-# SPECIALIZE Bin.delete :: (Pair k a -> Ordering) -> MapF k a -> MaybeS (MapF k a) #-}---- | Union two sets-union :: OrdF k => MapF k a -> MapF k a -> MapF k a-union t1 t2 = Bin.union comparePairKeys t1 t2-{-# INLINABLE union #-}--- {-# SPECIALIZE Bin.union compare :: OrdF k => MapF k a -> MapF k a -> MapF k a #-}----------------------------------------------------------------------------- updateAtKey---- | Update request tells when to do with value-data UpdateRequest v-   = -- | Keep the current value.-     Keep-     -- | Set the value to a new value.-   | Set !v-     -- | Delete a value.-   | Delete--data AtKeyResult k a where-  AtKeyUnchanged :: AtKeyResult k a-  AtKeyInserted :: MapF k a -> AtKeyResult k a-  AtKeyModified :: MapF k a -> AtKeyResult k a-  AtKeyDeleted  :: MapF k a -> AtKeyResult k a--atKey' :: (OrdF k, Functor f)-       => k tp-       -> f (Maybe (a tp)) -- ^ Function to call if no element is found.-       -> (a tp -> f (UpdateRequest (a tp)))-       -> MapF k a-       -> f (AtKeyResult k a)-atKey' k onNotFound onFound t =-  case asBin t of-    TipTree -> ins <$> onNotFound-      where ins Nothing  = AtKeyUnchanged-            ins (Just v) = AtKeyInserted (singleton k v)-    BinTree yp@(Pair kx y) l r ->-      case compareF k kx of-        LTF -> ins <$> atKey' k onNotFound onFound l-          where ins AtKeyUnchanged = AtKeyUnchanged-                ins (AtKeyInserted l') = AtKeyInserted (balanceL yp l' r)-                ins (AtKeyModified l') = AtKeyModified (bin      yp l' r)-                ins (AtKeyDeleted  l') = AtKeyDeleted  (balanceR yp l' r)-        GTF -> ins <$> atKey' k onNotFound onFound r-          where ins AtKeyUnchanged = AtKeyUnchanged-                ins (AtKeyInserted r') = AtKeyInserted (balanceR yp l r')-                ins (AtKeyModified r') = AtKeyModified (bin      yp l r')-                ins (AtKeyDeleted  r') = AtKeyDeleted  (balanceL yp l r')-        EQF -> ins <$> onFound y-          where ins Keep    = AtKeyUnchanged-                ins (Set x) = AtKeyModified (bin (Pair kx x) l r)-                ins Delete  = AtKeyDeleted (glue l r)-{-# INLINABLE atKey' #-}---- | Log-time algorithm that allows a value at a specific key to be added, replaced,--- or deleted.-updateAtKey :: (OrdF k, Functor f)-            => k tp -- ^ Key to update-            -> f (Maybe (a tp))-               -- ^ Action to call if nothing is found-            -> (a tp -> f (UpdateRequest (a tp)))-               -- ^ Action to call if value is found.-            -> MapF k a-               -- ^ Map to update-            -> f (Updated (MapF k a))-updateAtKey k onNotFound onFound t = ins <$> atKey' k onNotFound onFound t-  where ins AtKeyUnchanged = Unchanged t-        ins (AtKeyInserted t') = Updated t'-        ins (AtKeyModified t') = Updated t'-        ins (AtKeyDeleted  t') = Updated t'-{-# INLINABLE updateAtKey #-}---- | Create a Map from a list of pairs.-fromList :: OrdF k => [Pair k a] -> MapF k a-fromList = foldl' (\m (Pair k a) -> insert k a m) Data.Parameterized.Map.empty--toList :: MapF k a -> [Pair k a]-toList = foldrWithKey (\k x m -> Pair k x : m) []---- | Generate a map from a foldable collection of keys and a--- function from keys to values.-fromKeys :: forall m (t :: Type -> Type) (a :: k -> Type) (v :: k -> Type)-          .  (Monad m, Foldable t, OrdF a)-            => (forall tp . a tp -> m (v tp))-            -- ^ Function for evaluating a register value.-            -> t (Some a)-               -- ^ Set of X86 registers-            -> m (MapF a v)-fromKeys f = foldM go empty-  where go :: MapF a v -> Some a -> m (MapF a v)-        go m (Some k) = (\v -> insert k v m) <$> f k---- | Generate a map from a foldable collection of keys and a monadic--- function from keys to values.-fromKeysM :: forall m (t :: Type -> Type) (a :: k -> Type) (v :: k -> Type)-          .  (Monad m, Foldable t, OrdF a)-           => (forall tp . a tp -> m (v tp))-           -- ^ Function for evaluating a register value.-           -> t (Some a)-           -- ^ Set of X86 registers-           -> m (MapF a v)-fromKeysM f = foldM go empty-  where go :: MapF a v -> Some a -> m (MapF a v)-        go m (Some k) = (\v -> insert k v m) <$> f k--filterGtMaybe :: OrdF k => MaybeS (k x) -> MapF k a -> MapF k a-filterGtMaybe NothingS m = m-filterGtMaybe (JustS k) m = filterGt k m--filterLtMaybe :: OrdF k => MaybeS (k x) -> MapF k a -> MapF k a-filterLtMaybe NothingS m = m-filterLtMaybe (JustS k) m = filterLt k m---- | Merge bindings in two maps to get a third.-mergeWithKeyM :: forall k a b c m-               . (Applicative m, OrdF k)-              => (forall tp . k tp -> a tp -> b tp -> m (Maybe (c tp)))-              -> (MapF k a -> m (MapF k c))-              -> (MapF k b -> m (MapF k c))-              -> MapF k a-              -> MapF k b-              -> m (MapF k c)-mergeWithKeyM f g1 g2 = go-  where-    go Tip t2 = g2 t2-    go t1 Tip = g1 t1-    go t1 t2 = hedgeMerge NothingS NothingS t1 t2--    hedgeMerge :: MaybeS (k x) -> MaybeS (k y) -> MapF k a -> MapF k b -> m (MapF k c)-    hedgeMerge _   _   t1  Tip = g1 t1-    hedgeMerge blo bhi Tip (Bin _ kx x l r) =-      g2 $ Bin.link (Pair kx x) (filterGtMaybe blo l) (filterLtMaybe bhi r)-    hedgeMerge blo bhi (Bin _ kx x l r) t2 =-        let Bin.PairS found trim_t2 = trimLookupLo kx bhi t2-            resolve_g1 :: MapF k c -> MapF k c -> MapF k c -> MapF k c-            resolve_g1 Tip = Bin.merge-            resolve_g1 (Bin _ k' x' Tip Tip) = Bin.link (Pair k' x')-            resolve_g1 _ = error "mergeWithKey: Bad function g1"-            resolve_f Nothing = Bin.merge-            resolve_f (Just x') = Bin.link (Pair kx x')-         in case found of-              Nothing ->-                resolve_g1 <$> g1 (singleton kx x)-                           <*> hedgeMerge blo bmi l (trim blo bmi t2)-                           <*> hedgeMerge bmi bhi r trim_t2-              Just x2 ->-                resolve_f <$> f kx x x2-                          <*> hedgeMerge blo bmi l (trim blo bmi t2)-                          <*> hedgeMerge bmi bhi r trim_t2-      where bmi = JustS kx-{-# INLINABLE mergeWithKeyM #-}--{---------------------------------------------------------------------  [trim blo bhi t] trims away all subtrees that surely contain no-  values between the range [blo] to [bhi]. The returned tree is either-  empty or the key of the root is between @blo@ and @bhi@.---------------------------------------------------------------------}-trim :: OrdF k => MaybeS (k x) -> MaybeS (k y) -> MapF k a -> MapF k a-trim NothingS   NothingS   t = t-trim (JustS lk) NothingS   t = filterGt lk t-trim NothingS   (JustS hk) t = filterLt hk t-trim (JustS lk) (JustS hk) t = filterMiddle lk hk t---- | Returns only entries that are strictly between the two keys.-filterMiddle :: OrdF k => k x -> k y -> MapF k a -> MapF k a-filterMiddle lo hi (Bin _ k _ _ r)-  | k `leqF` lo = filterMiddle lo hi r-filterMiddle lo hi (Bin _ k _ l _)-  | k `geqF` hi = filterMiddle lo hi l-filterMiddle _  _  t = t-{-# INLINABLE filterMiddle #-}------ Helper function for 'mergeWithKey'. The @'trimLookupLo' lk hk t@ performs both--- @'trim' (JustS lk) hk t@ and @'lookup' lk t@.---- See Note: Type of local 'go' function-trimLookupLo :: OrdF k => k tp -> MaybeS (k y) -> MapF k a -> Bin.PairS (Maybe (a tp)) (MapF k a)-trimLookupLo lk NothingS t = greater lk t-  where greater :: OrdF k => k tp -> MapF k a -> Bin.PairS (Maybe (a tp)) (MapF k a)-        greater lo t'@(Bin _ kx x l r) =-           case compareF lo kx of-             LTF -> Bin.PairS (lookup lo l) t'-             EQF -> Bin.PairS (Just x) r-             GTF -> greater lo r-        greater _ Tip = Bin.PairS Nothing Tip-trimLookupLo lk (JustS hk) t = middle lk hk t-  where middle :: OrdF k => k tp -> k y -> MapF k a -> Bin.PairS (Maybe (a tp)) (MapF k a)-        middle lo hi t'@(Bin _ kx x l r) =-          case compareF lo kx of-            LTF | kx `ltF` hi -> Bin.PairS (lookup lo l) t'-                | otherwise -> middle lo hi l-            EQF -> Bin.PairS (Just x) (lesser hi r)-            GTF -> middle lo hi r-        middle _ _ Tip = Bin.PairS Nothing Tip--        lesser :: OrdF k => k y -> MapF k a -> MapF k a-        lesser hi (Bin _ k _ l _) | k `geqF` hi = lesser hi l-        lesser _ t' = t'
− submodules/parameterized-utils/src/Data/Parameterized/NatRepr.hs
@@ -1,690 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2018-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This defines a type 'NatRepr' for representing a type-level natural-at runtime.  This can be used to branch on a type-level value.  For-each @n@, @NatRepr n@ contains a single value containing the vlaue-@n@.  This can be used to help use type-level variables on code-with data dependendent types.--The @TestEquality@ and @DecidableEq@ instances for 'NatRepr'-are implemented using 'unsafeCoerce', as is the `isZeroNat` function. This-should be typesafe because we maintain the invariant that the integer value-contained in a NatRepr value matches its static type.--}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE EmptyCase #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeApplications #-}-#if MIN_VERSION_base(4,9,0)-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-#endif-#if __GLASGOW_HASKELL__ >= 805-{-# LANGUAGE NoStarIsType #-}-#endif-module Data.Parameterized.NatRepr-  ( NatRepr-  , natValue-  , intValue-  , knownNat-  , withKnownNat-  , IsZeroNat(..)-  , isZeroNat-  , isZeroOrGT1-  , NatComparison(..)-  , compareNat-  , decNat-  , predNat-  , incNat-  , addNat-  , subNat-  , divNat-  , halfNat-  , withDivModNat-  , natMultiply-  , someNat-  , mkNatRepr-  , maxNat-  , natRec-  , natRecStrong-  , natRecBounded-  , natForEach-  , natFromZero-  , NatCases(..)-  , testNatCases-    -- * Strict order-  , lessThanIrreflexive-  , lessThanAsymmetric-    -- * Bitvector utilities-  , widthVal-  , minUnsigned-  , maxUnsigned-  , minSigned-  , maxSigned-  , toUnsigned-  , toSigned-  , unsignedClamp-  , signedClamp-    -- * LeqProof-  , LeqProof(..)-  , decideLeq-  , testLeq-  , testStrictLeq-  , leqRefl-  , leqTrans-  , leqAdd2-  , leqSub2-  , leqMulCongr-    -- * LeqProof combinators-  , leqProof-  , withLeqProof-  , isPosNat-  , leqAdd-  , leqSub-  , leqMulPos-  , leqAddPos-  , addIsLeq-  , withAddLeq-  , addPrefixIsLeq-  , withAddPrefixLeq-  , addIsLeqLeft1-  , dblPosIsPos-  , leqMulMono-    -- * Arithmetic proof-  , plusComm-  , mulComm-  , plusMinusCancel-  , minusPlusCancel-  , addMulDistribRight-  , withAddMulDistribRight-  , withSubMulDistribRight-  , mulCancelR-  , mul2Plus-  , lemmaMul-    -- * Re-exports typelists basics---  , NatK-  , type (+)-  , type (-)-  , type (*)-  , type (<=)-  , Equality.TestEquality(..)-  , (Equality.:~:)(..)-  , Data.Parameterized.Some.Some-    -- * Backdoor, no touchy-  , activateNatReprCoercionBackdoor_IPromiseIKnowWhatIAmDoing-  ) where--import Data.Bits ((.&.), bit)-import Data.Hashable-import Data.Proxy as Proxy-import Data.Type.Equality as Equality-import Data.Void as Void-import Numeric.Natural-import GHC.TypeNats as TypeNats-import Unsafe.Coerce--import Data.Parameterized.Classes-import Data.Parameterized.DecidableEq-import Data.Parameterized.Some--maxInt :: Natural-maxInt = fromIntegral (maxBound :: Int)----------------------------------------------------------------------------- Nat---- | A runtime presentation of a type-level 'Nat'.------ This can be used for performing dynamic checks on a type-level natural--- numbers.-newtype NatRepr (n::Nat) = NatRepr { natValue :: Natural-                                     -- ^ The underlying natural value of the number.-                                   }-  deriving (Hashable)--type role NatRepr nominal--intValue :: NatRepr n -> Integer-intValue n = toInteger (natValue n)-{-# INLINE intValue #-}---- | If you are not 110% sure what the consequences of using this are and---   how to use it, don't.-activateNatReprCoercionBackdoor_IPromiseIKnowWhatIAmDoing :: ((Natural -> NatRepr n) -> a) -> a-activateNatReprCoercionBackdoor_IPromiseIKnowWhatIAmDoing k = k NatRepr-{-# INLINE activateNatReprCoercionBackdoor_IPromiseIKnowWhatIAmDoing #-}---- | Return the value of the nat representation.-widthVal :: NatRepr n -> Int-widthVal (NatRepr i) | i <= maxInt = fromIntegral i-                     | otherwise   = error ("Width is too large: " ++ show i)--instance Eq (NatRepr m) where-  _ == _ = True--instance TestEquality NatRepr where-  testEquality (NatRepr m) (NatRepr n)-    | m == n = Just (unsafeCoerce Refl)-    | otherwise = Nothing--instance DecidableEq NatRepr where-  decEq (NatRepr m) (NatRepr n)-    | m == n    = Left $ unsafeCoerce Refl-    | otherwise = Right $-        \x -> seq x $ error "Impossible [DecidableEq on NatRepr]"---- | Result of comparing two numbers.-data NatComparison m n where-  -- First number is less than second.-  NatLT :: x+1 <= x+(y+1) => !(NatRepr y) -> NatComparison x (x+(y+1))-  NatEQ :: NatComparison x x-  -- First number is greater than second.-  NatGT :: x+1 <= x+(y+1) => !(NatRepr y) -> NatComparison (x+(y+1)) x--compareNat :: NatRepr m -> NatRepr n -> NatComparison m n-compareNat m n =-  case compare (natValue m) (natValue n) of-    LT -> unsafeCoerce (NatLT @0 @0) (NatRepr (natValue n - natValue m - 1))-    EQ -> unsafeCoerce  NatEQ-    GT -> unsafeCoerce (NatGT @0 @0) (NatRepr (natValue m - natValue n - 1))--instance OrdF NatRepr where-  compareF x y =-    case compareNat x y of-      NatLT _ -> LTF-      NatEQ -> EQF-      NatGT _ -> GTF--instance PolyEq (NatRepr m) (NatRepr n) where-  polyEqF x y = fmap (\Refl -> Refl) $ testEquality x y--instance Show (NatRepr n) where-  show (NatRepr n) = show n--instance ShowF NatRepr--instance HashableF NatRepr where-  hashWithSaltF = hashWithSalt---- | This generates a NatRepr from a type-level context.-knownNat :: forall n . KnownNat n => NatRepr n-knownNat = NatRepr (natVal (Proxy :: Proxy n))--instance (KnownNat n) => KnownRepr NatRepr n where-  knownRepr = knownNat--withKnownNat :: forall n r. NatRepr n -> (KnownNat n => r) -> r-withKnownNat (NatRepr nVal) v =-  case someNatVal nVal of-    SomeNat (Proxy :: Proxy n') ->-      case unsafeCoerce (Refl :: n :~: n) :: n :~: n' of-        Refl -> v--data IsZeroNat n where-  ZeroNat    :: IsZeroNat 0-  NonZeroNat :: IsZeroNat (n+1)--isZeroNat :: NatRepr n -> IsZeroNat n-isZeroNat (NatRepr 0) = unsafeCoerce ZeroNat-isZeroNat (NatRepr _) = unsafeCoerce NonZeroNat---- | Every nat is either zero or >= 1.-isZeroOrGT1 :: NatRepr n -> Either (n :~: 0) (LeqProof 1 n)-isZeroOrGT1 n =-  case isZeroNat n of-    ZeroNat    -> Left Refl-    NonZeroNat -> Right $-      -- We have n = m + 1 for some m.-      let-        -- | x <= x + 1-        leqSucc:: forall x. LeqProof x (x+1)-        leqSucc = leqAdd2 (LeqProof :: LeqProof x x) (LeqProof :: LeqProof 0 1)-        leqPlus :: forall f x y. ((x + 1) ~ y) => f x ->  LeqProof 1 y-        leqPlus fx =-          case (plusComm fx (knownNat @1) :: x + 1 :~: 1 + x)    of { Refl ->-          case (plusMinusCancel (knownNat @1) fx :: 1+x-x :~: 1) of { Refl ->-          case (LeqProof :: LeqProof (x+1) y)                    of { LeqProof ->-          case (LeqProof :: LeqProof (1+x-x) (y-x))              of { LeqProof ->-            leqTrans (LeqProof :: LeqProof 1 (y-x))-                     (leqSub (LeqProof :: LeqProof y y)-                             (leqTrans (leqSucc :: LeqProof x (x+1))-                                       (LeqProof) :: LeqProof x y) :: LeqProof (y - x) y)-          }}}}-      in leqPlus (predNat n)---- | Decrement a @NatRepr@-decNat :: (1 <= n) => NatRepr n -> NatRepr (n-1)-decNat (NatRepr i) = NatRepr (i-1)---- | Get the predecessor of a nat-predNat :: NatRepr (n+1) -> NatRepr n-predNat (NatRepr i) = NatRepr (i-1)---- | Increment a @NatRepr@-incNat :: NatRepr n -> NatRepr (n+1)-incNat (NatRepr x) = NatRepr (x+1)--halfNat :: NatRepr (n+n) -> NatRepr n-halfNat (NatRepr x) = NatRepr (x `div` 2)--addNat :: NatRepr m -> NatRepr n -> NatRepr (m+n)-addNat (NatRepr m) (NatRepr n) = NatRepr (m+n)--subNat :: (n <= m) => NatRepr m -> NatRepr n -> NatRepr (m-n)-subNat (NatRepr m) (NatRepr n) = NatRepr (m-n)--divNat :: (1 <= n) => NatRepr (m * n) -> NatRepr n -> NatRepr m-divNat (NatRepr x) (NatRepr y) = NatRepr (div x y)--withDivModNat :: forall n m a.-                 NatRepr n-              -> NatRepr m-              -> (forall div mod. (n ~ ((div * m) + mod)) =>-                  NatRepr div -> NatRepr mod -> a)-              -> a-withDivModNat n m f =-  case ( Some (NatRepr divPart), Some (NatRepr modPart)) of-     ( Some (divn :: NatRepr div), Some (modn :: NatRepr mod) )-       -> case unsafeCoerce (Refl :: 0 :~: 0) of-            (Refl :: (n :~: ((div * m) + mod))) -> f divn modn-  where-    (divPart, modPart) = divMod (natValue n) (natValue m)--natMultiply :: NatRepr n -> NatRepr m -> NatRepr (n * m)-natMultiply (NatRepr n) (NatRepr m) = NatRepr (n * m)----------------------------------------------------------------------------- Operations for using NatRepr as a bitwidth.---- | Return minimum unsigned value for bitvector with given width (always 0).-minUnsigned :: NatRepr w -> Integer-minUnsigned _ = 0---- | Return maximum unsigned value for bitvector with given width.-maxUnsigned :: NatRepr w -> Integer-maxUnsigned w = bit (widthVal w) - 1---- | Return minimum value for bitvector in 2s complement with given width.-minSigned :: (1 <= w) => NatRepr w -> Integer-minSigned w = negate (bit (widthVal w - 1))---- | Return maximum value for bitvector in 2s complement with given width.-maxSigned :: (1 <= w) => NatRepr w -> Integer-maxSigned w = bit (widthVal w - 1) - 1---- | @toUnsigned w i@ maps @i@ to a @i `mod` 2^w@.-toUnsigned :: NatRepr w -> Integer -> Integer-toUnsigned w i = maxUnsigned w .&. i---- | @toSigned w i@ interprets the least-significant @w@ bits in @i@ as a--- signed number in two's complement notation and returns that value.-toSigned :: (1 <= w) => NatRepr w -> Integer -> Integer-toSigned w i0-    | i > maxSigned w = i - bit (widthVal w)-    | otherwise       = i-  where i = i0 .&. maxUnsigned w---- | @unsignedClamp w i@ rounds @i@ to the nearest value between--- @0@ and @2^w-1@ (inclusive).-unsignedClamp :: NatRepr w -> Integer -> Integer-unsignedClamp w i-  | i < minUnsigned w = minUnsigned w-  | i > maxUnsigned w = maxUnsigned w-  | otherwise         = i---- | @signedClamp w i@ rounds @i@ to the nearest value between--- @-2^(w-1)@ and @2^(w-1)-1@ (inclusive).-signedClamp :: (1 <= w) => NatRepr w -> Integer -> Integer-signedClamp w i-  | i < minSigned w = minSigned w-  | i > maxSigned w = maxSigned w-  | otherwise       = i----------------------------------------------------------------------------- Some NatRepr---- | Turn an @Integral@ value into a @NatRepr@.  Returns @Nothing@---   if the given value is negative.-someNat :: Integral a => a -> Maybe (Some NatRepr)-someNat x | x >= 0 = Just . Some . NatRepr $! fromIntegral x-someNat _ = Nothing---- | Turn a @Natural@ into the corresponding @NatRepr@-mkNatRepr :: Natural -> Some NatRepr-mkNatRepr n = Some (NatRepr n)---- | Return the maximum of two nat representations.-maxNat :: NatRepr m -> NatRepr n -> Some NatRepr-maxNat x y-  | natValue x >= natValue y = Some x-  | otherwise = Some y----------------------------------------------------------------------------- Arithmetic---- | Produce evidence that + is commutative.-plusComm :: forall f m g n . f m -> g n -> m+n :~: n+m-plusComm _ _ = unsafeCoerce (Refl :: m+n :~: m+n)---- | Produce evidence that * is commutative.-mulComm :: forall f m g n. f m -> g n -> (m * n) :~: (n * m)-mulComm _ _ = unsafeCoerce Refl--mul2Plus :: forall f n. f n -> (n + n) :~: (2 * n)-mul2Plus n = case addMulDistribRight (Proxy @1) (Proxy @1) n of-               Refl -> Refl---- | Cancel an add followed b a subtract-plusMinusCancel :: forall f m g n . f m -> g n -> (m + n) - n :~: m-plusMinusCancel _ _ = unsafeCoerce (Refl :: m :~: m)--minusPlusCancel :: forall f m g n . (n <= m) => f m -> g n -> (m - n) + n :~: m-minusPlusCancel _ _ = unsafeCoerce (Refl :: m :~: m)--addMulDistribRight :: forall n m p f g h. f n -> g m -> h p-                    -> ((n * p) + (m * p)) :~: ((n + m) * p)-addMulDistribRight _n _m _p = unsafeCoerce Refl----withAddMulDistribRight :: forall n m p f g h a. f n -> g m -> h p-                    -> ( (((n * p) + (m * p)) ~ ((n + m) * p)) => a) -> a-withAddMulDistribRight n m p f =-  case addMulDistribRight n m p of-    Refl -> f--withSubMulDistribRight :: forall n m p f g h a. (m <= n) => f n -> g m -> h p-                    -> ( (((n * p) - (m * p)) ~ ((n - m) * p)) => a) -> a-withSubMulDistribRight _n _m _p f =-  case unsafeCoerce (Refl :: 0 :~: 0) of-    (Refl :: (((n * p) - (m * p)) :~: ((n - m) * p)) ) -> f----------------------------------------------------------------------------- LeqProof---- | @LeqProof m n@ is a type whose values are only inhabited when @m@--- is less than or equal to @n@.-data LeqProof m n where-  LeqProof :: (m <= n) => LeqProof m n---- | (<=) is a decidable relation on nats.-decideLeq :: NatRepr a -> NatRepr b -> Either (LeqProof a b) ((LeqProof a b) -> Void)-decideLeq (NatRepr m) (NatRepr n)-  | m <= n    = Left $ unsafeCoerce (LeqProof :: LeqProof 0 0)-  | otherwise = Right $-      \x -> seq x $ error "Impossible [decidable <= on NatRepr]"--testStrictLeq :: forall m n-               . (m <= n)-              => NatRepr m-              -> NatRepr n-              -> Either (LeqProof (m+1) n) (m :~: n)-testStrictLeq (NatRepr m) (NatRepr n)-  | m < n = Left (unsafeCoerce (LeqProof :: LeqProof 0 0))-  | otherwise = Right (unsafeCoerce (Refl :: m :~: m))-{-# NOINLINE testStrictLeq #-}---- As for NatComparison above, but works with LeqProof-data NatCases m n where-  -- First number is less than second.-  NatCaseLT :: LeqProof (m+1) n -> NatCases m n-  NatCaseEQ :: NatCases m m-  -- First number is greater than second.-  NatCaseGT :: LeqProof (n+1) m -> NatCases m n--testNatCases ::  forall m n-              . NatRepr m-             -> NatRepr n-             -> NatCases m n-testNatCases m n =-  case compare (natValue m) (natValue n) of-    LT -> NatCaseLT (unsafeCoerce (LeqProof :: LeqProof 0 0))-    EQ -> unsafeCoerce $ (NatCaseEQ :: NatCases m m)-    GT -> NatCaseGT (unsafeCoerce (LeqProof :: LeqProof 0 0))-{-# NOINLINE testNatCases #-}---- | The strict order (<), defined by n < m <-> n + 1 <= m, is irreflexive.-lessThanIrreflexive :: forall f (a :: Nat). f a -> LeqProof (1 + a) a -> Void-lessThanIrreflexive a prf =-  let prf1 :: LeqProof (1 + a - a) (a - a)-      prf1 = leqSub2 prf (LeqProof :: LeqProof a a)-      prf2 :: 1 + a - a :~: 1-      prf2 = plusMinusCancel (knownNat @1) a-      prf3 :: a - a :~: 0-      prf3 = plusMinusCancel (knownNat @0) a-      prf4 :: LeqProof 1 0-      prf4 = case prf2 of Refl -> case prf3 of { Refl -> prf1 }-  in case prf4 of {}---- | The strict order on the naturals is irreflexive.-lessThanAsymmetric :: forall m f n-                    . LeqProof (n+1) m-                   -> LeqProof (m+1) n-                   -> f n-                   -> Void-lessThanAsymmetric nLTm mLTn n =-  case plusComm n (knownNat @1) :: n + 1 :~: 1 + n of { Refl ->-  case leqAdd (LeqProof :: LeqProof m m) (knownNat @1) :: LeqProof m (m+1) of-    LeqProof -> lessThanIrreflexive n $ leqTrans (leqTrans nLTm LeqProof) mLTn-  }---- | @x `testLeq` y@ checks whether @x@ is less than or equal to @y@.-testLeq :: forall m n . NatRepr m -> NatRepr n -> Maybe (LeqProof m n)-testLeq (NatRepr m) (NatRepr n)-   | m <= n    = Just (unsafeCoerce (LeqProof :: LeqProof 0 0))-   | otherwise = Nothing-{-# NOINLINE testLeq #-}---- | Apply reflexivity to LeqProof-leqRefl :: forall f n . f n -> LeqProof n n-leqRefl _ = LeqProof---- | Apply transitivity to LeqProof-leqTrans :: LeqProof m n -> LeqProof n p -> LeqProof m p-leqTrans LeqProof LeqProof = unsafeCoerce (LeqProof :: LeqProof 0 0)-{-# NOINLINE leqTrans #-}---- | Add both sides of two inequalities-leqAdd2 :: LeqProof x_l x_h -> LeqProof y_l y_h -> LeqProof (x_l + y_l) (x_h + y_h)-leqAdd2 x y = seq x $ seq y $ unsafeCoerce (LeqProof :: LeqProof 0 0)-{-# NOINLINE leqAdd2 #-}---- | Subtract sides of two inequalities.-leqSub2 :: LeqProof x_l x_h-        -> LeqProof y_l y_h-        -> LeqProof (x_l-y_h) (x_h-y_l)-leqSub2 LeqProof LeqProof = unsafeCoerce (LeqProof :: LeqProof 0 0)-{-# NOINLINE leqSub2 #-}----------------------------------------------------------------------------- LeqProof combinators---- | Create a leqProof using two proxies-leqProof :: (m <= n) => f m -> g n -> LeqProof m n-leqProof _ _ = LeqProof--withLeqProof :: LeqProof m n -> ((m <= n) => a) -> a-withLeqProof p a =-  case p of-    LeqProof -> a---- | Test whether natural number is positive.-isPosNat :: NatRepr n -> Maybe (LeqProof 1 n)-isPosNat = testLeq (knownNat :: NatRepr 1)---- | Congruence rule for multiplication-leqMulCongr :: LeqProof a x-            -> LeqProof b y-            -> LeqProof (a*b) (x*y)-leqMulCongr LeqProof LeqProof = unsafeCoerce (LeqProof :: LeqProof 1 1)-{-# NOINLINE leqMulCongr #-}---- | Multiplying two positive numbers results in a positive number.-leqMulPos :: forall p q x y-          .  (1 <= x, 1 <= y)-          => p x-          -> q y-          -> LeqProof 1 (x*y)-leqMulPos _ _ = leqMulCongr (LeqProof :: LeqProof 1 x) (LeqProof :: LeqProof 1 y)--leqMulMono :: (1 <= x) => p x -> q y -> LeqProof y (x * y)-leqMulMono x y = leqMulCongr (leqProof (Proxy :: Proxy 1) x) (leqRefl y)---- | Produce proof that adding a value to the larger element in an LeqProof--- is larger-leqAdd :: forall f m n p . LeqProof m n -> f p -> LeqProof m (n+p)-leqAdd x _ = leqAdd2 x (LeqProof :: LeqProof 0 p)--leqAddPos :: (1 <= m, 1 <= n) => p m -> q n -> LeqProof 1 (m + n)-leqAddPos m n = leqAdd (leqProof (Proxy :: Proxy 1) m) n---- | Produce proof that subtracting a value from the smaller element is smaller.-leqSub :: forall m n p . LeqProof m n -> LeqProof p m -> LeqProof (m-p) n-leqSub x _ = leqSub2 x (LeqProof :: LeqProof 0 p)--addIsLeq :: f n -> g m -> LeqProof n (n + m)-addIsLeq n m = leqAdd (leqRefl n) m--addPrefixIsLeq :: f m -> g n -> LeqProof n (m + n)-addPrefixIsLeq m n =-  case plusComm n m of-    Refl -> addIsLeq n m--dblPosIsPos :: forall n . LeqProof 1 n -> LeqProof 1 (n+n)-dblPosIsPos x = leqAdd x Proxy--addIsLeqLeft1 :: forall n n' m . LeqProof (n + n') m -> LeqProof n m-addIsLeqLeft1 p =-    case plusMinusCancel n n' of-      Refl -> leqSub p le-  where n :: Proxy n-        n = Proxy-        n' :: Proxy n'-        n' = Proxy-        le :: LeqProof n' (n + n')-        le = addPrefixIsLeq n n'--{-# INLINE withAddPrefixLeq #-}-withAddPrefixLeq :: NatRepr n -> NatRepr m -> ((m <= n + m) => a) -> a-withAddPrefixLeq n m = withLeqProof (addPrefixIsLeq n m)--withAddLeq :: forall n m a. NatRepr n -> NatRepr m -> ((n <= n + m) => NatRepr (n + m) -> a) -> a-withAddLeq n m f = withLeqProof (addIsLeq n m) (f (addNat n m))--natForEach' :: forall l h a-            . NatRepr l-            -> NatRepr h-            -> (forall n. LeqProof l n -> LeqProof n h -> NatRepr n -> a)-            -> [a]-natForEach' l h f-  | Just LeqProof  <- testLeq l h =-    let f' :: forall n. LeqProof (l + 1) n -> LeqProof n h -> NatRepr n -> a-        f' = \lp hp -> f (addIsLeqLeft1 lp) hp-     in f LeqProof LeqProof l : natForEach' (incNat l) h f'-  | otherwise             = []---- | Apply a function to each element in a range; return the list of values--- obtained.-natForEach :: forall l h a-            . NatRepr l-           -> NatRepr h-           -> (forall n. (l <= n, n <= h) => NatRepr n -> a)-           -> [a]-natForEach l h f = natForEach' l h (\LeqProof LeqProof -> f)---- | Apply a function to each element in a range starting at zero;--- return the list of values obtained.-natFromZero :: forall h a-            . NatRepr h-           -> (forall n. (n <= h) => NatRepr n -> a)-           -> [a]-natFromZero = natForEach (knownNat @0)---- | Recursor for natural numbeers.-natRec :: forall p f-       .  NatRepr p-       -> f 0 {- ^ base case -}-       -> (forall n. NatRepr n -> f n -> f (n + 1))-       -> f p-natRec n base ind =-  case isZeroNat n of-    ZeroNat    -> base-    NonZeroNat -> let n' = predNat n-                  in ind n' (natRec n' base ind)---- | Strong induction variant of the recursor.-natRecStrong :: forall p f-             .  NatRepr p-             -> f 0 {- ^ base case -}-             -> (forall n.-                  NatRepr n ->-                  (forall m. (m <= n) => NatRepr m -> f m) ->-                  f (n + 1)) {- ^ inductive step -}-             -> f p-natRecStrong p base ind = natRecStrong' base ind p-  where -- We can't use use "flip" or some other basic combinator-        -- because type variables can't be instantiated to contain "forall"s.-        natRecStrong' :: forall p' f'-                      .  f' 0 {- ^ base case -}-                      -> (forall n.-                            NatRepr n ->-                            (forall m. (m <= n) => NatRepr m -> f' m) ->-                            f' (n + 1)) {- ^ inductive step -}-                      -> NatRepr p'-                      -> f' p'-        natRecStrong' base' ind' n =-          case isZeroNat n of-            ZeroNat    -> base'-            NonZeroNat -> ind' (predNat n) (natRecStrong' base' ind')---- | Bounded recursor for natural numbers.------ If you can prove:--- - Base case: f 0--- - Inductive step: if n <= h and (f n) then (f (n + 1))--- You can conclude: for all n <= h, (f (n + 1)).-natRecBounded :: forall m h f. (m <= h)-              => NatRepr m-              -> NatRepr h-              -> f 0-              -> (forall n. (n <= h) => NatRepr n -> f n -> f (n + 1))-              -> f (m + 1)-natRecBounded m h base indH =-  case isZeroOrGT1 m of-    Left Refl      -> indH (knownNat @0) base-    Right LeqProof ->-      case decideLeq m h of-        Left LeqProof {- :: m <= h -} ->-          let -- Since m is non-zero, it is n + 1 for some n.-              lemma :: LeqProof (m-1) h-              lemma = leqSub (LeqProof :: LeqProof m h) (LeqProof :: LeqProof 1 m)-          in indH m $-            case lemma of { LeqProof ->-            case minusPlusCancel m (knownNat @1) of { Refl ->-              natRecBounded @(m - 1) @h @f (predNat m) h base indH-            }}-        Right f {- :: (m <= h) -> Void -} ->-          absurd $ f (LeqProof :: LeqProof m h)--mulCancelR ::-  (1 <= c, (n1 * c) ~ (n2 * c)) => f1 n1 -> f2 n2 -> f3 c -> (n1 :~: n2)-mulCancelR _ _ _ = unsafeCoerce Refl---- | Used in @Vector@-lemmaMul :: (1 <= n) => p w -> q n -> (w + (n-1) * w) :~: (n * w)-lemmaMul = unsafeCoerce Refl
− submodules/parameterized-utils/src/Data/Parameterized/Nonce.hs
@@ -1,163 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2016-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This module provides a simple generator of new indexes in the ST monad.-It is predictable and not intended for cryptographic purposes.--This module also provides a global nonce generator that will generate-2^64 nonces before looping.--NOTE: The 'TestEquality' and 'OrdF' instances for the 'Nonce' type simply-compare the generated nonce values and then assert to the compiler-(via 'unsafeCoerce') that the types ascribed to the nonces are equal-if their values are equal.--}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE Trustworthy #-}-#if MIN_VERSION_base(4,9,0)-{-# LANGUAGE TypeInType #-}-#endif-module Data.Parameterized.Nonce-  ( -- * NonceGenerator-    NonceGenerator-  , freshNonce-  , countNoncesGenerated-  , Nonce-  , indexValue-    -- * Accessing a nonce generator-  , newSTNonceGenerator-  , newIONonceGenerator-  , withIONonceGenerator-  , withSTNonceGenerator-  , withGlobalSTNonceGenerator-  , GlobalNonceGenerator-  , globalNonceGenerator-  ) where--import Control.Monad.ST-import Data.Hashable-import Data.IORef-import Data.STRef-import Data.Typeable-import Data.Word-import Unsafe.Coerce-import System.IO.Unsafe (unsafePerformIO)--import Data.Parameterized.Classes-import Data.Parameterized.Some--#if MIN_VERSION_base(4,9,0) && __GLASGOW_HASKELL__ < 805-import Data.Kind-#endif---- | Provides a monadic action for getting fresh typed names.------ The first type parameter @m@ is the monad used for generating names, and--- the second parameter @s@ is used for the counter.-data NonceGenerator (m :: * -> *) (s :: *) where-  STNG :: !(STRef t Word64) -> NonceGenerator (ST t) s-  IONG :: !(IORef Word64) -> NonceGenerator IO s--#if MIN_VERSION_base(4,9,0)--- We have to make the k explicit in GHC 8.0 to avoid a warning.-freshNonce :: forall m s k (tp :: k) . NonceGenerator m s -> m (Nonce s tp)-#else-freshNonce :: forall m s (tp :: k) . NonceGenerator m s -> m (Nonce s tp)-#endif-freshNonce (IONG r) =-  atomicModifyIORef' r $ \n -> (n+1, Nonce n)-freshNonce (STNG r) = do-  i <- readSTRef r-  writeSTRef r $! i+1-  return $ Nonce i-  -- (Weirdly, there's no atomicModifySTRef'.  Yes, only the IO monad-  -- does concurrency, but the ST monad is part of the IO monad via-  -- stToIO, so there's no guarantee that ST code won't be run in-  -- multiple threads.)--{-# INLINE freshNonce #-}-  -- Inlining is particularly necessary since there's no @Monad m@-  -- constraint on 'freshNonce', so SPECIALIZE doesn't work on it.  In-  -- this case, though, we get specialization for free from inlining.-  -- For instance, a @NonceGenerator IO s@ must be an @IONG@, so the-  -- simplifier eliminates the STNG branch.---- | The number of nonces generated so far by this generator.  Only--- really useful for profiling.-countNoncesGenerated :: NonceGenerator m s -> m Integer-countNoncesGenerated (IONG r) = toInteger <$> readIORef r-countNoncesGenerated (STNG r) = toInteger <$> readSTRef r---- | Create a new counter.-withGlobalSTNonceGenerator :: (forall t . NonceGenerator (ST t) t -> ST t r) -> r-withGlobalSTNonceGenerator f = runST $ do-  r <- newSTRef (toEnum 0)-  f $! STNG r---- | Create a new nonce generator in the ST monad.-newSTNonceGenerator :: ST t (Some (NonceGenerator (ST t)))-newSTNonceGenerator = Some . STNG <$> newSTRef (toEnum 0)---- | Create a new nonce generator in the ST monad.-newIONonceGenerator :: IO (Some (NonceGenerator IO))-newIONonceGenerator = Some . IONG <$> newIORef (toEnum 0)---- | Run a ST computation with a new nonce generator in the ST monad.-withSTNonceGenerator :: (forall s . NonceGenerator (ST t) s -> (ST t) r) -> ST t r-withSTNonceGenerator f = do-  Some r <- newSTNonceGenerator-  f r---- | Create a new nonce generator in the IO monad.-withIONonceGenerator :: (forall s . NonceGenerator IO s -> IO r) -> IO r-withIONonceGenerator f = do-  Some r <- newIONonceGenerator-  f r---- | An index generated by the counter.-newtype Nonce (s :: *) (tp :: k) = Nonce { indexValue :: Word64 }-  deriving (Eq, Ord, Hashable, Show)----  Force the type role of Nonce to be nominal: this prevents Data.Coerce.coerce---  from casting the types of nonces, which it would otherwise be able to do---  because tp is a phantom type parameter.  This partially helps to protect---  the nonce abstraction.-type role Nonce nominal nominal--instance TestEquality (Nonce s) where-  testEquality x y | indexValue x == indexValue y = unsafeCoerce (Just Refl)-                   | otherwise = Nothing--instance OrdF (Nonce s) where-  compareF x y =-    case compare (indexValue x) (indexValue y) of-      LT -> LTF-      EQ -> unsafeCoerce EQF-      GT -> GTF--instance HashableF (Nonce s) where-  hashWithSaltF s (Nonce x) = hashWithSalt s x--instance ShowF (Nonce s)----------------------------------------------------------------------------- GlobalNonceGenerator--data GlobalNonceGenerator--globalNonceIORef :: IORef Word64-globalNonceIORef = unsafePerformIO (newIORef 0)-{-# NOINLINE globalNonceIORef #-}---- | A nonce generator that uses a globally-defined counter.-globalNonceGenerator :: NonceGenerator IO GlobalNonceGenerator-globalNonceGenerator = IONG globalNonceIORef
− submodules/parameterized-utils/src/Data/Parameterized/Nonce/Transformers.hs
@@ -1,70 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2016-Maintainer       : Eddy Westbrook <westbrook@galois.com>--This module provides a typeclass and monad transformers for generating-nonces.--}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeFamilies #-}-module Data.Parameterized.Nonce.Transformers-  ( MonadNonce(..)-  , NonceT(..)-  , NonceST-  , NonceIO-  , getNonceSTGen-  , runNonceST-  , runNonceIO-  , module Data.Parameterized.Nonce-  ) where--import Control.Monad.Reader-import Control.Monad.ST-import Control.Monad.State--import Data.Parameterized.Nonce----- | A 'MonadNonce' is a monad that can generate fresh 'Nonce's in a given set--- (where we view the phantom type parameter of 'Nonce' as a designator of the--- set that the 'Nonce' came from).-class Monad m => MonadNonce m where-  type NonceSet m :: *-  freshNonceM :: forall (tp :: k) . m (Nonce (NonceSet m) tp)---- | This transformer adds a nonce generator to a given monad.-newtype NonceT s m a =-  NonceT { runNonceT :: ReaderT (NonceGenerator m s) m a }-  deriving (Functor, Applicative, Monad)--instance MonadTrans (NonceT s) where-  lift m = NonceT $ lift m--instance Monad m => MonadNonce (NonceT s m) where-  type NonceSet (NonceT s m) = s-  freshNonceM = NonceT $ lift . freshNonce =<< ask--instance MonadNonce m => MonadNonce (StateT s m) where-  type NonceSet (StateT s m) = NonceSet m-  freshNonceM = lift $ freshNonceM---- | Helper type to build a 'MonadNonce' from the 'ST' monad.-type NonceST t s = NonceT s (ST t)---- | Helper type to build a 'MonadNonce' from the 'IO' monad.-type NonceIO s = NonceT s IO---- | Return the actual 'NonceGenerator' used in an 'ST' computation.-getNonceSTGen :: NonceST t s (NonceGenerator (ST t) s)-getNonceSTGen = NonceT ask---- | Run a 'NonceST' computation with a fresh 'NonceGenerator'.-runNonceST :: (forall t s. NonceST t s a) -> a-runNonceST m = runST $ withSTNonceGenerator $ runReaderT $ runNonceT m---- | Run a 'NonceIO' computation with a fresh 'NonceGenerator' inside 'IO'.-runNonceIO :: (forall s. NonceIO s a) -> IO a-runNonceIO m = withIONonceGenerator $ runReaderT $ runNonceT m
− submodules/parameterized-utils/src/Data/Parameterized/Nonce/Unsafe.hs
@@ -1,107 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.NonceGenerator--- Description      : A counter in the ST monad.--- Copyright        : (c) Galois, Inc 2014--- Maintainer       : Joe Hendrix <jhendrix@galois.com>--- Stability        : provisional------ This module provides a simple generator of new indexes in the ST monad.--- It is predictable and not intended for cryptographic purposes.------ NOTE: the 'TestEquality' and 'OrdF' instances for the 'Nonce' type simply--- compare the generated nonce values and then assert to the compiler--- (via 'unsafeCoerce') that the types ascribed to the nonces are equal--- if their values are equal.  This is only OK because of the discipline--- by which nonces should be used: they should only be generated from--- a 'NonceGenerator' (i.e., should not be built directly), and nonces from--- different generators must never be compared!  Arranging to compare--- Nonces from different origins would allow users to build 'unsafeCoerce'--- via the 'testEquality' function.------ A somewhat safer API would be to brand the generated Nonces with the--- state type variable of the NonceGenerator whence they came, and to only--- provide NonceGenerators via a Rank-2 continuation-passing API, similar to--- 'runST'. This would (via a meta-argument involving parametricity)--- help to prevent nonces of different origin from being compared.--- However, this would force us to push the 'ST' type brand into a significant--- number of other structures and APIs.------ Another alternative would be to use 'unsafePerformIO' magic to make--- a global nonce generator, and make that the only way to generate nonces.--- It is not clear that this is actually an improvement from a type safety--- point of view, but an argument could be made.------ For now, be careful using Nonces, and ensure that you do not mix--- Nonces from different NonceGenerators.--------------------------------------------------------------------------{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE Unsafe #-}-module Data.Parameterized.Nonce.Unsafe-  ( NonceGenerator-  , newNonceGenerator-  , freshNonce-  , atLimit-  , Nonce-  , indexValue-  ) where--import Control.Monad.ST-import Data.Hashable-import Data.STRef-import Data.Word-import Unsafe.Coerce--import Data.Parameterized.Classes---- | A simple type that for getting fresh indices in the 'ST' monad.--- The type parameter @s@ is used for the 'ST' monad parameter.-newtype NonceGenerator s = NonceGenerator (STRef s Word64)---- | Create a new counter.-newNonceGenerator :: ST s (NonceGenerator s)-newNonceGenerator = NonceGenerator `fmap` newSTRef (toEnum 0)---- | An index generated by the counter.-newtype Nonce (tp :: k) = Nonce { indexValue :: Word64 }-  deriving (Eq, Ord, Hashable, Show)----  Force the type role of Nonce to be nominal: this prevents Data.Coerce.coerce---  from casting the types of nonces, which it would otherwise be able to do---  because tp is a phantom type parameter.  This partially helps to protect---  the nonce abstraction.-type role Nonce nominal--instance TestEquality Nonce where-  testEquality x y | indexValue x == indexValue y = unsafeCoerce (Just Refl)-                   | otherwise = Nothing--instance OrdF Nonce where-  compareF x y =-    case compare (indexValue x) (indexValue y) of-      LT -> LTF-      EQ -> unsafeCoerce EQF-      GT -> GTF--instance HashableF Nonce where-  hashWithSaltF s (Nonce x) = hashWithSalt s x--instance ShowF Nonce--{-# INLINE freshNonce #-}--- | Get a fresh index and increment the counter.-freshNonce :: NonceGenerator s -> ST s (Nonce tp)-freshNonce (NonceGenerator r) = do-  i <- readSTRef r-  writeSTRef r $! succ i-  return (Nonce i)---- | Return true if counter has reached the limit, and can't be--- incremented without risk of error.-atLimit :: NonceGenerator s -> ST s Bool-atLimit (NonceGenerator r) = do-  i <- readSTRef r-  return (i == maxBound)
− submodules/parameterized-utils/src/Data/Parameterized/Pair.hs
@@ -1,51 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2017--This module defines a 2-tuple where both elements are parameterized over the-same existentially quantified parameter.---}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-module Data.Parameterized.Pair-  ( Pair(..)-  , fstPair-  , sndPair-  , viewPair-  ) where--import Data.Parameterized.Classes-import Data.Parameterized.Some-import Data.Parameterized.TraversableF---- | Like a 2-tuple, but with an existentially quantified parameter that both of--- the elements share.-data Pair (a :: k -> *) (b :: k -> *) where-  Pair :: !(a tp) -> !(b tp) -> Pair a b--instance (TestEquality a, EqF b) => Eq (Pair a b) where-  Pair xa xb == Pair ya yb =-    case testEquality xa ya of-      Just Refl -> eqF xb yb-      Nothing -> False--instance FunctorF (Pair a) where-  fmapF f (Pair x y) = Pair x (f y)--instance FoldableF (Pair a) where-  foldMapF f (Pair _ y) = f y-  foldrF f z (Pair _ y) = f y z---- | Extract the first element of a pair.-fstPair :: Pair a b -> Some a-fstPair (Pair x _) = Some x---- | Extract the second element of a pair.-sndPair :: Pair a b -> Some b-sndPair (Pair _ y) = Some y---- | Project out of Pair.-viewPair :: (forall tp. a tp -> b tp -> c) -> Pair a b -> c-viewPair f (Pair x y) = f x y
− submodules/parameterized-utils/src/Data/Parameterized/Peano.hs
@@ -1,285 +0,0 @@-{-|--This defines a type 'Peano' and 'PeanoRepr' for representing a-type-level natural at runtime. These type-level numbers are defined-inductively instead of using GHC.TypeLits.--As a result, type-level computation defined recursively over these-numbers works more smoothly. (For example, see the type-level-function Repeatn below.)--Note: as in NatRepr, the runtime representation of these type-level-natural numbers is an Int.---}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE EmptyCase #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}--#if MIN_VERSION_base(4,9,0)-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-#endif-#if __GLASGOW_HASKELL__ >= 805-{-# LANGUAGE NoStarIsType #-}-#endif-module Data.Parameterized.Peano-   ( Peano-     , Z , S-     , Plus, Minus, Mul, Le, Lt, Gt, Ge, Max, Min, Repeat-     , plusP, minusP, mulP, maxP, minP, repeatP-     , zeroP, succP, predP--     , KnownPeano-     , withKnownPeano--     , PeanoRepr, peanoValue-     , PeanoView(..), peanoView-     , viewRepr--     , somePeano-     , mkPeanoRepr-     , maxPeano-     , minPeano--     -- * Re-exports-     , TestEquality(..)-     , (:~:)(..)-     , Data.Parameterized.Some.Some--     ) where--import           Data.Parameterized.Classes-import           Data.Parameterized.DecidableEq-import           Data.Parameterized.Some--import           Data.Hashable-import           Data.Constraint-import           Data.Word--import           Unsafe.Coerce(unsafeCoerce)----------------------------------------------------------------------------- ** Peano - a unary representation of natural numbers--data Peano = Z | S Peano--- | Peano zero-type Z = 'Z--- | Peano successor-type S = 'S---- Peano numbers are more about *counting* than arithmetic.--- They are most useful as iteration arguments and list indices--- However, for completeness, we define a few standard--- operations.--type family Plus (a :: Peano) (b :: Peano) :: Peano where-  Plus Z     b = b-  Plus (S a) b = S (Plus a b)--type family Minus (a :: Peano) (b :: Peano) :: Peano where-  Minus Z     b     = Z-  Minus (S a) (S b) = Minus a b-  Minus a    Z      = a--type family Mul (a :: Peano) (b :: Peano) :: Peano where-  Mul Z     b = Z-  Mul (S a) b = Plus a (Mul a b)--type family Le  (a :: Peano) (b :: Peano) :: Bool where-  Le  a  a        = 'True-  Le  Z  b        = 'True-  Le  a  Z        = 'False-  Le  (S a) (S b) = Le a b--type family Lt  (a :: Peano) (b :: Peano) :: Bool where-  Lt a b = Le (S a) b--type family Gt  (a :: Peano) (b :: Peano) :: Bool where-  Gt a b = Lt b a--type family Ge  (a :: Peano) (b :: Peano) :: Bool where-  Ge a b = Le b a--type family Max (a :: Peano) (b :: Peano) :: Peano where-  Max Z b = b-  Max a Z = a-  Max (S a) (S b) = S (Max a b)--type family Min (a :: Peano) (b :: Peano) :: Peano where-  Min Z b = Z-  Min a Z = Z-  Min (S a) (S b) = S (Min a b)---- Apply a constructor 'f' n-times to an argument 's'-type family Repeat (m :: Peano) (f :: k -> k) (s :: k) :: k where-  Repeat Z f s     = s-  Repeat (S m) f s = f (Repeat m f s)------------------------------------------------------------------------------ ** Run time representation of Peano numbers---- | The run time value, stored as an Word64--- As these are unary numbers, we don't worry about overflow.-newtype PeanoRepr (n :: Peano) =-  PeanoRepr { peanoValue :: Word64 }---- n is Phantom in the definition, but we don't want to allow coerce-type role PeanoRepr nominal---------------------------------------------------------------- | Because we have optimized the runtime representation,--- we need to have a "view" that decomposes the representation--- into the standard form.-data PeanoView (n :: Peano) where-  ZRepr :: PeanoView Z-  SRepr :: PeanoRepr n -> PeanoView (S n)---- | Test whether a number is Zero or Successor-peanoView :: PeanoRepr n -> PeanoView n-peanoView (PeanoRepr i) =-  if i == 0 then unsafeCoerce ZRepr else unsafeCoerce (SRepr (PeanoRepr (i-1)))---- | convert the view back to the runtime representation-viewRepr :: PeanoView n -> PeanoRepr n-viewRepr ZRepr     = PeanoRepr 0-viewRepr (SRepr n) = PeanoRepr (peanoValue n + 1)--------------------------------------------------------------instance Hashable (PeanoRepr n) where-  hashWithSalt i (PeanoRepr x) = hashWithSalt i x--instance Eq (PeanoRepr m) where-  _ == _ = True--instance TestEquality PeanoRepr where-  testEquality (PeanoRepr m) (PeanoRepr n)-    | m == n = Just (unsafeCoerce Refl)-    | otherwise = Nothing--instance DecidableEq PeanoRepr where-  decEq (PeanoRepr m) (PeanoRepr n)-    | m == n    = Left $ unsafeCoerce Refl-    | otherwise = Right $-        \x -> seq x $ error "Impossible [DecidableEq on PeanoRepr]"--instance OrdF PeanoRepr where-  compareF (PeanoRepr m) (PeanoRepr n)-    | m < n     = unsafeCoerce LTF-    | m == n    = unsafeCoerce EQF-    | otherwise = unsafeCoerce GTF--instance PolyEq (PeanoRepr m) (PeanoRepr n) where-  polyEqF x y = (\Refl -> Refl) <$> testEquality x y---- Display as digits, not in unary-instance Show (PeanoRepr p) where-  show p = show (peanoValue p)--instance ShowF PeanoRepr--instance HashableF PeanoRepr where-  hashWithSaltF = hashWithSalt--------------------------------------------------------------- * Implicit runtime Peano numbers--type KnownPeano = KnownRepr PeanoRepr--instance KnownRepr PeanoRepr Z where-  knownRepr = viewRepr ZRepr-instance (KnownRepr PeanoRepr n) => KnownRepr PeanoRepr (S n) where-  knownRepr = viewRepr (SRepr knownRepr)--newtype DI a = Don'tInstantiate (KnownPeano a => Dict (KnownPeano a))--peanoInstance :: forall a . PeanoRepr a -> Dict (KnownPeano a)-peanoInstance s = with_sing_i Dict-  where-    with_sing_i :: (KnownPeano a => Dict (KnownPeano a)) -> Dict (KnownPeano a)-    with_sing_i si = unsafeCoerce (Don'tInstantiate si) s---- | convert an explicit number to an implicit number-withKnownPeano :: forall n r. PeanoRepr n -> (KnownPeano n => r) -> r-withKnownPeano si r = case peanoInstance si of-                        Dict -> r--------------------------------------------------------------- * Operations on runtime numbers---- | zero-zeroP :: PeanoRepr Z-zeroP = PeanoRepr 0---- | Successor, Increment-succP :: PeanoRepr n -> PeanoRepr (S n)-succP (PeanoRepr i) = PeanoRepr (i+1)---- | Get the predecessor (decrement)-predP :: PeanoRepr (S n) -> PeanoRepr n-predP (PeanoRepr i) = PeanoRepr (i-1)---plusP :: PeanoRepr a -> PeanoRepr b -> PeanoRepr (Plus a b)-plusP (PeanoRepr a) (PeanoRepr b) = PeanoRepr (a + b)--minusP :: PeanoRepr a -> PeanoRepr b -> PeanoRepr (Minus a b)-minusP (PeanoRepr a) (PeanoRepr b) = PeanoRepr (a - b)--mulP :: PeanoRepr a -> PeanoRepr b -> PeanoRepr (Mul a b)-mulP (PeanoRepr a) (PeanoRepr b) = PeanoRepr (a * b)--maxP :: PeanoRepr a -> PeanoRepr b -> PeanoRepr (Max a b)-maxP (PeanoRepr a) (PeanoRepr b) = PeanoRepr (max a b)--minP :: PeanoRepr a -> PeanoRepr b -> PeanoRepr (Min a b)-minP (PeanoRepr a) (PeanoRepr b) = PeanoRepr (min a b)--repeatP :: PeanoRepr m -> (forall a. repr a -> repr (f a)) -> repr s -> repr (Repeat m f s)-repeatP n f s = case peanoView n of-  ZRepr   -> s-  SRepr m -> f (repeatP m f s)----------------------------------------------------------------------------- * Some PeanoRepr---- | Convert a Word64 to a PeanoRepr-mkPeanoRepr :: Word64 -> Some PeanoRepr-mkPeanoRepr n = Some (PeanoRepr n)---- | Turn an @Integral@ value into a @PeanoRepr@.  Returns @Nothing@---   if the given value is negative.-somePeano :: Integral a => a -> Maybe (Some PeanoRepr)-somePeano x | x >= 0 = Just . Some . PeanoRepr $! fromIntegral x-somePeano _ = Nothing---- | Return the maximum of two representations.-maxPeano :: PeanoRepr m -> PeanoRepr n -> Some PeanoRepr-maxPeano x y-  | peanoValue x >= peanoValue y = Some x-  | otherwise = Some y---- | Return the minimum of two representations.-minPeano :: PeanoRepr m -> PeanoRepr n -> Some PeanoRepr-minPeano x y-  | peanoValue y >= peanoValue x = Some x-  | otherwise = Some y-----------------------------------------------------------------------------  LocalWords:  PeanoRepr withKnownPeano runtime Peano unary
− submodules/parameterized-utils/src/Data/Parameterized/Some.hs
@@ -1,59 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.Some--- Copyright        : (c) Galois, Inc 2014--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module provides 'Some', a GADT that hides a type parameter.--------------------------------------------------------------------------{-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-module Data.Parameterized.Some-  ( Some(..)-  , viewSome-  , mapSome-  , traverseSome-  , traverseSome_-  ) where--import Data.Hashable-import Data.Parameterized.Classes---data Some (f:: k -> *) = forall x . Some (f x)--instance TestEquality f => Eq (Some f) where-  Some x == Some y = isJust (testEquality x y)--instance OrdF f => Ord (Some f) where-  compare (Some x) (Some y) = toOrdering (compareF x y)--instance HashableF f => Hashable (Some f) where-  hashWithSalt s (Some x) = hashWithSaltF s x-  hash (Some x) = hashF x--instance ShowF f => Show (Some f) where-  show (Some x) = showF x---- | Project out of Some.-viewSome :: (forall tp . f tp -> r) -> Some f -> r-viewSome f (Some x) = f x---- | Apply function to inner value.-mapSome :: (forall tp . f tp -> g tp) -> Some f -> Some g-mapSome f (Some x) = Some $! f x--{-# INLINE traverseSome #-}--- | Modify the inner value.-traverseSome :: Functor m-             => (forall tp . f tp -> m (g tp))-             -> Some f-             -> m (Some g)-traverseSome f (Some x) = Some `fmap` f x--{-# INLINE traverseSome_ #-}--- | Modify the inner value.-traverseSome_ :: Functor m => (forall tp . f tp -> m ()) -> Some f -> m ()-traverseSome_ f (Some x) = (\_ -> ()) `fmap` f x
− submodules/parameterized-utils/src/Data/Parameterized/SymbolRepr.hs
@@ -1,106 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2015-Maintainer       : Joe Hendrix <jhendrix@galois.com>--This defines a type family 'SymbolRepr' for representing a type-level string-(AKA symbol) at runtime.  This can be used to branch on a type-level value.--The 'TestEquality' and 'OrdF' instances for 'SymbolRepr' are implemented using-'unsafeCoerce'.  This should be typesafe because we maintain the invariant-that the string value contained in a SymbolRepr value matches its static type.--At the type level, symbols have very few operations, so SymbolRepr-correspondingly has very few functions that manipulate them.--}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE Trustworthy #-}-module Data.Parameterized.SymbolRepr-  ( -- * SymbolRepr-    SymbolRepr-  , symbolRepr-  , knownSymbol-  , someSymbol-    -- * Re-exports-  , type GHC.Symbol-  , GHC.KnownSymbol-  ) where--import GHC.TypeLits as GHC-import Unsafe.Coerce (unsafeCoerce)--import Data.Hashable-import Data.Proxy-import qualified Data.Text as Text--import Data.Parameterized.Classes-import Data.Parameterized.Some---- | A runtime representation of a GHC type-level symbol.-newtype SymbolRepr (nm::GHC.Symbol)-  = SymbolRepr { symbolRepr :: Text.Text-                 -- ^ The underlying text representation of the symbol-               }--- INVARIANT: The contained runtime text value matches the value--- of the type level symbol.  The SymbolRepr constructor--- is not exported so we can maintain this invariant in this--- module.---- | Generate a symbol representative at runtime.  The type-level---   symbol will be abstract, as it is hidden by the 'Some' constructor.-someSymbol :: Text.Text -> Some SymbolRepr-someSymbol nm = Some (SymbolRepr nm)---- | Generate a value representative for the type level symbol.-knownSymbol :: GHC.KnownSymbol s => SymbolRepr s-knownSymbol = go Proxy-  where go :: GHC.KnownSymbol s => Proxy s -> SymbolRepr s-        go p = SymbolRepr $! packSymbol (GHC.symbolVal p)--        -- NOTE here we explicitly test that unpacking the packed text value-        -- gives the desired string.  This is to avoid pathological corner cases-        -- involving string values that have no text representation.-        packSymbol str-           | Text.unpack txt == str = txt-           | otherwise = error $ "Unrepresentable symbol! "++ str-         where txt = Text.pack str--instance (GHC.KnownSymbol s) => KnownRepr SymbolRepr s where-  knownRepr = knownSymbol--instance TestEquality SymbolRepr where-   testEquality (SymbolRepr x :: SymbolRepr x) (SymbolRepr y)-      | x == y    = Just (unsafeCoerce (Refl :: x :~: x))-      | otherwise = Nothing-instance OrdF SymbolRepr where-   compareF (SymbolRepr x :: SymbolRepr x) (SymbolRepr y)-      | x <  y    = LTF-      | x == y    = unsafeCoerce (EQF :: OrderingF x x)-      | otherwise = GTF---- These instances are trivial by the invariant--- that the contained string matches the type-level--- symbol-instance Eq (SymbolRepr x) where-   _ == _ = True-instance Ord (SymbolRepr x) where-   compare _ _ = EQ--instance HashableF SymbolRepr where-  hashWithSaltF = hashWithSalt-instance Hashable (SymbolRepr nm) where-  hashWithSalt s (SymbolRepr nm) = hashWithSalt s nm--instance Show (SymbolRepr nm) where-  show (SymbolRepr nm) = Text.unpack nm--instance ShowF SymbolRepr
− submodules/parameterized-utils/src/Data/Parameterized/TH/GADT.hs
@@ -1,488 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.TH.GADT--- Copyright        : (c) Galois, Inc 2013-2014--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module declares template Haskell primitives so that it is easier--- to work with GADTs that have many constructors.--------------------------------------------------------------------------{-# LANGUAGE DoAndIfThenElse #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE EmptyCase #-}-module Data.Parameterized.TH.GADT-  ( -- * Instance generators-    -- $typePatterns-  structuralEquality-  , structuralTypeEquality-  , structuralTypeOrd-  , structuralTraversal-  , structuralShowsPrec-  , structuralHash-  , PolyEq(..)-    -- * Template haskell utilities that may be useful in other contexts.-  , DataD-  , lookupDataType'-  , asTypeCon-  , conPat-  , TypePat(..)-  , dataParamTypes-  , assocTypePats-  ) where--import Control.Monad-import Data.Hashable (hashWithSalt)-import Data.Maybe-import Data.Set (Set)-import qualified Data.Set as Set-import Language.Haskell.TH-import Language.Haskell.TH.Datatype---import Data.Parameterized.Classes----------------------------------------------------------------------------- Template Haskell utilities--type DataD = DatatypeInfo--lookupDataType' :: Name -> Q DatatypeInfo-lookupDataType' = reifyDatatype---- | Given a constructor and string, this generates a pattern for matching--- the expression, and the names of variables bound by pattern in order--- they appear in constructor.-conPat ::-  ConstructorInfo {- ^ constructor information -} ->-  String          {- ^ generated name prefix   -} ->-  Q (Pat, [Name]) {- ^ pattern and bound names -}-conPat con pre = do-  nms <- newNames pre (length (constructorFields con))-  return (ConP (constructorName con) (VarP <$> nms), nms)----- | Return an expression corresponding to the constructor.--- Note that this will have the type of a function expecting--- the argumetns given.-conExpr :: ConstructorInfo -> Exp-conExpr = ConE . constructorName----------------------------------------------------------------------------- TypePat---- | A type used to describe (and match) types appearing in generated pattern--- matches inside of the TH generators in this module ('structuralEquality',--- 'structuralTypeEquality', 'structuralTypeOrd', and 'structuralTraversal')-data TypePat-   = TypeApp TypePat TypePat -- ^ The application of a type.-   | AnyType       -- ^ Match any type.-   | DataArg Int   -- ^ Match the ith argument of the data type we are traversing.-   | ConType TypeQ -- ^ Match a ground type.--matchTypePat :: [Type] -> TypePat -> Type -> Q Bool-matchTypePat d (TypeApp p q) (AppT x y) = do-  r <- matchTypePat d p x-  case r of-    True -> matchTypePat d q y-    False -> return False-matchTypePat _ AnyType _ = return True-matchTypePat tps (DataArg i) tp-  | i < 0 || i > length tps = error $ "Illegal type pattern index " ++ show i-  | otherwise = do-    return $ stripSigT (tps !! i) == tp-  where-    -- th-abstraction can annotate type parameters with their kinds,-    -- we ignore these for matching-    stripSigT (SigT t _) = t-    stripSigT t          = t-matchTypePat _ (ConType tpq) tp = do-  tp' <- tpq-  return (tp' == tp)-matchTypePat _ _ _ = return False--dataParamTypes :: DatatypeInfo -> [Type]-dataParamTypes = datatypeVars---- | Find value associated with first pattern that matches given pat if any.-assocTypePats :: [Type] -> [(TypePat,v)] -> Type -> Q (Maybe v)-assocTypePats _ [] _ = return Nothing-assocTypePats dTypes ((p,v):pats) tp = do-  r <- matchTypePat dTypes p tp-  case r of-    True -> return (Just v)-    False -> assocTypePats dTypes pats tp----------------------------------------------------------------------------- Contructor cases--typeVars :: TypeSubstitution a => a -> Set Name-typeVars = Set.fromList . freeVariables----- | @structuralEquality@ declares a structural equality predicate.-structuralEquality :: TypeQ -> [(TypePat,ExpQ)] -> ExpQ-structuralEquality tpq pats =-  [| \x y -> isJust ($(structuralTypeEquality tpq pats) x y) |]--joinEqMaybe :: Name -> Name -> ExpQ -> ExpQ-joinEqMaybe x y r = do-  [| if $(varE x) == $(varE y) then $(r) else Nothing |]--joinTestEquality :: ExpQ -> Name -> Name -> ExpQ -> ExpQ-joinTestEquality f x y r =-  [| case $(f) $(varE x) $(varE y) of-      Nothing -> Nothing-      Just Refl -> $(r)-   |]--matchEqArguments :: [Type]-                    -- ^ Types bound by data arguments.-                  -> [(TypePat,ExpQ)] -- ^ Patterns for matching arguments-                 -> Name-                     -- ^ Name of constructor.-                 -> Set Name-                 -> [Type]-                 -> [Name]-                 -> [Name]-                 -> ExpQ-matchEqArguments dTypes pats cnm bnd (tp:tpl) (x:xl) (y:yl) = do-  doesMatch <- assocTypePats dTypes pats tp-  case doesMatch of-    Just q -> do-      let bnd' =-            case tp of-              AppT _ (VarT nm) -> Set.insert nm bnd-              _ -> bnd-      joinTestEquality q x y (matchEqArguments dTypes pats cnm bnd' tpl xl yl)-    Nothing | typeVars tp `Set.isSubsetOf` bnd -> do-      joinEqMaybe x y        (matchEqArguments dTypes pats cnm bnd  tpl xl yl)-    Nothing -> do-      fail $ "Unsupported argument type " ++ show tp-          ++ " in " ++ show (ppr cnm) ++ "."-matchEqArguments _ _ _ _ [] [] [] = [| Just Refl |]-matchEqArguments _ _ _ _ [] _  _  = error "Unexpected end of types."-matchEqArguments _ _ _ _ _  [] _  = error "Unexpected end of names."-matchEqArguments _ _ _ _ _  _  [] = error "Unexpected end of names."--mkSimpleEqF :: [Type] -- ^ Data declaration types-            -> Set Name-             -> [(TypePat,ExpQ)] -- ^ Patterns for matching arguments-             -> ConstructorInfo-             -> [Name]-             -> ExpQ-             -> Bool -- ^ wildcard case required-             -> ExpQ-mkSimpleEqF dTypes bnd pats con xv yQ multipleCases = do-  -- Get argument types for constructor.-  let nm = constructorName con-  (yp,yv) <- conPat con "y"-  let rv = matchEqArguments dTypes pats nm bnd (constructorFields con) xv yv-  caseE yQ $ match (pure yp) (normalB rv) []-           : [ match wildP (normalB [| Nothing |]) [] | multipleCases ]---- | Match equational form.-mkEqF :: DatatypeInfo -- ^ Data declaration.-      -> [(TypePat,ExpQ)]-      -> ConstructorInfo-      -> [Name]-      -> ExpQ-      -> Bool -- ^ wildcard case required-      -> ExpQ-mkEqF d pats con =-  let dVars = datatypeVars d-      bnd | null dVars = Set.empty-          | otherwise  = typeVars (init dVars)-  in mkSimpleEqF dVars bnd pats con---- | @structuralTypeEquality f@ returns a function with the type:---   forall x y . f x -> f y -> Maybe (x :~: y)-structuralTypeEquality :: TypeQ -> [(TypePat,ExpQ)] -> ExpQ-structuralTypeEquality tpq pats = do-  d <- reifyDatatype =<< asTypeCon "structuralTypeEquality" =<< tpq--  let multipleCons = not (null (drop 1 (datatypeCons d)))-      trueEqs yQ = [ do (xp,xv) <- conPat con "x"-                        match (pure xp) (normalB (mkEqF d pats con xv yQ multipleCons)) []-                   | con <- datatypeCons d-                   ]--  if null (datatypeCons d)-    then [| \x -> case x of {} |]-    else [| \x y -> $(caseE [| x |] (trueEqs [| y |])) |]---- | @structuralTypeOrd f@ returns a function with the type:---   forall x y . f x -> f y -> OrderingF x y------ This implementation avoids matching on both the first and second--- parameters in a simple case expression in order to avoid stressing--- GHC's coverage checker. In the case that the first and second parameters--- have unique constructors, a simple numeric comparison is done to--- compute the result.-structuralTypeOrd ::-  TypeQ ->-  [(TypePat,ExpQ)] {- ^ List of type patterns to match. -} ->-  ExpQ-structuralTypeOrd tpq l = do-  d <- reifyDatatype =<< asTypeCon "structuralTypeEquality" =<< tpq--  let withNumber :: ExpQ -> (Maybe ExpQ -> ExpQ) -> ExpQ-      withNumber yQ k-        | null (drop 1 (datatypeCons d)) = k Nothing-        | otherwise =  [| let yn :: Int-                              yn = $(caseE yQ (constructorNumberMatches (datatypeCons d)))-                          in $(k (Just [| yn |])) |]--  if null (datatypeCons d)-    then [| \x -> case x of {} |]-    else [| \x y -> $(withNumber [|y|] $ \mbYn -> caseE [| x |] (outerOrdMatches d [|y|] mbYn)) |]-  where-    constructorNumberMatches :: [ConstructorInfo] -> [MatchQ]-    constructorNumberMatches cons =-      [ match (recP (constructorName con) [])-              (normalB (litE (integerL i)))-              []-      | (i,con) <- zip [0..] cons ]--    outerOrdMatches :: DatatypeInfo -> ExpQ -> Maybe ExpQ -> [MatchQ]-    outerOrdMatches d yExp mbYn =-      [ do (pat,xv) <- conPat con "x"-           match (pure pat)-                 (normalB (do xs <- mkOrdF d l con i mbYn xv-                              caseE yExp xs))-                 []-      | (i,con) <- zip [0..] (datatypeCons d) ]---- | Generate a list of fresh names using the base name--- numbered 1 to n to make them useful in conjunction with--- @-dsuppress-unqiues@.-newNames ::-  String   {- ^ base name                     -} ->-  Int      {- ^ quantity                      -} ->-  Q [Name] {- ^ list of names: base1, base2.. -}-newNames base n = traverse (\i -> newName (base ++ show i)) [1..n]---joinCompareF :: ExpQ -> Name -> Name -> ExpQ -> ExpQ-joinCompareF f x y r = do-  [| case $(f) $(varE x) $(varE y) of-      LTF -> LTF-      GTF -> GTF-      EQF -> $(r)-   |]---- | Compare two variables and use following comparison if they are different.------ This returns an 'OrdF' instance.-joinCompareToOrdF :: Name -> Name -> ExpQ -> ExpQ-joinCompareToOrdF x y r =-  [| case compare $(varE x) $(varE y) of-      LT -> LTF-      GT -> GTF-      EQ -> $(r)-   |]--  -- Match expression with given type to variables-matchOrdArguments :: [Type]-                     -- ^ Types bound by data arguments-                  -> [(TypePat,ExpQ)] -- ^ Patterns for matching arguments-                  -> Name-                     -- ^ Name of constructor.-                  -> Set Name-                    -- ^ Names bound in data declaration-                  -> [Type]-                     -- ^ Types for constructors-                  -> [Name]-                     -- ^ Variables bound in first pattern-                  -> [Name]-                     -- ^ Variables bound in second pattern-                  -> ExpQ-matchOrdArguments dTypes pats cnm bnd (tp : tpl) (x:xl) (y:yl) = do-  doesMatch <- assocTypePats dTypes pats tp-  case doesMatch of-    Just f -> do-      let bnd' = case tp of-                   AppT _ (VarT nm) -> Set.insert nm bnd-                   _ -> bnd-      joinCompareF f x y (matchOrdArguments dTypes pats cnm bnd' tpl xl yl)-    Nothing | typeVars tp `Set.isSubsetOf` bnd -> do-      joinCompareToOrdF x y (matchOrdArguments dTypes pats cnm bnd tpl xl yl)-    Nothing ->-      fail $ "Unsupported argument type " ++ show (ppr tp)-             ++ " in " ++ show (ppr cnm) ++ "."-matchOrdArguments _ _ _ _ [] [] [] = [| EQF |]-matchOrdArguments _ _ _ _ [] _  _  = error "Unexpected end of types."-matchOrdArguments _ _ _ _ _  [] _  = error "Unexpected end of names."-matchOrdArguments _ _ _ _ _  _  [] = error "Unexpected end of names."--mkSimpleOrdF :: [Type] -- ^ Data declaration types-             -> [(TypePat,ExpQ)] -- ^ Patterns for matching arguments-             -> ConstructorInfo -- ^ Information about the second constructor-             -> Integer -- ^ First constructor's index-             -> Maybe ExpQ -- ^ Optional second constructor's index-             -> [Name]  -- ^ Name from first pattern-             -> Q [MatchQ]-mkSimpleOrdF dTypes pats con xnum mbYn xv = do-  (yp,yv) <- conPat con "y"-  let rv = matchOrdArguments dTypes pats (constructorName con) Set.empty (constructorFields con) xv yv-  -- Return match expression-  return $ match (pure yp) (normalB rv) []-         : case mbYn of-             Nothing -> []-             Just yn -> [match wildP (normalB [| if xnum < $yn then LTF else GTF |]) []]---- | Match equational form.-mkOrdF :: DatatypeInfo -- ^ Data declaration.-       -> [(TypePat,ExpQ)] -- ^ Patterns for matching arguments-       -> ConstructorInfo-       -> Integer-       -> Maybe ExpQ -- ^ optional right constructr index-       -> [Name]-       -> Q [MatchQ]-mkOrdF d pats = mkSimpleOrdF (datatypeVars d) pats---- | Find the first recurseArg f var tp@ applies @f@ to @var@ where @var@ has type @tp@.-recurseArg :: (Type -> Q (Maybe ExpQ))-           -> ExpQ -- ^ Function to apply-           -> ExpQ-           -> Type-           -> Q (Maybe Exp)-recurseArg m f v tp = do-  mr <- m tp-  case mr of-    Just g ->  Just <$> [| $(g) $(f) $(v) |]-    Nothing ->-      case tp of-        AppT (ConT _) (AppT (VarT _) _) -> Just <$> [| traverse $(f) $(v) |]-        AppT (VarT _) _ -> Just <$> [| $(f) $(v) |]-        _ -> return Nothing---- | @traverseAppMatch f c@ builds a case statement that matches a term with--- the constructor @c@ and applies @f@ to each argument.-traverseAppMatch :: (Type -> Q (Maybe ExpQ)) -- Pattern match function-                 -> ExpQ -- ^ Function to apply to each argument recursively.-                 -> ConstructorInfo -- ^ Constructor to match.-                 -> MatchQ -- ^ Match expression that-traverseAppMatch pats fv c0 = do-  (pat,patArgs) <- conPat c0 "p"-  exprs <- zipWithM (recurseArg pats fv) (varE <$> patArgs) (constructorFields c0)--  let mkRes :: ExpQ -> [(Name, Maybe Exp)] -> ExpQ-      mkRes e [] = e-      mkRes e ((v,Nothing):r) =-        mkRes (appE e (varE v)) r-      mkRes e ((_,Just{}):r) = do-        v <- newName "r"-        lamE [varP v] (mkRes (appE e (varE v)) r)--  -- Apply the remaining argument to the expression in list.-  let applyRest :: ExpQ -> [Exp] -> ExpQ-      applyRest e [] = e-      applyRest e (a:r) = applyRest [| $(e) <*> $(pure a) |] r--  -- Apply the first argument to the list-  let applyFirst :: ExpQ -> [Exp] -> ExpQ-      applyFirst e [] = [| pure $(e) |]-      applyFirst e (a:r) = applyRest [| $(e) <$> $(pure a) |] r--  let pargs = patArgs `zip` exprs-  let rhs = applyFirst (mkRes (pure (conExpr c0)) pargs) (catMaybes exprs)-  match (pure pat) (normalB rhs) []---- | @structuralTraversal tp@ generates a function that applies--- a traversal @f@ to the subterms with free variables in @tp@.-structuralTraversal :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ-structuralTraversal tpq pats0 = do-  d <- reifyDatatype =<< asTypeCon "structuralTraversal" =<< tpq-  f <- newName "f"-  a <- newName "a"-  lamE [varP f, varP a] $-      caseE (varE a)-      (traverseAppMatch (assocTypePats (datatypeVars d) pats0) (varE f) <$> datatypeCons d)--asTypeCon :: Monad m => String -> Type -> m Name-asTypeCon _ (ConT nm) = return nm-asTypeCon fn _ = fail $ fn ++ " expected type constructor."---- | @structuralHash tp@ generates a function with the type--- @Int -> tp -> Int@ that hashes type.-structuralHash :: TypeQ -> ExpQ-structuralHash tpq = do-  d <- reifyDatatype =<< asTypeCon "structuralHash" =<< tpq-  s <- newName "s"-  a <- newName "a"-  lamE [varP s, varP a] $-    caseE (varE a) (zipWith (matchHashCtor (varE s)) [0..] (datatypeCons d))--matchHashCtor :: ExpQ -> Integer  -> ConstructorInfo -> MatchQ-matchHashCtor s0 i c = do-  (pat,vars) <- conPat c "x"-  let args = [| $(litE (IntegerL i)) :: Int |] : (varE <$> vars)-  let go s e = [| hashWithSalt $(s) $(e) |]-  let rhs = foldl go s0 args-  match (pure pat) (normalB rhs) []---- | @structuralShow tp@ generates a function with the type--- @tp -> ShowS@ that shows the constructor.-structuralShowsPrec :: TypeQ -> ExpQ-structuralShowsPrec tpq = do-  d <- reifyDatatype =<< asTypeCon "structuralShowPrec" =<< tpq-  p <- newName "_p"-  a <- newName "a"-  lamE [varP p, varP a] $-    caseE (varE a) (matchShowCtor (varE p) <$> datatypeCons d)--showCon :: ExpQ -> Name -> Int -> MatchQ-showCon p nm n = do-  vars <- newNames "x" n-  let pat = ConP nm (VarP <$> vars)-  let go s e = [| $(s) . showChar ' ' . showsPrec 10 $(varE e) |]-  let ctor = [| showString $(return (LitE (StringL (nameBase nm)))) |]-  let rhs | null vars = ctor-          | otherwise = [| showParen ($(p) >= 10) $(foldl go ctor vars) |]-  match (pure pat) (normalB rhs) []--matchShowCtor :: ExpQ -> ConstructorInfo -> MatchQ-matchShowCtor p con = showCon p (constructorName con) (length (constructorFields con))---- $typePatterns------ The Template Haskell instance generators 'structuralEquality',--- 'structuralTypeEquality', 'structuralTypeOrd', and 'structuralTraversal'--- employ heuristics to generate valid instances in the majority of cases.  Most--- failures in the heuristics occur on sub-terms that are type indexed.  To--- handle cases where these functions fail to produce a valid instance, they--- take a list of exceptions in the form of their second parameter, which has--- type @[('TypePat', 'ExpQ')]@.  Each 'TypePat' is a /matcher/ that tells the--- TH generator to use the 'ExpQ' to process the matched sub-term.  Consider the--- following example:------ > data T a b where--- >   C1 :: NatRepr n -> T () n--- >--- > instance TestEquality (T a) where--- >   testEquality = $(structuralTypeEquality [t|T|]--- >                    [ (ConType [t|NatRepr|] `TypeApp` AnyType, [|testEquality|])--- >                    ])------ The exception list says that 'structuralTypeEquality' should use--- 'testEquality' to compare any sub-terms of type @'NatRepr' n@ in a value of--- type @T@.------ * 'AnyType' means that the type parameter in that position can be instantiated as any type------ * @'DataArg' n@ means that the type parameter in that position is the @n@-th---   type parameter of the GADT being traversed (@T@ in the example)------ * 'TypeApp' is type application------ * 'ConType' specifies a base type------ The exception list could have equivalently (and more precisely) have been specified as:------ > [(ConType [t|NatRepr|] `TypeApp` DataArg 1, [|testEquality|])]------ The use of 'DataArg' says that the type parameter of the 'NatRepr' must--- be the same as the second type parameter of @T@.
− submodules/parameterized-utils/src/Data/Parameterized/TestEquality.hs
@@ -1,36 +0,0 @@-{-|-Copyright        : (c) Galois, Inc 2014-2018-Maintainer       : Langston Barrett <langston@galois.com--Utilities for working with "Data.Type.TestEquality".--NB: This module contains an orphan instance.--}--{-# LANGUAGE GADTs #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}--import Data.Functor.Compose-import Data.Type.Equality--testEqualityComposeBare :: forall f g x y.-                           (forall w z. f w -> f z -> Maybe (w :~: z))-                        -> Compose f g x-                        -> Compose f g y-                        -> Maybe (x :~: y)-testEqualityComposeBare testEquality_ (Compose x) (Compose y) =-  case (testEquality_ x y :: Maybe (g x :~: g y)) of-    Just Refl -> Just (Refl :: x :~: y)-    Nothing   -> Nothing--testEqualityCompose :: forall f g x y. (TestEquality f)-                    => Compose f g x-                    -> Compose f g y-                    -> Maybe (x :~: y)-testEqualityCompose = testEqualityComposeBare testEquality---- | The deduction (via generativity) that if @g x :~: g y@ then @x :~: y@.-instance (TestEquality f) => TestEquality (Compose f g) where-  testEquality = testEqualityCompose
− submodules/parameterized-utils/src/Data/Parameterized/TraversableF.hs
@@ -1,146 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.TraversableF--- Copyright        : (c) Galois, Inc 2014-2015--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module declares classes for working with structures that accept--- a single parametric type parameter.--------------------------------------------------------------------------{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE Trustworthy #-}-module Data.Parameterized.TraversableF-  ( FunctorF(..)-  , FoldableF(..)-  , TraversableF(..)-  , traverseF_-  , fmapFDefault-  , foldMapFDefault-  , allF-  , anyF-  ) where--import Control.Applicative-import Control.Monad.Identity-import Data.Coerce-import Data.Functor.Compose (Compose(..))-import Data.Monoid-import GHC.Exts (build)--import Data.Parameterized.TraversableFC---- | A parameterized type that is a functor on all instances.-class FunctorF m where-  fmapF :: (forall x . f x -> g x) -> m f -> m g--instance FunctorF (Const x) where-  fmapF _ = coerce----------------------------------------------------------------------------- FoldableF---- | This is a coercion used to avoid overhead associated--- with function composition.-(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)-(#.) _f = coerce---- | This is a generalization of the @Foldable@ class to--- structures over parameterized terms.-class FoldableF (t :: (k -> *) -> *) where-  {-# MINIMAL foldMapF | foldrF #-}--  -- | Map each element of the structure to a monoid,-  -- and combine the results.-  foldMapF :: Monoid m => (forall s . e s -> m) -> t e -> m-  foldMapF f = foldrF (mappend . f) mempty--  -- | Right-associative fold of a structure.-  foldrF :: (forall s . e s -> b -> b) -> b -> t e -> b-  foldrF f z t = appEndo (foldMapF (Endo #. f) t) z--  -- | Left-associative fold of a structure.-  foldlF :: (forall s . b -> e s -> b) -> b -> t e -> b-  foldlF f z t = appEndo (getDual (foldMapF (\e -> Dual (Endo (\r -> f r e))) t)) z--  -- | Right-associative fold of a structure,-  -- but with strict application of the operator.-  foldrF' :: (forall s . e s -> b -> b) -> b -> t e -> b-  foldrF' f0 z0 xs = foldlF (f' f0) id xs z0-    where f' f k x z = k $! f x z--  -- | Left-associative fold of a parameterized structure-  -- with a strict accumulator.-  foldlF' :: (forall s . b -> e s -> b) -> b -> t e -> b-  foldlF' f0 z0 xs = foldrF (f' f0) id xs z0-    where f' f x k z = k $! f z x--  -- | Convert structure to list.-  toListF :: (forall tp . f tp -> a) -> t f -> [a]-  toListF f t = build (\c n -> foldrF (\e v -> c (f e) v) n t)---- | Return 'True' if all values satisfy predicate.-allF :: FoldableF t => (forall tp . f tp -> Bool) -> t f -> Bool-allF p = getAll #. foldMapF (All #. p)---- | Return 'True' if any values satisfy predicate.-anyF :: FoldableF t => (forall tp . f tp -> Bool) -> t f -> Bool-anyF p = getAny #. foldMapF (Any #. p)--instance FoldableF (Const x) where-  foldMapF _ _ = mempty----------------------------------------------------------------------------- TraversableF--class (FunctorF t, FoldableF t) => TraversableF t where-  traverseF :: Applicative m-            => (forall s . e s -> m (f s))-            -> t e-            -> m (t f)--instance TraversableF (Const x) where-  traverseF _ (Const x) = pure (Const x)---- | This function may be used as a value for `fmapF` in a `FunctorF`--- instance.-fmapFDefault :: TraversableF t => (forall s . e s -> f s) -> t e -> t f-fmapFDefault f = runIdentity #. traverseF (Identity #. f)-{-# INLINE fmapFDefault #-}---- | This function may be used as a value for `Data.Foldable.foldMap`--- in a `Foldable` instance.-foldMapFDefault :: (TraversableF t, Monoid m) => (forall s . e s -> m) -> t e -> m-foldMapFDefault f = getConst #. traverseF (Const #. f)---- | Map each element of a structure to an action, evaluate--- these actions from left to right, and ignore the results.-traverseF_ :: (FoldableF t, Applicative f) => (forall s . e s  -> f a) -> t e -> f ()-traverseF_ f = foldrF (\e r -> f e *> r) (pure ())----------------------------------------------------------------------------- TraversableF (Compose s t)--instance ( FunctorF (s :: (k -> *) -> *)-         , FunctorFC (t :: (l -> *) -> (k -> *))-         ) =>-         FunctorF (Compose s t) where-  fmapF f (Compose v) = Compose $ fmapF (fmapFC f) v--instance ( TraversableF (s :: (k -> *) -> *)-         , TraversableFC (t :: (l -> *) -> (k -> *))-         ) =>-         FoldableF (Compose s t) where-  foldMapF = foldMapFDefault---- | Traverse twice over: go under the @t@, under the @s@ and lift @m@ out.-instance ( TraversableF (s :: (k -> *) -> *)-         , TraversableFC (t :: (l -> *) -> (k -> *))-         ) =>-         TraversableF (Compose s t) where-  traverseF :: forall (f :: l -> *) (g :: l -> *) m. (Applicative m) =>-               (forall (u :: l). f u -> m (g u))-            -> Compose s t f -> m (Compose s t g)-  traverseF f (Compose v) = Compose <$> traverseF (traverseFC f) v
− submodules/parameterized-utils/src/Data/Parameterized/TraversableFC.hs
@@ -1,161 +0,0 @@---------------------------------------------------------------------------- |--- Module           : Data.Parameterized.TraversableFC--- Copyright        : (c) Galois, Inc 2014-2015--- Maintainer       : Joe Hendrix <jhendrix@galois.com>------ This module declares classes for working with structures that accept--- a parametric type parameter followed by some fixed kind.--------------------------------------------------------------------------{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE Trustworthy #-}-{-# LANGUAGE TypeOperators #-}-module Data.Parameterized.TraversableFC-  ( TestEqualityFC(..)-  , OrdFC(..)-  , ShowFC(..)-  , HashableFC(..)-  , FunctorFC(..)-  , FoldableFC(..)-  , TraversableFC(..)-  , traverseFC_-  , forMFC_-  , fmapFCDefault-  , foldMapFCDefault-  , allFC-  , anyFC-  , lengthFC-  ) where--import Control.Applicative (Const(..) )-import Control.Monad.Identity ( Identity (..) )-import Data.Coerce-import Data.Monoid-import GHC.Exts (build)-import Data.Type.Equality--import Data.Parameterized.Classes---- | A parameterized type that is a function on all instances.-class FunctorFC (t :: (k -> *) -> l -> *) where-  fmapFC :: forall f g. (forall x. f x -> g x) ->-                        (forall x. t f x -> t g x)---- | A parameterized class for types which can be shown, when given---   functions to show parameterized subterms.-class ShowFC (t :: (k -> *) -> l -> *) where-  {-# MINIMAL showFC | showsPrecFC #-}--  showFC :: forall f. (forall x. f x -> String)-         -> (forall x. t f x -> String)-  showFC sh x = showsPrecFC (\_prec z rest -> sh z ++ rest) 0 x []--  showsPrecFC :: forall f. (forall x. Int -> f x -> ShowS) ->-                           (forall x. Int -> t f x -> ShowS)-  showsPrecFC sh _prec x rest = showFC (\z -> sh 0 z []) x ++ rest----- | A parameterized class for types which can be hashed, when given---   functions to hash parameterized subterms.-class HashableFC (t :: (k -> *) -> l -> *) where-  hashWithSaltFC :: forall f. (forall x. Int -> f x -> Int) ->-                              (forall x. Int -> t f x -> Int)---- | A parameterized class for types which can be tested for parameterized equality,---   when given an equality test for subterms.-class TestEqualityFC (t :: (k -> *) -> l -> *) where-  testEqualityFC :: forall f. (forall x y. f x -> f y -> (Maybe (x :~: y))) ->-                              (forall x y. t f x -> t f y -> (Maybe (x :~: y)))---- | A parameterized class for types which can be tested for parameterized ordering,---   when given an comparison test for subterms.-class TestEqualityFC t => OrdFC (t :: (k -> *) -> l -> *) where-  compareFC :: forall f. (forall x y. f x -> f y -> OrderingF x y) ->-                         (forall x y. t f x -> t f y -> OrderingF x y)----------------------------------------------------------------------------- FoldableF---- | This is a coercision used to avoid overhead associated--- with function composition.-(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)-(#.) _f = coerce---- | This is a generalization of the @Foldable@ class to--- structures over parameterized terms.-class FoldableFC (t :: (k -> *) -> l -> *) where-  {-# MINIMAL foldMapFC | foldrFC #-}--  -- | Map each element of the structure to a monoid,-  -- and combine the results.-  foldMapFC :: forall f m. Monoid m => (forall x. f x -> m) -> (forall x. t f x -> m)-  foldMapFC f = foldrFC (mappend . f) mempty--  -- | Right-associative fold of a structure.-  foldrFC :: forall f b. (forall x. f x -> b -> b) -> (forall x. b -> t f x -> b)-  foldrFC f z t = appEndo (foldMapFC (Endo #. f) t) z--  -- | Left-associative fold of a structure.-  foldlFC :: forall f b. (forall x. b -> f x -> b) -> (forall x. b -> t f x -> b)-  foldlFC f z t = appEndo (getDual (foldMapFC (\e -> Dual (Endo (\r -> f r e))) t)) z--  -- | Right-associative fold of a structure,-  -- but with strict application of the operator.-  foldrFC' :: forall f b. (forall x. f x -> b -> b) -> (forall x. b -> t f x -> b)-  foldrFC' f0 z0 xs = foldlFC (f' f0) id xs z0-    where f' f k x z = k $! f x z--  -- | Left-associative fold of a parameterized structure-  -- with a strict accumulator.-  foldlFC' :: forall f b. (forall x. b -> f x -> b) -> (forall x. b -> t f x -> b)-  foldlFC' f0 z0 xs = foldrFC (f' f0) id xs z0-    where f' f x k z = k $! f z x--  -- | Convert structure to list.-  toListFC :: forall f a. (forall x. f x -> a) -> (forall x. t f x -> [a])-  toListFC f t = build (\c n -> foldrFC (\e v -> c (f e) v) n t)---- | Return 'True' if all values satisfy predicate.-allFC :: FoldableFC t => (forall x. f x -> Bool) -> (forall x. t f x -> Bool)-allFC p = getAll #. foldMapFC (All #. p)---- | Return 'True' if any values satisfy predicate.-anyFC :: FoldableFC t => (forall x. f x -> Bool) -> (forall x. t f x -> Bool)-anyFC p = getAny #. foldMapFC (Any #. p)---- | Return number of elements in list.-lengthFC :: FoldableFC t => t f x -> Int-lengthFC = foldrFC (const (+1)) 0----------------------------------------------------------------------------- TraversableF--class (FunctorFC t, FoldableFC t) => TraversableFC (t :: (k -> *) -> l -> *) where-  traverseFC :: forall f g m. Applicative m-             => (forall x. f x -> m (g x))-             -> (forall x. t f x -> m (t g x))---- | This function may be used as a value for `fmapF` in a `FunctorF`--- instance.-fmapFCDefault :: TraversableFC t => forall f g. (forall x. f x -> g x) -> (forall x. t f x -> t g x)-fmapFCDefault = \f -> runIdentity . traverseFC (Identity . f)-{-# INLINE fmapFCDefault #-}---- | This function may be used as a value for `Data.Foldable.foldMap`--- in a `Foldable` instance.-foldMapFCDefault :: (TraversableFC t, Monoid m) => (forall x. f x -> m) -> (forall x. t f x -> m)-foldMapFCDefault = \f -> getConst . traverseFC (Const . f)-{-# INLINE foldMapFCDefault #-}---- | Map each element of a structure to an action, evaluate--- these actions from left to right, and ignore the results.-traverseFC_ :: (FoldableFC t, Applicative m) => (forall x. f x -> m a) -> (forall x. t f x -> m ())-traverseFC_ f = foldrFC (\e r -> f e *> r) (pure ())-{-# INLINE traverseFC_ #-}---- | Map each element of a structure to an action, evaluate--- these actions from left to right, and ignore the results.-forMFC_ :: (FoldableFC t, Applicative m) => t f c -> (forall x. f x -> m a) -> m ()-forMFC_ v f = traverseFC_ f v-{-# INLINE forMFC_ #-}
− submodules/parameterized-utils/src/Data/Parameterized/Utils/BinTree.hs
@@ -1,368 +0,0 @@-{-|-Description      : Utilities for balanced binary trees.-Copyright        : (c) Galois, Inc 2014-Maintainer       : Joe Hendrix <jhendrix@galois.com>--}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE Safe #-}-module Data.Parameterized.Utils.BinTree-  ( MaybeS(..)-  , fromMaybeS-  , Updated(..)-  , updatedValue-  , TreeApp(..)-  , IsBinTree(..)-  , balanceL-  , balanceR-  , glue-  , merge-  , filterGt-  , filterLt-  , insert-  , delete-  , union-  , link-  , PairS(..)-  ) where--import Control.Applicative----------------------------------------------------------------------------- MaybeS---- | A strict version of 'Maybe'-data MaybeS v-   = JustS !v-   | NothingS--instance Functor MaybeS where-  fmap _ NothingS = NothingS-  fmap f (JustS v) = JustS (f v)--instance Alternative MaybeS where-  empty = NothingS-  mv@JustS{} <|> _ = mv-  NothingS <|> v = v--instance Applicative MaybeS where-  pure = JustS--  NothingS <*> _ = NothingS-  JustS{} <*> NothingS = NothingS-  JustS f <*> JustS x = JustS (f x)--fromMaybeS :: a -> MaybeS a -> a-fromMaybeS r NothingS = r-fromMaybeS _ (JustS v) = v----------------------------------------------------------------------------- Updated---- | Updated a contains a value that has been flagged on whether it was--- modified by an operation.-data Updated a-   = Updated   !a-   | Unchanged !a--updatedValue :: Updated a -> a-updatedValue (Updated a) = a-updatedValue (Unchanged a) = a----------------------------------------------------------------------------- IsBinTree--data TreeApp e t-   = BinTree !e !t !t-   | TipTree--class IsBinTree t e | t -> e where-  asBin :: t -> TreeApp e t-  tip :: t--  bin :: e -> t -> t -> t-  size :: t -> Int--delta,ratio :: Int-delta = 3-ratio = 2---- `balanceL p l r` returns a balanced tree for the sequence @l ++ [p] ++ r@.------ It assumes that @l@ and @r@ are close to being balanced, and that only--- @l@ may contain too many elements.-balanceL :: (IsBinTree c e) => e -> c -> c -> c-balanceL p l r = do-  case asBin l of-    BinTree l_pair ll lr | size l > max 1 (delta*size r) ->-      case asBin lr of-        BinTree lr_pair lrl lrr | size lr >= max 2 (ratio*size ll) ->-          bin lr_pair (bin l_pair ll lrl) (bin p lrr r)-        _ -> bin l_pair ll (bin p lr r)--    _ -> bin p l r-{-# INLINE balanceL #-}---- `balanceR p l r` returns a balanced tree for the sequence @l ++ [p] ++ r@.------ It assumes that @l@ and @r@ are close to being balanced, and that only--- @r@ may contain too many elements.-balanceR :: (IsBinTree c e) => e -> c -> c -> c-balanceR p l r = do-  case asBin r of-    BinTree r_pair rl rr | size r > max 1 (delta*size l) ->-      case asBin rl of-        BinTree rl_pair rll rlr | size rl >= max 2 (ratio*size rr) ->-          (bin rl_pair $! bin p l rll) $! bin r_pair rlr rr-        _ -> bin r_pair (bin p l rl) rr-    _ -> bin p l r-{-# INLINE balanceR #-}---- | Insert a new maximal element.-insertMax :: IsBinTree c e => e -> c -> c-insertMax p t =-  case asBin t of-    TipTree -> bin p tip tip-    BinTree q l r -> balanceR q l (insertMax p r)---- | Insert a new minimal element.-insertMin :: IsBinTree c e => e -> c -> c-insertMin p t =-  case asBin t of-    TipTree -> bin p tip tip-    BinTree q l r -> balanceL q (insertMin p l) r---- | link is called to insert a key and value between two disjoint subtrees.-link :: IsBinTree c e => e -> c -> c -> c-link p l r =-  case (asBin l, asBin r) of-    (TipTree, _) -> insertMin p r-    (_, TipTree) -> insertMax p l-    (BinTree py ly ry, BinTree pz lz rz)-     | delta*size l < size r -> balanceL pz (link p l lz) rz-     | delta*size r < size l -> balanceR py ly (link p ry r)-     | otherwise             -> bin p l r-{-# INLINE link #-}---- | A Strict pair-data PairS f s = PairS !f !s--deleteFindMin :: IsBinTree c e => e -> c -> c -> PairS e c-deleteFindMin p l r =-  case asBin l of-    TipTree -> PairS p r-    BinTree lp ll lr ->-      case deleteFindMin lp ll lr of-        PairS q l' -> PairS q (balanceR p l' r)-{-# INLINABLE deleteFindMin #-}--deleteFindMax :: IsBinTree c e => e -> c -> c -> PairS e c-deleteFindMax p l r =-  case asBin r of-    TipTree -> PairS p l-    BinTree rp rl rr ->-      case deleteFindMax rp rl rr of-        PairS q r' -> PairS q (balanceL p l r')-{-# INLINABLE deleteFindMax #-}---- | Concatenate two trees that are ordered with respect to each other.-merge :: IsBinTree c e => c -> c -> c-merge l r =-  case (asBin l, asBin r) of-    (TipTree, _) -> r-    (_, TipTree) -> l-    (BinTree x lx rx, BinTree y ly ry)-      | delta*size l < size r -> balanceL y (merge l ly) ry-      | delta*size r < size l -> balanceR x lx (merge rx r)-      | size l > size r ->-        case deleteFindMax x lx rx of-          PairS q l' -> balanceR q l' r-      | otherwise ->-        case deleteFindMin y ly ry of-          PairS q r' -> balanceL q l r'-{-# INLINABLE merge #-}----------------------------------------------------------------------------- Ordered operations---- | @insert p m@ inserts the binding into @m@.  It returns--- an Unchanged value if the map stays the same size and an updated--- value if a new entry was inserted.-insert :: (IsBinTree c e) => (e -> e -> Ordering) -> e -> c -> Updated c-insert comp x t =-  case asBin t of-    TipTree -> Updated (bin x tip tip)-    BinTree y l r ->-      case comp x y of-        LT ->-          case insert comp x l of-            Updated l'   -> Updated   (balanceL y l' r)-            Unchanged l' -> Unchanged (bin       y l' r)-        GT ->-          case insert comp x r of-            Updated r'   -> Updated   (balanceR y l r')-            Unchanged r' -> Unchanged (bin       y l r')-        EQ -> Unchanged (bin x l r)-{-# INLINABLE insert #-}---- | 'glue l r' concatenates @l@ and @r@.------ It assumes that @l@ and @r@ are already balanced with respect to each other.-glue :: IsBinTree c e => c -> c -> c-glue l r =-  case (asBin l, asBin r) of-    (TipTree, _) -> r-    (_, TipTree) -> l-    (BinTree x lx rx, BinTree y ly ry)-     | size l > size r ->-       case deleteFindMax x lx rx of-         PairS q l' -> balanceR q l' r-     | otherwise ->-       case deleteFindMin y ly ry of-         PairS q r' -> balanceL q l r'-{-# INLINABLE glue #-}--delete :: IsBinTree c e-       => (e -> Ordering)-          -- ^ Predicate that returns whether the entry is less than, greater than, or equal-          -- to the key we are entry that we are looking for.-       -> c-       -> MaybeS c-delete k t =-  case asBin t of-    TipTree -> NothingS-    BinTree p l r ->-      case k p of-        LT -> (\l' -> balanceR p l' r) <$> delete k l-        GT -> (\r' -> balanceL p l r') <$> delete k r-        EQ -> JustS (glue l r)-{-# INLINABLE delete #-}----------------------------------------------------------------------------- filter---- | Returns only entries that are less than predicate with respect to the ordering--- and Nothing if no elements are discared.-filterGt :: IsBinTree c e => (e -> Ordering) -> c -> MaybeS c-filterGt k t =-  case asBin t of-    TipTree -> NothingS-    BinTree x l r ->-      case k x of-        LT -> (\l' -> link x l' r) <$> filterGt k l-        GT -> filterGt k r <|> JustS r-        EQ -> JustS r-{-# INLINABLE filterGt #-}----- | @filterLt' k m@ returns submap of @m@ that only contains entries--- that are smaller than @k@.  If no entries are deleted then return Nothing.-filterLt :: IsBinTree c e => (e -> Ordering) -> c -> MaybeS c-filterLt k t =-  case asBin t of-    TipTree -> NothingS-    BinTree x l r ->-      case k x of-        LT -> filterLt k l <|> JustS l-        GT -> (\r' -> link x l r') <$> filterLt k r-        EQ -> JustS l-{-# INLINABLE filterLt #-}----------------------------------------------------------------------------- Union---- Insert a new key and value in the map if it is not already present.--- Used by `union`.-insertR :: forall c e . (IsBinTree c e) => (e -> e -> Ordering) -> e -> c -> c-insertR comp e m = fromMaybeS m (go e m)-  where-    go :: e -> c -> MaybeS c-    go x t =-      case asBin t of-        TipTree -> JustS (bin x tip tip)-        BinTree y l r ->-          case comp x y of-            LT -> (\l' -> balanceL y l' r) <$> go x l-            GT -> (\r' -> balanceR y l r') <$> go x r-            EQ -> NothingS-{-# INLINABLE insertR #-}---- | Union two sets-union :: (IsBinTree c e) => (e -> e -> Ordering) -> c -> c -> c-union comp t1 t2 =-  case (asBin t1, asBin t2) of-    (TipTree, _) -> t2-    (_, TipTree) -> t1-    (_, BinTree p (asBin -> TipTree) (asBin -> TipTree)) -> insertR comp p t1-    (BinTree x l r, _) ->-      link x-           (hedgeUnion_UB comp x   l t2)-           (hedgeUnion_LB comp x r   t2)-{-# INLINABLE union #-}---- | Hedge union where we only add elements in second map if key is--- strictly above a lower bound.-hedgeUnion_LB :: (IsBinTree c e) => (e -> e -> Ordering) -> e -> c -> c -> c-hedgeUnion_LB comp lo t1 t2 =-  case (asBin t1, asBin t2) of-    (_, TipTree) -> t1-    (TipTree, _) -> fromMaybeS t2 (filterGt (comp lo) t2)-    -- Prune left tree.-    (_, BinTree k _ r) | comp k lo <= EQ -> hedgeUnion_LB comp lo t1 r-    -- Special case when t2 is a single element.-    (_, BinTree x (asBin -> TipTree) (asBin -> TipTree)) -> insertR comp x t1-    -- Split on left-and-right subtrees of t1.-    (BinTree x l r, _) ->-      link x-           (hedgeUnion_LB_UB comp lo x  l t2)-           (hedgeUnion_LB    comp x     r t2)-{-# INLINABLE hedgeUnion_LB #-}---- | Hedge union where we only add elements in second map if key is--- strictly below a upper bound.-hedgeUnion_UB :: (IsBinTree c e) => (e -> e -> Ordering) -> e -> c -> c -> c-hedgeUnion_UB comp hi t1 t2 =-  case (asBin t1, asBin t2) of-    (_, TipTree) -> t1-    (TipTree, _) -> fromMaybeS t2 (filterLt (comp hi) t2)-    -- Prune right tree.-    (_, BinTree x l _) | comp x hi >= EQ -> hedgeUnion_UB comp hi t1 l-    -- Special case when t2 is a single element.-    (_, BinTree x (asBin -> TipTree) (asBin -> TipTree))  -> insertR comp x t1-    -- Split on left-and-right subtrees of t1.-    (BinTree x l r, _) ->-      link x-           (hedgeUnion_UB    comp x      l t2)-           (hedgeUnion_LB_UB comp x  hi  r t2)-{-# INLINABLE hedgeUnion_UB #-}---- | Hedge union where we only add elements in second map if key is--- strictly between a lower and upper bound.-hedgeUnion_LB_UB :: (IsBinTree c e) => (e -> e -> Ordering) -> e -> e -> c -> c -> c-hedgeUnion_LB_UB comp lo hi t1 t2 =-  case (asBin t1, asBin t2) of-    (_, TipTree) -> t1-    -- Prune left tree.-    (_,   BinTree k _ r) | comp k lo <= EQ -> hedgeUnion_LB_UB comp lo hi t1 r-    -- Prune right tree.-    (_,   BinTree k l _) | comp k hi >= EQ -> hedgeUnion_LB_UB comp lo hi t1 l-    -- When t1 becomes empty (assumes lo <= k <= hi)-    (TipTree, BinTree x l r) ->-      case (filterGt (comp lo) l, filterLt (comp hi) r) of-        -- No variables in t2 were eliminated.-        (NothingS, NothingS) -> t2-        -- Relink t2 with filtered elements removed.-        (l',r') -> link x (fromMaybeS l l') (fromMaybeS r r')-    -- Special case when t2 is a single element.-    (_, BinTree x (asBin -> TipTree) (asBin -> TipTree)) -> insertR comp x t1-    -- Split on left-and-right subtrees of t1.-    (BinTree x l r, _) ->-      link x-           (hedgeUnion_LB_UB comp lo x  l t2)-           (hedgeUnion_LB_UB comp x  hi r t2)-{-# INLINABLE hedgeUnion_LB_UB #-}
− submodules/parameterized-utils/src/Data/Parameterized/Utils/Endian.hs
@@ -1,3 +0,0 @@-module Data.Parameterized.Utils.Endian where--data Endian = LittleEndian | BigEndian deriving (Eq,Show,Ord)
− submodules/parameterized-utils/src/Data/Parameterized/Vector.hs
@@ -1,507 +0,0 @@-{-# Language GADTs, DataKinds, TypeOperators, BangPatterns #-}-{-# Language PatternGuards #-}-{-# Language TypeApplications, ScopedTypeVariables #-}-{-# Language Rank2Types, RoleAnnotations #-}-{-# Language CPP #-}-#if __GLASGOW_HASKELL__ >= 805-{-# Language NoStarIsType #-}-#endif--- | A vector fixed-size vector of typed elements.-module Data.Parameterized.Vector-  ( Vector-    -- * Lists-  , fromList-  , toList--    -- * Length-  , length-  , nonEmpty-  , lengthInt--  -- * Indexing-  , elemAt-  , elemAtMaybe-  , elemAtUnsafe--  -- * Update-  , insertAt-  , insertAtMaybe--    -- * Sub sequences-  , uncons-  , slice-  , Data.Parameterized.Vector.take--    -- * Zipping-  , zipWith-  , zipWithM-  , zipWithM_-  , interleave--    -- * Reorder-  , shuffle-  , reverse-  , rotateL-  , rotateR-  , shiftL-  , shiftR--    -- * Construction-  , singleton-  , cons-  , snoc-  , generate-  , generateM--    -- * Splitting and joining-    -- ** General-  , joinWithM-  , joinWith-  , splitWith-  , splitWithA--    -- ** Vectors-  , split-  , join-  , append--  ) where--import qualified Data.Vector as Vector-import Data.Functor.Compose-import Data.Coerce-import Data.Vector.Mutable (MVector)-import qualified Data.Vector.Mutable as MVector-import Control.Monad.ST-import Data.Functor.Identity-import Data.Parameterized.NatRepr-import Data.Proxy-import Prelude hiding (length,reverse,zipWith)-import Numeric.Natural--import Data.Parameterized.Utils.Endian---- | Fixed-size non-empty vectors.-data Vector n a where-  Vector :: (1 <= n) => !(Vector.Vector a) -> Vector n a--type role Vector nominal representational--instance Eq a => Eq (Vector n a) where-  (Vector x) == (Vector y) = x == y--instance Show a => Show (Vector n a) where-  show (Vector x) = show x---- | Get the elements of the vector as a list, lowest index first.-toList :: Vector n a -> [a]-toList (Vector v) = Vector.toList v-{-# Inline toList #-}---- | Length of the vector.--- @O(1)@-length :: Vector n a -> NatRepr n-length (Vector xs) =-  activateNatReprCoercionBackdoor_IPromiseIKnowWhatIAmDoing $ \mk ->-    mk (fromIntegral (Vector.length xs) :: Natural)-{-# INLINE length #-}---- | The length of the vector as an "Int".-lengthInt :: Vector n a -> Int-lengthInt (Vector xs) = Vector.length xs-{-# Inline lengthInt #-}--elemAt :: ((i+1) <= n) => NatRepr i -> Vector n a -> a-elemAt n (Vector xs) = xs Vector.! widthVal n---- | Get the element at the given index.--- @O(1)@-elemAtMaybe :: Int -> Vector n a -> Maybe a-elemAtMaybe n (Vector xs) = xs Vector.!? n-{-# INLINE elemAt #-}---- | Get the element at the given index.--- Raises an exception if the element is not in the vector's domain.--- @O(1)@-elemAtUnsafe :: Int -> Vector n a -> a-elemAtUnsafe n (Vector xs) = xs Vector.! n-{-# INLINE elemAtUnsafe #-}----- | Insert an element at the given index.--- @O(n)@.-insertAt :: ((i + 1) <= n) => NatRepr i -> a -> Vector n a -> Vector n a-insertAt n a (Vector xs) = Vector (Vector.unsafeUpd xs [(widthVal n,a)])---- | Insert an element at the given index.--- Return 'Nothing' if the element is outside the vector bounds.--- @O(n)@.-insertAtMaybe :: Int -> a -> Vector n a -> Maybe (Vector n a)-insertAtMaybe n a (Vector xs)-  | 0 <= n && n < Vector.length xs = Just (Vector (Vector.unsafeUpd xs [(n,a)]))-  | otherwise = Nothing----- | Proof that the length of this vector is not 0.-nonEmpty :: Vector n a -> LeqProof 1 n-nonEmpty (Vector _) = LeqProof-{-# Inline nonEmpty #-}----- | Remove the first element of the vector, and return the rest, if any.-uncons :: forall n a.  Vector n a -> (a, Either (n :~: 1) (Vector (n-1) a))-uncons v@(Vector xs) = (Vector.head xs, mbTail)-  where-  mbTail :: Either (n :~: 1) (Vector (n - 1) a)-  mbTail = case testStrictLeq (knownNat @1) (length v) of-             Left n2_leq_n ->-               do LeqProof <- return (leqSub2 n2_leq_n (leqRefl (knownNat @1)))-                  return (Vector (Vector.tail xs))-             Right Refl    -> Left Refl-{-# Inline uncons #-}--------------------------------------------------------------------------------------- | Make a vector of the given length and element type.--- Returns "Nothing" if the input list does not have the right number of--- elements.--- @O(n)@.-fromList :: (1 <= n) => NatRepr n -> [a] -> Maybe (Vector n a)-fromList n xs-  | widthVal n == Vector.length v = Just (Vector v)-  | otherwise                     = Nothing-  where-  v = Vector.fromList xs-{-# INLINE fromList #-}----- | Extract a subvector of the given vector.-slice :: (i + w <= n, 1 <= w) =>-            NatRepr i {- ^ Start index -} ->-            NatRepr w {- ^ Width of sub-vector -} ->-            Vector n a -> Vector w a-slice i w (Vector xs) = Vector (Vector.slice (widthVal i) (widthVal w) xs)-{-# INLINE slice #-}---- | Take the front (lower-indexes) part of the vector.-take :: forall n x a. (1 <= n) => NatRepr n -> Vector (n + x) a -> Vector n a-take | LeqProof <- prf = slice (knownNat @0)-  where-  prf = leqAdd (leqRefl (Proxy @n)) (Proxy @x)------------------------------------------------------------------------------------instance Functor (Vector n) where-  fmap f (Vector xs) = Vector (Vector.map f xs)-  {-# Inline fmap #-}--instance Foldable (Vector n) where-  foldMap f (Vector xs) = foldMap f xs--instance Traversable (Vector n) where-  traverse f (Vector xs) = Vector <$> traverse f xs-  {-# Inline traverse #-}---- | Zip two vectors, potentially changing types.--- @O(n)@-zipWith :: (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c-zipWith f (Vector xs) (Vector ys) = Vector (Vector.zipWith f xs ys)-{-# Inline zipWith #-}--zipWithM :: Monad m => (a -> b -> m c) ->-                       Vector n a -> Vector n b -> m (Vector n c)-zipWithM f (Vector xs) (Vector ys) = Vector <$> Vector.zipWithM f xs ys-{-# Inline zipWithM #-}--zipWithM_ :: Monad m => (a -> b -> m ()) -> Vector n a -> Vector n b -> m ()-zipWithM_ f (Vector xs) (Vector ys) = Vector.zipWithM_ f xs ys-{-# Inline zipWithM_ #-}--{- | Interleave two vectors.  The elements of the first vector are-at even indexes in the result, the elements of the second are at odd indexes. -}-interleave ::-  forall n a. (1 <= n) => Vector n a -> Vector n a -> Vector (2 * n) a-interleave (Vector xs) (Vector ys)-  | LeqProof <- leqMulPos (Proxy @2) (Proxy @n) = Vector zs-  where-  len = Vector.length xs + Vector.length ys-  zs  = Vector.generate len (\i -> let v = if even i then xs else ys-                                   in v Vector.! (i `div` 2))-------------------------------------------------------------------------------------{- | Move the elements around, as specified by the given function.-  * Note: the reindexing function says where each of the elements-          in the new vector come from.-  * Note: it is OK for the same input element to end up in mulitple places-          in the result.-@O(n)@--}-shuffle :: (Int -> Int) -> Vector n a -> Vector n a-shuffle f (Vector xs) = Vector ys-  where-  ys = Vector.generate (Vector.length xs) (\i -> xs Vector.! f i)-{-# Inline shuffle #-}---- | Reverse the vector.-reverse :: forall a n. (1 <= n) => Vector n a -> Vector n a-reverse x = shuffle (\i -> lengthInt x - i - 1) x---- | Rotate "left".  The first element of the vector is on the "left", so--- rotate left moves all elemnts toward the corresponding smaller index.--- Elements that fall off the beginning end up at the end.-rotateL :: Int -> Vector n a -> Vector n a-rotateL !n xs = shuffle rotL xs-  where-  !len   = lengthInt xs-  rotL i = (i + n) `mod` len          -- `len` is known to be >= 1-{-# Inline rotateL #-}---- | Rotate "right".  The first element of the vector is on the "left", so--- rotate right moves all elemnts toward the corresponding larger index.--- Elements that fall off the end, end up at the beginning.-rotateR :: Int -> Vector n a -> Vector n a-rotateR !n xs = shuffle rotR xs-  where-  !len   = lengthInt xs-  rotR i = (i - n) `mod` len        -- `len` is known to be >= 1-{-# Inline rotateR #-}--{- | Move all elements towards smaller indexes.-Elements that fall off the front are ignored.-Empty slots are filled in with the given element.-@O(n)@. -}-shiftL :: Int -> a -> Vector n a -> Vector n a-shiftL !x a (Vector xs) = Vector ys-  where-  !len = Vector.length xs-  ys   = Vector.generate len (\i -> let j = i + x-                                    in if j >= len then a else xs Vector.! j)-{-# Inline shiftL #-}--{- | Move all elements towards the larger indexes.-Elements that "fall" off the end are ignored.-Empty slots are filled in with the given element.-@O(n)@. -}-shiftR :: Int -> a -> Vector n a -> Vector n a-shiftR !x a (Vector xs) = Vector ys-  where-  !len = Vector.length xs-  ys   = Vector.generate len (\i -> let j = i - x-                                    in if j < 0 then a else xs Vector.! j)-{-# Inline shiftR #-}---------------------------------------------------------------------------------i---- | Append two vectors. The first one is at lower indexes in the result.-append :: Vector m a -> Vector n a -> Vector (m + n) a-append v1@(Vector xs) v2@(Vector ys) =-  case leqAddPos (length v1) (length v2) of { LeqProof ->-    Vector (xs Vector.++ ys)-  }-{-# Inline append #-}------------------------------------------------------------------------------------- Constructing Vectors---- | Vector with exactly one element-singleton :: forall a. a -> Vector 1 a-singleton a = Vector (Vector.singleton a)--leqLen :: forall n a. Vector n a -> LeqProof 1 (n + 1)-leqLen v =-  let leqSucc :: forall f z. f z -> LeqProof z (z + 1)-      leqSucc fz = leqAdd (leqRefl fz :: LeqProof z z) (knownNat @1)-  in leqTrans (nonEmpty v :: LeqProof 1 n) (leqSucc (length v))---- | Add an element to the head of a vector-cons :: forall n a. a -> Vector n a -> Vector (n+1) a-cons a v@(Vector x) = case leqLen v of LeqProof -> (Vector (Vector.cons a x))---- | Add an element to the tail of a vector-snoc :: forall n a. Vector n a -> a -> Vector (n+1) a-snoc v@(Vector x) a = case leqLen v of LeqProof -> (Vector (Vector.snoc x a))---- | This newtype wraps Vector so that we can curry it in the call to--- @natRecBounded@. It adds 1 to the length so that the base case is--- a @Vector@ of non-zero length.-newtype Vector' a n = MkVector' (Vector (n+1) a)--unVector' :: Vector' a n -> Vector (n+1) a-unVector' (MkVector' v) = v--snoc' :: forall a m. Vector' a m -> a -> Vector' a (m+1)-snoc' v = MkVector' . snoc (unVector' v)--generate' :: forall h a-           . NatRepr h-          -> (forall n. (n <= h) => NatRepr n -> a)-          -> Vector' a h-generate' h gen =-  case isZeroOrGT1 h of-    Left Refl -> base-    Right LeqProof ->-      case (minusPlusCancel h (knownNat @1) :: h - 1 + 1 :~: h) of { Refl ->-      natRecBounded (decNat h) (decNat h) base step-      }-  where base :: Vector' a 0-        base = MkVector' $ singleton (gen (knownNat @0))-        step :: forall m. (1 <= h, m <= h - 1)-             => NatRepr m -> Vector' a m -> Vector' a (m + 1)-        step m v =-          case minusPlusCancel h (knownNat @1) :: h - 1 + 1 :~: h of { Refl ->-          case (leqAdd2 (LeqProof :: LeqProof m (h-1))-                        (LeqProof :: LeqProof 1 1) :: LeqProof (m+1) h) of { LeqProof ->-            snoc' v (gen (incNat m))-          }}---- | Apply a function to each element in a range starting at zero;--- return the a vector of values obtained.--- cf. both @natFromZero@ and @Data.Vector.generate@-generate :: forall h a-          . NatRepr h-         -> (forall n. (n <= h) => NatRepr n -> a)-         -> Vector (h + 1) a-generate h gen = unVector' (generate' h gen)---- | Since @Vector@ is traversable, we can pretty trivially sequence--- @natFromZeroVec@ inside a monad.-generateM :: forall m h a. (Monad m)-          => NatRepr h-          -> (forall n. (n <= h) => NatRepr n -> m a)-          -> m (Vector (h + 1) a)-generateM h gen = sequence $ generate h gen------------------------------------------------------------------------------------coerceVec :: Coercible a b => Vector n a -> Vector n b-coerceVec = coerce---- | Monadically join a vector of values, using the given function.--- This functionality can sometimes be reproduced by creating a newtype--- wrapper and using @joinWith@, this implementation is provided for--- convenience.-joinWithM ::-  forall m f n w.-  (1 <= w, Monad m) =>-  (forall l. (1 <= l) => NatRepr l -> f w -> f l -> m (f (w + l)))-  {- ^ A function for appending contained elements.-       Earlier vector indexes are the first argument of the join function.-       Pass a different function to implmenet little/big endian behaviors -} ->-  NatRepr w -> Vector n (f w) -> m (f (n * w))--joinWithM jn w = fmap fst . go-  where-  go :: forall l. Vector l (f w) -> m (f (l * w), NatRepr (l * w))-  go exprs =-    case uncons exprs of-      (a, Left Refl) -> return (a, w)-      (a, Right rest) ->-        case nonEmpty rest                of { LeqProof ->-        case leqMulPos (length rest) w    of { LeqProof ->-        case nonEmpty exprs               of { LeqProof ->-        case lemmaMul w (length exprs)    of { Refl -> do-          -- @siddharthist: This could probably be written applicatively?-          (res, sz) <- go rest-          joined <- jn sz a res-          return (joined, addNat w sz)-        }}}}---- | Join a vector of values, using the given function.-joinWith ::-  forall f n w.-  (1 <= w) =>-  (forall l. (1 <= l) => NatRepr l -> f w -> f l -> f (w + l))-  {- ^ A function for appending contained elements.-       Earlier vector indexes are the first argument of the join function.-       Pass a different function to implmenet little/big endian behaviors -} ->-  NatRepr w -> Vector n (f w) -> f (n * w)-joinWith jn w v = runIdentity $ joinWithM (\n x -> pure . (jn n x)) w v-{-# Inline joinWith #-}---- | Split a bit-vector into a vector of bit-vectors.--- If "LittleEndian", then less significant bits go into smaller indexes.--- If "BigEndian", then less significant bits go into larger indexes.-splitWith :: forall f w n.-  (1 <= w, 1 <= n) =>-  Endian ->-  (forall i. (i + w <= n * w) =>-             NatRepr (n * w) -> NatRepr i -> f (n * w) -> f w)-  {- ^ A function for slicing out a chunk of length @w@, starting at @i@ -} ->-  NatRepr n -> NatRepr w -> f (n * w) -> Vector n (f w)-splitWith endian select n w val = Vector (Vector.create initializer)-  where-  len          = widthVal n-  start :: Int-  next :: Int -> Int-  (start,next) = case endian of-                   LittleEndian -> (0, succ)-                   BigEndian    -> (len - 1, pred)--  initializer :: forall s. ST s (MVector s (f w))-  initializer =-    do LeqProof <- return (leqMulPos n w)-       LeqProof <- return (leqMulMono n w)--       v <- MVector.new len-       let fill :: Int -> NatRepr i -> ST s ()-           fill loc i =-             let end = addNat i w in-             case testLeq end inLen of-               Just LeqProof ->-                 do MVector.write v loc (select inLen i val)-                    fill (next loc) end-               Nothing -> return ()---       fill start (knownNat @0)-       return v--  inLen :: NatRepr (n * w)-  inLen = natMultiply n w-{-# Inline splitWith #-}---- We can sneakily put our functor in the parameter "f" of @splitWith@ using the--- @Compose@ newtype.--- | An applicative version of @splitWith@.-splitWithA :: forall f g w n. (Applicative f, 1 <= w, 1 <= n) =>-  Endian ->-  (forall i. (i + w <= n * w) =>-             NatRepr (n * w) -> NatRepr i -> g (n * w) -> f (g w))-  {- ^ f function for slicing out f chunk of length @w@, starting at @i@ -} ->-  NatRepr n -> NatRepr w -> g (n * w) -> f (Vector n (g w))-splitWithA e select n w val = traverse getCompose $-  splitWith @(Compose f g) e select' n w $ Compose (pure val)-  where -- Wrap everything in Compose-        select' :: (forall i. (i + w <= n * w)-                => NatRepr (n * w) -> NatRepr i -> Compose f g (n * w) -> Compose f g w)-        -- Whatever we pass in as "val" is what's passed to select anyway,-        -- so there's no need to examine the argument. Just use "val" directly here.-        select' nw i _ = Compose $ select nw i val--newtype Vec a n = Vec (Vector n a)--vSlice :: (i + w <= l, 1 <= w) =>-  NatRepr w -> NatRepr l -> NatRepr i -> Vec a l -> Vec a w-vSlice w _ i (Vec xs) = Vec (slice i w xs)-{-# Inline vSlice #-}---- | Append the two bit vectors.  The first argument is--- at the lower indexes of the resulting vector.-vAppend :: NatRepr n -> Vec a m -> Vec a n -> Vec a (m + n)-vAppend _ (Vec xs) (Vec ys) = Vec (append xs ys)-{-# Inline vAppend #-}---- | Split a vector into a vector of vectors.-split :: (1 <= w, 1 <= n) =>-        NatRepr n -> NatRepr w -> Vector (n * w) a -> Vector n (Vector w a)-split n w xs = coerceVec (splitWith LittleEndian (vSlice w) n w (Vec xs))-{-# Inline split #-}---- | Join a vector of vectors into a single vector.-join :: (1 <= w) => NatRepr w -> Vector n (Vector w a) -> Vector (n * w) a-join w xs = ys-  where Vec ys = joinWith vAppend w (coerceVec xs)-{-# Inline join #-}
− submodules/parameterized-utils/test/Test/Context.hs
@@ -1,178 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE PolyKinds #-}-module Test.Context-( contextTests-) where--import Test.Tasty-import Test.QuickCheck-import Test.Tasty.QuickCheck--import Control.Lens-import Data.Parameterized.Classes-import Data.Parameterized.TraversableFC-import Data.Parameterized.Some--import qualified Data.Parameterized.Context as C-import qualified Data.Parameterized.Context.Safe as S-import qualified Data.Parameterized.Context.Unsafe as U--data Payload (ty :: *) where-  IntPayload    :: Int -> Payload Int-  StringPayload :: String -> Payload String-  BoolPayload   :: Bool -> Payload Bool--instance TestEquality Payload where-  testEquality (IntPayload x) (IntPayload y) = if x == y then Just Refl else Nothing-  testEquality (StringPayload x) (StringPayload y) = if x == y then Just Refl else Nothing-  testEquality (BoolPayload x) (BoolPayload y) = if x == y then Just Refl else Nothing-  testEquality _ _ = Nothing--instance Show (Payload tp) where-  show (IntPayload x) = show x-  show (StringPayload x) = show x-  show (BoolPayload x) = show x--instance ShowF Payload--instance Arbitrary (Some Payload) where-  arbitrary = oneof-    [ Some . IntPayload <$> arbitrary-    , Some . StringPayload <$> arbitrary-    , Some . BoolPayload <$> arbitrary-    ]--type UAsgn = U.Assignment Payload-type SAsgn = S.Assignment Payload--mkUAsgn :: [Some Payload] -> Some UAsgn-mkUAsgn = go U.empty- where go :: UAsgn ctx -> [Some Payload] -> Some UAsgn-       go a [] = Some a-       go a (Some x : xs) = go (U.extend a x) xs--mkSAsgn :: [Some Payload] -> Some SAsgn-mkSAsgn = go S.empty- where go :: SAsgn ctx -> [Some Payload] -> Some SAsgn-       go a [] = Some a-       go a (Some x : xs) = go (S.extend a x) xs--instance Arbitrary (Some UAsgn) where-  arbitrary = mkUAsgn <$> arbitrary-instance Arbitrary (Some SAsgn) where-  arbitrary = mkSAsgn <$> arbitrary--twiddle :: Payload a -> Payload a-twiddle (IntPayload n) = IntPayload (n+1)-twiddle (StringPayload str) = StringPayload (str++"asdf")-twiddle (BoolPayload b) = BoolPayload (not b)--contextTests :: IO TestTree-contextTests = testGroup "Context" <$> return-   [ testProperty "safe_index_eq" $ \v vs i -> ioProperty $ do-         let vals = v:vs-         let i' = min (max 0 i) (length vals - 1)-         Some a <- return $ mkSAsgn vals-         Just (Some idx) <- return $ S.intIndex i' (S.size a)-         return (Some (a S.! idx) == vals !! i')-   , testProperty "unsafe_index_eq" $ \v vs i -> ioProperty $ do-         let vals = v:vs-         let i' = min (max 0 i) (length vals - 1)-         Some a <- return $ mkUAsgn vals-         Just (Some idx) <- return $ U.intIndex i' (U.size a)-         return (Some (a U.! idx) == vals !! i')-   , testProperty "safe_tolist" $ \vals -> ioProperty $ do-         Some a <- return $ mkSAsgn vals-         let vals' = toListFC Some a-         return (vals == vals')-   , testProperty "unsafe_tolist" $ \vals -> ioProperty $ do-         Some a <- return $ mkUAsgn vals-         let vals' = toListFC Some a-         return (vals == vals')-   , testProperty "adjust test monadic" $ \v vs i -> ioProperty $ do-         let vals = v:vs  -- ensures vals is not an empty array-         Some x <- return $ mkUAsgn vals-         Some y <- return $ mkSAsgn vals-         let i' = min (max 0 i) (length vals - 1)--         Just (Some idx_x) <- return $ U.intIndex i' (U.size x)-         Just (Some idx_y) <- return $ S.intIndex i' (S.size y)--         x' <- U.adjustM (return . twiddle) idx_x x-         y' <- S.adjustM (return . twiddle) idx_y y--         return (toListFC Some x' == toListFC Some y')--   , testProperty "adjust test" $ \v vs i -> ioProperty $ do-         let vals = v:vs  -- ensures vals is not an empty array-         Some x <- return $ mkUAsgn vals-         Some y <- return $ mkSAsgn vals-         let i' = min (max 0 i) (length vals - 1)--         Just (Some idx_x) <- return $ U.intIndex i' (U.size x)-         Just (Some idx_y) <- return $ S.intIndex i' (S.size y)--         let x' = over (ixF idx_x) twiddle x-             y' = (ixF idx_y) %~ twiddle $ y-             x'' = U.adjust twiddle idx_x x-             y'' = S.adjust twiddle idx_y y--         return (toListFC Some x' == toListFC Some y' &&-                 -- adjust actually modified the entry-                 toListFC Some x /= toListFC Some x' &&-                 toListFC Some y /= toListFC Some y' &&-                 -- verify new version is equivalent to older deprecated version-                 toListFC Some x'' == toListFC Some x' &&-                 toListFC Some y'' == toListFC Some y')--   , testProperty "update test" $ \v vs i -> ioProperty $ do-         let vals = v:vs  -- ensures vals is not an empty array-         Some x <- return $ mkUAsgn vals-         Some y <- return $ mkSAsgn vals-         let i' = min (max 0 i) (length vals - 1)--         Just (Some idx_x) <- return $ U.intIndex i' (U.size x)-         Just (Some idx_y) <- return $ S.intIndex i' (S.size y)--         let x' = over (ixF idx_x) twiddle x-             y' = (ixF idx_y) %~ twiddle $ y-             updX = set (ixF idx_x) (x' U.! idx_x) x-             updY = (ixF idx_y) .~  (y' S.! idx_y) $ y-             updX' = U.update idx_x (x' U.! idx_x) x-             updY' = S.update idx_y (y' S.! idx_y) y--         return (toListFC Some updX == toListFC Some updY &&-                 -- update actually modified the entry-                 toListFC Some x /= toListFC Some updX &&-                 toListFC Some y /= toListFC Some updY &&-                 -- update modified the expected entry-                 toListFC Some x' == toListFC Some updX &&-                 toListFC Some y' == toListFC Some updY &&-                 -- verify new version is equivalent to older deprecated version-                 toListFC Some updX == toListFC Some updX' &&-                 toListFC Some updY == toListFC Some updY'-                )--   , testProperty "safe_eq" $ \vals1 vals2 -> ioProperty $ do-         Some x <- return $ mkSAsgn vals1-         Some y <- return $ mkSAsgn vals2-         case testEquality x y of-           Just Refl -> return $ vals1 == vals2-           Nothing   -> return $ vals1 /= vals2-   , testProperty "unsafe_eq" $ \vals1 vals2 -> ioProperty $ do-         Some x <- return $ mkUAsgn vals1-         Some y <- return $ mkUAsgn vals2-         case testEquality x y of-           Just Refl -> return $ vals1 == vals2-           Nothing   -> return $ vals1 /= vals2--   , testProperty "append_take" $ \vals1 vals2 -> ioProperty $ do-         Some x <- return $ mkUAsgn vals1-         Some y <- return $ mkUAsgn vals2-         let z = x U.<++> y-         let x' = C.take (U.size x) (U.size y) z-         return $ isJust $ testEquality x x'-   ]
− submodules/parameterized-utils/test/Test/NatRepr.hs
@@ -1,18 +0,0 @@-module Test.NatRepr-( natTests-) where--import Test.Tasty-import Test.Tasty.QuickCheck--import Data.Parameterized.NatRepr-import Data.Parameterized.Some-import GHC.TypeLits--natTests :: IO TestTree-natTests = testGroup "Nat" <$> return-  [ testProperty "withKnownNat" $ \nInt ->-      case someNat nInt of-        Nothing -> nInt < 0-        Just (Some r) -> nInt == withKnownNat r (natVal r)-  ]
− submodules/parameterized-utils/test/Test/Vector.hs
@@ -1,67 +0,0 @@-{-# Language DataKinds #-}-{-# Language ExplicitForAll #-}-{-# Language TypeOperators #-}-{-# Language TypeFamilies #-}-{-# Language FlexibleInstances #-}-{-# Language ScopedTypeVariables #-}-{-# Language StandaloneDeriving #-}-{-# Language CPP #-}-#if __GLASGOW_HASKELL__ >= 805-{-# Language NoStarIsType #-}-#endif-module Test.Vector-( vecTests-) where--import Test.Tasty-import Test.Tasty.QuickCheck (Arbitrary(..), Gen, testProperty)--import Data.Parameterized.NatRepr-import Data.Parameterized.Vector-import GHC.TypeLits-import Prelude hiding (reverse)--instance KnownNat n => Arbitrary (NatRepr n) where-  arbitrary = return knownNat---- GHC thinks that this instances overlaps with the--- "Arbitrary a => Arbitrary (Maybe a)" instance from QuickCheck, but it doesn't:--- there is no "Arbitrary a => Arbitrary (Vector n a)".------ While it might seem like this would just successfully generate a lot--- of "Nothing", it does a pretty good job. Just try changing one of the tests!-instance {-# OVERLAPS #-} forall a n. (1 <= n, Arbitrary a, KnownNat n)-    => Arbitrary (Maybe (Vector n a)) where-  arbitrary = do-    n <- (arbitrary :: Gen (NatRepr n))-    l <- (arbitrary :: Gen [a])-    return $ fromList n l--instance Show (Int -> Ordering) where-  show _ = "unshowable"---- We use @Ordering@ just because it's simple-vecTests :: IO TestTree-vecTests = testGroup "Vector" <$> return-  [ testProperty "reverse100" $-      \n v -> fromList (n :: NatRepr 100) (v :: [Ordering]) ==-              (reverse <$> (reverse <$> (fromList n v)))-  , testProperty "reverseSingleton" $-      \n v -> fromList (n :: NatRepr 1) (v :: [Ordering]) ==-              (reverse <$> (fromList n v))-  , testProperty "split-join" $-      \n w v -> (v :: Maybe (Vector (5 * 5) Ordering)) ==-                (join (n :: NatRepr 5) . split n (w :: NatRepr 5) <$> v)-  -- @cons@ is the same for vectors or lists-  , testProperty "cons" $-      \n v x -> (cons x <$> fromList (n :: NatRepr 20) (v :: [Ordering])) ==-                (fromList (incNat n) (x:v))-  -- @snoc@ is like appending to a list-  , testProperty "snoc" $-      \n v x -> (flip snoc x <$> fromList (n :: NatRepr 20) (v :: [Ordering])) ==-                (fromList (incNat n) (v ++ [x]))-  -- @generate@ is like mapping a function over indices-  , testProperty "generate" $-      \n f -> Just (generate (n :: NatRepr 55) ((f :: Int -> Ordering) . widthVal)) ==-              (fromList (incNat n) (map f [0..widthVal n]) :: Maybe (Vector 56 Ordering))-  ]
− submodules/parameterized-utils/test/UnitTest.hs
@@ -1,24 +0,0 @@-import Test.Tasty-import Test.Tasty.Ingredients-import Test.Tasty.Runners.AntXML--import qualified Test.Context-import qualified Test.NatRepr-import qualified Test.Vector--main :: IO ()-main = tests >>= defaultMainWithIngredients ingrs--ingrs :: [Ingredient]-ingrs =-   [ antXMLRunner-   ]-   ++-   defaultIngredients--tests :: IO TestTree-tests = testGroup "ParameterizedUtils" <$> sequence-  [ Test.Context.contextTests-  , Test.NatRepr.natTests-  , Test.Vector.vecTests-  ]