Project

General

Profile

« Previous | Next » 

Revision a56f563e

Added by LĂ©lio Brun over 3 years ago

more compact assign clauses for state variables, and remove useless memory pack predicates and assertions

View differences:

src/backends/C/c_backend_spec.ml
89 89

  
90 90
let pp_var_decl fmt v = pp_print_string fmt v.var_id
91 91

  
92
let pp_reg self fmt field =
93
  pp_access pp_indirect' pp_var_decl fmt ((self, "_reg"), field)
94

  
95 92
let pp_true fmt () = pp_print_string fmt "\\true"
96 93

  
97 94
let pp_cast pp_ty pp fmt (ty, x) = fprintf fmt "(%a) %a" pp_ty ty pp x
......
117 114
let find_machine f = List.find (fun m -> m.mname.node_id = f)
118 115

  
119 116
let instances machines m =
120
  let open List in
121
  let grow paths i td mems =
122
    match paths with
123
    | [] ->
124
      [ [ i, (td, mems) ] ]
125
    | _ ->
126
      map (cons (i, (td, mems))) paths
127
  in
128
  let rec aux paths m =
129
    map
130
      (fun (i, (td, _)) ->
131
        try
132
          let m = find_machine (node_name td) machines in
133
          aux (grow paths i td m.mmemory) m
134
        with Not_found -> grow paths i td [])
135
      m.minstances
136
    |> flatten
117
  let rec aux m =
118
    List.(fold_left (fun insts (inst, (td, _)) ->
119
        let mems, insts' =
120
          try
121
            let m' = find_machine (node_name td) machines in
122
            m'.mmemory, aux m'
123
          with Not_found ->
124
            if Arrow.td_is_arrow td then arrow_machine.mmemory, [[]] else assert false
125
        in
126
        insts @ map (cons (inst, (td, mems))) insts') [[]] m.minstances)
137 127
  in
138
  aux [] m |> map rev
139

  
140
let memories insts =
141
  List.(
142
    map
143
      (fun path ->
144
        let _, (_, mems) = hd (rev path) in
145
        map (fun mem -> path, mem) mems)
146
      insts
147
    |> flatten)
148

  
149
let pp_instance ?(indirect = true) pp ptr =
150
  pp_print_list
151
    ~pp_prologue:(fun fmt () -> fprintf fmt "%a->" pp ptr)
152
    ~pp_sep:(fun fmt () -> pp_print_string fmt (if indirect then "->" else "."))
153
    (fun fmt (i, _) -> pp_print_string fmt i)
154

  
155
let pp_memory ?(indirect = true) ptr fmt (path, mem) =
156
  pp_access
157
    ((if indirect then pp_indirect else pp_access)
158
       (pp_instance ~indirect pp_print_string ptr)
159
       pp_print_string)
160
    pp_var_decl
161
    fmt
162
    ((path, "_reg"), mem)
128
  match aux m with
129
  | [] :: l -> l
130
  | l -> l
163 131

  
164
let prefixes l =
165
  let rec pref acc = function
166
    | x :: l ->
167
      pref ([ x ] :: List.map (List.cons x) acc) l
168
    | [] ->
169
      acc
170
  in
171
  pref [] (List.rev l)
132
let pp_instance ?(indirect = true) ?pp_epilogue fmt =
133
    pp_print_list
134
      ~pp_sep:(fun fmt () -> pp_print_string fmt (if indirect then "->" else "."))
135
      ?pp_epilogue
136
      (fun fmt (i, _) -> pp_print_string fmt i)
137
      fmt
172 138

  
173
let powerset_instances paths =
174
  List.map prefixes paths |> List.flatten |> remove_duplicates
139
let pp_reg ?(indirect = true) self fmt paths =
140
  fprintf fmt "%s->%a%s"
141
    self
142
    (pp_instance
143
       ~indirect
144
       ~pp_epilogue:(fun fmt () -> pp_print_string fmt (if indirect then "->" else ".")))
145
    paths
146
    "_reg"
175 147

  
176 148
let pp_separated pp_self pp_mem pp_ptr fmt (self, mem, paths, ptrs) =
177 149
  fprintf
......
181 153
    self
182 154
    pp_mem
183 155
    mem
184
    (pp_comma_list ~pp_prologue:pp_print_comma (pp_instance pp_self self))
156
    (pp_comma_list ~pp_prologue:pp_print_comma
157
       (fun fmt path -> pp_indirect pp_print_string pp_instance fmt (self, path)))
185 158
    paths
186 159
    (pp_comma_list ~pp_prologue:pp_print_comma pp_ptr)
187 160
    ptrs
......
707 680
         ~pp_epilogue:pp_print_cut
708 681
         ~pp_open_box:pp_open_vbox0
709 682
         (pp_memory_pack_def m))
710
      m.mspec.mmemory_packs
683
      (snd m.mspec.mmemory_packs)
711 684

  
712 685
let pp_transition_def m fmt t =
713 686
  let name = t.tname.node_id in
......
990 963
          (name, mem, self)
991 964
          (pp_ensures
992 965
             (pp_memory_pack_aux
993
                ~i:(List.length m.mspec.mmemory_packs - 2)
966
                ~i:(fst m.mspec.mmemory_packs)
994 967
                pp_ptr
995 968
                pp_print_string))
996 969
          (name, mem, self)
......
1493 1466
  let pp_step_spec fmt machines self mem m =
1494 1467
    let name = m.mname.node_id in
1495 1468
    let insts = instances machines m in
1496
    let insts' = powerset_instances insts in
1497
    let insts'' =
1498
      List.(
1499
        filter
1500
          (fun l -> l <> [])
1501
          (map (filter (fun (_, (td, _)) -> not (Arrow.td_is_arrow td))) insts))
1469
    let insts_no_arrow =
1470
      List.(filter
1471
              (fun path ->
1472
                 let _, (td, _) = hd (rev path) in
1473
                 not (Arrow.td_is_arrow td))
1474
              insts)
1475
    in
1476
    let stateful_insts =
1477
      List.(filter
1478
              (fun path ->
1479
                 let _, (_, mems) = hd (rev path) in
1480
                 mems <> [])
1481
              insts)
1502 1482
    in
1503 1483
    let inputs = m.mstep.step_inputs in
1504 1484
    let outputs = m.mstep.step_outputs in
......
1596 1576
             %a@,\
1597 1577
             %a@,\
1598 1578
             %a@,\
1599
             %a@,\
1600
             %a@,\
1601 1579
             %a"
1602 1580
            (pp_if_outputs (pp_requires (pp_valid pp_var_decl)))
1603 1581
            outputs
1604 1582
            (pp_requires pp_mem_valid')
1605 1583
            (name, self)
1606 1584
            (pp_requires (pp_separated' self mem))
1607
            (insts', outputs)
1585
            (insts, outputs)
1608 1586
            (pp_requires (pp_memory_pack_aux pp_ptr pp_print_string))
1609 1587
            (name, mem, self)
1610 1588
            (pp_ensures (pp_memory_pack_aux pp_ptr pp_print_string))
......
1617 1595
            c
1618 1596
            (pp_assigns pp_ptr_decl)
1619 1597
            outputs
1620
            (pp_assigns (pp_reg self))
1621
            m.mmemory
1598
            (if m.mmemory = [] then pp_print_nothing else pp_assigns (pp_reg self))
1599
            [[]]
1622 1600
            (pp_assigns pp_reset_flag')
1623 1601
            [ self ]
1624
            (pp_assigns (pp_memory self))
1625
            (memories insts')
1626
            (pp_assigns (pp_register_chain self))
1627
            insts
1602
            (pp_assigns (pp_reg self))
1603
            stateful_insts
1628 1604
            (pp_assigns (pp_reset_flag_chain self))
1629
            insts''
1630
            (pp_assigns (pp_reg mem))
1631
            m.mmemory
1605
            insts_no_arrow
1606
            (if m.mmemory = [] then pp_print_nothing else pp_assigns (pp_reg mem))
1607
            [[]]
1632 1608
            (pp_assigns pp_reset_flag')
1633 1609
            [ mem ]
1634
            (pp_assigns (pp_memory ~indirect:false mem))
1635
            (memories insts')
1636
            (pp_assigns (pp_register_chain ~indirect:false mem))
1637
            insts
1610
            (pp_assigns (pp_reg ~indirect:false mem))
1611
            stateful_insts
1638 1612
            (pp_assigns (pp_reset_flag_chain ~indirect:false mem))
1639
            insts'')
1613
            insts_no_arrow)
1640 1614
      fmt
1641 1615
      ()
1642 1616

  
......
1737 1711

  
1738 1712
  let pp_main_loop_invariants main_mem machines fmt m =
1739 1713
    let name = m.mname.node_id in
1740
    let insts = powerset_instances (instances machines m) in
1714
    let insts = instances machines m in
1741 1715
    pp_acsl_cut
1742 1716
      (fun fmt () ->
1743 1717
        fprintf
......
1937 1911
    mpformula = sanitize_formula mp.mpformula
1938 1912
  }
1939 1913

  
1940
let sanitize_memory_packs = List.map sanitize_memory_pack
1914
let sanitize_memory_packs (n, mps) = n, List.map sanitize_memory_pack mps
1941 1915

  
1942 1916
let sanitize_spec s =
1943 1917
  { s with
src/machine_code.ml
185 185
  (* Step instructions *)
186 186
  s : instr_t list;
187 187
  (* Memory pack spec *)
188
  mp : mc_formula_t list;
188
  mp : (int * mc_formula_t) list;
189 189
  (* Transition spec *)
190 190
  t :
191 191
    (var_decl list
......
247 247
  let outputs_pi = Lustre_live.inter_live_i_with id (i - 1) outputs in
248 248
  let locals_i = Lustre_live.inter_live_i_with id i locals in
249 249
  let outputs_i = Lustre_live.inter_live_i_with id i outputs in
250
  let pred_mp ctx a = And [ mk_memory_pack ~i:(i - 1) id; a ] :: ctx.mp in
250
  let pred_mp ctx a =
251
    let j = try fst (List.hd ctx.mp) with _ -> 0 in
252
    match a with
253
    | Some a -> (i, And [ mk_memory_pack ~i:j id; a ]) :: ctx.mp
254
    | None -> ctx.mp
255
  in
251 256
  let pred_t ctx a =
252 257
    ( inputs @ locals_i @ outputs_i,
253 258
      ctx.m,
......
273 278
        {
274 279
          inst with
275 280
          instr_spec =
276
            (if fst (get_stateless_status_node nd) then []
281
            (if fst (get_stateless_status_node nd) || spec_mp = None then []
277 282
            else [ mk_memory_pack ~i id ])
278 283
            @ [
279 284
                mk_transition
......
308 313
    let ctx =
309 314
      ctl
310 315
        (MStep ([ var_x ], inst, [ c1; c2 ]))
311
        (mk_memory_pack ~inst (node_name td))
316
        (Some (mk_memory_pack ~inst (node_name td)))
312 317
        (mk_transition ~inst false (node_name td) [ vdecl_to_val var_x ])
313 318
        { ctx with j = IMap.add inst (td, []) ctx.j }
314 319
    in
......
318 323
    let e = translate_expr e in
319 324
    ctl
320 325
      (MStateAssign (var_x, e))
321
      (mk_state_variable_pack var_x)
326
      (Some (mk_state_variable_pack var_x))
322 327
      (mk_state_assign_tr var_x e)
323 328
      { ctx with m = ISet.add x ctx.m }
324 329
  | [ x ], Expr_fby (e1, e2) when env.is_local x ->
......
327 332
    let ctx =
328 333
      ctl
329 334
        (MStateAssign (var_x, e2))
330
        (mk_state_variable_pack var_x)
335
        (Some (mk_state_variable_pack var_x))
331 336
        (mk_state_assign_tr var_x e2)
332 337
        { ctx with m = ISet.add x ctx.m }
333 338
    in
......
356 361
    let stateless = Stateless.check_node node_f in
357 362
    let inst = if stateless then None else Some i in
358 363
    let mp =
359
      if stateless then True else mk_memory_pack ?inst (node_name node_f)
364
      if stateless then None else Some (mk_memory_pack ?inst (node_name node_f))
360 365
    in
361 366
    let ctx =
362 367
      ctl
......
387 392
    try
388 393
      let var_x = env.get_var x in
389 394
      let instr, spec = translate_act (var_x, eq.eq_rhs) in
390
      control_on_clock eq.eq_rhs.expr_clock instr True spec ctx
395
      control_on_clock eq.eq_rhs.expr_clock instr None spec ctx
391 396
    with Not_found ->
392 397
      Format.eprintf "ERROR: node %s, eq %a@." id Printers.pp_node_eq eq;
393 398
      raise Not_found)
......
609 614
  (* Build the machine *)
610 615
  let mmap = IMap.bindings ctx.j in
611 616
  let mmemory_packs =
617
    let i = try fst (List.hd ctx.mp) with _ -> 0 in
618
    i,
612 619
    memory_pack_0 nd
613
    :: List.mapi
614
         (fun i f -> { mpname = nd; mpindex = Some (i + 1); mpformula = red f })
620
    :: List.map
621
         (fun (i, f) -> { mpname = nd; mpindex = Some i; mpformula = red f })
615 622
         (List.rev ctx.mp)
616
    @ [ memory_pack_toplevel nd (List.length ctx.mp) ]
623
    @ [ memory_pack_toplevel nd i ]
617 624
  in
618 625
  let mtransitions =
619 626
    transition_0 nd
src/machine_code_common.ml
344 344
      | Some (Contract spec) ->
345 345
        pp_mspec m fmt spec)
346 346
    (pp_memory_packs m)
347
    m.mspec.mmemory_packs
347
    (snd m.mspec.mmemory_packs)
348 348
    (pp_transitions m)
349 349
    m.mspec.mtransitions
350 350
    (pp_print_list Printers.pp_expr_annot)
......
449 449
          ];
450 450
        step_asserts = [];
451 451
      };
452
    mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = [] };
452
    mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = -1, [] };
453 453
    mannot = [];
454 454
    msch = None;
455 455
    mis_contract = false;
......
492 492
        step_instrs = [];
493 493
        step_asserts = [];
494 494
      };
495
    mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = [] };
495
    mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = -1, [] };
496 496
    mannot = [];
497 497
    msch = None;
498 498
    mis_contract = false;
src/machine_code_types.mli
66 66
type machine_spec = {
67 67
  mnode_spec : mc_contract_t node_spec_t option;
68 68
  mtransitions : mc_transition_t list;
69
  mmemory_packs : mc_memory_pack_t list;
69
  mmemory_packs : int * mc_memory_pack_t list;
70 70
}
71 71

  
72 72
type machine_t = {

Also available in: Unified diff