{-# LANGUAGE CPP #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Language.Fixpoint.Horn.Transformations (
uniq
, flatten
, elim
, elimPis
, solveEbs
, cstrToExpr
) where
import Language.Fixpoint.Horn.Types
import Language.Fixpoint.Horn.Info
import Language.Fixpoint.Smt.Theories as F
import qualified Language.Fixpoint.Types as F
import qualified Language.Fixpoint.Types.Config as F
import Language.Fixpoint.Graph as FG
import qualified Data.HashMap.Strict as M
import Data.String (IsString (..))
import Data.Either (partitionEithers, rights)
#if MIN_VERSION_base(4,20,0)
import Data.List (nub)
#else
import Data.List (nub, foldl')
#endif
import qualified Data.Set as S
import qualified Data.HashSet as HS
import qualified Data.Graph as DG
import Control.Monad.State
import Data.Maybe (catMaybes, mapMaybe, fromMaybe)
import Language.Fixpoint.Types.Visitor as V
import System.Console.CmdArgs.Verbosity
import Data.Bifunctor (first, second)
import System.IO (hFlush, stdout)
trace :: String -> a -> a
trace :: forall a. [Char] -> a -> a
trace [Char]
_msg a
v = a
v
printPiSols :: (F.PPrint a1, F.PPrint a2, F.PPrint a3) =>
M.HashMap a1 ((a4, a2), a3) -> IO ()
printPiSols :: forall a1 a2 a3 a4.
(PPrint a1, PPrint a2, PPrint a3) =>
HashMap a1 ((a4, a2), a3) -> IO ()
printPiSols HashMap a1 ((a4, a2), a3)
piSols =
((a1, ((a4, a2), a3)) -> IO ()) -> [(a1, ((a4, a2), a3))] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_
(\(a1
piVar', ((a4
_, a2
args), a3
cstr)) -> do
[Char] -> IO ()
putStr ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ a1 -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp a1
piVar'
[Char] -> IO ()
putStr [Char]
" := "
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ a2 -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp a2
args
[Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ a3 -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp a3
cstr
[Char] -> IO ()
putStr [Char]
"\n"
Handle -> IO ()
hFlush Handle
stdout)
(HashMap a1 ((a4, a2), a3) -> [(a1, ((a4, a2), a3))]
forall k v. HashMap k v -> [(k, v)]
M.toList HashMap a1 ((a4, a2), a3)
piSols)
solveEbs :: (F.Fixpoint a, F.PPrint a) => F.Config -> Query a -> IO (Query a)
solveEbs :: forall a.
(Fixpoint a, PPrint a) =>
Config -> Query a -> IO (Query a)
solveEbs Config
cfg query :: Query a
query@(Query {}) = do
let cons :: HashMap Symbol Sort
cons = Query a -> HashMap Symbol Sort
forall a. Query a -> HashMap Symbol Sort
qCon Query a
query
let cstr :: Cstr a
cstr = Query a -> Cstr a
forall a. Query a -> Cstr a
qCstr Query a
query
let dist :: HashMap Symbol Sort
dist = Query a -> HashMap Symbol Sort
forall a. Query a -> HashMap Symbol Sort
qDis Query a
query
let normalizedC :: Cstr a
normalizedC = Cstr a -> Cstr a
forall a. Flatten a => a -> a
flatten (Cstr a -> Cstr a) -> (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
pruneTauts (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
hornify Cstr a
cstr
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"Normalized EHC:"
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
normalizedC
if Cstr a -> Bool
forall a. Cstr a -> Bool
isNNF Cstr a
cstr then Query a -> IO (Query a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query a -> IO (Query a)) -> Query a -> IO (Query a)
forall a b. (a -> b) -> a -> b
$ Query a
query{ qCstr = normalizedC } else do
let kvars :: Set Symbol
kvars = Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
normalizedC
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"Skolemized:"
let poked :: Cstr a
poked = Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
pokec Cstr a
normalizedC
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
poked
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"Skolemized + split:"
let (Cstr a
_horn, Cstr a
_side) = case Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
forall a. Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
split Cstr a
poked of
(Just Cstr a
h, Just Cstr a
s) -> (Cstr a
h, Cstr a
s)
(Maybe (Cstr a), Maybe (Cstr a))
_ -> [Char] -> (Cstr a, Cstr a)
forall a. HasCallStack => [Char] -> a
error [Char]
"Couldn't split poked in solveEbs"
let horn :: Cstr a
horn = Cstr a -> Cstr a
forall a. Flatten a => a -> a
flatten (Cstr a -> Cstr a) -> (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
pruneTauts (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a
_horn
let side :: Cstr a
side = Cstr a -> Cstr a
forall a. Flatten a => a -> a
flatten (Cstr a -> Cstr a) -> (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
pruneTauts (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a
_side
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ (Cstr a, Cstr a) -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp (Cstr a
horn, Cstr a
side)
let pivars :: Set Symbol
pivars = Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
poked Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` Set Symbol
kvars
let cuts :: Set Symbol
cuts = Config -> Query a -> Cstr a -> Set Symbol
forall a.
(Fixpoint a, PPrint a) =>
Config -> Query a -> Cstr a -> Set Symbol
calculateCuts Config
cfg Query a
query (Set Symbol -> Cstr a -> Cstr a
forall a. Set Symbol -> Cstr a -> Cstr a
forgetPiVars Set Symbol
pivars Cstr a
horn)
let acyclicKs :: Set Symbol
acyclicKs = Set Symbol
kvars Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` Set Symbol
cuts
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"solved acyclic kvars:"
let (Cstr a
hornk, Cstr a
sidek) = [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
forall a. [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimKs' (Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList Set Symbol
acyclicKs) (Cstr a
horn, Cstr a
side)
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
hornk
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
sidek
let elimCutK :: Symbol -> Cstr a -> Cstr a
elimCutK Symbol
k Cstr a
c = Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [] Cstr a
c
hornCut :: Cstr a
hornCut = (Symbol -> Cstr a -> Cstr a) -> Cstr a -> Set Symbol -> Cstr a
forall a b. (a -> b -> b) -> b -> Set a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Symbol -> Cstr a -> Cstr a
forall {a}. Symbol -> Cstr a -> Cstr a
elimCutK Cstr a
hornk Set Symbol
cuts
sideCut :: Cstr a
sideCut = (Symbol -> Cstr a -> Cstr a) -> Cstr a -> Set Symbol -> Cstr a
forall a b. (a -> b -> b) -> b -> Set a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Symbol -> Cstr a -> Cstr a
forall {a}. Symbol -> Cstr a -> Cstr a
elimCutK Cstr a
sidek Set Symbol
cuts
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"pi defining constraints:"
let piSols :: HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols = [(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a))
-> [(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
forall a b. (a -> b) -> a -> b
$ (Symbol -> (Symbol, ((Symbol, [Symbol]), Cstr a)))
-> [Symbol] -> [(Symbol, ((Symbol, [Symbol]), Cstr a))]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Symbol
pivar -> (Symbol
pivar, Symbol -> Cstr a -> ((Symbol, [Symbol]), Cstr a)
forall a. Symbol -> Cstr a -> ((Symbol, [Symbol]), Cstr a)
piDefConstr Symbol
pivar Cstr a
hornCut)) (Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList Set Symbol
pivars)
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ HashMap Symbol ((Symbol, [Symbol]), Cstr a) -> IO ()
forall a1 a2 a3 a4.
(PPrint a1, PPrint a2, PPrint a3) =>
HashMap a1 ((a4, a2), a3) -> IO ()
printPiSols HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"solved pis:"
let solvedPiCstrs :: HashMap Symbol Pred
solvedPiCstrs = Config
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
forall a.
Config
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
solPis Config
cfg ([Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList ([Symbol] -> Set Symbol) -> [Symbol] -> Set Symbol
forall a b. (a -> b) -> a -> b
$ HashMap Symbol Sort -> [Symbol]
forall k v. HashMap k v -> [k]
M.keys HashMap Symbol Sort
cons [Symbol] -> [Symbol] -> [Symbol]
forall a. [a] -> [a] -> [a]
++ HashMap Symbol Sort -> [Symbol]
forall k v. HashMap k v -> [k]
M.keys HashMap Symbol Sort
dist) HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ HashMap Symbol Pred -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp HashMap Symbol Pred
solvedPiCstrs
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"solved horn:"
let solvedHorn :: Cstr a
solvedHorn = HashMap Symbol Pred -> Cstr a -> Cstr a
forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
solvedPiCstrs Cstr a
hornCut
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
solvedHorn
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn [Char]
"solved side:"
let solvedSide :: Cstr a
solvedSide = HashMap Symbol Pred -> Cstr a -> Cstr a
forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
solvedPiCstrs Cstr a
sideCut
IO () -> IO ()
whenLoud (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> IO ()
putStrLn ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$ Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
solvedSide
Query a -> IO (Query a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query a
query { qCstr = CAnd [solvedHorn, solvedSide] })
piDefConstr :: F.Symbol -> Cstr a -> ((F.Symbol, [F.Symbol]), Cstr a)
piDefConstr :: forall a. Symbol -> Cstr a -> ((Symbol, [Symbol]), Cstr a)
piDefConstr Symbol
k Cstr a
c = (([Symbol] -> Symbol
forall a. HasCallStack => [a] -> a
head [Symbol]
syms, [[Symbol]] -> [Symbol]
forall a. HasCallStack => [a] -> a
head [[Symbol]]
formalSyms), Cstr a
defCStr)
where
([Symbol]
syms, [[Symbol]]
formalSyms, Cstr a
defCStr) = case Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall a. Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
go Cstr a
c of
([Symbol]
ns, [[Symbol]]
formals, Just Cstr a
defC) -> ([Symbol]
ns, [[Symbol]]
formals, Cstr a
defC)
([Symbol]
_, [[Symbol]]
_, Maybe (Cstr a)
Nothing) -> [Char] -> ([Symbol], [[Symbol]], Cstr a)
forall a. HasCallStack => [Char] -> a
error ([Char] -> ([Symbol], [[Symbol]], Cstr a))
-> [Char] -> ([Symbol], [[Symbol]], Cstr a)
forall a b. (a -> b) -> a -> b
$ [Char]
"pi variable " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Symbol -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Symbol
k [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" has no defining constraint."
go :: Cstr a -> ([F.Symbol], [[F.Symbol]], Maybe (Cstr a))
go :: forall a. Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
go (CAnd [Cstr a]
cs) = (\([[Symbol]]
as, [[[Symbol]]]
bs, [Maybe (Cstr a)]
mcs) -> ([[Symbol]] -> [Symbol]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Symbol]]
as, [[[Symbol]]] -> [[Symbol]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[[Symbol]]]
bs, [Maybe (Cstr a)] -> Maybe (Cstr a)
forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
cAndMaybes [Maybe (Cstr a)]
mcs)) (([[Symbol]], [[[Symbol]]], [Maybe (Cstr a)])
-> ([Symbol], [[Symbol]], Maybe (Cstr a)))
-> ([[Symbol]], [[[Symbol]]], [Maybe (Cstr a)])
-> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall a b. (a -> b) -> a -> b
$ [([Symbol], [[Symbol]], Maybe (Cstr a))]
-> ([[Symbol]], [[[Symbol]]], [Maybe (Cstr a)])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 ([([Symbol], [[Symbol]], Maybe (Cstr a))]
-> ([[Symbol]], [[[Symbol]]], [Maybe (Cstr a)]))
-> [([Symbol], [[Symbol]], Maybe (Cstr a))]
-> ([[Symbol]], [[[Symbol]]], [Maybe (Cstr a)])
forall a b. (a -> b) -> a -> b
$ Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall a. Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
go (Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a)))
-> [Cstr a] -> [([Symbol], [[Symbol]], Maybe (Cstr a))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
go (All b :: Bind a
b@(Bind Symbol
n Sort
_ (Var Symbol
k' [Symbol]
xs) a
_) Cstr a
c')
| Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k' = ([Symbol
n], [Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList (Set Symbol -> [Symbol]) -> Set Symbol -> [Symbol]
forall a b. (a -> b) -> a -> b
$ [Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList [Symbol]
xs Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` Symbol -> Set Symbol
forall a. a -> Set a
S.singleton Symbol
n], Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c')
| Bool
otherwise = (Maybe (Cstr a) -> Maybe (Cstr a))
-> ([Symbol], [[Symbol]], Maybe (Cstr a))
-> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall c d a b. (c -> d) -> (a, b, c) -> (a, b, d)
map3 ((Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b)) (Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall a. Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
go Cstr a
c')
go (All Bind a
b Cstr a
c') = (Maybe (Cstr a) -> Maybe (Cstr a))
-> ([Symbol], [[Symbol]], Maybe (Cstr a))
-> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall c d a b. (c -> d) -> (a, b, c) -> (a, b, d)
map3 ((Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b)) (Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
forall a. Cstr a -> ([Symbol], [[Symbol]], Maybe (Cstr a))
go Cstr a
c')
go Cstr a
_ = ([], [], Maybe (Cstr a)
forall a. Maybe a
Nothing)
cAndMaybes :: [Maybe (Cstr a)] -> Maybe (Cstr a)
cAndMaybes :: forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
cAndMaybes [Maybe (Cstr a)]
maybeCs = case [Maybe (Cstr a)] -> [Cstr a]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (Cstr a)]
maybeCs of
[] -> Maybe (Cstr a)
forall a. Maybe a
Nothing
[Cstr a]
cs -> Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Cstr a]
cs
map3 :: (c -> d) -> (a, b, c) -> (a, b, d)
map3 :: forall c d a b. (c -> d) -> (a, b, c) -> (a, b, d)
map3 c -> d
f (a
x, b
y, c
z) = (a
x, b
y, c -> d
f c
z)
solPis :: F.Config -> S.Set F.Symbol -> M.HashMap F.Symbol ((F.Symbol, [F.Symbol]), Cstr a) -> M.HashMap F.Symbol Pred
solPis :: forall a.
Config
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
solPis Config
cfg Set Symbol
measures HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSolsMap = [(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
forall {a}.
[(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
go (HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> [(Symbol, ((Symbol, [Symbol]), Cstr a))]
forall k v. HashMap k v -> [(k, v)]
M.toList HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSolsMap) HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSolsMap
where
go :: [(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
go ((Symbol
pi', ((Symbol
n, [Symbol]
xs), Cstr a
c)):[(Symbol, ((Symbol, [Symbol]), Cstr a))]
pis) HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols = Symbol -> Pred -> HashMap Symbol Pred -> HashMap Symbol Pred
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert Symbol
pi' Pred
solved (HashMap Symbol Pred -> HashMap Symbol Pred)
-> HashMap Symbol Pred -> HashMap Symbol Pred
forall a b. (a -> b) -> a -> b
$ [(Symbol, ((Symbol, [Symbol]), Cstr a))]
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> HashMap Symbol Pred
go [(Symbol, ((Symbol, [Symbol]), Cstr a))]
pis HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols
where solved :: Pred
solved = Config
-> Set Symbol
-> Symbol
-> Symbol
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> Cstr a
-> Pred
forall a.
Config
-> Set Symbol
-> Symbol
-> Symbol
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> Cstr a
-> Pred
solPi Config
cfg Set Symbol
measures Symbol
pi' Symbol
n ([Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList [Symbol]
xs) HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols Cstr a
c
go [] HashMap Symbol ((Symbol, [Symbol]), Cstr a)
_ = HashMap Symbol Pred
forall a. Monoid a => a
mempty
solPi :: F.Config -> S.Set F.Symbol -> F.Symbol -> F.Symbol -> S.Set F.Symbol -> M.HashMap F.Symbol ((F.Symbol, [F.Symbol]), Cstr a) -> Cstr a -> Pred
solPi :: forall a.
Config
-> Set Symbol
-> Symbol
-> Symbol
-> Set Symbol
-> HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> Cstr a
-> Pred
solPi Config
cfg Set Symbol
measures Symbol
basePi Symbol
n Set Symbol
args HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols Cstr a
cstr = [Char] -> Pred -> Pred
forall a. [Char] -> a -> a
trace ([Char]
"\n\nsolPi: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Symbol -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Symbol
basePi [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Symbol -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Symbol
n [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Symbol] -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp (Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList Set Symbol
args) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [((Symbol, [Expr]), [Symbol])] -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp ((\((Symbol, [Expr])
a, Symbol
_, [Symbol]
c) -> ((Symbol, [Expr])
a, [Symbol]
c)) (((Symbol, [Expr]), Symbol, [Symbol])
-> ((Symbol, [Expr]), [Symbol]))
-> [((Symbol, [Expr]), Symbol, [Symbol])]
-> [((Symbol, [Expr]), [Symbol])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [((Symbol, [Expr]), Symbol, [Symbol])]
edges) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Expr] -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp (Symbol -> [Expr]
sols Symbol
n) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Pred] -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp [Pred]
rewritten [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Cstr a -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Cstr a
cstr [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\n\n") (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ [Pred] -> Pred
PAnd [Pred]
rewritten
where
rewritten :: [Pred]
rewritten = Config
-> Set Symbol -> Symbol -> Set Symbol -> [(Symbol, Expr)] -> [Pred]
rewriteWithEqualities Config
cfg Set Symbol
measures Symbol
n Set Symbol
args [(Symbol, Expr)]
equalities
equalities :: [(Symbol, Expr)]
equalities = ([(Symbol, Expr)] -> [(Symbol, Expr)]
forall a. Eq a => [a] -> [a]
nub ([(Symbol, Expr)] -> [(Symbol, Expr)])
-> (([(Symbol, Expr)], Set Symbol) -> [(Symbol, Expr)])
-> ([(Symbol, Expr)], Set Symbol)
-> [(Symbol, Expr)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(Symbol, Expr)], Set Symbol) -> [(Symbol, Expr)]
forall a b. (a, b) -> a
fst) (([(Symbol, Expr)], Set Symbol) -> [(Symbol, Expr)])
-> ([(Symbol, Expr)], Set Symbol) -> [(Symbol, Expr)]
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go (Symbol -> Set Symbol
forall a. a -> Set a
S.singleton Symbol
basePi) Cstr a
cstr
edges :: [((Symbol, [Expr]), Symbol, [Symbol])]
edges = Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
args HashMap Symbol ([Symbol], [Expr])
forall a. Monoid a => a
mempty [(Symbol, Expr)]
equalities
(Graph
eGraph, Int -> ((Symbol, [Expr]), Symbol, [Symbol])
vf, Symbol -> Maybe Int
lookupVertex) = [((Symbol, [Expr]), Symbol, [Symbol])]
-> (Graph, Int -> ((Symbol, [Expr]), Symbol, [Symbol]),
Symbol -> Maybe Int)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Int -> (node, key, [key]), key -> Maybe Int)
DG.graphFromEdges [((Symbol, [Expr]), Symbol, [Symbol])]
edges
sols :: Symbol -> [Expr]
sols Symbol
x = case Symbol -> Maybe Int
lookupVertex Symbol
x of
Maybe Int
Nothing -> []
Just Int
vertex -> [Expr] -> [Expr]
forall a. Eq a => [a] -> [a]
nub ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter (Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
/= Symbol -> Expr
forall v. v -> ExprV v
F.EVar Symbol
x) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Expr]
forall a. Monoid a => [a] -> a
mconcat [[Expr]
es | ((Symbol
_, [Expr]
es), Symbol
_, [Symbol]
_) <- Int -> ((Symbol, [Expr]), Symbol, [Symbol])
vf (Int -> ((Symbol, [Expr]), Symbol, [Symbol]))
-> [Int] -> [((Symbol, [Expr]), Symbol, [Symbol])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Graph -> Int -> [Int]
DG.reachable Graph
eGraph Int
vertex]
go :: S.Set F.Symbol -> Cstr a -> ([(F.Symbol, F.Expr)], S.Set F.Symbol)
go :: forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go Set Symbol
visitedSyms (Head Pred
p a
_) = (Pred -> [(Symbol, Expr)]
collectEqualities Pred
p, Set Symbol
visitedSyms)
go Set Symbol
visitedSyms (CAnd [Cstr a]
cs) = (([(Symbol, Expr)], Set Symbol)
-> Cstr a -> ([(Symbol, Expr)], Set Symbol))
-> ([(Symbol, Expr)], Set Symbol)
-> [Cstr a]
-> ([(Symbol, Expr)], Set Symbol)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\([(Symbol, Expr)]
eqs, Set Symbol
visited) Cstr a
c -> let ([(Symbol, Expr)]
eqs', Set Symbol
visited') = Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go Set Symbol
visited Cstr a
c in ([(Symbol, Expr)]
eqs' [(Symbol, Expr)] -> [(Symbol, Expr)] -> [(Symbol, Expr)]
forall a. Semigroup a => a -> a -> a
<> [(Symbol, Expr)]
eqs, Set Symbol
visited')) ([(Symbol, Expr)]
forall a. Monoid a => a
mempty, Set Symbol
visitedSyms) [Cstr a]
cs
go Set Symbol
visited (All (Bind Symbol
_ Sort
_ (Var Symbol
pi' [Symbol]
_) a
_) Cstr a
c)
| Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member Symbol
pi' Set Symbol
visited = Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go Set Symbol
visited Cstr a
c
| Bool
otherwise = let ((Symbol, [Symbol])
_, Cstr a
defC) = (HashMap Symbol ((Symbol, [Symbol]), Cstr a)
piSols HashMap Symbol ((Symbol, [Symbol]), Cstr a)
-> Symbol -> ((Symbol, [Symbol]), Cstr a)
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
M.! Symbol
pi')
([(Symbol, Expr)]
eqs', Set Symbol
newVisited) = Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go (Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => a -> Set a -> Set a
S.insert Symbol
pi' Set Symbol
visited) Cstr a
defC
([(Symbol, Expr)]
eqs'', Set Symbol
newVisited') = Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go Set Symbol
newVisited Cstr a
c in
([(Symbol, Expr)]
eqs' [(Symbol, Expr)] -> [(Symbol, Expr)] -> [(Symbol, Expr)]
forall a. Semigroup a => a -> a -> a
<> [(Symbol, Expr)]
eqs'', Set Symbol
newVisited')
go Set Symbol
visited (All (Bind Symbol
_ Sort
_ Pred
p a
_) Cstr a
c) = let ([(Symbol, Expr)]
eqs, Set Symbol
visited') = Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
forall a. Set Symbol -> Cstr a -> ([(Symbol, Expr)], Set Symbol)
go Set Symbol
visited Cstr a
c in
([(Symbol, Expr)]
eqs [(Symbol, Expr)] -> [(Symbol, Expr)] -> [(Symbol, Expr)]
forall a. Semigroup a => a -> a -> a
<> Pred -> [(Symbol, Expr)]
collectEqualities Pred
p, Set Symbol
visited')
go Set Symbol
_ Any{} = [Char] -> ([(Symbol, Expr)], Set Symbol)
forall a. HasCallStack => [Char] -> a
error [Char]
"exists should not be present in piSols"
pokec :: Cstr a -> Cstr a
pokec :: forall a. Cstr a -> Cstr a
pokec = [Symbol] -> Cstr a -> Cstr a
forall {a}. [Symbol] -> Cstr a -> Cstr a
go [Symbol]
forall a. Monoid a => a
mempty
where
go :: [Symbol] -> Cstr a -> Cstr a
go [Symbol]
_ (Head Pred
c a
l) = Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
c a
l
go [Symbol]
xs (CAnd [Cstr a]
c) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Symbol] -> Cstr a -> Cstr a
go [Symbol]
xs (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
c)
go [Symbol]
xs (All Bind a
b Cstr a
c2) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ [Symbol] -> Cstr a -> Cstr a
go (Bind a -> Symbol
forall a. Bind a -> Symbol
bSym Bind a
b Symbol -> [Symbol] -> [Symbol]
forall a. a -> [a] -> [a]
: [Symbol]
xs) Cstr a
c2
go [Symbol]
xs (Any b :: Bind a
b@(Bind Symbol
x Sort
t Pred
p a
ann) Cstr a
c2) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b' (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
p a
l, [Symbol] -> Cstr a -> Cstr a
go (Symbol
xSymbol -> [Symbol] -> [Symbol]
forall a. a -> [a] -> [a]
:[Symbol]
xs) Cstr a
c2], Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any Bind a
b (Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
pi' a
l)]
where
b' :: Bind a
b' = Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t Pred
pi' a
ann
pi' :: Pred
pi' = Symbol -> [Symbol] -> Pred
piVar Symbol
x [Symbol]
xs
l :: a
l = Cstr a -> a
forall a. Cstr a -> a
cLabel Cstr a
c2
piVar :: F.Symbol -> [F.Symbol] -> Pred
piVar :: Symbol -> [Symbol] -> Pred
piVar Symbol
x [Symbol]
xs = Symbol -> [Symbol] -> Pred
Var (Symbol -> Symbol
piSym Symbol
x) (Symbol
xSymbol -> [Symbol] -> [Symbol]
forall a. a -> [a] -> [a]
:[Symbol]
xs)
piSym :: F.Symbol -> F.Symbol
piSym :: Symbol -> Symbol
piSym Symbol
s = [Char] -> Symbol
forall a. IsString a => [Char] -> a
fromString ([Char] -> Symbol) -> [Char] -> Symbol
forall a b. (a -> b) -> a -> b
$ [Char]
"π" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Symbol -> [Char]
F.symbolString Symbol
s
split :: Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
split :: forall a. Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
split (CAnd [Cstr a]
cs) = ([Maybe (Cstr a)] -> Maybe (Cstr a)
forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
andMaybes [Maybe (Cstr a)]
nosides, [Maybe (Cstr a)] -> Maybe (Cstr a)
forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
andMaybes [Maybe (Cstr a)]
sides)
where ([Maybe (Cstr a)]
nosides, [Maybe (Cstr a)]
sides) = [(Maybe (Cstr a), Maybe (Cstr a))]
-> ([Maybe (Cstr a)], [Maybe (Cstr a)])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Maybe (Cstr a), Maybe (Cstr a))]
-> ([Maybe (Cstr a)], [Maybe (Cstr a)]))
-> [(Maybe (Cstr a), Maybe (Cstr a))]
-> ([Maybe (Cstr a)], [Maybe (Cstr a)])
forall a b. (a -> b) -> a -> b
$ Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
forall a. Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
split (Cstr a -> (Maybe (Cstr a), Maybe (Cstr a)))
-> [Cstr a] -> [(Maybe (Cstr a), Maybe (Cstr a))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
split (All Bind a
b Cstr a
c) = (Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Cstr a)
c', Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Cstr a)
c'')
where (Maybe (Cstr a)
c',Maybe (Cstr a)
c'') = Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
forall a. Cstr a -> (Maybe (Cstr a), Maybe (Cstr a))
split Cstr a
c
split c :: Cstr a
c@Any{} = (Maybe (Cstr a)
forall a. Maybe a
Nothing, Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c)
split c :: Cstr a
c@Head{} = (Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c, Maybe (Cstr a)
forall a. Maybe a
Nothing)
andMaybes :: [Maybe (Cstr a)] -> Maybe (Cstr a)
andMaybes :: forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
andMaybes [Maybe (Cstr a)]
mcs = case [Maybe (Cstr a)] -> [Cstr a]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (Cstr a)]
mcs of
[] -> Maybe (Cstr a)
forall a. Maybe a
Nothing
[Cstr a
c] -> Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c
[Cstr a]
cs -> Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Cstr a]
cs
elimPis :: [F.Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimPis :: forall a. [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimPis [] (Cstr a, Cstr a)
cc = (Cstr a, Cstr a)
cc
elimPis (Symbol
n:[Symbol]
ns) (Cstr a
horn, Cstr a
side) = [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
forall a. [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimPis [Symbol]
ns (Cstr a -> Cstr a
apply Cstr a
horn, Cstr a -> Cstr a
apply Cstr a
side)
where nSol' :: Cstr a
nSol' = case Symbol -> Cstr a -> Maybe (Cstr a)
forall a. Symbol -> Cstr a -> Maybe (Cstr a)
defs Symbol
n Cstr a
horn of
Just Cstr a
nSol -> Cstr a
nSol
Maybe (Cstr a)
Nothing -> [Char] -> Cstr a
forall a. HasCallStack => [Char] -> a
error [Char]
"Unexpected nothing elimPis"
apply :: Cstr a -> Cstr a
apply = Symbol -> Cstr a -> Cstr a -> Cstr a
forall a. Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi (Symbol -> Symbol
piSym Symbol
n) Cstr a
nSol'
applyPi :: F.Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi :: forall a. Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi Symbol
k Cstr a
defCstr (All (Bind Symbol
x Sort
t (Var Symbol
k' [Symbol]
_xs) a
ann) Cstr a
c)
| Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k'
= Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Expr -> Pred
Reft (Expr -> Pred) -> Expr -> Pred
forall a b. (a -> b) -> a -> b
$ Cstr a -> Expr
forall a. Cstr a -> Expr
cstrToExpr Cstr a
defCstr) a
ann) Cstr a
c
applyPi Symbol
k Cstr a
bp (CAnd [Cstr a]
cs)
= [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ Symbol -> Cstr a -> Cstr a -> Cstr a
forall a. Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi Symbol
k Cstr a
bp (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
applyPi Symbol
k Cstr a
bp (All Bind a
b Cstr a
c)
= Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Symbol -> Cstr a -> Cstr a -> Cstr a
forall a. Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi Symbol
k Cstr a
bp Cstr a
c)
applyPi Symbol
k Cstr a
bp (Any Bind a
b Cstr a
c)
= Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any Bind a
b (Symbol -> Cstr a -> Cstr a -> Cstr a
forall a. Symbol -> Cstr a -> Cstr a -> Cstr a
applyPi Symbol
k Cstr a
bp Cstr a
c)
applyPi Symbol
k Cstr a
defCstr (Head (Var Symbol
k' [Symbol]
_xs) a
a)
| Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k'
= Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Expr -> Pred
Reft (Expr -> Pred) -> Expr -> Pred
forall a b. (a -> b) -> a -> b
$ Cstr a -> Expr
forall a. Cstr a -> Expr
cstrToExpr Cstr a
defCstr) a
a
applyPi Symbol
_ Cstr a
_ (Head Pred
p a
a) = Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
p a
a
defs :: F.Symbol -> Cstr a -> Maybe (Cstr a)
defs :: forall a. Symbol -> Cstr a -> Maybe (Cstr a)
defs Symbol
x (CAnd [Cstr a]
cs) = [Maybe (Cstr a)] -> Maybe (Cstr a)
forall a. [Maybe (Cstr a)] -> Maybe (Cstr a)
andMaybes ([Maybe (Cstr a)] -> Maybe (Cstr a))
-> [Maybe (Cstr a)] -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ Symbol -> Cstr a -> Maybe (Cstr a)
forall a. Symbol -> Cstr a -> Maybe (Cstr a)
defs Symbol
x (Cstr a -> Maybe (Cstr a)) -> [Cstr a] -> [Maybe (Cstr a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
defs Symbol
x (All (Bind Symbol
x' Sort
_ Pred
_ a
_) Cstr a
c)
| Symbol
x' Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
x
= Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cstr a
c
defs Symbol
x (All Bind a
_ Cstr a
c) = Symbol -> Cstr a -> Maybe (Cstr a)
forall a. Symbol -> Cstr a -> Maybe (Cstr a)
defs Symbol
x Cstr a
c
defs Symbol
_ (Head Pred
_ a
_) = Maybe (Cstr a)
forall a. Maybe a
Nothing
defs Symbol
_ (Any Bind a
_ Cstr a
_) = [Char] -> Maybe (Cstr a)
forall a. HasCallStack => [Char] -> a
error [Char]
"defs should be run only after noside and poke"
cstrToExpr :: Cstr a -> F.Expr
cstrToExpr :: forall a. Cstr a -> Expr
cstrToExpr (Head Pred
p a
_) = Pred -> Expr
predToExpr Pred
p
cstrToExpr (CAnd [Cstr a]
cs) = [Expr] -> Expr
forall v. [ExprV v] -> ExprV v
F.PAnd ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Cstr a -> Expr
forall a. Cstr a -> Expr
cstrToExpr (Cstr a -> Expr) -> [Cstr a] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
cstrToExpr (All (Bind Symbol
x Sort
t Pred
p a
_) Cstr a
c) = [(Symbol, Sort)] -> Expr -> Expr
forall v. [(Symbol, Sort)] -> ExprV v -> ExprV v
F.PAll [(Symbol
x,Sort
t)] (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Expr -> Expr -> Expr
forall v. ExprV v -> ExprV v -> ExprV v
F.PImp (Pred -> Expr
predToExpr Pred
p) (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Cstr a -> Expr
forall a. Cstr a -> Expr
cstrToExpr Cstr a
c
cstrToExpr (Any (Bind Symbol
x Sort
t Pred
p a
_) Cstr a
c) = [(Symbol, Sort)] -> Expr -> Expr
forall v. [(Symbol, Sort)] -> ExprV v -> ExprV v
F.PExist [(Symbol
x,Sort
t)] (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Expr -> Expr -> Expr
forall v. ExprV v -> ExprV v -> ExprV v
F.PImp (Pred -> Expr
predToExpr Pred
p) (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Cstr a -> Expr
forall a. Cstr a -> Expr
cstrToExpr Cstr a
c
predToExpr :: Pred -> F.Expr
predToExpr :: Pred -> Expr
predToExpr (Reft Expr
e) = Expr
e
predToExpr (Var Symbol
k [Symbol]
xs) = KVar -> SubstV Symbol -> Expr
forall v. KVar -> SubstV v -> ExprV v
F.PKVar (Symbol -> KVar
F.KV Symbol
k) (HashMap Symbol Expr -> SubstV Symbol
forall v. HashMap Symbol (ExprV v) -> SubstV v
F.Su (HashMap Symbol Expr -> SubstV Symbol)
-> HashMap Symbol Expr -> SubstV Symbol
forall a b. (a -> b) -> a -> b
$ [(Symbol, Expr)] -> HashMap Symbol Expr
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList [(Symbol, Expr)]
su)
where su :: [(Symbol, Expr)]
su = [Symbol] -> [Expr] -> [(Symbol, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Symbol -> [Symbol]
kargs Symbol
k) (Symbol -> Expr
forall v. v -> ExprV v
F.EVar (Symbol -> Expr) -> [Symbol] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Symbol]
xs)
predToExpr (PAnd [Pred]
ps) = [Expr] -> Expr
forall v. [ExprV v] -> ExprV v
F.PAnd ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Pred -> Expr
predToExpr (Pred -> Expr) -> [Pred] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps
elimKs' :: [F.Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimKs' :: forall a. [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimKs' [] (Cstr a, Cstr a)
cstrs = (Cstr a, Cstr a)
cstrs
elimKs' (Symbol
k:[Symbol]
ks) (Cstr a
noside, Cstr a
side) = [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
forall a. [Symbol] -> (Cstr a, Cstr a) -> (Cstr a, Cstr a)
elimKs' ([Char] -> [Symbol] -> [Symbol]
forall a. [Char] -> a -> a
trace ([Char]
"solved kvar " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Symbol -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp Symbol
k [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
":\n" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [([Bind a], [Expr])] -> [Char]
forall a. PPrint a => a -> [Char]
F.showpp [([Bind a], [Expr])]
sol) [Symbol]
ks) (Cstr a
noside', Cstr a
side')
where
sol :: [([Bind a], [Expr])]
sol = Symbol -> Cstr a -> [([Bind a], [Expr])]
forall a. Symbol -> Cstr a -> [([Bind a], [Expr])]
sol1 Symbol
k (Cstr a -> [([Bind a], [Expr])]) -> Cstr a -> [([Bind a], [Expr])]
forall a b. (a -> b) -> a -> b
$ Symbol -> Cstr a -> Cstr a
forall {a}. Symbol -> Cstr a -> Cstr a
scope Symbol
k Cstr a
noside
noside' :: Cstr a
noside' = Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
simplify (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [([Bind a], [Expr])]
sol Cstr a
noside
side' :: Cstr a
side' = Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
simplify (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [([Bind a], [Expr])]
sol Cstr a
side
instance V.Foldable Pred where
foldE :: forall a c. Monoid a => Folder a c -> c -> Pred -> FoldM a Pred
foldE Folder a c
v c
c (PAnd [Pred]
ps) = [Pred] -> Pred
PAnd ([Pred] -> Pred)
-> ReaderT (IORef a) IO [Pred] -> ReaderT (IORef a) IO Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Pred -> ReaderT (IORef a) IO Pred)
-> [Pred] -> ReaderT (IORef a) IO [Pred]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Folder a c -> c -> Pred -> ReaderT (IORef a) IO Pred
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c. Monoid a => Folder a c -> c -> Pred -> FoldM a Pred
foldE Folder a c
v c
c) [Pred]
ps
foldE Folder a c
v c
c (Reft Expr
e) = Expr -> Pred
Reft (Expr -> Pred)
-> ReaderT (IORef a) IO Expr -> ReaderT (IORef a) IO Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Folder a c -> c -> Expr -> ReaderT (IORef a) IO Expr
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c. Monoid a => Folder a c -> c -> Expr -> FoldM a Expr
foldE Folder a c
v c
c Expr
e
foldE Folder a c
_ c
_ Pred
var = Pred -> ReaderT (IORef a) IO Pred
forall a. a -> ReaderT (IORef a) IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
var
instance V.Foldable (Cstr a) where
foldE :: forall a c.
Monoid a =>
Folder a c -> c -> Cstr a -> FoldM a (Cstr a)
foldE Folder a c
v c
c (CAnd [Cstr a]
cs) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a)
-> ReaderT (IORef a) IO [Cstr a] -> ReaderT (IORef a) IO (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Cstr a -> ReaderT (IORef a) IO (Cstr a))
-> [Cstr a] -> ReaderT (IORef a) IO [Cstr a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Folder a c -> c -> Cstr a -> ReaderT (IORef a) IO (Cstr a)
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c.
Monoid a =>
Folder a c -> c -> Cstr a -> FoldM a (Cstr a)
foldE Folder a c
v c
c) [Cstr a]
cs
foldE Folder a c
v c
c (Head Pred
p a
a) = Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Pred -> a -> Cstr a)
-> ReaderT (IORef a) IO Pred -> ReaderT (IORef a) IO (a -> Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Folder a c -> c -> Pred -> ReaderT (IORef a) IO Pred
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c. Monoid a => Folder a c -> c -> Pred -> FoldM a Pred
foldE Folder a c
v c
c Pred
p ReaderT (IORef a) IO (a -> Cstr a)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO (Cstr a)
forall a b.
ReaderT (IORef a) IO (a -> b)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> ReaderT (IORef a) IO a
forall a. a -> ReaderT (IORef a) IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
foldE Folder a c
v c
ctx (All (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Bind a -> Cstr a -> Cstr a)
-> ReaderT (IORef a) IO (Bind a)
-> ReaderT (IORef a) IO (Cstr a -> Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Pred -> a -> Bind a)
-> ReaderT (IORef a) IO Pred -> ReaderT (IORef a) IO (a -> Bind a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Folder a c -> c -> Pred -> ReaderT (IORef a) IO Pred
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c. Monoid a => Folder a c -> c -> Pred -> FoldM a Pred
foldE Folder a c
v c
ctx Pred
p ReaderT (IORef a) IO (a -> Bind a)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO (Bind a)
forall a b.
ReaderT (IORef a) IO (a -> b)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> ReaderT (IORef a) IO a
forall a. a -> ReaderT (IORef a) IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
l) ReaderT (IORef a) IO (Cstr a -> Cstr a)
-> ReaderT (IORef a) IO (Cstr a) -> ReaderT (IORef a) IO (Cstr a)
forall a b.
ReaderT (IORef a) IO (a -> b)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Folder a c -> c -> Cstr a -> ReaderT (IORef a) IO (Cstr a)
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c.
Monoid a =>
Folder a c -> c -> Cstr a -> FoldM a (Cstr a)
foldE Folder a c
v c
ctx Cstr a
c
foldE Folder a c
v c
ctx (Any (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Bind a -> Cstr a -> Cstr a)
-> ReaderT (IORef a) IO (Bind a)
-> ReaderT (IORef a) IO (Cstr a -> Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Pred -> a -> Bind a)
-> ReaderT (IORef a) IO Pred -> ReaderT (IORef a) IO (a -> Bind a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Folder a c -> c -> Pred -> ReaderT (IORef a) IO Pred
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c. Monoid a => Folder a c -> c -> Pred -> FoldM a Pred
foldE Folder a c
v c
ctx Pred
p ReaderT (IORef a) IO (a -> Bind a)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO (Bind a)
forall a b.
ReaderT (IORef a) IO (a -> b)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> ReaderT (IORef a) IO a
forall a. a -> ReaderT (IORef a) IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
l) ReaderT (IORef a) IO (Cstr a -> Cstr a)
-> ReaderT (IORef a) IO (Cstr a) -> ReaderT (IORef a) IO (Cstr a)
forall a b.
ReaderT (IORef a) IO (a -> b)
-> ReaderT (IORef a) IO a -> ReaderT (IORef a) IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Folder a c -> c -> Cstr a -> ReaderT (IORef a) IO (Cstr a)
forall t a c.
(Foldable t, Monoid a) =>
Folder a c -> c -> t -> FoldM a t
forall a c.
Monoid a =>
Folder a c -> c -> Cstr a -> FoldM a (Cstr a)
foldE Folder a c
v c
ctx Cstr a
c
rewriteWithEqualities :: F.Config -> S.Set F.Symbol -> F.Symbol -> S.Set F.Symbol -> [(F.Symbol, F.Expr)] -> [Pred]
rewriteWithEqualities :: Config
-> Set Symbol -> Symbol -> Set Symbol -> [(Symbol, Expr)] -> [Pred]
rewriteWithEqualities Config
cfg Set Symbol
measures Symbol
n Set Symbol
args [(Symbol, Expr)]
equalities = [Pred]
preds
where
(Graph
eGraph, Int -> ((Symbol, [Expr]), Symbol, [Symbol])
vf, Symbol -> Maybe Int
lookupVertex) = [((Symbol, [Expr]), Symbol, [Symbol])]
-> (Graph, Int -> ((Symbol, [Expr]), Symbol, [Symbol]),
Symbol -> Maybe Int)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Int -> (node, key, [key]), key -> Maybe Int)
DG.graphFromEdges ([((Symbol, [Expr]), Symbol, [Symbol])]
-> (Graph, Int -> ((Symbol, [Expr]), Symbol, [Symbol]),
Symbol -> Maybe Int))
-> [((Symbol, [Expr]), Symbol, [Symbol])]
-> (Graph, Int -> ((Symbol, [Expr]), Symbol, [Symbol]),
Symbol -> Maybe Int)
forall a b. (a -> b) -> a -> b
$ Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
args HashMap Symbol ([Symbol], [Expr])
forall a. Monoid a => a
mempty [(Symbol, Expr)]
equalities
nResult :: (Symbol, [Expr])
nResult = (Symbol
n, Int -> [Expr] -> [Expr]
makeWellFormed Int
15 ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ Symbol -> [Expr]
sols Symbol
n)
argResults :: [(Symbol, [Expr])]
argResults = (Symbol -> (Symbol, [Expr])) -> [Symbol] -> [(Symbol, [Expr])]
forall a b. (a -> b) -> [a] -> [b]
map (\Symbol
arg -> (Symbol
arg, Int -> [Expr] -> [Expr]
makeWellFormed Int
15 ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ Symbol -> [Expr]
sols Symbol
arg)) (Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList Set Symbol
args)
preds :: [Pred]
preds = [[Pred]] -> [Pred]
forall a. Monoid a => [a] -> a
mconcat ([[Pred]] -> [Pred]) -> [[Pred]] -> [Pred]
forall a b. (a -> b) -> a -> b
$ (\(Symbol
x, [Expr]
es) -> [[Pred]] -> [Pred]
forall a. Monoid a => [a] -> a
mconcat ([[Pred]] -> [Pred]) -> [[Pred]] -> [Pred]
forall a b. (a -> b) -> a -> b
$ Symbol -> Expr -> [Pred]
mkEquality Symbol
x (Expr -> [Pred]) -> [Expr] -> [[Pred]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr]
es) ((Symbol, [Expr]) -> [Pred]) -> [(Symbol, [Expr])] -> [[Pred]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Symbol, [Expr])
nResult(Symbol, [Expr]) -> [(Symbol, [Expr])] -> [(Symbol, [Expr])]
forall a. a -> [a] -> [a]
:[(Symbol, [Expr])]
argResults)
mkEquality :: Symbol -> Expr -> [Pred]
mkEquality Symbol
x Expr
e = [Expr -> Pred
Reft (Brel -> Expr -> Expr -> Expr
forall v. Brel -> ExprV v -> ExprV v -> ExprV v
F.PAtom Brel
F.Eq (Symbol -> Expr
forall v. v -> ExprV v
F.EVar Symbol
x) Expr
e)]
sols :: F.Symbol -> [F.Expr]
sols :: Symbol -> [Expr]
sols Symbol
x = case Symbol -> Maybe Int
lookupVertex Symbol
x of
Maybe Int
Nothing -> []
Just Int
vertex -> [Expr] -> [Expr]
forall a. Eq a => [a] -> [a]
nub ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter (Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
/= Symbol -> Expr
forall v. v -> ExprV v
F.EVar Symbol
x) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Expr]
forall a. Monoid a => [a] -> a
mconcat [[Expr]
es | ((Symbol
_, [Expr]
es), Symbol
_, [Symbol]
_) <- Int -> ((Symbol, [Expr]), Symbol, [Symbol])
vf (Int -> ((Symbol, [Expr]), Symbol, [Symbol]))
-> [Int] -> [((Symbol, [Expr]), Symbol, [Symbol])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Graph -> Int -> [Int]
DG.reachable Graph
eGraph Int
vertex]
argsAndPrims :: Set Symbol
argsAndPrims = Set Symbol
args Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.union` [Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList (((Symbol, TheorySymbol) -> Symbol)
-> [(Symbol, TheorySymbol)] -> [Symbol]
forall a b. (a -> b) -> [a] -> [b]
map (Symbol, TheorySymbol) -> Symbol
forall a b. (a, b) -> a
fst ([(Symbol, TheorySymbol)] -> [Symbol])
-> [(Symbol, TheorySymbol)] -> [Symbol]
forall a b. (a -> b) -> a -> b
$ SEnv TheorySymbol -> [(Symbol, TheorySymbol)]
forall a. SEnv a -> [(Symbol, a)]
F.toListSEnv (SEnv TheorySymbol -> [(Symbol, TheorySymbol)])
-> SEnv TheorySymbol -> [(Symbol, TheorySymbol)]
forall a b. (a -> b) -> a -> b
$ SMTSolver -> [DataDecl] -> SEnv TheorySymbol
F.theorySymbols (Config -> SMTSolver
F.solver Config
cfg) []) Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.union`Set Symbol
measures
isWellFormed :: F.Expr -> Bool
isWellFormed :: Expr -> Bool
isWellFormed Expr
e = [Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList (Expr -> [Symbol]
forall a. Subable a => a -> [Symbol]
F.syms Expr
e) Set Symbol -> Set Symbol -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`S.isSubsetOf` Set Symbol
argsAndPrims
makeWellFormed :: Int -> [F.Expr] -> [F.Expr]
makeWellFormed :: Int -> [Expr] -> [Expr]
makeWellFormed Int
0 [Expr]
exprs = (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter Expr -> Bool
isWellFormed [Expr]
exprs
makeWellFormed Int
m [Expr]
exprs = Int -> [Expr] -> [Expr]
makeWellFormed (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Expr]
forall a. Monoid a => [a] -> a
mconcat ([[Expr]] -> [Expr]) -> [[Expr]] -> [Expr]
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr]
go (Expr -> [Expr]) -> [Expr] -> [[Expr]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr]
exprs
where
go :: Expr -> [Expr]
go Expr
expr = if Expr -> Bool
isWellFormed Expr
expr then [Expr
expr] else [(Symbol, [Expr])] -> [Expr] -> [Expr]
forall {a}. Subable a => [(Symbol, [Expr])] -> [a] -> [a]
rewrite [(Symbol, [Expr])]
rewrites [Expr
expr]
where
needSolving :: Set Symbol
needSolving = [Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList (Expr -> [Symbol]
forall a. Subable a => a -> [Symbol]
F.syms Expr
expr) Set Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` Set Symbol
argsAndPrims
rewrites :: [(Symbol, [Expr])]
rewrites = (\Symbol
x -> (Symbol
x, (Expr -> Bool) -> [Expr] -> [Expr]
forall a. (a -> Bool) -> [a] -> [a]
filter (Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
/= Symbol -> Expr
forall v. v -> ExprV v
F.EVar Symbol
x) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ Symbol -> [Expr]
sols Symbol
x)) (Symbol -> (Symbol, [Expr])) -> [Symbol] -> [(Symbol, [Expr])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Symbol -> [Symbol]
forall a. Set a -> [a]
S.toList Set Symbol
needSolving
rewrite :: [(Symbol, [Expr])] -> [a] -> [a]
rewrite [] [a]
es = [a]
es
rewrite ((Symbol
x, [Expr]
rewriteExprs):[(Symbol, [Expr])]
rewriteExprs') [a]
es = [(Symbol, [Expr])] -> [a] -> [a]
rewrite [(Symbol, [Expr])]
rewriteExprs' ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ [SubstV Symbol -> a -> a
forall a. Subable a => SubstV Symbol -> a -> a
F.subst ([(Symbol, Expr)] -> SubstV Symbol
F.mkSubst [(Symbol
x, Expr
e')]) a
e | Expr
e' <- [Expr]
rewriteExprs, a
e <- [a]
es]
eqEdges :: S.Set F.Symbol ->
M.HashMap F.Symbol ([F.Symbol], [F.Expr]) ->
[(F.Symbol, F.Expr)] ->
[((F.Symbol, [F.Expr]), F.Symbol, [F.Symbol])]
eqEdges :: Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
_args HashMap Symbol ([Symbol], [Expr])
edgeMap [] = (Symbol
-> ([Symbol], [Expr])
-> [((Symbol, [Expr]), Symbol, [Symbol])]
-> [((Symbol, [Expr]), Symbol, [Symbol])])
-> [((Symbol, [Expr]), Symbol, [Symbol])]
-> HashMap Symbol ([Symbol], [Expr])
-> [((Symbol, [Expr]), Symbol, [Symbol])]
forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
M.foldrWithKey (\Symbol
x ([Symbol]
ys, [Expr]
es) [((Symbol, [Expr]), Symbol, [Symbol])]
edges -> ((Symbol
x, [Expr]
es), Symbol
x, [Symbol]
ys)((Symbol, [Expr]), Symbol, [Symbol])
-> [((Symbol, [Expr]), Symbol, [Symbol])]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
forall a. a -> [a] -> [a]
:[((Symbol, [Expr]), Symbol, [Symbol])]
edges) [] HashMap Symbol ([Symbol], [Expr])
edgeMap
eqEdges Set Symbol
args HashMap Symbol ([Symbol], [Expr])
edgeMap ((Symbol
x, Expr
e):[(Symbol, Expr)]
eqs)
| F.EVar Symbol
y <- Expr
e
, Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member Symbol
y Set Symbol
args = Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
args ((([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr]))
-> Symbol
-> ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith ([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr])
forall a. Semigroup a => a -> a -> a
(<>) Symbol
x ([Symbol
y], [Symbol -> Expr
forall v. v -> ExprV v
F.EVar Symbol
y]) HashMap Symbol ([Symbol], [Expr])
edgeMap) [(Symbol, Expr)]
eqs
| F.EVar Symbol
y <- Expr
e = Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
args ((([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr]))
-> Symbol
-> ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith ([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr])
forall a. Semigroup a => a -> a -> a
(<>) Symbol
x ([Symbol
y], []) HashMap Symbol ([Symbol], [Expr])
edgeMap) [(Symbol, Expr)]
eqs
| Bool
otherwise = Set Symbol
-> HashMap Symbol ([Symbol], [Expr])
-> [(Symbol, Expr)]
-> [((Symbol, [Expr]), Symbol, [Symbol])]
eqEdges Set Symbol
args ((([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr]))
-> Symbol
-> ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
-> HashMap Symbol ([Symbol], [Expr])
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
M.insertWith ([Symbol], [Expr]) -> ([Symbol], [Expr]) -> ([Symbol], [Expr])
forall a. Semigroup a => a -> a -> a
(<>) Symbol
x ([], [Expr
e]) HashMap Symbol ([Symbol], [Expr])
edgeMap) [(Symbol, Expr)]
eqs
collectEqualities :: Pred -> [(F.Symbol, F.Expr)]
collectEqualities :: Pred -> [(Symbol, Expr)]
collectEqualities = Pred -> [(Symbol, Expr)]
goP
where
goP :: Pred -> [(Symbol, Expr)]
goP (Reft Expr
e) = Expr -> [(Symbol, Expr)]
goE Expr
e
goP (PAnd [Pred]
ps) = [[(Symbol, Expr)]] -> [(Symbol, Expr)]
forall a. Monoid a => [a] -> a
mconcat ([[(Symbol, Expr)]] -> [(Symbol, Expr)])
-> [[(Symbol, Expr)]] -> [(Symbol, Expr)]
forall a b. (a -> b) -> a -> b
$ Pred -> [(Symbol, Expr)]
goP (Pred -> [(Symbol, Expr)]) -> [Pred] -> [[(Symbol, Expr)]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps
goP Pred
_ = [(Symbol, Expr)]
forall a. Monoid a => a
mempty
goE :: Expr -> [(Symbol, Expr)]
goE (F.PAtom Brel
F.Eq Expr
left Expr
right) = Expr -> Expr -> [(Symbol, Expr)]
extractEquality Expr
left Expr
right
goE (F.PAnd [Expr]
es) = [[(Symbol, Expr)]] -> [(Symbol, Expr)]
forall a. Monoid a => [a] -> a
mconcat ([[(Symbol, Expr)]] -> [(Symbol, Expr)])
-> [[(Symbol, Expr)]] -> [(Symbol, Expr)]
forall a b. (a -> b) -> a -> b
$ Expr -> [(Symbol, Expr)]
goE (Expr -> [(Symbol, Expr)]) -> [Expr] -> [[(Symbol, Expr)]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr]
es
goE Expr
_ = [(Symbol, Expr)]
forall a. Monoid a => a
mempty
extractEquality :: F.Expr -> F.Expr -> [(F.Symbol, F.Expr)]
Expr
left Expr
right
| F.EVar Symbol
x <- Expr
left, F.EVar Symbol
y <- Expr
right, Symbol
x Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
y = [(Symbol, Expr)]
forall a. Monoid a => a
mempty
| F.EVar Symbol
x <- Expr
left, F.EVar Symbol
y <- Expr
right = [(Symbol
x, Expr
right), (Symbol
y, Expr
left)]
| F.EVar Symbol
x <- Expr
left = [(Symbol
x, Expr
right)]
| F.EVar Symbol
x <- Expr
right = [(Symbol
x, Expr
left)]
| Bool
otherwise = [(Symbol, Expr)]
forall a. Monoid a => a
mempty
substPiSols :: M.HashMap F.Symbol Pred -> Cstr a -> Cstr a
substPiSols :: forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
_ c :: Cstr a
c@Head{} = Cstr a
c
substPiSols HashMap Symbol Pred
piSols (CAnd [Cstr a]
cs) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ HashMap Symbol Pred -> Cstr a -> Cstr a
forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
piSols (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
substPiSols HashMap Symbol Pred
piSols (All (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c)
| Var Symbol
k [Symbol]
_ <- Pred
p = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Pred -> Symbol -> HashMap Symbol Pred -> Pred
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
M.lookupDefault Pred
p Symbol
k HashMap Symbol Pred
piSols) a
l) (HashMap Symbol Pred -> Cstr a -> Cstr a
forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
piSols Cstr a
c)
| Bool
otherwise = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t Pred
p a
l) (HashMap Symbol Pred -> Cstr a -> Cstr a
forall a. HashMap Symbol Pred -> Cstr a -> Cstr a
substPiSols HashMap Symbol Pred
piSols Cstr a
c)
substPiSols HashMap Symbol Pred
piSols (Any (Bind Symbol
n Sort
_ Pred
p a
_) Cstr a
c)
| Head (Var Symbol
pi' [Symbol]
_) a
label <- Cstr a
c, Just Pred
sol <- Symbol -> HashMap Symbol Pred -> Maybe Pred
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup Symbol
pi' HashMap Symbol Pred
piSols =
case Symbol -> Pred -> Maybe Expr
findSol Symbol
n Pred
sol of
Just Expr
e -> Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Pred -> Pred
forall a. Flatten a => a -> a
flatten (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ [Pred] -> Pred
PAnd ([Pred] -> Pred) -> [Pred] -> Pred
forall a b. (a -> b) -> a -> b
$ (\Pred
predFn -> Pred -> (Symbol, Expr) -> Pred
forall a. Subable a => a -> (Symbol, Expr) -> a
F.subst1 Pred
predFn (Symbol
n, Expr
e)) (Pred -> Pred) -> [Pred] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred
p, Pred
sol]) a
label
Maybe Expr
Nothing -> Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Expr -> Pred
Reft (Expr -> Pred) -> Expr -> Pred
forall a b. (a -> b) -> a -> b
$ [Expr] -> Expr
forall v. [ExprV v] -> ExprV v
F.PAnd []) a
label
| Bool
otherwise = [Char] -> Cstr a
forall a. HasCallStack => [Char] -> a
error [Char]
"missing piSol"
findSol :: F.Symbol -> Pred -> Maybe F.Expr
findSol :: Symbol -> Pred -> Maybe Expr
findSol Symbol
sym = Pred -> Maybe Expr
go
where
go :: Pred -> Maybe Expr
go (Reft Expr
e) = Expr -> Maybe Expr
findEq Expr
e
go Var{} = Maybe Expr
forall a. Maybe a
Nothing
go (PAnd [Pred]
ps) = case (Pred -> Maybe Expr) -> [Pred] -> [Expr]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Pred -> Maybe Expr
go [Pred]
ps of
[] -> Maybe Expr
forall a. Maybe a
Nothing
Expr
x:[Expr]
_ -> Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
x
findEq :: Expr -> Maybe Expr
findEq (F.PAtom Brel
F.Eq Expr
left Expr
right)
| F.EVar Symbol
y <- Expr
left, Symbol
y Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
sym = Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
right
| F.EVar Symbol
y <- Expr
right, Symbol
y Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
sym = Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
left
findEq Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
type RenameMap = M.HashMap F.Symbol (Integer, [Integer])
uniq :: Cstr a -> Cstr a
uniq :: forall a. Cstr a -> Cstr a
uniq Cstr a
c = State RenameMap (Cstr a) -> RenameMap -> Cstr a
forall s a. State s a -> s -> a
evalState (Cstr a -> State RenameMap (Cstr a)
forall a. Cstr a -> State RenameMap (Cstr a)
uniq' Cstr a
c) RenameMap
forall k v. HashMap k v
M.empty
uniq' :: Cstr a -> State RenameMap (Cstr a)
uniq' :: forall a. Cstr a -> State RenameMap (Cstr a)
uniq' (Head Pred
c a
a) = (RenameMap -> a -> Cstr a)
-> StateT RenameMap Identity (a -> Cstr a)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Pred -> a -> Cstr a)
-> (RenameMap -> Pred) -> RenameMap -> a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> RenameMap -> Pred
rename Pred
c) StateT RenameMap Identity (a -> Cstr a)
-> StateT RenameMap Identity a
-> StateT RenameMap Identity (Cstr a)
forall a b.
StateT RenameMap Identity (a -> b)
-> StateT RenameMap Identity a -> StateT RenameMap Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> StateT RenameMap Identity a
forall a. a -> StateT RenameMap Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
uniq' (CAnd [Cstr a]
c) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a)
-> StateT RenameMap Identity [Cstr a]
-> StateT RenameMap Identity (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Cstr a -> StateT RenameMap Identity (Cstr a))
-> [Cstr a] -> StateT RenameMap Identity [Cstr a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Cstr a -> StateT RenameMap Identity (Cstr a)
forall a. Cstr a -> State RenameMap (Cstr a)
uniq' [Cstr a]
c
uniq' (All b :: Bind a
b@(Bind Symbol
x Sort
_ Pred
_ a
_) Cstr a
c2) = do
Bind a
b' <- Bind a -> State RenameMap (Bind a)
forall a. Bind a -> State RenameMap (Bind a)
uBind Bind a
b
Cstr a
c2' <- Cstr a -> StateT RenameMap Identity (Cstr a)
forall a. Cstr a -> State RenameMap (Cstr a)
uniq' Cstr a
c2
(RenameMap -> RenameMap) -> StateT RenameMap Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenameMap -> RenameMap) -> StateT RenameMap Identity ())
-> (RenameMap -> RenameMap) -> StateT RenameMap Identity ()
forall a b. (a -> b) -> a -> b
$ Symbol -> RenameMap -> RenameMap
popName Symbol
x
Cstr a -> StateT RenameMap Identity (Cstr a)
forall a. a -> StateT RenameMap Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cstr a -> StateT RenameMap Identity (Cstr a))
-> Cstr a -> StateT RenameMap Identity (Cstr a)
forall a b. (a -> b) -> a -> b
$ Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b' Cstr a
c2'
uniq' (Any b :: Bind a
b@(Bind Symbol
x Sort
_ Pred
_ a
_) Cstr a
c2) = do
Bind a
b' <- Bind a -> State RenameMap (Bind a)
forall a. Bind a -> State RenameMap (Bind a)
uBind Bind a
b
Cstr a
c2' <- Cstr a -> StateT RenameMap Identity (Cstr a)
forall a. Cstr a -> State RenameMap (Cstr a)
uniq' Cstr a
c2
(RenameMap -> RenameMap) -> StateT RenameMap Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((RenameMap -> RenameMap) -> StateT RenameMap Identity ())
-> (RenameMap -> RenameMap) -> StateT RenameMap Identity ()
forall a b. (a -> b) -> a -> b
$ Symbol -> RenameMap -> RenameMap
popName Symbol
x
Cstr a -> StateT RenameMap Identity (Cstr a)
forall a. a -> StateT RenameMap Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cstr a -> StateT RenameMap Identity (Cstr a))
-> Cstr a -> StateT RenameMap Identity (Cstr a)
forall a b. (a -> b) -> a -> b
$ Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any Bind a
b' Cstr a
c2'
popName :: F.Symbol -> RenameMap -> RenameMap
popName :: Symbol -> RenameMap -> RenameMap
popName Symbol
x RenameMap
m = ((Integer, [Integer]) -> (Integer, [Integer]))
-> Symbol -> RenameMap -> RenameMap
forall k v.
(Eq k, Hashable k) =>
(v -> v) -> k -> HashMap k v -> HashMap k v
M.adjust (([Integer] -> [Integer])
-> (Integer, [Integer]) -> (Integer, [Integer])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second [Integer] -> [Integer]
forall a. HasCallStack => [a] -> [a]
tail) Symbol
x RenameMap
m
pushName :: Maybe (Integer, [Integer]) -> Maybe (Integer, [Integer])
pushName :: Maybe (Integer, [Integer]) -> Maybe (Integer, [Integer])
pushName Maybe (Integer, [Integer])
Nothing = (Integer, [Integer]) -> Maybe (Integer, [Integer])
forall a. a -> Maybe a
Just (Integer
0, [Integer
0])
pushName (Just (Integer
i, [Integer]
is)) = (Integer, [Integer]) -> Maybe (Integer, [Integer])
forall a. a -> Maybe a
Just (Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1, (Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1)Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
:[Integer]
is)
uBind :: Bind a -> State RenameMap (Bind a)
uBind :: forall a. Bind a -> State RenameMap (Bind a)
uBind (Bind Symbol
x Sort
t Pred
p a
l) = do
Symbol
x' <- Symbol -> State RenameMap Symbol
forall a. IsString a => Symbol -> State RenameMap a
uVariable Symbol
x
Pred
p' <- (RenameMap -> Pred) -> StateT RenameMap Identity Pred
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Pred -> RenameMap -> Pred
rename Pred
p)
Bind a -> State RenameMap (Bind a)
forall a. a -> StateT RenameMap Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bind a -> State RenameMap (Bind a))
-> Bind a -> State RenameMap (Bind a)
forall a b. (a -> b) -> a -> b
$ Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x' Sort
t Pred
p' a
l
uVariable :: IsString a => F.Symbol -> State RenameMap a
uVariable :: forall a. IsString a => Symbol -> State RenameMap a
uVariable Symbol
x = do
(RenameMap -> RenameMap) -> StateT RenameMap Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Maybe (Integer, [Integer]) -> Maybe (Integer, [Integer]))
-> Symbol -> RenameMap -> RenameMap
forall k v.
(Eq k, Hashable k) =>
(Maybe v -> Maybe v) -> k -> HashMap k v -> HashMap k v
M.alter Maybe (Integer, [Integer]) -> Maybe (Integer, [Integer])
pushName Symbol
x)
Integer
i <- (RenameMap -> Integer) -> StateT RenameMap Identity Integer
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ([Integer] -> Integer
forall a. HasCallStack => [a] -> a
head ([Integer] -> Integer)
-> (RenameMap -> [Integer]) -> RenameMap -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer, [Integer]) -> [Integer]
forall a b. (a, b) -> b
snd ((Integer, [Integer]) -> [Integer])
-> (RenameMap -> (Integer, [Integer])) -> RenameMap -> [Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RenameMap -> Symbol -> (Integer, [Integer])
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
M.! Symbol
x))
a -> State RenameMap a
forall a. a -> StateT RenameMap Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> State RenameMap a) -> a -> State RenameMap a
forall a b. (a -> b) -> a -> b
$ Symbol -> Integer -> a
forall a. IsString a => Symbol -> Integer -> a
numSym Symbol
x Integer
i
rename :: Pred -> RenameMap -> Pred
rename :: Pred -> RenameMap -> Pred
rename Pred
e RenameMap
m = HashMap Symbol Symbol -> Pred -> Pred
substPred ((Symbol -> (Integer, [Integer]) -> Maybe Symbol)
-> RenameMap -> HashMap Symbol Symbol
forall k v1 v2.
(k -> v1 -> Maybe v2) -> HashMap k v1 -> HashMap k v2
M.mapMaybeWithKey (\Symbol
k (Integer, [Integer])
v -> case (Integer, [Integer])
v of
(Integer
_, Integer
n:[Integer]
_) -> Symbol -> Maybe Symbol
forall a. a -> Maybe a
Just (Symbol -> Maybe Symbol) -> Symbol -> Maybe Symbol
forall a b. (a -> b) -> a -> b
$ Symbol -> Integer -> Symbol
forall a. IsString a => Symbol -> Integer -> a
numSym Symbol
k Integer
n
(Integer, [Integer])
_ -> Maybe Symbol
forall a. Maybe a
Nothing) RenameMap
m) Pred
e
numSym :: IsString a => F.Symbol -> Integer -> a
numSym :: forall a. IsString a => Symbol -> Integer -> a
numSym Symbol
s Integer
0 = [Char] -> a
forall a. IsString a => [Char] -> a
fromString ([Char] -> a) -> [Char] -> a
forall a b. (a -> b) -> a -> b
$ Symbol -> [Char]
F.symbolString Symbol
s
numSym Symbol
s Integer
i = [Char] -> a
forall a. IsString a => [Char] -> a
fromString ([Char] -> a) -> [Char] -> a
forall a b. (a -> b) -> a -> b
$ Symbol -> [Char]
F.symbolString Symbol
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"#" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Integer -> [Char]
forall a. Show a => a -> [Char]
show Integer
i
substPred :: M.HashMap F.Symbol F.Symbol -> Pred -> Pred
substPred :: HashMap Symbol Symbol -> Pred -> Pred
substPred HashMap Symbol Symbol
su (Reft Expr
e) = Expr -> Pred
Reft (Expr -> Pred) -> Expr -> Pred
forall a b. (a -> b) -> a -> b
$ SubstV Symbol -> Expr -> Expr
forall a. Subable a => SubstV Symbol -> a -> a
F.subst (HashMap Symbol Expr -> SubstV Symbol
forall v. HashMap Symbol (ExprV v) -> SubstV v
F.Su (HashMap Symbol Expr -> SubstV Symbol)
-> HashMap Symbol Expr -> SubstV Symbol
forall a b. (a -> b) -> a -> b
$ Symbol -> Expr
forall v. v -> ExprV v
F.EVar (Symbol -> Expr) -> HashMap Symbol Symbol -> HashMap Symbol Expr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap Symbol Symbol
su) Expr
e
substPred HashMap Symbol Symbol
su (PAnd [Pred]
ps) = [Pred] -> Pred
PAnd ([Pred] -> Pred) -> [Pred] -> Pred
forall a b. (a -> b) -> a -> b
$ HashMap Symbol Symbol -> Pred -> Pred
substPred HashMap Symbol Symbol
su (Pred -> Pred) -> [Pred] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps
substPred HashMap Symbol Symbol
su (Var Symbol
k [Symbol]
xs) = Symbol -> [Symbol] -> Pred
Var Symbol
k ([Symbol] -> Pred) -> [Symbol] -> Pred
forall a b. (a -> b) -> a -> b
$ Symbol -> Symbol
upd (Symbol -> Symbol) -> [Symbol] -> [Symbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Symbol]
xs
where upd :: Symbol -> Symbol
upd Symbol
x = Symbol -> Symbol -> HashMap Symbol Symbol -> Symbol
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
M.lookupDefault Symbol
x Symbol
x HashMap Symbol Symbol
su
elim :: Cstr a -> Cstr a
elim :: forall a. Cstr a -> Cstr a
elim Cstr a
c = if Set Symbol -> Bool
forall a. Set a -> Bool
S.null (Set Symbol -> Bool) -> Set Symbol -> Bool
forall a b. (a -> b) -> a -> b
$ Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
res then Cstr a
res else [Char] -> Cstr a
forall a. HasCallStack => [Char] -> a
error [Char]
"called elim on cyclic constraint"
where
res :: Cstr a
res = (Cstr a -> Symbol -> Cstr a) -> Cstr a -> Set Symbol -> Cstr a
forall a b. (a -> b -> a) -> a -> Set b -> a
S.foldl' Cstr a -> Symbol -> Cstr a
forall a. Cstr a -> Symbol -> Cstr a
elim1 Cstr a
c (Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
c)
elim1 :: Cstr a -> F.Symbol -> Cstr a
elim1 :: forall a. Cstr a -> Symbol -> Cstr a
elim1 Cstr a
c Symbol
k = Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
simplify (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [([Bind a], [Expr])]
sol Cstr a
c
where sol :: [([Bind a], [Expr])]
sol = Symbol -> Cstr a -> [([Bind a], [Expr])]
forall a. Symbol -> Cstr a -> [([Bind a], [Expr])]
sol1 Symbol
k (Symbol -> Cstr a -> Cstr a
forall {a}. Symbol -> Cstr a -> Cstr a
scope Symbol
k Cstr a
c)
scope :: F.Symbol -> Cstr a -> Cstr a
scope :: forall {a}. Symbol -> Cstr a -> Cstr a
scope Symbol
k Cstr a
cstr = case Cstr a -> Either a (Cstr a)
forall {a}. Cstr a -> Either a (Cstr a)
go Cstr a
cstr of
Right Cstr a
c -> Cstr a
c
Left a
l -> Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Expr -> Pred
Reft Expr
forall v. ExprV v
F.PTrue) a
l
where
go :: Cstr a -> Either a (Cstr a)
go c :: Cstr a
c@(Head (Var Symbol
k' [Symbol]
_) a
_)
| Symbol
k' Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k = Cstr a -> Either a (Cstr a)
forall a b. b -> Either a b
Right Cstr a
c
go (Head Pred
_ a
l) = a -> Either a (Cstr a)
forall a b. a -> Either a b
Left a
l
go c :: Cstr a
c@(All (Bind Symbol
_ Sort
_ Pred
p a
_) Cstr a
c') =
if Symbol
k Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Pred -> Set Symbol
pKVars Pred
p then Cstr a -> Either a (Cstr a)
forall a b. b -> Either a b
Right Cstr a
c else Cstr a -> Either a (Cstr a)
go Cstr a
c'
go Any{} = [Char] -> Either a (Cstr a)
forall a. HasCallStack => [Char] -> a
error [Char]
"any should not appear after poke"
go cstr' :: Cstr a
cstr'@(CAnd [Cstr a]
cs) = case [Either a (Cstr a)] -> [Cstr a]
forall a b. [Either a b] -> [b]
rights (Cstr a -> Either a (Cstr a)
go (Cstr a -> Either a (Cstr a)) -> [Cstr a] -> [Either a (Cstr a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs) of
[] -> a -> Either a (Cstr a)
forall a b. a -> Either a b
Left (a -> Either a (Cstr a)) -> a -> Either a (Cstr a)
forall a b. (a -> b) -> a -> b
$ Cstr a -> a
forall a. Cstr a -> a
cLabel Cstr a
cstr'
[Cstr a
c] -> Cstr a -> Either a (Cstr a)
forall a b. b -> Either a b
Right Cstr a
c
[Cstr a]
_ -> Cstr a -> Either a (Cstr a)
forall a b. b -> Either a b
Right Cstr a
cstr'
sol1 :: F.Symbol -> Cstr a -> [([Bind a], [F.Expr])]
sol1 :: forall a. Symbol -> Cstr a -> [([Bind a], [Expr])]
sol1 Symbol
k (CAnd [Cstr a]
cs) = Symbol -> Cstr a -> [([Bind a], [Expr])]
forall a. Symbol -> Cstr a -> [([Bind a], [Expr])]
sol1 Symbol
k (Cstr a -> [([Bind a], [Expr])])
-> [Cstr a] -> [([Bind a], [Expr])]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Cstr a]
cs
sol1 Symbol
k (All Bind a
b Cstr a
c) = ([Bind a] -> [Bind a]) -> ([Bind a], [Expr]) -> ([Bind a], [Expr])
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Bind a
b Bind a -> [Bind a] -> [Bind a]
forall a. a -> [a] -> [a]
:) (([Bind a], [Expr]) -> ([Bind a], [Expr]))
-> [([Bind a], [Expr])] -> [([Bind a], [Expr])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Symbol -> Cstr a -> [([Bind a], [Expr])]
forall a. Symbol -> Cstr a -> [([Bind a], [Expr])]
sol1 Symbol
k Cstr a
c
sol1 Symbol
k (Head (Var Symbol
k' [Symbol]
ys) a
_) | Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k'
= [([], (Expr -> Expr -> Expr) -> [Expr] -> [Expr] -> [Expr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Brel -> Expr -> Expr -> Expr
forall v. Brel -> ExprV v -> ExprV v -> ExprV v
F.PAtom Brel
F.Eq) (Symbol -> Expr
forall v. v -> ExprV v
F.EVar (Symbol -> Expr) -> [Symbol] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Symbol]
xs) (Symbol -> Expr
forall v. v -> ExprV v
F.EVar (Symbol -> Expr) -> [Symbol] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Symbol]
ys))]
where xs :: [Symbol]
xs = (Symbol -> Symbol -> Symbol) -> [Symbol] -> [Symbol] -> [Symbol]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Symbol -> Symbol -> Symbol
forall a b. a -> b -> a
const (Symbol -> [Symbol]
kargs Symbol
k) [Symbol]
ys
sol1 Symbol
_ (Head Pred
_ a
_) = []
sol1 Symbol
_ (Any Bind a
_ Cstr a
_) = [Char] -> [([Bind a], [Expr])]
forall a. HasCallStack => [Char] -> a
error [Char]
"ebinds don't work with old elim"
kargs :: F.Symbol -> [F.Symbol]
kargs :: Symbol -> [Symbol]
kargs Symbol
k = [Char] -> Symbol
forall a. IsString a => [Char] -> a
fromString ([Char] -> Symbol) -> (Integer -> [Char]) -> Integer -> Symbol
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char]
"κarg$" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Symbol -> [Char]
F.symbolString Symbol
k [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"#") [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([Char] -> [Char]) -> (Integer -> [Char]) -> Integer -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> [Char]
forall a. Show a => a -> [Char]
show (Integer -> Symbol) -> [Integer] -> [Symbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Integer
1 :: Integer ..]
doelim :: F.Symbol -> [([Bind a], [F.Expr])] -> Cstr a -> Cstr a
doelim :: forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
sym [([Bind a], [Expr])]
bss (CAnd [Cstr a]
cs)
= [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
sym [([Bind a], [Expr])]
bss (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
doelim Symbol
sym [([Bind a], [Expr])]
bss (All (Bind Symbol
sym' Sort
sort' Pred
p a
l) Cstr a
cstr) =
case Symbol -> Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
findKVarInGuard Symbol
sym Pred
p of
Right Pred
_ -> Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
sym' Sort
sort' Pred
p a
l) (Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
sym [([Bind a], [Expr])]
bss Cstr a
cstr)
Left ([(Symbol, [Symbol])]
kvars, [Pred]
preds) -> Symbol
-> Sort
-> a
-> [(Symbol, [Symbol])]
-> [Pred]
-> Cstr a
-> [([Bind a], [Expr])]
-> Cstr a
forall a.
Symbol
-> Sort
-> a
-> [(Symbol, [Symbol])]
-> [Pred]
-> Cstr a
-> [([Bind a], [Expr])]
-> Cstr a
demorgan Symbol
sym' Sort
sort' a
l [(Symbol, [Symbol])]
kvars [Pred]
preds (Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
sym [([Bind a], [Expr])]
bss Cstr a
cstr) [([Bind a], [Expr])]
bss
where
demorgan :: F.Symbol -> F.Sort -> a -> [(F.Symbol, [F.Symbol])] -> [Pred] -> Cstr a -> [([Bind a], [F.Expr])] -> Cstr a
demorgan :: forall a.
Symbol
-> Sort
-> a
-> [(Symbol, [Symbol])]
-> [Pred]
-> Cstr a
-> [([Bind a], [Expr])]
-> Cstr a
demorgan Symbol
x Sort
t a
ann [(Symbol, [Symbol])]
kvars [Pred]
preds Cstr a
cstr' [([Bind a], [Expr])]
bindExprs = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
mkAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ ([Bind a], [Expr]) -> Cstr a
cubeSol (([Bind a], [Expr]) -> Cstr a) -> [([Bind a], [Expr])] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [([Bind a], [Expr])]
bindExprs
where su :: SubstV Symbol
su = HashMap Symbol Expr -> SubstV Symbol
forall v. HashMap Symbol (ExprV v) -> SubstV v
F.Su (HashMap Symbol Expr -> SubstV Symbol)
-> HashMap Symbol Expr -> SubstV Symbol
forall a b. (a -> b) -> a -> b
$ [(Symbol, Expr)] -> HashMap Symbol Expr
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Symbol, Expr)] -> HashMap Symbol Expr)
-> [(Symbol, Expr)] -> HashMap Symbol Expr
forall a b. (a -> b) -> a -> b
$ ((Symbol, [Symbol]) -> [(Symbol, Expr)])
-> [(Symbol, [Symbol])] -> [(Symbol, Expr)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Symbol
k, [Symbol]
xs) -> [Symbol] -> [Expr] -> [(Symbol, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Symbol -> [Symbol]
kargs Symbol
k) (Symbol -> Expr
forall v. v -> ExprV v
F.EVar (Symbol -> Expr) -> [Symbol] -> [Expr]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Symbol]
xs)) [(Symbol, [Symbol])]
kvars
mkAnd :: [Cstr a] -> Cstr a
mkAnd [Cstr a
c] = Cstr a
c
mkAnd [Cstr a]
cs = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Cstr a]
cs
cubeSol :: ([Bind a], [Expr]) -> Cstr a
cubeSol (Bind a
b:[Bind a]
bs, [Expr]
eqs) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ ([Bind a], [Expr]) -> Cstr a
cubeSol ([Bind a]
bs, [Expr]
eqs)
cubeSol ([], [Expr]
eqs) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t ([Pred] -> Pred
PAnd ([Pred] -> Pred) -> [Pred] -> Pred
forall a b. (a -> b) -> a -> b
$ (Expr -> Pred
Reft (Expr -> Pred) -> [Expr] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SubstV Symbol -> [Expr] -> [Expr]
forall a. Subable a => SubstV Symbol -> a -> a
F.subst SubstV Symbol
su [Expr]
eqs) [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ (SubstV Symbol -> Pred -> Pred
forall a. Subable a => SubstV Symbol -> a -> a
F.subst SubstV Symbol
su (Pred -> Pred) -> [Pred] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
preds)) a
ann) Cstr a
cstr'
doelim Symbol
k [([Bind a], [Expr])]
_ (Head (Var Symbol
k' [Symbol]
_) a
a)
| Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k'
= Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Expr -> Pred
Reft Expr
forall v. ExprV v
F.PTrue) a
a
doelim Symbol
_ [([Bind a], [Expr])]
_ (Head Pred
p a
a) = Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
p a
a
doelim Symbol
k [([Bind a], [Expr])]
bss (Any (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c) =
case Symbol -> Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
findKVarInGuard Symbol
k Pred
p of
Right Pred
_ -> Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t Pred
p a
l) (Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [([Bind a], [Expr])]
bss Cstr a
c)
Left ([(Symbol, [Symbol])]
_, [Pred]
rights') -> Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t ([Pred] -> Pred
PAnd [Pred]
rights') a
l) (Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
forall a. Symbol -> [([Bind a], [Expr])] -> Cstr a -> Cstr a
doelim Symbol
k [([Bind a], [Expr])]
bss Cstr a
c)
findKVarInGuard :: F.Symbol -> Pred -> Either ([(F.Symbol, [F.Symbol])], [Pred]) Pred
findKVarInGuard :: Symbol -> Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
findKVarInGuard Symbol
k (PAnd [Pred]
ps) =
if [([(Symbol, [Symbol])], [Pred])] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([(Symbol, [Symbol])], [Pred])]
lefts
then Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
forall a b. b -> Either a b
Right ([Pred] -> Pred
PAnd [Pred]
ps)
else ([(Symbol, [Symbol])], [Pred])
-> Either ([(Symbol, [Symbol])], [Pred]) Pred
forall a b. a -> Either a b
Left ([(Symbol, [Symbol])]
newLefts, [Pred]
newRights)
where findResults :: [Either ([(Symbol, [Symbol])], [Pred]) Pred]
findResults = Symbol -> Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
findKVarInGuard Symbol
k (Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred)
-> [Pred] -> [Either ([(Symbol, [Symbol])], [Pred]) Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps
([([(Symbol, [Symbol])], [Pred])]
lefts, [Pred]
rights') = [Either ([(Symbol, [Symbol])], [Pred]) Pred]
-> ([([(Symbol, [Symbol])], [Pred])], [Pred])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either ([(Symbol, [Symbol])], [Pred]) Pred]
findResults
newLefts :: [(Symbol, [Symbol])]
newLefts = (([(Symbol, [Symbol])], [Pred]) -> [(Symbol, [Symbol])])
-> [([(Symbol, [Symbol])], [Pred])] -> [(Symbol, [Symbol])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([(Symbol, [Symbol])], [Pred]) -> [(Symbol, [Symbol])]
forall a b. (a, b) -> a
fst [([(Symbol, [Symbol])], [Pred])]
lefts
newRights :: [Pred]
newRights = (([(Symbol, [Symbol])], [Pred]) -> [Pred])
-> [([(Symbol, [Symbol])], [Pred])] -> [Pred]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([(Symbol, [Symbol])], [Pred]) -> [Pred]
forall a b. (a, b) -> b
snd [([(Symbol, [Symbol])], [Pred])]
lefts [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ [Pred]
rights'
findKVarInGuard Symbol
k p :: Pred
p@(Var Symbol
k' [Symbol]
xs)
| Symbol
k Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Symbol
k' = ([(Symbol, [Symbol])], [Pred])
-> Either ([(Symbol, [Symbol])], [Pred]) Pred
forall a b. a -> Either a b
Left ([(Symbol
k', [Symbol]
xs)], [])
| Bool
otherwise = Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
forall a b. b -> Either a b
Right Pred
p
findKVarInGuard Symbol
_ Pred
p = Pred -> Either ([(Symbol, [Symbol])], [Pred]) Pred
forall a b. b -> Either a b
Right Pred
p
boundKvars :: Cstr a -> S.Set F.Symbol
boundKvars :: forall a. Cstr a -> Set Symbol
boundKvars (Head Pred
p a
_) = Pred -> Set Symbol
pKVars Pred
p
boundKvars (CAnd [Cstr a]
c) = [Set Symbol] -> Set Symbol
forall a. Monoid a => [a] -> a
mconcat ([Set Symbol] -> Set Symbol) -> [Set Symbol] -> Set Symbol
forall a b. (a -> b) -> a -> b
$ Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars (Cstr a -> Set Symbol) -> [Cstr a] -> [Set Symbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
c
boundKvars (All (Bind Symbol
_ Sort
_ Pred
p a
_) Cstr a
c) = Pred -> Set Symbol
pKVars Pred
p Set Symbol -> Set Symbol -> Set Symbol
forall a. Semigroup a => a -> a -> a
<> Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
c
boundKvars (Any (Bind Symbol
_ Sort
_ Pred
p a
_) Cstr a
c) = Pred -> Set Symbol
pKVars Pred
p Set Symbol -> Set Symbol -> Set Symbol
forall a. Semigroup a => a -> a -> a
<> Cstr a -> Set Symbol
forall a. Cstr a -> Set Symbol
boundKvars Cstr a
c
pKVars :: Pred -> S.Set F.Symbol
pKVars :: Pred -> Set Symbol
pKVars (Var Symbol
k [Symbol]
_) = Symbol -> Set Symbol
forall a. a -> Set a
S.singleton Symbol
k
pKVars (PAnd [Pred]
ps) = [Set Symbol] -> Set Symbol
forall a. Monoid a => [a] -> a
mconcat ([Set Symbol] -> Set Symbol) -> [Set Symbol] -> Set Symbol
forall a b. (a -> b) -> a -> b
$ Pred -> Set Symbol
pKVars (Pred -> Set Symbol) -> [Pred] -> [Set Symbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps
pKVars Pred
_ = Set Symbol
forall a. Set a
S.empty
isNNF :: Cstr a -> Bool
isNNF :: forall a. Cstr a -> Bool
isNNF Head{} = Bool
True
isNNF (CAnd [Cstr a]
cs) = (Cstr a -> Bool) -> [Cstr a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Cstr a -> Bool
forall a. Cstr a -> Bool
isNNF [Cstr a]
cs
isNNF (All Bind a
_ Cstr a
c) = Cstr a -> Bool
forall a. Cstr a -> Bool
isNNF Cstr a
c
isNNF Any{} = Bool
False
calculateCuts :: (F.Fixpoint a, F.PPrint a) => F.Config -> Query a -> Cstr a -> S.Set F.Symbol
calculateCuts :: forall a.
(Fixpoint a, PPrint a) =>
Config -> Query a -> Cstr a -> Set Symbol
calculateCuts Config
cfg q :: Query a
q@(Query {}) Cstr a
nnf = HashSet KVar -> Set Symbol
convert (HashSet KVar -> Set Symbol) -> HashSet KVar -> Set Symbol
forall a b. (a -> b) -> a -> b
$ Elims KVar -> HashSet KVar
forall a. Elims a -> HashSet a
FG.depCuts Elims KVar
deps
where
([CEdge]
_, Elims KVar
deps) = Config -> GInfo SubC a -> ([CEdge], Elims KVar)
forall (c :: * -> *) a.
TaggedC c a =>
Config -> GInfo c a -> ([CEdge], Elims KVar)
elimVars Config
cfg (Config -> Query a -> GInfo SubC a
forall a. (Fixpoint a, PPrint a) => Config -> Query a -> FInfo a
hornFInfo Config
cfg (Query a -> GInfo SubC a) -> Query a -> GInfo SubC a
forall a b. (a -> b) -> a -> b
$ Query a
q { qCstr = nnf })
convert :: HashSet KVar -> Set Symbol
convert HashSet KVar
hashset = [Symbol] -> Set Symbol
forall a. Ord a => [a] -> Set a
S.fromList ([Symbol] -> Set Symbol) -> [Symbol] -> Set Symbol
forall a b. (a -> b) -> a -> b
$ KVar -> Symbol
F.kv (KVar -> Symbol) -> [KVar] -> [Symbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashSet KVar -> [KVar]
forall a. HashSet a -> [a]
HS.toList HashSet KVar
hashset
forgetPiVars :: S.Set F.Symbol -> Cstr a -> Cstr a
forgetPiVars :: forall a. Set Symbol -> Cstr a -> Cstr a
forgetPiVars Set Symbol
_ c :: Cstr a
c@Head{} = Cstr a
c
forgetPiVars Set Symbol
pis (CAnd [Cstr a]
cs) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
forall a. Set Symbol -> Cstr a -> Cstr a
forgetPiVars Set Symbol
pis (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
forgetPiVars Set Symbol
pis (All (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c)
| Var Symbol
k [Symbol]
_ <- Pred
p, Symbol
k Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Set Symbol
pis = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t ([Pred] -> Pred
PAnd []) a
l) (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
forall a. Set Symbol -> Cstr a -> Cstr a
forgetPiVars Set Symbol
pis Cstr a
c
| Bool
otherwise = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t Pred
p a
l) (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
forall a. Set Symbol -> Cstr a -> Cstr a
forgetPiVars Set Symbol
pis Cstr a
c
forgetPiVars Set Symbol
_ Any{} = [Char] -> Cstr a
forall a. HasCallStack => [Char] -> a
error [Char]
"shouldn't be present"
simplify :: Cstr a -> Cstr a
simplify :: forall a. Cstr a -> Cstr a
simplify = Cstr a -> Cstr a
forall a. Flatten a => a -> a
flatten (Cstr a -> Cstr a) -> (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
pruneTauts (Cstr a -> Cstr a) -> (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
removeDuplicateBinders
class Flatten a where
flatten :: a -> a
instance Flatten (Cstr a) where
flatten :: Cstr a -> Cstr a
flatten Cstr a
c = case Cstr a -> Maybe (Cstr a)
forall a. Cstr a -> Maybe (Cstr a)
flattenCstr Cstr a
c of
Just Cstr a
c' -> Cstr a
c'
Maybe (Cstr a)
Nothing -> [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd []
flattenCstr :: Cstr a -> Maybe (Cstr a)
flattenCstr :: forall a. Cstr a -> Maybe (Cstr a)
flattenCstr = Cstr a -> Maybe (Cstr a)
forall a. Cstr a -> Maybe (Cstr a)
go
where
go :: Cstr a -> Maybe (Cstr a)
go (Head (PAnd []) a
_) = Maybe (Cstr a)
forall a. Maybe a
Nothing
go (Head (Reft Expr
p) a
_)
| Expr -> Bool
forall v. Eq v => ExprV v -> Bool
F.isTautoPred Expr
p = Maybe (Cstr a)
forall a. Maybe a
Nothing
go (Head Pred
p a
a) = Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head (Pred -> Pred
forall a. Flatten a => a -> a
flatten Pred
p) a
a
go (CAnd [Cstr a]
cs) = [Cstr a] -> Maybe (Cstr a)
forall {a}. [Cstr a] -> Maybe (Cstr a)
mk ([Cstr a] -> Maybe (Cstr a))
-> ([Cstr a] -> [Cstr a]) -> [Cstr a] -> Maybe (Cstr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Cstr a -> [Cstr a]) -> [Cstr a] -> [Cstr a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Cstr a -> [Cstr a]
forall a. Cstr a -> [Cstr a]
splitAnd ([Cstr a] -> Maybe (Cstr a)) -> [Cstr a] -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ (Cstr a -> Maybe (Cstr a)) -> [Cstr a] -> [Cstr a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Cstr a -> Maybe (Cstr a)
forall a. Cstr a -> Maybe (Cstr a)
flattenCstr [Cstr a]
cs
go (All (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Pred -> Pred
forall a. Flatten a => a -> a
flatten Pred
p) a
l) (Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Cstr a -> Maybe (Cstr a)
go Cstr a
c
go (Any (Bind Symbol
x Sort
t Pred
p a
l) Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any (Symbol -> Sort -> Pred -> a -> Bind a
forall a. Symbol -> Sort -> Pred -> a -> Bind a
Bind Symbol
x Sort
t (Pred -> Pred
forall a. Flatten a => a -> a
flatten Pred
p) a
l) (Cstr a -> Cstr a) -> Maybe (Cstr a) -> Maybe (Cstr a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Cstr a -> Maybe (Cstr a)
go Cstr a
c
mk :: [Cstr a] -> Maybe (Cstr a)
mk [] = Maybe (Cstr a)
forall a. Maybe a
Nothing
mk [Cstr a
c] = Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c
mk [Cstr a]
cs = Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just ([Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Cstr a]
cs)
instance Flatten [Cstr a] where
flatten :: [Cstr a] -> [Cstr a]
flatten (CAnd [Cstr a]
cs : [Cstr a]
xs) = [Cstr a] -> [Cstr a]
forall a. Flatten a => a -> a
flatten [Cstr a]
cs [Cstr a] -> [Cstr a] -> [Cstr a]
forall a. [a] -> [a] -> [a]
++ [Cstr a] -> [Cstr a]
forall a. Flatten a => a -> a
flatten [Cstr a]
xs
flatten (Cstr a
x:[Cstr a]
xs)
| Head (Reft Expr
p) a
_ <- Cstr a
fx
, Expr -> Bool
forall v. Eq v => ExprV v -> Bool
F.isTautoPred Expr
p = [Cstr a] -> [Cstr a]
forall a. Flatten a => a -> a
flatten [Cstr a]
xs
| Bool
otherwise = Cstr a
fxCstr a -> [Cstr a] -> [Cstr a]
forall a. a -> [a] -> [a]
:[Cstr a] -> [Cstr a]
forall a. Flatten a => a -> a
flatten [Cstr a]
xs
where fx :: Cstr a
fx = Cstr a -> Cstr a
forall a. Flatten a => a -> a
flatten Cstr a
x
flatten [] = []
splitAnd :: Cstr a -> [Cstr a]
splitAnd :: forall a. Cstr a -> [Cstr a]
splitAnd (CAnd [Cstr a]
cs) = [Cstr a]
cs
splitAnd Cstr a
c = [Cstr a
c]
instance Flatten Pred where
flatten :: Pred -> Pred
flatten (PAnd [Pred]
preds) = case [Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
preds of
[Pred
p] -> Pred
p
[Pred]
ps -> [Pred] -> Pred
PAnd [Pred]
ps
flatten Pred
p = Pred
p
instance Flatten [Pred] where
flatten :: [Pred] -> [Pred]
flatten (PAnd [Pred]
ps' : [Pred]
ps) = [Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
ps' [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ [Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
ps
flatten (Pred
p : [Pred]
ps)
| Reft Expr
e <- Pred
fp
, Expr -> Bool
forall v. Eq v => ExprV v -> Bool
F.isTautoPred Expr
e = [Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
ps
| Bool
otherwise = Pred
fp Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: [Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
ps
where fp :: Pred
fp = Pred -> Pred
forall a. Flatten a => a -> a
flatten Pred
p
flatten [] = []
instance Flatten F.Expr where
flatten :: Expr -> Expr
flatten (F.PAnd [Expr]
exprs) = case [Expr] -> [Expr]
forall a. Flatten a => a -> a
flatten [Expr]
exprs of
[Expr
p] -> Expr
p
[Expr]
ps -> [Expr] -> Expr
forall v. [ExprV v] -> ExprV v
F.PAnd [Expr]
ps
flatten Expr
p = Expr
p
instance Flatten [F.Expr] where
flatten :: [Expr] -> [Expr]
flatten (F.PAnd [Expr]
ps' : [Expr]
ps) = [Expr] -> [Expr]
forall a. Flatten a => a -> a
flatten [Expr]
ps' [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Expr] -> [Expr]
forall a. Flatten a => a -> a
flatten [Expr]
ps
flatten (Expr
p : [Expr]
ps)
| Expr -> Bool
forall v. Eq v => ExprV v -> Bool
F.isTautoPred Expr
fp = [Expr] -> [Expr]
forall a. Flatten a => a -> a
flatten [Expr]
ps
| Bool
otherwise = Expr
fp Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: [Expr] -> [Expr]
forall a. Flatten a => a -> a
flatten [Expr]
ps
where fp :: Expr
fp = Expr -> Expr
forall a. Flatten a => a -> a
flatten Expr
p
flatten [] = []
hornify :: Cstr a -> Cstr a
hornify :: forall a. Cstr a -> Cstr a
hornify (Head (PAnd [Pred]
ps) a
a) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ((Pred -> a -> Cstr a) -> a -> Pred -> Cstr a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head a
a (Pred -> Cstr a) -> [Pred] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps')
where ps' :: [Pred]
ps' = let ([Pred]
ks, [Pred]
qs) = [Pred] -> [Pred] -> [Pred] -> ([Pred], [Pred])
splitP [] [] ([Pred] -> [Pred]
forall a. Flatten a => a -> a
flatten [Pred]
ps) in [Pred] -> Pred
PAnd [Pred]
qs Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: [Pred]
ks
splitP :: [Pred] -> [Pred] -> [Pred] -> ([Pred], [Pred])
splitP [Pred]
kacc [Pred]
pacc ((Var Symbol
x [Symbol]
xs):[Pred]
qs) = [Pred] -> [Pred] -> [Pred] -> ([Pred], [Pred])
splitP (Symbol -> [Symbol] -> Pred
Var Symbol
x [Symbol]
xs Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: [Pred]
kacc) [Pred]
pacc [Pred]
qs
splitP [Pred]
kacc [Pred]
pacc (Pred
q:[Pred]
qs) = [Pred] -> [Pred] -> [Pred] -> ([Pred], [Pred])
splitP [Pred]
kacc (Pred
qPred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
:[Pred]
pacc) [Pred]
qs
splitP [Pred]
kacc [Pred]
pacc [] = ([Pred]
kacc, [Pred]
pacc)
hornify (Head (Reft Expr
expr) a
a) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ((Pred -> a -> Cstr a) -> a -> Pred -> Cstr a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head a
a (Pred -> Cstr a) -> [Pred] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Expr -> Pred
Reft ([Expr] -> Expr
forall v. [ExprV v] -> ExprV v
F.PAnd [Expr]
ps)Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
:(Expr -> Pred
Reft (Expr -> Pred) -> [Expr] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr]
ks)))
where ([Expr]
ks, [Expr]
ps) = [Expr] -> [Expr] -> [Expr] -> ([Expr], [Expr])
forall {v}.
[ExprV v] -> [ExprV v] -> [ExprV v] -> ([ExprV v], [ExprV v])
splitP [] [] ([Expr] -> ([Expr], [Expr])) -> [Expr] -> ([Expr], [Expr])
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr]
F.splitPAnd Expr
expr
splitP :: [ExprV v] -> [ExprV v] -> [ExprV v] -> ([ExprV v], [ExprV v])
splitP [ExprV v]
kacc [ExprV v]
pacc (r :: ExprV v
r@F.PKVar{}:[ExprV v]
rs) = [ExprV v] -> [ExprV v] -> [ExprV v] -> ([ExprV v], [ExprV v])
splitP (ExprV v
rExprV v -> [ExprV v] -> [ExprV v]
forall a. a -> [a] -> [a]
:[ExprV v]
kacc) [ExprV v]
pacc [ExprV v]
rs
splitP [ExprV v]
kacc [ExprV v]
pacc (ExprV v
r:[ExprV v]
rs) = [ExprV v] -> [ExprV v] -> [ExprV v] -> ([ExprV v], [ExprV v])
splitP [ExprV v]
kacc (ExprV v
rExprV v -> [ExprV v] -> [ExprV v]
forall a. a -> [a] -> [a]
:[ExprV v]
pacc) [ExprV v]
rs
splitP [ExprV v]
kacc [ExprV v]
pacc [] = ([ExprV v]
kacc,[ExprV v]
pacc)
hornify (Head Pred
h a
a) = Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
h a
a
hornify (All Bind a
b Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
hornify Cstr a
c
hornify (Any Bind a
b Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
hornify Cstr a
c
hornify (CAnd [Cstr a]
cs) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ Cstr a -> Cstr a
forall a. Cstr a -> Cstr a
hornify (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
removeDuplicateBinders :: Cstr a -> Cstr a
removeDuplicateBinders :: forall a. Cstr a -> Cstr a
removeDuplicateBinders = Set Symbol -> Cstr a -> Cstr a
forall a. Set Symbol -> Cstr a -> Cstr a
go Set Symbol
forall a. Set a
S.empty
where
go :: Set Symbol -> Cstr a -> Cstr a
go Set Symbol
_ c :: Cstr a
c@Head{} = Cstr a
c
go Set Symbol
xs (CAnd [Cstr a]
cs) = [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd ([Cstr a] -> Cstr a) -> [Cstr a] -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
go Set Symbol
xs (Cstr a -> Cstr a) -> [Cstr a] -> [Cstr a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cstr a]
cs
go Set Symbol
xs (All b :: Bind a
b@(Bind Symbol
x Sort
_ Pred
_ a
_) Cstr a
c) = if Symbol
x Symbol -> Set Symbol -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Set Symbol
xs then Set Symbol -> Cstr a -> Cstr a
go Set Symbol
xs Cstr a
c else Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
go (Symbol -> Set Symbol -> Set Symbol
forall a. Ord a => a -> Set a -> Set a
S.insert Symbol
x Set Symbol
xs) Cstr a
c
go Set Symbol
xs (Any Bind a
b Cstr a
c) = Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
Any Bind a
b (Cstr a -> Cstr a) -> Cstr a -> Cstr a
forall a b. (a -> b) -> a -> b
$ Set Symbol -> Cstr a -> Cstr a
go Set Symbol
xs Cstr a
c
pruneTauts :: Cstr a -> Cstr a
pruneTauts :: forall a. Cstr a -> Cstr a
pruneTauts = Cstr a -> Maybe (Cstr a) -> Cstr a
forall a. a -> Maybe a -> a
fromMaybe ([Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd []) (Maybe (Cstr a) -> Cstr a)
-> (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Cstr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cstr a -> Maybe (Cstr a)
forall a. Cstr a -> Maybe (Cstr a)
go
where
go :: Cstr a -> Maybe (Cstr a)
go (Head Pred
p a
l) = do
Pred
p' <- Pred -> Maybe Pred
goP Pred
p
Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ Pred -> a -> Cstr a
forall a. Pred -> a -> Cstr a
Head Pred
p' a
l
go (CAnd [Cstr a]
cs) = if [Cstr a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Cstr a]
cs' then Maybe (Cstr a)
forall a. Maybe a
Nothing else Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just (Cstr a -> Maybe (Cstr a)) -> Cstr a -> Maybe (Cstr a)
forall a b. (a -> b) -> a -> b
$ [Cstr a] -> Cstr a
forall a. [Cstr a] -> Cstr a
CAnd [Cstr a]
cs'
where cs' :: [Cstr a]
cs' = (Cstr a -> Maybe (Cstr a)) -> [Cstr a] -> [Cstr a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Cstr a -> Maybe (Cstr a)
go [Cstr a]
cs
go (All Bind a
b Cstr a
c) = do
Cstr a
c' <- Cstr a -> Maybe (Cstr a)
go Cstr a
c
Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bind a -> Cstr a -> Cstr a
forall a. Bind a -> Cstr a -> Cstr a
All Bind a
b Cstr a
c')
go c :: Cstr a
c@Any{} = Cstr a -> Maybe (Cstr a)
forall a. a -> Maybe a
Just Cstr a
c
goP :: Pred -> Maybe Pred
goP (Reft Expr
e) = if Expr -> Bool
forall v. Eq v => ExprV v -> Bool
F.isTautoPred Expr
e then Maybe Pred
forall a. Maybe a
Nothing else Pred -> Maybe Pred
forall a. a -> Maybe a
Just (Pred -> Maybe Pred) -> Pred -> Maybe Pred
forall a b. (a -> b) -> a -> b
$ Expr -> Pred
Reft Expr
e
goP p :: Pred
p@Var{} = Pred -> Maybe Pred
forall a. a -> Maybe a
Just Pred
p
goP (PAnd [Pred]
ps) = if [Pred] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pred]
ps' then Maybe Pred
forall a. Maybe a
Nothing else Pred -> Maybe Pred
forall a. a -> Maybe a
Just (Pred -> Maybe Pred) -> Pred -> Maybe Pred
forall a b. (a -> b) -> a -> b
$ [Pred] -> Pred
PAnd [Pred]
ps'
where ps' :: [Pred]
ps' = (Pred -> Maybe Pred) -> [Pred] -> [Pred]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Pred -> Maybe Pred
goP [Pred]
ps