|
52 | 52 | All transfer functions reset the counter to 0, so counting only happens between old and new values at a local unknown. *) |
53 | 53 | module DLifter (S: Spec): Spec = |
54 | 54 | struct |
55 | | - module D = |
| 55 | + module DD (D: Lattice.S) = |
56 | 56 | struct |
57 | | - include Dom (S.D) (LocalChainParams) |
| 57 | + include Dom (D) (LocalChainParams) |
58 | 58 |
|
59 | 59 | let printXml f (b, i) = |
60 | | - BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" S.D.printXml b Chain.printXml i |
| 60 | + BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" D.printXml b Chain.printXml i |
| 61 | + |
| 62 | + let lift d = (d, 0) |
| 63 | + let unlift (d, _) = d |
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 |
76 | | - |
77 | | - let startstate v = (S.startstate v, 0) |
78 | | - let exitstate v = (S.exitstate v, 0) |
79 | 72 | let morphstate v (d, l) = (S.morphstate v d, l) |
80 | 73 |
|
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 | 74 | 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) |
| 75 | + let liftmap = List.map (fun (x, _) -> (x, snd man.local)) in |
| 76 | + (* TODO: expose conv from DomainLifter? *) |
| 77 | + liftmap (paths_as_set man) |
120 | 78 | end |
121 | 79 |
|
122 | 80 | (** Lift {!S} to use widening delay for global unknowns. *) |
|
0 commit comments