tpdb-2.7.1: src/TPDB/DP/Graph.hs
{-# language OverloadedStrings #-}
module TPDB.DP.Graph where
import TPDB.DP.TCap
import TPDB.DP.Unify
import TPDB.DP.Transform
import TPDB.Data
import TPDB.Pretty
import TPDB.Plain.Read -- for testing
import TPDB.Plain.Write -- for testing
import qualified Data.IntSet as S
import qualified Data.IntMap.Strict as M
import Data.Graph ( stronglyConnComp, SCC(..) )
import Control.Monad ( guard, forM )
import Control.Applicative
import Control.Monad.State.Strict
-- | DP problems for strongly connected components,
-- topologically sorted, with CyclicComponents in Right,
-- others in Left.
components s = do
let su = indexed s
ns = filter (not . strict) (rules s)
es = M.fromListWith (<>)
$ do (i,j) <- edges su ; return (i, S.singleton j)
comp <- reverse $ stronglyConnComp $ do
(i,u) <- M.toList su
let js = M.findWithDefault mempty i es
return (u, i, S.toList js)
return $ case comp of
CyclicSCC vs -> Right $ s { rules = vs <> ns }
AcyclicSCC v -> Left v
-- | edges of the estimated dependency graph
edges su = do
(i,u) <- M.toList su
(j,v) <- M.toList su
guard $ unifies ( vmap Left $ tcap (M.elems su) $ rhs u )
( vmap Right $ lhs v )
return (i,j)
check = edges $ indexed $ dp sys
-- | numbering for non-strict rules
indexed :: TRS v c -> M.IntMap (Rule (Term v c))
indexed s = M.fromList $ zip [0::Int ..] $ filter strict $ rules s
-- example from "DP Revisited" http://colo6-c703.uibk.ac.at/ttt/rta04.pdf
Right sys =
TPDB.Plain.Read.trs "(VAR x y) (RULES not(not(x)) -> x not(or(x,y)) -> and(not(x),not(y)) not(and(x,y)) -> or (not(x),not(y)) and(x,or(y,z)) -> or(and(x,z),and(y,z)) and(or(y,z),x) -> or(and(x,y),and(x,z)))"