Project

General

Profile

« Previous | Next » 

Revision 1b57e111

Added by Teme Kahsai almost 8 years ago

adding sfunction support

View differences:

src/backends/Horn/horn_backend_printers.ml
79 79
*)
80 80
let pp_assign m pp_var fmt var_name value =
81 81
  let self = m.mname.node_id in
82
  fprintf fmt "(= %a %a)" 
82
  fprintf fmt "(= %a %a)"
83 83
    (pp_horn_val ~is_lhs:true self pp_var) var_name
84 84
    (pp_value_suffix self pp_var) value
85
    
85

  
86 86

  
87 87
(* In case of no reset call, we define mid_mem = current_mem *)
88 88
let pp_no_reset machines m fmt i =
89 89
  let (n,_) = List.assoc i m.minstances in
90 90
  let target_machine = List.find (fun m  -> m.mname.node_id = (node_name n)) machines in
91 91

  
92
  let m_list = 
92
  let m_list =
93 93
    rename_machine_list
94 94
      (concat m.mname.node_id i)
95 95
      (rename_mid_list (full_memory_vars machines target_machine))
......
104 104
    fprintf fmt "(= %a %a)"
105 105
      (pp_horn_var m) mhd
106 106
      (pp_horn_var m) chd
107
  
107

  
108 108
  | _ -> (
109 109
    fprintf fmt "@[<v 0>(and @[<v 0>";
110
    List.iter2 (fun mhd chd -> 
110
    List.iter2 (fun mhd chd ->
111 111
      fprintf fmt "(= %a %a)@ "
112 112
      (pp_horn_var m) mhd
113 113
      (pp_horn_var m) chd
......
120 120
let pp_instance_reset machines m fmt i =
121 121
  let (n,_) = List.assoc i m.minstances in
122 122
  let target_machine = List.find (fun m  -> m.mname.node_id = (node_name n)) machines in
123
  
123

  
124 124
  fprintf fmt "(%a @[<v 0>%a)@]"
125 125
    pp_machine_reset_name (node_name n)
126
    (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) 
126
    (Utils.fprintf_list ~sep:"@ " (pp_horn_var m))
127 127
    (
128 128
      (rename_machine_list
129 129
	 (concat m.mname.node_id i)
130 130
	 (rename_current_list (full_memory_vars machines target_machine))
131
      ) 
131
      )
132 132
      @
133 133
	(rename_machine_list
134 134
	   (concat m.mname.node_id i)
......
146 146
      if not (List.mem i reset_instances) then
147 147
	(* If not, declare mem_m = mem_c *)
148 148
	pp_no_reset machines m fmt i;
149
      
149

  
150 150
      let mems = full_memory_vars machines target_machine in
151 151
      let rename_mems f = rename_machine_list (concat m.mname.node_id i) (f mems) in
152 152
      let mid_mems = rename_mems rename_mid_list in
......
157 157
	fprintf fmt "@[<v 5>(and ";
158 158
	fprintf fmt "(= %a (ite %a %a %a))"
159 159
	  (pp_horn_val ~is_lhs:true self (pp_horn_var m)) (mk_val (LocalVar o) o.var_type) (* output var *)
160
	  (pp_horn_var m) mem_m 
160
	  (pp_horn_var m) mem_m
161 161
	  (pp_horn_val self (pp_horn_var m)) i1
162 162
	  (pp_horn_val self (pp_horn_var m)) i2
163 163
	;
......
175 175
	  (List.map (fun v -> mk_val (LocalVar v) v.var_type) outputs)
176 176
	  (Utils.pp_final_char_if_non_empty "@ " outputs)
177 177
	  (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) (mid_mems@next_mems)
178
	
178

  
179 179
      end
180 180
    end
181 181
  with Not_found -> ( (* stateless node instance *)
......
188 188
      (Utils.fprintf_list ~sep:"@ " (pp_horn_val self (pp_horn_var m)))
189 189
      (List.map (fun v -> mk_val (LocalVar v) v.var_type) outputs)
190 190
  )
191
    
192
    
191

  
192

  
193 193
(* Print the instruction and update the set of reset instances *)
194 194
let rec pp_machine_instr machines reset_instances (m: machine_t) fmt instr : ident list =
195 195
  match instr with
......
230 230
       statement. *)
231 231
    let self = m.mname.node_id in
232 232
    let pp_branch fmt (tag, instrs) =
233
      fprintf fmt 
234
	"@[<v 3>(or (not (= %a %s))@ " 
233
      fprintf fmt
234
	"@[<v 3>(or (not (= %a %s))@ "
235 235
	(*"@[<v 3>(=> (= %a %s)@ "*)  (* Issues with some versions of Z3. It
236 236
					  seems that => within Horn predicate
237 237
					  may cause trouble. I have hard time
......
244 244
      () (* rs *)
245 245
    in
246 246
    pp_conj pp_branch fmt hl;
247
    reset_instances 
247
    reset_instances
248 248

  
249
and pp_machine_instrs machines reset_instances m fmt instrs = 
249
and pp_machine_instrs machines reset_instances m fmt instrs =
250 250
  let ppi rs fmt i = pp_machine_instr machines rs m fmt i in
251 251
  match instrs with
252
  | [x] -> ppi reset_instances fmt x 
252
  | [x] -> ppi reset_instances fmt x
253 253
  | _::_ ->
254 254
    fprintf fmt "(and @[<v 0>";
255
    let rs = List.fold_left (fun rs i -> 
255
    let rs = List.fold_left (fun rs i ->
256 256
      let rs = ppi rs fmt i in
257 257
      fprintf fmt "@ ";
258 258
      rs
259 259
    )
260
      reset_instances instrs 
260
      reset_instances instrs
261 261
    in
262 262
    fprintf fmt "@])";
263 263
    rs
......
269 269
  fprintf fmt "@[<v 5>(and @ ";
270 270

  
271 271
  (* print "x_m = x_c" for each local memory *)
272
  (Utils.fprintf_list ~sep:"@ " (fun fmt v -> 
272
  (Utils.fprintf_list ~sep:"@ " (fun fmt v ->
273 273
    fprintf fmt "(= %a %a)"
274 274
      (pp_horn_var m) (rename_mid v)
275 275
      (pp_horn_var m) (rename_current v)
......
281 281
  *)
282 282
  (Utils.fprintf_list ~sep:"@ " (fun fmt (id, (n, _)) ->
283 283
    let name = node_name n in
284
    if name = "_arrow" then ( 
284
    if name = "_arrow" then (
285 285
      fprintf fmt "(= %s._arrow._first_m true)"
286
	(concat m.mname.node_id id)  
286
	(concat m.mname.node_id id)
287 287
    ) else (
288
      let machine_n = get_machine machines name in 
289
      fprintf fmt "(%s_reset @[<hov 0>%a@])" 
288
      let machine_n = get_machine machines name in
289
      fprintf fmt "(%s_reset @[<hov 0>%a@])"
290 290
	name
291
	(Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) 
291
	(Utils.fprintf_list ~sep:"@ " (pp_horn_var m))
292 292
	(rename_machine_list (concat m.mname.node_id id) (reset_vars machines machine_n))
293 293
    )
294 294
   )) fmt m.minstances;
......
314 314
  else
315 315
    begin
316 316
      fprintf fmt "; %s@." m.mname.node_id;
317
      
317

  
318 318
      (* Printing variables *)
319 319
      Utils.fprintf_list ~sep:"@." pp_decl_var fmt
320 320
	(
......
358 358

  
359 359
	  (* Rule for reset *)
360 360
	  fprintf fmt "@[<v 2>(rule (=> @ %a@ (%a @[<v 0>%a)@]@]@.))@.@."
361
	    (pp_machine_reset machines) m 
361
	    (pp_machine_reset machines) m
362 362
	    pp_machine_reset_name m.mname.node_id
363 363
	    (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) (reset_vars machines m);
364 364

  
......
373 373
		pp_machine_step_name m.mname.node_id
374 374
		(Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) (step_vars machines m);
375 375
	    end
376
	  | assertsl -> 
376
	  | assertsl ->
377 377
	    begin
378 378
	      let pp_val = pp_horn_val ~is_lhs:true m.mname.node_id (pp_horn_var m) in
379 379
	      (* print_string pp_val; *)
380 380
	      fprintf fmt "; with Assertions @.";
381
	      
381

  
382 382
	      (*Rule for step*)
383 383
	      fprintf fmt "@[<v 2>(rule (=> @ (and @ ";
384 384
	      ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs);
......
386 386
		pp_machine_step_name m.mname.node_id
387 387
		(Utils.fprintf_list ~sep:" " (pp_horn_var m)) (step_vars machines m);
388 388
	    end
389
	      
390
	      
389

  
390

  
391 391
	end
392 392
    end
393 393

  
394 394

  
395
let mk_flags arity =
396
 let b_range =
397
   let rec range i j =
398
     if i > arity then [] else i :: (range (i+1) j) in
399
   range 2 arity;
400
 in
401
 List.fold_left (fun acc x -> acc ^ " false") "true" b_range
402

  
403

  
404
  (*Get sfunction infos from command line*)
405
let get_sf_info() =
406
  let splitted = Str.split (Str.regexp "@") !Options.sfunction in
407
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. sfunction name: %s@," !Options.sfunction);
408
  let sf_name, flags, arity = match splitted with
409
      [h;flg;par] -> h, flg, par
410
    | _ -> failwith "Wrong Sfunction info"
411

  
412
  in
413
  Log.report ~level:1 (fun fmt -> fprintf fmt "... sf_name: %s@, .. flags: %s@ .. arity: %s@," sf_name flags arity);
414
  sf_name, flags, arity
415

  
416

  
417
    (*a function to print the rules in case we have an s-function*)
418
  let print_sfunction machines fmt m =
419
      if m.mname.node_id = arrow_id then
420
        (* We don't print arrow function *)
421
        ()
422
      else
423
        begin
424
          Format.fprintf fmt "; SFUNCTION@.";
425
          Format.fprintf fmt "; %s@." m.mname.node_id;
426
          Format.fprintf fmt "; EndPoint Predicate %s." !Options.sfunction;
427

  
428
          (* Check if there is annotation for s-function *)
429
          if m.mannot != [] then(
430
              Format.fprintf fmt "; @[%a@]@]@\n" (Utils.fprintf_list ~sep:"@ " Printers.pp_s_function) m.mannot;
431
            );
432

  
433
       (* Printing variables *)
434
          Utils.fprintf_list ~sep:"@." pp_decl_var fmt
435
                             ((step_vars machines m)@
436
    	                        (rename_machine_list m.mname.node_id m.mstep.step_locals));
437
          Format.pp_print_newline fmt ();
438
          let sf_name, flags, arity = get_sf_info() in
439

  
440
       if is_stateless m then
441
         begin
442
           (* Declaring single predicate *)
443
           Format.fprintf fmt "(declare-rel %a (%a))@."
444
    	                  pp_machine_stateless_name m.mname.node_id
445
    	                  (Utils.fprintf_list ~sep:" " pp_type)
446
    	                  (List.map (fun v -> v.var_type) (reset_vars machines m));
447
           Format.pp_print_newline fmt ();
448
           (* Rule for single predicate *)
449
           let str_flags = sf_name ^ " " ^ mk_flags (int_of_string flags) in
450
           Format.fprintf fmt "@[<v 2>(rule (=> @ (%s %a) (%a %a)@]@.))@.@."
451
                          str_flags
452
                          (Utils.fprintf_list ~sep:" " (pp_horn_var m)) (reset_vars machines m)
453
	                  pp_machine_stateless_name m.mname.node_id
454
	                  (Utils.fprintf_list ~sep:" " (pp_horn_var m)) (reset_vars machines m);
455
         end
456
      else
457
         begin
458
           (* Declaring predicate *)
459
           Format.fprintf fmt "(declare-rel %a (%a))@."
460
    	                  pp_machine_reset_name m.mname.node_id
461
    	                  (Utils.fprintf_list ~sep:" " pp_type)
462
    	                  (List.map (fun v -> v.var_type) (inout_vars machines m));
463

  
464
           Format.fprintf fmt "(declare-rel %a (%a))@."
465
    	                  pp_machine_step_name m.mname.node_id
466
    	                  (Utils.fprintf_list ~sep:" " pp_type)
467
    	                  (List.map (fun v -> v.var_type) (step_vars machines m));
468

  
469
           Format.pp_print_newline fmt ();
470
          (* Adding assertions *)
471
           match m.mstep.step_asserts with
472
	  | [] ->
473
	    begin
474

  
475
	      (* Rule for step*)
476
	      fprintf fmt "@[<v 2>(rule (=> @ ";
477
	      ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs);
478
	      fprintf fmt "@ (%a @[<v 0>%a)@]@]@.))@.@."
479
		pp_machine_step_name m.mname.node_id
480
		(Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) (step_vars machines m);
481
	    end
482
	  | assertsl ->
483
	    begin
484
	      let pp_val = pp_horn_val ~is_lhs:true m.mname.node_id (pp_horn_var m) in
485
	      (* print_string pp_val; *)
486
	      fprintf fmt "; with Assertions @.";
487

  
488
	      (*Rule for step*)
489
	      fprintf fmt "@[<v 2>(rule (=> @ (and @ ";
490
	      ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs);
491
	      fprintf fmt "@. %a)(%a @[<v 0>%a)@]@]@.))@.@." (pp_conj pp_val) assertsl
492
		pp_machine_step_name m.mname.node_id
493
		(Utils.fprintf_list ~sep:" " (pp_horn_var m)) (step_vars machines m);
494
	    end
495

  
496
         end
497

  
498
        end
395 499
(* Local Variables: *)
396 500
(* compile-command:"make -C ../../.." *)
397 501
(* End: *)

Also available in: Unified diff