package goblint
Static analysis framework for C
Install
Dune Dependency
Authors
Maintainers
Sources
goblint-2.5.0.tbz
sha256=452d8491527aea21f2cbb11defcc14ba0daf9fdb6bdb9fc0af73e56eac57b916
sha512=1993cd45c4c7fe124ca6e157f07d17ec50fab5611b270a434ed1b7fb2910aa85a8e6eaaa77dad770430710aafb2f6d676c774dd33942d921f23e2f9854486551
doc/src/goblint.solver/topDown_term.ml.html
Source file topDown_term.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
(** Terminating top-down solver ([topdown_term]). Simpler version of {!Td3} without space-efficiency and incremental. *) open Batteries open ConstrSys open Messages module WP = functor (S:EqConstrSys) -> functor (HM:Hashtbl.S with type key = S.v) -> struct include Generic.SolverStats (S) (HM) module VS = Set.Make (S.Var) module P = struct type t = S.Var.t * S.Var.t [@@deriving eq, hash] end type phase = Widen | Narrow let solve st vs = let stable = HM.create 10 in let infl = HM.create 10 in (* y -> xs *) let called = HM.create 10 in let rho = HM.create 10 in let rho' = HM.create 10 in let wpoint = HM.create 10 in let add_infl y x = if tracing then trace "sol2" "add_infl %a %a" S.Var.pretty_trace y S.Var.pretty_trace x; HM.replace infl y (VS.add x (try HM.find infl y with Not_found -> VS.empty)) in let rec destabilize x = if tracing then trace "sol2" "destabilize %a" S.Var.pretty_trace x; let w = HM.find_default infl x VS.empty in HM.replace infl x VS.empty; VS.iter (fun y -> HM.remove stable y; (* if tracing then trace "sol2" "destabilize %a" S.Var.pretty_trace y; *) if not (HM.mem called y) then destabilize y) w and solve x phase = if tracing then trace "sol2" "solve %a, called: %b, stable: %b" S.Var.pretty_trace x (HM.mem called x) (HM.mem stable x); if not (HM.mem called x || HM.mem stable x) then ( HM.replace stable x (); HM.replace called x (); let wpx = HM.mem wpoint x in init x; let old = HM.find rho x in let tmp = eq x (eval x) side in let tmp = S.Dom.join tmp (try HM.find rho' x with Not_found -> S.Dom.bot ()) in if tracing then trace "sol" "Var: %a" S.Var.pretty_trace x ; if tracing then trace "sol" "Contrib:%a" S.Dom.pretty tmp; HM.remove called x; let tmp = if wpx then match phase with Widen -> S.Dom.widen old (S.Dom.join old tmp) | Narrow -> S.Dom.narrow old tmp else tmp in if not (S.Dom.equal old tmp) then ( (* if tracing then if is_side x then trace "sol2" "solve side: old = %a, tmp = %a, widen = %a" S.Dom.pretty old S.Dom.pretty tmp S.Dom.pretty (S.Dom.widen old (S.Dom.join old tmp)); *) update_var_event x old tmp; if tracing then trace "sol" "New Value:%a" S.Dom.pretty tmp; (* if tracing then trace "sol2" "new value for %a (wpx: %b, is_side: %b) is %a. Old value was %a" S.Var.pretty_trace x (HM.mem rho x) (is_side x) S.Dom.pretty tmp S.Dom.pretty old; *) HM.replace rho x tmp; destabilize x; (solve[@tailcall]) x phase; ) else if not (HM.mem stable x) then ( (solve[@tailcall]) x Widen; ) else if phase = Widen && S.system x <> None then ( HM.remove stable x; (solve[@tailcall]) x Narrow; ); ) and eq x get set = if tracing then trace "sol2" "eq %a" S.Var.pretty_trace x; eval_rhs_event x; match S.system x with | None -> S.Dom.bot () | Some f -> f get set and eval x y = if tracing then trace "sol2" "eval %a ## %a" S.Var.pretty_trace x S.Var.pretty_trace y; get_var_event y; if HM.mem called y then HM.replace wpoint y (); solve y Widen; add_infl y x; HM.find rho y and side y d = let old = try HM.find rho' y with Not_found -> S.Dom.bot () in if not (S.Dom.leq d old) then ( HM.replace rho' y (S.Dom.widen old d); HM.remove stable y; init y; solve y Widen; ) and init x = if tracing then trace "sol2" "init %a" S.Var.pretty_trace x; if not (HM.mem rho x) then ( new_var_event x; HM.replace rho x (S.Dom.bot ()) ) in let set_start (x,d) = if tracing then trace "sol2" "set_start %a ## %a" S.Var.pretty_trace x S.Dom.pretty d; init x; HM.replace rho x d; solve x Widen in start_event (); List.iter set_start st; List.iter init vs; List.iter (fun x -> solve x Widen) vs; (* iterate until there are no unstable variables * after termination, only those variables are stable which are * - reachable from any of the queried variables vs, or * - effected by side-effects and have no constraints on their own (this should be the case for all of our analyses) *) let rec solve_sidevs () = let non_stable = List.filter (neg (HM.mem stable)) vs in if non_stable <> [] then ( List.iter (fun x -> solve x Widen) non_stable; solve_sidevs () ) in solve_sidevs (); stop_event (); HM.clear stable; HM.clear infl ; HM.clear rho' ; rho end let _ = Selector.add_solver ("topdown_term", (module PostSolver.EqIncrSolverFromEqSolver (WP)));
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>