Project

General

Profile

Download (8.77 KB) Statistics
| Branch: | Tag: | Revision:
1
(********************************************************************)
2
(*                                                                  *)
3
(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
4
(*  Copyright 2012 -    --   ONERA - CNRS - INPT                    *)
5
(*                                                                  *)
6
(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
7
(*  under the terms of the GNU Lesser General Public License        *)
8
(*  version 2.1.                                                    *)
9
(*                                                                  *)
10
(********************************************************************)
11

    
12
(* The compilation presented here was first defined in Garoche, Gurfinkel,
13
   Kahsai, HCSV'14.
14

    
15
   This is a modified version that handle reset *)
16

    
17
open Utils
18
open Format
19
open Lustre_types
20
open Corelang
21
open Machine_code_types
22
open Horn_backend_common
23
open Horn_backend_printers
24

    
25
(* XXX: UNUSED *)
26
(* let pp_traces =
27
 *   pp_comma_list (fun fmt (v, e) -> fprintf fmt "%s -> %a" v Printers.pp_expr e) *)
28

    
29
(* Compute memories associated to each machine *)
30
let compute_mems machines m =
31
  let rec aux prefix m =
32
    List.map (fun mem -> prefix, mem) m.mmemory
33
    @ List.fold_left
34
        (fun accu (id, (n, _)) ->
35
          let name = node_name n in
36
          if name = "_arrow" then accu
37
          else
38
            let machine_n = get_machine machines name in
39
            aux ((id, machine_n) :: prefix) machine_n @ accu)
40
        []
41
        m.minstances
42
  in
43
  aux [] m
44

    
45
(* We extract the annotation dealing with traceability *)
46
let machines_traces machines =
47
  List.map
48
    (fun m ->
49
      let traces : (ident * expr) list =
50
        let all_annots =
51
          List.flatten (List.map (fun ann -> ann.annots) m.mannot)
52
        in
53
        let filtered =
54
          List.filter (fun (kwds, _) -> kwds = [ "traceability" ]) all_annots
55
        in
56
        (* List.iter (eprintf "Annots: %a@." Printers.pp_expr_annot) (m.mannot); *)
57
        let content = List.map snd filtered in
58
        (* Elements are supposed to be a pair (tuple): variable, expression *)
59
        List.map
60
          (fun ee ->
61
            match ee.eexpr_quantifiers, ee.eexpr_qfexpr.expr_desc with
62
            | [], Expr_tuple [ v; e ] -> (
63
              match v.expr_desc with
64
              | Expr_ident vid ->
65
                vid, e
66
              | _ ->
67
                assert false)
68
            | _ ->
69
              assert false)
70
          content
71
      in
72
      (* eprintf "Build traces: %a@." pp_traces traces; *)
73
      m, traces)
74
    machines
75

    
76
let memories_old machines m =
77
  List.map
78
    (fun (p, v) ->
79
      let machine = match p with [] -> m | (_, m') :: _ -> m' in
80
      let traces = List.assoc machine (machines_traces machines) in
81
      if List.mem_assoc v.var_id traces then
82
        ( (* We take the expression associated to variable v in the trace info *)
83

    
84
          (* eprintf "Found variable %a in traces: %a@." Printers.pp_var v *
85
             Printers.pp_expr (List.assoc v.var_id traces); *)
86
          p,
87
          List.assoc v.var_id traces )
88
      else
89
        ( (* We keep the variable as is: we create an expression v *)
90

    
91
          (* eprintf "Unable to found variable %a in traces (%a)@."
92
             Printers.pp_var v * pp_traces traces; *)
93
          p,
94
          mkexpr Location.dummy (Expr_ident v.var_id) ))
95
    (compute_mems machines m)
96

    
97
let memories_next machines m =
98
  (* We remove the topest pre in each expression *)
99
  List.map
100
    (fun (prefix, ee) ->
101
      let m = match prefix with [] -> m | (_, m') :: _ -> m' in
102
      match ee.expr_desc with
103
      | Expr_pre e ->
104
        prefix, e
105
      | Expr_ident var_id ->
106
        (* This memory was not introduced through normalization. It shall then
107
           be a regular x = pre y expression. Otherwise it would have been
108
           rewritten. We have to get its definition and extract the argument of
109
           the pre *)
110
        let selected_def =
111
          try
112
            List.find
113
              (fun def ->
114
                match def with
115
                | Eq eq -> (
116
                  match eq.eq_lhs with [ v ] -> v = var_id | _ -> assert false)
117
                | _ ->
118
                  false)
119
              m.mname.node_stmts
120
          with _ ->
121
            eprintf
122
              "Unable to find definition of %s in stmts %a@.prefix=%a@.@?"
123
              var_id
124
              Printers.pp_node_stmts
125
              m.mname.node_stmts
126
              (pp_comma_list (fun fmt (id, n) ->
127
                   fprintf fmt "(%s,%s)" id n.mname.node_id))
128
              (List.rev prefix);
129

    
130
            assert false
131
        in
132
        let def =
133
          match selected_def with
134
          | Eq eq -> (
135
            match eq.eq_lhs, eq.eq_rhs.expr_desc with
136
            | [ single_var ], Expr_pre e ->
137
              if single_var = var_id then e else assert false
138
            | _ ->
139
              assert false)
140
          | _ ->
141
            assert false
142
        in
143
        prefix, def
144
      | _ ->
145
        eprintf
146
          "Mem Failure: (prefix: %a, eexpr: %a)@.@?"
147
          (pp_comma_list (fun fmt (id, n) ->
148
               fprintf fmt "(%s,%s)" id n.mname.node_id))
149
          (List.rev prefix)
150
          Printers.pp_expr
151
          ee;
152
        assert false)
153
    (memories_old machines m)
154

    
155
(* XXX: UNUSED *)
156
(* let pp_prefix_rev fmt prefix =
157
 *   pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt ".")
158
 *     (fun fmt (id, n) -> fprintf fmt "(%s,%s)" id n.mname.node_id)
159
 *     fmt (List.rev prefix) *)
160

    
161
let traces_file fmt machines =
162
  let pp_l = pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt " | ") in
163
  fprintf fmt "<?xml version=\"1.0\"?>@.";
164
  fprintf
165
    fmt
166
    "<Traces xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">@.";
167
  fprintf
168
    fmt
169
    "@[<v 5>@ %a@ @]@."
170
    (pp_print_list (fun fmt m ->
171
         let pp_var = pp_horn_var m in
172
         let memories_old = memories_old machines m in
173
         let memories_next = memories_next machines m in
174

    
175
         (* fprintf fmt "; Node %s@." m.mname.node_id; *)
176
         fprintf fmt "@[<v 2><Node name=\"%s\">@ " m.mname.node_id;
177

    
178
         let input_vars =
179
           rename_machine_list m.mname.node_id m.mstep.step_inputs
180
         in
181
         let output_vars =
182
           rename_machine_list m.mname.node_id m.mstep.step_outputs
183
         in
184
         fprintf
185
           fmt
186
           "<input name=\"%a\" type=\"%a\">%a</input>@ "
187
           (pp_l (pp_horn_var m))
188
           input_vars
189
           (pp_l (fun fmt id -> pp_type fmt id.var_type))
190
           input_vars
191
           (pp_l (pp_horn_var m))
192
           m.mstep.step_inputs;
193

    
194
         fprintf
195
           fmt
196
           "<output name=\"%a\" type=\"%a\">%a</output>@ "
197
           (pp_l pp_var)
198
           output_vars
199
           (pp_l (fun fmt id -> pp_type fmt id.var_type))
200
           output_vars
201
           (pp_l pp_var)
202
           m.mstep.step_outputs;
203

    
204
         let local_vars =
205
           try full_memory_vars ~without_arrow:true machines m
206
           with Not_found ->
207
             eprintf "machine %s@.@?" m.mname.node_id;
208
             assert false
209
         in
210
         let init_local_vars = rename_next_list local_vars in
211
         let step_local_vars = rename_current_list local_vars in
212

    
213
         fprintf
214
           fmt
215
           "<localInit name=\"%a\" type=\"%a\">%t%a</localInit>@ "
216
           (pp_l pp_var)
217
           init_local_vars
218
           (pp_l (fun fmt id -> pp_type fmt id.var_type))
219
           init_local_vars
220
           (fun fmt ->
221
             match memories_next with [] -> () | _ -> fprintf fmt "")
222
           (pp_l (fun fmt (_, ee) -> fprintf fmt "%a" pp_xml_expr ee))
223
           memories_next;
224

    
225
         fprintf
226
           fmt
227
           "<localStep name=\"%a\" type=\"%a\">%t%a</localStep>@ "
228
           (pp_l pp_var)
229
           step_local_vars
230
           (pp_l (fun fmt id -> pp_type fmt id.var_type))
231
           step_local_vars
232
           (fun fmt -> match memories_old with [] -> () | _ -> fprintf fmt "")
233
           (pp_l (fun fmt (_, ee) -> fprintf fmt "(%a)" pp_xml_expr ee))
234
           memories_old;
235

    
236
         let arrow_vars = arrow_vars machines m in
237
         let arrow_vars_curr = rename_current_list arrow_vars
238
         and arrow_vars_mid = rename_mid_list arrow_vars
239
         and arrow_vars_next = rename_next_list arrow_vars in
240
         pp_print_list
241
           (fun fmt v -> fprintf fmt "<reset name=\"%a\"/>" pp_var v)
242
           fmt
243
           (arrow_vars_curr @ arrow_vars_mid @ arrow_vars_next);
244
         fprintf fmt "@]@ </Node>"))
245
    (List.rev machines);
246
  fprintf fmt "</Traces>@."
247

    
248
(* (Utils.fprintf_list ~sep:" | " (fun fmt (prefix, ee) -> fprintf fmt "%a%a"
249
   pp_prefix_rev prefix Printers.pp_expr ee)) memories_next; *)
250
(* (Utils.fprintf_list ~sep:" | " (fun fmt (prefix,ee) -> fprintf fmt "%a(%a)" *)
251
(* pp_prefix_rev prefix Printers.pp_expr ee)) (memories_old); *)
252

    
253
(* Local Variables: *)
254
(* compile-command:"make -C ../.." *)
255
(* End: *)
(9-9/10)