|
|
@ -26,6 +26,12 @@ module type WithBottom = sig
|
|
|
|
val empty : astate
|
|
|
|
val empty : astate
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module type WithTop = sig
|
|
|
|
|
|
|
|
include S
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val top : astate
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
module BottomLifted (Domain : S) = struct
|
|
|
|
module BottomLifted (Domain : S) = struct
|
|
|
|
type astate =
|
|
|
|
type astate =
|
|
|
|
| Bottom
|
|
|
|
| Bottom
|
|
|
@ -65,6 +71,46 @@ module BottomLifted (Domain : S) = struct
|
|
|
|
| NonBottom astate -> Domain.pp fmt astate
|
|
|
|
| NonBottom astate -> Domain.pp fmt astate
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module TopLifted (Domain: S) = struct
|
|
|
|
|
|
|
|
type astate =
|
|
|
|
|
|
|
|
| Top
|
|
|
|
|
|
|
|
| NonTop of Domain.astate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let top = Top
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let (<=) ~lhs ~rhs =
|
|
|
|
|
|
|
|
if phys_equal lhs rhs
|
|
|
|
|
|
|
|
then true
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
match lhs, rhs with
|
|
|
|
|
|
|
|
| _, Top -> true
|
|
|
|
|
|
|
|
| Top, _ -> false
|
|
|
|
|
|
|
|
| NonTop lhs, NonTop rhs -> Domain.(<=) ~lhs ~rhs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let join astate1 astate2 =
|
|
|
|
|
|
|
|
if phys_equal astate1 astate2
|
|
|
|
|
|
|
|
then astate1
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
match astate1, astate2 with
|
|
|
|
|
|
|
|
| Top, _
|
|
|
|
|
|
|
|
| _, Top -> Top
|
|
|
|
|
|
|
|
| NonTop a1, NonTop a2 -> NonTop (Domain.join a1 a2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let widen ~prev ~next ~num_iters =
|
|
|
|
|
|
|
|
if phys_equal prev next
|
|
|
|
|
|
|
|
then prev
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
match prev, next with
|
|
|
|
|
|
|
|
| Top, _
|
|
|
|
|
|
|
|
| _, Top -> Top
|
|
|
|
|
|
|
|
| NonTop prev, NonTop next -> NonTop (Domain.widen ~prev ~next ~num_iters)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pp fmt = function
|
|
|
|
|
|
|
|
| Top -> F.fprintf fmt "T"
|
|
|
|
|
|
|
|
| NonTop astate -> Domain.pp fmt astate
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
module Pair (Domain1 : S) (Domain2 : S) = struct
|
|
|
|
module Pair (Domain1 : S) (Domain2 : S) = struct
|
|
|
|
type astate = Domain1.astate * Domain2.astate
|
|
|
|
type astate = Domain1.astate * Domain2.astate
|
|
|
|
|
|
|
|
|
|
|
|