 blocking0 (ProcessAction ac _ _ )
--         | isBlocking ac = Just (S.singleton [1])
--         | otherwise     = Nothing
-- blocking0 (ProcessComb NDC _ pl pr)
--     | (Just sl) <- blocking0 pl, (Just sr) <- blocking0 pr = Just (([1] <.>sl) `S.union` ([2]<.>sr))
--     | otherwise = Nothing
-- blocking0 _ =  Nothing

pfFrom :: (MonadCatch m, Show ann, Typeable ann) => AnProcess ann -> m (S.Set ProcessPosition)
pfFrom process = from' process True
    where
    from' proc b 
        | ProcessNull _ <- proc  = return S.empty
        | otherwise = do
        -- |  (ProcessAction ac _ p' ) <- proc = 
        -- singletonOrEmpty (conditionAction proc b) `S.union` [1]<.> from' p' (isBlocking ac)
        -- | (ProcessComb comb _ pl pr) <- proc =
        res <- foldM (addWithRecursive proc) S.empty (next proc)
        return $ singletonOrEmpty (conditionAction proc b) `S.union` res
        -- `S.union`   ([1] <.> from' pl False)
        -- `S.union`   ([2] <.> from' pr False)
    singletonOrEmpty True  =  S.singleton []
    singletonOrEmpty False =  S.empty
    conditionAction proc b = not (blocking proc) && b -- condition to add singleton set is given, see Def. 14 in paper
    addWithRecursive proc accu pos = do
                        p'   <- processAt proc pos
                        res  <- from' p' (blocking proc)
                        return $ accu `S.union` (pos <.> res)

-- | Combine set of sets of position so that they describe alternatives (see comment for progressTo)
-- combine x y = { union of xi and yi | xi in x and yi in y}
c
pfFrom :: (MonadCatch m, Show ann, Typeable ann) => AnProcess ann -> m (S.Set ProcessPosition)
pfFrom process = from' process True
    where
    from' proc b 
        | ProcessNull _ <- proc  = return S.empty
        | otherwise = do
        -- |  (ProcessAction ac _ p' ) <- proc = 
        -- singletonOrEmpty (conditionAction proc b) `S.union` [1]<.> from' p' (isBlocking ac)
        -- | (ProcessComb comb _ pl pr) <- proc =
        res <- foldM (addWithRecursive proc) S.empty (next proc)
        return $ singletonOrEmpty (conditionAction proc b) `S.union` res
        -- `S.union`   ([1] <.> from' pl False)
        -- `S.union`   ([2] <.> from' pr False)
    singletonOrEmpty True  =  S.singleton []
    singletonOrEmpty False =  S.empty
    conditionAction proc b = not (blocking proc) && b -- condition to add singleton set is given, see Def. 14 in paper
    addWithRecursive proc accu pos = do
                        p'   <- processAt proc pos
                        res  <- from' p' (blocking proc)
                        return $ accu `S.union` (pos <.> res)

-- | Combine set of sets of position so that they describe alternatives (see comment for progressTo)
-- combine x y = { union of xi and yi | xi in x and yi in y}
pfFrom process = from' process True
    where
    from' proc b 
        | ProcessNull _ <- proc  = return S.empty
        | otherwise = do
        -- |  (ProcessAction ac _ p' ) <- proc = 
        -- singletonOrEmpty (conditionAction proc b) `S.union` [1]<.> from' p' (isBlocking ac)
        -- | (ProcessComb comb _ pl pr) <- proc =
        res <- foldM (addWithRecursive proc) S.empty (next proc)
        return $ singletonOrEmpty (conditionAction proc b) `S.union` res
        -- `S.union`   ([1] <.> from' pl False)
        -- `S.union`   ([2] <.> from' pr False)
    singletonOrEmpty True  =  S.singleton []
    singletonOrEmpty False =  S.empty
    conditionAction proc b = not (blocking proc) && b -- condition to add singleton set is given, see Def. 14 in paper
    addWithRecursive proc accu pos = do
                        p'   <- processAt proc pos
                        res  <- from' p' (blocking proc)
                        return $ accu `S.union` (pos <.> res)

-- | Combine set of sets of position so that they describe alternatives (see comment for progressTo)
-- combine x y = { union of xi and yi | xi in x and yi in y}