Skip to content

Commit ee7dbed

Browse files
committed
[looper] Remove guards
1 parent 9d989a8 commit ee7dbed

8 files changed

+32
-420
lines changed

infer/src/backend/Summary.ml

-4
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ module LooperSummary = struct
132132
; err_log }
133133

134134

135-
(* module SQLite = SqliteUtils.MarshalledDataNOTForComparison (struct
136-
type nonrec t = t
137-
end) *)
138-
139135
let merge ~into x = Errlog.merge ~into:into.err_log x.err_log
140136

141137
module SQLite = struct

infer/src/looper/DifferenceConstraint.ml

+10-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ let make ?(const_part = (Binop.PlusA None, IntLit.zero)) lhs_norm rhs_norm =
2727

2828
let make_value_rhs ?(const_part = (Binop.PlusA None, IntLit.zero)) rhs_norm =
2929
let op, rhs_const = const_part in
30-
match op with Binop.PlusA _ | Binop.Shiftrt -> (rhs_norm, op, rhs_const) | _ -> assert false
30+
match op with
31+
| Binop.PlusA _ ->
32+
let rhs_const =
33+
if IntLit.lt rhs_const IntLit.minus_one then IntLit.minus_one else rhs_const
34+
in
35+
(rhs_norm, op, rhs_const)
36+
| Binop.Shiftrt ->
37+
(rhs_norm, op, rhs_const)
38+
| _ ->
39+
assert false
3140

3241

3342
let rec is_constant (lhs_norm, rhs) =

infer/src/looper/DifferenceConstraintProgram.ml

+3-68
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,16 @@ module F = Format
66
module DC = DifferenceConstraint
77
module LTS = LabeledTransitionSystem
88

9-
(* Difference Constraint Program *)
10-
type edge_output_type = GuardedDCP | DCP [@@deriving compare]
11-
129
module EdgeData = struct
1310
type t =
1411
{ backedge: bool
1512
; branch_info: (Sil.if_kind * bool * Location.t) option
1613
; mutable calls: EdgeExp.CallPair.Set.t
1714
; mutable constraints: DC.t list
18-
; mutable guards: EdgeExp.Set.t
1915
; mutable condition_norms: EdgeExp.Set.t list
2016
; mutable bound: EdgeExp.T.t option
2117
; mutable bound_norms: EdgeExp.Set.t list
22-
; mutable computing_bound: bool
23-
; mutable edge_type: edge_output_type }
18+
; mutable computing_bound: bool }
2419
[@@deriving compare]
2520

2621
let equal = [%compare.equal: t]
@@ -30,12 +25,10 @@ module EdgeData = struct
3025
; branch_info= lts_edge_data.branch_info
3126
; calls= lts_edge_data.calls
3227
; constraints= []
33-
; guards= EdgeExp.Set.empty
3428
; condition_norms= lts_edge_data.condition_norms
3529
; bound= None
3630
; bound_norms= []
37-
; computing_bound= false
38-
; edge_type= DCP }
31+
; computing_bound= false }
3932

4033

4134
let get_dc key constraints =
@@ -77,63 +70,20 @@ module EdgeData = struct
7770

7871
let is_backedge edge = edge.backedge
7972

80-
let active_guards edge =
81-
let normal_guards =
82-
EdgeExp.Set.fold
83-
(fun guard acc ->
84-
match get_dc guard edge.constraints with
85-
| Some dc ->
86-
if DC.is_decreasing dc && DC.same_norms dc then acc else EdgeExp.Set.add guard acc
87-
| _ ->
88-
EdgeExp.Set.add guard acc )
89-
edge.guards EdgeExp.Set.empty
90-
in
91-
let guards_via_constant_reset =
92-
List.filter_map edge.constraints ~f:(fun (lhs_norm, rhs) ->
93-
let process_value (rhs_norm, op, const) =
94-
if EdgeExp.is_zero rhs_norm then
95-
match op with
96-
| (Binop.PlusA _ | Binop.PlusPI) when IntLit.gt const IntLit.zero ->
97-
true
98-
| _ ->
99-
false
100-
else
101-
match EdgeExp.evaluate_const_exp rhs_norm with
102-
| Some value ->
103-
let total_value = EdgeExp.eval_consts op value const in
104-
if IntLit.gt total_value IntLit.zero then true else false
105-
| None ->
106-
false
107-
in
108-
match rhs with
109-
| DC.Value v ->
110-
if process_value v then Some lhs_norm else None
111-
| DC.Pair (lb, ub) ->
112-
if process_value lb && process_value ub then Some lhs_norm else None )
113-
in
114-
EdgeExp.Set.union normal_guards (EdgeExp.Set.of_list guards_via_constant_reset)
115-
116-
11773
(* Required by Graph module interface *)
11874
let default =
11975
{ backedge= false
12076
; branch_info= None
121-
; edge_type= DCP
12277
; constraints= []
12378
; calls= EdgeExp.CallPair.Set.empty
124-
; guards= EdgeExp.Set.empty
12579
; condition_norms= []
12680
; bound= None
12781
; bound_norms= []
12882
; computing_bound= false }
12983

13084

131-
let set_edge_output_type edge output_type = edge.edge_type <- output_type
132-
13385
let branch_type edge = match edge.branch_info with Some (_, branch, _) -> branch | _ -> false
13486

135-
let add_guards edge guards = edge.guards <- guards
136-
13787
let add_constraint edge dc =
13888
(* debug_log "[DC derivation] Adding new DC: %a\n" DC.pp dc; *)
13989
edge.constraints <- edge.constraints @ [dc]
@@ -189,9 +139,7 @@ let edge_attributes : E.t -> 'a list =
189139
F.asprintf "%s : %a" (EdgeExp.call_to_string call) Location.pp loc
190140
| EdgeExp.CallPair.P (((_, _, _, loc1) as lb_call), ub_call) ->
191141
F.asprintf "[%s; %s] : %a" (EdgeExp.call_to_string lb_call)
192-
(EdgeExp.call_to_string ub_call) Location.pp loc1
193-
| _ ->
194-
assert false )
142+
(EdgeExp.call_to_string ub_call) Location.pp loc1 )
195143
in
196144
Some (String.concat ~sep:"\n" call_list)
197145
in
@@ -222,19 +170,6 @@ let edge_attributes : E.t -> 'a list =
222170
let label_parts =
223171
[edge_label edge_data; backedge_label; local_bounds_label; calls_str; condition_norms]
224172
in
225-
let label_parts =
226-
match edge_data.edge_type with
227-
| GuardedDCP ->
228-
let guards =
229-
Some
230-
( List.map (EdgeExp.Set.elements edge_data.guards) ~f:(fun guard ->
231-
F.asprintf "[GUARD] %s > 0" (EdgeExp.to_string guard) )
232-
|> String.concat ~sep:"\n" )
233-
in
234-
label_parts @ [guards]
235-
| DCP ->
236-
label_parts
237-
in
238173
let constraints =
239174
Some (List.map edge_data.constraints ~f:(fun dc -> DC.to_string dc) |> String.concat ~sep:"\n")
240175
in

infer/src/looper/DifferenceConstraintProgram.mli

+1-12
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@ module F = Format
55
module DC = DifferenceConstraint
66
module LTS = LabeledTransitionSystem
77

8-
(* Difference Constraint Program *)
9-
type edge_output_type = GuardedDCP | DCP [@@deriving compare]
10-
118
module EdgeData : sig
129
type t =
1310
{ backedge: bool
1411
; branch_info: (Sil.if_kind * bool * Location.t) option
1512
; mutable calls: EdgeExp.CallPair.Set.t
1613
; mutable constraints: DC.t list
17-
; mutable guards: EdgeExp.Set.t
1814
; mutable condition_norms: EdgeExp.Set.t list
1915
; mutable bound: EdgeExp.T.t option
2016
; mutable bound_norms: EdgeExp.Set.t list
21-
; mutable computing_bound: bool
22-
; mutable edge_type: edge_output_type }
17+
; mutable computing_bound: bool }
2318
[@@deriving compare]
2419

2520
val equal : t -> t -> bool
@@ -32,17 +27,11 @@ module EdgeData : sig
3227

3328
val is_backedge : t -> bool
3429

35-
val active_guards : t -> EdgeExp.Set.t
36-
3730
(* Required by Graph module interface *)
3831
val default : t
3932

40-
val set_edge_output_type : t -> edge_output_type -> unit
41-
4233
val branch_type : t -> bool
4334

44-
val add_guards : t -> EdgeExp.Set.t -> unit
45-
4635
val add_constraint : t -> DC.t -> unit
4736
end
4837

infer/src/looper/GraphConstructor.ml

+10-11
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,9 @@ let exec_instr :
382382
(fun ptr_arg (lb, ub) acc ->
383383
debug_log "Side-effect: %a ---> [%a, %a]@," EdgeExp.pp ptr_arg EdgeExp.pp lb
384384
EdgeExp.pp ub ;
385-
let arg_access = HilExp.AccessExpression.dereference_2 (extract_access ptr_arg) in
385+
let arg_access =
386+
HilExp.AccessExpression.dereference_2 (extract_access ptr_arg)
387+
in
386388
let output_bound = EdgeExp.ValuePair.P (lb, ub) in
387389
LTS.EdgeData.add_assignment acc arg_access output_bound )
388390
call_model.side_effects graph_data.edge_data
@@ -1057,16 +1059,13 @@ let process_split_node node successors predecessors (graph_data, proc_data) =
10571059
let prev_is_loop_head = Procdesc.is_loop_head graph_data.proc_desc prev_node in
10581060
let current_is_loop_head = Procdesc.is_loop_head graph_data.proc_desc node in
10591061
let node_map, loop_heads =
1060-
if prev_is_loop_head then (
1062+
if prev_is_loop_head then
10611063
let node_map = Procdesc.NodeMap.add prev_node prune_node graph_data.node_map in
1062-
node_map, graph_data.loop_heads
1063-
) else if current_is_loop_head then (
1064+
(node_map, graph_data.loop_heads)
1065+
else if current_is_loop_head then
10641066
let loop_heads = prune_node :: graph_data.loop_heads in
1065-
Procdesc.NodeMap.add node prune_node graph_data.node_map, loop_heads
1066-
) else (
1067-
Procdesc.NodeMap.add node prune_node graph_data.node_map,
1068-
graph_data.loop_heads
1069-
)
1067+
(Procdesc.NodeMap.add node prune_node graph_data.node_map, loop_heads)
1068+
else (Procdesc.NodeMap.add node prune_node graph_data.node_map, graph_data.loop_heads)
10701069
in
10711070
let graph_data =
10721071
{ graph_data with
@@ -1357,7 +1356,7 @@ let construct : LooperSummary.t InterproceduralAnalysis.t -> procedure_data =
13571356
let nodes = LTS.NodeSet.remove node const_nodes in
13581357
let backedge_in_edges, in_edges =
13591358
List.partition_tf (LTS.pred_e proc_data.lts node)
1360-
~f:(fun (_, (edge_data : LTS.EdgeData.t), _) -> edge_data.backedge)
1359+
~f:(fun (_, (edge_data : LTS.EdgeData.t), _) -> edge_data.backedge )
13611360
in
13621361
let shared_const_assignments =
13631362
List.map in_edges ~f:(fun ((_, edge_data, _) as edge) ->
@@ -1470,7 +1469,7 @@ let construct : LooperSummary.t InterproceduralAnalysis.t -> procedure_data =
14701469
let rec cut_branch access_edge node =
14711470
let _, in_edges =
14721471
List.partition_tf (LTS.pred_e proc_data.lts node)
1473-
~f:(fun (_, (edge_data : LTS.EdgeData.t), _) -> edge_data.backedge)
1472+
~f:(fun (_, (edge_data : LTS.EdgeData.t), _) -> edge_data.backedge )
14741473
in
14751474
LTS.remove_edge_e proc_data.lts access_edge ;
14761475
if Int.equal (List.length in_edges) 1 then (

infer/src/looper/LabeledTransitionSystem.ml

-90
Original file line numberDiff line numberDiff line change
@@ -171,78 +171,7 @@ module EdgeData = struct
171171
EdgeExp.ValuePair.V (EdgeExp.T.Access lhs_access)
172172

173173

174-
let derive_guards edge why3_norms tenv (prover_data : Provers.prover_data) =
175-
let selected_theory = prover_data.real_data in
176-
let or_terms =
177-
List.fold edge.conditions ~init:[] ~f:(fun or_terms and_terms ->
178-
let condition_set =
179-
EdgeExp.Set.fold
180-
(fun cond acc ->
181-
match cond with
182-
| EdgeExp.T.BinOp (_, EdgeExp.T.Const _, EdgeExp.T.Const _) ->
183-
acc
184-
| EdgeExp.T.UnOp _ | EdgeExp.T.BinOp _ -> (
185-
try
186-
debug_log "Transforming: %a@," EdgeExp.pp cond ;
187-
let cond_why3, type_conditions =
188-
EdgeExp.to_why3_expr cond tenv ~selected_theory prover_data
189-
in
190-
Why3.Term.Sterm.add cond_why3 (Why3.Term.Sterm.union type_conditions acc)
191-
with error ->
192-
debug_log
193-
"Failed to transform condition '%a' to Why3 expression, skipping: %a@,"
194-
EdgeExp.pp cond Exn.pp error ;
195-
acc )
196-
| _ ->
197-
L.(die InternalError)
198-
"[Guards] Condition of form '%a' is not supported" EdgeExp.pp cond )
199-
and_terms Why3.Term.Sterm.empty
200-
in
201-
if Why3.Term.Sterm.is_empty condition_set then or_terms
202-
else (Why3.Term.Sterm.elements condition_set |> Why3.Term.t_and_l) :: or_terms )
203-
in
204-
if List.is_empty or_terms then EdgeExp.Set.empty
205-
else
206-
let lhs = Why3.Term.t_or_l or_terms in
207-
let gt = selected_theory.get_op ">" in
208-
let zero_const = selected_theory.mk_const (Why3.BigInt.of_int 0) in
209-
let goal_symbol = Why3.Decl.create_prsymbol (Why3.Ident.id_fresh "is_guard") in
210-
let lhs_vars = Why3.Term.Mvs.keys (Why3.Term.t_vars lhs) in
211-
let is_norm_guard why3_norm =
212-
let rhs = Why3.Term.t_app_infer gt [why3_norm; zero_const] in
213-
let formula = Why3.Term.t_implies lhs rhs in
214-
let rhs_vars = Why3.Term.Mvs.keys (Why3.Term.t_vars rhs) in
215-
let free_vars = lhs_vars @ rhs_vars in
216-
let quantified_fmla = Why3.Term.t_forall_close free_vars [] formula in
217-
let task = Why3.Task.use_export None selected_theory.theory in
218-
let task = Why3.Task.add_prop_decl task Why3.Decl.Pgoal goal_symbol quantified_fmla in
219-
let prover_call =
220-
Why3.Driver.prove_task prover_data.driver task ~config:prover_data.main
221-
~command:prover_data.prover_conf.command
222-
~limit:{Why3.Call_provers.empty_limit with limit_time= 5.}
223-
in
224-
let result = Why3.Call_provers.wait_on_call prover_call in
225-
match result.pr_answer with
226-
| Why3.Call_provers.Valid ->
227-
(* Implication [conditions] => [norm > 0] always holds *)
228-
true
229-
| Why3.Call_provers.Invalid | Why3.Call_provers.Unknown _ ->
230-
false
231-
| _ ->
232-
debug_log "Failed task: %a\n" Why3.Pretty.print_task task ;
233-
debug_log "Fail: %s\n" result.pr_output ;
234-
assert false
235-
in
236-
let guards =
237-
List.fold why3_norms ~init:EdgeExp.Set.empty ~f:(fun guard_acc (norm, why3_norm) ->
238-
if is_norm_guard why3_norm then EdgeExp.Set.add norm guard_acc else guard_acc )
239-
in
240-
guards
241-
242-
243174
let derive_constraint edge_data (norm, used_assignments) formals tenv proc_name =
244-
(* List.iter edge_data.assignments ~f:(fun (lhs, rhs) ->
245-
debug_log "Assignment: %a = %a@," HilExp.AccessExpression.pp lhs EdgeExp.ValuePair.pp rhs ) ; *)
246175
let get_assignment lhs_access =
247176
debug_log "get_assignment: %a@," HilExp.AccessExpression.pp lhs_access ;
248177
let lhs_access_stripped =
@@ -333,25 +262,6 @@ module EdgeData = struct
333262
else EdgeExp.AssignmentSet.empty
334263
in
335264
(accesses, Some rhs)
336-
(* if
337-
(not (EdgeExp.equal norm rhs_exp))
338-
&& AccessExpressionSet.mem access used_assignments
339-
then (
340-
(* debug_log "############ FAIL ###########@,"; *)
341-
(* L.die InternalError "[%a] Edge '%a = %a' assignment previously used " Procname.pp
342-
proc_name HilExp.AccessExpression.pp access EdgeExp.pp rhs *)
343-
L.user_warning
344-
"[%a] Edge '%a = %a' assignment previously used, skipping substitution...@."
345-
Procname.pp proc_name HilExp.AccessExpression.pp access EdgeExp.pp rhs ;
346-
debug_log "Returning rhs: %a@," EdgeExp.pp norm ;
347-
(AccessExpressionSet.empty, Some norm) )
348-
else
349-
let accesses =
350-
if (not (EdgeExp.equal norm rhs)) && not (EdgeExp.is_zero rhs) then
351-
AccessExpressionSet.singleton access
352-
else AccessExpressionSet.empty
353-
in
354-
(accesses, Some rhs) *)
355265
in
356266
match rhs with
357267
| EdgeExp.ValuePair.P (lower_bound, upper_bound) -> (

infer/src/looper/LabeledTransitionSystem.mli

-3
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ module EdgeData : sig
6666

6767
val get_assignment_rhs : t -> HilExp.access_expression -> EdgeExp.ValuePair.t
6868

69-
val derive_guards :
70-
t -> (EdgeExp.T.t * Why3.Term.term) list -> Tenv.t -> Provers.prover_data -> EdgeExp.Set.t
71-
7269
(* Derive difference constraint "x <= y + c" based on edge assignments *)
7370
val derive_constraint :
7471
t

0 commit comments

Comments
 (0)