grisette-0.3.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
( pevalBVToSignedTerm,
pevalBVToUnsignedTerm,
pevalBVConcatTerm,
pevalBVSelectTerm,
pevalBVExtendTerm,
pevalBVZeroExtendTerm,
pevalBVSignExtendTerm,
)
where
import Data.Typeable
import GHC.TypeNats
import Grisette.Core.Data.Class.BitVector
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.InternedCtors
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.Term
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.TermUtils
import Grisette.IR.SymPrim.Data.Prim.PartialEval.Unfold
-- ToSigned
pevalBVToSignedTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (ubv n),
forall n. (KnownNat n, 1 <= n) => SupportedPrim (sbv n),
Typeable ubv,
Typeable sbv,
KnownNat n,
1 <= n,
BVSignConversion (ubv n) (sbv n)
) =>
Term (ubv n) ->
Term (sbv n)
pevalBVToSignedTerm = unaryUnfoldOnce doPevalBVToSignedTerm bvToSignedTerm
doPevalBVToSignedTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (ubv n),
forall n. (KnownNat n, 1 <= n) => SupportedPrim (sbv n),
Typeable ubv,
Typeable sbv,
KnownNat n,
1 <= n,
BVSignConversion (ubv n) (sbv n)
) =>
Term (ubv n) ->
Maybe (Term (sbv n))
doPevalBVToSignedTerm (ConTerm _ b) = Just $ conTerm $ toSigned b
doPevalBVToSignedTerm (BVToUnsignedTerm _ b) = Just b >>= castTerm
doPevalBVToSignedTerm _ = Nothing
-- ToUnsigned
{-
bvToUnsignedTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (sbv n),
forall n. (KnownNat n, 1 <= n) => SupportedPrim (ubv n),
Typeable sbv,
Typeable ubv,
KnownNat n,
1 <= n,
BVToUnsigned (sbv n) (ubv n)
) =>
Term (sbv n) ->
Term (ubv n)
bvToUnsignedTerm = internTerm . UBVToUnsignedTerm
-}
pevalBVToUnsignedTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (ubv n),
forall n. (KnownNat n, 1 <= n) => SupportedPrim (sbv n),
Typeable ubv,
Typeable sbv,
KnownNat n,
1 <= n,
BVSignConversion (ubv n) (sbv n)
) =>
Term (sbv n) ->
Term (ubv n)
pevalBVToUnsignedTerm = unaryUnfoldOnce doPevalBVToUnsignedTerm bvToUnsignedTerm
doPevalBVToUnsignedTerm ::
( forall n. (KnownNat n, 1 <= n) => SupportedPrim (ubv n),
forall n. (KnownNat n, 1 <= n) => SupportedPrim (sbv n),
Typeable ubv,
Typeable sbv,
KnownNat n,
1 <= n,
BVSignConversion (ubv n) (sbv n)
) =>
Term (sbv n) ->
Maybe (Term (ubv n))
doPevalBVToUnsignedTerm (ConTerm _ b) = Just $ conTerm $ toUnsigned b
doPevalBVToUnsignedTerm (BVToSignedTerm _ b) = Just b >>= castTerm
doPevalBVToUnsignedTerm _ = 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