1
|
open Basetypes
|
2
|
open Datatype
|
3
|
open Format
|
4
|
open Log
|
5
|
open SF
|
6
|
|
7
|
let actions_performed = ref []
|
8
|
|
9
|
|
10
|
(*******************************)
|
11
|
|
12
|
type env_t = bool ActiveStates.Env.t (* Don't care for values yet *)
|
13
|
let pp_env = ActiveStates.Env.pp_env
|
14
|
|
15
|
type success_t = env_t -> path_t -> env_t
|
16
|
type fail_t = env_t -> env_t
|
17
|
|
18
|
type kenv_t = {
|
19
|
cont_node : (
|
20
|
path_t * (
|
21
|
(kenv_t -> env_t -> path_t -> event_t -> env_t) *
|
22
|
(kenv_t -> env_t -> event_t -> env_t) *
|
23
|
(kenv_t -> env_t -> event_t -> env_t)
|
24
|
)
|
25
|
) list;
|
26
|
cont_junc : (
|
27
|
junction_name_t * (
|
28
|
kenv_t -> env_t -> success_t -> fail_t -> event_t -> env_t)
|
29
|
) list
|
30
|
}
|
31
|
|
32
|
let theta_j dest theta =
|
33
|
(try
|
34
|
List.assoc dest theta.cont_junc
|
35
|
with Not_found ->
|
36
|
(eprintf "Lost junction %a@ " pp_junction_name dest;
|
37
|
assert false
|
38
|
)
|
39
|
) theta
|
40
|
|
41
|
let theta_e, theta_d, theta_x =
|
42
|
let theta_node id theta =
|
43
|
try
|
44
|
List.assoc id theta.cont_node
|
45
|
with Not_found ->
|
46
|
(eprintf "Lost path [%a]@." pp_path id;
|
47
|
assert false
|
48
|
)
|
49
|
in
|
50
|
(fun id theta -> let (e,d,x) = theta_node id theta in e theta),
|
51
|
(fun id theta -> let (e,d,x) = theta_node id theta in d theta),
|
52
|
(fun id theta -> let (e,d,x) = theta_node id theta in x theta)
|
53
|
|
54
|
let add_action a = actions_performed := !actions_performed @ [a]
|
55
|
|
56
|
let eval_act action theta rho =
|
57
|
(match action with
|
58
|
| Action.Call _ -> assert false
|
59
|
| Action.Quote s -> add_action s; () (*Format.eprintf "----- action = %s@." s*)
|
60
|
| Action.Nil -> () (* no action *)
|
61
|
| _ -> assert false (* other constructs should not appear here *)
|
62
|
);
|
63
|
rho
|
64
|
|
65
|
let rec eval_cond condition (evt, rho) =
|
66
|
match condition, evt with
|
67
|
| Condition.True, _ -> true
|
68
|
| Condition.Active p, _ -> ActiveStates.Env.find p rho
|
69
|
| Condition.Event e, Some evt -> e = evt
|
70
|
| Condition.Event e, None -> false
|
71
|
| Condition.Neg cond, _ -> not (eval_cond cond (evt, rho))
|
72
|
| Condition.And (cond1, cond2), _ -> (eval_cond cond1 (evt, rho)) && (eval_cond cond2 (evt, rho))
|
73
|
| Condition.Quote c, _ -> add_action c; true (* invalid behavior but similar to the other: should evaluate condition *)
|
74
|
|
75
|
(* (match condition with Some s -> printf "----- cond = %s@." s | _ -> ()); *)
|
76
|
(* true *)
|
77
|
|
78
|
let bot _ = assert false
|
79
|
|
80
|
let eval_dest dest theta rho success fail e =
|
81
|
log (fun fmt -> fprintf fmt "@[<v 2>D[[%a]] (%a)?@ " SF.pp_dest dest pp_env rho);
|
82
|
let res =
|
83
|
match dest with
|
84
|
| DPath p -> success rho p
|
85
|
| DJunction j -> theta_j j theta rho success fail e
|
86
|
in
|
87
|
log (fun fmt -> fprintf fmt "@]@ D[[%a]]: %a@ " SF.pp_dest dest pp_env res);
|
88
|
res
|
89
|
|
90
|
let eval_tau trans theta rho success fail e =
|
91
|
(* eprintf "%t@." (fun fmt -> fprintf fmt "@[<v 2>tau[[%a]] (%a)?@ " SF.pp_trans trans pp_env rho); *)
|
92
|
let res =
|
93
|
if (match trans.event with None -> true | _ -> e = trans.event) && eval_cond trans.condition (trans.event, rho) then
|
94
|
let success' rho_s p =
|
95
|
(* eprintf "succes de tau %a: p = %a@." pp_trans trans pp_path p; *)
|
96
|
if p = [] then (
|
97
|
(* eprintf "cas1@."; *)
|
98
|
success rho_s [] (* was p but p is [] *)
|
99
|
)
|
100
|
else (
|
101
|
(* eprintf "cas2@."; *)
|
102
|
success (eval_act trans.transition_act theta rho_s) p
|
103
|
)
|
104
|
in
|
105
|
eval_dest trans.dest theta (eval_act trans.condition_act theta rho) success' fail e
|
106
|
else
|
107
|
fail rho
|
108
|
|
109
|
in
|
110
|
(* eprintf "%t@." (fun fmt -> fprintf fmt "@]@ tau[[%a]]: %a@ " pp_trans trans pp_env res); *)
|
111
|
res
|
112
|
|
113
|
let rec eval_T tl theta rho success fail e =
|
114
|
log (fun fmt -> fprintf fmt "@[<v 2>T[[%a]] (%a)?@ " pp_transitions tl pp_env rho);
|
115
|
let res =
|
116
|
match tl with
|
117
|
| [] -> success rho []
|
118
|
| t::[] -> eval_tau t theta rho success fail e
|
119
|
| t::t'::tl ->
|
120
|
let fail' rho_f = eval_T (t'::tl) theta rho_f success fail e in
|
121
|
eval_tau t theta rho success fail' e
|
122
|
in
|
123
|
log (fun fmt -> fprintf fmt "@]@ T[[%a]]: %a@ " pp_transitions tl pp_env res);
|
124
|
res
|
125
|
|
126
|
let eval_open rho p = ActiveStates.Env.add p true rho
|
127
|
let eval_close rho p = ActiveStates.Env.add p false rho
|
128
|
|
129
|
let eval_Ce prefix comp theta rho e =
|
130
|
log (fun fmt -> fprintf fmt "@[<v 2>Ce[[%a, %a]] (%a)?@ " pp_path prefix pp_comp comp pp_env rho);
|
131
|
let res =
|
132
|
match comp with
|
133
|
| Or (_T, []) -> log (fun fmt -> fprintf fmt "no content: = no impact@ "); rho
|
134
|
| Or (_T, _S) -> eval_T _T theta rho (fun rho_s p -> theta_e p theta rho_s [] e) bot e
|
135
|
| And (_S) -> List.fold_left (fun accu p -> theta_e (prefix@[p]) theta rho [] e) rho _S
|
136
|
in
|
137
|
log (fun fmt -> fprintf fmt "@]@ Ce[[%a, %a]]: %a@ " pp_path prefix pp_comp comp pp_env res);
|
138
|
res
|
139
|
|
140
|
let rec eval_Cd prefix comp theta rho e =
|
141
|
log (fun fmt -> fprintf fmt "@[<v 0>Cd[[%a, %a]] (%a)?@ " pp_path prefix pp_comp comp pp_env rho);
|
142
|
let res =
|
143
|
match comp with
|
144
|
| Or (_T, []) -> rho
|
145
|
| Or (_T, p::_S) ->
|
146
|
if ActiveStates.Env.find (prefix@[p]) rho then (
|
147
|
log (fun fmt -> fprintf fmt "active node %a: running it@ " pp_path (prefix@[p]));
|
148
|
|
149
|
(* (\********** QUESTION SUR L'ORDRE A HAMZA **************\) *)
|
150
|
(* let rho', success = *)
|
151
|
(* (\* if true (\\* cas 1: during_act effectué avant execution des components *\\) then *\) *)
|
152
|
(* theta_d (prefix@[p]) theta rho e, (\* <-- update rho with theta_d of node (prefix@[p]) *\) *)
|
153
|
(* (fun rho_s p' -> theta_d p' theta rho_s e) (\* <-- default success function *\) *)
|
154
|
(* (\* je ne suis pas sur de ce p', peut etre faut il rajouter prefix@[p] devant ? *\) *)
|
155
|
(* (\* else (\\* cas 2: during_act postponé apres execution des components *\\) *\) *)
|
156
|
(* (\* rho, (\\* <-- on ne touche pas a rho *\\) *\) *)
|
157
|
(* (\* (fun rho_s p' -> theta_d p' theta rho_s e) *\) *)
|
158
|
(* (\* (\\* je ne suis pas sur de ce p', peut etre faut il rajouter prefix@[p] devant ? *\\) *\) *)
|
159
|
(* in *)
|
160
|
(* eval_T _T theta rho' success bot e *)
|
161
|
(* (\********** QUESTION SUR L'ORDRE A HAMZA **************\) *)
|
162
|
|
163
|
(* CODE PRECEDENT TEL QUE DECRIT DANS L'ARTICLE *)
|
164
|
theta_d (prefix@[p]) theta rho e
|
165
|
(* CODE PRECEDENT TEL QUE DECRIT DANS L'ARTICLE *)
|
166
|
)
|
167
|
else (
|
168
|
log (fun fmt -> fprintf fmt "inactive node %a: continuing on the list %a@ " pp_path (prefix@[p]) (Utils.fprintf_list ~sep:"; " pp_state_name) _S);
|
169
|
eval_Cd prefix (Or (_T, _S)) theta rho e
|
170
|
)
|
171
|
| And (_S) -> List.fold_left (fun accu p -> theta_d (prefix@[p]) theta rho e) rho _S
|
172
|
in
|
173
|
log (fun fmt -> fprintf fmt "@]@ Cd[[%a, %a]]: %a@ " pp_path prefix pp_comp comp pp_env res);
|
174
|
res
|
175
|
|
176
|
let eval_Cx prefix comp theta rho e : env_t =
|
177
|
log (fun fmt -> fprintf fmt "@[<v 2>Cx[[%a, %a]] (%a)?@ " pp_path prefix pp_comp comp pp_env rho);
|
178
|
let res =
|
179
|
match comp with
|
180
|
| Or (_T, _S) ->
|
181
|
List.fold_left
|
182
|
(fun rho p -> if ActiveStates.Env.find (prefix @ [p]) rho then theta_x (prefix@[p]) theta rho e else rho)
|
183
|
rho
|
184
|
_S
|
185
|
| And (_S) -> List.fold_left (fun accu p -> theta_x (prefix@[p]) theta rho e) rho _S
|
186
|
in
|
187
|
log (fun fmt -> fprintf fmt "@]@ Cx[[%a, %a]]: %a@ " pp_path prefix pp_comp comp pp_env res);
|
188
|
res
|
189
|
|
190
|
let eval_Se (p:path_t) p_def theta rho path e =
|
191
|
log (fun fmt -> fprintf fmt "@[<v 2>Se[[node %a, path %a]] (%a)?@ " pp_path p pp_path path pp_env rho);
|
192
|
let res =
|
193
|
let rho' = eval_act p_def.state_actions.entry_act theta rho in
|
194
|
match path with
|
195
|
| [] -> eval_open (eval_Ce p p_def.internal_composition theta rho' e) p
|
196
|
| s::path_tl -> eval_open (theta_e (p@[s]) theta rho' path_tl e) p
|
197
|
in
|
198
|
log (fun fmt -> fprintf fmt "@]@ Se[[node %a, path %a]]: %a@ " pp_path p pp_path path pp_env res);
|
199
|
res
|
200
|
|
201
|
let eval_Sx p p_def theta rho e =
|
202
|
log (fun fmt -> fprintf fmt "@[<v 2>Sx[[node %a]] (%a)?@ " pp_path p pp_env rho);
|
203
|
let res =
|
204
|
eval_close
|
205
|
(eval_act p_def.state_actions.exit_act theta
|
206
|
(eval_Cx p p_def.internal_composition theta rho e)
|
207
|
)
|
208
|
p
|
209
|
in
|
210
|
log (fun fmt -> fprintf fmt "@]@ Sx[[node %a]]: %a@ " pp_path p pp_env res);
|
211
|
res
|
212
|
|
213
|
let rec eval_open_path theta rho p p1 p2 term e =
|
214
|
match p1, p2 with
|
215
|
| _, [] -> term rho
|
216
|
| x::ps, y::pd ->
|
217
|
if x = y then
|
218
|
eval_open_path theta rho (p@[x]) ps pd term e
|
219
|
else
|
220
|
let rho_x = theta_x (p@[x]) theta rho e in
|
221
|
theta_e (p@[y]) theta rho_x pd e
|
222
|
| _ -> assert false
|
223
|
|
224
|
let eval_Sd p p_def theta rho e =
|
225
|
log (fun fmt -> fprintf fmt "@[<v 2>Sd[[node %a]] (%a)?@ " pp_path p pp_env rho);
|
226
|
let res =
|
227
|
let fail rho_f =
|
228
|
let faili (rho_fi: env_t) : env_t =
|
229
|
eval_Cd p p_def.internal_composition theta (eval_act p_def.state_actions.during_act theta rho_fi) e
|
230
|
in
|
231
|
let successi rho_si p_d =
|
232
|
eval_open_path theta rho_si [] p p_d faili e in
|
233
|
log (fun fmt -> fprintf fmt "eval_inner %a@ " pp_transitions p_def.inner_trans);
|
234
|
eval_T p_def.inner_trans theta rho_f successi faili e
|
235
|
in
|
236
|
let success rho_s p_d =
|
237
|
eval_open_path theta rho_s [] p p_d fail e in
|
238
|
log (fun fmt -> fprintf fmt "eval_outer %a@ " pp_transitions p_def.outer_trans);
|
239
|
eval_T p_def.outer_trans theta rho success fail e
|
240
|
in
|
241
|
log (fun fmt -> fprintf fmt "@]@ Sd[[node %a]]: %a@ " pp_path p pp_env res);
|
242
|
res
|
243
|
|
244
|
|
245
|
let eval_prog (s, defs) (e, rho) =
|
246
|
(* Action list is uglily encoded using global variables. Shame on me! *)
|
247
|
actions_performed := [];
|
248
|
(* (match e with Some s -> printf "EVENT = %s@." s | _ -> ()); *)
|
249
|
let theta = List.fold_left (
|
250
|
fun accu d -> match d with
|
251
|
| State (p, defp) -> { accu with cont_node = (p, (eval_Se p defp, eval_Sd p defp, eval_Sx p defp))::accu.cont_node }
|
252
|
| Junction (j, defj) -> { accu with cont_junc = (j, (eval_T defj))::accu.cont_junc }
|
253
|
) {cont_node = []; cont_junc = []} defs in
|
254
|
let res =
|
255
|
if ActiveStates.Env.find [s] rho then
|
256
|
theta_d [s] theta rho e
|
257
|
else
|
258
|
theta_e [s] theta rho [] e
|
259
|
in
|
260
|
res, !actions_performed
|
261
|
|