liquid-fixpoint-8.10.7: src/Language/Fixpoint/Congruence/Types.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Language.Fixpoint.Congruence.Types
( -- * Queries
CongQuery (..)
, Equality (..)
, Disequality (..)
-- * Terms
, Term
, identity
-- * Constructors
, app
, var
) where
import Data.Function (on)
import Data.Hashable
import Data.Interned
import qualified Language.Fixpoint.Types as F
-- 1. x = y => f x = f y
-- 2. f(f(f(x))) = x => f(f(f(f(f(x))))) = x => f(x) = a
_examples = [t1, t2]
where
t1 = app "f" [var "x", var "y"]
t2 = app "f" [var "x", var "y"]
data CongQuery = Query [Equality] [Disequality]
data Equality = Eq Term Term
data Disequality = Diseq Term Term
--------------------------------------------------------------------------------
-- | Exported Constructors
--------------------------------------------------------------------------------
app :: F.Symbol -> [Term] -> Term
app f as = intern (BApp f as)
var :: F.Symbol -> Term
var x = intern (BVar x)
--------------------------------------------------------------------------------
-- | Hash-consed Term DataType
--------------------------------------------------------------------------------
data Term
= Var {-# UNPACK #-} !Id !F.Symbol
| App {-# UNPACK #-} !Id !F.Symbol [Term]
--------------------------------------------------------------------------------
data UninternedTerm
= BVar !F.Symbol
| BApp !F.Symbol [Term]
instance Interned Term where
type Uninterned Term = UninternedTerm
data Description Term = DVar F.Symbol
| DApp F.Symbol [Id]
deriving Show
describe (BApp f as) = DApp f (identity <$> as)
describe (BVar x) = DVar x
identify i = go
where
go (BApp f as) = App i f as
go (BVar x) = Var i x
cache = termCache
identity :: Term -> Id
identity (App i _ _) = i
identity (Var i _) = i
instance Uninternable Term where
unintern (App _ f as) = BApp f as
unintern (Var _ x) = BVar x
termCache :: Cache Term
termCache = mkCache
{-# NOINLINE termCache #-}
instance Eq (Description Term) where
DApp f as == DApp f' as' = f == f' && as == as'
DVar x == DVar x' = x == x'
_ == _ = False
instance Hashable (Description Term) where
hashWithSalt s (DApp f a) = s `hashWithSalt` (0 :: Int) `hashWithSalt` f `hashWithSalt` a
hashWithSalt s (DVar n) = s `hashWithSalt` (3 :: Int) `hashWithSalt` n
instance Eq Term where
(==) = (==) `on` identity
instance Ord Term where
compare = compare `on` identity