summaryrefslogtreecommitdiff
path: root/abstract/constant_domain.ml
diff options
context:
space:
mode:
Diffstat (limited to 'abstract/constant_domain.ml')
-rw-r--r--abstract/constant_domain.ml206
1 files changed, 53 insertions, 153 deletions
diff --git a/abstract/constant_domain.ml b/abstract/constant_domain.ml
index 544d2e9..4bd5cf2 100644
--- a/abstract/constant_domain.ml
+++ b/abstract/constant_domain.ml
@@ -1,153 +1,53 @@
-open Util
-open Abstract_syntax_tree
-
-module CD : Domain.S =
- struct
-
- exception DivideByZero
- exception TypeError
- exception Bot
- exception NotImplemented
-
- type tv = (* type for a variable *)
- | Top
- | I of Z.t
-
- type ts = (* type for an environment *)
- | Bot
- | Nb of tv VarMap.t
-
- let top_ts = Nb VarMap.empty
-
- let ts_union a b =
- begin match a, b with
- | Bot, Bot -> Bot
- | Nb a, Bot -> Nb a
- | Bot, Nb b -> Nb b
- | Nb a, Nb b ->
- Nb
- (VarMap.fold
- (fun var value a ->
- try match VarMap.find var a with
- | Top -> a
- | I x ->
- match value with
- | I y when y = x -> a
- | _ -> VarMap.add var Top a
- with
- | Not_found -> VarMap.add var value a)
- b a)
- end
-
- (* must not raise exception *)
- let ts_add_bool_constraint expr (s : ts) =
- s (* TODO, not necessary... *)
-
-
- (* only evaluates numerical statements, raises
- TypeError when result is bool *)
- let rec eval_abs expr (s : tv VarMap.t) =
- match expr with
- | AST_unary(op, (i, _)) ->
- begin match eval_abs i s with
- | Top -> Top
- | I x ->
- match op with
- | AST_UNARY_PLUS -> I x
- | AST_UNARY_MINUS -> I (Z.neg x)
- | _ -> raise TypeError
- end
- | AST_binary(op, (a, _), (b, _)) ->
- begin match eval_abs a s, eval_abs b s with
- | I x, I y ->
- begin match op with
- | AST_PLUS -> I (Z.add x y)
- | AST_MINUS -> I (Z.sub x y)
- | AST_MULTIPLY -> I (Z.mul x y)
- | AST_DIVIDE ->
- if y = Z.zero then raise DivideByZero;
- I (Z.div x y)
- | AST_MODULO ->
- if y = Z.zero then raise DivideByZero;
- I (Z.rem x y)
- | _ -> raise TypeError
- end
- | _ -> Top
- end
- | AST_identifier(id, _) ->
- begin
- try VarMap.find id s
- with _ -> Top
- end
- | AST_int_const(s, _) ->
- I (Z.of_string s)
- | AST_bool_const(_) -> raise TypeError
- | AST_int_rand _ -> Top
- | _ -> raise NotImplemented (* extensions *)
-
- (* returns true if the expression can evaluate to true
- returns false if the expression always evaluates to false *)
- let rec eval_bool_abs expr (s : tv VarMap.t) =
- true (* TODO *)
-
- (* must not raise exception *)
- let rec interp_abs stat s =
- begin match s with
- | Bot -> Bot
- | Nb vars ->
- begin match stat with
- | AST_block b ->
- List.fold_left
- (fun ss (st, _) -> interp_abs st ss)
- s b
- | AST_assign ((id, _), (exp, _)) ->
- begin
- try
- let value = eval_abs exp vars in
- Nb (VarMap.add id value vars)
- with _ -> Bot
- end
- | AST_if ((cond, _), (tb, _), None) ->
- ts_union (Nb vars)
- (interp_abs tb
- (ts_add_bool_constraint cond (Nb vars)))
- | AST_if ((cond, l), (tb, _), Some (eb, _)) ->
- ts_union
- (interp_abs tb
- (ts_add_bool_constraint cond (Nb vars)))
- (interp_abs eb
- (ts_add_bool_constraint
- (AST_unary (AST_NOT, (cond, l)))
- (Nb vars)))
- | AST_while ((cond, _), (body, _)) ->
- let f s =
- ts_union
- s
- (ts_add_bool_constraint cond s)
- in
- fix f (Nb vars)
- | AST_HALT -> Bot
- | AST_assert (cond, _) ->
- if eval_bool_abs cond vars
- then Nb vars
- else begin
- print_string "Assert fail\n";
- Bot
- end
- | AST_print items ->
- List.iter
- (fun (var, _) ->
- print_string (var ^ " = ");
- try
- match VarMap.find var vars with
- | Top -> print_string "T\n"
- | I x -> print_string (Z.to_string x ^ "\n")
- with _ -> print_string "T\n")
- items;
- Nb vars
- | _ -> raise NotImplemented (* extensions *)
- end
- end
-
- end
-
+open Value_domain
+
+module Constants : VALUE_DOMAIN = struct
+ type t =
+ | Top
+ | Int of Z.t
+ | Bot
+
+ let top = Top
+ let bottom = Bot
+ let const i = Int i
+ let rand i j = if i <> j then Top else Int i
+
+ let subset a b = match a, b with
+ | _, Top -> true
+ | Bot, _ -> true
+ | Int a, Int b -> a = b
+ | _, _ -> false
+
+ let join a b = match a, b with
+ | Bot, x | x, Bot -> x
+ | Int a, Int b when a = b -> Int a
+ | _ -> Top
+
+ let meet a b = match a, b with
+ | Top, x | x, Top -> x
+ | Int a, Int b when a = b -> Int a
+ | _ -> Bot
+
+ let widen = meet (* pas besoin d'accélerer la convergence au-delà *)
+
+ let neg = function
+ | Int a -> Int (Z.neg a)
+ | x -> x
+
+ let b_aux op a b = match a, b with
+ | Int x, Int y -> Int (op x y)
+ | Bot, _ | _, Bot -> Bot
+ | _ -> Top
+ let add = b_aux Z.add
+ let sub = b_aux Z.sub
+ let mul = b_aux Z.mul
+ let div = b_aux Z.div
+ let rem = b_aux Z.rem
+
+ let leq a b =
+ match a, b with
+ | Int a, Int b when Z.leq a b ->
+ if Z.leq a b
+ then Int a, Int b
+ else Bot, Bot
+ | x, y -> x, y
+end