package lustre-v6

  1. Overview
  2. Docs
The Lustre V6 Verimag compiler

Install

Dune Dependency

Authors

Maintainers

Sources

lustre-v6.v6.107.1.tgz
md5=4b642b106a76e19de3751afb53ccdcf4
sha512=ec6d35f0f4da219490cad7969d86e9128b7c3f03baa507f662b038b1915383581eda697ddb0e734a1a5311ef6b0908b1d0cf375a0be5dbb1aa7e9e79848037cc

doc/src/lustre-v6/actionsDeps.ml.html

Source file actionsDeps.ml

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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
(** Time-stamp: <modified the 21/03/2022 (at 11:43) by Erwan Jahier> *)
  
let dbg = (Lv6Verbose.get_flag "deps")

type action = Action.t

(*********************************************************************************)
module OrderedAction = struct
  type t = action
  let compare = compare
end

(** Gère un ensemble d'actions uniques. *)
module Actions = Set.Make(OrderedAction)

module MapAction = Map.Make(OrderedAction)

(** maps an action to the set of actions that it depends on *)
(* exported *)
type t = Actions.t MapAction.t

(* exported *)
let empty: t = MapAction.empty

(* exported *)
let (have_deps : t -> action -> bool) = 
  fun m a -> 
    MapAction.mem a m
  
(* exported *)
let (remove_dep :  t -> action -> t) =
  fun deps a -> 
  Lv6Verbose.exe ~flag:dbg (fun () ->
      Printf.printf "  remove_deps(%s)\n%!" (Action.to_string a));
    MapAction.remove a deps

(* exported *)
let (find_deps: t -> action -> action list) = 
  fun m a ->
  let res =
    try Actions.elements (MapAction.find a m) with Not_found -> []
  in
  Lv6Verbose.exe ~flag:dbg (fun () ->
      Printf.printf "find_deps(%s)='%s'\n%!" (Action.to_string a)
        (String.concat "+" (List.map Action.to_string res)));
  res

let rec (depends_on : t -> Action.t -> Action.t -> bool) =
  fun m a1 a2 ->
    try
      let a1_deps = MapAction.find a1 m in
      Actions.mem a2 a1_deps || 
        (* XXX should I compute the closure of the deps once for all ? *)
        Actions.exists (fun a1 -> depends_on m a1 a2) a1_deps
    with 
        Not_found -> false
    
(*********************************************************************************)
(** Ajoute une liste de dépendances à une action. *)
let add_deps: t -> action -> action list -> t =
  fun m a -> function
    | [] ->
      Lv6Verbose.exe
        ~flag:dbg (fun () -> Printf.printf " add_deps(%s,[]) \n%!"  (Action.to_string a));
      m
    | al ->
      Lv6Verbose.exe
        ~flag:dbg (fun () -> Printf.printf "\n add_deps(%s,???)\n%!" (Action.to_string a));
      let actions = try MapAction.find a m with Not_found -> Actions.empty in
      let actions = List.fold_left (fun set a -> Actions.add a set) actions al in
      Lv6Verbose.exe ~flag:dbg (fun () ->
          Printf.printf " add_deps(%s,[%s])\n%!" (Action.to_string a)
            (String.concat "+" (List.map Action.to_string al)));
      MapAction.add a actions m

(* exported *)
let (concat: t -> t -> t) =
  fun m1 m2 ->
    MapAction.fold (fun key value m -> add_deps m key (Actions.elements value)) m1 m2
   
(*********************************************************************************)
(* exported *)
let (generate_deps_from_step_policy:
       Soc.precedence list -> (string * action) list -> t) =
  fun precedences actions ->
    let generate_deps_for_action: (t -> string * string list -> t) =
      fun ad (action_name, actions_needed) ->
        let main_action = snd (List.find (fun (n, _) -> n = action_name) actions) in
        let deps =
          List.map
            (fun dep_name -> snd (List.find (fun (n, _) -> n = dep_name) actions))
            actions_needed
        in
          add_deps ad main_action deps
    in
      List.fold_left (generate_deps_for_action) empty precedences


(*********************************************************************************)
module VarMap = Map.Make(String)

(** A Data structure that maps a Soc.var_expr to all the
    actions that needed to compute it. 

    It is used to know which actions impact which Soc.var_expr.

nb : you can have several actions associated to the same var_expr
when defining arrays or structures parts by parts. For instance
  x[0]=42;
  x[1]=1;
 are two actions that define the var_expr "x"

*)
type var2actions_tbl = Actions.t VarMap.t

let var2actions k tbl =
  let k = SocUtils.string_of_filter k in
  let res = try VarMap.find k tbl with Not_found -> Actions.empty in
  res
 
let rec (gen_parents : Soc.var_expr  -> Soc.var_expr list) =
  fun var -> 
(* if var = t.[2].field, then it returns [t.[2].field; t.[2] ; t]  *)
    match var with
      | Soc.Slice(ve,_,_,_,_,_)
      | Soc.Field(ve,_,_)  
      | Soc.Index(ve,_,_) -> ve::(gen_parents ve)
      | Soc.Var(_,_vt)
      | Soc.Const(_,_vt) -> [var]

let rec (_get_top_var : Soc.var_expr  -> Soc.var_expr) =
  fun var -> 
(* if var = t.[2].field, then it returns (also) t.[2] and t  *)
    match var with
      | Soc.Slice(ve,_,_,_,_,_)
      | Soc.Field(ve,_,_)  
      | Soc.Index(ve,_,_) -> _get_top_var ve
      | Soc.Var(_,_vt)
      | Soc.Const(_,_vt) -> var 

(** If x is a int^2, then  
     then actions such as  a="x = y" 
  should produce the following dependancies :
     x -> a
     x[0] -> a
     x[1] -> a

  Hence, gen_children "x" produces "x[0]", and "x[1]"
 *) 
let rec (gen_children: Soc.var_expr -> Soc.var_expr list) =
  fun v ->
  match Soc.data_type_of_var_expr v with
  | Data.Alpha _ | Data.Extern _ | Data.Enum _ | Data.String
  | Data.Bool | Data.Int | Data.Real
    -> [v]
  | Data.Struct(_ident, ident_t_list) ->
     List.fold_left
       (fun acc (id,t) ->
        let new_ve = Soc.Field(v,id,t) in
        new_ve::((gen_children new_ve) @ acc)
       )
       []
       ident_t_list
  | Data.Array(t,size) ->
     let new_ve_list = ref [] in
     for i=0 to size - 1 do
       let new_ve = Soc.Index(v, i, t) in
       new_ve_list := new_ve::((gen_children new_ve) @ !new_ve_list);
     done;
     !new_ve_list
  | Data.Alias(_,_t) ->  assert false (* sno ? *)

let nodupl l =
  List.fold_left (fun acc x -> if List.mem x acc then acc else x::acc) [] l 

                               
let (get_var2actions_tbl : action list -> var2actions_tbl) = 
  fun al ->
  let (tabulate_action : var2actions_tbl -> action -> var2actions_tbl) =
    fun tbl action ->
      let _, _, lhs, _, _lxm = action in
      let (tabulate_output:var2actions_tbl -> Soc.var_expr -> var2actions_tbl) =
        fun tbl output ->
          let v = (* get_top_var *) output in (* for x of type t^2^2  *)
          let children = gen_children v in (*    children(x[0]) = [x[0][0];x[0][1]] *)
          let parents = gen_parents v in   (* and parents(x[0]) = [x] *)
          let all = nodupl ((v::children)@parents) in
          let tbl =
            (* add the current action as a dep of v and its children and its parents *)
            List.fold_left
              (fun tbl cv ->
                 Lv6Verbose.exe ~flag:dbg (fun () ->
                     Printf.printf "  var_add_deps:  '%s' depends on '%s'\n%!"
                       (SocUtils.string_of_var_expr cv) (Action.to_string action));
                 let cv_actions = var2actions cv tbl in
                 VarMap.add (SocUtils.string_of_filter cv) (Actions.add action cv_actions) tbl)
              tbl all
          in
          tbl
      in
      List.fold_left tabulate_output tbl lhs
  in
  List.fold_left tabulate_action VarMap.empty al


(** Returns the actions that depend on a set of vars, according to the content
   of a table compute before
    
    [actions_of_vars input_vars al] trouve toutes les actions de [al] qui
    ont besoin d'être effectuées avant de pouvoir se servir de [input_vars]
    comme entrée d'une autre action.

    TODO: gérer les dépendances entre des filtres plus complexes,
    comme par ex., l'utilisation d'un champ d'une structure.
*)
let (_actions_of_vars_old: Soc.var_expr list -> var2actions_tbl -> action list) =
  fun vars tbl ->
    let find_deps var = Actions.elements (var2actions var tbl) in
    (*     let vars = List.flatten (List.map gen_parents vars) in   *)
    (*     let vars = List.fold_left (* remove duplicates *) *)
    (*                  (fun acc x -> if List.mem x acc then acc else x::acc) [] vars *)
    (*     in *)
    List.flatten (List.map find_deps vars)

let (actions_of_vars: Soc.var_expr list -> var2actions_tbl -> action list) =
  fun vars tbl ->
  let actions = 
    List.fold_left 
      (fun acc v -> Actions.union acc (var2actions v tbl))
      Actions.empty
      vars
  in
  let res = Actions.elements actions in
  Lv6Verbose.exe
    ~flag:dbg (fun () ->
        Printf.printf "actions_of_vars(%s)='%s'\n%!"
          (String.concat "," (List.map SocUtils.string_of_var_expr vars))
          (String.concat "+" (List.map Action.to_string res))
      );
  res
     
(*********************************************************************************)
(* Some Printers to ease the debugging *)

let string_of_actions: Actions.t -> string = fun s ->
  let to_string a acc =
    acc ^ "\n\t + '"^ (Action.to_string_msg a) ^ "'"
  in
    "" ^ (Actions.fold to_string s "") ^ ""

let string_of_var2actions_tbl: var2actions_tbl -> string = 
  fun s ->
    let to_string key value acc =
      let entry = Format.sprintf "%s depends on the following actions: %s"
          key (string_of_actions value)
      in
        acc ^ entry ^ "\n"
    in
      "var2actions_tbl: {\n" ^ (VarMap.fold to_string s "") ^ "}"

let to_string: t -> string = fun m ->
  let to_string key value acc =
    let entry =
      Format.sprintf "- '%s' depends on:%s"
        (Action.to_string key)
        (string_of_actions value)
    in
      acc ^ entry ^ "\n"
  in
    "dependencies between equations are: \n" ^ (MapAction.fold to_string m "") ^ ""

(*
let (add_parents : var2actions_tbl -> var2actions_tbl) =
  fun tbl ->
  let f var actions acc =
    let pvars = gen_parents var in
    List.folf_left
      (fun acc pvar ->
       let pactions = try var2actions pvar acc with Not_found -> Actions.empty in

      )
      acc pvars
  in
  VarMap.fold f tbl tbl
 *)                                                                                 
(* It's useless to close this ; toposort will do it

let rec close : t -> t =
  fun deps ->
  let f action actions acc =
      Actions.fold
        (fun a acc ->
         let a_actions = MapAction.find a acc in
         let new_actions = Actions.union actions a_actions in
         MapAction.add action new_actions acc
        )
        actions acc    
  in
  let new_deps = MapAction.fold f deps deps in
  if deps = new_deps (* use MapAction.equal ? *)
  then deps else close new_deps
 *)                                        
(*********************************************************************************)
(* exported *)
let build_data_deps_from_actions:  (Lic.type_ -> Data.t) -> t -> action list -> t =
  fun lic_to_data_type deps al ->
  let tbl = get_var2actions_tbl al in
  (*   let tbl = add_parents tbl in *)
  let pp_dbg () = 
    let al_str = List.map Action.to_string al in
    print_string "\n ====> List of actions to be sorted:\n - ";
    print_string (String.concat "\n - " al_str);
    print_string "\n ====> List of previously computed dependencies:(\n  ";
    print_string (string_of_var2actions_tbl tbl);
    print_string ")\n";
    flush stdout
  in
    let deps =
    Lv6Verbose.exe ~flag:dbg pp_dbg;
    List.fold_left
      (fun acc_deps action ->
       let (clk, rhs, _, _,_) = action in
       let dep_vars = match clk with
         | Lic.BaseLic -> rhs
         | Lic.ClockVar _int -> rhs
         | Lic.On ((_cc,cv,ct),_) ->
            (* The clock should be computed before the clocked expression *)
           (Soc.Var(cv, lic_to_data_type ct))::rhs
       in
       let action_deps = actions_of_vars dep_vars tbl in
       if action_deps = [] then (
         let dep_str = String.concat "," (List.map SocUtils.string_of_filter dep_vars) in
         Lv6Verbose.exe
           ~flag:dbg (fun () ->
               Printf.printf "   No deps for %s (dep_vars=%s) \n%!" (Action.to_string action) dep_str);
         acc_deps
       )
       else (
         Lv6Verbose.exe ~flag:dbg (fun () ->
             Printf.printf " %s depends on %s ==> calling add_deps\n" (Action.to_string action)
               (String.concat "  +  " (List.map Action.to_string action_deps)));
         add_deps acc_deps action action_deps
       )
      )
      deps
      al
  in
  (*     let deps = close deps in *)
  deps

   
OCaml

Innovation. Community. Security.