diff options
author | Alex Auvolat <alex.auvolat@ansys.com> | 2014-06-24 17:12:04 +0200 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ansys.com> | 2014-06-24 17:12:04 +0200 |
commit | 99cf7409d4eaacd7f8b86ff4de8b92c86a10dd5f (patch) | |
tree | 4fddba970a4a5db064d48859c9525baff4d4ae6f /abstract/abs_domain.ml | |
parent | 6dec5b2fae34f4be8e57745e3b1a7063a62e1fc4 (diff) | |
download | scade-analyzer-99cf7409d4eaacd7f8b86ff4de8b92c86a10dd5f.tar.gz scade-analyzer-99cf7409d4eaacd7f8b86ff4de8b92c86a10dd5f.zip |
Implementation of disjunction domain seems to work.
Diffstat (limited to 'abstract/abs_domain.ml')
-rw-r--r-- | abstract/abs_domain.ml | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/abstract/abs_domain.ml b/abstract/abs_domain.ml deleted file mode 100644 index d6ff489..0000000 --- a/abstract/abs_domain.ml +++ /dev/null @@ -1,401 +0,0 @@ -open Ast -open Formula -open Num_domain -open Typing -open Util - -type disjunct_policy = - | DAlways - | DNever - | DSometimes - -module type ENVIRONMENT_DOMAIN = sig - type t - type itv - - (* construction *) - val init : t - val bottom : t - val vbottom : t -> t (* bottom value with same environment *) - val is_bot : t -> bool - - (* variable management *) - val addvar : t -> id -> Typing.typ -> t - val rmvar : t -> id -> t - val vars : t -> (id * Typing.typ) list - - val forgetvar : t -> id -> t - val var_itv : t -> id -> itv - val set_disjunct : t -> id -> disjunct_policy -> t - - (* set_theoretic operations *) - val join : t -> t -> t (* union *) - val meet : t -> t -> t (* intersection *) - val widen : t -> t -> t - - val subset : t -> t -> bool - val eq : t -> t -> bool - - (* abstract operations *) - val apply_f : t -> bool_expr -> t - val apply_cl : t -> conslist -> t - val assign : t -> (id * id) list -> t - - (* pretty-printing *) - val print_vars : Format.formatter -> t -> id list -> unit - val print_all : Format.formatter -> t -> unit - val print_itv : Format.formatter -> itv -> unit - -end - - -module D_ignore_enum (ND : NUMERICAL_ENVIRONMENT_DOMAIN) : ENVIRONMENT_DOMAIN = -struct - type t = ND.t - type itv = ND.itv - - - let init = ND.init - let bottom = ND.bottom - let vbottom = ND.vbottom - let is_bot = ND.is_bot - - let addvar x id ty = ND.addvar x id (ty = TReal) - let rmvar = ND.rmvar - let vars x = List.map (fun (id, r) -> id, if r then TReal else TInt) (ND.vars x) - - let forgetvar = ND.forgetvar - let var_itv = ND.var_itv - let set_disjunct x _ _ = x - - let join = ND.join - let meet = ND.meet - let widen = ND.widen - - let subset = ND.subset - let eq = ND.eq - - let rec apply_cl x (econs, cons, rest) = match rest with - | CLTrue -> - ND.apply_ncl x cons - | CLFalse -> vbottom x - | CLAnd(a, b) -> - let y = apply_cl x (econs, cons, a) in - apply_cl y (econs, cons, b) - | CLOr((eca, ca, ra), (ecb, cb, rb)) -> - let y = apply_cl x (econs@eca, cons@ca, ra) in - let z = apply_cl x (econs@ecb, cons@cb, rb) in - join y z - - let apply_f x f = apply_cl x (conslist_of_f f) - - let assign x v = ND.assign x (List.map (fun (id, id2) -> id, NIdent id2) v) - - let print_vars = ND.print_vars - let print_all = ND.print_all - let print_itv = ND.print_itv -end - -module D (ND : NUMERICAL_ENVIRONMENT_DOMAIN) : ENVIRONMENT_DOMAIN = struct - - module Valuation = struct - type t = string VarMap.t - let compare = VarMap.compare Pervasives.compare - - let subset a b = - VarMap.for_all - (fun id v -> - try v = VarMap.find id b - with Not_found -> true) - a - - let print fmt x = - let b = List.map (fun (x, y) -> y, x) (VarMap.bindings x) in - let s = List.sort Pervasives.compare b in - let rec bl = function - | [] -> [] - | (v, id)::q -> - begin match bl q with - | (vv, ids)::q when vv = v -> (v, id::ids)::q - | r -> (v, [id])::r - end - in - let sbl = bl s in - Format.fprintf fmt "@[<v 2>{ "; - List.iteri - (fun j (v, ids) -> - if j > 0 then Format.fprintf fmt "@ "; - Format.fprintf fmt "@[<hov 4>"; - List.iteri - (fun i id -> - if i > 0 then Format.fprintf fmt ",@ "; - Format.fprintf fmt "%a" Formula_printer.print_id id) - ids; - Format.fprintf fmt " ≡ %s@]" v) - sbl; - Format.fprintf fmt " }@]" - - end - module VMap = Mapext.Make(Valuation) - - type t = { - nvars : (id * bool) list; - evars : (id * string list) list; - nd_init : ND.t; - nd_bottom : ND.t; - value : ND.t VMap.t; - disj_v : id list; - nodisj_v : id list; - } - type itv = - | IN of ND.itv VMap.t - | IE of SSet.t - - - let init = { - nvars = []; evars = []; disj_v = []; nodisj_v = []; - nd_init = ND.init; - nd_bottom = ND.bottom; - value = VMap.singleton VarMap.empty ND.init; - } - let bottom = { - nvars = []; evars = []; disj_v = []; nodisj_v = []; - nd_init = ND.init; - nd_bottom = ND.bottom; - value = VMap.empty; - } - let vbottom x = { x with value = VMap.empty } - - let is_bot x = VMap.is_empty x.value || VMap.for_all (fun _ v -> ND.is_bot v) x.value - - let strict value = - VMap.filter (fun _ v -> not (ND.is_bot v)) value - - let add_case_w widen x (enum, num) = - let value = x.value in - let enum = VarMap.filter (fun k v -> not (List.mem k x.nodisj_v)) enum in - let v = - if VMap.exists - (fun e0 n0 -> Valuation.subset enum e0 && ND.subset num n0) - value - || ND.is_bot num - then - value - else - try VMap.add enum - ((if widen then ND.widen else ND.join) (VMap.find enum value) num) - value - with Not_found -> VMap.add enum num value - in { x with value = v } - let add_case = add_case_w false - - let addvar x id ty = match ty with - | TInt | TReal -> - let is_real = (ty = TReal) in - { x with - nvars = (id, is_real)::(x.nvars); - nd_init = ND.addvar x.nd_init id is_real; - nd_bottom = ND.addvar x.nd_bottom id is_real; - value = VMap.map (fun v -> ND.addvar v id is_real) x.value - } - | TEnum options -> - { x with - evars = (id, options)::x.evars - } - - let vars x = - List.map (fun (id, r) -> id, if r then TReal else TInt) x.nvars @ - List.map (fun (id, o) -> id, TEnum o) x.evars - - let forgetvar x id = - if List.mem_assoc id x.evars then - VMap.fold - (fun enum num value -> - let enum' = VarMap.remove id enum in - add_case value (enum', num)) - x.value - { x with value = VMap.empty } - else - { x with value = strict @@ VMap.map (fun v -> ND.forgetvar v id) x.value } - - let rmvar x id = - if List.mem_assoc id x.evars then - let y = forgetvar x id in - { y with - evars = List.remove_assoc id x.evars } - else - { x with - nvars = List.remove_assoc id x.nvars; - value = strict @@ VMap.map (fun v -> ND.rmvar v id) x.value } - - let var_itv x id = - if List.mem_assoc id x.nvars - then - let x = List.fold_left - (fun x (v, _) -> - if v.[0] = 'N' || (String.length v > 3 && String.sub v 0 3 = "pre") - then forgetvar x v else x) - x x.evars in - IN (VMap.map (fun v -> ND.var_itv v id) x.value) - else - let all = List.fold_left (fun a b -> SSet.add b a) SSet.empty - (List.assoc id x.evars) in - IE - (VMap.fold - (fun enum _ s -> - try SSet.add (VarMap.find id enum) s - with Not_found -> all) - x.value - SSet.empty) - - let set_disjunct x id p = - { x with - disj_v = (if p = DAlways then id::x.disj_v - else List.filter ((<>) id) x.disj_v); - nodisj_v = (if p = DNever then id::x.nodisj_v - else List.filter ((<>) id) x.nodisj_v); - } - - let join x y = - VMap.fold - (fun enum num value -> add_case value (enum, num)) - y.value - x - let meet x y = not_implemented "meet for enum+num domain" - let widen x y = - let value = VMap.merge - (fun _ a b -> match a, b with - | Some x, None -> Some x - | None, Some y -> Some y - | Some x, Some y -> Some (ND.widen x y) - | _ -> None) - x.value y.value - in { x with value = value } - - (* Some cases of subset/equality not detected *) - let subset a b = - VMap.for_all - (fun enum num -> - VMap.exists - (fun enum_b num_b -> - Valuation.subset enum enum_b && ND.subset num num_b) - b.value) - a.value - let eq a b = subset a b && subset b a - - (* Constraints ! *) - let apply_ec x (op, a, b) = - VMap.fold - (fun enum num value -> - match a, b with - | i, EItem u -> - begin try let v = VarMap.find i enum in - if (if op = E_EQ then u = v else u <> v) - then add_case value (enum, num) - else value - with Not_found -> - if op = E_EQ - then add_case value (VarMap.add i u enum, num) - else (* MAKE A DISJUNCTION *) - List.fold_left - (fun value item -> - add_case value (VarMap.add i item enum, num)) - value - (List.filter ((<>) u) (List.assoc i x.evars)) - end - | i, EIdent j -> - begin - try let x = VarMap.find i enum in - try let y = VarMap.find j enum in - if (if op = E_EQ then x = y else x <> y) - then add_case value (enum, num) - else value - with Not_found (* J not found *) -> - add_case value (VarMap.add j x enum, num) - with Not_found (* I not found *) -> - try let y = VarMap.find j enum in - add_case value (VarMap.add i y enum, num) - with Not_found (* J not found *) -> - if op = E_EQ - then (* MAKE A DISJUNCTION ! *) - List.fold_left - (fun value item -> - let enum = VarMap.add i item enum in - let enum = VarMap.add j item enum in - add_case value (enum, num)) - value - (List.assoc i x.evars) - else - add_case value (enum, num) - end) - x.value - { x with value = VMap.empty } - - let apply_ecl x cons = - let f x = List.fold_left apply_ec x cons in - fix eq f x - - - let apply_ncl x econs = - { x with value = strict @@ VMap.map (fun x -> ND.apply_ncl x econs) x.value } - - let rec apply_cl x (econs, ncons, rest) = match rest with - | CLTrue -> - let y = apply_ecl x econs in - let z = apply_ncl y ncons in - z - | CLFalse -> vbottom x - | CLAnd(a, b) -> - let y = apply_cl x (econs, ncons, a) in - apply_cl y (econs, ncons, b) - | CLOr((eca, ca, ra), (ecb, cb, rb)) -> - let y = apply_cl x (econs@eca, ncons@ca, ra) in - let z = apply_cl x (econs@ecb, ncons@cb, rb) in - join y z - - let apply_f x f = apply_cl x (conslist_of_f f) - - let assign x e = - let ee, ne = List.partition (fun (id, id2) -> List.mem_assoc id x.evars) e in - let ne_e = List.map (fun (id, id2) -> id, NIdent id2) ne in - - VMap.fold - (fun enum0 num value -> - let enum = List.fold_left - (fun enum (id, id2) -> - try let y = VarMap.find id2 enum0 in - VarMap.add id y enum - with Not_found -> - VarMap.remove id enum) - enum0 ee - in - add_case value (enum, ND.assign num ne_e)) - x.value - { x with value = VMap.empty } - - let print_all fmt x = - Format.fprintf fmt "@[<v>"; - VMap.iter - (fun enum num -> - Format.fprintf fmt "@[<hv 2>{ %a ∧@ %a }@]@ " - Valuation.print enum ND.print_all num) - x.value; - Format.fprintf fmt "@]" - - let print_vars fmt x idl = print_all fmt x (* TODO *) - - let print_itv fmt = function - | IN x -> - Format.fprintf fmt "@[<v 0>"; - VMap.iter - (fun enum i -> - Format.fprintf fmt "%a when %a@ " - ND.print_itv i Valuation.print enum) - x; - Format.fprintf fmt "@]" - | IE x -> - Format.fprintf fmt "@[<hov 2>{ "; - SSet.iter (fun x -> Format.fprintf fmt "%s@ " x) x; - Format.fprintf fmt "}@]" - -end |