Improved congruence, implemented RP, fixed whitespace.
This commit is contained in:
parent
5d3416bae9
commit
185f016303
9 changed files with 57 additions and 9 deletions
|
@ -21,7 +21,9 @@ let doit filename = begin
|
||||||
| "signs" -> SignIterator.iterate cfg
|
| "signs" -> SignIterator.iterate cfg
|
||||||
| "interval" -> IntervalIterator.iterate cfg
|
| "interval" -> IntervalIterator.iterate cfg
|
||||||
| "constants" -> ConstIterator.iterate cfg
|
| "constants" -> ConstIterator.iterate cfg
|
||||||
| _ -> ConstIterator.iterate cfg in
|
| "congruence" -> CongIterator.iterate cfg
|
||||||
|
| "product" -> RPIterator.iterate cfg
|
||||||
|
| _ -> failwith "No valid iterator specified" in
|
||||||
Format.printf "@[<v 0>Failed asserts :@ %a@]" pp_asserts f end
|
Format.printf "@[<v 0>Failed asserts :@ %a@]" pp_asserts f end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
open Naked
|
open Naked
|
||||||
open Abstract_syntax_tree
|
open Abstract_syntax_tree
|
||||||
|
|
||||||
module Congruence : NAKED_VALUE_DOMAIN = struct
|
module Congruence (*: NAKED_VALUE_DOMAIN*) = struct
|
||||||
type t = { multiple : Z.t; offset : Z.t }
|
type t = { multiple : Z.t; offset : Z.t }
|
||||||
|
|
||||||
let all_numbers = { multiple = Z.one; offset = Z.zero }
|
let all_numbers = { multiple = Z.one; offset = Z.zero }
|
||||||
|
@ -83,7 +83,9 @@ module Congruence : NAKED_VALUE_DOMAIN = struct
|
||||||
offset = Z.div z1.offset z2.offset;
|
offset = Z.div z1.offset z2.offset;
|
||||||
}
|
}
|
||||||
else all_numbers
|
else all_numbers
|
||||||
| AST_MODULO -> all_numbers
|
| AST_MODULO -> if (Z.equal z2.multiple Z.zero) && (Z.divisible z1.multiple z2.offset) then
|
||||||
|
const (Z.rem z1.offset z2.offset)
|
||||||
|
else all_numbers
|
||||||
|
|
||||||
let compatible z = function AST_EQUAL -> z | _ -> raise NeedTop
|
let compatible z = function AST_EQUAL -> z | _ -> raise NeedTop
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
open Naked
|
open Naked
|
||||||
open Abstract_syntax_tree
|
open Abstract_syntax_tree
|
||||||
|
|
||||||
module Interval : NAKED_VALUE_DOMAIN = struct
|
module Interval (*: NAKED_VALUE_DOMAIN*) = struct
|
||||||
type t = { lower : Z.t; upper : Z.t }
|
type t = { lower : Z.t; upper : Z.t }
|
||||||
|
|
||||||
let const a = { lower = a; upper = a }
|
let const a = { lower = a; upper = a }
|
||||||
|
|
|
@ -32,7 +32,7 @@ sig
|
||||||
val print: Format.formatter -> t -> unit
|
val print: Format.formatter -> t -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module AddTopBot (N : NAKED_VALUE_DOMAIN) : VALUE_DOMAIN =
|
module AddTopBot (N : NAKED_VALUE_DOMAIN) (*: VALUE_DOMAIN*) =
|
||||||
struct
|
struct
|
||||||
type t = Bot | Top | V of N.t
|
type t = Bot | Top | V of N.t
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ module ReducedProduct (C : CROSS_REDUCTION) : VALUE_DOMAIN = struct
|
||||||
(C.V.meet (fst p) (fst p')),
|
(C.V.meet (fst p) (fst p')),
|
||||||
(C.W.meet (snd p) (snd p')))
|
(C.W.meet (snd p) (snd p')))
|
||||||
|
|
||||||
(* we do NOTC.cross-reduce p : it would not guarantee convergence anymore *)
|
(* we do NOT cross-reduce p : it would not guarantee convergence anymore *)
|
||||||
let widen p p' = let p' = C.cr p' in C.V.widen (fst p) (fst p'), C.W.widen (snd p) (snd p')
|
let widen p p' = let p' = C.cr p' in C.V.widen (fst p) (fst p'), C.W.widen (snd p) (snd p')
|
||||||
let narrow p p' = let p' = C.cr p' in C.V.narrow (fst p) (fst p'), C.W.narrow (snd p) (snd p')
|
let narrow p p' = let p' = C.cr p' in C.V.narrow (fst p) (fst p'), C.W.narrow (snd p) (snd p')
|
||||||
|
|
||||||
|
@ -43,5 +43,6 @@ module ReducedProduct (C : CROSS_REDUCTION) : VALUE_DOMAIN = struct
|
||||||
C.V.subset (fst p) (fst p') && C.W.subset (snd p) (snd p')
|
C.V.subset (fst p) (fst p') && C.W.subset (snd p) (snd p')
|
||||||
let is_bottom p = (C.cr p) = bottom
|
let is_bottom p = (C.cr p) = bottom
|
||||||
let print fmt p =
|
let print fmt p =
|
||||||
Format.fprintf fmt "@[<h 0>(%a, %a)@]@ " C.V.print (fst p) C.W.print (snd p)
|
Format.fprintf fmt "@[<h 0>(%a, %a)@]" C.V.print (fst p) C.W.print (snd p)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ module NonRelational (V : VALUE_DOMAIN) : DOMAIN = struct
|
||||||
let print out env = match env with
|
let print out env = match env with
|
||||||
| Bot -> Format.fprintf out "@[<h 0>Bot@]"
|
| Bot -> Format.fprintf out "@[<h 0>Bot@]"
|
||||||
| E map -> begin Format.fprintf out "@[<h 0>{";
|
| E map -> begin Format.fprintf out "@[<h 0>{";
|
||||||
VMap.iter (fun varid val1 -> Format.fprintf out "%a : %a @ " Cfg_printer.print_var varid V.print val1) map;
|
VMap.iter (fun varid val1 -> Format.fprintf out "%a : %a@ " Cfg_printer.print_var varid V.print val1) map;
|
||||||
Format.fprintf out "}@]"; end
|
Format.fprintf out "}@]"; end
|
||||||
|
|
||||||
let rec compute e expr = match expr with
|
let rec compute e expr = match expr with
|
||||||
|
|
5
examples/congruence/congruence.c
Normal file
5
examples/congruence/congruence.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
void main() {
|
||||||
|
int x = rand(0, 10);
|
||||||
|
x = 2 * x;
|
||||||
|
assert(x % 2 == 0);
|
||||||
|
}
|
6
examples/congruence/congruence_mul.c
Normal file
6
examples/congruence/congruence_mul.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
void main() {
|
||||||
|
int x = rand(-4,8);
|
||||||
|
x = 2*x;
|
||||||
|
x = 3*x + 2;
|
||||||
|
assert(x % 6 == 2);
|
||||||
|
}
|
|
@ -93,9 +93,41 @@ open Sign
|
||||||
open Constant
|
open Constant
|
||||||
open Naked
|
open Naked
|
||||||
open Value_domain
|
open Value_domain
|
||||||
|
open Congruence
|
||||||
|
open Reduced_product
|
||||||
|
|
||||||
|
module IntervalxCongr : CROSS_REDUCTION = struct
|
||||||
|
module V = AddTopBot(Interval)
|
||||||
|
module W = AddTopBot(Congruence)
|
||||||
|
let cr (v,w) = match v,w with
|
||||||
|
| _, W.Bot | V.Bot, _ -> V.Bot, W.Bot
|
||||||
|
| V.Top, _ | _, W.Top -> v,w
|
||||||
|
| V.V i, W.V c -> match c.multiple with
|
||||||
|
| m when Z.equal Z.zero m -> if Z.leq i.lower c.offset && Z.leq c.offset i.upper then
|
||||||
|
V.V {lower=c.offset; upper=c.offset}, w
|
||||||
|
else
|
||||||
|
V.Bot, W.Bot
|
||||||
|
| m -> (* Non-trivial multiplier : can only hope refining the bounds *)
|
||||||
|
let q = Z.div (Z.sub i.upper c.offset) m in (*rounds towards zero*)
|
||||||
|
let q' = Z.div (Z.sub i.lower c.offset) m in
|
||||||
|
if Z.equal q' q then
|
||||||
|
let z = Z.add c.offset (Z.mul q' m) in
|
||||||
|
let newint = V.const z and
|
||||||
|
newmod = W.const z in newint, newmod
|
||||||
|
else (if Z.leq q' q then
|
||||||
|
let newint = V.rand (Z.add c.offset (Z.mul q' m))
|
||||||
|
(Z.add c.offset (Z.mul q m)) in
|
||||||
|
newint, w
|
||||||
|
else
|
||||||
|
V.Bot, W.Bot)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
module ConstIterator = Iterator(NonRelational(AddTopBot(Constants)))
|
module ConstIterator = Iterator(NonRelational(AddTopBot(Constants)))
|
||||||
module SignIterator = Iterator(NonRelational(AddTopBot(Signs)))
|
module SignIterator = Iterator(NonRelational(AddTopBot(Signs)))
|
||||||
module IntervalIterator = Iterator(NonRelational(AddTopBot(Interval)))
|
module IntervalIterator = Iterator(NonRelational(AddTopBot(Interval)))
|
||||||
|
module CongIterator = Iterator(NonRelational(AddTopBot(Congruence)))
|
||||||
|
module RPIterator = Iterator(NonRelational(ReducedProduct(IntervalxCongr)))
|
||||||
(*
|
(*
|
||||||
let iterate cfg =
|
let iterate cfg =
|
||||||
let () = Random.self_init () in
|
let () = Random.self_init () in
|
||||||
|
|
Loading…
Reference in a new issue