{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

-- |
-- Module      :   Grisette.Internal.SymPrim.Prim.Internal.Term
-- Copyright   :   (c) Sirui Lu 2021-2024
-- License     :   BSD-3-Clause (see the LICENSE file)
--
-- Maintainer  :   siruilu@cs.washington.edu
-- Stability   :   Experimental
-- Portability :   GHC only
module Grisette.Internal.SymPrim.Prim.Internal.Term
  ( -- * Supported primitive types
    SupportedPrimConstraint (..),
    SupportedPrim (..),
    SymRep (..),
    ConRep (..),
    LinkedRep (..),

    -- * Partial evaluation for the terms
    UnaryOp (..),
    BinaryOp (..),
    TernaryOp (..),
    PEvalApplyTerm (..),
    PEvalBitwiseTerm (..),
    PEvalShiftTerm (..),
    PEvalRotateTerm (..),
    PEvalNumTerm (..),
    pevalSubNumTerm,
    PEvalOrdTerm (..),
    pevalGtOrdTerm,
    pevalGeOrdTerm,
    pevalNEqTerm,
    PEvalDivModIntegralTerm (..),
    PEvalBVSignConversionTerm (..),
    PEvalBVTerm (..),

    -- * Typed symbols
    TypedSymbol (..),
    SomeTypedSymbol (..),
    showUntyped,
    withSymbolSupported,
    someTypedSymbol,

    -- * Terms
    Term (..),
    identity,
    identityWithTypeRep,
    introSupportedPrimConstraint,
    pformat,

    -- * Interning
    UTerm (..),
    prettyPrintTerm,
    constructUnary,
    constructBinary,
    constructTernary,
    conTerm,
    symTerm,
    ssymTerm,
    isymTerm,
    notTerm,
    orTerm,
    andTerm,
    eqTerm,
    iteTerm,
    addNumTerm,
    negNumTerm,
    mulNumTerm,
    absNumTerm,
    signumNumTerm,
    ltOrdTerm,
    leOrdTerm,
    andBitsTerm,
    orBitsTerm,
    xorBitsTerm,
    complementBitsTerm,
    shiftLeftTerm,
    shiftRightTerm,
    rotateLeftTerm,
    rotateRightTerm,
    toSignedTerm,
    toUnsignedTerm,
    bvconcatTerm,
    bvselectTerm,
    bvextendTerm,
    bvsignExtendTerm,
    bvzeroExtendTerm,
    applyTerm,
    divIntegralTerm,
    modIntegralTerm,
    quotIntegralTerm,
    remIntegralTerm,

    -- * Support for boolean type
    trueTerm,
    falseTerm,
    pattern BoolConTerm,
    pattern TrueTerm,
    pattern FalseTerm,
    pattern BoolTerm,
    pevalNotTerm,
    pevalOrTerm,
    pevalAndTerm,
    pevalImplyTerm,
    pevalXorTerm,
    pevalITEBasic,
    pevalITEBasicTerm,
    pevalDefaultEqTerm,
    --
    NonFuncSBVRep (..),
    SupportedNonFuncPrim (..),
    SBVRep (..),
    SBVFreshMonad (..),
    translateTypeError,
    parseSMTModelResultError,
    partitionCVArg,
  )
where

import Control.DeepSeq (NFData (rnf))
import Control.Monad (msum)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Reader (MonadTrans (lift), ReaderT)
import Control.Monad.State (StateT)
import Data.Array ((!))
import Data.Bits (Bits)
import Data.Function (on)
import qualified Data.HashMap.Strict as M
import Data.Hashable (Hashable (hash, hashWithSalt))
import Data.IORef (atomicModifyIORef')
import Data.Interned
  ( Cache,
    Id,
    Interned (Description, Uninterned, cache, cacheWidth, describe, identify),
  )
import Data.Interned.Internal
  ( Cache (getCache),
    CacheState (CacheState),
  )
import Data.Kind (Constraint)
import Data.Maybe (fromMaybe)
import qualified Data.SBV as SBV
import qualified Data.SBV.Dynamic as SBVD
import qualified Data.SBV.Trans as SBVT
import qualified Data.SBV.Trans.Control as SBVTC
import Data.String (IsString (fromString))
import Data.Typeable (Proxy (Proxy), cast)
import GHC.Exts (sortWith)
import GHC.IO (unsafeDupablePerformIO)
import GHC.Stack (HasCallStack)
import GHC.TypeNats (KnownNat, Nat, type (+), type (<=))
import Grisette.Internal.Core.Data.Class.BitVector
  ( SizedBV,
  )
import Grisette.Internal.Core.Data.Class.SignConversion (SignConversion)
import Grisette.Internal.Core.Data.Class.SymRotate (SymRotate)
import Grisette.Internal.Core.Data.Class.SymShift (SymShift)
import Grisette.Internal.Core.Data.Symbol
  ( Identifier,
    Symbol (IndexedSymbol, SimpleSymbol),
  )
import Grisette.Internal.SymPrim.Prim.Internal.Caches
  ( typeMemoizedCache,
  )
import Grisette.Internal.SymPrim.Prim.Internal.IsZero (KnownIsZero)
import Grisette.Internal.SymPrim.Prim.Internal.Utils
  ( eqHeteroRep,
    eqTypeRepBool,
    pattern Dyn,
  )
import Grisette.Internal.SymPrim.Prim.ModelValue
  ( ModelValue,
    toModelValue,
  )
import Language.Haskell.TH.Syntax (Lift (liftTyped))
import Type.Reflection
  ( SomeTypeRep (SomeTypeRep),
    TypeRep,
    Typeable,
    eqTypeRep,
    someTypeRep,
    typeRep,
    type (:~~:) (HRefl),
  )
import Unsafe.Coerce (unsafeCoerce)

#if MIN_VERSION_prettyprinter(1,7,0)
import Prettyprinter
  ( column,
    pageWidth,
    Doc,
    PageWidth(Unbounded, AvailablePerLine),
    Pretty(pretty),
  )
#else
import Data.Text.Prettyprint.Doc
  ( column,
    pageWidth,
    Doc,
    PageWidth(Unbounded, AvailablePerLine),
    Pretty(pretty),
  )
#endif

#if !MIN_VERSION_sbv(10, 0, 0)
#define SMTDefinable Uninterpreted
#endif

-- $setup
-- >>> import Grisette.Core
-- >>> import Grisette.SymPrim

-- SBV Translation
class (Monad m) => SBVFreshMonad m where
  sbvFresh :: (SBV.SymVal a) => String -> m (SBV.SBV a)

instance (MonadIO m) => SBVFreshMonad (SBVT.SymbolicT m) where
  sbvFresh :: forall a. SymVal a => String -> SymbolicT m (SBV a)
sbvFresh = String -> SymbolicT m (SBV a)
forall a (m :: * -> *).
(SymVal a, MonadSymbolic m) =>
String -> m (SBV a)
forall (m :: * -> *). MonadSymbolic m => String -> m (SBV a)
SBVT.free

instance (MonadIO m) => SBVFreshMonad (SBVTC.QueryT m) where
  sbvFresh :: forall a. SymVal a => String -> QueryT m (SBV a)
sbvFresh = String -> QueryT m (SBV a)
forall a (m :: * -> *).
(MonadIO m, MonadQuery m, SymVal a) =>
String -> m (SBV a)
SBVTC.freshVar

instance (SBVFreshMonad m) => SBVFreshMonad (ReaderT r m) where
  sbvFresh :: forall a. SymVal a => String -> ReaderT r m (SBV a)
sbvFresh = m (SBV a) -> ReaderT r m (SBV a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (SBV a) -> ReaderT r m (SBV a))
-> (String -> m (SBV a)) -> String -> ReaderT r m (SBV a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m (SBV a)
forall a. SymVal a => String -> m (SBV a)
forall (m :: * -> *) a.
(SBVFreshMonad m, SymVal a) =>
String -> m (SBV a)
sbvFresh

instance (SBVFreshMonad m) => SBVFreshMonad (StateT s m) where
  sbvFresh :: forall a. SymVal a => String -> StateT s m (SBV a)
sbvFresh = m (SBV a) -> StateT s m (SBV a)
forall (m :: * -> *) a. Monad m => m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (SBV a) -> StateT s m (SBV a))
-> (String -> m (SBV a)) -> String -> StateT s m (SBV a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> m (SBV a)
forall a. SymVal a => String -> m (SBV a)
forall (m :: * -> *) a.
(SBVFreshMonad m, SymVal a) =>
String -> m (SBV a)
sbvFresh

translateTypeError :: (HasCallStack) => Maybe String -> TypeRep a -> b
translateTypeError :: forall a b. HasCallStack => Maybe String -> TypeRep a -> b
translateTypeError Maybe String
Nothing TypeRep a
ta =
  String -> b
forall a. HasCallStack => String -> a
error (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$
    String
"Don't know how to translate the type " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep a -> String
forall a. Show a => a -> String
show TypeRep a
ta String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" to SMT"
translateTypeError (Just String
reason) TypeRep a
ta =
  String -> b
forall a. HasCallStack => String -> a
error (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$
    String
"Don't know how to translate the type " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep a -> String
forall a. Show a => a -> String
show TypeRep a
ta String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" to SMT: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
reason

class (SupportedPrim a, Ord a) => NonFuncSBVRep a where
  type NonFuncSBVBaseType (n :: Nat) a

class (NonFuncSBVRep a) => SupportedNonFuncPrim a where
  conNonFuncSBVTerm ::
    (KnownIsZero n) =>
    proxy n ->
    a ->
    SBV.SBV (NonFuncSBVBaseType n a)
  symNonFuncSBVTerm ::
    (SBVFreshMonad m, KnownIsZero n) =>
    proxy n ->
    String ->
    m (SBV.SBV (NonFuncSBVBaseType n a))
  withNonFuncPrim ::
    (KnownIsZero n) =>
    proxy n ->
    ( ( SBV.SymVal (NonFuncSBVBaseType n a),
        SBV.EqSymbolic (SBVType n a),
        SBV.Mergeable (SBVType n a),
        SBV.SMTDefinable (SBVType n a),
        SBV.Mergeable (SBVType n a),
        SBVType n a ~ SBV.SBV (NonFuncSBVBaseType n a),
        PrimConstraint n a
      ) =>
      r
    ) ->
    r

partitionCVArg ::
  forall a.
  (SupportedNonFuncPrim a) =>
  [([SBVD.CV], SBVD.CV)] ->
  [(a, [([SBVD.CV], SBVD.CV)])]
partitionCVArg :: forall a.
SupportedNonFuncPrim a =>
[([CV], CV)] -> [(a, [([CV], CV)])]
partitionCVArg [([CV], CV)]
cv =
  [(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
forall a.
SupportedNonFuncPrim a =>
[(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
partitionOrdCVArg ([(a, [([CV], CV)])] -> [(a, [([CV], CV)])])
-> [(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
forall a b. (a -> b) -> a -> b
$
    [([CV], CV)] -> [(a, [([CV], CV)])]
forall a.
SupportedNonFuncPrim a =>
[([CV], CV)] -> [(a, [([CV], CV)])]
parseFirstCVArg [([CV], CV)]
cv
  where
    parseFirstCVArg ::
      forall a.
      (SupportedNonFuncPrim a) =>
      [([SBVD.CV], SBVD.CV)] ->
      [(a, [([SBVD.CV], SBVD.CV)])]
    parseFirstCVArg :: forall a.
SupportedNonFuncPrim a =>
[([CV], CV)] -> [(a, [([CV], CV)])]
parseFirstCVArg =
      (([CV], CV) -> (a, [([CV], CV)]))
-> [([CV], CV)] -> [(a, [([CV], CV)])]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
        ( \case
            (CV
x : [CV]
xs, CV
v) ->
              (Int -> ([([CV], CV)], CV) -> a
forall t. SupportedPrim t => Int -> ([([CV], CV)], CV) -> t
parseSMTModelResult Int
0 ([([], CV
x)], CV
x), [([CV]
xs, CV
v)])
            ([CV], CV)
_ -> String -> (a, [([CV], CV)])
forall a. HasCallStack => String -> a
error String
"impossible"
        )
    partitionOrdCVArg ::
      forall a.
      (SupportedNonFuncPrim a) =>
      [(a, [([SBVD.CV], SBVD.CV)])] ->
      [(a, [([SBVD.CV], SBVD.CV)])]
    partitionOrdCVArg :: forall a.
SupportedNonFuncPrim a =>
[(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
partitionOrdCVArg [(a, [([CV], CV)])]
v = [(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
forall {a} {a}. Eq a => [(a, [a])] -> [(a, [a])]
go [(a, [([CV], CV)])]
sorted
      where
        sorted :: [(a, [([CV], CV)])]
sorted = ((a, [([CV], CV)]) -> a)
-> [(a, [([CV], CV)])] -> [(a, [([CV], CV)])]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith (a, [([CV], CV)]) -> a
forall a b. (a, b) -> a
fst [(a, [([CV], CV)])]
v :: [(a, [([SBVD.CV], SBVD.CV)])]
        go :: [(a, [a])] -> [(a, [a])]
go ((a, [a])
x : (a, [a])
x1 : [(a, [a])]
xs) =
          if (a, [a]) -> a
forall a b. (a, b) -> a
fst (a, [a])
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== (a, [a]) -> a
forall a b. (a, b) -> a
fst (a, [a])
x1
            then [(a, [a])] -> [(a, [a])]
go ([(a, [a])] -> [(a, [a])]) -> [(a, [a])] -> [(a, [a])]
forall a b. (a -> b) -> a -> b
$ ((a, [a]) -> a
forall a b. (a, b) -> a
fst (a, [a])
x, (a, [a]) -> [a]
forall a b. (a, b) -> b
snd (a, [a])
x [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ (a, [a]) -> [a]
forall a b. (a, b) -> b
snd (a, [a])
x1) (a, [a]) -> [(a, [a])] -> [(a, [a])]
forall a. a -> [a] -> [a]
: [(a, [a])]
xs
            else (a, [a])
x (a, [a]) -> [(a, [a])] -> [(a, [a])]
forall a. a -> [a] -> [a]
: [(a, [a])] -> [(a, [a])]
go ((a, [a])
x1 (a, [a]) -> [(a, [a])] -> [(a, [a])]
forall a. a -> [a] -> [a]
: [(a, [a])]
xs)
        go [(a, [a])]
x = [(a, [a])]
x

class SBVRep t where
  type SBVType (n :: Nat) t

class SupportedPrimConstraint t where
  type PrimConstraint (n :: Nat) t :: Constraint
  type PrimConstraint _ _ = ()

-- | Indicates that a type is supported and can be represented as a symbolic
-- term.
class
  ( Lift t,
    Typeable t,
    Hashable t,
    Eq t,
    Show t,
    NFData t,
    SupportedPrimConstraint t,
    SBVRep t
  ) =>
  SupportedPrim t
  where
  termCache :: Cache (Term t)
  termCache = Cache (Term t)
forall a. (Interned a, Typeable a) => Cache a
typeMemoizedCache
  pformatCon :: t -> String
  default pformatCon :: (Show t) => t -> String
  pformatCon = t -> String
forall a. Show a => a -> String
show
  pformatSym :: TypedSymbol t -> String
  pformatSym = TypedSymbol t -> String
forall t. TypedSymbol t -> String
showUntyped
  defaultValue :: t
  defaultValueDynamic :: proxy t -> ModelValue
  defaultValueDynamic proxy t
_ = t -> ModelValue
forall a. (Show a, Eq a, Hashable a, Typeable a) => a -> ModelValue
toModelValue (forall t. SupportedPrim t => t
defaultValue @t)
  pevalITETerm :: Term Bool -> Term t -> Term t -> Term t
  pevalEqTerm :: Term t -> Term t -> Term Bool
  conSBVTerm :: (KnownIsZero n) => proxy n -> t -> SBVType n t
  symSBVName :: TypedSymbol t -> Int -> String
  symSBVTerm ::
    (SBVFreshMonad m, KnownIsZero n) =>
    proxy n ->
    String ->
    m (SBVType n t)
  default withPrim ::
    ( PrimConstraint n t,
      SBV.SMTDefinable (SBVType n t),
      SBV.Mergeable (SBVType n t),
      Typeable (SBVType n t),
      KnownIsZero n
    ) =>
    p n ->
    ( ( PrimConstraint n t,
        SBV.SMTDefinable (SBVType n t),
        SBV.Mergeable (SBVType n t),
        Typeable (SBVType n t)
      ) =>
      a
    ) ->
    a
  withPrim ::
    (KnownIsZero n) =>
    p n ->
    ( ( PrimConstraint n t,
        SBV.SMTDefinable (SBVType n t),
        SBV.Mergeable (SBVType n t),
        Typeable (SBVType n t)
      ) =>
      a
    ) ->
    a
  withPrim p n
_ (PrimConstraint n t, SMTDefinable (SBVType n t),
 Mergeable (SBVType n t), Typeable (SBVType n t)) =>
a
i = a
(PrimConstraint n t, SMTDefinable (SBVType n t),
 Mergeable (SBVType n t), Typeable (SBVType n t)) =>
a
i
  sbvIte ::
    (KnownIsZero n) =>
    proxy n ->
    SBV.SBV Bool ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvIte proxy n
p = forall t (n :: Nat) (p :: Nat -> *) a.
(SupportedPrim t, KnownIsZero n) =>
p n
-> ((PrimConstraint n t, SMTDefinable (SBVType n t),
     Mergeable (SBVType n t), Typeable (SBVType n t)) =>
    a)
-> a
withPrim @t proxy n
p SBV Bool -> SBVType n t -> SBVType n t -> SBVType n t
(PrimConstraint n t, SMTDefinable (SBVType n t),
 Mergeable (SBVType n t), Typeable (SBVType n t)) =>
SBV Bool -> SBVType n t -> SBVType n t -> SBVType n t
forall a. Mergeable a => SBV Bool -> a -> a -> a
SBV.ite
  sbvEq ::
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBV.SBV Bool
  default sbvEq ::
    (KnownIsZero n, SBVT.EqSymbolic (SBVType n t)) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBV.SBV Bool
  sbvEq proxy n
_ = SBVType n t -> SBVType n t -> SBV Bool
forall a. EqSymbolic a => a -> a -> SBV Bool
(SBV..==)
  parseSMTModelResult :: Int -> ([([SBVD.CV], SBVD.CV)], SBVD.CV) -> t

parseSMTModelResultError :: TypeRep a -> ([([SBVD.CV], SBVD.CV)], SBVD.CV) -> a
parseSMTModelResultError :: forall a. TypeRep a -> ([([CV], CV)], CV) -> a
parseSMTModelResultError TypeRep a
ty ([([CV], CV)], CV)
cv =
  String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
    String
"BUG: cannot parse SBV model value \""
      String -> String -> String
forall a. Semigroup a => a -> a -> a
<> ([([CV], CV)], CV) -> String
forall a. Show a => a -> String
show ([([CV], CV)], CV)
cv
      String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\" to Grisette model value with the type "
      String -> String -> String
forall a. Semigroup a => a -> a -> a
<> TypeRep a -> String
forall a. Show a => a -> String
show TypeRep a
ty

pevalNEqTerm :: (SupportedPrim a) => Term a -> Term a -> Term Bool
pevalNEqTerm :: forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalNEqTerm Term a
l Term a
r = Term Bool -> Term Bool
pevalNotTerm (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalEqTerm Term a
l Term a
r
{-# INLINE pevalNEqTerm #-}

-- | Type family to resolve the concrete type associated with a symbolic type.
class ConRep sym where
  type ConType sym

-- | Type family to resolve the symbolic type associated with a concrete type.
class (SupportedPrim con) => SymRep con where
  type SymType con

-- | One-to-one mapping between symbolic types and concrete types.
class
  (ConRep sym, SymRep con, sym ~ SymType con, con ~ ConType sym) =>
  LinkedRep con sym
    | con -> sym,
      sym -> con
  where
  underlyingTerm :: sym -> Term con
  wrapTerm :: Term con -> sym

-- Partial Evaluation for the terms
class
  (SupportedPrim f, SupportedPrim a, SupportedPrim b) =>
  PEvalApplyTerm f a b
    | f -> a b
  where
  pevalApplyTerm :: Term f -> Term a -> Term b
  sbvApplyTerm ::
    (KnownIsZero n) => proxy n -> SBVType n f -> SBVType n a -> SBVType n b

class (SupportedPrim t, Bits t) => PEvalBitwiseTerm t where
  pevalAndBitsTerm :: Term t -> Term t -> Term t
  pevalOrBitsTerm :: Term t -> Term t -> Term t
  pevalXorBitsTerm :: Term t -> Term t -> Term t
  pevalComplementBitsTerm :: Term t -> Term t
  withSbvBitwiseTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((Bits (SBVType n t)) => r)) ->
    r
  sbvAndBitsTerm ::
    (KnownIsZero n) => proxy n -> SBVType n t -> SBVType n t -> SBVType n t
  sbvAndBitsTerm proxy n
p = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalBitwiseTerm t, KnownIsZero n) =>
proxy n -> (Bits (SBVType n t) => r) -> r
withSbvBitwiseTermConstraint @t proxy n
p Bits (SBVType n t) => SBVType n t -> SBVType n t -> SBVType n t
SBVType n t -> SBVType n t -> SBVType n t
forall a. Bits a => a -> a -> a
(SBV..&.)
  sbvOrBitsTerm ::
    (KnownIsZero n) => proxy n -> SBVType n t -> SBVType n t -> SBVType n t
  sbvOrBitsTerm proxy n
p = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalBitwiseTerm t, KnownIsZero n) =>
proxy n -> (Bits (SBVType n t) => r) -> r
withSbvBitwiseTermConstraint @t proxy n
p Bits (SBVType n t) => SBVType n t -> SBVType n t -> SBVType n t
SBVType n t -> SBVType n t -> SBVType n t
forall a. Bits a => a -> a -> a
(SBV..|.)
  sbvXorBitsTerm ::
    (KnownIsZero n) => proxy n -> SBVType n t -> SBVType n t -> SBVType n t
  sbvXorBitsTerm proxy n
p = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalBitwiseTerm t, KnownIsZero n) =>
proxy n -> (Bits (SBVType n t) => r) -> r
withSbvBitwiseTermConstraint @t proxy n
p Bits (SBVType n t) => SBVType n t -> SBVType n t -> SBVType n t
SBVType n t -> SBVType n t -> SBVType n t
forall a. Bits a => a -> a -> a
SBV.xor
  sbvComplementBitsTerm ::
    (KnownIsZero n) => proxy n -> SBVType n t -> SBVType n t
  sbvComplementBitsTerm proxy n
p = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalBitwiseTerm t, KnownIsZero n) =>
proxy n -> (Bits (SBVType n t) => r) -> r
withSbvBitwiseTermConstraint @t proxy n
p Bits (SBVType n t) => SBVType n t -> SBVType n t
SBVType n t -> SBVType n t
forall a. Bits a => a -> a
SBV.complement

class (SupportedNonFuncPrim t, SymShift t) => PEvalShiftTerm t where
  pevalShiftLeftTerm :: Term t -> Term t -> Term t
  pevalShiftRightTerm :: Term t -> Term t -> Term t
  withSbvShiftTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((SBV.SIntegral (NonFuncSBVBaseType n t)) => r)) ->
    r
  sbvShiftLeftTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvShiftLeftTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @t proxy n
p (((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
   Mergeable (SBVType n t), SMTDefinable (SBVType n t),
   Mergeable (SBVType n t),
   SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
  SBVType n t)
 -> SBVType n t)
-> ((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
     Mergeable (SBVType n t), SMTDefinable (SBVType n t),
     Mergeable (SBVType n t),
     SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
    SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
      forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalShiftTerm t, KnownIsZero n) =>
proxy n -> (SIntegral (NonFuncSBVBaseType n t) => r) -> r
withSbvShiftTermConstraint @t proxy n
p ((SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
 -> SBVType n t)
-> (SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
        SBV (NonFuncSBVBaseType n t)
-> SBV (NonFuncSBVBaseType n t) -> SBV (NonFuncSBVBaseType n t)
forall a b. (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
SBV.sShiftLeft SBV (NonFuncSBVBaseType n t)
SBVType n t
l SBV (NonFuncSBVBaseType n t)
SBVType n t
r
  sbvShiftRightTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvShiftRightTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @t proxy n
p (((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
   Mergeable (SBVType n t), SMTDefinable (SBVType n t),
   Mergeable (SBVType n t),
   SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
  SBVType n t)
 -> SBVType n t)
-> ((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
     Mergeable (SBVType n t), SMTDefinable (SBVType n t),
     Mergeable (SBVType n t),
     SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
    SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
      forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalShiftTerm t, KnownIsZero n) =>
proxy n -> (SIntegral (NonFuncSBVBaseType n t) => r) -> r
withSbvShiftTermConstraint @t proxy n
p ((SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
 -> SBVType n t)
-> (SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
        SBV (NonFuncSBVBaseType n t)
-> SBV (NonFuncSBVBaseType n t) -> SBV (NonFuncSBVBaseType n t)
forall a b. (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
SBV.sShiftRight SBV (NonFuncSBVBaseType n t)
SBVType n t
l SBV (NonFuncSBVBaseType n t)
SBVType n t
r

class (SupportedNonFuncPrim t, SymRotate t) => PEvalRotateTerm t where
  pevalRotateLeftTerm :: Term t -> Term t -> Term t
  pevalRotateRightTerm :: Term t -> Term t -> Term t
  withSbvRotateTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((SBV.SIntegral (NonFuncSBVBaseType n t)) => r)) ->
    r
  sbvRotateLeftTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvRotateLeftTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @t proxy n
p (((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
   Mergeable (SBVType n t), SMTDefinable (SBVType n t),
   Mergeable (SBVType n t),
   SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
  SBVType n t)
 -> SBVType n t)
-> ((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
     Mergeable (SBVType n t), SMTDefinable (SBVType n t),
     Mergeable (SBVType n t),
     SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
    SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
      forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalRotateTerm t, KnownIsZero n) =>
proxy n -> (SIntegral (NonFuncSBVBaseType n t) => r) -> r
withSbvRotateTermConstraint @t proxy n
p ((SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
 -> SBVType n t)
-> (SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
        SBV (NonFuncSBVBaseType n t)
-> SBV (NonFuncSBVBaseType n t) -> SBV (NonFuncSBVBaseType n t)
forall a b. (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
SBV.sRotateLeft SBV (NonFuncSBVBaseType n t)
SBVType n t
l SBV (NonFuncSBVBaseType n t)
SBVType n t
r
  sbvRotateRightTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvRotateRightTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @t proxy n
p (((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
   Mergeable (SBVType n t), SMTDefinable (SBVType n t),
   Mergeable (SBVType n t),
   SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
  SBVType n t)
 -> SBVType n t)
-> ((SymVal (NonFuncSBVBaseType n t), EqSymbolic (SBVType n t),
     Mergeable (SBVType n t), SMTDefinable (SBVType n t),
     Mergeable (SBVType n t),
     SBVType n t ~ SBV (NonFuncSBVBaseType n t), PrimConstraint n t) =>
    SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
      forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalRotateTerm t, KnownIsZero n) =>
proxy n -> (SIntegral (NonFuncSBVBaseType n t) => r) -> r
withSbvRotateTermConstraint @t proxy n
p ((SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
 -> SBVType n t)
-> (SIntegral (NonFuncSBVBaseType n t) => SBVType n t)
-> SBVType n t
forall a b. (a -> b) -> a -> b
$
        SBV (NonFuncSBVBaseType n t)
-> SBV (NonFuncSBVBaseType n t) -> SBV (NonFuncSBVBaseType n t)
forall a b. (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
SBV.sRotateRight SBV (NonFuncSBVBaseType n t)
SBVType n t
l SBV (NonFuncSBVBaseType n t)
SBVType n t
r

class (SupportedPrim t, Num t) => PEvalNumTerm t where
  pevalAddNumTerm :: Term t -> Term t -> Term t
  pevalNegNumTerm :: Term t -> Term t
  pevalMulNumTerm :: Term t -> Term t -> Term t
  pevalAbsNumTerm :: Term t -> Term t
  pevalSignumNumTerm :: Term t -> Term t
  withSbvNumTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((Num (SBVType n t)) => r)) ->
    r
  sbvAddNumTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvAddNumTerm proxy n
p SBVType n t
l SBVType n t
r = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalNumTerm t, KnownIsZero n) =>
proxy n -> (Num (SBVType n t) => r) -> r
withSbvNumTermConstraint @t proxy n
p ((Num (SBVType n t) => SBVType n t) -> SBVType n t)
-> (Num (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. Num a => a -> a -> a
+ SBVType n t
r
  sbvNegNumTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t
  sbvNegNumTerm proxy n
p SBVType n t
l = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalNumTerm t, KnownIsZero n) =>
proxy n -> (Num (SBVType n t) => r) -> r
withSbvNumTermConstraint @t proxy n
p ((Num (SBVType n t) => SBVType n t) -> SBVType n t)
-> (Num (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ -SBVType n t
l
  sbvMulNumTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvMulNumTerm proxy n
p SBVType n t
l SBVType n t
r = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalNumTerm t, KnownIsZero n) =>
proxy n -> (Num (SBVType n t) => r) -> r
withSbvNumTermConstraint @t proxy n
p ((Num (SBVType n t) => SBVType n t) -> SBVType n t)
-> (Num (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. Num a => a -> a -> a
* SBVType n t
r
  sbvAbsNumTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t
  sbvAbsNumTerm proxy n
p SBVType n t
l = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalNumTerm t, KnownIsZero n) =>
proxy n -> (Num (SBVType n t) => r) -> r
withSbvNumTermConstraint @t proxy n
p ((Num (SBVType n t) => SBVType n t) -> SBVType n t)
-> (Num (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t -> SBVType n t
forall a. Num a => a -> a
abs SBVType n t
l
  sbvSignumNumTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t
  sbvSignumNumTerm proxy n
p SBVType n t
l = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalNumTerm t, KnownIsZero n) =>
proxy n -> (Num (SBVType n t) => r) -> r
withSbvNumTermConstraint @t proxy n
p ((Num (SBVType n t) => SBVType n t) -> SBVType n t)
-> (Num (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t -> SBVType n t
forall a. Num a => a -> a
signum SBVType n t
l

pevalSubNumTerm :: (PEvalNumTerm a) => Term a -> Term a -> Term a
pevalSubNumTerm :: forall a. PEvalNumTerm a => Term a -> Term a -> Term a
pevalSubNumTerm Term a
l Term a
r = Term a -> Term a -> Term a
forall a. PEvalNumTerm a => Term a -> Term a -> Term a
pevalAddNumTerm Term a
l (Term a -> Term a
forall t. PEvalNumTerm t => Term t -> Term t
pevalNegNumTerm Term a
r)

class (SupportedPrim t, Ord t) => PEvalOrdTerm t where
  pevalLtOrdTerm :: Term t -> Term t -> Term Bool
  pevalLeOrdTerm :: Term t -> Term t -> Term Bool
  withSbvOrdTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((SBV.OrdSymbolic (SBVType n t)) => r)) ->
    r
  sbvLtOrdTerm ::
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBV.SBV Bool
  sbvLtOrdTerm proxy n
p SBVType n t
l SBVType n t
r = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalOrdTerm t, KnownIsZero n) =>
proxy n -> (OrdSymbolic (SBVType n t) => r) -> r
withSbvOrdTermConstraint @t proxy n
p ((OrdSymbolic (SBVType n t) => SBV Bool) -> SBV Bool)
-> (OrdSymbolic (SBVType n t) => SBV Bool) -> SBV Bool
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
SBV..< SBVType n t
r
  sbvLeOrdTerm ::
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBV.SBV Bool
  sbvLeOrdTerm proxy n
p SBVType n t
l SBVType n t
r = forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalOrdTerm t, KnownIsZero n) =>
proxy n -> (OrdSymbolic (SBVType n t) => r) -> r
withSbvOrdTermConstraint @t proxy n
p ((OrdSymbolic (SBVType n t) => SBV Bool) -> SBV Bool)
-> (OrdSymbolic (SBVType n t) => SBV Bool) -> SBV Bool
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
SBV..<= SBVType n t
r

pevalGtOrdTerm :: (PEvalOrdTerm a) => Term a -> Term a -> Term Bool
pevalGtOrdTerm :: forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
pevalGtOrdTerm = (Term a -> Term a -> Term Bool) -> Term a -> Term a -> Term Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Term a -> Term a -> Term Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
pevalLtOrdTerm

pevalGeOrdTerm :: (PEvalOrdTerm a) => Term a -> Term a -> Term Bool
pevalGeOrdTerm :: forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
pevalGeOrdTerm = (Term a -> Term a -> Term Bool) -> Term a -> Term a -> Term Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Term a -> Term a -> Term Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
pevalLeOrdTerm

class (SupportedPrim t, Integral t) => PEvalDivModIntegralTerm t where
  pevalDivIntegralTerm :: Term t -> Term t -> Term t
  pevalModIntegralTerm :: Term t -> Term t -> Term t
  pevalQuotIntegralTerm :: Term t -> Term t -> Term t
  pevalRemIntegralTerm :: Term t -> Term t -> Term t
  withSbvDivModIntegralTermConstraint ::
    (KnownIsZero n) =>
    proxy n ->
    (((SBV.SDivisible (SBVType n t)) => r)) ->
    r
  sbvDivIntegralTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvDivIntegralTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalDivModIntegralTerm t, KnownIsZero n) =>
proxy n -> (SDivisible (SBVType n t) => r) -> r
withSbvDivModIntegralTermConstraint @t proxy n
p ((SDivisible (SBVType n t) => SBVType n t) -> SBVType n t)
-> (SDivisible (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. SDivisible a => a -> a -> a
`SBV.sDiv` SBVType n t
r
  sbvModIntegralTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvModIntegralTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalDivModIntegralTerm t, KnownIsZero n) =>
proxy n -> (SDivisible (SBVType n t) => r) -> r
withSbvDivModIntegralTermConstraint @t proxy n
p ((SDivisible (SBVType n t) => SBVType n t) -> SBVType n t)
-> (SDivisible (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. SDivisible a => a -> a -> a
`SBV.sMod` SBVType n t
r
  sbvQuotIntegralTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvQuotIntegralTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalDivModIntegralTerm t, KnownIsZero n) =>
proxy n -> (SDivisible (SBVType n t) => r) -> r
withSbvDivModIntegralTermConstraint @t proxy n
p ((SDivisible (SBVType n t) => SBVType n t) -> SBVType n t)
-> (SDivisible (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. SDivisible a => a -> a -> a
`SBV.sQuot` SBVType n t
r
  sbvRemIntegralTerm ::
    forall proxy n.
    (KnownIsZero n) =>
    proxy n ->
    SBVType n t ->
    SBVType n t ->
    SBVType n t
  sbvRemIntegralTerm proxy n
p SBVType n t
l SBVType n t
r =
    forall t (n :: Nat) (proxy :: Nat -> *) r.
(PEvalDivModIntegralTerm t, KnownIsZero n) =>
proxy n -> (SDivisible (SBVType n t) => r) -> r
withSbvDivModIntegralTermConstraint @t proxy n
p ((SDivisible (SBVType n t) => SBVType n t) -> SBVType n t)
-> (SDivisible (SBVType n t) => SBVType n t) -> SBVType n t
forall a b. (a -> b) -> a -> b
$ SBVType n t
l SBVType n t -> SBVType n t -> SBVType n t
forall a. SDivisible a => a -> a -> a
`SBV.sRem` SBVType n t
r

class
  ( PEvalBVTerm s,
    PEvalBVTerm u,
    forall n. (KnownNat n, 1 <= n) => SupportedNonFuncPrim (u n),
    forall n. (KnownNat n, 1 <= n) => SupportedNonFuncPrim (s n),
    forall n. (KnownNat n, 1 <= n) => SignConversion (u n) (s n)
  ) =>
  PEvalBVSignConversionTerm u s
    | u -> s,
      s -> u
  where
  pevalBVToSignedTerm :: (KnownNat n, 1 <= n) => Term (u n) -> Term (s n)
  pevalBVToUnsignedTerm :: (KnownNat n, 1 <= n) => Term (s n) -> Term (u n)
  withSbvSignConversionTermConstraint ::
    forall n integerBitwidth p q r.
    (KnownIsZero integerBitwidth, KnownNat n, 1 <= n) =>
    p n ->
    q integerBitwidth ->
    ( ( ( Integral (NonFuncSBVBaseType integerBitwidth (u n)),
          Integral (NonFuncSBVBaseType integerBitwidth (s n))
        ) =>
        r
      )
    ) ->
    r
  sbvToSigned ::
    forall n integerBitwidth o p q.
    (KnownIsZero integerBitwidth, KnownNat n, 1 <= n) =>
    o u ->
    p n ->
    q integerBitwidth ->
    SBVType integerBitwidth (u n) ->
    SBVType integerBitwidth (s n)
  sbvToSigned o u
_ p n
_ q integerBitwidth
qint SBVType integerBitwidth (u n)
u =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @(u n) q integerBitwidth
qint (((SymVal (NonFuncSBVBaseType integerBitwidth (u n)),
   EqSymbolic (SBVType integerBitwidth (u n)),
   Mergeable (SBVType integerBitwidth (u n)),
   SMTDefinable (SBVType integerBitwidth (u n)),
   Mergeable (SBVType integerBitwidth (u n)),
   SBVType integerBitwidth (u n)
   ~ SBV (NonFuncSBVBaseType integerBitwidth (u n)),
   PrimConstraint integerBitwidth (u n)) =>
  SBVType integerBitwidth (s n))
 -> SBVType integerBitwidth (s n))
-> ((SymVal (NonFuncSBVBaseType integerBitwidth (u n)),
     EqSymbolic (SBVType integerBitwidth (u n)),
     Mergeable (SBVType integerBitwidth (u n)),
     SMTDefinable (SBVType integerBitwidth (u n)),
     Mergeable (SBVType integerBitwidth (u n)),
     SBVType integerBitwidth (u n)
     ~ SBV (NonFuncSBVBaseType integerBitwidth (u n)),
     PrimConstraint integerBitwidth (u n)) =>
    SBVType integerBitwidth (s n))
-> SBVType integerBitwidth (s n)
forall a b. (a -> b) -> a -> b
$
      forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @(s n) q integerBitwidth
qint (((SymVal (NonFuncSBVBaseType integerBitwidth (s n)),
   EqSymbolic (SBVType integerBitwidth (s n)),
   Mergeable (SBVType integerBitwidth (s n)),
   SMTDefinable (SBVType integerBitwidth (s n)),
   Mergeable (SBVType integerBitwidth (s n)),
   SBVType integerBitwidth (s n)
   ~ SBV (NonFuncSBVBaseType integerBitwidth (s n)),
   PrimConstraint integerBitwidth (s n)) =>
  SBVType integerBitwidth (s n))
 -> SBVType integerBitwidth (s n))
-> ((SymVal (NonFuncSBVBaseType integerBitwidth (s n)),
     EqSymbolic (SBVType integerBitwidth (s n)),
     Mergeable (SBVType integerBitwidth (s n)),
     SMTDefinable (SBVType integerBitwidth (s n)),
     Mergeable (SBVType integerBitwidth (s n)),
     SBVType integerBitwidth (s n)
     ~ SBV (NonFuncSBVBaseType integerBitwidth (s n)),
     PrimConstraint integerBitwidth (s n)) =>
    SBVType integerBitwidth (s n))
-> SBVType integerBitwidth (s n)
forall a b. (a -> b) -> a -> b
$
        forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat)
       (integerBitwidth :: Nat) (p :: Nat -> *) (q :: Nat -> *) r.
(PEvalBVSignConversionTerm u s, KnownIsZero integerBitwidth,
 KnownNat n, 1 <= n) =>
p n
-> q integerBitwidth
-> ((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
     Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
    r)
-> r
withSbvSignConversionTermConstraint @u @s (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) q integerBitwidth
qint (((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
   Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
  SBVType integerBitwidth (s n))
 -> SBVType integerBitwidth (s n))
-> ((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
     Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
    SBVType integerBitwidth (s n))
-> SBVType integerBitwidth (s n)
forall a b. (a -> b) -> a -> b
$
          SBV (NonFuncSBVBaseType integerBitwidth (u n))
-> SBV (NonFuncSBVBaseType integerBitwidth (s n))
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
 SymVal b) =>
SBV a -> SBV b
SBV.sFromIntegral SBV (NonFuncSBVBaseType integerBitwidth (u n))
SBVType integerBitwidth (u n)
u
  sbvToUnsigned ::
    forall n integerBitwidth o p q.
    (KnownIsZero integerBitwidth, KnownNat n, 1 <= n) =>
    o s ->
    p n ->
    q integerBitwidth ->
    SBVType integerBitwidth (s n) ->
    SBVType integerBitwidth (u n)
  sbvToUnsigned o s
_ p n
_ q integerBitwidth
qint SBVType integerBitwidth (s n)
u =
    forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @(u n) q integerBitwidth
qint (((SymVal (NonFuncSBVBaseType integerBitwidth (u n)),
   EqSymbolic (SBVType integerBitwidth (u n)),
   Mergeable (SBVType integerBitwidth (u n)),
   SMTDefinable (SBVType integerBitwidth (u n)),
   Mergeable (SBVType integerBitwidth (u n)),
   SBVType integerBitwidth (u n)
   ~ SBV (NonFuncSBVBaseType integerBitwidth (u n)),
   PrimConstraint integerBitwidth (u n)) =>
  SBVType integerBitwidth (u n))
 -> SBVType integerBitwidth (u n))
-> ((SymVal (NonFuncSBVBaseType integerBitwidth (u n)),
     EqSymbolic (SBVType integerBitwidth (u n)),
     Mergeable (SBVType integerBitwidth (u n)),
     SMTDefinable (SBVType integerBitwidth (u n)),
     Mergeable (SBVType integerBitwidth (u n)),
     SBVType integerBitwidth (u n)
     ~ SBV (NonFuncSBVBaseType integerBitwidth (u n)),
     PrimConstraint integerBitwidth (u n)) =>
    SBVType integerBitwidth (u n))
-> SBVType integerBitwidth (u n)
forall a b. (a -> b) -> a -> b
$
      forall a (n :: Nat) (proxy :: Nat -> *) r.
(SupportedNonFuncPrim a, KnownIsZero n) =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n a), EqSymbolic (SBVType n a),
     Mergeable (SBVType n a), SMTDefinable (SBVType n a),
     Mergeable (SBVType n a),
     SBVType n a ~ SBV (NonFuncSBVBaseType n a), PrimConstraint n a) =>
    r)
-> r
withNonFuncPrim @(s n) q integerBitwidth
qint (((SymVal (NonFuncSBVBaseType integerBitwidth (s n)),
   EqSymbolic (SBVType integerBitwidth (s n)),
   Mergeable (SBVType integerBitwidth (s n)),
   SMTDefinable (SBVType integerBitwidth (s n)),
   Mergeable (SBVType integerBitwidth (s n)),
   SBVType integerBitwidth (s n)
   ~ SBV (NonFuncSBVBaseType integerBitwidth (s n)),
   PrimConstraint integerBitwidth (s n)) =>
  SBVType integerBitwidth (u n))
 -> SBVType integerBitwidth (u n))
-> ((SymVal (NonFuncSBVBaseType integerBitwidth (s n)),
     EqSymbolic (SBVType integerBitwidth (s n)),
     Mergeable (SBVType integerBitwidth (s n)),
     SMTDefinable (SBVType integerBitwidth (s n)),
     Mergeable (SBVType integerBitwidth (s n)),
     SBVType integerBitwidth (s n)
     ~ SBV (NonFuncSBVBaseType integerBitwidth (s n)),
     PrimConstraint integerBitwidth (s n)) =>
    SBVType integerBitwidth (u n))
-> SBVType integerBitwidth (u n)
forall a b. (a -> b) -> a -> b
$
        forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat)
       (integerBitwidth :: Nat) (p :: Nat -> *) (q :: Nat -> *) r.
(PEvalBVSignConversionTerm u s, KnownIsZero integerBitwidth,
 KnownNat n, 1 <= n) =>
p n
-> q integerBitwidth
-> ((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
     Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
    r)
-> r
withSbvSignConversionTermConstraint @u @s (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) q integerBitwidth
qint (((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
   Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
  SBVType integerBitwidth (u n))
 -> SBVType integerBitwidth (u n))
-> ((Integral (NonFuncSBVBaseType integerBitwidth (u n)),
     Integral (NonFuncSBVBaseType integerBitwidth (s n))) =>
    SBVType integerBitwidth (u n))
-> SBVType integerBitwidth (u n)
forall a b. (a -> b) -> a -> b
$
          SBV (NonFuncSBVBaseType integerBitwidth (s n))
-> SBV (NonFuncSBVBaseType integerBitwidth (u n))
forall a b.
(Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
 SymVal b) =>
SBV a -> SBV b
SBV.sFromIntegral SBV (NonFuncSBVBaseType integerBitwidth (s n))
SBVType integerBitwidth (s n)
u

class
  ( forall n. (KnownNat n, 1 <= n) => SupportedPrim (bv n),
    SizedBV bv,
    Typeable bv
  ) =>
  PEvalBVTerm bv
  where
  pevalBVConcatTerm ::
    (KnownNat l, KnownNat r, 1 <= l, 1 <= r) =>
    Term (bv l) ->
    Term (bv r) ->
    Term (bv (l + r))
  pevalBVExtendTerm ::
    (KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
    Bool ->
    proxy r ->
    Term (bv l) ->
    Term (bv r)
  pevalBVSelectTerm ::
    (KnownNat n, KnownNat ix, KnownNat w, 1 <= n, 1 <= w, ix + w <= n) =>
    p ix ->
    q w ->
    Term (bv n) ->
    Term (bv w)
  sbvBVConcatTerm ::
    (KnownIsZero n, KnownNat l, KnownNat r, 1 <= l, 1 <= r) =>
    p0 n ->
    p1 l ->
    p2 r ->
    SBVType n (bv l) ->
    SBVType n (bv r) ->
    SBVType n (bv (l + r))
  sbvBVExtendTerm ::
    (KnownIsZero n, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
    p0 n ->
    p1 l ->
    p2 r ->
    Bool ->
    SBVType n (bv l) ->
    SBVType n (bv r)
  sbvBVSelectTerm ::
    ( KnownIsZero int,
      KnownNat ix,
      KnownNat w,
      KnownNat n,
      1 <= n,
      1 <= w,
      ix + w <= n
    ) =>
    p0 int ->
    p1 ix ->
    p2 w ->
    p3 n ->
    SBVType int (bv n) ->
    SBVType int (bv w)

class
  (SupportedPrim arg, SupportedPrim t, Lift tag, NFData tag, Show tag, Typeable tag, Eq tag, Hashable tag) =>
  UnaryOp tag arg t
    | tag arg -> t
  where
  pevalUnary :: (Typeable tag, Typeable t) => tag -> Term arg -> Term t
  pformatUnary :: tag -> Term arg -> String

class
  ( SupportedPrim arg1,
    SupportedPrim arg2,
    SupportedPrim t,
    Lift tag,
    NFData tag,
    Show tag,
    Typeable tag,
    Eq tag,
    Hashable tag
  ) =>
  BinaryOp tag arg1 arg2 t
    | tag arg1 arg2 -> t
  where
  pevalBinary :: (Typeable tag, Typeable t) => tag -> Term arg1 -> Term arg2 -> Term t
  pformatBinary :: tag -> Term arg1 -> Term arg2 -> String

class
  ( SupportedPrim arg1,
    SupportedPrim arg2,
    SupportedPrim arg3,
    SupportedPrim t,
    Lift tag,
    NFData tag,
    Show tag,
    Typeable tag,
    Eq tag,
    Hashable tag
  ) =>
  TernaryOp tag arg1 arg2 arg3 t
    | tag arg1 arg2 arg3 -> t
  where
  pevalTernary :: (Typeable tag, Typeable t) => tag -> Term arg1 -> Term arg2 -> Term arg3 -> Term t
  pformatTernary :: tag -> Term arg1 -> Term arg2 -> Term arg3 -> String

-- Typed Symbols

-- | A typed symbol is a symbol that is associated with a type. Note that the
-- same symbol bodies with different types are considered different symbols
-- and can coexist in a term.
--
-- Simple symbols can be created with the 'OverloadedStrings' extension:
--
-- >>> :set -XOverloadedStrings
-- >>> "a" :: TypedSymbol Bool
-- a :: Bool
data TypedSymbol t where
  TypedSymbol :: (SupportedPrim t) => {forall t. TypedSymbol t -> Symbol
unTypedSymbol :: Symbol} -> TypedSymbol t

instance Eq (TypedSymbol t) where
  TypedSymbol Symbol
x == :: TypedSymbol t -> TypedSymbol t -> Bool
== TypedSymbol Symbol
y = Symbol
x Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
y

instance Ord (TypedSymbol t) where
  TypedSymbol Symbol
x <= :: TypedSymbol t -> TypedSymbol t -> Bool
<= TypedSymbol Symbol
y = Symbol
x Symbol -> Symbol -> Bool
forall a. Ord a => a -> a -> Bool
<= Symbol
y

instance Lift (TypedSymbol t) where
  liftTyped :: forall (m :: * -> *).
Quote m =>
TypedSymbol t -> Code m (TypedSymbol t)
liftTyped (TypedSymbol Symbol
x) = [||Symbol -> TypedSymbol t
forall t. SupportedPrim t => Symbol -> TypedSymbol t
TypedSymbol Symbol
x||]

instance Show (TypedSymbol t) where
  show :: TypedSymbol t -> String
show (TypedSymbol Symbol
symbol) = Symbol -> String
forall a. Show a => a -> String
show Symbol
symbol String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" :: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep t -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @t)

showUntyped :: TypedSymbol t -> String
showUntyped :: forall t. TypedSymbol t -> String
showUntyped (TypedSymbol Symbol
symbol) = Symbol -> String
forall a. Show a => a -> String
show Symbol
symbol

instance Hashable (TypedSymbol t) where
  Int
s hashWithSalt :: Int -> TypedSymbol t -> Int
`hashWithSalt` TypedSymbol Symbol
x = Int
s Int -> Symbol -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Symbol
x

instance NFData (TypedSymbol t) where
  rnf :: TypedSymbol t -> ()
rnf (TypedSymbol Symbol
str) = Symbol -> ()
forall a. NFData a => a -> ()
rnf Symbol
str

instance (SupportedPrim t) => IsString (TypedSymbol t) where
  fromString :: String -> TypedSymbol t
fromString = Symbol -> TypedSymbol t
forall t. SupportedPrim t => Symbol -> TypedSymbol t
TypedSymbol (Symbol -> TypedSymbol t)
-> (String -> Symbol) -> String -> TypedSymbol t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Symbol
forall a. IsString a => String -> a
fromString

withSymbolSupported :: TypedSymbol t -> ((SupportedPrim t) => a) -> a
withSymbolSupported :: forall t a. TypedSymbol t -> (SupportedPrim t => a) -> a
withSymbolSupported (TypedSymbol Symbol
_) SupportedPrim t => a
a = a
SupportedPrim t => a
a

data SomeTypedSymbol where
  SomeTypedSymbol :: forall t. TypeRep t -> TypedSymbol t -> SomeTypedSymbol

instance NFData SomeTypedSymbol where
  rnf :: SomeTypedSymbol -> ()
rnf (SomeTypedSymbol TypeRep t
p TypedSymbol t
s) = SomeTypeRep -> ()
forall a. NFData a => a -> ()
rnf (TypeRep t -> SomeTypeRep
forall k (a :: k). TypeRep a -> SomeTypeRep
SomeTypeRep TypeRep t
p) () -> () -> ()
forall a b. a -> b -> b
`seq` TypedSymbol t -> ()
forall a. NFData a => a -> ()
rnf TypedSymbol t
s

instance Eq SomeTypedSymbol where
  (SomeTypedSymbol TypeRep t
t1 TypedSymbol t
s1) == :: SomeTypedSymbol -> SomeTypedSymbol -> Bool
== (SomeTypedSymbol TypeRep t
t2 TypedSymbol t
s2) = case TypeRep t -> TypeRep t -> Maybe (t :~~: t)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
eqTypeRep TypeRep t
t1 TypeRep t
t2 of
    Just t :~~: t
HRefl -> TypedSymbol t
s1 TypedSymbol t -> TypedSymbol t -> Bool
forall a. Eq a => a -> a -> Bool
== TypedSymbol t
TypedSymbol t
s2
    Maybe (t :~~: t)
_ -> Bool
False

instance Ord SomeTypedSymbol where
  (SomeTypedSymbol TypeRep t
t1 TypedSymbol t
s1) <= :: SomeTypedSymbol -> SomeTypedSymbol -> Bool
<= (SomeTypedSymbol TypeRep t
t2 TypedSymbol t
s2) =
    TypeRep t -> SomeTypeRep
forall k (a :: k). TypeRep a -> SomeTypeRep
SomeTypeRep TypeRep t
t1 SomeTypeRep -> SomeTypeRep -> Bool
forall a. Ord a => a -> a -> Bool
< TypeRep t -> SomeTypeRep
forall k (a :: k). TypeRep a -> SomeTypeRep
SomeTypeRep TypeRep t
t2
      Bool -> Bool -> Bool
|| ( case TypeRep t -> TypeRep t -> Maybe (t :~~: t)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
eqTypeRep TypeRep t
t1 TypeRep t
t2 of
             Just t :~~: t
HRefl -> TypedSymbol t
s1 TypedSymbol t -> TypedSymbol t -> Bool
forall a. Ord a => a -> a -> Bool
<= TypedSymbol t
TypedSymbol t
s2
             Maybe (t :~~: t)
_ -> Bool
False
         )

instance Hashable SomeTypedSymbol where
  hashWithSalt :: Int -> SomeTypedSymbol -> Int
hashWithSalt Int
s (SomeTypedSymbol TypeRep t
t1 TypedSymbol t
s1) = Int
s Int -> TypedSymbol t -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypedSymbol t
s1 Int -> TypeRep t -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep t
t1

instance Show SomeTypedSymbol where
  show :: SomeTypedSymbol -> String
show (SomeTypedSymbol TypeRep t
_ TypedSymbol t
s) = TypedSymbol t -> String
forall a. Show a => a -> String
show TypedSymbol t
s

someTypedSymbol :: forall t. TypedSymbol t -> SomeTypedSymbol
someTypedSymbol :: forall t. TypedSymbol t -> SomeTypedSymbol
someTypedSymbol s :: TypedSymbol t
s@(TypedSymbol Symbol
_) = TypeRep t -> TypedSymbol t -> SomeTypedSymbol
forall a. TypeRep a -> TypedSymbol a -> SomeTypedSymbol
SomeTypedSymbol (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @t) TypedSymbol t
s

-- Terms

data Term t where
  ConTerm :: (SupportedPrim t) => {-# UNPACK #-} !Id -> !t -> Term t
  SymTerm :: (SupportedPrim t) => {-# UNPACK #-} !Id -> !(TypedSymbol t) -> Term t
  UnaryTerm ::
    (UnaryOp tag arg t) =>
    {-# UNPACK #-} !Id ->
    !tag ->
    !(Term arg) ->
    Term t
  BinaryTerm ::
    (BinaryOp tag arg1 arg2 t) =>
    {-# UNPACK #-} !Id ->
    !tag ->
    !(Term arg1) ->
    !(Term arg2) ->
    Term t
  TernaryTerm ::
    (TernaryOp tag arg1 arg2 arg3 t) =>
    {-# UNPACK #-} !Id ->
    !tag ->
    !(Term arg1) ->
    !(Term arg2) ->
    !(Term arg3) ->
    Term t
  NotTerm :: {-# UNPACK #-} !Id -> !(Term Bool) -> Term Bool
  OrTerm :: {-# UNPACK #-} !Id -> !(Term Bool) -> !(Term Bool) -> Term Bool
  AndTerm :: {-# UNPACK #-} !Id -> !(Term Bool) -> !(Term Bool) -> Term Bool
  EqTerm ::
    (SupportedPrim t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term Bool
  ITETerm ::
    (SupportedPrim t) =>
    {-# UNPACK #-} !Id ->
    !(Term Bool) ->
    !(Term t) ->
    !(Term t) ->
    Term t
  AddNumTerm ::
    (PEvalNumTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  NegNumTerm ::
    (PEvalNumTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    Term t
  MulNumTerm ::
    (PEvalNumTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  AbsNumTerm ::
    (PEvalNumTerm t) => {-# UNPACK #-} !Id -> !(Term t) -> Term t
  SignumNumTerm :: (PEvalNumTerm t) => {-# UNPACK #-} !Id -> !(Term t) -> Term t
  LtOrdTerm ::
    (PEvalOrdTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term Bool
  LeOrdTerm ::
    (PEvalOrdTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term Bool
  AndBitsTerm ::
    (PEvalBitwiseTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  OrBitsTerm ::
    (PEvalBitwiseTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  XorBitsTerm ::
    (PEvalBitwiseTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  ComplementBitsTerm ::
    (PEvalBitwiseTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    Term t
  ShiftLeftTerm ::
    (PEvalShiftTerm t) => {-# UNPACK #-} !Id -> !(Term t) -> !(Term t) -> Term t
  ShiftRightTerm ::
    (PEvalShiftTerm t) => {-# UNPACK #-} !Id -> !(Term t) -> !(Term t) -> Term t
  RotateLeftTerm ::
    (PEvalRotateTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  RotateRightTerm ::
    (PEvalRotateTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  ToSignedTerm ::
    (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
    {-# UNPACK #-} !Id ->
    !(Term (u n)) ->
    Term (s n)
  ToUnsignedTerm ::
    (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
    {-# UNPACK #-} !Id ->
    !(Term (s n)) ->
    Term (u n)
  BVConcatTerm ::
    ( PEvalBVTerm bv,
      KnownNat l,
      KnownNat r,
      KnownNat (l + r),
      1 <= l,
      1 <= r,
      1 <= l + r
    ) =>
    {-# UNPACK #-} !Id ->
    !(Term (bv l)) ->
    !(Term (bv r)) ->
    Term (bv (l + r))
  BVSelectTerm ::
    ( PEvalBVTerm bv,
      KnownNat n,
      KnownNat ix,
      KnownNat w,
      1 <= n,
      1 <= w,
      ix + w <= n
    ) =>
    {-# UNPACK #-} !Id ->
    !(TypeRep ix) ->
    !(TypeRep w) ->
    !(Term (bv n)) ->
    Term (bv w)
  BVExtendTerm ::
    (PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
    {-# UNPACK #-} !Id ->
    !Bool ->
    !(TypeRep r) ->
    !(Term (bv l)) ->
    Term (bv r)
  ApplyTerm ::
    ( SupportedPrim a,
      SupportedPrim b,
      SupportedPrim f,
      PEvalApplyTerm f a b
    ) =>
    {-# UNPACK #-} !Id ->
    !(Term f) ->
    !(Term a) ->
    Term b
  DivIntegralTerm ::
    (PEvalDivModIntegralTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  ModIntegralTerm ::
    (PEvalDivModIntegralTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  QuotIntegralTerm ::
    (PEvalDivModIntegralTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t
  RemIntegralTerm ::
    (PEvalDivModIntegralTerm t) =>
    {-# UNPACK #-} !Id ->
    !(Term t) ->
    !(Term t) ->
    Term t

identity :: Term t -> Id
identity :: forall t. Term t -> Int
identity = (SomeTypeRep, Int) -> Int
forall a b. (a, b) -> b
snd ((SomeTypeRep, Int) -> Int)
-> (Term t -> (SomeTypeRep, Int)) -> Term t -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term t -> (SomeTypeRep, Int)
forall t. Term t -> (SomeTypeRep, Int)
identityWithTypeRep
{-# INLINE identity #-}

identityWithTypeRep :: forall t. Term t -> (SomeTypeRep, Id)
identityWithTypeRep :: forall t. Term t -> (SomeTypeRep, Int)
identityWithTypeRep (ConTerm Int
i t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (SymTerm Int
i TypedSymbol t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (UnaryTerm Int
i tag
_ Term arg
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (BinaryTerm Int
i tag
_ Term arg1
_ Term arg2
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (TernaryTerm Int
i tag
_ Term arg1
_ Term arg2
_ Term arg3
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (NotTerm Int
i Term Bool
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (OrTerm Int
i Term Bool
_ Term Bool
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (AndTerm Int
i Term Bool
_ Term Bool
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (EqTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ITETerm Int
i Term Bool
_ Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (AddNumTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (NegNumTerm Int
i Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (MulNumTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (AbsNumTerm Int
i Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (SignumNumTerm Int
i Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (LtOrdTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (LeOrdTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (AndBitsTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (OrBitsTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (XorBitsTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ComplementBitsTerm Int
i Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ShiftLeftTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ShiftRightTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (RotateLeftTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (RotateRightTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ToSignedTerm Int
i Term (u n)
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ToUnsignedTerm Int
i Term (s n)
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (BVConcatTerm Int
i Term (bv l)
_ Term (bv r)
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (BVSelectTerm Int
i TypeRep ix
_ TypeRep w
_ Term (bv n)
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (BVExtendTerm Int
i Bool
_ TypeRep r
_ Term (bv l)
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ApplyTerm Int
i Term f
_ Term a
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (DivIntegralTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (ModIntegralTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (QuotIntegralTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
identityWithTypeRep (RemIntegralTerm Int
i Term t
_ Term t
_) = (Proxy t -> SomeTypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> SomeTypeRep
someTypeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @t), Int
i)
{-# INLINE identityWithTypeRep #-}

introSupportedPrimConstraint :: forall t a. Term t -> ((SupportedPrim t) => a) -> a
introSupportedPrimConstraint :: forall t a. Term t -> (SupportedPrim t => a) -> a
introSupportedPrimConstraint ConTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint SymTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint UnaryTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint BinaryTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint TernaryTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint NotTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint OrTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint AndTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint EqTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ITETerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint AddNumTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint NegNumTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint MulNumTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint AbsNumTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint SignumNumTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint LtOrdTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint LeOrdTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint AndBitsTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint OrBitsTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint XorBitsTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ComplementBitsTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ShiftLeftTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint RotateLeftTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ShiftRightTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint RotateRightTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ToSignedTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ToUnsignedTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint BVConcatTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint BVSelectTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint BVExtendTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ApplyTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint DivIntegralTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint ModIntegralTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint QuotIntegralTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
introSupportedPrimConstraint RemIntegralTerm {} SupportedPrim t => a
x = a
SupportedPrim t => a
x
{-# INLINE introSupportedPrimConstraint #-}

pformat :: forall t. (SupportedPrim t) => Term t -> String
pformat :: forall t. SupportedPrim t => Term t -> String
pformat (ConTerm Int
_ t
t) = t -> String
forall t. SupportedPrim t => t -> String
pformatCon t
t
pformat (SymTerm Int
_ TypedSymbol t
sym) = TypedSymbol t -> String
forall t. SupportedPrim t => TypedSymbol t -> String
pformatSym TypedSymbol t
sym
pformat (UnaryTerm Int
_ tag
tag Term arg
arg1) = tag -> Term arg -> String
forall tag arg t. UnaryOp tag arg t => tag -> Term arg -> String
pformatUnary tag
tag Term arg
arg1
pformat (BinaryTerm Int
_ tag
tag Term arg1
arg1 Term arg2
arg2) = tag -> Term arg1 -> Term arg2 -> String
forall tag arg1 arg2 t.
BinaryOp tag arg1 arg2 t =>
tag -> Term arg1 -> Term arg2 -> String
pformatBinary tag
tag Term arg1
arg1 Term arg2
arg2
pformat (TernaryTerm Int
_ tag
tag Term arg1
arg1 Term arg2
arg2 Term arg3
arg3) = tag -> Term arg1 -> Term arg2 -> Term arg3 -> String
forall tag arg1 arg2 arg3 t.
TernaryOp tag arg1 arg2 arg3 t =>
tag -> Term arg1 -> Term arg2 -> Term arg3 -> String
pformatTernary tag
tag Term arg1
arg1 Term arg2
arg2 Term arg3
arg3
pformat (NotTerm Int
_ Term Bool
arg) = String
"(! " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (OrTerm Int
_ Term Bool
arg1 Term Bool
arg2) = String
"(|| " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (AndTerm Int
_ Term Bool
arg1 Term Bool
arg2) = String
"(&& " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (EqTerm Int
_ Term t
arg1 Term t
arg2) = String
"(= " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ITETerm Int
_ Term Bool
cond Term t
arg1 Term t
arg2) = String
"(ite " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall t. SupportedPrim t => Term t -> String
pformat Term Bool
cond String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (AddNumTerm Int
_ Term t
arg1 Term t
arg2) = String
"(+ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (NegNumTerm Int
_ Term t
arg) = String
"(- " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (MulNumTerm Int
_ Term t
arg1 Term t
arg2) = String
"(* " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (AbsNumTerm Int
_ Term t
arg) = String
"(abs " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (SignumNumTerm Int
_ Term t
arg) = String
"(signum " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (LtOrdTerm Int
_ Term t
arg1 Term t
arg2) = String
"(< " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (LeOrdTerm Int
_ Term t
arg1 Term t
arg2) = String
"(<= " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (AndBitsTerm Int
_ Term t
arg1 Term t
arg2) = String
"(& " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (OrBitsTerm Int
_ Term t
arg1 Term t
arg2) = String
"(| " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (XorBitsTerm Int
_ Term t
arg1 Term t
arg2) = String
"(^ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ComplementBitsTerm Int
_ Term t
arg) = String
"(~ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ShiftLeftTerm Int
_ Term t
arg Term t
n) = String
"(shl " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ShiftRightTerm Int
_ Term t
arg Term t
n) = String
"(shr " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (RotateLeftTerm Int
_ Term t
arg Term t
n) = String
"(rotl " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (RotateRightTerm Int
_ Term t
arg Term t
n) = String
"(rotr " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ToSignedTerm Int
_ Term (u n)
arg) = String
"(u2s " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (u n) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (u n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ToUnsignedTerm Int
_ Term (s n)
arg) = String
"(s2u " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (s n) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (s n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (BVConcatTerm Int
_ Term (bv l)
arg1 Term (bv r)
arg2) = String
"(bvconcat " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv l) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (bv l)
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv r) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (bv r)
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (BVSelectTerm Int
_ TypeRep ix
ix TypeRep w
w Term (bv n)
arg) = String
"(bvselect " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep ix -> String
forall a. Show a => a -> String
show TypeRep ix
ix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep w -> String
forall a. Show a => a -> String
show TypeRep w
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv n) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (bv n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (BVExtendTerm Int
_ Bool
signed TypeRep r
n Term (bv l)
arg) =
  (if Bool
signed then String
"(bvsext " else String
"(bvzext ") String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep r -> String
forall a. Show a => a -> String
show TypeRep r
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv l) -> String
forall t. SupportedPrim t => Term t -> String
pformat Term (bv l)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ApplyTerm Int
_ Term f
func Term a
arg) = String
"(apply " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term f -> String
forall t. SupportedPrim t => Term t -> String
pformat Term f
func String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term a -> String
forall t. SupportedPrim t => Term t -> String
pformat Term a
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (DivIntegralTerm Int
_ Term t
arg1 Term t
arg2) = String
"(div " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (ModIntegralTerm Int
_ Term t
arg1 Term t
arg2) = String
"(mod " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (QuotIntegralTerm Int
_ Term t
arg1 Term t
arg2) = String
"(quot " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
pformat (RemIntegralTerm Int
_ Term t
arg1 Term t
arg2) = String
"(rem " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
{-# INLINE pformat #-}

instance NFData (Term a) where
  rnf :: Term a -> ()
rnf Term a
i = Term a -> Int
forall t. Term t -> Int
identity Term a
i Int -> () -> ()
forall a b. a -> b -> b
`seq` ()

instance Lift (Term t) where
  liftTyped :: forall (m :: * -> *). Quote m => Term t -> Code m (Term t)
liftTyped (ConTerm Int
_ t
i) = [||t -> Term t
forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm t
i||]
  liftTyped (SymTerm Int
_ TypedSymbol t
sym) = [||Symbol -> Term t
forall t. (SupportedPrim t, Typeable t) => Symbol -> Term t
symTerm (TypedSymbol t -> Symbol
forall t. TypedSymbol t -> Symbol
unTypedSymbol TypedSymbol t
sym)||]
  liftTyped (UnaryTerm Int
_ tag
tag Term arg
arg) = [||tag -> Term arg -> Term t
forall tag arg t.
(SupportedPrim t, UnaryOp tag arg t, Typeable tag, Typeable t,
 Show tag) =>
tag -> Term arg -> Term t
constructUnary tag
tag Term arg
arg||]
  liftTyped (BinaryTerm Int
_ tag
tag Term arg1
arg1 Term arg2
arg2) = [||tag -> Term arg1 -> Term arg2 -> Term t
forall tag arg1 arg2 t.
(SupportedPrim t, BinaryOp tag arg1 arg2 t, Typeable tag,
 Typeable t, Show tag) =>
tag -> Term arg1 -> Term arg2 -> Term t
constructBinary tag
tag Term arg1
arg1 Term arg2
arg2||]
  liftTyped (TernaryTerm Int
_ tag
tag Term arg1
arg1 Term arg2
arg2 Term arg3
arg3) = [||tag -> Term arg1 -> Term arg2 -> Term arg3 -> Term t
forall tag arg1 arg2 arg3 t.
(SupportedPrim t, TernaryOp tag arg1 arg2 arg3 t, Typeable tag,
 Typeable t, Show tag) =>
tag -> Term arg1 -> Term arg2 -> Term arg3 -> Term t
constructTernary tag
tag Term arg1
arg1 Term arg2
arg2 Term arg3
arg3||]
  liftTyped (NotTerm Int
_ Term Bool
arg) = [||Term Bool -> Term Bool
notTerm Term Bool
arg||]
  liftTyped (OrTerm Int
_ Term Bool
arg1 Term Bool
arg2) = [||Term Bool -> Term Bool -> Term Bool
orTerm Term Bool
arg1 Term Bool
arg2||]
  liftTyped (AndTerm Int
_ Term Bool
arg1 Term Bool
arg2) = [||Term Bool -> Term Bool -> Term Bool
andTerm Term Bool
arg1 Term Bool
arg2||]
  liftTyped (EqTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
eqTerm Term t
arg1 Term t
arg2||]
  liftTyped (ITETerm Int
_ Term Bool
cond Term t
arg1 Term t
arg2) = [||Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
iteTerm Term Bool
cond Term t
arg1 Term t
arg2||]
  liftTyped (AddNumTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalNumTerm a => Term a -> Term a -> Term a
addNumTerm Term t
arg1 Term t
arg2||]
  liftTyped (NegNumTerm Int
_ Term t
arg) = [||Term a -> Term a
forall t. PEvalNumTerm t => Term t -> Term t
negNumTerm Term t
arg||]
  liftTyped (MulNumTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalNumTerm a => Term a -> Term a -> Term a
mulNumTerm Term t
arg1 Term t
arg2||]
  liftTyped (AbsNumTerm Int
_ Term t
arg) = [||Term a -> Term a
forall t. PEvalNumTerm t => Term t -> Term t
absNumTerm Term t
arg||]
  liftTyped (SignumNumTerm Int
_ Term t
arg) = [||Term a -> Term a
forall t. PEvalNumTerm t => Term t -> Term t
signumNumTerm Term t
arg||]
  liftTyped (LtOrdTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
ltOrdTerm Term t
arg1 Term t
arg2||]
  liftTyped (LeOrdTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
leOrdTerm Term t
arg1 Term t
arg2||]
  liftTyped (AndBitsTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
andBitsTerm Term t
arg1 Term t
arg2||]
  liftTyped (OrBitsTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
orBitsTerm Term t
arg1 Term t
arg2||]
  liftTyped (XorBitsTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
xorBitsTerm Term t
arg1 Term t
arg2||]
  liftTyped (ComplementBitsTerm Int
_ Term t
arg) = [||Term a -> Term a
forall a. PEvalBitwiseTerm a => Term a -> Term a
complementBitsTerm Term t
arg||]
  liftTyped (ShiftLeftTerm Int
_ Term t
arg Term t
n) = [||Term a -> Term a -> Term a
forall a. PEvalShiftTerm a => Term a -> Term a -> Term a
shiftLeftTerm Term t
arg Term t
n||]
  liftTyped (ShiftRightTerm Int
_ Term t
arg Term t
n) = [||Term a -> Term a -> Term a
forall a. PEvalShiftTerm a => Term a -> Term a -> Term a
shiftRightTerm Term t
arg Term t
n||]
  liftTyped (RotateLeftTerm Int
_ Term t
arg Term t
n) = [||Term a -> Term a -> Term a
forall a. PEvalRotateTerm a => Term a -> Term a -> Term a
rotateLeftTerm Term t
arg Term t
n||]
  liftTyped (RotateRightTerm Int
_ Term t
arg Term t
n) = [||Term a -> Term a -> Term a
forall a. PEvalRotateTerm a => Term a -> Term a -> Term a
rotateRightTerm Term t
arg Term t
n||]
  liftTyped (ToSignedTerm Int
_ Term (u n)
v) = [||Term (u n) -> Term (s n)
forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat).
(PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
Term (u n) -> Term (s n)
toSignedTerm Term (u n)
v||]
  liftTyped (ToUnsignedTerm Int
_ Term (s n)
v) = [||Term (s n) -> Term (u n)
forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat).
(PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
Term (s n) -> Term (u n)
toUnsignedTerm Term (s n)
v||]
  liftTyped (BVConcatTerm Int
_ Term (bv l)
arg1 Term (bv r)
arg2) = [||Term (bv l) -> Term (bv r) -> Term (bv (l + r))
forall (bv :: Nat -> *) (l :: Nat) (r :: Nat).
(PEvalBVTerm bv, KnownNat l, KnownNat r, KnownNat (l + r), 1 <= l,
 1 <= r, 1 <= (l + r)) =>
Term (bv l) -> Term (bv r) -> Term (bv (l + r))
bvconcatTerm Term (bv l)
arg1 Term (bv r)
arg2||]
  liftTyped (BVSelectTerm Int
_ (TypeRep ix
_ :: TypeRep ix) (TypeRep w
_ :: TypeRep w) Term (bv n)
arg) = [||p ix -> q w -> Term (bv n) -> Term (bv w)
forall (bv :: Nat -> *) (n :: Nat) (ix :: Nat) (w :: Nat)
       (p :: Nat -> *) (q :: Nat -> *).
(PEvalBVTerm bv, KnownNat n, KnownNat ix, KnownNat w, 1 <= n,
 1 <= w, (ix + w) <= n) =>
p ix -> q w -> Term (bv n) -> Term (bv w)
bvselectTerm (forall (t :: k). Proxy t
forall {k} (t :: k). Proxy t
Proxy @ix) (forall (t :: k). Proxy t
forall {k} (t :: k). Proxy t
Proxy @w) Term (bv n)
arg||]
  liftTyped (BVExtendTerm Int
_ Bool
signed (TypeRep r
_ :: TypeRep n) Term (bv l)
arg) = [||Bool -> proxy r -> Term (bv l) -> Term (bv r)
forall (bv :: Nat -> *) (l :: Nat) (r :: Nat) (proxy :: Nat -> *).
(PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
Bool -> proxy r -> Term (bv l) -> Term (bv r)
bvextendTerm Bool
signed (forall (t :: k). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) Term (bv l)
arg||]
  liftTyped (ApplyTerm Int
_ Term f
f Term a
arg) = [||Term f -> Term a -> Term b
forall a b f.
(SupportedPrim a, SupportedPrim b, SupportedPrim f,
 PEvalApplyTerm f a b) =>
Term f -> Term a -> Term b
applyTerm Term f
f Term a
arg||]
  liftTyped (DivIntegralTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
divIntegralTerm Term t
arg1 Term t
arg2||]
  liftTyped (ModIntegralTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
modIntegralTerm Term t
arg1 Term t
arg2||]
  liftTyped (QuotIntegralTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
quotIntegralTerm Term t
arg1 Term t
arg2||]
  liftTyped (RemIntegralTerm Int
_ Term t
arg1 Term t
arg2) = [||Term a -> Term a -> Term a
forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
remIntegralTerm Term t
arg1 Term t
arg2||]

instance Show (Term ty) where
  show :: Term ty -> String
show (ConTerm Int
i ty
v) = String
"ConTerm{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", v=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ ty -> String
forall a. Show a => a -> String
show ty
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (SymTerm Int
i TypedSymbol ty
name) =
    String
"SymTerm{id="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", name="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypedSymbol ty -> String
forall a. Show a => a -> String
show TypedSymbol ty
name
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", type="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep ty -> String
forall a. Show a => a -> String
show (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @ty)
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (UnaryTerm Int
i tag
tag Term arg
arg) = String
"Unary{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", tag=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ tag -> String
forall a. Show a => a -> String
show tag
tag String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg -> String
forall a. Show a => a -> String
show Term arg
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (BinaryTerm Int
i tag
tag Term arg1
arg1 Term arg2
arg2) =
    String
"Binary{id="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", tag="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ tag -> String
forall a. Show a => a -> String
show tag
tag
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg1 -> String
forall a. Show a => a -> String
show Term arg1
arg1
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg2 -> String
forall a. Show a => a -> String
show Term arg2
arg2
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (TernaryTerm Int
i tag
tag Term arg1
arg1 Term arg2
arg2 Term arg3
arg3) =
    String
"Ternary{id="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", tag="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ tag -> String
forall a. Show a => a -> String
show tag
tag
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg1 -> String
forall a. Show a => a -> String
show Term arg1
arg1
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg2 -> String
forall a. Show a => a -> String
show Term arg2
arg2
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg3="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term arg3 -> String
forall a. Show a => a -> String
show Term arg3
arg3
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (NotTerm Int
i Term Bool
arg) = String
"Not{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (OrTerm Int
i Term Bool
arg1 Term Bool
arg2) = String
"Or{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (AndTerm Int
i Term Bool
arg1 Term Bool
arg2) = String
"And{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (EqTerm Int
i Term t
arg1 Term t
arg2) = String
"Eqv{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ITETerm Int
i Term Bool
cond Term ty
l Term ty
r) =
    String
"ITE{id="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", cond="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term Bool -> String
forall a. Show a => a -> String
show Term Bool
cond
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", then="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
l
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", else="
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
r
      String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (AddNumTerm Int
i Term ty
arg1 Term ty
arg2) = String
"AddNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (NegNumTerm Int
i Term ty
arg) = String
"NegNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (MulNumTerm Int
i Term ty
arg1 Term ty
arg2) = String
"MulNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (AbsNumTerm Int
i Term ty
arg) = String
"AbsNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (SignumNumTerm Int
i Term ty
arg) = String
"SignumNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (LtOrdTerm Int
i Term t
arg1 Term t
arg2) = String
"LTNum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (LeOrdTerm Int
i Term t
arg1 Term t
arg2) = String
"LENum{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term t -> String
forall a. Show a => a -> String
show Term t
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (AndBitsTerm Int
i Term ty
arg1 Term ty
arg2) = String
"AndBits{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (OrBitsTerm Int
i Term ty
arg1 Term ty
arg2) = String
"OrBits{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (XorBitsTerm Int
i Term ty
arg1 Term ty
arg2) = String
"XorBits{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ComplementBitsTerm Int
i Term ty
arg) = String
"ComplementBits{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ShiftLeftTerm Int
i Term ty
arg Term ty
n) = String
"ShiftLeft{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", n=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ShiftRightTerm Int
i Term ty
arg Term ty
n) = String
"ShiftRight{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", n=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (RotateLeftTerm Int
i Term ty
arg Term ty
n) = String
"RotateLeft{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", n=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (RotateRightTerm Int
i Term ty
arg Term ty
n) = String
"RotateRight{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", n=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ToSignedTerm Int
i Term (u n)
arg) = String
"ToSigned{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (u n) -> String
forall a. Show a => a -> String
show Term (u n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ToUnsignedTerm Int
i Term (s n)
arg) = String
"ToUnsigned{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (s n) -> String
forall a. Show a => a -> String
show Term (s n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (BVConcatTerm Int
i Term (bv l)
arg1 Term (bv r)
arg2) = String
"BVConcat{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv l) -> String
forall a. Show a => a -> String
show Term (bv l)
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv r) -> String
forall a. Show a => a -> String
show Term (bv r)
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (BVSelectTerm Int
i TypeRep ix
ix TypeRep w
w Term (bv n)
arg) =
    String
"BVSelect{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", ix=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep ix -> String
forall a. Show a => a -> String
show TypeRep ix
ix String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", w=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep w -> String
forall a. Show a => a -> String
show TypeRep w
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv n) -> String
forall a. Show a => a -> String
show Term (bv n)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (BVExtendTerm Int
i Bool
signed TypeRep r
n Term (bv l)
arg) =
    String
"BVExtend{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", signed=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show Bool
signed String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", n=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep r -> String
forall a. Show a => a -> String
show TypeRep r
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term (bv l) -> String
forall a. Show a => a -> String
show Term (bv l)
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ApplyTerm Int
i Term f
f Term a
arg) =
    String
"Apply{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", f=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term f -> String
forall a. Show a => a -> String
show Term f
f String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term a -> String
forall a. Show a => a -> String
show Term a
arg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (DivIntegralTerm Int
i Term ty
arg1 Term ty
arg2) =
    String
"DivIntegral{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (ModIntegralTerm Int
i Term ty
arg1 Term ty
arg2) =
    String
"ModIntegral{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (QuotIntegralTerm Int
i Term ty
arg1 Term ty
arg2) =
    String
"QuotIntegral{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
  show (RemIntegralTerm Int
i Term ty
arg1 Term ty
arg2) =
    String
"RemIntegral{id=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg1=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", arg2=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Term ty -> String
forall a. Show a => a -> String
show Term ty
arg2 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"

prettyPrintTerm :: Term t -> Doc ann
prettyPrintTerm :: forall t ann. Term t -> Doc ann
prettyPrintTerm Term t
v =
  (Int -> Doc ann) -> Doc ann
forall ann. (Int -> Doc ann) -> Doc ann
column
    ( \Int
c ->
        (PageWidth -> Doc ann) -> Doc ann
forall ann. (PageWidth -> Doc ann) -> Doc ann
pageWidth ((PageWidth -> Doc ann) -> Doc ann)
-> (PageWidth -> Doc ann) -> Doc ann
forall a b. (a -> b) -> a -> b
$ \case
          AvailablePerLine Int
i Double
r ->
            if Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
r
              then Doc ann
"..."
              else String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty String
formatted
          PageWidth
Unbounded -> String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty String
formatted
    )
  where
    formatted :: String
formatted = Term t -> (SupportedPrim t => String) -> String
forall t a. Term t -> (SupportedPrim t => a) -> a
introSupportedPrimConstraint Term t
v ((SupportedPrim t => String) -> String)
-> (SupportedPrim t => String) -> String
forall a b. (a -> b) -> a -> b
$ Term t -> String
forall t. SupportedPrim t => Term t -> String
pformat Term t
v
    len :: Int
len = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
formatted

instance (SupportedPrim t) => Eq (Term t) where
  == :: Term t -> Term t -> Bool
(==) = Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Int -> Int -> Bool) -> (Term t -> Int) -> Term t -> Term t -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Term t -> Int
forall t. Term t -> Int
identity

instance (SupportedPrim t) => Hashable (Term t) where
  hashWithSalt :: Int -> Term t -> Int
hashWithSalt Int
s Term t
t = Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Term t -> Int
forall t. Term t -> Int
identity Term t
t

-- Interning

data UTerm t where
  UConTerm :: (SupportedPrim t) => !t -> UTerm t
  USymTerm :: (SupportedPrim t) => !(TypedSymbol t) -> UTerm t
  UUnaryTerm :: (UnaryOp tag arg t) => !tag -> !(Term arg) -> UTerm t
  UBinaryTerm ::
    (BinaryOp tag arg1 arg2 t) =>
    !tag ->
    !(Term arg1) ->
    !(Term arg2) ->
    UTerm t
  UTernaryTerm ::
    (TernaryOp tag arg1 arg2 arg3 t) =>
    !tag ->
    !(Term arg1) ->
    !(Term arg2) ->
    !(Term arg3) ->
    UTerm t
  UNotTerm :: !(Term Bool) -> UTerm Bool
  UOrTerm :: !(Term Bool) -> !(Term Bool) -> UTerm Bool
  UAndTerm :: !(Term Bool) -> !(Term Bool) -> UTerm Bool
  UEqTerm :: (SupportedPrim t) => !(Term t) -> !(Term t) -> UTerm Bool
  UITETerm ::
    (SupportedPrim t) =>
    !(Term Bool) ->
    !(Term t) ->
    !(Term t) ->
    UTerm t
  UAddNumTerm :: (PEvalNumTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UNegNumTerm :: (PEvalNumTerm t) => !(Term t) -> UTerm t
  UMulNumTerm :: (PEvalNumTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UAbsNumTerm :: (PEvalNumTerm t) => !(Term t) -> UTerm t
  USignumNumTerm :: (PEvalNumTerm t) => !(Term t) -> UTerm t
  ULtOrdTerm :: (PEvalOrdTerm t) => !(Term t) -> !(Term t) -> UTerm Bool
  ULeOrdTerm :: (PEvalOrdTerm t) => !(Term t) -> !(Term t) -> UTerm Bool
  UAndBitsTerm :: (PEvalBitwiseTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UOrBitsTerm :: (PEvalBitwiseTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UXorBitsTerm :: (PEvalBitwiseTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UComplementBitsTerm :: (PEvalBitwiseTerm t) => !(Term t) -> UTerm t
  UShiftLeftTerm :: (PEvalShiftTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UShiftRightTerm :: (PEvalShiftTerm t) => !(Term t) -> !(Term t) -> UTerm t
  URotateLeftTerm :: (PEvalRotateTerm t) => !(Term t) -> !(Term t) -> UTerm t
  URotateRightTerm :: (PEvalRotateTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UToSignedTerm ::
    (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
    !(Term (u n)) ->
    UTerm (s n)
  UToUnsignedTerm ::
    (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
    !(Term (s n)) ->
    UTerm (u n)
  UBVConcatTerm ::
    ( PEvalBVTerm bv,
      KnownNat l,
      KnownNat r,
      KnownNat (l + r),
      1 <= l,
      1 <= r,
      1 <= l + r
    ) =>
    !(Term (bv l)) ->
    !(Term (bv r)) ->
    UTerm (bv (l + r))
  UBVSelectTerm ::
    ( PEvalBVTerm bv,
      KnownNat n,
      KnownNat ix,
      KnownNat w,
      1 <= n,
      1 <= w,
      ix + w <= n
    ) =>
    !(TypeRep ix) ->
    !(TypeRep w) ->
    !(Term (bv n)) ->
    UTerm (bv w)
  UBVExtendTerm ::
    (PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
    !Bool ->
    !(TypeRep r) ->
    !(Term (bv l)) ->
    UTerm (bv r)
  UApplyTerm ::
    ( SupportedPrim a,
      SupportedPrim b,
      SupportedPrim f,
      PEvalApplyTerm f a b
    ) =>
    Term f ->
    Term a ->
    UTerm b
  UDivIntegralTerm ::
    (PEvalDivModIntegralTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UModIntegralTerm ::
    (PEvalDivModIntegralTerm t) => !(Term t) -> !(Term t) -> UTerm t
  UQuotIntegralTerm ::
    (PEvalDivModIntegralTerm t) => !(Term t) -> !(Term t) -> UTerm t
  URemIntegralTerm ::
    (PEvalDivModIntegralTerm t) => !(Term t) -> !(Term t) -> UTerm t

eqTypedId :: (TypeRep a, Id) -> (TypeRep b, Id) -> Bool
eqTypedId :: forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep a
a, Int
i1) (TypeRep b
b, Int
i2) = Int
i1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i2 Bool -> Bool -> Bool
&& TypeRep a -> TypeRep b -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep a
a TypeRep b
b
{-# INLINE eqTypedId #-}

eqHeteroTag :: (Eq a) => (TypeRep a, a) -> (TypeRep b, b) -> Bool
eqHeteroTag :: forall a b. Eq a => (TypeRep a, a) -> (TypeRep b, b) -> Bool
eqHeteroTag (TypeRep a
tpa, a
taga) (TypeRep b
tpb, b
tagb) = TypeRep a -> TypeRep b -> a -> b -> Bool
forall a b. Eq a => TypeRep a -> TypeRep b -> a -> b -> Bool
eqHeteroRep TypeRep a
tpa TypeRep b
tpb a
taga b
tagb
{-# INLINE eqHeteroTag #-}

instance (SupportedPrim t) => Interned (Term t) where
  type Uninterned (Term t) = UTerm t
  data Description (Term t) where
    DConTerm :: t -> Description (Term t)
    DSymTerm :: TypedSymbol t -> Description (Term t)
    DUnaryTerm ::
      (Eq tag, Hashable tag) =>
      {-# UNPACK #-} !(TypeRep tag, tag) ->
      {-# UNPACK #-} !(TypeRep arg, Id) ->
      Description (Term t)
    DBinaryTerm ::
      (Eq tag, Hashable tag) =>
      {-# UNPACK #-} !(TypeRep tag, tag) ->
      {-# UNPACK #-} !(TypeRep arg1, Id) ->
      {-# UNPACK #-} !(TypeRep arg2, Id) ->
      Description (Term t)
    DTernaryTerm ::
      (Eq tag, Hashable tag) =>
      {-# UNPACK #-} !(TypeRep tag, tag) ->
      {-# UNPACK #-} !(TypeRep arg1, Id) ->
      {-# UNPACK #-} !(TypeRep arg2, Id) ->
      {-# UNPACK #-} !(TypeRep arg3, Id) ->
      Description (Term t)
    DNotTerm :: {-# UNPACK #-} !Id -> Description (Term Bool)
    DOrTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term Bool)
    DAndTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term Bool)
    DEqTerm :: TypeRep args -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term Bool)
    DITETerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DAddNumTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DNegNumTerm :: {-# UNPACK #-} !Id -> Description (Term t)
    DMulNumTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DAbsNumTerm :: {-# UNPACK #-} !Id -> Description (Term t)
    DSignumNumTerm :: {-# UNPACK #-} !Id -> Description (Term t)
    DLtOrdTerm :: TypeRep args -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term Bool)
    DLeOrdTerm :: TypeRep args -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term Bool)
    DAndBitsTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DOrBitsTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DXorBitsTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DComplementBitsTerm :: {-# UNPACK #-} !Id -> Description (Term t)
    DShiftLeftTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DShiftRightTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DRotateLeftTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DRotateRightTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DBVConcatTerm :: TypeRep bv1 -> TypeRep bv2 -> {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term t)
    DToSignedTerm ::
      !(TypeRep u, Id) ->
      Description (Term s)
    DToUnsignedTerm ::
      !(TypeRep s, Id) ->
      Description (Term u)
    DBVSelectTerm ::
      forall bv (n :: Nat) (w :: Nat) (ix :: Nat).
      !(TypeRep ix) ->
      !(TypeRep (bv n), Id) ->
      Description (Term (bv w))
    DBVExtendTerm ::
      forall bv (l :: Nat) (r :: Nat).
      !Bool ->
      !(TypeRep r) ->
      {-# UNPACK #-} !(TypeRep (bv l), Id) ->
      Description (Term (bv r))
    DApplyTerm ::
      ( PEvalApplyTerm f a b
      ) =>
      {-# UNPACK #-} !(TypeRep f, Id) ->
      {-# UNPACK #-} !(TypeRep a, Id) ->
      Description (Term b)
    DDivIntegralTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term a)
    DModIntegralTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term a)
    DQuotIntegralTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term a)
    DRemIntegralTerm :: {-# UNPACK #-} !Id -> {-# UNPACK #-} !Id -> Description (Term a)

  describe :: Uninterned (Term t) -> Description (Term t)
describe (UConTerm t
v) = t -> Description (Term t)
forall t. t -> Description (Term t)
DConTerm t
v
  describe ((USymTerm TypedSymbol t
name) :: UTerm t) = forall t. TypedSymbol t -> Description (Term t)
DSymTerm @t TypedSymbol t
name
  describe ((UUnaryTerm (tag
tag :: tagt) (Term arg
tm :: Term arg)) :: UTerm t) =
    (TypeRep tag, tag) -> (TypeRep arg, Int) -> Description (Term t)
forall a f t.
(Eq a, Hashable a) =>
(TypeRep a, a) -> (TypeRep f, Int) -> Description (Term t)
DUnaryTerm (TypeRep tag
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, tag
tag) (TypeRep arg
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg, Term arg -> Int
forall t. Term t -> Int
identity Term arg
tm)
  describe ((UBinaryTerm (tag
tag :: tagt) (Term arg1
tm1 :: Term arg1) (Term arg2
tm2 :: Term arg2)) :: UTerm t) =
    forall a f r t.
(Eq a, Hashable a) =>
(TypeRep a, a)
-> (TypeRep f, Int) -> (TypeRep r, Int) -> Description (Term t)
DBinaryTerm @tagt @arg1 @arg2 @t (TypeRep tag
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, tag
tag) (TypeRep arg1
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, Term arg1 -> Int
forall t. Term t -> Int
identity Term arg1
tm1) (TypeRep arg2
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, Term arg2 -> Int
forall t. Term t -> Int
identity Term arg2
tm2)
  describe ((UTernaryTerm (tag
tag :: tagt) (Term arg1
tm1 :: Term arg1) (Term arg2
tm2 :: Term arg2) (Term arg3
tm3 :: Term arg3)) :: UTerm t) =
    forall a f r w t.
(Eq a, Hashable a) =>
(TypeRep a, a)
-> (TypeRep f, Int)
-> (TypeRep r, Int)
-> (TypeRep w, Int)
-> Description (Term t)
DTernaryTerm @tagt @arg1 @arg2 @arg3 @t
      (TypeRep tag
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, tag
tag)
      (TypeRep arg1
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, Term arg1 -> Int
forall t. Term t -> Int
identity Term arg1
tm1)
      (TypeRep arg2
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, Term arg2 -> Int
forall t. Term t -> Int
identity Term arg2
tm2)
      (TypeRep arg3
forall {k} (a :: k). Typeable a => TypeRep a
typeRep, Term arg3 -> Int
forall t. Term t -> Int
identity Term arg3
tm3)
  describe (UNotTerm Term Bool
arg) = Int -> Description (Term Bool)
DNotTerm (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
arg)
  describe (UOrTerm Term Bool
arg1 Term Bool
arg2) = Int -> Int -> Description (Term Bool)
DOrTerm (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
arg1) (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
arg2)
  describe (UAndTerm Term Bool
arg1 Term Bool
arg2) = Int -> Int -> Description (Term Bool)
DAndTerm (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
arg1) (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
arg2)
  describe (UEqTerm (Term t
arg1 :: Term arg) Term t
arg2) = TypeRep t -> Int -> Int -> Description (Term Bool)
forall a. TypeRep a -> Int -> Int -> Description (Term Bool)
DEqTerm (TypeRep t
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UITETerm Term Bool
cond (Term t
l :: Term arg) Term t
r) = Int -> Int -> Int -> Description (Term t)
forall t. Int -> Int -> Int -> Description (Term t)
DITETerm (Term Bool -> Int
forall t. Term t -> Int
identity Term Bool
cond) (Term t -> Int
forall t. Term t -> Int
identity Term t
l) (Term t -> Int
forall t. Term t -> Int
identity Term t
r)
  describe (UAddNumTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DAddNumTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UNegNumTerm Term t
arg) = Int -> Description (Term t)
forall t. Int -> Description (Term t)
DNegNumTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg)
  describe (UMulNumTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DMulNumTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UAbsNumTerm Term t
arg) = Int -> Description (Term t)
forall t. Int -> Description (Term t)
DAbsNumTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg)
  describe (USignumNumTerm Term t
arg) = Int -> Description (Term t)
forall t. Int -> Description (Term t)
DSignumNumTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg)
  describe (ULtOrdTerm (Term t
arg1 :: arg) Term t
arg2) = TypeRep (Term t) -> Int -> Int -> Description (Term Bool)
forall a. TypeRep a -> Int -> Int -> Description (Term Bool)
DLtOrdTerm (TypeRep (Term t)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (ULeOrdTerm (Term t
arg1 :: arg) Term t
arg2) = TypeRep (Term t) -> Int -> Int -> Description (Term Bool)
forall a. TypeRep a -> Int -> Int -> Description (Term Bool)
DLeOrdTerm (TypeRep (Term t)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UAndBitsTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DAndBitsTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UOrBitsTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DOrBitsTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UXorBitsTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DXorBitsTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UComplementBitsTerm Term t
arg) = Int -> Description (Term t)
forall t. Int -> Description (Term t)
DComplementBitsTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg)
  describe (UShiftLeftTerm Term t
arg Term t
n) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DShiftLeftTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
n)
  describe (UShiftRightTerm Term t
arg Term t
n) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DShiftRightTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
n)
  describe (URotateLeftTerm Term t
arg Term t
n) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DRotateLeftTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
n)
  describe (URotateRightTerm Term t
arg Term t
n) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DRotateRightTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg) (Term t -> Int
forall t. Term t -> Int
identity Term t
n)
  describe (UToSignedTerm (Term (u n)
arg :: Term bv)) = (TypeRep (u n), Int) -> Description (Term t)
forall a s. (TypeRep a, Int) -> Description (Term s)
DToSignedTerm (TypeRep (u n)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep bv, Term (u n) -> Int
forall t. Term t -> Int
identity Term (u n)
arg)
  describe (UToUnsignedTerm (Term (s n)
arg :: Term bv)) = (TypeRep (s n), Int) -> Description (Term t)
forall a s. (TypeRep a, Int) -> Description (Term s)
DToSignedTerm (TypeRep (s n)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep bv, Term (s n) -> Int
forall t. Term t -> Int
identity Term (s n)
arg)
  describe (UBVConcatTerm (Term (bv l)
arg1 :: bv1) (Term (bv r)
arg2 :: bv2)) =
    TypeRep (Term (bv l))
-> TypeRep (Term (bv r)) -> Int -> Int -> Description (Term t)
forall a f t.
TypeRep a -> TypeRep f -> Int -> Int -> Description (Term t)
DBVConcatTerm (TypeRep (Term (bv l))
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep bv1) (TypeRep (Term (bv r))
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep bv2) (Term (bv l) -> Int
forall t. Term t -> Int
identity Term (bv l)
arg1) (Term (bv r) -> Int
forall t. Term t -> Int
identity Term (bv r)
arg2)
  describe (UBVSelectTerm (TypeRep ix
ix :: TypeRep ix) TypeRep w
_ (Term (bv n)
arg :: Term arg)) =
    TypeRep ix -> (TypeRep (bv n), Int) -> Description (Term (bv w))
forall (a :: Nat -> *) (f :: Nat) (r :: Nat) (w :: Nat).
TypeRep w -> (TypeRep (a f), Int) -> Description (Term (a r))
DBVSelectTerm TypeRep ix
ix (TypeRep (bv n)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg, Term (bv n) -> Int
forall t. Term t -> Int
identity Term (bv n)
arg)
  describe (UBVExtendTerm Bool
signed (TypeRep r
n :: TypeRep n) (Term (bv l)
arg :: Term arg)) =
    Bool
-> TypeRep r -> (TypeRep (bv l), Int) -> Description (Term (bv r))
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
Bool
-> TypeRep r -> (TypeRep (a f), Int) -> Description (Term (a r))
DBVExtendTerm Bool
signed TypeRep r
n (TypeRep (bv l)
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep arg, Term (bv l) -> Int
forall t. Term t -> Int
identity Term (bv l)
arg)
  describe (UApplyTerm (Term f
f :: Term f) (Term a
arg :: Term a)) =
    (TypeRep f, Int) -> (TypeRep a, Int) -> Description (Term t)
forall a f b.
PEvalApplyTerm a f b =>
(TypeRep a, Int) -> (TypeRep f, Int) -> Description (Term b)
DApplyTerm (TypeRep f
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep f, Term f -> Int
forall t. Term t -> Int
identity Term f
f) (TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep :: TypeRep a, Term a -> Int
forall t. Term t -> Int
identity Term a
arg)
  describe (UDivIntegralTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DDivIntegralTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UModIntegralTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DModIntegralTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (UQuotIntegralTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DRemIntegralTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)
  describe (URemIntegralTerm Term t
arg1 Term t
arg2) = Int -> Int -> Description (Term t)
forall t. Int -> Int -> Description (Term t)
DQuotIntegralTerm (Term t -> Int
forall t. Term t -> Int
identity Term t
arg1) (Term t -> Int
forall t. Term t -> Int
identity Term t
arg2)

  identify :: Int -> Uninterned (Term t) -> Term t
identify Int
i = Uninterned (Term t) -> Term t
UTerm t -> Term t
go
    where
      go :: UTerm t -> Term t
go (UConTerm t
v) = Int -> t -> Term t
forall t. SupportedPrim t => Int -> t -> Term t
ConTerm Int
i t
v
      go (USymTerm TypedSymbol t
v) = Int -> TypedSymbol t -> Term t
forall t. SupportedPrim t => Int -> TypedSymbol t -> Term t
SymTerm Int
i TypedSymbol t
v
      go (UUnaryTerm tag
tag Term arg
tm) = Int -> tag -> Term arg -> Term t
forall a f t. UnaryOp a f t => Int -> a -> Term f -> Term t
UnaryTerm Int
i tag
tag Term arg
tm
      go (UBinaryTerm tag
tag Term arg1
tm1 Term arg2
tm2) = Int -> tag -> Term arg1 -> Term arg2 -> Term t
forall a f r t.
BinaryOp a f r t =>
Int -> a -> Term f -> Term r -> Term t
BinaryTerm Int
i tag
tag Term arg1
tm1 Term arg2
tm2
      go (UTernaryTerm tag
tag Term arg1
tm1 Term arg2
tm2 Term arg3
tm3) = Int -> tag -> Term arg1 -> Term arg2 -> Term arg3 -> Term t
forall a f r w t.
TernaryOp a f r w t =>
Int -> a -> Term f -> Term r -> Term w -> Term t
TernaryTerm Int
i tag
tag Term arg1
tm1 Term arg2
tm2 Term arg3
tm3
      go (UNotTerm Term Bool
arg) = Int -> Term Bool -> Term Bool
NotTerm Int
i Term Bool
arg
      go (UOrTerm Term Bool
arg1 Term Bool
arg2) = Int -> Term Bool -> Term Bool -> Term Bool
OrTerm Int
i Term Bool
arg1 Term Bool
arg2
      go (UAndTerm Term Bool
arg1 Term Bool
arg2) = Int -> Term Bool -> Term Bool -> Term Bool
AndTerm Int
i Term Bool
arg1 Term Bool
arg2
      go (UEqTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term Bool
forall a. SupportedPrim a => Int -> Term a -> Term a -> Term Bool
EqTerm Int
i Term t
arg1 Term t
arg2
      go (UITETerm Term Bool
cond Term t
l Term t
r) = Int -> Term Bool -> Term t -> Term t -> Term t
forall t.
SupportedPrim t =>
Int -> Term Bool -> Term t -> Term t -> Term t
ITETerm Int
i Term Bool
cond Term t
l Term t
r
      go (UAddNumTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t. PEvalNumTerm t => Int -> Term t -> Term t -> Term t
AddNumTerm Int
i Term t
arg1 Term t
arg2
      go (UNegNumTerm Term t
arg) = Int -> Term t -> Term t
forall t. PEvalNumTerm t => Int -> Term t -> Term t
NegNumTerm Int
i Term t
arg
      go (UMulNumTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t. PEvalNumTerm t => Int -> Term t -> Term t -> Term t
MulNumTerm Int
i Term t
arg1 Term t
arg2
      go (UAbsNumTerm Term t
arg) = Int -> Term t -> Term t
forall t. PEvalNumTerm t => Int -> Term t -> Term t
AbsNumTerm Int
i Term t
arg
      go (USignumNumTerm Term t
arg) = Int -> Term t -> Term t
forall t. PEvalNumTerm t => Int -> Term t -> Term t
SignumNumTerm Int
i Term t
arg
      go (ULtOrdTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term Bool
forall a. PEvalOrdTerm a => Int -> Term a -> Term a -> Term Bool
LtOrdTerm Int
i Term t
arg1 Term t
arg2
      go (ULeOrdTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term Bool
forall a. PEvalOrdTerm a => Int -> Term a -> Term a -> Term Bool
LeOrdTerm Int
i Term t
arg1 Term t
arg2
      go (UAndBitsTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t. PEvalBitwiseTerm t => Int -> Term t -> Term t -> Term t
AndBitsTerm Int
i Term t
arg1 Term t
arg2
      go (UOrBitsTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t. PEvalBitwiseTerm t => Int -> Term t -> Term t -> Term t
OrBitsTerm Int
i Term t
arg1 Term t
arg2
      go (UXorBitsTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t. PEvalBitwiseTerm t => Int -> Term t -> Term t -> Term t
XorBitsTerm Int
i Term t
arg1 Term t
arg2
      go (UComplementBitsTerm Term t
arg) = Int -> Term t -> Term t
forall t. PEvalBitwiseTerm t => Int -> Term t -> Term t
ComplementBitsTerm Int
i Term t
arg
      go (UShiftLeftTerm Term t
arg Term t
n) = Int -> Term t -> Term t -> Term t
forall t. PEvalShiftTerm t => Int -> Term t -> Term t -> Term t
ShiftLeftTerm Int
i Term t
arg Term t
n
      go (UShiftRightTerm Term t
arg Term t
n) = Int -> Term t -> Term t -> Term t
forall t. PEvalShiftTerm t => Int -> Term t -> Term t -> Term t
ShiftRightTerm Int
i Term t
arg Term t
n
      go (URotateLeftTerm Term t
arg Term t
n) = Int -> Term t -> Term t -> Term t
forall t. PEvalRotateTerm t => Int -> Term t -> Term t -> Term t
RotateLeftTerm Int
i Term t
arg Term t
n
      go (URotateRightTerm Term t
arg Term t
n) = Int -> Term t -> Term t -> Term t
forall t. PEvalRotateTerm t => Int -> Term t -> Term t -> Term t
RotateRightTerm Int
i Term t
arg Term t
n
      go (UToSignedTerm Term (u n)
arg) = Int -> Term (u n) -> Term (s n)
forall (a :: Nat -> *) (f :: Nat -> *) (r :: Nat).
(PEvalBVSignConversionTerm a f, KnownNat r, 1 <= r) =>
Int -> Term (a r) -> Term (f r)
ToSignedTerm Int
i Term (u n)
arg
      go (UToUnsignedTerm Term (s n)
arg) = Int -> Term (s n) -> Term (u n)
forall (a :: Nat -> *) (f :: Nat -> *) (r :: Nat).
(PEvalBVSignConversionTerm a f, KnownNat r, 1 <= r) =>
Int -> Term (f r) -> Term (a r)
ToUnsignedTerm Int
i Term (s n)
arg
      go (UBVConcatTerm Term (bv l)
arg1 Term (bv r)
arg2) = Int -> Term (bv l) -> Term (bv r) -> Term (bv (l + r))
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, KnownNat (f + r), 1 <= f,
 1 <= r, 1 <= (f + r)) =>
Int -> Term (a f) -> Term (a r) -> Term (a (f + r))
BVConcatTerm Int
i Term (bv l)
arg1 Term (bv r)
arg2
      go (UBVSelectTerm TypeRep ix
ix TypeRep w
w Term (bv n)
arg) = Int -> TypeRep ix -> TypeRep w -> Term (bv n) -> Term (bv w)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat) (w :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, KnownNat w, 1 <= f, 1 <= w,
 (r + w) <= f) =>
Int -> TypeRep r -> TypeRep w -> Term (a f) -> Term (a w)
BVSelectTerm Int
i TypeRep ix
ix TypeRep w
w Term (bv n)
arg
      go (UBVExtendTerm Bool
signed TypeRep r
n Term (bv l)
arg) = Int -> Bool -> TypeRep r -> Term (bv l) -> Term (bv r)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, 1 <= f, 1 <= r, f <= r) =>
Int -> Bool -> TypeRep r -> Term (a f) -> Term (a r)
BVExtendTerm Int
i Bool
signed TypeRep r
n Term (bv l)
arg
      go (UApplyTerm Term f
f Term a
arg) = Int -> Term f -> Term a -> Term t
forall a b f.
(SupportedPrim a, SupportedPrim b, SupportedPrim f,
 PEvalApplyTerm f a b) =>
Int -> Term f -> Term a -> Term b
ApplyTerm Int
i Term f
f Term a
arg
      go (UDivIntegralTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t.
PEvalDivModIntegralTerm t =>
Int -> Term t -> Term t -> Term t
DivIntegralTerm Int
i Term t
arg1 Term t
arg2
      go (UModIntegralTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t.
PEvalDivModIntegralTerm t =>
Int -> Term t -> Term t -> Term t
ModIntegralTerm Int
i Term t
arg1 Term t
arg2
      go (UQuotIntegralTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t.
PEvalDivModIntegralTerm t =>
Int -> Term t -> Term t -> Term t
QuotIntegralTerm Int
i Term t
arg1 Term t
arg2
      go (URemIntegralTerm Term t
arg1 Term t
arg2) = Int -> Term t -> Term t -> Term t
forall t.
PEvalDivModIntegralTerm t =>
Int -> Term t -> Term t -> Term t
RemIntegralTerm Int
i Term t
arg1 Term t
arg2
  cache :: Cache (Term t)
cache = Cache (Term t)
forall t. SupportedPrim t => Cache (Term t)
termCache

instance (SupportedPrim t) => Eq (Description (Term t)) where
  DConTerm (t
l :: tyl) == :: Description (Term t) -> Description (Term t) -> Bool
== DConTerm (t
r :: tyr) = forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast @tyl @tyr t
l Maybe t -> Maybe t -> Bool
forall a. Eq a => a -> a -> Bool
== t -> Maybe t
forall a. a -> Maybe a
Just t
r
  DSymTerm TypedSymbol t
ls == DSymTerm TypedSymbol t
rs = TypedSymbol t
ls TypedSymbol t -> TypedSymbol t -> Bool
forall a. Eq a => a -> a -> Bool
== TypedSymbol t
rs
  DUnaryTerm ((TypeRep tag, tag)
tagl :: tagl) (TypeRep arg, Int)
li == DUnaryTerm ((TypeRep tag, tag)
tagr :: tagr) (TypeRep arg, Int)
ri = (TypeRep tag, tag) -> (TypeRep tag, tag) -> Bool
forall a b. Eq a => (TypeRep a, a) -> (TypeRep b, b) -> Bool
eqHeteroTag (TypeRep tag, tag)
tagl (TypeRep tag, tag)
tagr Bool -> Bool -> Bool
&& (TypeRep arg, Int) -> (TypeRep arg, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg, Int)
li (TypeRep arg, Int)
ri
  DBinaryTerm ((TypeRep tag, tag)
tagl :: tagl) (TypeRep arg1, Int)
li1 (TypeRep arg2, Int)
li2 == DBinaryTerm ((TypeRep tag, tag)
tagr :: tagr) (TypeRep arg1, Int)
ri1 (TypeRep arg2, Int)
ri2 =
    (TypeRep tag, tag) -> (TypeRep tag, tag) -> Bool
forall a b. Eq a => (TypeRep a, a) -> (TypeRep b, b) -> Bool
eqHeteroTag (TypeRep tag, tag)
tagl (TypeRep tag, tag)
tagr Bool -> Bool -> Bool
&& (TypeRep arg1, Int) -> (TypeRep arg1, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg1, Int)
li1 (TypeRep arg1, Int)
ri1 Bool -> Bool -> Bool
&& (TypeRep arg2, Int) -> (TypeRep arg2, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg2, Int)
li2 (TypeRep arg2, Int)
ri2
  DTernaryTerm ((TypeRep tag, tag)
tagl :: tagl) (TypeRep arg1, Int)
li1 (TypeRep arg2, Int)
li2 (TypeRep arg3, Int)
li3 == DTernaryTerm ((TypeRep tag, tag)
tagr :: tagr) (TypeRep arg1, Int)
ri1 (TypeRep arg2, Int)
ri2 (TypeRep arg3, Int)
ri3 =
    (TypeRep tag, tag) -> (TypeRep tag, tag) -> Bool
forall a b. Eq a => (TypeRep a, a) -> (TypeRep b, b) -> Bool
eqHeteroTag (TypeRep tag, tag)
tagl (TypeRep tag, tag)
tagr Bool -> Bool -> Bool
&& (TypeRep arg1, Int) -> (TypeRep arg1, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg1, Int)
li1 (TypeRep arg1, Int)
ri1 Bool -> Bool -> Bool
&& (TypeRep arg2, Int) -> (TypeRep arg2, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg2, Int)
li2 (TypeRep arg2, Int)
ri2 Bool -> Bool -> Bool
&& (TypeRep arg3, Int) -> (TypeRep arg3, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep arg3, Int)
li3 (TypeRep arg3, Int)
ri3
  DNotTerm Int
li == DNotTerm Int
ri = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri
  DOrTerm Int
li1 Int
li2 == DOrTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DAndTerm Int
li1 Int
li2 == DAndTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DEqTerm TypeRep args
lrep Int
li1 Int
li2 == DEqTerm TypeRep args
rrep Int
ri1 Int
ri2 = TypeRep args -> TypeRep args -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep args
lrep TypeRep args
rrep Bool -> Bool -> Bool
&& Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DITETerm Int
lc Int
li1 Int
li2 == DITETerm Int
rc Int
ri1 Int
ri2 = Int
lc Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rc Bool -> Bool -> Bool
&& Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DAddNumTerm Int
li1 Int
li2 == DAddNumTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DNegNumTerm Int
li == DNegNumTerm Int
ri = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri
  DMulNumTerm Int
li1 Int
li2 == DMulNumTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DAbsNumTerm Int
li == DAbsNumTerm Int
ri = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri
  DSignumNumTerm Int
li == DSignumNumTerm Int
ri = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri
  DLtOrdTerm TypeRep args
lrep Int
li1 Int
li2 == DLtOrdTerm TypeRep args
rrep Int
ri1 Int
ri2 = TypeRep args -> TypeRep args -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep args
lrep TypeRep args
rrep Bool -> Bool -> Bool
&& Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DLeOrdTerm TypeRep args
lrep Int
li1 Int
li2 == DLeOrdTerm TypeRep args
rrep Int
ri1 Int
ri2 = TypeRep args -> TypeRep args -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep args
lrep TypeRep args
rrep Bool -> Bool -> Bool
&& Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DAndBitsTerm Int
li1 Int
li2 == DAndBitsTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DOrBitsTerm Int
li1 Int
li2 == DOrBitsTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DXorBitsTerm Int
li1 Int
li2 == DXorBitsTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DComplementBitsTerm Int
li == DComplementBitsTerm Int
ri = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri
  DShiftLeftTerm Int
li Int
ln == DShiftLeftTerm Int
ri Int
rn = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri Bool -> Bool -> Bool
&& Int
ln Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rn
  DShiftRightTerm Int
li Int
ln == DShiftRightTerm Int
ri Int
rn = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri Bool -> Bool -> Bool
&& Int
ln Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rn
  DRotateLeftTerm Int
li Int
ln == DRotateLeftTerm Int
ri Int
rn = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri Bool -> Bool -> Bool
&& Int
ln Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rn
  DRotateRightTerm Int
li Int
ln == DRotateRightTerm Int
ri Int
rn = Int
li Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri Bool -> Bool -> Bool
&& Int
ln Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
rn
  DToSignedTerm (TypeRep u, Int)
li == DToSignedTerm (TypeRep u, Int)
ri = (TypeRep u, Int) -> (TypeRep u, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep u, Int)
li (TypeRep u, Int)
ri
  DToUnsignedTerm (TypeRep s, Int)
li == DToUnsignedTerm (TypeRep s, Int)
ri = (TypeRep s, Int) -> (TypeRep s, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep s, Int)
li (TypeRep s, Int)
ri
  DBVConcatTerm TypeRep bv1
lrep1 TypeRep bv2
lrep2 Int
li1 Int
li2 == DBVConcatTerm TypeRep bv1
rrep1 TypeRep bv2
rrep2 Int
ri1 Int
ri2 =
    TypeRep bv1 -> TypeRep bv1 -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep bv1
lrep1 TypeRep bv1
rrep1 Bool -> Bool -> Bool
&& TypeRep bv2 -> TypeRep bv2 -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep bv2
lrep2 TypeRep bv2
rrep2 Bool -> Bool -> Bool
&& Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DBVSelectTerm TypeRep ix
lix (TypeRep (bv n), Int)
li == DBVSelectTerm TypeRep ix
rix (TypeRep (bv n), Int)
ri =
    TypeRep ix -> TypeRep ix -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep ix
lix TypeRep ix
rix Bool -> Bool -> Bool
&& (TypeRep (bv n), Int) -> (TypeRep (bv n), Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep (bv n), Int)
li (TypeRep (bv n), Int)
ri
  DBVExtendTerm Bool
lIsSigned TypeRep r
ln (TypeRep (bv l), Int)
li == DBVExtendTerm Bool
rIsSigned TypeRep r
rn (TypeRep (bv l), Int)
ri =
    Bool
lIsSigned Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
rIsSigned
      Bool -> Bool -> Bool
&& TypeRep r -> TypeRep r -> Bool
forall ka kb (a :: ka) (b :: kb). TypeRep a -> TypeRep b -> Bool
eqTypeRepBool TypeRep r
ln TypeRep r
rn
      Bool -> Bool -> Bool
&& (TypeRep (bv l), Int) -> (TypeRep (bv l), Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep (bv l), Int)
li (TypeRep (bv l), Int)
ri
  DApplyTerm (TypeRep f, Int)
lf (TypeRep a, Int)
li == DApplyTerm (TypeRep f, Int)
rf (TypeRep a, Int)
ri = (TypeRep f, Int) -> (TypeRep f, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep f, Int)
lf (TypeRep f, Int)
rf Bool -> Bool -> Bool
&& (TypeRep a, Int) -> (TypeRep a, Int) -> Bool
forall a b. (TypeRep a, Int) -> (TypeRep b, Int) -> Bool
eqTypedId (TypeRep a, Int)
li (TypeRep a, Int)
ri
  DDivIntegralTerm Int
li1 Int
li2 == DDivIntegralTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DModIntegralTerm Int
li1 Int
li2 == DModIntegralTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DQuotIntegralTerm Int
li1 Int
li2 == DQuotIntegralTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  DRemIntegralTerm Int
li1 Int
li2 == DRemIntegralTerm Int
ri1 Int
ri2 = Int
li1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri1 Bool -> Bool -> Bool
&& Int
li2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ri2
  Description (Term t)
_ == Description (Term t)
_ = Bool
False

instance (SupportedPrim t) => Hashable (Description (Term t)) where
  hashWithSalt :: Int -> Description (Term t) -> Int
hashWithSalt Int
s (DConTerm t
c) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
0 :: Int) Int -> t -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` t
c
  hashWithSalt Int
s (DSymTerm TypedSymbol t
name) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
1 :: Int) Int -> TypedSymbol t -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypedSymbol t
name
  hashWithSalt Int
s (DUnaryTerm (TypeRep tag, tag)
tag (TypeRep arg, Int)
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
2 :: Int) Int -> (TypeRep tag, tag) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep tag, tag)
tag Int -> (TypeRep arg, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg, Int)
id1
  hashWithSalt Int
s (DBinaryTerm (TypeRep tag, tag)
tag (TypeRep arg1, Int)
id1 (TypeRep arg2, Int)
id2) =
    Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
3 :: Int) Int -> (TypeRep tag, tag) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep tag, tag)
tag Int -> (TypeRep arg1, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg1, Int)
id1 Int -> (TypeRep arg2, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg2, Int)
id2
  hashWithSalt Int
s (DTernaryTerm (TypeRep tag, tag)
tag (TypeRep arg1, Int)
id1 (TypeRep arg2, Int)
id2 (TypeRep arg3, Int)
id3) =
    Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
4 :: Int) Int -> (TypeRep tag, tag) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep tag, tag)
tag Int -> (TypeRep arg1, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg1, Int)
id1 Int -> (TypeRep arg2, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg2, Int)
id2 Int -> (TypeRep arg3, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep arg3, Int)
id3
  hashWithSalt Int
s (DNotTerm Int
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
5 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
  hashWithSalt Int
s (DOrTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
6 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DAndTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
7 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DEqTerm TypeRep args
rep Int
id1 Int
id2) =
    Int
s
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
8 :: Int)
      Int -> TypeRep args -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep args
rep
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DITETerm Int
idc Int
id1 Int
id2) =
    Int
s
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
9 :: Int)
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
idc
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DAddNumTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
10 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DNegNumTerm Int
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
11 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
  hashWithSalt Int
s (DMulNumTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
12 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DAbsNumTerm Int
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
13 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
  hashWithSalt Int
s (DSignumNumTerm Int
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
14 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
  hashWithSalt Int
s (DLtOrdTerm TypeRep args
rep Int
id1 Int
id2) =
    Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
15 :: Int) Int -> TypeRep args -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep args
rep Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DLeOrdTerm TypeRep args
rep Int
id1 Int
id2) =
    Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
16 :: Int) Int -> TypeRep args -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep args
rep Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DAndBitsTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
17 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DOrBitsTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
18 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DXorBitsTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
19 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DComplementBitsTerm Int
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
20 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1
  hashWithSalt Int
s (DShiftLeftTerm Int
id1 Int
idn) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
38 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
idn
  hashWithSalt Int
s (DShiftRightTerm Int
id1 Int
idn) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
39 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
idn
  hashWithSalt Int
s (DRotateLeftTerm Int
id1 Int
idn) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
40 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
idn
  hashWithSalt Int
s (DRotateRightTerm Int
id1 Int
idn) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
41 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
idn
  hashWithSalt Int
s (DToSignedTerm (TypeRep u, Int)
id) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
23 :: Int) Int -> (TypeRep u, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep u, Int)
id
  hashWithSalt Int
s (DToUnsignedTerm (TypeRep s, Int)
id) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
24 :: Int) Int -> (TypeRep s, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep s, Int)
id
  hashWithSalt Int
s (DBVConcatTerm TypeRep bv1
rep1 TypeRep bv2
rep2 Int
id1 Int
id2) =
    Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
25 :: Int) Int -> TypeRep bv1 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep bv1
rep1 Int -> TypeRep bv2 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep bv2
rep2 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DBVSelectTerm TypeRep ix
ix (TypeRep (bv n), Int)
id1) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
26 :: Int) Int -> TypeRep ix -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep ix
ix Int -> (TypeRep (bv n), Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep (bv n), Int)
id1
  hashWithSalt Int
s (DBVExtendTerm Bool
signed TypeRep r
n (TypeRep (bv l), Int)
id1) =
    Int
s
      Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
27 :: Int)
      Int -> Bool -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Bool
signed
      Int -> TypeRep r -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` TypeRep r
n
      Int -> (TypeRep (bv l), Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep (bv l), Int)
id1
  hashWithSalt Int
s (DDivIntegralTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
30 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DModIntegralTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
31 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DQuotIntegralTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
32 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DRemIntegralTerm Int
id1 Int
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
33 :: Int) Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id1 Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
id2
  hashWithSalt Int
s (DApplyTerm (TypeRep f, Int)
id1 (TypeRep a, Int)
id2) = Int
s Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
38 :: Int) Int -> (TypeRep f, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep f, Int)
id1 Int -> (TypeRep a, Int) -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (TypeRep a, Int)
id2

internTerm :: forall t. (SupportedPrim t) => Uninterned (Term t) -> Term t
internTerm :: forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm !Uninterned (Term t)
bt = IO (Term t) -> Term t
forall a. IO a -> a
unsafeDupablePerformIO (IO (Term t) -> Term t) -> IO (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ IORef (CacheState (Term t))
-> (CacheState (Term t) -> (CacheState (Term t), Term t))
-> IO (Term t)
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (CacheState (Term t))
slot CacheState (Term t) -> (CacheState (Term t), Term t)
go
  where
    slot :: IORef (CacheState (Term t))
slot = Cache (Term t) -> Array Int (IORef (CacheState (Term t)))
forall t. Cache t -> Array Int (IORef (CacheState t))
getCache Cache (Term t)
forall t. Interned t => Cache t
cache Array Int (IORef (CacheState (Term t)))
-> Int -> IORef (CacheState (Term t))
forall i e. Ix i => Array i e -> i -> e
! Int
r
    !dt :: Description (Term t)
dt = Uninterned (Term t) -> Description (Term t)
forall t. Interned t => Uninterned t -> Description t
describe Uninterned (Term t)
bt
    !hdt :: Int
hdt = Description (Term t) -> Int
forall a. Hashable a => a -> Int
hash Description (Term t)
dt
    !wid :: Int
wid = Description (Term t) -> Int
forall t (p :: * -> *). Interned t => p t -> Int
forall (p :: * -> *). p (Term t) -> Int
cacheWidth Description (Term t)
dt
    r :: Int
r = Int
hdt Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
wid
    go :: CacheState (Term t) -> (CacheState (Term t), Term t)
go (CacheState Int
i HashMap (Description (Term t)) (Term t)
m) = case Description (Term t)
-> HashMap (Description (Term t)) (Term t) -> Maybe (Term t)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Description (Term t)
dt HashMap (Description (Term t)) (Term t)
m of
      Maybe (Term t)
Nothing -> let t :: Term t
t = Int -> Uninterned (Term t) -> Term t
forall t. Interned t => Int -> Uninterned t -> t
identify (Int
wid Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
r) Uninterned (Term t)
bt in (Int
-> HashMap (Description (Term t)) (Term t) -> CacheState (Term t)
forall t. Int -> HashMap (Description t) t -> CacheState t
CacheState (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Description (Term t)
-> Term t
-> HashMap (Description (Term t)) (Term t)
-> HashMap (Description (Term t)) (Term t)
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert Description (Term t)
dt Term t
t HashMap (Description (Term t)) (Term t)
m), Term t
t)
      Just Term t
t -> (Int
-> HashMap (Description (Term t)) (Term t) -> CacheState (Term t)
forall t. Int -> HashMap (Description t) t -> CacheState t
CacheState Int
i HashMap (Description (Term t)) (Term t)
m, Term t
t)

constructUnary ::
  forall tag arg t.
  (SupportedPrim t, UnaryOp tag arg t, Typeable tag, Typeable t, Show tag) =>
  tag ->
  Term arg ->
  Term t
constructUnary :: forall tag arg t.
(SupportedPrim t, UnaryOp tag arg t, Typeable tag, Typeable t,
 Show tag) =>
tag -> Term arg -> Term t
constructUnary tag
tag Term arg
tm = let x :: Term t
x = Uninterned (Term t) -> Term t
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term t) -> Term t) -> Uninterned (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ tag -> Term arg -> UTerm t
forall a f t. UnaryOp a f t => a -> Term f -> UTerm t
UUnaryTerm tag
tag Term arg
tm in Term t
x
{-# INLINE constructUnary #-}

constructBinary ::
  forall tag arg1 arg2 t.
  (SupportedPrim t, BinaryOp tag arg1 arg2 t, Typeable tag, Typeable t, Show tag) =>
  tag ->
  Term arg1 ->
  Term arg2 ->
  Term t
constructBinary :: forall tag arg1 arg2 t.
(SupportedPrim t, BinaryOp tag arg1 arg2 t, Typeable tag,
 Typeable t, Show tag) =>
tag -> Term arg1 -> Term arg2 -> Term t
constructBinary tag
tag Term arg1
tm1 Term arg2
tm2 = Uninterned (Term t) -> Term t
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term t) -> Term t) -> Uninterned (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ tag -> Term arg1 -> Term arg2 -> UTerm t
forall a f r t.
BinaryOp a f r t =>
a -> Term f -> Term r -> UTerm t
UBinaryTerm tag
tag Term arg1
tm1 Term arg2
tm2
{-# INLINE constructBinary #-}

constructTernary ::
  forall tag arg1 arg2 arg3 t.
  (SupportedPrim t, TernaryOp tag arg1 arg2 arg3 t, Typeable tag, Typeable t, Show tag) =>
  tag ->
  Term arg1 ->
  Term arg2 ->
  Term arg3 ->
  Term t
constructTernary :: forall tag arg1 arg2 arg3 t.
(SupportedPrim t, TernaryOp tag arg1 arg2 arg3 t, Typeable tag,
 Typeable t, Show tag) =>
tag -> Term arg1 -> Term arg2 -> Term arg3 -> Term t
constructTernary tag
tag Term arg1
tm1 Term arg2
tm2 Term arg3
tm3 = Uninterned (Term t) -> Term t
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term t) -> Term t) -> Uninterned (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ tag -> Term arg1 -> Term arg2 -> Term arg3 -> UTerm t
forall a f r w t.
TernaryOp a f r w t =>
a -> Term f -> Term r -> Term w -> UTerm t
UTernaryTerm tag
tag Term arg1
tm1 Term arg2
tm2 Term arg3
tm3
{-# INLINE constructTernary #-}

conTerm :: (SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) => t -> Term t
conTerm :: forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm t
t = Uninterned (Term t) -> Term t
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term t) -> Term t) -> Uninterned (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ t -> UTerm t
forall t. SupportedPrim t => t -> UTerm t
UConTerm t
t
{-# INLINE conTerm #-}

symTerm :: forall t. (SupportedPrim t, Typeable t) => Symbol -> Term t
symTerm :: forall t. (SupportedPrim t, Typeable t) => Symbol -> Term t
symTerm Symbol
t = Uninterned (Term t) -> Term t
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term t) -> Term t) -> Uninterned (Term t) -> Term t
forall a b. (a -> b) -> a -> b
$ TypedSymbol t -> UTerm t
forall t. SupportedPrim t => TypedSymbol t -> UTerm t
USymTerm (TypedSymbol t -> UTerm t) -> TypedSymbol t -> UTerm t
forall a b. (a -> b) -> a -> b
$ Symbol -> TypedSymbol t
forall t. SupportedPrim t => Symbol -> TypedSymbol t
TypedSymbol Symbol
t
{-# INLINE symTerm #-}

ssymTerm :: (SupportedPrim t, Typeable t) => Identifier -> Term t
ssymTerm :: forall t. (SupportedPrim t, Typeable t) => Identifier -> Term t
ssymTerm = Symbol -> Term t
forall t. (SupportedPrim t, Typeable t) => Symbol -> Term t
symTerm (Symbol -> Term t)
-> (Identifier -> Symbol) -> Identifier -> Term t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier -> Symbol
SimpleSymbol
{-# INLINE ssymTerm #-}

isymTerm :: (SupportedPrim t, Typeable t) => Identifier -> Int -> Term t
isymTerm :: forall t.
(SupportedPrim t, Typeable t) =>
Identifier -> Int -> Term t
isymTerm Identifier
str Int
idx = Symbol -> Term t
forall t. (SupportedPrim t, Typeable t) => Symbol -> Term t
symTerm (Symbol -> Term t) -> Symbol -> Term t
forall a b. (a -> b) -> a -> b
$ Identifier -> Int -> Symbol
IndexedSymbol Identifier
str Int
idx
{-# INLINE isymTerm #-}

notTerm :: Term Bool -> Term Bool
notTerm :: Term Bool -> Term Bool
notTerm = Uninterned (Term Bool) -> Term Bool
UTerm Bool -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm Bool -> Term Bool)
-> (Term Bool -> UTerm Bool) -> Term Bool -> Term Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term Bool -> UTerm Bool
UNotTerm
{-# INLINE notTerm #-}

orTerm :: Term Bool -> Term Bool -> Term Bool
orTerm :: Term Bool -> Term Bool -> Term Bool
orTerm Term Bool
l Term Bool
r = Uninterned (Term Bool) -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term Bool) -> Term Bool)
-> Uninterned (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> UTerm Bool
UOrTerm Term Bool
l Term Bool
r
{-# INLINE orTerm #-}

andTerm :: Term Bool -> Term Bool -> Term Bool
andTerm :: Term Bool -> Term Bool -> Term Bool
andTerm Term Bool
l Term Bool
r = Uninterned (Term Bool) -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term Bool) -> Term Bool)
-> Uninterned (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> UTerm Bool
UAndTerm Term Bool
l Term Bool
r
{-# INLINE andTerm #-}

eqTerm :: (SupportedPrim a) => Term a -> Term a -> Term Bool
eqTerm :: forall a. SupportedPrim a => Term a -> Term a -> Term Bool
eqTerm Term a
l Term a
r = Uninterned (Term Bool) -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term Bool) -> Term Bool)
-> Uninterned (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm Bool
forall a. SupportedPrim a => Term a -> Term a -> UTerm Bool
UEqTerm Term a
l Term a
r
{-# INLINE eqTerm #-}

iteTerm :: (SupportedPrim a) => Term Bool -> Term a -> Term a -> Term a
iteTerm :: forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
iteTerm Term Bool
c Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> UTerm a
forall t.
SupportedPrim t =>
Term Bool -> Term t -> Term t -> UTerm t
UITETerm Term Bool
c Term a
l Term a
r
{-# INLINE iteTerm #-}

addNumTerm :: (PEvalNumTerm a) => Term a -> Term a -> Term a
addNumTerm :: forall a. PEvalNumTerm a => Term a -> Term a -> Term a
addNumTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalNumTerm t => Term t -> Term t -> UTerm t
UAddNumTerm Term a
l Term a
r
{-# INLINE addNumTerm #-}

negNumTerm :: (PEvalNumTerm a) => Term a -> Term a
negNumTerm :: forall t. PEvalNumTerm t => Term t -> Term t
negNumTerm = Uninterned (Term a) -> Term a
UTerm a -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm a -> Term a) -> (Term a -> UTerm a) -> Term a -> Term a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term a -> UTerm a
forall t. PEvalNumTerm t => Term t -> UTerm t
UNegNumTerm
{-# INLINE negNumTerm #-}

mulNumTerm :: (PEvalNumTerm a) => Term a -> Term a -> Term a
mulNumTerm :: forall a. PEvalNumTerm a => Term a -> Term a -> Term a
mulNumTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalNumTerm t => Term t -> Term t -> UTerm t
UMulNumTerm Term a
l Term a
r
{-# INLINE mulNumTerm #-}

absNumTerm :: (PEvalNumTerm a) => Term a -> Term a
absNumTerm :: forall t. PEvalNumTerm t => Term t -> Term t
absNumTerm = Uninterned (Term a) -> Term a
UTerm a -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm a -> Term a) -> (Term a -> UTerm a) -> Term a -> Term a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term a -> UTerm a
forall t. PEvalNumTerm t => Term t -> UTerm t
UAbsNumTerm
{-# INLINE absNumTerm #-}

signumNumTerm :: (PEvalNumTerm a) => Term a -> Term a
signumNumTerm :: forall t. PEvalNumTerm t => Term t -> Term t
signumNumTerm = Uninterned (Term a) -> Term a
UTerm a -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm a -> Term a) -> (Term a -> UTerm a) -> Term a -> Term a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term a -> UTerm a
forall t. PEvalNumTerm t => Term t -> UTerm t
USignumNumTerm
{-# INLINE signumNumTerm #-}

ltOrdTerm :: (PEvalOrdTerm a) => Term a -> Term a -> Term Bool
ltOrdTerm :: forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
ltOrdTerm Term a
l Term a
r = Uninterned (Term Bool) -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term Bool) -> Term Bool)
-> Uninterned (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> UTerm Bool
ULtOrdTerm Term a
l Term a
r
{-# INLINE ltOrdTerm #-}

leOrdTerm :: (PEvalOrdTerm a) => Term a -> Term a -> Term Bool
leOrdTerm :: forall a. PEvalOrdTerm a => Term a -> Term a -> Term Bool
leOrdTerm Term a
l Term a
r = Uninterned (Term Bool) -> Term Bool
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term Bool) -> Term Bool)
-> Uninterned (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm Bool
forall a. PEvalOrdTerm a => Term a -> Term a -> UTerm Bool
ULeOrdTerm Term a
l Term a
r
{-# INLINE leOrdTerm #-}

andBitsTerm :: (PEvalBitwiseTerm a) => Term a -> Term a -> Term a
andBitsTerm :: forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
andBitsTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalBitwiseTerm t => Term t -> Term t -> UTerm t
UAndBitsTerm Term a
l Term a
r
{-# INLINE andBitsTerm #-}

orBitsTerm :: (PEvalBitwiseTerm a) => Term a -> Term a -> Term a
orBitsTerm :: forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
orBitsTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalBitwiseTerm t => Term t -> Term t -> UTerm t
UOrBitsTerm Term a
l Term a
r
{-# INLINE orBitsTerm #-}

xorBitsTerm :: (PEvalBitwiseTerm a) => Term a -> Term a -> Term a
xorBitsTerm :: forall a. PEvalBitwiseTerm a => Term a -> Term a -> Term a
xorBitsTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalBitwiseTerm t => Term t -> Term t -> UTerm t
UXorBitsTerm Term a
l Term a
r
{-# INLINE xorBitsTerm #-}

complementBitsTerm :: (PEvalBitwiseTerm a) => Term a -> Term a
complementBitsTerm :: forall a. PEvalBitwiseTerm a => Term a -> Term a
complementBitsTerm = Uninterned (Term a) -> Term a
UTerm a -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm a -> Term a) -> (Term a -> UTerm a) -> Term a -> Term a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term a -> UTerm a
forall t. PEvalBitwiseTerm t => Term t -> UTerm t
UComplementBitsTerm
{-# INLINE complementBitsTerm #-}

shiftLeftTerm :: (PEvalShiftTerm a) => Term a -> Term a -> Term a
shiftLeftTerm :: forall a. PEvalShiftTerm a => Term a -> Term a -> Term a
shiftLeftTerm Term a
t Term a
n = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalShiftTerm t => Term t -> Term t -> UTerm t
UShiftLeftTerm Term a
t Term a
n
{-# INLINE shiftLeftTerm #-}

shiftRightTerm :: (PEvalShiftTerm a) => Term a -> Term a -> Term a
shiftRightTerm :: forall a. PEvalShiftTerm a => Term a -> Term a -> Term a
shiftRightTerm Term a
t Term a
n = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalShiftTerm t => Term t -> Term t -> UTerm t
UShiftRightTerm Term a
t Term a
n
{-# INLINE shiftRightTerm #-}

rotateLeftTerm :: (PEvalRotateTerm a) => Term a -> Term a -> Term a
rotateLeftTerm :: forall a. PEvalRotateTerm a => Term a -> Term a -> Term a
rotateLeftTerm Term a
t Term a
n = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalRotateTerm t => Term t -> Term t -> UTerm t
URotateLeftTerm Term a
t Term a
n
{-# INLINE rotateLeftTerm #-}

rotateRightTerm :: (PEvalRotateTerm a) => Term a -> Term a -> Term a
rotateRightTerm :: forall a. PEvalRotateTerm a => Term a -> Term a -> Term a
rotateRightTerm Term a
t Term a
n = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalRotateTerm t => Term t -> Term t -> UTerm t
URotateRightTerm Term a
t Term a
n
{-# INLINE rotateRightTerm #-}

toSignedTerm ::
  (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
  Term (u n) ->
  Term (s n)
toSignedTerm :: forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat).
(PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
Term (u n) -> Term (s n)
toSignedTerm = Uninterned (Term (s n)) -> Term (s n)
UTerm (s n) -> Term (s n)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm (s n) -> Term (s n))
-> (Term (u n) -> UTerm (s n)) -> Term (u n) -> Term (s n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term (u n) -> UTerm (s n)
forall (a :: Nat -> *) (f :: Nat -> *) (r :: Nat).
(PEvalBVSignConversionTerm a f, KnownNat r, 1 <= r) =>
Term (a r) -> UTerm (f r)
UToSignedTerm

toUnsignedTerm ::
  (PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
  Term (s n) ->
  Term (u n)
toUnsignedTerm :: forall (u :: Nat -> *) (s :: Nat -> *) (n :: Nat).
(PEvalBVSignConversionTerm u s, KnownNat n, 1 <= n) =>
Term (s n) -> Term (u n)
toUnsignedTerm = Uninterned (Term (u n)) -> Term (u n)
UTerm (u n) -> Term (u n)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (UTerm (u n) -> Term (u n))
-> (Term (s n) -> UTerm (u n)) -> Term (s n) -> Term (u n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term (s n) -> UTerm (u n)
forall (a :: Nat -> *) (f :: Nat -> *) (r :: Nat).
(PEvalBVSignConversionTerm a f, KnownNat r, 1 <= r) =>
Term (f r) -> UTerm (a r)
UToUnsignedTerm

bvconcatTerm ::
  ( PEvalBVTerm bv,
    KnownNat l,
    KnownNat r,
    KnownNat (l + r),
    1 <= l,
    1 <= r,
    1 <= l + r
  ) =>
  Term (bv l) ->
  Term (bv r) ->
  Term (bv (l + r))
bvconcatTerm :: forall (bv :: Nat -> *) (l :: Nat) (r :: Nat).
(PEvalBVTerm bv, KnownNat l, KnownNat r, KnownNat (l + r), 1 <= l,
 1 <= r, 1 <= (l + r)) =>
Term (bv l) -> Term (bv r) -> Term (bv (l + r))
bvconcatTerm Term (bv l)
l Term (bv r)
r = Uninterned (Term (bv (l + r))) -> Term (bv (l + r))
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term (bv (l + r))) -> Term (bv (l + r)))
-> Uninterned (Term (bv (l + r))) -> Term (bv (l + r))
forall a b. (a -> b) -> a -> b
$ Term (bv l) -> Term (bv r) -> UTerm (bv (l + r))
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, KnownNat (f + r), 1 <= f,
 1 <= r, 1 <= (f + r)) =>
Term (a f) -> Term (a r) -> UTerm (a (f + r))
UBVConcatTerm Term (bv l)
l Term (bv r)
r
{-# INLINE bvconcatTerm #-}

bvselectTerm ::
  forall bv n ix w p q.
  ( PEvalBVTerm bv,
    KnownNat n,
    KnownNat ix,
    KnownNat w,
    1 <= n,
    1 <= w,
    ix + w <= n
  ) =>
  p ix ->
  q w ->
  Term (bv n) ->
  Term (bv w)
bvselectTerm :: forall (bv :: Nat -> *) (n :: Nat) (ix :: Nat) (w :: Nat)
       (p :: Nat -> *) (q :: Nat -> *).
(PEvalBVTerm bv, KnownNat n, KnownNat ix, KnownNat w, 1 <= n,
 1 <= w, (ix + w) <= n) =>
p ix -> q w -> Term (bv n) -> Term (bv w)
bvselectTerm p ix
_ q w
_ Term (bv n)
v = Uninterned (Term (bv w)) -> Term (bv w)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term (bv w)) -> Term (bv w))
-> Uninterned (Term (bv w)) -> Term (bv w)
forall a b. (a -> b) -> a -> b
$ TypeRep ix -> TypeRep w -> Term (bv n) -> UTerm (bv w)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat) (w :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, KnownNat w, 1 <= f, 1 <= w,
 (r + w) <= f) =>
TypeRep r -> TypeRep w -> Term (a f) -> UTerm (a w)
UBVSelectTerm (forall (a :: Nat). Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @ix) (forall (a :: Nat). Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @w) Term (bv n)
v
{-# INLINE bvselectTerm #-}

bvextendTerm ::
  forall bv l r proxy.
  (PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
  Bool ->
  proxy r ->
  Term (bv l) ->
  Term (bv r)
bvextendTerm :: forall (bv :: Nat -> *) (l :: Nat) (r :: Nat) (proxy :: Nat -> *).
(PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
Bool -> proxy r -> Term (bv l) -> Term (bv r)
bvextendTerm Bool
signed proxy r
_ Term (bv l)
v = Uninterned (Term (bv r)) -> Term (bv r)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term (bv r)) -> Term (bv r))
-> Uninterned (Term (bv r)) -> Term (bv r)
forall a b. (a -> b) -> a -> b
$ Bool -> TypeRep r -> Term (bv l) -> UTerm (bv r)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, 1 <= f, 1 <= r, f <= r) =>
Bool -> TypeRep r -> Term (a f) -> UTerm (a r)
UBVExtendTerm Bool
signed (forall (a :: Nat). Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @r) Term (bv l)
v
{-# INLINE bvextendTerm #-}

bvsignExtendTerm ::
  forall bv l r proxy.
  (PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
  proxy r ->
  Term (bv l) ->
  Term (bv r)
bvsignExtendTerm :: forall (bv :: Nat -> *) (l :: Nat) (r :: Nat) (proxy :: Nat -> *).
(PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
proxy r -> Term (bv l) -> Term (bv r)
bvsignExtendTerm proxy r
_ Term (bv l)
v = Uninterned (Term (bv r)) -> Term (bv r)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term (bv r)) -> Term (bv r))
-> Uninterned (Term (bv r)) -> Term (bv r)
forall a b. (a -> b) -> a -> b
$ Bool -> TypeRep r -> Term (bv l) -> UTerm (bv r)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, 1 <= f, 1 <= r, f <= r) =>
Bool -> TypeRep r -> Term (a f) -> UTerm (a r)
UBVExtendTerm Bool
True (forall (a :: Nat). Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @r) Term (bv l)
v
{-# INLINE bvsignExtendTerm #-}

bvzeroExtendTerm ::
  forall bv l r proxy.
  (PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
  proxy r ->
  Term (bv l) ->
  Term (bv r)
bvzeroExtendTerm :: forall (bv :: Nat -> *) (l :: Nat) (r :: Nat) (proxy :: Nat -> *).
(PEvalBVTerm bv, KnownNat l, KnownNat r, 1 <= l, 1 <= r, l <= r) =>
proxy r -> Term (bv l) -> Term (bv r)
bvzeroExtendTerm proxy r
_ Term (bv l)
v = Uninterned (Term (bv r)) -> Term (bv r)
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term (bv r)) -> Term (bv r))
-> Uninterned (Term (bv r)) -> Term (bv r)
forall a b. (a -> b) -> a -> b
$ Bool -> TypeRep r -> Term (bv l) -> UTerm (bv r)
forall (a :: Nat -> *) (f :: Nat) (r :: Nat).
(PEvalBVTerm a, KnownNat f, KnownNat r, 1 <= f, 1 <= r, f <= r) =>
Bool -> TypeRep r -> Term (a f) -> UTerm (a r)
UBVExtendTerm Bool
False (forall (a :: Nat). Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @r) Term (bv l)
v
{-# INLINE bvzeroExtendTerm #-}

applyTerm ::
  (SupportedPrim a, SupportedPrim b, SupportedPrim f, PEvalApplyTerm f a b) =>
  Term f ->
  Term a ->
  Term b
applyTerm :: forall a b f.
(SupportedPrim a, SupportedPrim b, SupportedPrim f,
 PEvalApplyTerm f a b) =>
Term f -> Term a -> Term b
applyTerm Term f
f Term a
a = Uninterned (Term b) -> Term b
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term b) -> Term b) -> Uninterned (Term b) -> Term b
forall a b. (a -> b) -> a -> b
$ Term f -> Term a -> UTerm b
forall a b f.
(SupportedPrim a, SupportedPrim b, SupportedPrim f,
 PEvalApplyTerm f a b) =>
Term f -> Term a -> UTerm b
UApplyTerm Term f
f Term a
a
{-# INLINE applyTerm #-}

divIntegralTerm :: (PEvalDivModIntegralTerm a) => Term a -> Term a -> Term a
divIntegralTerm :: forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
divIntegralTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalDivModIntegralTerm t => Term t -> Term t -> UTerm t
UDivIntegralTerm Term a
l Term a
r
{-# INLINE divIntegralTerm #-}

modIntegralTerm :: (PEvalDivModIntegralTerm a) => Term a -> Term a -> Term a
modIntegralTerm :: forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
modIntegralTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalDivModIntegralTerm t => Term t -> Term t -> UTerm t
UModIntegralTerm Term a
l Term a
r
{-# INLINE modIntegralTerm #-}

quotIntegralTerm :: (PEvalDivModIntegralTerm a) => Term a -> Term a -> Term a
quotIntegralTerm :: forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
quotIntegralTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalDivModIntegralTerm t => Term t -> Term t -> UTerm t
UQuotIntegralTerm Term a
l Term a
r
{-# INLINE quotIntegralTerm #-}

remIntegralTerm :: (PEvalDivModIntegralTerm a) => Term a -> Term a -> Term a
remIntegralTerm :: forall a. PEvalDivModIntegralTerm a => Term a -> Term a -> Term a
remIntegralTerm Term a
l Term a
r = Uninterned (Term a) -> Term a
forall t. SupportedPrim t => Uninterned (Term t) -> Term t
internTerm (Uninterned (Term a) -> Term a) -> Uninterned (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$ Term a -> Term a -> UTerm a
forall t. PEvalDivModIntegralTerm t => Term t -> Term t -> UTerm t
URemIntegralTerm Term a
l Term a
r
{-# INLINE remIntegralTerm #-}

-- Support for boolean type
defaultValueForBool :: Bool
defaultValueForBool :: Bool
defaultValueForBool = Bool
False

defaultValueForBoolDyn :: ModelValue
defaultValueForBoolDyn :: ModelValue
defaultValueForBoolDyn = Bool -> ModelValue
forall a. (Show a, Eq a, Hashable a, Typeable a) => a -> ModelValue
toModelValue Bool
defaultValueForBool

trueTerm :: Term Bool
trueTerm :: Term Bool
trueTerm = Bool -> Term Bool
forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm Bool
True
{-# INLINE trueTerm #-}

falseTerm :: Term Bool
falseTerm :: Term Bool
falseTerm = Bool -> Term Bool
forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm Bool
False
{-# INLINE falseTerm #-}

boolConTermView :: forall a. Term a -> Maybe Bool
boolConTermView :: forall a. Term a -> Maybe Bool
boolConTermView (ConTerm Int
_ a
b) = a -> Maybe Bool
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast a
b
boolConTermView Term a
_ = Maybe Bool
forall a. Maybe a
Nothing
{-# INLINE boolConTermView #-}

pattern BoolConTerm :: Bool -> Term a
pattern $mBoolConTerm :: forall {r} {a}. Term a -> (Bool -> r) -> ((# #) -> r) -> r
BoolConTerm b <- (boolConTermView -> Just b)

pattern TrueTerm :: Term a
pattern $mTrueTerm :: forall {r} {a}. Term a -> ((# #) -> r) -> ((# #) -> r) -> r
TrueTerm <- BoolConTerm True

pattern FalseTerm :: Term a
pattern $mFalseTerm :: forall {r} {a}. Term a -> ((# #) -> r) -> ((# #) -> r) -> r
FalseTerm <- BoolConTerm False

boolTermView :: forall a. Term a -> Maybe (Term Bool)
boolTermView :: forall a. Term a -> Maybe (Term Bool)
boolTermView Term a
t = Term a
-> (SupportedPrim a => Maybe (Term Bool)) -> Maybe (Term Bool)
forall t a. Term t -> (SupportedPrim t => a) -> a
introSupportedPrimConstraint Term a
t ((SupportedPrim a => Maybe (Term Bool)) -> Maybe (Term Bool))
-> (SupportedPrim a => Maybe (Term Bool)) -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term a -> Maybe (Term Bool)
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast Term a
t
{-# INLINE boolTermView #-}

pattern BoolTerm :: Term Bool -> Term a
pattern $mBoolTerm :: forall {r} {a}. Term a -> (Term Bool -> r) -> ((# #) -> r) -> r
BoolTerm b <- (boolTermView -> Just b)

-- Not
pevalNotTerm :: Term Bool -> Term Bool
pevalNotTerm :: Term Bool -> Term Bool
pevalNotTerm (NotTerm Int
_ Term Bool
tm) = Term Bool
tm
pevalNotTerm (ConTerm Int
_ Bool
a) = if Bool
a then Term Bool
falseTerm else Term Bool
trueTerm
pevalNotTerm (OrTerm Int
_ (NotTerm Int
_ Term Bool
n1) Term Bool
n2) = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
n1 (Term Bool -> Term Bool
pevalNotTerm Term Bool
n2)
pevalNotTerm (OrTerm Int
_ Term Bool
n1 (NotTerm Int
_ Term Bool
n2)) = Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
n1) Term Bool
n2
pevalNotTerm (AndTerm Int
_ (NotTerm Int
_ Term Bool
n1) Term Bool
n2) = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
n1 (Term Bool -> Term Bool
pevalNotTerm Term Bool
n2)
pevalNotTerm (AndTerm Int
_ Term Bool
n1 (NotTerm Int
_ Term Bool
n2)) = Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
n1) Term Bool
n2
pevalNotTerm Term Bool
tm = Term Bool -> Term Bool
notTerm Term Bool
tm
{-# INLINEABLE pevalNotTerm #-}

orEqFirst :: Term Bool -> Term Bool -> Bool
orEqFirst :: Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
_ (ConTerm Int
_ Bool
False) = Bool
True
orEqFirst
  (NotTerm Int
_ (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b)))
  (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b)))
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Bool
True
orEqFirst Term Bool
x Term Bool
y
  | Term Bool
x Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
y = Bool
True
  | Bool
otherwise = Bool
False
{-# INLINE orEqFirst #-}

orEqTrue :: Term Bool -> Term Bool -> Bool
orEqTrue :: Term Bool -> Term Bool -> Bool
orEqTrue (ConTerm Int
_ Bool
True) Term Bool
_ = Bool
True
orEqTrue Term Bool
_ (ConTerm Int
_ Bool
True) = Bool
True
-- orEqTrue (NotTerm _ e1) (NotTerm _ e2) = andEqFalse e1 e2
orEqTrue
  (NotTerm Int
_ (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b)))
  (NotTerm Int
_ (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b))))
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Bool
True
orEqTrue (NotTerm Int
_ Term Bool
l) Term Bool
r | Term Bool
l Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
r = Bool
True
orEqTrue Term Bool
l (NotTerm Int
_ Term Bool
r) | Term Bool
l Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
r = Bool
True
orEqTrue Term Bool
_ Term Bool
_ = Bool
False
{-# INLINE orEqTrue #-}

andEqFirst :: Term Bool -> Term Bool -> Bool
andEqFirst :: Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
_ (ConTerm Int
_ Bool
True) = Bool
True
-- andEqFirst x (NotTerm _ y) = andEqFalse x y
andEqFirst
  (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b))
  (NotTerm Int
_ (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b))))
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Bool
True
andEqFirst Term Bool
x Term Bool
y
  | Term Bool
x Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
y = Bool
True
  | Bool
otherwise = Bool
False
{-# INLINE andEqFirst #-}

andEqFalse :: Term Bool -> Term Bool -> Bool
andEqFalse :: Term Bool -> Term Bool -> Bool
andEqFalse (ConTerm Int
_ Bool
False) Term Bool
_ = Bool
True
andEqFalse Term Bool
_ (ConTerm Int
_ Bool
False) = Bool
True
-- andEqFalse (NotTerm _ e1) (NotTerm _ e2) = orEqTrue e1 e2
andEqFalse
  (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b))
  (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b)))
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Bool
True
andEqFalse (NotTerm Int
_ Term Bool
x) Term Bool
y | Term Bool
x Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
y = Bool
True
andEqFalse Term Bool
x (NotTerm Int
_ Term Bool
y) | Term Bool
x Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
y = Bool
True
andEqFalse Term Bool
_ Term Bool
_ = Bool
False
{-# INLINE andEqFalse #-}

-- Or
pevalOrTerm :: Term Bool -> Term Bool -> Term Bool
pevalOrTerm :: Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l Term Bool
r = Term Bool
trueTerm
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r Term Bool
l = Term Bool
r
pevalOrTerm Term Bool
l r :: Term Bool
r@(OrTerm Int
_ Term Bool
r1 Term Bool
r2)
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l Term Bool
r1 = Term Bool
trueTerm
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l Term Bool
r2 = Term Bool
trueTerm
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r1 Term Bool
l = Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r2 Term Bool
l = Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l Term Bool
r1 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l Term Bool
r2
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l Term Bool
r2 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l Term Bool
r1
pevalOrTerm l :: Term Bool
l@(OrTerm Int
_ Term Bool
l1 Term Bool
l2) Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l1 Term Bool
r = Term Bool
trueTerm
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l2 Term Bool
r = Term Bool
trueTerm
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l1 Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l2 Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r Term Bool
l1 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l2 Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r Term Bool
l2 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l1 Term Bool
r
pevalOrTerm Term Bool
l (AndTerm Int
_ Term Bool
r1 Term Bool
r2)
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l Term Bool
r1 = Term Bool
l
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
l Term Bool
r2 = Term Bool
l
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l Term Bool
r1 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l Term Bool
r2
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l Term Bool
r2 = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l Term Bool
r1
pevalOrTerm (AndTerm Int
_ Term Bool
l1 Term Bool
l2) Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r Term Bool
l1 = Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqFirst Term Bool
r Term Bool
l2 = Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l1 Term Bool
r = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l2 Term Bool
r
  | Term Bool -> Term Bool -> Bool
orEqTrue Term Bool
l2 Term Bool
r = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
l1 Term Bool
r
pevalOrTerm (NotTerm Int
_ Term Bool
nl) (NotTerm Int
_ Term Bool
nr) = Term Bool -> Term Bool
pevalNotTerm (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
nl Term Bool
nr
pevalOrTerm Term Bool
l Term Bool
r = Term Bool -> Term Bool -> Term Bool
orTerm Term Bool
l Term Bool
r
{-# INLINEABLE pevalOrTerm #-}

pevalAndTerm :: Term Bool -> Term Bool -> Term Bool
pevalAndTerm :: Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l Term Bool
r = Term Bool
falseTerm
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r Term Bool
l = Term Bool
r
pevalAndTerm Term Bool
l r :: Term Bool
r@(AndTerm Int
_ Term Bool
r1 Term Bool
r2)
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l Term Bool
r1 = Term Bool
falseTerm
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l Term Bool
r2 = Term Bool
falseTerm
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r1 Term Bool
l = Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r2 Term Bool
l = Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l Term Bool
r1 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l Term Bool
r2
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l Term Bool
r2 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l Term Bool
r1
pevalAndTerm l :: Term Bool
l@(AndTerm Int
_ Term Bool
l1 Term Bool
l2) Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l1 Term Bool
r = Term Bool
falseTerm
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l2 Term Bool
r = Term Bool
falseTerm
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l1 Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l2 Term Bool
r = Term Bool
l
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r Term Bool
l1 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l2 Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r Term Bool
l2 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l1 Term Bool
r
pevalAndTerm Term Bool
l (OrTerm Int
_ Term Bool
r1 Term Bool
r2)
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l Term Bool
r1 = Term Bool
l
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
l Term Bool
r2 = Term Bool
l
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l Term Bool
r1 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l Term Bool
r2
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l Term Bool
r2 = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l Term Bool
r1
pevalAndTerm (OrTerm Int
_ Term Bool
l1 Term Bool
l2) Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r Term Bool
l1 = Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFirst Term Bool
r Term Bool
l2 = Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l1 Term Bool
r = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l2 Term Bool
r
  | Term Bool -> Term Bool -> Bool
andEqFalse Term Bool
l2 Term Bool
r = Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l1 Term Bool
r
pevalAndTerm (NotTerm Int
_ Term Bool
nl) (NotTerm Int
_ Term Bool
nr) = Term Bool -> Term Bool
pevalNotTerm (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
nl Term Bool
nr
pevalAndTerm Term Bool
l Term Bool
r = Term Bool -> Term Bool -> Term Bool
andTerm Term Bool
l Term Bool
r
{-# INLINEABLE pevalAndTerm #-}

pevalImplyTerm :: Term Bool -> Term Bool -> Term Bool
pevalImplyTerm :: Term Bool -> Term Bool -> Term Bool
pevalImplyTerm Term Bool
l = Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
l)

pevalXorTerm :: Term Bool -> Term Bool -> Term Bool
pevalXorTerm :: Term Bool -> Term Bool -> Term Bool
pevalXorTerm Term Bool
l Term Bool
r = Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
l) Term Bool
r) (Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
l (Term Bool -> Term Bool
pevalNotTerm Term Bool
r))

pevalImpliesTerm :: Term Bool -> Term Bool -> Bool
pevalImpliesTerm :: Term Bool -> Term Bool -> Bool
pevalImpliesTerm (ConTerm Int
_ Bool
False) Term Bool
_ = Bool
True
pevalImpliesTerm Term Bool
_ (ConTerm Int
_ Bool
True) = Bool
True
pevalImpliesTerm
  (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b))
  (NotTerm Int
_ (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b))))
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Bool
True
pevalImpliesTerm Term Bool
a Term Bool
b
  | Term Bool
a Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
b = Bool
True
  | Bool
otherwise = Bool
False
{-# INLINE pevalImpliesTerm #-}

pevalITEBoolLeftNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftNot Term Bool
cond Term Bool
nIfTrue Term Bool
ifFalse
  -- need test
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
nIfTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifFalse
  | Bool
otherwise = case Term Bool
nIfTrue of
      AndTerm Int
_ Term Bool
nt1 Term Bool
nt2 -> Maybe (Term Bool)
ra
        where
          ra :: Maybe (Term Bool)
ra
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond Term Bool
nt1 =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt2) Term Bool
ifFalse
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond Term Bool
nt2 =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt1) Term Bool
ifFalse
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt1)
                Bool -> Bool -> Bool
|| Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt2) =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse
            | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing
      OrTerm Int
_ Term Bool
nt1 Term Bool
nt2 -> Maybe (Term Bool)
ra
        where
          ra :: Maybe (Term Bool)
ra
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond Term Bool
nt1 Bool -> Bool -> Bool
|| Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond Term Bool
nt2 =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifFalse
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt1) =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt2) Term Bool
ifFalse
            | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt2) =
                Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
nt1) Term Bool
ifFalse
            | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing
      Term Bool
_ -> Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolBothNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBothNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBothNot Term Bool
cond Term Bool
nIfTrue Term Bool
nIfFalse =
  Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool
pevalNotTerm (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
nIfTrue Term Bool
nIfFalse

pevalITEBoolRightNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightNot :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightNot Term Bool
cond Term Bool
ifTrue Term Bool
nIfFalse
  -- need test
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
nIfFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifTrue
  | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing -- need work

pevalInferImplies :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies :: Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies Term Bool
cond (NotTerm Int
_ Term Bool
nt1) Term Bool
trueRes Term Bool
falseRes
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
nt1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just Term Bool
falseRes
  | Bool
otherwise = case (Term Bool
cond, Term Bool
nt1) of
      ( EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b),
        EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b))
        )
          | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 -> Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just Term Bool
trueRes
      (Term Bool, Term Bool)
_ -> Maybe (Term Bool)
forall a. Maybe a
Nothing
pevalInferImplies
  (EqTerm Int
_ (Term t
e1 :: Term a) (ec1 :: Term t
ec1@(ConTerm Int
_ t
_) :: Term b))
  (EqTerm Int
_ (Dyn (Term t
e2 :: Term a)) (Dyn (ec2 :: Term t
ec2@(ConTerm Int
_ t
_) :: Term b)))
  Term Bool
_
  Term Bool
falseRes
    | Term t
e1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
== Term t
e2 Bool -> Bool -> Bool
&& Term t
ec1 Term t -> Term t -> Bool
forall a. Eq a => a -> a -> Bool
/= Term t
ec2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just Term Bool
falseRes
pevalInferImplies Term Bool
_ Term Bool
_ Term Bool
_ Term Bool
_ = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolLeftAnd :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftAnd :: Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftAnd Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
ifFalse
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalImplyTerm Term Bool
cond Term Bool
t2
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalImplyTerm Term Bool
cond Term Bool
t1
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
t1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
ifFalse
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
t2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
ifFalse
  | Bool
otherwise =
      [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
        [ Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies Term Bool
cond Term Bool
t1 (Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
ifFalse) (Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifFalse),
          Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies Term Bool
cond Term Bool
t2 (Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
ifFalse) (Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifFalse)
        ]

pevalITEBoolBothAnd :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBothAnd :: Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Maybe (Term Bool)
pevalITEBoolBothAnd Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
f1 Term Bool
f2
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
f2
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
f1
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
f2
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
f1
  | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolRightAnd :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightAnd :: Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightAnd Term Bool
cond Term Bool
ifTrue Term Bool
f1 Term Bool
f2
  | Term Bool
f1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
f1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
f2
  | Term Bool
f2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
f2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
f1
  | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolLeftOr :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftOr :: Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftOr Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
ifFalse
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
cond Term Bool
t2
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
cond Term Bool
t1
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
t1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
t2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse
  | Bool
otherwise =
      [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
        [ Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies Term Bool
cond Term Bool
t1 (Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse) (Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
ifFalse),
          Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalInferImplies Term Bool
cond Term Bool
t2 (Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse) (Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
ifFalse)
        ]

pevalITEBoolBothOr :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBothOr :: Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Maybe (Term Bool)
pevalITEBoolBothOr Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
f1 Term Bool
f2
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
f2
  | Term Bool
t1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t2 Term Bool
f1
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f1 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
f2
  | Term Bool
t2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
f2 = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
t2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term Bool
t1 Term Bool
f1
  | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolRightOr :: Term Bool -> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightOr :: Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightOr Term Bool
cond Term Bool
ifTrue Term Bool
f1 Term Bool
f2
  | Term Bool
f1 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
f1 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
f2
  | Term Bool
f2 Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
f2 (Term Bool -> Term Bool) -> Term Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
f1
  | Bool
otherwise = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolLeft :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeft :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeft Term Bool
cond (AndTerm Int
_ Term Bool
t1 Term Bool
t2) Term Bool
ifFalse =
  [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
    [ Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftAnd Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
ifFalse,
      case Term Bool
ifFalse of
        AndTerm Int
_ Term Bool
f1 Term Bool
f2 -> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Maybe (Term Bool)
pevalITEBoolBothAnd Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
f1 Term Bool
f2
        Term Bool
_ -> Maybe (Term Bool)
forall a. Maybe a
Nothing
    ]
pevalITEBoolLeft Term Bool
cond (OrTerm Int
_ Term Bool
t1 Term Bool
t2) Term Bool
ifFalse =
  [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
    [ Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftOr Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
ifFalse,
      case Term Bool
ifFalse of
        OrTerm Int
_ Term Bool
f1 Term Bool
f2 -> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Term Bool
-> Maybe (Term Bool)
pevalITEBoolBothOr Term Bool
cond Term Bool
t1 Term Bool
t2 Term Bool
f1 Term Bool
f2
        Term Bool
_ -> Maybe (Term Bool)
forall a. Maybe a
Nothing
    ]
pevalITEBoolLeft Term Bool
cond (NotTerm Int
_ Term Bool
nIfTrue) Term Bool
ifFalse =
  [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
    [ Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeftNot Term Bool
cond Term Bool
nIfTrue Term Bool
ifFalse,
      case Term Bool
ifFalse of
        NotTerm Int
_ Term Bool
nIfFalse ->
          Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBothNot Term Bool
cond Term Bool
nIfTrue Term Bool
nIfFalse
        Term Bool
_ -> Maybe (Term Bool)
forall a. Maybe a
Nothing
    ]
pevalITEBoolLeft Term Bool
_ Term Bool
_ Term Bool
_ = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBoolNoLeft :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolNoLeft :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolNoLeft Term Bool
cond Term Bool
ifTrue (AndTerm Int
_ Term Bool
f1 Term Bool
f2) = Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightAnd Term Bool
cond Term Bool
ifTrue Term Bool
f1 Term Bool
f2
pevalITEBoolNoLeft Term Bool
cond Term Bool
ifTrue (OrTerm Int
_ Term Bool
f1 Term Bool
f2) = Term Bool
-> Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightOr Term Bool
cond Term Bool
ifTrue Term Bool
f1 Term Bool
f2
pevalITEBoolNoLeft Term Bool
cond Term Bool
ifTrue (NotTerm Int
_ Term Bool
nIfFalse) = Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolRightNot Term Bool
cond Term Bool
ifTrue Term Bool
nIfFalse
pevalITEBoolNoLeft Term Bool
_ Term Bool
_ Term Bool
_ = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBasic :: (SupportedPrim a) => Term Bool -> Term a -> Term a -> Maybe (Term a)
pevalITEBasic :: forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Maybe (Term a)
pevalITEBasic (ConTerm Int
_ Bool
True) Term a
ifTrue Term a
_ = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just Term a
ifTrue
pevalITEBasic (ConTerm Int
_ Bool
False) Term a
_ Term a
ifFalse = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just Term a
ifFalse
pevalITEBasic (NotTerm Int
_ Term Bool
ncond) Term a
ifTrue Term a
ifFalse = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
ncond Term a
ifFalse Term a
ifTrue
pevalITEBasic Term Bool
_ Term a
ifTrue Term a
ifFalse | Term a
ifTrue Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
ifFalse = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just Term a
ifTrue
pevalITEBasic (ITETerm Int
_ Term Bool
cc Term Bool
ct Term Bool
cf) (ITETerm Int
_ Term Bool
tc Term a
tt Term a
tf) (ITETerm Int
_ Term Bool
fc Term a
ft Term a
ff) -- later
  | Term Bool
cc Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
tc Bool -> Bool -> Bool
&& Term Bool
cc Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
fc = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cc (Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
ct Term a
tt Term a
ft) (Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cf Term a
tf Term a
ff)
pevalITEBasic Term Bool
cond (ITETerm Int
_ Term Bool
tc Term a
tt Term a
tf) Term a
ifFalse -- later
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
tc = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term a
tt Term a
ifFalse
  | Term a
tt Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
ifFalse = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm (Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
tc) Term a
tt Term a
tf
  | Term a
tf Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
ifFalse = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm (Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
cond Term Bool
tc) Term a
tt Term a
tf
pevalITEBasic Term Bool
cond Term a
ifTrue (ITETerm Int
_ Term Bool
fc Term a
ft Term a
ff) -- later
  | Term a
ifTrue Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
ft = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm (Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
fc) Term a
ifTrue Term a
ff
  | Term a
ifTrue Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
ff = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm (Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond (Term Bool -> Term Bool
pevalNotTerm Term Bool
fc)) Term a
ifTrue Term a
ft
  | Term Bool -> Term Bool -> Bool
pevalImpliesTerm Term Bool
fc Term Bool
cond = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just (Term a -> Maybe (Term a)) -> Term a -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITETerm Term Bool
cond Term a
ifTrue Term a
ff
pevalITEBasic Term Bool
_ Term a
_ Term a
_ = Maybe (Term a)
forall a. Maybe a
Nothing

pevalITEBoolBasic :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBasic :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBasic Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifTrue = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse
  | Term Bool
cond Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term Bool
ifFalse = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
cond Term Bool
ifTrue
pevalITEBoolBasic Term Bool
cond (ConTerm Int
_ Bool
v) Term Bool
ifFalse
  | Bool
v = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
cond Term Bool
ifFalse
  | Bool
otherwise = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifFalse
pevalITEBoolBasic Term Bool
cond Term Bool
ifTrue (ConTerm Int
_ Bool
v)
  | Bool
v = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
cond) Term Bool
ifTrue
  | Bool
otherwise = Term Bool -> Maybe (Term Bool)
forall a. a -> Maybe a
Just (Term Bool -> Maybe (Term Bool)) -> Term Bool -> Maybe (Term Bool)
forall a b. (a -> b) -> a -> b
$ Term Bool -> Term Bool -> Term Bool
pevalAndTerm Term Bool
cond Term Bool
ifTrue
pevalITEBoolBasic Term Bool
_ Term Bool
_ Term Bool
_ = Maybe (Term Bool)
forall a. Maybe a
Nothing

pevalITEBool :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBool :: Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBool Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse =
  [Maybe (Term Bool)] -> Maybe (Term Bool)
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum
    [ Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Maybe (Term a)
pevalITEBasic Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse,
      Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolBasic Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse,
      Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolLeft Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse,
      Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBoolNoLeft Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse
    ]

pevalITEBasicTerm :: (SupportedPrim a) => Term Bool -> Term a -> Term a -> Term a
pevalITEBasicTerm :: forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
pevalITEBasicTerm Term Bool
cond Term a
ifTrue Term a
ifFalse =
  Term a -> Maybe (Term a) -> Term a
forall a. a -> Maybe a -> a
fromMaybe (Term Bool -> Term a -> Term a -> Term a
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
iteTerm Term Bool
cond Term a
ifTrue Term a
ifFalse) (Maybe (Term a) -> Term a) -> Maybe (Term a) -> Term a
forall a b. (a -> b) -> a -> b
$
    Term Bool -> Term a -> Term a -> Maybe (Term a)
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Maybe (Term a)
pevalITEBasic Term Bool
cond Term a
ifTrue Term a
ifFalse

pevalDefaultEqTerm :: (SupportedPrim a) => Term a -> Term a -> Term Bool
pevalDefaultEqTerm :: forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm l :: Term a
l@ConTerm {} r :: Term a
r@ConTerm {} = Bool -> Term Bool
forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm (Bool -> Term Bool) -> Bool -> Term Bool
forall a b. (a -> b) -> a -> b
$ Term a
l Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
r
pevalDefaultEqTerm l :: Term a
l@ConTerm {} Term a
r = Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
r Term a
l
pevalDefaultEqTerm Term a
l (BoolConTerm Bool
rv) =
  if Bool
rv
    then Term a -> Term Bool
forall a b. a -> b
unsafeCoerce Term a
l
    else Term Bool -> Term Bool
pevalNotTerm (Term a -> Term Bool
forall a b. a -> b
unsafeCoerce Term a
l)
pevalDefaultEqTerm (NotTerm Int
_ Term Bool
lv) Term a
r
  | Term Bool
lv Term Bool -> Term Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
Term Bool
r = Term Bool
falseTerm
pevalDefaultEqTerm Term a
l (NotTerm Int
_ Term Bool
rv)
  | Term a
l Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
Term Bool
rv = Term Bool
falseTerm
pevalDefaultEqTerm (AddNumTerm Int
_ (ConTerm Int
_ a
c) Term a
v) (ConTerm Int
_ a
c2) =
  Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
v (a -> Term a
forall t.
(SupportedPrim t, Typeable t, Hashable t, Eq t, Show t) =>
t -> Term t
conTerm (a -> Term a) -> a -> Term a
forall a b. (a -> b) -> a -> b
$ a
c2 a -> a -> a
forall a. Num a => a -> a -> a
- a
c)
pevalDefaultEqTerm Term a
l (ITETerm Int
_ Term Bool
c Term a
t Term a
f)
  | Term a
l Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
t = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
c (Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
l Term a
f)
  | Term a
l Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
f = Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
c) (Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
l Term a
t)
pevalDefaultEqTerm (ITETerm Int
_ Term Bool
c Term a
t Term a
f) Term a
r
  | Term a
t Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
r = Term Bool -> Term Bool -> Term Bool
pevalOrTerm Term Bool
c (Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
f Term a
r)
  | Term a
f Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
r = Term Bool -> Term Bool -> Term Bool
pevalOrTerm (Term Bool -> Term Bool
pevalNotTerm Term Bool
c) (Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm Term a
t Term a
r)
pevalDefaultEqTerm Term a
l Term a
r
  | Term a
l Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
r = Term Bool
trueTerm
  | Bool
otherwise = Term a -> Term a -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
eqTerm Term a
l Term a
r
{-# INLINEABLE pevalDefaultEqTerm #-}

instance SBVRep Bool where
  type SBVType _ Bool = SBV.SBV Bool

instance SupportedPrimConstraint Bool

instance SupportedPrim Bool where
  pformatCon :: Bool -> String
pformatCon Bool
True = String
"true"
  pformatCon Bool
False = String
"false"
  defaultValue :: Bool
defaultValue = Bool
defaultValueForBool
  defaultValueDynamic :: forall (proxy :: * -> *). proxy Bool -> ModelValue
defaultValueDynamic proxy Bool
_ = ModelValue
defaultValueForBoolDyn
  pevalITETerm :: Term Bool -> Term Bool -> Term Bool -> Term Bool
pevalITETerm Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse =
    Term Bool -> Maybe (Term Bool) -> Term Bool
forall a. a -> Maybe a -> a
fromMaybe (Term Bool -> Term Bool -> Term Bool -> Term Bool
forall a.
SupportedPrim a =>
Term Bool -> Term a -> Term a -> Term a
iteTerm Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse) (Maybe (Term Bool) -> Term Bool) -> Maybe (Term Bool) -> Term Bool
forall a b. (a -> b) -> a -> b
$
      Term Bool -> Term Bool -> Term Bool -> Maybe (Term Bool)
pevalITEBool Term Bool
cond Term Bool
ifTrue Term Bool
ifFalse
  pevalEqTerm :: Term Bool -> Term Bool -> Term Bool
pevalEqTerm = Term Bool -> Term Bool -> Term Bool
forall a. SupportedPrim a => Term a -> Term a -> Term Bool
pevalDefaultEqTerm
  conSBVTerm :: forall (n :: Nat) (proxy :: Nat -> *).
KnownIsZero n =>
proxy n -> Bool -> SBVType n Bool
conSBVTerm proxy n
_ Bool
n = if Bool
n then SBV Bool
SBVType n Bool
SBV.sTrue else SBV Bool
SBVType n Bool
SBV.sFalse
  symSBVName :: TypedSymbol Bool -> Int -> String
symSBVName TypedSymbol Bool
symbol Int
_ = TypedSymbol Bool -> String
forall a. Show a => a -> String
show TypedSymbol Bool
symbol
  symSBVTerm :: forall (m :: * -> *) (n :: Nat) (proxy :: Nat -> *).
(SBVFreshMonad m, KnownIsZero n) =>
proxy n -> String -> m (SBVType n Bool)
symSBVTerm proxy n
_ = String -> m (SBV Bool)
String -> m (SBVType n Bool)
forall a. SymVal a => String -> m (SBV a)
forall (m :: * -> *) a.
(SBVFreshMonad m, SymVal a) =>
String -> m (SBV a)
sbvFresh
  withPrim :: forall (n :: Nat) (p :: Nat -> *) a.
KnownIsZero n =>
p n
-> ((PrimConstraint n Bool, SMTDefinable (SBVType n Bool),
     Mergeable (SBVType n Bool), Typeable (SBVType n Bool)) =>
    a)
-> a
withPrim p n
_ (PrimConstraint n Bool, SMTDefinable (SBVType n Bool),
 Mergeable (SBVType n Bool), Typeable (SBVType n Bool)) =>
a
r = a
(PrimConstraint n Bool, SMTDefinable (SBVType n Bool),
 Mergeable (SBVType n Bool), Typeable (SBVType n Bool)) =>
a
r
  parseSMTModelResult :: Int -> ([([CV], CV)], CV) -> Bool
parseSMTModelResult Int
_ ([], SBVD.CV Kind
SBVD.KBool (SBVD.CInteger Integer
n)) = Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
  parseSMTModelResult Int
_ ([([], SBVD.CV Kind
SBVD.KBool (SBVD.CInteger Integer
n))], CV
_) = Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0
  parseSMTModelResult Int
_ ([([CV], CV)], CV)
cv = TypeRep Bool -> ([([CV], CV)], CV) -> Bool
forall a. TypeRep a -> ([([CV], CV)], CV) -> a
parseSMTModelResultError (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @Bool) ([([CV], CV)], CV)
cv

instance NonFuncSBVRep Bool where
  type NonFuncSBVBaseType _ Bool = Bool

instance SupportedNonFuncPrim Bool where
  conNonFuncSBVTerm :: forall (n :: Nat) (proxy :: Nat -> *).
KnownIsZero n =>
proxy n -> Bool -> SBV (NonFuncSBVBaseType n Bool)
conNonFuncSBVTerm = proxy n -> Bool -> SBV (NonFuncSBVBaseType n Bool)
proxy n -> Bool -> SBVType n Bool
forall (n :: Nat) (proxy :: Nat -> *).
KnownIsZero n =>
proxy n -> Bool -> SBVType n Bool
forall t (n :: Nat) (proxy :: Nat -> *).
(SupportedPrim t, KnownIsZero n) =>
proxy n -> t -> SBVType n t
conSBVTerm
  symNonFuncSBVTerm :: forall (m :: * -> *) (n :: Nat) (proxy :: Nat -> *).
(SBVFreshMonad m, KnownIsZero n) =>
proxy n -> String -> m (SBV (NonFuncSBVBaseType n Bool))
symNonFuncSBVTerm = forall t (m :: * -> *) (n :: Nat) (proxy :: Nat -> *).
(SupportedPrim t, SBVFreshMonad m, KnownIsZero n) =>
proxy n -> String -> m (SBVType n t)
symSBVTerm @Bool
  withNonFuncPrim :: forall (n :: Nat) (proxy :: Nat -> *) r.
KnownIsZero n =>
proxy n
-> ((SymVal (NonFuncSBVBaseType n Bool),
     EqSymbolic (SBVType n Bool), Mergeable (SBVType n Bool),
     SMTDefinable (SBVType n Bool), Mergeable (SBVType n Bool),
     SBVType n Bool ~ SBV (NonFuncSBVBaseType n Bool),
     PrimConstraint n Bool) =>
    r)
-> r
withNonFuncPrim proxy n
_ (SymVal (NonFuncSBVBaseType n Bool), EqSymbolic (SBVType n Bool),
 Mergeable (SBVType n Bool), SMTDefinable (SBVType n Bool),
 Mergeable (SBVType n Bool),
 SBVType n Bool ~ SBV (NonFuncSBVBaseType n Bool),
 PrimConstraint n Bool) =>
r
r = r
(SymVal (NonFuncSBVBaseType n Bool), EqSymbolic (SBVType n Bool),
 Mergeable (SBVType n Bool), SMTDefinable (SBVType n Bool),
 Mergeable (SBVType n Bool),
 SBVType n Bool ~ SBV (NonFuncSBVBaseType n Bool),
 PrimConstraint n Bool) =>
r
r