smcdel-1.3.0: src/SMCDEL/Internal/TaggedBDD.hs
module SMCDEL.Internal.TaggedBDD where
import Data.Tagged
import Data.HasCacBDD hiding (Top,Bot)
import SMCDEL.Language
-- * Tagged BDDs
-- | Operations on tagged BDDs.
-- The tag `a` is meant to be an empty type.
class TagForBDDs a where
-- | How many copies of the vocabulary do we have?
-- This is the number of markers + 1.
multiplier :: Tagged a Bdd -> Int
multiplier _ = 2
-- | Move back, must be without markers!
unmvBdd :: Tagged a Bdd -> Bdd
unmvBdd = relabelFun (\n -> if even n then n `div` 2 else error ("Odd: " ++ show n)) . untag
-- | Move into double vocabulary, but do not add marker
mv :: Bdd -> Tagged a Bdd
mv = cpMany 0
-- | Move into extended vocabulary, add one marker
cp :: Bdd -> Tagged a Bdd
cp = cpMany 1
-- | Move into extended vocabulary, add k many markers, MUST be available!
cpMany :: Int -> Bdd -> Tagged a Bdd
cpMany k b = let x = pure $ relabelFun (\n -> (2*n) + k) b
in if k >= multiplier x then error "Not enough markers!" else x
-- | Evaluate a tagged BDD.
tagBddEval :: [Prp] -> Tagged a Bdd -> Bool
tagBddEval truths querybdd = evaluateFun (untag querybdd) (\n -> P n `elem` truths)
-- * Pre-defined tags
-- | Tag for BDDs using the duplicated vocabulary \(V \cup V'\).
data Dubbel
instance TagForBDDs Dubbel where
multiplier = const 2
-- | Tag for BDDs using the triple vocabulary \(V \cup V' \cup V''\).
data Tripel
instance TagForBDDs Tripel where
multiplier = const 3
-- | Tag for BDDs using the quadruple vocabulary \(V \cup V' \cup V'' \cup V'''\).
data Quadrupel
instance TagForBDDs Quadrupel where
multiplier = const 4
-- * Generic definition for tagged BDDs
-- | The total relation as a tagged BDD.
totalRelBdd :: Tagged a Bdd
totalRelBdd = pure top
-- | The empty relation as a tagged BDD.
emptyRelBdd :: Tagged a Bdd
emptyRelBdd = pure bot
-- | Given a vocabulary, make a tagged BDD to say
-- that each plain variable \(p\) and the corresponding
-- marked variable \(p'\) variable have the same value:
-- \( \wedge_p (p \leftrightarrow p') \).
-- This encodes the identity relation.
allsamebdd :: TagForBDDs a => [Prp] -> Tagged a Bdd
allsamebdd ps = conSet <$> sequence [ equ <$> mv (var x) <*> cp (var x) | (P x) <- ps ]