@@ -9,11 +9,13 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
99
1010 module GM = Hashtbl. Make (System. GVar )
1111 module LM = Hashtbl. Make (System. LVar )
12+ module OM = Hashtbl. Make (Node )
13+
14+ let source = System.LVar. node
1215
1316 let gwarrow a b = if G. leq b a then G. narrow a b else G. widen a (G. join a b)
1417 let lwarrow a b = if D. leq b a then D. narrow a b else D. widen a (D. join a b)
1518
16-
1719 let work = ref (([] : System.LVar.t list ), LS. empty)
1820
1921 let add_work x = let (l,s) = ! work in
@@ -30,7 +32,7 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
3032
3133 let gas = ref (10 ,3 )
3234
33- type glob = {value : G .t ; init : G .t ; infl : System.LVar .t list ; from : (G .t * int * int ) LM .t }
35+ type glob = {value : G .t ; init : G .t ; infl : System.LVar .t list ; from : (G .t * int * int ) OM .t }
3436 (*
3537 now table from with widening delay and narrowing gas to ensure termination
3638 *)
@@ -42,7 +44,7 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
4244 let get_global_ref g =
4345 try GM. find glob g
4446 with _ ->
45- (let rglob = {value = G. bot () ; init = G. bot () ; infl = [] ; from = LM . create 10 } in
47+ (let rglob = {value = G. bot () ; init = G. bot () ; infl = [] ; from = OM . create 10 } in
4648 GM. add glob g rglob;
4749 rglob
4850 )
@@ -52,16 +54,17 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
5254 value = d;
5355 init = d;
5456 infl = [] ;
55- from = LM . create 10
57+ from = OM . create 10
5658 }
5759
58- let get_global_value init from = LM . fold (fun _ (b ,_ ,_ ) a -> G. join a b) from init
60+ let get_global_value init from = OM . fold (fun _ (b ,_ ,_ ) a -> G. join a b) from init
5961
6062 let get_old_global_value x from =
61- try LM. find from x
63+ let sx = source x in
64+ try OM. find from sx
6265 with _ ->
6366 let (delay,gas) = ! gas in
64- LM . add from x (G. bot () ,delay,gas);
67+ OM . add from sx (G. bot () ,delay,gas);
6568 (G. bot () ,delay,gas)
6669
6770 (* now the getters and setters for globals, setters with warrowing per origin *)
@@ -72,6 +75,7 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
7275 rglob.value
7376
7477 let set_global x g d =
78+ let sx = source x in
7579 (*
7680 replaces old contribution with the new one;
7781 reconstructs value of g from contributions;
@@ -81,24 +85,27 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
8185 let (old_value,delay,gas) = get_old_global_value x from in
8286 if G. equal d old_value then ()
8387 else let (new_value,delay,gas) = if G. leq d old_value then
84- if gas > 0 then (G. narrow old_value d,delay,gas-1 )
85- else (old_value,delay,0 )
86- else if delay > 0 then (G. join old_value d,delay-1 ,gas)
87- else (G. widen old_value (G. join old_value d), 0 , gas) in
88- let _ = LM . replace from x (new_value,delay,gas) in
89- let new_g = get_global_value init from in
90- if G. equal value new_g then
91- ()
92- else
93- let _ = List. iter add_work infl in
94- GM. replace glob g {value = new_g; init = init; infl = [] ; from}
88+ if gas > 0 then (G. narrow old_value d,delay,gas-1 )
89+ else (old_value,delay,0 )
90+ else if delay > 0 then (G. join old_value d,delay-1 ,gas)
91+ else (G. widen old_value (G. join old_value d), 0 , gas) in
92+ let _ = OM . replace from sx (new_value,delay,gas) in
93+ let new_g = get_global_value init from in
94+ if G. equal value new_g then
95+ ()
96+ else
97+ let _ = List. iter add_work infl in
98+ GM. replace glob g {value = new_g; init = init; infl = [] ; from}
9599
96100 type loc = {loc_value : D .t ; loc_init : D .t ; loc_infl : System.LVar .t list ; loc_from : (D .t * int * int ) LM .t }
97101 (*
98102 init may contain some initial value not provided by separate origin;
99103 perhaps, dynamic tracking of dependencies required for certain locals?
100104
101- One might additionally maintain in table loc_from some widening delay?
105+ One might additionally maintain in table loc the set of previous contribs
106+ for rewoking vacuous previous contributions - important if large values
107+ are prematurely propagated which later become obsolete (no contrib from that
108+ origin anymore ...
102109 *)
103110
104111 let loc: loc LM. t = LM. create 100
@@ -146,17 +153,17 @@ module FwdSolver (System: FwdGlobConstrSys) = struct
146153 let (old_value,delay,gas) = get_old_local_value x loc_from in
147154 if D. equal d old_value then ()
148155 else let (new_value,delay,gas) = if D. leq d old_value then
149- if gas > 0 then (D. narrow old_value d,delay,gas-1 )
150- else (old_value,delay,0 )
151- else if delay > 0 then (D. join old_value d,delay-1 ,gas)
152- else (D. widen old_value (D. join old_value d), 0 , gas) in
153- let _ = LM. replace loc_from x (new_value,delay,gas) in
154- let new_y = get_local_value loc_init loc_from in
155- if D. equal loc_value new_y then
156- ()
157- else let _ = add_work y in
158- let _ = List. iter add_work loc_infl in
159- LM. replace loc y {loc_value = new_y; loc_init; loc_infl = [] ; loc_from}
156+ if gas > 0 then (D. narrow old_value d,delay,gas-1 )
157+ else (old_value,delay,0 )
158+ else if delay > 0 then (D. join old_value d,delay-1 ,gas)
159+ else (D. widen old_value (D. join old_value d), 0 , gas) in
160+ let _ = LM. replace loc_from x (new_value,delay,gas) in
161+ let new_y = get_local_value loc_init loc_from in
162+ if D. equal loc_value new_y then
163+ ()
164+ else let _ = add_work y in
165+ let _ = List. iter add_work loc_infl in
166+ LM. replace loc y {loc_value = new_y; loc_init; loc_infl = [] ; loc_from}
160167
161168(*
162169 wrapper around propagation function to collect multiple contributions to same unknowns;
0 commit comments