Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
linconsext.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
(****************************************************************************) (* This file is an extension for the Lincons1 module from the apron Library *) (****************************************************************************) (* It only adds function, nothing is removed *) include Apron.Lincons1 include Array_maker.LinconsExt module C = Apron.Coeff let fold f g l = let acc = ref (g (get_cst l)) in iter (fun c v -> acc := f c v !acc) l; !acc let neg_typ = function | EQ -> DISEQ | SUP -> SUPEQ | SUPEQ -> SUP | DISEQ -> EQ | _ -> assert false let neg d = let d = copy d in set_cst d (C.neg (get_cst d)); iter (fun c v -> set_coeff d v (C.neg c)) d; set_typ d (get_typ d |> neg_typ); d (* split a = b into a >= b and a <= b*) let spliteq c = if get_typ c = EQ then let c1 = copy c in set_typ c1 SUPEQ; let c2 = copy c1 in set_cst c2 (C.neg (get_cst c2)); iter (fun c v -> set_coeff c2 v (C.neg c)) c2; c1,c2 else raise (Invalid_argument "spliteq must take an equality constraint") (* split a <> b into a > b or a < b*) let splitdiseq c = if get_typ c = DISEQ then let c1 = copy c in set_typ c1 SUP; let c2 = copy c1 in set_cst c2 (C.neg (get_cst c2)); iter (fun c v -> set_coeff c2 v (C.neg c)) c2; c1,c2 else raise (Invalid_argument "splitdiseq must take a disequality constraint") let print_typ fmt = function | EQ -> Format.fprintf fmt "=" | SUP -> Format.fprintf fmt ">" | SUPEQ -> Format.fprintf fmt ">=" | DISEQ -> Format.fprintf fmt "<>" | EQMOD _ -> Format.fprintf fmt "eqmod" let pp_monom fmt (c,v) = let open Apron in if c = Coeff.s_of_int 1 then Format.fprintf fmt "%a" Var.print v else Format.fprintf fmt "%a%a" Coeff.print c Var.print v let plus_sep fmt () = Format.fprintf fmt "+" let print_list fmt l = let l = List.filter (fun (c,_) -> C.cmp c (C.s_of_int 0) <> 0) l in Format.pp_print_list ~pp_sep:plus_sep pp_monom fmt l let pp_print fmt (c:t) = let left = ref[] in let right = ref[] in let is_neg c = C.cmp c (C.s_of_int 0) < 0 in iter (fun c v -> if is_neg c then right := (C.neg c,v)::!right else left := (c,v)::!left ) c; let l = List.rev !left in let r = List.rev !right in let cst = get_cst c in let t = get_typ c in match l,r with | [],r -> Format.fprintf fmt "%a%a%a" print_list r print_typ (neg_typ t) C.print cst | l,[] -> Format.fprintf fmt "%a%a%a" print_list l print_typ t C.print (C.neg cst) | l,r -> if C.cmp cst (C.s_of_int 0) <> 0 then let neg = C.neg cst in Format.fprintf fmt "%a%a%a%s%a" print_list l print_typ t print_list r (if is_neg neg then "" else "+") C.print neg else Format.fprintf fmt "%a%a%a" print_list l print_typ t print_list r