grisette-0.4.0.0: src/Grisette/IR/SymPrim/Data/Prim/PartialEval/BV.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
-- Module : Grisette.IR.SymPrim.Data.Prim.PartialEval.BV
-- Copyright : (c) Sirui Lu 2021-2023
-- License : BSD-3-Clause (see the LICENSE file)
--
-- Maintainer : siruilu@cs.washington.edu
-- Stability : Experimental
-- Portability : GHC only
module Grisette.IR.SymPrim.Data.Prim.PartialEval.BV
( pevalToSignedTerm,
pevalToUnsignedTerm,
pevalBVConcatTerm,
pevalBVSelectTerm,
pevalBVExtendTerm,
pevalBVZeroExtendTerm,
pevalBVSignExtendTerm,
)
where
import Data.Typeable (Typeable)
import GHC.TypeNats (KnownNat, type (+), type (<=))
import Grisette.Core.Data.Class.BitVector
( SizedBV (sizedBVConcat, sizedBVSelect, sizedBVSext, sizedBVZext),
)
import Grisette.Core.Data.Class.SignConversion (SignConversion (toSigned, toUnsigned))
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.InternedCtors
( bvconcatTerm,
bvextendTerm,
bvselectTerm,
conTerm,
toSignedTerm,
toUnsignedTerm,
)
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.Term
( SupportedPrim,
Term (ConTerm, ToSignedTerm, ToUnsignedTerm),
)
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.TermUtils
( castTerm,
)
import Grisette.IR.SymPrim.Data.Prim.PartialEval.Unfold
( binaryUnfoldOnce,
unaryUnfoldOnce,
)
-- ToSigned
pevalToSignedTerm ::
( SupportedPrim u,
SupportedPrim s,
SignConversion u s
) =>
Term u ->
Term s
pevalToSignedTerm = unaryUnfoldOnce doPevalToSignedTerm toSignedTerm
doPevalToSignedTerm ::
( SupportedPrim u,
SupportedPrim s,
SignConversion u s
) =>
Term u ->
Maybe (Term s)
doPevalToSignedTerm (ConTerm _ b) = Just $ conTerm $ toSigned b
doPevalToSignedTerm (ToUnsignedTerm _ b) = Just b >>= castTerm
doPevalToSignedTerm _ = Nothing
-- ToUnsigned
pevalToUnsignedTerm ::
( SupportedPrim u,
SupportedPrim s,
SignConversion u s
) =>
Term s ->
Term u
pevalToUnsignedTerm = unaryUnfoldOnce doPevalToUnsignedTerm toUnsignedTerm
doPevalToUnsignedTerm ::
( SupportedPrim u,
SupportedPrim s,
SignConversion u s
) =>
Term s ->
Maybe (Term u)
doPevalToUnsignedTerm (ConTerm _ b) = Just $ conTerm $ toUnsigned b
doPevalToUnsignedTerm (ToSignedTerm _ b) = Just b >>= castTerm
doPevalToUnsignedTerm _ = Nothing
-- select
pevalBVSelectTerm ::
forall bv n ix w p q.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat n,
KnownNat ix,
KnownNat w,
1 <= n,
1 <= w,
ix + w <= n,
SizedBV bv
) =>
p ix ->
q w ->
Term (bv n) ->
Term (bv w)
pevalBVSelectTerm ix w = unaryUnfoldOnce (doPevalBVSelectTerm ix w) (bvselectTerm ix w)
doPevalBVSelectTerm ::
forall bv n ix w p q.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat n,
KnownNat ix,
KnownNat w,
1 <= n,
1 <= w,
ix + w <= n,
SizedBV bv
) =>
p ix ->
q w ->
Term (bv n) ->
Maybe (Term (bv w))
doPevalBVSelectTerm ix w (ConTerm _ b) = Just $ conTerm $ sizedBVSelect ix w b
doPevalBVSelectTerm _ _ _ = Nothing
-- ext
pevalBVZeroExtendTerm ::
forall proxy l r bv.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat l,
KnownNat r,
1 <= l,
1 <= r,
l <= r,
SizedBV bv
) =>
proxy r ->
Term (bv l) ->
Term (bv r)
pevalBVZeroExtendTerm = pevalBVExtendTerm False
pevalBVSignExtendTerm ::
forall proxy l r bv.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat l,
KnownNat r,
1 <= l,
1 <= r,
l <= r,
SizedBV bv
) =>
proxy r ->
Term (bv l) ->
Term (bv r)
pevalBVSignExtendTerm = pevalBVExtendTerm True
pevalBVExtendTerm ::
forall proxy l r bv.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat l,
KnownNat r,
1 <= l,
1 <= r,
l <= r,
SizedBV bv
) =>
Bool ->
proxy r ->
Term (bv l) ->
Term (bv r)
pevalBVExtendTerm signed p = unaryUnfoldOnce (doPevalBVExtendTerm signed p) (bvextendTerm signed p)
doPevalBVExtendTerm ::
forall proxy l r bv.
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat l,
KnownNat r,
1 <= l,
1 <= r,
l <= r,
SizedBV bv
) =>
Bool ->
proxy r ->
Term (bv l) ->
Maybe (Term (bv r))
doPevalBVExtendTerm signed p (ConTerm _ b) = Just $ conTerm $ if signed then sizedBVSext p b else sizedBVZext p b
doPevalBVExtendTerm _ _ _ = Nothing
pevalBVConcatTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat a,
KnownNat b,
KnownNat (a + b),
1 <= a,
1 <= b,
1 <= a + b,
SizedBV bv
) =>
Term (bv a) ->
Term (bv b) ->
Term (bv (a + b))
pevalBVConcatTerm = binaryUnfoldOnce doPevalBVConcatTerm bvconcatTerm
doPevalBVConcatTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
Typeable bv,
KnownNat a,
KnownNat b,
KnownNat (a + b),
1 <= a,
1 <= b,
1 <= (a + b),
SizedBV bv
) =>
Term (bv a) ->
Term (bv b) ->
Maybe (Term (bv (a + b)))
doPevalBVConcatTerm (ConTerm _ v) (ConTerm _ v') = Just $ conTerm $ sizedBVConcat v v'
doPevalBVConcatTerm _ _ = Nothing