writeHLNet :: Monad m => FilePath -> String -> PN m SimValue -> IO ()
    writeHLNet file _partName pn = do
        handle <- openFile file WriteMode
        hPutStrLn handle "PEP"
        hPutStrLn handle "HLNet"
        hPutStrLn handle "FORMAT_N"
        hPutStrLn handle "PL"
        mapM_ (hPutStrLn handle . (flip showPlace) "") $ DM.assocs $ pnPlaces pn
        hPutStrLn handle "TR"
        mapM_ (hPutStrLn handle . (flip showTrans) "") $ DM.assocs $ pnTrans pn
        hPutStrLn handle "TP"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showTtoP pos transNo placeNo "") $ zip [0..] $ transOutPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hPutStrLn handle "PT"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showPtoT pos placeNo transNo "") $ zip [0..] $ transInPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hClose handle
        where
            showPlace (placeNo, place) = shows placeNo . shows (joinLabel (placeLabel place)) .
                showString "0@0" .
                showString "Z\"" .
                (case placeType place of
                    BlackPlaceType -> showString "{dot}"
                    NumericPlaceType width -> showString "{0.." . shows ((bit width :: Integer) - 1) . showChar '}'
                    ) .
                showString "\"" .
                initMarking
                where
                    initMarking = case marking DM.! placeNo of
                        [] -> id
                        [value] -> let
                            markingShows = showChar '"' . showChar '{' . showSimValue value . showChar '}' .
                                showChar '"'
                            in showChar 'z' . markingShows . showChar 'y' . markingShows
                        _ -> error "writeHLNet: can't handle initial marking with >1 token"

            showTrans (transNo, trans) = shows transNo . shows (joinLabel (transLabel trans)) .
                showString "0@0" .
                showString "g\"" . -- tt & " .
                (case transCondition trans of
                    Just cond -> hlShowPNExpr cond . showString " & "
                    _ -> id) .
                (showListWithSep (showString " & ") showExpr $ zip [(0::Int)..] (transExprs trans)) .
                showString "\""
                where showExpr (i, expr) = showChar 'o' . shows i . showString " = " . hlShowPNExpr expr

            showTtoP pos transNo placeNo = shows transNo . showChar '<' . shows placeNo .
                showString "p\"o" . shows (pos :: Int) . showString "\""

            showPtoT pos placeNo transNo = shows placeNo . showChar '>' . shows transNo .
                showString "p\"i" . shows (pos :: Int) . showString "\""

            showSimValue NoSimValue = showString "dot"
            showSimValue (SimValue int []) = shows int
            showSimValue simValue = error $ "writeHLNet: can't print SimValue `" ++ show simValue ++ "'"

            marking = pnInitialMarking pn
            -- placesToTrans = pnPlacesToTrans pn
writeHLNet :: Monad m => FilePath -> String -> PN m SimValue -> IO ()
writeHLNet file _partName pn = do
        handle <- openFile file WriteMode
        hPutStrLn handle "PEP"
        hPutStrLn handle "HLNet"
        hPutStrLn handle "FORMAT_N"
        hPutStrLn handle "PL"
        mapM_ (hPutStrLn handle . (flip showPlace) "") $ DM.assocs $ pnPlaces pn
        hPutStrLn handle "TR"
        mapM_ (hPutStrLn handle . (flip showTrans) "") $ DM.assocs $ pnTrans pn
        hPutStrLn handle "TP"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showTtoP pos transNo placeNo "") $ zip [0..] $ transOutPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hPutStrLn handle "PT"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showPtoT pos placeNo transNo "") $ zip [0..] $ transInPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hClose handle
        where
            showPlace (placeNo, place) = shows placeNo . shows (joinLabel (placeLabel place)) .
                showString "0@0" .
                showString "Z\"" .
                (case placeType place of
                    BlackPlaceType -> showString "{dot}"
                    NumericPlaceType width -> showString "{0.." . shows ((bit width :: Integer) - 1) . showChar '}'
                    ) .
                showString "\"" .
                initMarking
                where
                    initMarking = case marking DM.! placeNo of
                        [] -> id
                        [value] -> let
                            markingShows = showChar '"' . showChar '{' . showSimValue value . showChar '}' .
                                showChar '"'
                            in showChar 'z' . markingShows . showChar 'y' . markingShows
                        _ -> error "writeHLNet: can't handle initial marking with >1 token"

            showTrans (transNo, trans) = shows transNo . shows (joinLabel (transLabel trans)) .
                showString "0@0" .
                showString "g\"" . -- tt & " .
                (case transCondition trans of
                    Just cond -> hlShowPNExpr cond . showString " & "
                    _ -> id) .
                (showListWithSep (showString " & ") showExpr $ zip [(0::Int)..] (transExprs trans)) .
                showString "\""
                where showExpr (i, expr) = showChar 'o' . shows i . showString " = " . hlShowPNExpr expr

            showTtoP pos transNo placeNo = shows transNo . showChar '<' . shows placeNo .
                showString "p\"o" . shows (pos :: Int) . showString "\""

            showPtoT pos placeNo transNo = shows placeNo . showChar '>' . shows transNo .
                showString "p\"i" . shows (pos :: Int) . showString "\""

            showSimValue NoSimValue = showString "dot"
            showSimValue (SimValue int []) = shows int
            showSimValue simValue = error $ "writeHLNet: can't print SimValue `" ++ show simValue ++ "'"

            marking = pnInitialMarking pn
            -- placesToTrans = pnPlacesToTrans pn
writeHLNet file _partName pn = do
        handle <- openFile file WriteMode
        hPutStrLn handle "PEP"
        hPutStrLn handle "HLNet"
        hPutStrLn handle "FORMAT_N"
        hPutStrLn handle "PL"
        mapM_ (hPutStrLn handle . (flip showPlace) "") $ DM.assocs $ pnPlaces pn
        hPutStrLn handle "TR"
        mapM_ (hPutStrLn handle . (flip showTrans) "") $ DM.assocs $ pnTrans pn
        hPutStrLn handle "TP"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showTtoP pos transNo placeNo "") $ zip [0..] $ transOutPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hPutStrLn handle "PT"
        mapM_ (\(transNo, trans) -> mapM' (\(pos, placeNo) ->
            hPutStrLn handle $ showPtoT pos placeNo transNo "") $ zip [0..] $ transInPlaces trans
            ) $ DM.assocs $ pnTrans pn
        hClose handle
        where
            showPlace (placeNo, place) = shows placeNo . shows (joinLabel (placeLabel place)) .
                showString "0@0" .
                showString "Z\"" .
                (case placeType place of
                    BlackPlaceType -> showString "{dot}"
                    NumericPlaceType width -> showString "{0.." . shows ((bit width :: Integer) - 1) . showChar '}'
                    ) .
                showString "\"" .
                initMarking
                where
                    initMarking = case marking DM.! placeNo of
                        [] -> id
                        [value] -> let
                            markingShows = showChar '"' . showChar '{' . showSimValue value . showChar '}' .
                                showChar '"'
                            in showChar 'z' . markingShows . showChar 'y' . markingShows
                        _ -> error "writeHLNet: can't handle initial marking with >1 token"

            showTrans (transNo, trans) = shows transNo . shows (joinLabel (transLabel trans)) .
                showString "0@0" .
                showString "g\"" . -- tt & " .
                (case transCondition trans of
                    Just cond -> hlShowPNExpr cond . showString " & "
                    _ -> id) .
                (showListWithSep (showString " & ") showExpr $ zip [(0::Int)..] (transExprs trans)) .
                showString "\""
                where showExpr (i, expr) = showChar 'o' . shows i . showString " = " . hlShowPNExpr expr

            showTtoP pos transNo placeNo = shows transNo . showChar '<' . shows placeNo .
                showString "p\"o" . shows (pos :: Int) . showString "\""

            showPtoT pos placeNo transNo = shows placeNo . showChar '>' . shows transNo .
                showString "p\"i" . shows (pos :: Int) . showString "\""

            showSimValue NoSimValue = showString "dot"
            showSimValue (SimValue int []) = shows int
            showSimValue simValue = error $ "writeHLNet: can't print SimValue `" ++ show simValue ++ "'"

            marking = pnInitialMarking pn
            -- placesToTrans = pnPlacesToTrans pn