Skip to content

Commit 19f5f06

Browse files
committed
[#328] [stbx-core] linearisation of wiring tree
1 parent dec939e commit 19f5f06

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed
Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
module Statebox.Core.WiringTree where
22

33
import Prelude
4-
import Data.Array (head)
4+
import Control.Apply (lift3)
5+
import Data.Array (head, length, partition, range)
6+
import Data.Either (Either(..), either)
57
import Data.Maybe (Maybe)
8+
import Data.Tuple.Nested ((/\))
69

7-
import Statebox.Core.Types (Diagram, Net, Wiring)
10+
import Data.ArrayMultiset (ArrayMultiset)
11+
import Data.Petrinet.Representation.NLL (ErrNetEncoding, TransitionF', fromNLL)
12+
import Statebox.Core.Execution (Path)
13+
import Statebox.Core.Types (Diagram, Net, PID, TID, Wiring)
814

915
data WiringTree
1016
= Net Net
@@ -14,3 +20,60 @@ data WiringTree
1420
-- | For the moment, we forget about diagrams and gluings and we consider only simple nets
1521
wiringToWiringTree :: Wiring -> Maybe WiringTree
1622
wiringToWiringTree wiring = Net <$> head wiring.nets
23+
24+
type Transition =
25+
{ path :: Path
26+
, transition :: TID
27+
, name :: String
28+
}
29+
30+
data Glued a
31+
= Untouched a
32+
| Initial a
33+
| Final a
34+
| Glued a a
35+
36+
isInitial :: forall a. Glued a -> Boolean
37+
isInitial = case _ of
38+
Initial a -> true
39+
_ -> false
40+
41+
isFinal :: forall a. Glued a -> Boolean
42+
isFinal = case _ of
43+
Final a -> true
44+
_ -> false
45+
46+
data LinerisationError
47+
= DiagramNotYetAllowed
48+
| NLLDecodingFailed ErrNetEncoding
49+
50+
linearise :: WiringTree -> Either LinerisationError (Array (Glued Transition))
51+
linearise (Net net) = lineariseNet net
52+
linearise (Diagram diagram branches) = Left DiagramNotYetAllowed
53+
54+
lineariseNet :: Net -> Either LinerisationError (Array (Glued Transition))
55+
lineariseNet net = linearisePartitionsAndNames net.partition net.names
56+
57+
linearisePartitionsAndNames :: ArrayMultiset PID -> Array String -> Either LinerisationError (Array (Glued Transition))
58+
linearisePartitionsAndNames partition names =
59+
either (NLLDecodingFailed >>> Left) (Right <<< flip lineriseTransitionsAndNames names) $ fromNLL 0 partition
60+
61+
-- the use of `lift3` does not consider the fact that the arrays could in principle have different lenghts
62+
lineriseTransitionsAndNames :: Array (TransitionF' PID) -> Array String -> Array (Glued Transition)
63+
lineriseTransitionsAndNames transitions names =
64+
sortInitialFinal $ lift3 buildGluedTransition (range 0 (length transitions - 1)) transitions names
65+
66+
buildGluedTransition :: TID -> TransitionF' PID -> String -> Glued Transition
67+
buildGluedTransition tId (inputs /\ outputs) name =
68+
case (inputs /\ outputs) of
69+
([] /\ _ ) -> Initial { name: name, path: [0, 0, 0], transition: tId } -- the path is [0, 0, 0] because we consider a trivial diagram to be there
70+
(_ /\ [] ) -> Final { name: name, path: [0, 0, 0], transition: tId }
71+
(inp /\ out) -> Untouched { name: name, path: [0, 0, 0], transition: tId }
72+
73+
-- | we are using this custom function instead of `sortBy` because that does not guarantee
74+
-- | the order of equal things to be preserved
75+
sortInitialFinal :: forall a. Array (Glued a) -> Array (Glued a)
76+
sortInitialFinal gluedItems =
77+
let { no: notInitial , yes: initial } = partition isInitial gluedItems
78+
{ no: notInitialAndFinal, yes: final } = partition isFinal notInitial
79+
in initial <> notInitialAndFinal <> final

0 commit comments

Comments
 (0)