Project

General

Profile

Download (7.93 KB) Statistics
| Branch: | Tag: | Revision:
1
(* Rebuilding Cex *)
2
(* In order to properly rebuild the Cex, one needsthe unsliced model. Otherwise
3
   some input or state variables are removed.
4

    
5
*)
6

    
7

    
8
open Lustre_types
9
open Machine_code_types
10
(* open Machine_code_common *)
11
open Zustre_common
12

    
13
open Zustre_data
14

    
15
let get_conjuncts e =
16
  assert (Z3.Boolean.is_bool e);
17
  if Z3.Boolean.is_and e then
18
    Z3.Expr.get_args e
19
  else
20
    [e]
21

    
22
let build_cex machine machines decl_err =
23
  (* Recovering associated top machine (to build full traces) and property *) 
24
  (* TODO: for example extract top node and ok prop. We may have multiple
25
     MAIN/ERR loaded at the same time. Each of them should be assocaited with a
26
     CEX/Inv/Timeout.*)
27
  
28
  let node_id = machine.mname.node_id in
29

    
30
  let cex = match Z3.Fixedpoint.get_answer !fp with Some e -> e | None -> raise Not_found in
31
  (* Original code used the function Z3.Fixedpoint.get_ground_sat_answer !fp *)
32

    
33
  let stats = Z3.Fixedpoint.get_statistics !fp in
34
  
35
  let conjuncts = List.rev (get_conjuncts cex) in
36

    
37
  Format.eprintf "cex: %s@.%i conjuncts: @[<v 0>%a@]@."
38
    (Z3.Expr.to_string cex)
39
    (List.length conjuncts)
40
    (Utils.fprintf_list ~sep:"@ " (fun fmt e -> Format.fprintf fmt "%s" (Z3.Expr.to_string e))) conjuncts;
41

    
42
  (* Checking size *)
43
  let inputs = machine.mstep.step_inputs in
44
  let nb_inputs = List.length inputs in
45
  let outputs = machine.mstep.step_outputs in
46
  let nb_outputs = List.length inputs in
47
  let nb_mems = List.length (full_memory_vars machines machine) in
48
  
49
  let main, funs =
50
    List.fold_left (fun (main, funs) conj ->
51
    (* Filtering out non MAIN decls *)
52
    let func_decl = Z3.Expr.get_func_decl conj in
53
    let node_name = Z3.Symbol.get_string (Z3.FuncDecl.get_name func_decl) in
54
    (* Focusing only on MAIN_nodeid predicates *)
55
    if node_name = "MAIN_" ^ node_id then
56
      (* Extracting info *)
57
      (* Recall that MAIN args are in@mems@out *)
58
      let args = Z3.Expr.get_args conj in
59
      if List.length args = 1 + nb_inputs + nb_mems + nb_outputs then
60
        (* Should be done with get_int but that function vanished from the opam Z3 API *)
61
	let id = Big_int.int_of_big_int (Z3.Arithmetic.Integer.get_big_int (List.hd args)) in
62
	let input_values = Utils.List.extract args 1 (1 + nb_inputs) in
63
	let output_values = Utils.List.extract args (1+nb_inputs+nb_mems) (1 + nb_inputs + nb_mems + nb_outputs) in
64
	(id, (input_values, output_values))::main, funs
65
      else
66
	assert false
67
    else
68
      let reg = Str.regexp_string "[a-z]*_step" in
69
      if Str.string_match reg node_name 0 then (
70
	let actual_name = Str.matched_group 0 node_name in
71
	Format.eprintf "Name %s@." actual_name;
72
	main, funs
73
      )
74
      else (
75
	Format.eprintf "pas matché %s@." node_name;
76
	main, funs
77
      )
78
    ) ((* main*) [],(* other functions *) []) conjuncts
79
  in
80
  let main = List.sort (fun (id1, _) (id2, _) -> compare id1 id2) main in
81
  List.iter (
82
    fun (id, expr) ->
83
      Format.eprintf "Id %i: %a@."
84
	(id)
85
	(Utils.fprintf_list ~sep:", "
86
	   (fun fmt e -> Format.fprintf fmt "%s" (Z3.Expr.to_string e)))
87
	(fst expr)
88
  ) main;		    
89
   (* let ground_val = List.map (fun e -> Z3.Expr.to_string e) (Z3.Expr.get_args conj) in *)
90

    
91
   (* We recover the Zustre XML format, projecting each cex on each input/output
92
      signal *)
93
  let in_signals, out_signals =
94
    List.fold_right (
95
      fun (id, (sigs_in, sigs_out)) (res_sigs_in, res_sigs_out) ->
96
	let add l1 l2 = List.map2 (fun e1 e2 -> fst e2, ((id, e1)::(snd e2))) l1 l2 in
97
	let sigs_in_id = add sigs_in res_sigs_in in
98
	let sigs_out_id = add sigs_out res_sigs_out in
99
	sigs_in_id, sigs_out_id
100
    ) main (List.map (fun v -> v, []) inputs, List.map (fun v -> v, []) outputs)
101
  in
102

    
103
  (* let _ = List.mapi (fun k conj -> *)
104
  (*   (\* k-iterate *\) *)
105
  (*   let ground_val = List.map (fun e -> Z3.Expr.to_string e) (Z3.Expr.get_args conj) in *)
106
  (*   let func_decl = Z3.Expr.get_func_decl conj in *)
107
  (*   if !debug then Format.eprintf "FuncDecl %s@." (Z3.FuncDecl.to_string func_decl); *)
108
  (*   let node_name = Z3.Symbol.get_string (Z3.FuncDecl.get_name func_decl) in *)
109

    
110
   
111
  (*   if !debug then Format.eprintf "Node %s, args %a@." node_name  (Utils.fprintf_list ~sep:", " (Format.pp_print_string)) ground_val; *)
112
    
113
  (*   () *)
114
  (*   (\*  ground_pair = [] *)
115
  (*           try: *)
116
  (*               ground_vars = pred_dict[node_name] *)
117
  (*               ground_pair = zip(ground_vars,ground_val) *)
118
  (*               if "_reset" in node_name: *)
119
  (*                   # this condition is to remove the node nodename_reset added by lustrec *)
120
  (*                   continue *)
121
  (*                   # node = node_name.split("_reset")[0] *)
122
  (*                   # cex_dict.update({node:{k:ground_pair}}) *)
123
  (*               elif "_step" in node_name: *)
124
  (*                   node = node_name.split("_step")[0] *)
125
  (*                   try: *)
126
  (*                       # case in which we already have the node in dict *)
127
  (*                       d = cex_dict[node] *)
128
  (*                       max_key = max(k for k, v in d.iteritems() if v != 0) #get the maximum key value and add 1 *)
129
  (*                       d.update({(max_key+1):ground_pair}) *)
130
  (*                   except Exception as e: *)
131
  (*                       self._log.warning("Adding a new node cex " + str(e)) *)
132
  (*                       cex_dict.update({node:{k:ground_pair}}) *)
133
  (*               else: *)
134
  (*                   node = node_name *)
135
  (*                   try: *)
136
  (*                       d = cex_dict[node] *)
137
  (*                       max_key = max(k for k, v in d.iteritems() if v != 0) #get the maximum key value and add 1 *)
138
  (*                       d.update({(max_key+1):ground_pair}) *)
139
  (*                   except Exception as e: *)
140
  (*                       if node not in ["MAIN", "ERR"]: *)
141
  (*                           self._log.warning("Adding a new node cex " + str(e)) *)
142
  (*                           cex_dict.update({node:{k:ground_pair}}) *)
143
  (*           except Exception as e: *)
144
  (*               self._log.warning("Problem with getting a node name: " + str(e)) *)
145
  (*   *\) *)
146
  (* ) conjuncts in *)
147
  (*   let rules_expr = Z3.Fixedpoint.get_rules !fp in *)
148
  (*   if !debug then *)
149
  (*     Format.eprintf "@[<v 2>Registered rules:@ %a@ @]@." *)
150
  (* 	(Utils.fprintf_list ~sep:"@ " *)
151
  (*   	   (fun fmt e -> Format.pp_print_string fmt (Z3.Expr.to_string e)) ) *)
152
  (* 	rules_expr; *)
153
  (*   if !debug then *)
154
  (*     Format.eprintf "FP help: %s@." (Z3.Fixedpoint.get_help !fp); *)
155

    
156
  let stats_entries =   Z3.Statistics.get_entries stats in
157
  (* List.iter (fun e -> Format.eprintf "%s@.@?" *)
158
  (*   (Z3.Statistics.Entry.to_string e) *)
159
    
160
  (* ) stats_entries; *)
161
  let json : Yojson.json =
162
    `Assoc [
163
      "Results",
164
      `Assoc [
165
	"Property",
166
	`Assoc [
167
	  "name", `String node_id;
168
	  "date", `String (Utils.get_date ());
169
	  "query", `Assoc ["unit", `String "sec";
170
			   "value", `Float (
171
			     let time_opt = Z3.Statistics.get stats "time.spacer.solve" in
172
			     match time_opt with None -> -1.
173
			     | Some f -> Z3.Statistics.Entry.get_float f)
174
			  ];
175
	  "answer", `String "CEX";
176
	  "counterexample",
177
	  `Assoc [
178
	    node_id, `Assoc
179
	      (
180
		List.map (fun (vardecl, values) ->
181
		  vardecl.var_id,
182
		  `Assoc [
183
		    "type", (let _ = Format.fprintf Format.str_formatter "%a" Printers.pp_var_type vardecl in
184
			    let s = Format.flush_str_formatter () in
185
			    `String s);
186
		    "values", `Assoc (List.map (fun (id, v) ->
187
		      string_of_int id, `String (Z3.Expr.to_string v))
188
					values)
189
		  ]   
190
		) in_signals
191
	      )
192
	  ]
193
	]
194
      ]
195
     ]
196
  in
197
  Format.eprintf "JSON: %s@."
198
    (Yojson.to_string json);
199
  ()
200
  (* Results *)
201
  (*   Property *)
202
  (*   Date *)
203
  (*   Query time *)
204
  (*   Answer CEX *)
205
  (*   Counterexample *)
206
  (*     Node name="nodeid" *)
207
  (*       Stream name="opt.x" type="unk" *)
208
  (* 	  Value instant="0">xxx</Value>		       *)
209
  (* () *)
210
	(* ordered_by_signal = self.reorder(cex_dict) *)
211
        (* return self.mk_cex_xml(ordered_by_signal) *)
212

    
213
(* Local Variables: *)
214
(* compile-command:"make -C ../.. lustrev" *)
215
(* End: *)
216

    
217
	
(2-2/6)