Project

General

Profile

« Previous | Next » 

Revision 4c945dde

Added by Pierre-Loïc Garoche over 1 year ago

Improved tiny backend

View differences:

src/tools/tiny/tiny_tube.ml
1
(* 
2
TODO:
3

  
4
- export du tube sur la tete de boucle:
5
  - par exemple un tube par dimension en 2d: temps x valeur
6
  - en sage ? en gnuplot? en tikz?
7
  - deux facon de visualiser le partitionnement
8
    - si on choisi un tube 2d, par exemple la variable x, on doit pouvoir visualiser le split du tube en fonction d'une variable booleenne. Par exemple on choisi b1 et on voit deux couleurs sur le tube de x. Ou on se restreint a b1 true ou b1 false 
9
    - on doit aussi pouvoir afficher globalement pour une variable booleen le split. On choisi par exemple b1 de facon gloable et tous les tubes sont raffines en b1 true / b1 false / b1 both / b1 split enfin pour avoir deux plots separes.
10

  
11
   - par exemple un csv
12
   nb_temps, x_min, x_max, y_min, y_max, b1_true_x_min, b1_true_x_max, b1_true_y_min, b1_true_y_max, ....
13

  
14

  
15
  - 
16
- export de l'ast en latex avec des instructions tikz puis ensuite l'affichage des elements abstraits a chaque point de programme pour les articles. On peut desactiver ou activer les domaines grace aux options
17

  
18
*)
19

  
20

  
21
let pp_var fmt ((n,t),ctx) =
22
  (* Tiny.Ast.Var.pp_ fmt v *)
23
  match ctx with
24
  | None ->
25
    Format.fprintf fmt "%s" n  
26
  | Some ((bv, _),b) ->
27
     Format.fprintf fmt "%s __ %s = %b" n bv b  
28

  
29
  
30
let pp_bound fmt b = Tiny.Scalar.pp fmt b 
31

  
32
module type S =
33
  sig
34
    module Results: Tiny.Analyze.Results
35
    val list: (int * Results.Dom.t) list
36
    val bounds:  ((Tiny.Ast.Var.t * (Tiny.Ast.Var.t * bool) option) * (Tiny.Scalar.t * Tiny.Scalar.t)) list
37
  end
38
  
39
let process env ast results =
40
  let module Results = (val results: Tiny.Analyze.Results) in
41
  let module Dom = Results.Dom in
42
  let module PrintResults = Tiny.PrintResults.Make (Dom) in
43
  let m = Results.results in
44
  
45
  let while_loc = Tiny.Ast.get_main_while_loc ast in
46
  let list = PrintResults.get_unrolled_info m while_loc in
47
  let join =
48
    match list with
49
    | [] -> Dom.bottom env
50
    | (_,hd)::tl -> List.fold_left (fun accu (_,e) -> Dom.join accu e) hd tl
51
  in
52
  let bounds = Dom.to_bounds join in
53
  let module M = struct
54
      module Results = Results
55
      module PrintResults = PrintResults
56
      let list = list
57
      let bounds = bounds
58
    end
59
  in
60
  (module M: S)
61
  (*                 
62
let build f_header f_content env ast results =
63
  let module Results = (val results: Tiny.Analyze.Results) in
64
  let module Dom = Results.Dom in
65
  let module PrintResults = Tiny.PrintResults.Make (Dom) in
66
  let m = Results.results in
67
  
68
  let while_loc = Tiny.Ast.get_main_while_loc ast in
69
  let list = PrintResults.get_unrolled_info m while_loc in
70
  let join =
71
    match list with
72
    | [] -> Dom.bottom env
73
    | (_,hd)::tl -> List.fold_left (fun accu (_,e) -> Dom.join accu e) hd tl
74
  in
75
  let bounds = Dom.to_bounds join in
76
  f_header bounds;
77
  f_content list
78
  *)
79

  
80
let pp_bounds fmt bounds =
81
  List.iter (fun ((v,ctx) as x, (min, max)) ->
82
      
83
      Format.fprintf fmt
84
        "%a in %a,%a@."
85
        pp_var x
86
        pp_bound min
87
        pp_bound max)
88
    bounds
89
  
90
let pp env ast results fmt =
91
  let m = process env ast results in
92
  let module M = (val m: S) in
93
  pp_bounds fmt  M.bounds;
94
  Format.fprintf fmt "Tube: %i@." (List.length M.list);
95
  List.iter (fun (idx, elem) ->
96
      Format.fprintf fmt "%i -> %a@." idx M.Results.Dom.fprint elem) M.list
97

  
98
let export env ast results fmt =
99
  let m = process env ast results in
100
  let module M = (val m: S) in
101
  List.iter (fun (x, (min, max)) ->
102
      Format.fprintf fmt
103
        "%a in %a,%a@."
104
        pp_var x
105
        pp_bound min
106
        pp_bound max)
107
    M.bounds;
108
  Format.fprintf fmt "Tube: %i@." (List.length M.list);
109
  List.iter (fun (idx, elem) ->
110
      Format.fprintf fmt
111
        "%i -> %a@."
112
        idx
113
        pp_bounds (M.Results.Dom.to_bounds elem)
114
    ) M.list
115

  
116
let export_to_wide_csv  env ast results fmt =
117
  let m = process env ast results in
118
  let module M = (val m: S) in
119
  let bounds = List.map (fun (idx, elem) -> idx, M.Results.Dom.to_bounds elem) M.list in
120
  (* Gather all variable ids *)
121
  let module VarIdSet = Set.Make (
122
                         struct
123
                           type t = Tiny.Ast.Var.t * (Tiny.Ast.Var.t * bool) option
124
                           let compare = compare
125
                         end)
126
  in
127
  let var_ids = List.fold_left (
128
                    fun accu (_, bounds) ->
129
                    List.fold_left (fun accu (vctx, _) -> VarIdSet.add vctx accu) accu bounds
130
                  ) VarIdSet.empty bounds
131
  in
132
  let ordered_list = VarIdSet.elements var_ids in
133
  Format.fprintf fmt "timestep,%a@."
134
    (Utils.fprintf_list ~sep:","
135
       (fun fmt ((n,_),ctx) ->
136
         let pp fmt =
137
           match ctx with
138
             None ->
139
              Format.fprintf fmt "%s" n
140
           | Some ((bn,_),b) ->
141
              Format.fprintf fmt "%s_//%s_eq_%b" n bn b
142
         in
143
         Format.fprintf fmt "%t_min,%t_max" pp pp
144
    ))
145
    ordered_list;
146
  Format.fprintf fmt "%a@."
147
    (Utils.fprintf_list ~sep:"@."
148
    (fun fmt (idx, bounds_idx) ->
149
      Format.fprintf fmt "@[<h 0>%i, %a@]"
150
        idx
151
        (Utils.fprintf_list ~sep:", "
152
           (fun fmt (min_, max_) ->
153
             let pp_bound fmt b = match b with
154
               | None -> Format.fprintf fmt ","
155
               | Some b -> Tiny.Scalar.pp fmt b
156
             in
157
             Format.fprintf fmt "%a, %a" pp_bound min_ pp_bound max_))
158
        (List.map (fun v -> if List.mem_assoc v bounds_idx then
159
                              let min_, max_ = List.assoc v bounds_idx in
160
                              Some min_, Some max_
161
                            else
162
                              None, None
163
           ) ordered_list)
164
    ))
165
    bounds;
166
  ()
167

  
168

  
169
let export_to_csv  env ast results fmt =
170
  let m = process env ast results in
171
  let module M = (val m: S) in
172
  let bounds = List.map (fun (idx, elem) ->
173
                   idx,
174
                   try M.Results.Dom.to_bounds elem with Tiny.Relational.BotEnv -> Format.eprintf "Issues exporting env %a to bounds: bottom!@." M.Results.Dom.fprint elem; assert false
175
                 ) M.list
176
  in
177
  (* Gather all variable ids *)
178
  let pp_vctx fmt ((n,t), ctx ) =
179
    match ctx with
180
    | None -> Format.fprintf fmt "%s,%a,," n (Tiny.Ast.pp_base_type) t
181
    | Some ((bname,_ (* type should be bool *) ), bval) ->
182
        Format.fprintf fmt "%s,%a,%s,%b" n (Tiny.Ast.pp_base_type) t bname bval
183
  in
184
  let pp_bound fmt (min_, max_) =
185
    Format.fprintf fmt "%a,%a" Tiny.Scalar.pp min_ Tiny.Scalar.pp max_
186
  in
187
  Format.fprintf fmt "timestep,varid,type,boolpart,boolval,min,max@.";
188
  Utils.fprintf_list ~sep:"@." (
189
      fun fmt (idx, idx_bounds) ->
190
      Utils.fprintf_list ~sep:"@." (fun fmt (vctx, vctx_bound) ->
191
          Format.fprintf fmt "%i,%a,%a" idx pp_vctx vctx pp_bound vctx_bound
192
        ) fmt idx_bounds
193
    ) fmt bounds
194

  
195
  
src/tools/tiny/tiny_utils.ml
26 26
    expr_type = Ast.BoolT }
27 27

  
28 28
let cst_num loc t q =
29
  let s = Q.to_string q in
30
  let s =  if t = Tiny.Ast.RealT && Z.equal (Q.den q) Z.one then s ^ "."
31
             else s in
29 32
{ Ast.expr_desc =
30
    Ast.Cst(q, Q.to_string q);
33
    Ast.Cst(q, s);
31 34
  expr_loc = loc;
32 35
  expr_type = t }
33 36
  
......
91 94
         | ">=", [v1;v2] ->
92 95
            Ast.Cond (build (Ast.Binop (Ast.Minus, v1, v2)) t_arg, Ast.Loose)
93 96
         | "uminus", [v1] -> Ast.Binop (Ast.Minus, cst_num loc t_arg Q.zero, v1)
94
         | "=", [v1;v2] -> Ast.Binop (Ast.Eq, v1, v2)
97
         (* | "=", [v1;v2] when v1.xxxtype != BoolT (\* if arguments are numerical then basic comparison *\)  
98
          *    Ast.Cond (build (Ast.Binop (Ast.Minus, v1, v2)) t_arg, Ast.Loose)
99
          *    Ast.Binop (Ast.Eq, v1, v2) *)
100
         | "=", [v1;v2] 
95 101
         | "equi", [v1;v2] -> Ast.Binop (Ast.Eq, v1, v2)
96 102
                            
97 103
         | "!=", [v1;v2] -> Ast.Unop (Ast.Not, build (Ast.Binop (Ast.Eq, v1, v2)) Ast.BoolT)
98 104
         | "not", [v1] -> Ast.Unop (Ast.Not, v1)
99 105
         | "&&", [v1;v2] -> Ast.Binop (Ast.And, v1, v2)
100 106
         | "||", [v1;v2] -> Ast.Binop (Ast.Or, v1, v2)
107
         | "impl", [v1;v2] ->
108
            let neg_v1 = Ast.neg_guard v1 in
109
            Ast.Binop (Ast.Or, neg_v1, v2)
101 110
                          
102 111
         | _ -> Format.eprintf "No tiny translation for operator %s@.@?" op; assert false    
103 112
       )
......
210 219
         )
211 220
         | name, _ -> 
212 221
            (
213
              Format.eprintf "No tiny translation for node call  %s@.@?" name;
222
              Format.eprintf "No tiny translation for stateful node call  %s@.@?" name;
214 223
              assert false
215 224
            )
216 225
       else (
217
         Format.eprintf "No tiny translation for node call  %s@.@?" id;
226
         Format.eprintf "No tiny translation for function call  %s@.@?" id;
218 227
         assert false
219 228
       )
220 229
    | MReset id
......
228 237
  let min, max =
229 238
    match bounds_opt with
230 239
      Some (min,max) -> min, max
231
    | None -> (Q.of_int (-1), "-1"), (Q.of_int 1, "1")
240
    | None ->
241
       let one, minus_one =
242
         match Types.is_real_type v.Lustre_types.var_type with
243
         | true -> "1.", "-1."
244
         | false -> "1", "-1"
245
                      
246
       in
247
       (Q.of_int (-1), minus_one), (Q.of_int 1, one)
232 248
  in
233 249
  let range = {
234 250
      Ast.expr_desc = Ast.Rand (min,max);
src/tools/tiny/tiny_verifier.ml
5 5
let descending = ref 1
6 6
let unrolling = ref 0
7 7
let output = ref false
8

  
8
let reachtube = ref false (* used to produce a list of set iterates *)
9 9
              
10 10
let quiet () = Tiny.Report.verbosity := 0
11 11
let report = Tiny_utils.report
......
55 55
  (* TODO: deal woth contracts, asserts, ... *)
56 56
  let bounds_inputs = [] in
57 57
  let ast = Tiny_utils.machine_to_ast bounds_inputs m in
58
  let mems = m.mmemory in
58
  (* let mems = m.mmemory in *)
59 59
  if !output then (
60 60
    let destname = !Options.dest_dir ^ "/" ^ basename ^ "_" ^ node_name ^ ".tiny" in
61 61
    report ~level:2 (fun fmt -> Format.fprintf fmt "Exporting resulting tiny source as %s@ " destname);
......
64 64
    Format.fprintf fmt "%a@." Tiny.Ast.Var.Set.pp env; 
65 65
    Format.fprintf fmt "%a@." Tiny.Ast.fprint_stm ast; 
66 66
    close_out out;
67
  
68
  
67
    
68
    
69 69
  );
70 70
  report ~level:1 (fun fmt -> Format.fprintf fmt "%a@." Tiny.Ast.fprint_stm ast); 
71 71
  
72 72
  let dom =
73
     let open Tiny.Load_domains in
74
     prepare_domains (List.map get_domain !domains)
75
   in
76
   let results = Tiny.Analyze.analyze dom !descending !unrolling env ast in
77
   let module Results = (val results: Tiny.Analyze.Results) in
78
   let module Dom = Results.Dom in
79
   let module PrintResults = Tiny.PrintResults.Make (Dom) in
80
   let m = Results.results in
81
   (* if !Tiny.Report.verbosity > 1 then *)
82
   report ~level:1 (PrintResults.print m env ast)
83
   (* no !output_file *);
84
        (* else PrintResults.print_invariants m ast !output_file *)
73
    let open Tiny.Load_domains in
74
    prepare_domains (List.map get_domain !domains)
75
  in
76
  let results = Tiny.Analyze.analyze
77
                  dom
78
                  (not !reachtube) (* when this argument is false, a
79
                                      simulation is performed*)
80
                  !descending
81
                  !unrolling
82
                  env
83
                  ast
84
  in
85
  (* if !Tiny.Report.verbosity > 1 then *)
86
  if !reachtube then (
87
    (* Print preamble *)
88
    report ~level:1 (Tiny_tube.export_to_csv env ast results);
89
    (* We produce in a folder: the csv file, the tiny file *)
90
    let destname = !Options.dest_dir ^ "/" ^ basename ^ "_" ^ node_name ^ ".csv" in
91
    report ~level:1 (fun fmt -> Format.fprintf fmt "Exporting resulting tube as %s@ " destname);
92
    let out = open_out destname in
93
    let fmt = Format.formatter_of_out_channel out in
94
    Format.fprintf fmt "%t@." (Tiny_tube.export_to_csv env ast results); 
95
    close_out out;
96
    
97
  )
98
  else
99
    let module Results = (val results: Tiny.Analyze.Results) in
100
    let module Dom = Results.Dom in
101
    let module PrintResults = Tiny.PrintResults.Make (Dom) in
102
    let m = Results.results in
103
    report ~level:1 (PrintResults.print m env ast)
104
    (* no !output_file *);
105
    (* else PrintResults.print_invariants m ast !output_file *)
85 106

  
86
   ()
107
    ()
87 108
  
88 109
  
89 110
module Verifier =
90 111
  (struct
91 112
    include VerifierType.Default
113

  
114
    (* Enforce global inline from top node *)
115
    let get_normalization_params () =
116
      Options.global_inline := true;
117
      get_normalization_params ()
118
      
92 119
    let name = "tiny"
93 120
    let options =
94 121
      [
......
128 155
         * is reached (default is 1)"); *)
129 156
      ("-unrolling", Arg.Set_int unrolling,
130 157
       "<n>  Unroll loops <n> times before computing fixpoint (default is 0)");
158
      ("-reachtube", Arg.Int (fun n -> unrolling :=n; reachtube:=true),
159
       "<n>  Unroll main loop <n> times to compute finite horizon analysis (default is invariant, with 0)");
131 160
      ("-output", Arg.Set output,
132 161
       "<n>  Export resulting tiny file as <name>_<mainnode>.tiny");
133 162
      (* (\* ("-u", Arg.Set_int unrolling,

Also available in: Unified diff