 | Given a process p, find set of set of positions describing the conjunctive
-- normal form of the positions that    we need to go to.
-- For example: {{p1},{p2,p3}} means we need to go to p1 AND to either p2 or p3.
-- Correspond to f in Def. 15
f :: (Show ann, MonadCatch m, Typeable ann) => AnProcess ann -> m (S.Set (S.Set ProcessPosition))
f  p -- corresponds to f within generate progressfunction.ml
    | blocking p = return $ ss []
    | (ProcessComb Parallel  _ pl pr) <- p =  do
                ll <- f pl
                lr <- f pr
                return $ S.union ([1] <..>  ll) ([2] <..>  lr)
    | otherwise = foldM combineWithRecursive
                            (S.singleton S.empty) -- accumulator, set of sets of position
                                                  -- not that the Singleton set of the empty set is
                                                  -- the neutral element with respect to combine
                                                  -- the empty set combined with anything gives an emptyset
                            (next0 p) -- list of p∈next^0(proc)
    where ss x = S.singleton ( S.singleton x) -- shortcut for singleton set of singleton set
          combineWithRecursive acc pos = do -- combine pss with positions from recursive call (case of nested NDCs)
                        proc'   <- processAt p pos
                        lpos <- f proc'
                        return $ combine (pos <..> lpos) acc

-- | Compute progress function of proc
pf 
f :: (Show ann, MonadCatch m, Typeable ann) => AnProcess ann -> m (S.Set (S.Set ProcessPosition))
f  p -- corresponds to f within generate progressfunction.ml
    | blocking p = return $ ss []
    | (ProcessComb Parallel  _ pl pr) <- p =  do
                ll <- f pl
                lr <- f pr
                return $ S.union ([1] <..>  ll) ([2] <..>  lr)
    | otherwise = foldM combineWithRecursive
                            (S.singleton S.empty) -- accumulator, set of sets of position
                                                  -- not that the Singleton set of the empty set is
                                                  -- the neutral element with respect to combine
                                                  -- the empty set combined with anything gives an emptyset
                            (next0 p) -- list of p∈next^0(proc)
    where ss x = S.singleton ( S.singleton x) -- shortcut for singleton set of singleton set
          combineWithRecursive acc pos = do -- combine pss with positions from recursive call (case of nested NDCs)
                        proc'   <- processAt p pos
                        lpos <- f proc'
                        return $ combine (pos <..> lpos) acc

-- | Compute progress function of proc
f  p -- corresponds to f within generate progressfunction.ml
    | blocking p = return $ ss []
    | (ProcessComb Parallel  _ pl pr) <- p =  do
                ll <- f pl
                lr <- f pr
                return $ S.union ([1] <..>  ll) ([2] <..>  lr)
    | otherwise = foldM combineWithRecursive
                            (S.singleton S.empty) -- accumulator, set of sets of position
                                                  -- not that the Singleton set of the empty set is
                                                  -- the neutral element with respect to combine
                                                  -- the empty set combined with anything gives an emptyset
                            (next0 p) -- list of p∈next^0(proc)
    where ss x = S.singleton ( S.singleton x) -- shortcut for singleton set of singleton set
          combineWithRecursive acc pos = do -- combine pss with positions from recursive call (case of nested NDCs)
                        proc'   <- processAt p pos
                        lpos <- f proc'
                        return $ combine (pos <..> lpos) acc

-- | Compute progress function of proc