Skip to content

Commit 71309a0

Browse files
committed
S906-017 merge AdaCore master with upstream next branch
To get fix for soundness issue OCamlPro#248 Change-Id: I853a3d577919dc360e4839474d8b4daa1a5106fd
2 parents 06fe444 + 5f5a776 commit 71309a0

File tree

8 files changed

+84
-25
lines changed

8 files changed

+84
-25
lines changed

extra/test_lib.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ocamlopt -o lib_usage \
2727
-I `ocamlfind query zarith` \
2828
-I `ocamlfind query ocplib-simplex` \
2929
-I `ocamlfind query psmt2-frontend` \
30-
-I `ocamlfind query camlzip` \
30+
-I `ocamlfind query zip` \
3131
-I $lib_path \
3232
nums.cmxa zarith.cmxa ocplibSimplex.cmxa psmt2Frontend.cmxa \
3333
unix.cmxa str.cmxa zip.cmxa dynlink.cmxa \

sources/alt-ergo-parsers.opam

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ depends: [
1414
"dune" { build }
1515
"alt-ergo-lib" { = "2.3.0+" }
1616
"psmt2-frontend" { >= "0.2" }
17-
"camlzip"
17+
"camlzip" { >= "1.07" }
1818
"menhir"
1919
]
2020
homepage: "http://alt-ergo.ocamlpro.com/"

sources/lib/reasoners/instances.ml

+13-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,19 @@ end
6969

7070
module Make(X : Theory.S) : S with type tbox = X.t = struct
7171

72-
module EM = Matching.Make(Ccx.Main)
72+
module EM = Matching.Make(struct
73+
74+
include Ccx.Main
75+
76+
(* This function from Ccx.Main is wrapped to ensure Fresh explanations
77+
will not leak through Ccx during matching, in which case assertions
78+
in various places will be raised. *)
79+
let term_repr t e ~init_term =
80+
try Ccx.Main.term_repr t ~init_term e
81+
with Ex.Inconsistent (d, _) as exn ->
82+
if Ex.exists_fresh d then e else raise exn
83+
84+
end)
7385

7486
type tbox = X.t
7587
type instances = (Expr.gformula * Ex.t) list

sources/lib/reasoners/intervalCalculus.ml

+25-8
Original file line numberDiff line numberDiff line change
@@ -402,26 +402,33 @@ end
402402
normalized polys *)
403403
let generic_find xp env =
404404
let is_mon = is_alien xp in
405+
if debug_fm () then
406+
fprintf fmt "generic_find: %a ... " X.print xp;
405407
try
406408
if not is_mon then raise Not_found;
407-
let i, use = MX.n_find xp env.monomes in i, use, is_mon
409+
let i, use = MX.n_find xp env.monomes in
410+
if debug_fm () then fprintf fmt "found@.";
411+
i, use, is_mon
408412
with Not_found ->
409413
(* according to this implem, it means that we can find aliens in polys
410414
but not in monomes. FIX THIS => an interval of x in monomes and in
411415
polys may be differents !!! *)
416+
if debug_fm () then
417+
fprintf fmt "not_found@.";
412418
let p0 = poly_of xp in
413419
let p, c = P.separate_constant p0 in
414420
let p, c0, d = P.normal_form_pos p in
421+
if debug_fm() then
422+
fprintf fmt "normalized into %a + %a * %a@."
423+
Q.print c Q.print d P.print p;
415424
assert (Q.sign d <> 0 && Q.sign c0 = 0);
416425
let ty = P.type_info p0 in
417426
let ip =
418427
try MP.n_find p env.polynomes with Not_found -> I.undefined ty
419428
in
420-
let ip = if Q.is_one d then ip else I.scale d ip in
421-
let ip =
422-
if Q.is_zero c then ip
423-
else I.add ip (I.point c ty Explanation.empty)
424-
in
429+
if debug_fm() then
430+
fprintf fmt "scaling %a by %a@." I.print ip Q.print d;
431+
let ip = I.affine_scale ~const:c ~coef:d ip in
425432
ip, SX.empty, is_mon
426433

427434

@@ -515,13 +522,21 @@ module Debug = struct
515522
fprintf fmt "\t0@.@."
516523
end
517524

518-
let tighten_interval_modulo_eq p1 p2 i1 i2 b1 b2 j =
525+
let tighten_interval_modulo_eq_begin p1 p2 =
519526
if debug_fm () then begin
520527
fprintf fmt "@.[fm] tighten intervals modulo eq: %a = %a@."
521528
P.print p1 P.print p2;
529+
end
530+
531+
let tighten_interval_modulo_eq_middle p1 p2 i1 i2 j =
532+
if debug_fm () then begin
522533
fprintf fmt " %a has interval %a@." P.print p1 I.print i1;
523534
fprintf fmt " %a has interval %a@." P.print p2 I.print i2;
524535
fprintf fmt " intersection is %a@." I.print j;
536+
end
537+
538+
let tighten_interval_modulo_eq_end p1 p2 b1 b2 =
539+
if debug_fm () then begin
525540
if b1 then fprintf fmt " > improve interval of %a@.@." P.print p1;
526541
if b2 then fprintf fmt " > improve interval of %a@.@." P.print p2;
527542
if not b1 && not b2 then fprintf fmt " > no improvement@.@."
@@ -1384,12 +1399,14 @@ let tighten_eq_bounds env r1 r2 p1 p2 origin_eq expl =
13841399
| Th_util.CS _ | Th_util.NCS _ -> env
13851400
| Th_util.Subst | Th_util.Other ->
13861401
(* Subst is needed, but is Other needed ?? or is it subsumed ? *)
1402+
Debug.tighten_interval_modulo_eq_begin p1 p2;
13871403
let i1, us1, is_mon_1 = generic_find r1 env in
13881404
let i2, us2, is_mon_2 = generic_find r2 env in
13891405
let j = I.add_explanation (I.intersect i1 i2) expl in
1406+
Debug.tighten_interval_modulo_eq_middle p1 p2 i1 i2 j;
13901407
let impr_i1 = I.is_strict_smaller j i1 in
13911408
let impr_i2 = I.is_strict_smaller j i2 in
1392-
Debug.tighten_interval_modulo_eq p1 p2 i1 i2 impr_i1 impr_i2 j;
1409+
Debug.tighten_interval_modulo_eq_end p1 p2 impr_i1 impr_i2;
13931410
let env =
13941411
if impr_i1 then generic_add r1 j us1 is_mon_1 env else env
13951412
in

sources/lib/reasoners/intervals.ml

+28-14
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,23 @@ let exclude =
445445
let uints1_c = union_intervals {uints1 with ints = l_c} in
446446
intersect uints1_c uints2
447447

448+
let add_borne b1 b2 =
449+
match b1,b2 with
450+
| Minfty, Pinfty | Pinfty, Minfty -> assert false
451+
| Minfty, _ | _, Minfty -> Minfty
452+
| Pinfty, _ | _, Pinfty -> Pinfty
453+
| Large (v1, e1), Large (v2, e2) ->
454+
Large (Q.add v1 v2, Ex.union e1 e2)
455+
| (Large (v1, e1) | Strict (v1, e1)), (Large (v2, e2) | Strict (v2, e2)) ->
456+
Strict (Q.add v1 v2, Ex.union e1 e2)
457+
458+
let translate c ((b1, b2) as b) =
459+
if Q.(equal zero) c then b
460+
else begin
461+
let tmp = Large (c, Ex.empty) in
462+
(add_borne b1 tmp, add_borne b2 tmp)
463+
end
464+
448465
let scale_interval_zero n (b1, b2) =
449466
assert (Q.sign n = 0);
450467
Large (Q.zero, explain_borne b1), Large (Q.zero, explain_borne b2)
@@ -463,34 +480,31 @@ let scale_interval_neg n (b1, b2) =
463480
minus_borne (scale_borne_non_zero (Q.minus n) b2),
464481
minus_borne (scale_borne_non_zero (Q.minus n) b1)
465482

466-
let scale n uints =
483+
484+
let affine_scale ~const ~coef uints =
467485
Options.tool_req 4 "TR-Arith-Axiomes scale";
468-
if Q.equal n Q.one then uints
486+
if Q.equal coef Q.one then
487+
{ uints with ints = List.map (translate const) uints.ints; }
469488
else
470-
let sgn = Q.sign n in
489+
let sgn = Q.sign coef in
471490
let aux =
472491
if sgn = 0 then scale_interval_zero
473492
else if sgn > 0 then scale_interval_pos
474493
else scale_interval_neg
475494
in
476-
let rl = List.rev_map (aux n) uints.ints in
495+
let rl = List.rev_map (fun bornes ->
496+
translate const (aux coef bornes)
497+
) uints.ints in
477498
let l =
478-
if uints.is_int then rev_normalize_int_bounds rl uints.expl n
499+
if uints.is_int then rev_normalize_int_bounds rl uints.expl coef
479500
else List.rev rl
480501
in
481502
let res = union_intervals { uints with ints = l } in
482503
assert (res.ints != []);
483504
res
484505

485-
let add_borne b1 b2 =
486-
match b1,b2 with
487-
| Minfty, Pinfty | Pinfty, Minfty -> assert false
488-
| Minfty, _ | _, Minfty -> Minfty
489-
| Pinfty, _ | _, Pinfty -> Pinfty
490-
| Large (v1, e1), Large (v2, e2) ->
491-
Large (Q.add v1 v2, Ex.union e1 e2)
492-
| (Large (v1, e1) | Strict (v1, e1)), (Large (v2, e2) | Strict (v2, e2)) ->
493-
Strict (Q.add v1 v2, Ex.union e1 e2)
506+
let scale coef uints =
507+
affine_scale ~const:Q.zero ~coef uints
494508

495509
let add_interval is_int l (b1,b2) =
496510
List.fold_right

sources/lib/reasoners/intervals.mli

+7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ val add : t -> t -> t
6565

6666
val scale : Numbers.Q.t -> t -> t
6767

68+
val affine_scale : const:Numbers.Q.t -> coef:Numbers.Q.t -> t -> t
69+
(** Perform an affine transformation on the given bounds.
70+
Suposing input bounds (b1, b2), this will return
71+
(const + coef * b1, const + coef * b2).
72+
This function is useful to avoid the incorrect roundings that
73+
can take place when scaling down an integer range. *)
74+
6875
val sub : t -> t -> t
6976

7077
val merge : t -> t -> t

sources/lib/structures/explanation.ml

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ let fresh_exp =
9494
incr r;
9595
Fresh !r
9696

97+
let exists_fresh t =
98+
S.exists (function
99+
| Fresh _ -> true
100+
| _ -> false
101+
) t
102+
97103
let remove_fresh fe s =
98104
if S.mem fe s then Some (S.remove fe s)
99105
else None

sources/lib/structures/explanation.mli

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ val fold_atoms : (exp -> 'a -> 'a ) -> t -> 'a -> 'a
5555

5656
val fresh_exp : unit -> exp
5757

58+
val exists_fresh : t -> bool
59+
(** Does there exists a [Fresh _] exp in an explanation set. *)
60+
5861
val remove_fresh : exp -> t -> t option
5962

6063
val remove : exp -> t -> t

0 commit comments

Comments
 (0)