This repository was archived by the owner on Jun 28, 2025. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathTypedTrace.hs
More file actions
158 lines (142 loc) · 5.45 KB
/
Copy pathTypedTrace.hs
File metadata and controls
158 lines (142 loc) · 5.45 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- |
-- Copyright : (c) NASA, 2024-2025
-- License : BSD-style (see the LICENSE file in the distribution)
--
-- Read and modify traces of specifications.
--
-- In the context of this module, a trace refers only to the values of
-- externs, since the state of a spec can be reproduced if the values of
-- externs are known.
module Copilot.Visualize.TypedTrace
( extractTrace
, updateWithTrace
, Trace(..)
, UValues(..)
)
where
-- External imports
import Data.List hiding ((++))
import Data.Maybe (fromMaybe)
import qualified Data.Type.Equality as DE
import Data.Typeable (Typeable)
import Prelude hiding (div, not, (++), (<), (>))
-- External imports: Copilot
import qualified Copilot.Core as Core
import Language.Copilot hiding (interpret, typeOf)
-- | Map stream names to their values.
newtype Trace = Trace
{ traceMap :: [ (String, UValues) ]
}
-- | Existentially typed list of values of a stream.
data UValues = forall a . Typeable a => UValues
{ uvType :: Core.Type a
, uvValues :: [ a ]
}
-- | Extract a trace from a core specification.
extractTrace :: Core.Spec -> Trace
extractTrace spec = Trace $ concat $ concat
[ fmap extractTraceStream (Core.specStreams spec)
, fmap extractTraceObserver (Core.specObservers spec)
, fmap extractTraceTrigger (Core.specTriggers spec)
]
-- | Extract the values of a core 'Stream'.
extractTraceStream :: Core.Stream -> [ (String, UValues) ]
extractTraceStream (Core.Stream _id _buf expr _ty) =
extractTraceExpr expr
-- | Extract the values of a core 'Observer'.
extractTraceObserver :: Core.Observer -> [ (String, UValues) ]
extractTraceObserver (Core.Observer _name expr _ty) =
extractTraceExpr expr
-- | Extract the values of a core 'Trigger'.
extractTraceTrigger :: Core.Trigger -> [ (String, UValues) ]
extractTraceTrigger (Core.Trigger _name expr args) = concat $
extractTraceExpr expr
: fmap extractTraceUExpr args
-- | Extract the values of a core 'Expr'.
extractTraceExpr :: Core.Expr a -> [ (String, UValues) ]
extractTraceExpr (Core.Local _ _ _ expr1 expr2) = concat
[ extractTraceExpr expr1
, extractTraceExpr expr2
]
extractTraceExpr (Core.ExternVar ty name values) =
[ (name, UValues ty (fromMaybe [] values)) ]
extractTraceExpr (Core.Op1 _op expr) =
extractTraceExpr expr
extractTraceExpr (Core.Op2 _op expr1 expr2) = concat
[ extractTraceExpr expr1
, extractTraceExpr expr2
]
extractTraceExpr (Core.Op3 _op expr1 expr2 expr3) = concat
[ extractTraceExpr expr1
, extractTraceExpr expr2
, extractTraceExpr expr3
]
extractTraceExpr (Core.Label _ty _lbl expr) =
extractTraceExpr expr
extractTraceExpr _ = []
-- | Extract the values of a core 'UExpr'.
extractTraceUExpr :: Core.UExpr -> [ (String, UValues) ]
extractTraceUExpr (Core.UExpr ty expr) = extractTraceExpr expr
-- | Update externs in a spec.
updateWithTrace :: Trace -> Core.Spec -> Core.Spec
updateWithTrace trace spec = spec
{ Core.specStreams =
fmap (updateWithTraceStream trace) (Core.specStreams spec)
, Core.specObservers =
fmap (updateWithTraceObserver trace) (Core.specObservers spec)
, Core.specTriggers =
fmap (updateWithTraceTrigger trace) (Core.specTriggers spec)
}
-- | Update the values of a 'Stream' based on an input trace.
updateWithTraceStream :: Trace -> Core.Stream -> Core.Stream
updateWithTraceStream trace (Core.Stream ident buf expr ty) =
Core.Stream ident buf (updateWithTraceExpr trace expr) ty
-- | Update the values of an 'Observer' based on an input trace.
updateWithTraceObserver :: Trace -> Core.Observer -> Core.Observer
updateWithTraceObserver trace (Core.Observer name expr ty) =
Core.Observer name (updateWithTraceExpr trace expr) ty
-- | Update the values of a 'Trigger' based on an input trace.
updateWithTraceTrigger :: Trace -> Core.Trigger -> Core.Trigger
updateWithTraceTrigger trace (Core.Trigger name expr args) =
Core.Trigger
name
(updateWithTraceExpr trace expr)
(fmap (updateWithTraceUExpr trace) args)
-- | Update the values of an 'Expr' based on an input trace.
updateWithTraceExpr :: Trace -> Core.Expr a -> Core.Expr a
updateWithTraceExpr trace (Core.Local ty1 ty2 name expr1 expr2) =
Core.Local
ty1
ty2
name
(updateWithTraceExpr trace expr1)
(updateWithTraceExpr trace expr2)
updateWithTraceExpr trace (Core.ExternVar ty name values) =
Core.ExternVar ty name values'
where
values' | Just (UValues ty2 vals) <- lookup name (traceMap trace)
, Just DE.Refl <- DE.testEquality ty ty2
= Just vals
| otherwise
= values
updateWithTraceExpr trace (Core.Op1 op expr) =
Core.Op1 op (updateWithTraceExpr trace expr)
updateWithTraceExpr trace (Core.Op2 op expr1 expr2) =
Core.Op2 op
(updateWithTraceExpr trace expr1)
(updateWithTraceExpr trace expr2)
updateWithTraceExpr trace (Core.Op3 op expr1 expr2 expr3) =
Core.Op3 op
(updateWithTraceExpr trace expr1)
(updateWithTraceExpr trace expr2)
(updateWithTraceExpr trace expr3)
updateWithTraceExpr trace (Core.Label ty lbl expr) =
Core.Label ty lbl (updateWithTraceExpr trace expr)
updateWithTraceExpr trace x = x
-- | Update the values of a 'UExpr' based on an input trace.
updateWithTraceUExpr :: Trace -> Core.UExpr -> Core.UExpr
updateWithTraceUExpr trace (Core.UExpr ty expr) =
Core.UExpr ty (updateWithTraceExpr trace expr)