-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ml
137 lines (116 loc) · 4.52 KB
/
main.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
open Value_domain
open Constant
open Interval
open Domain
(*
Cours "Sémantique et Application à la Vérification de programmes"
Antoine Miné 2015
Ecole normale supérieure, Paris, France / CNRS / INRIA
*)
module Constant = DomainOfValueDomain.Make(ConstantValueDomain)
module Interval = DomainOfValueDomain.Make(IntervalValueDomain)
module Octagon = ApronDomain.Make(ApronDomain.OctagonManager)
module Polyhedra = ApronDomain.Make(ApronDomain.PolyhedralManager)
let doit domain backward_analysis false_alarms
print_graph pr_invariants skip_assert max_decreasing_iteration filename =
let module Dom = (val domain : DOMAIN) in
let module Iterator = Forward.Make(Dom) in
let module BackwardIterator = Backward.Make(Dom) in
let print_failing_trace oc (src_inv, tr) =
(* Printf.fprintf oc "Entering program with values :\n" ;
Dom.print oc src_inv ; *)
Printf.printf "Trace :\n" ;
List.iter (fun a ->
let open Backward in
let open Cfg in
Printf.fprintf oc " %i -> %i: %a\n"
a.arc_src.node_id a.arc_dst.node_id Cfg_printer.print_inst a.arc_inst ;
) tr ;
Printf.printf " Assertion failing point.\n\n"
in
let print_invariants =
let open Cfg in
NodeMap.iter (fun node dval ->
Printf.printf "\nNode %d (%s, l%d) : \n"
node.node_id
node.node_pos.Lexing.pos_fname
node.node_pos.Lexing.pos_lnum ;
Dom.print stdout dval)
in
let prog = File_parser.parse_file filename in
let cfg = Tree_to_cfg.prog prog in
let cfg = SCfg.of_cfg cfg in
let (invariants, failed_assertions) = Iterator.iterate cfg skip_assert in
if backward_analysis
then
List.iter (fun fa ->
let (invariants, tr) = BackwardIterator.iterate cfg invariants fa in
match tr with
| Some ft ->
begin
Printf.printf "Assertion on %a failed on foward analysis.\n"
Cfg_printer.print_bool_expr (snd fa) ;
Printf.printf "Searching a trace of failure... found a failing trace!\n" ;
print_failing_trace stdout ft
end
| None when false_alarms ->
begin
Printf.printf "Assertion on %a failed on foward analysis.\n"
Cfg_printer.print_bool_expr (snd fa) ;
Printf.printf "Searching a trace of failure... false alarm.\n"
end
| None -> ()
) failed_assertions
else
List.iter (fun (x, expr) ->
Printf.printf "Assertion %a failed.\n"
Cfg_printer.print_bool_expr expr
) failed_assertions ;
if print_graph
then Printf.printf "%a\n" Cfg_printer.print_cfg cfg;
if pr_invariants
then print_invariants invariants
let domains =
[ "constant" , (module Constant : DOMAIN) ;
"interval" , (module Interval : DOMAIN) ;
"octagon" , (module Octagon : DOMAIN) ;
"polyhedra" , (module Polyhedra : DOMAIN) ]
let domains_name = List.split domains |> fst
let set_domain dom s = dom := List.assoc s domains
(* parses arguments to get filename *)
let main () =
let domain = ref (module Interval : DOMAIN) in
let backward_analysis = ref true in
let false_alarms = ref true in
let invariants = ref false in
let graph = ref false in
let skip_assert = ref false in
let max_decreasing_iterations = ref 3 in
let filename = ref None in
let spec =
let open Arg in
[ "-domain", Symbol (domains_name, set_domain domain), " Abstract domain" ;
"-backward-analysis" , Set backward_analysis, " Perform backward analysis" ;
"-no-backward-analysis", Clear backward_analysis,
" Don't perform backward analysis" ;
"-false-alarms" , Set false_alarms, " Print false alarms" ;
"-no-false-alarms", Clear false_alarms, " Don't print false alarms" ;
"-invariants" , Set invariants, " Print invariants of each nodes" ;
"-no-invariants" , Clear invariants, " Don't print invariants" ;
"-graph" , Set graph, " Print cfg" ;
"-no-graph" , Clear graph, " Don't print cfg" ;
"-skip-assert" , Set skip_assert, " Don't assume assertions" ;
"-no-skip-assert" , Clear skip_assert, " Assume assertions on outgoing flows" ;
"-max-decreasing-iterations", Set_int max_decreasing_iterations,
"<n> Number of decreasing iterations"]
|> align
in
let usage = "Usage : main.native [options] <filename>" in
Arg.parse spec (fun s -> filename := Some s) usage ;
match !filename with
| Some filename ->
doit !domain !backward_analysis !false_alarms !graph !invariants !skip_assert !max_decreasing_iterations filename
| None -> Arg.usage spec usage
let _ =
try main ()
with Apron.Manager.Error e -> Apron.Manager.print_exclog Format.std_formatter e