1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
module TermGraph.XML
where
import ICurry.Graph
import XML
import Data.Maybe (fromMaybe)
import Data.List (nub)
type FingerPrint = [(ChoiceID,Int)]
data State = State { graph :: Graph
, activeNode :: NodeID
, results :: [NodeID]
, fingerprint :: FingerPrint
}
deriving (Show, Eq)
generateTextgraph :: State -> String
generateTextgraph = showXmlDoc . generateXmlgraph
compose4 :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
compose4 = (.) . (.) . (.) . (.)
states2XmlGraphs :: [State] -> XmlExp
states2XmlGraphs states = xml "graphlist" (map generateXmlgraph states)
generateXmlgraph :: State -> XmlExp
generateXmlgraph (State (Graph nodes _ root) activenid results fp) =
xml "graph" $
(xmlEntry "root" (show root)) :
(map (generateXmlNode activenid results) nodes) ++
(map xmlChoiceMapping (replaceChoiceIDs nodes fp))
generateXmlNode :: NodeID -> [NodeID] -> (NodeID, Node) -> XmlExp
generateXmlNode activenid results (nid, node) =
XElem "node" []
[
xmlEntry "id" (show nid),
xmlEntry "type" nType,
xmlEntry "label" label,
xmlEntry "isActive" (show isActive),
xmlEntry "isResult" (show isResult),
XElem "children" []
(map ((xmlEntry "nodeId") . show) succs)
]
where
(nType, label, succs) = case node of
FuncNode nm chld -> ("FuncNode", nm, chld)
ConsNode nm chld -> ("ConsNode", nm, chld)
ChoiceNode cid chld1 chld2 -> ("ChoiceNode", "? " ++ show cid,
[chld1, chld2])
FreeNode -> ("FreeNode", "free", [])
PartNode nm (PartFuncCall _) chld -> ("FuncNode", nm, chld)
PartNode nm (PartConsCall _) chld -> ("ConsNode", nm, chld)
isActive = nid == activenid
isResult = elem nid results
xmlChoiceMappings :: [(NodeID,Int)] -> [XmlExp]
xmlChoiceMappings mappings = map xmlChoiceMapping mappings
xmlChoiceMapping :: (NodeID,Int) -> XmlExp
xmlChoiceMapping (nid,chld) =
XElem "ChoiceMapping" [("from",show nid), ("to",show chld)] []
replaceChoiceIDs :: [(NodeID,Node)] -> FingerPrint -> [(NodeID,Int)]
replaceChoiceIDs _ [] = []
replaceChoiceIDs nodes ((cn,cm):ms) =
map (\x -> (x,cm))
(filter ((flip (choiceReachableFrom nodes ((cn,cm):ms) [])) 1)
(lookupChoiceNodeIds nodes cn)) ++
(replaceChoiceIDs nodes ms)
lookupChoiceNodeIds :: [(NodeID,Node)] -> ChoiceID -> [NodeID]
lookupChoiceNodeIds [] _ = []
lookupChoiceNodeIds ((nid,n):nodes) cid = case n of
ChoiceNode ccid _ _ | ccid == cid -> nid : (lookupChoiceNodeIds nodes cid)
| otherwise -> lookupChoiceNodeIds nodes cid
_ -> lookupChoiceNodeIds nodes cid
choiceReachableFrom :: [(NodeID,Node)] -> FingerPrint -> [NodeID] -> NodeID
-> NodeID -> Bool
choiceReachableFrom graph cms visited toNId fromNId
| fromNId == toNId = True
| otherwise
= let node = fromMaybe (error "choiceReachableFrom: Reached a node that is not in the graph")
(lookup fromNId graph)
newvis = fromNId : visited
in case node of
ChoiceNode cid c1 c2
| chDst == 1 -> choiceReachableFrom graph cms newvis toNId c1
| chDst == 2 -> choiceReachableFrom graph cms newvis toNId c2
| otherwise -> False
where chDst = fromMaybe 0 (lookup cid cms)
_ -> or $ map (choiceReachableFrom graph cms newvis toNId)
(nub $ nodeChildren node)
xmlEntry :: String -> String -> XmlExp
xmlEntry attr val = xml attr [xtxt val]
|