|
24 | 24 | module Chain = Printable.Chain (ChainParams) |
25 | 25 | include Printable.Prod (Base) (Chain) |
26 | 26 |
|
| 27 | + let lift d = (d, 0) |
| 28 | + let unlift (d, _) = d |
| 29 | + |
27 | 30 | let bot () = (Base.bot (), 0) |
28 | 31 | let is_bot (b, _) = Base.is_bot b |
29 | 32 | let top () = (Base.top (), ChainParams.n ()) |
|
52 | 55 | All transfer functions reset the counter to 0, so counting only happens between old and new values at a local unknown. *) |
53 | 56 | module DLifter (S: Spec): Spec = |
54 | 57 | struct |
55 | | - module D = |
| 58 | + module DD (D: Lattice.S) = |
56 | 59 | struct |
57 | | - include Dom (S.D) (LocalChainParams) |
| 60 | + include Dom (D) (LocalChainParams) |
58 | 61 |
|
59 | 62 | let printXml f (b, i) = |
60 | | - BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" S.D.printXml b Chain.printXml i |
| 63 | + BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" D.printXml b Chain.printXml i |
61 | 64 | end |
62 | | - module G = S.G |
63 | | - module C = S.C |
64 | | - module V = S.V |
65 | | - module P = |
| 65 | + |
| 66 | + module NameLifter = |
66 | 67 | struct |
67 | | - include S.P |
68 | | - let of_elt (x, _) = of_elt x |
| 68 | + let lift_name x = x ^ " with widening delay" |
69 | 69 | end |
| 70 | + include SpecLifters.DomainLifter (NameLifter) (DD) (S) |
70 | 71 |
|
71 | | - let name () = S.name () ^ " with widening delay" |
72 | | - |
73 | | - type marshal = S.marshal |
74 | | - let init = S.init |
75 | | - let finalize = S.finalize |
| 72 | + (* Redefine morphstate and paths_as_set to keep counter instead of resetting to 0. *) |
76 | 73 |
|
77 | | - let startstate v = (S.startstate v, 0) |
78 | | - let exitstate v = (S.exitstate v, 0) |
79 | 74 | let morphstate v (d, l) = (S.morphstate v d, l) |
80 | 75 |
|
81 | | - let conv (man: (D.t, G.t, C.t, V.t) man): (S.D.t, S.G.t, S.C.t, S.V.t) man = |
82 | | - { man with local = fst man.local |
83 | | - ; split = (fun d es -> man.split (d, 0) es) |
84 | | - } |
85 | | - |
86 | | - let context man fd (d, _) = S.context (conv man) fd d |
87 | | - let startcontext () = S.startcontext () |
88 | | - |
89 | | - let lift_fun man f g h = |
90 | | - f @@ h (g (conv man)) |
91 | | - |
92 | | - let lift d = (d, 0) |
93 | | - |
94 | | - let sync man reason = lift_fun man lift S.sync ((|>) reason) |
95 | | - let query man (type a) (q: a Queries.t): a Queries.result = S.query (conv man) q |
96 | | - let assign man lv e = lift_fun man lift S.assign ((|>) e % (|>) lv) |
97 | | - let vdecl man v = lift_fun man lift S.vdecl ((|>) v) |
98 | | - let branch man e tv = lift_fun man lift S.branch ((|>) tv % (|>) e) |
99 | | - let body man f = lift_fun man lift S.body ((|>) f) |
100 | | - let return man r f = lift_fun man lift S.return ((|>) f % (|>) r) |
101 | | - let asm man = lift_fun man lift S.asm identity |
102 | | - let skip man = lift_fun man lift S.skip identity |
103 | | - let special man r f args = lift_fun man lift S.special ((|>) args % (|>) f % (|>) r) |
104 | | - |
105 | | - let enter man r f args = |
106 | | - let liftmap = List.map (Tuple2.mapn lift) in |
107 | | - lift_fun man liftmap S.enter ((|>) args % (|>) f % (|>) r) |
108 | | - let combine_env man r fe f args fc es f_ask = lift_fun man lift S.combine_env (fun p -> p r fe f args fc (fst es) f_ask) |
109 | | - let combine_assign man r fe f args fc es f_ask = lift_fun man lift S.combine_assign (fun p -> p r fe f args fc (fst es) f_ask) |
110 | | - |
111 | | - let threadenter man ~multiple lval f args = lift_fun man (List.map lift) (S.threadenter ~multiple) ((|>) args % (|>) f % (|>) lval) |
112 | | - let threadspawn man ~multiple lval f args fman = lift_fun man lift (S.threadspawn ~multiple) ((|>) (conv fman) % (|>) args % (|>) f % (|>) lval) |
113 | | - |
114 | 76 | let paths_as_set man = |
115 | | - let liftmap = List.map (fun x -> (x, snd man.local)) in |
116 | | - lift_fun man liftmap S.paths_as_set Fun.id |
117 | | - |
118 | | - let event man e oman = |
119 | | - lift_fun man lift S.event ((|>) (conv oman) % (|>) e) |
| 77 | + List.map (fun x -> (x, snd man.local)) @@ S.paths_as_set (conv man) |
120 | 78 | end |
121 | 79 |
|
122 | 80 | (** Lift {!S} to use widening delay for global unknowns. *) |
123 | 81 | module GLifter (S: Spec): Spec = |
124 | 82 | struct |
125 | | - module D = S.D |
126 | | - module G = |
| 83 | + module GG (G: Lattice.S) = |
127 | 84 | struct |
128 | | - include Dom (S.G) (GlobalChainParams) |
| 85 | + include Dom (G) (GlobalChainParams) |
129 | 86 |
|
130 | 87 | let printXml f (b, i) = |
131 | | - BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" S.G.printXml b Chain.printXml i |
| 88 | + BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" G.printXml b Chain.printXml i |
132 | 89 | end |
133 | | - module C = S.C |
134 | | - module V = S.V |
135 | | - module P = S.P |
136 | | - |
137 | | - let name () = S.name () ^ " with widening delay" |
138 | | - |
139 | | - type marshal = S.marshal |
140 | | - let init = S.init |
141 | | - let finalize = S.finalize |
142 | 90 |
|
143 | | - let startstate v = S.startstate v |
144 | | - let exitstate v = S.exitstate v |
145 | | - let morphstate v d = S.morphstate v d |
146 | | - |
147 | | - let conv (man: (D.t, G.t, C.t, V.t) man): (S.D.t, S.G.t, S.C.t, S.V.t) man = |
148 | | - { man with global = (fun v -> fst (man.global v)) |
149 | | - ; sideg = (fun v g -> man.sideg v (g, 0)) |
150 | | - } |
151 | | - |
152 | | - let context man fd d = S.context (conv man) fd d |
153 | | - let startcontext () = S.startcontext () |
154 | | - |
155 | | - let lift_fun man f g h = |
156 | | - f @@ h (g (conv man)) |
157 | | - |
158 | | - let lift d = d |
159 | | - |
160 | | - let sync man reason = lift_fun man lift S.sync ((|>) reason) |
161 | | - let query man (type a) (q: a Queries.t): a Queries.result = S.query (conv man) q |
162 | | - let assign man lv e = lift_fun man lift S.assign ((|>) e % (|>) lv) |
163 | | - let vdecl man v = lift_fun man lift S.vdecl ((|>) v) |
164 | | - let branch man e tv = lift_fun man lift S.branch ((|>) tv % (|>) e) |
165 | | - let body man f = lift_fun man lift S.body ((|>) f) |
166 | | - let return man r f = lift_fun man lift S.return ((|>) f % (|>) r) |
167 | | - let asm man = lift_fun man lift S.asm identity |
168 | | - let skip man = lift_fun man lift S.skip identity |
169 | | - let special man r f args = lift_fun man lift S.special ((|>) args % (|>) f % (|>) r) |
170 | | - |
171 | | - let enter man r f args = |
172 | | - let liftmap = List.map (Tuple2.mapn lift) in |
173 | | - lift_fun man liftmap S.enter ((|>) args % (|>) f % (|>) r) |
174 | | - let combine_env man r fe f args fc es f_ask = lift_fun man lift S.combine_env (fun p -> p r fe f args fc es f_ask) |
175 | | - let combine_assign man r fe f args fc es f_ask = lift_fun man lift S.combine_assign (fun p -> p r fe f args fc es f_ask) |
176 | | - |
177 | | - let threadenter man ~multiple lval f args = lift_fun man (List.map lift) (S.threadenter ~multiple) ((|>) args % (|>) f % (|>) lval) |
178 | | - let threadspawn man ~multiple lval f args fman = lift_fun man lift (S.threadspawn ~multiple) ((|>) (conv fman) % (|>) args % (|>) f % (|>) lval) |
179 | | - |
180 | | - let paths_as_set man = |
181 | | - lift_fun man Fun.id S.paths_as_set Fun.id |
182 | | - |
183 | | - let event man e oman = |
184 | | - lift_fun man lift S.event ((|>) (conv oman) % (|>) e) |
| 91 | + module NameLifter = |
| 92 | + struct |
| 93 | + let lift_name x = x ^ " with widening delay" |
| 94 | + end |
| 95 | + include SpecLifters.GlobalDomainLifter (NameLifter) (GG) (S) |
185 | 96 | end |
0 commit comments