summaryrefslogtreecommitdiff
path: root/abstract/relational_apron.ml
diff options
context:
space:
mode:
Diffstat (limited to 'abstract/relational_apron.ml')
-rw-r--r--abstract/relational_apron.ml91
1 files changed, 85 insertions, 6 deletions
diff --git a/abstract/relational_apron.ml b/abstract/relational_apron.ml
index bd078cf..926d2a9 100644
--- a/abstract/relational_apron.ml
+++ b/abstract/relational_apron.ml
@@ -1,3 +1,4 @@
+open Abstract_syntax_tree
open Apron
open Util
open Environment_domain
@@ -11,19 +12,86 @@ module RelationalDomain : ENVIRONMENT_DOMAIN = struct
(* abstract elements *)
type t = man Abstract1.t
+ (* translation in trees *)
+ let rec texpr_of_expr e =
+ match fst e with
+ | AST_identifier (id, _) -> Texpr1.Var (Var.of_string id)
+ | AST_int_const (s, _) -> Texpr1.Cst (Coeff.s_of_mpqf (Mpqf.of_string s))
+ | AST_int_rand ((s, _), (t, _)) ->
+ Texpr1.Cst (Coeff.i_of_mpqf (Mpqf.of_string s) (Mpqf.of_string t))
+ | AST_unary(AST_UNARY_PLUS, e) ->
+ texpr_of_expr e
+ | AST_unary(AST_UNARY_MINUS, e) ->
+ (*
+ (* APRON bug ? Unary negate seems to not work correctly... *)
+ Texpr1.Unop(
+ Texpr1.Neg,
+ (texpr_of_expr e),
+ Texpr1.Int,
+ Texpr1.Zero)
+ *)
+ Texpr1.Binop(
+ Texpr1.Sub,
+ Texpr1.Cst(Coeff.s_of_mpqf (Mpqf.of_string "0")),
+ (texpr_of_expr e),
+ Texpr1.Int,
+ Texpr1.Zero)
+ | AST_binary( op, e1, e2) ->
+ let f = match op with
+ | AST_PLUS -> Texpr1.Add
+ | AST_MINUS -> Texpr1.Sub
+ | AST_MULTIPLY -> Texpr1.Mul
+ | AST_DIVIDE -> Texpr1.Div
+ | AST_MODULO -> Texpr1.Mod
+ | _ -> assert false
+ in
+ Texpr1.Binop
+ (f, (texpr_of_expr e1), (texpr_of_expr e2), Texpr1.Int, Texpr1.Zero)
+ | _ -> assert false
+
(* implementation *)
let init = Abstract1.top manager (Environment.make [||] [||])
let bottom = Abstract1.bottom manager (Environment.make [||] [||])
let is_bot = Abstract1.is_bottom manager
- let addvar x id = x (* TODO *)
- let rmvar x id = x (* TODO *)
+ let addvar x id =
+ let env = Abstract1.env x in
+ let env2 = Environment.add env [| Var.of_string id |] [||] in
+ Abstract1.change_environment manager x env2 false
+ let rmvar x id =
+ let env = Abstract1.env x in
+ let env2 = Environment.remove env [| Var.of_string id |] in
+ Abstract1.change_environment manager x env2 false
let vars x =
List.map Var.to_string @@
- Array.to_list @@ snd @@ Environment.vars @@ Abstract1.env x
+ Array.to_list @@ fst @@ Environment.vars @@ Abstract1.env x
- let assign x id e = x (* TODO *)
- let compare x e1 e2 = x (* TODO *)
+ let assign x id e =
+ let expr = Texpr1.of_expr (Abstract1.env x) (texpr_of_expr e) in
+ let x' =
+ Abstract1.assign_texpr manager x
+ (Var.of_string id) expr None
+ in
+ if false then begin
+ Format.eprintf "Assign : ";
+ Abstract1.print Format.err_formatter x;
+ Format.eprintf " ; %s <- " id;
+ Texpr1.print Format.err_formatter expr;
+ Format.eprintf " ; ";
+ Abstract1.print Format.err_formatter x';
+ Format.eprintf "@.";
+ end;
+ x'
+ let compare op x e1 e2 =
+ let env = Abstract1.env x in
+ let expr = Texpr1.Binop
+ (Texpr1.Sub, texpr_of_expr e2, texpr_of_expr e1, Texpr1.Int, Texpr1.Zero) in
+ let cons = Tcons1.make (Texpr1.of_expr env expr) op in
+ let ar = Tcons1.array_make env 1 in
+ Tcons1.array_set ar 0 cons;
+ Abstract1.meet_tcons_array manager x ar
+ let compare_leq = compare Tcons1.SUPEQ
+ let compare_eq = compare Tcons1.EQ
let join = Abstract1.join manager
let meet = Abstract1.meet manager
@@ -31,7 +99,18 @@ module RelationalDomain : ENVIRONMENT_DOMAIN = struct
let subset = Abstract1.is_leq manager
- let var_str x idl = "" (* TODO *)
+ let var_str x idl =
+ let prevars = vars x in
+ let rm_vars_l = List.filter (fun id -> not (List.mem id idl)) prevars in
+ (* print_list "prevars" prevars;
+ print_list "idl" idl;
+ print_list "rm_vars_l" rm_vars_l; *)
+ let rm_vars = Array.of_list (List.map Var.of_string rm_vars_l) in
+ let xx = Abstract1.forget_array manager x rm_vars false in
+ let b = Buffer.create 80 in
+ let s = Format.formatter_of_buffer b in
+ Abstract1.print s xx; Format.fprintf s "@?";
+ (Buffer.contents b)
end