Skip to content
Snippets Groups Projects
Commit 52c031d1 authored by Julien Signoles's avatar Julien Signoles
Browse files

[interval] improve non-recursive logic functions case

parent 1cf3c003
No related branches found
No related tags found
No related merge requests found
...@@ -208,7 +208,7 @@ let rec infer t = ...@@ -208,7 +208,7 @@ let rec infer t =
let i2 = infer t2 in let i2 = infer t2 in
Ival.meet i1 i2 Ival.meet i1 i2
| Tapp (li, _, _args) -> | Tapp (li, _, args) ->
(match li.l_type with (match li.l_type with
| None -> assert false (* [None] only possible for predicates *) | None -> assert false (* [None] only possible for predicates *)
| Some Linteger -> | Some Linteger ->
...@@ -216,53 +216,47 @@ let rec infer t = ...@@ -216,53 +216,47 @@ let rec infer t =
| LBpred _ -> | LBpred _ ->
Ival.zero_or_one Ival.zero_or_one
| LBterm t' -> | LBterm t' ->
let i = (* TODO: should not be necessary to distinguish the recursive case.
if Misc.is_recursive li then Stack overflow if not distingued *)
(* 1) Build a system of interval equations that if Misc.is_recursive li then
constrain the solution: (* 1) Build a system of interval equations that constrain the
do so by returning a variable when encoutering solution: do so by returning a variable when encoutering a call
a call of a recursive function instead of of a recursive function instead of performing the usual interval
performing the usual interval inference inference BEWARE: we might be tempted to memoize the solution
BEWARE: we might be tempted to memoize the for a given function signature HOWEVER: it cannot be done in a
solution for a given function signature straightforward manner due to the cases of functions that use C
HOWEVER: it cannot be done in a straightforward (global) variables in their definition (as the values of those
manner due to the cases of functions that use variables can change between two function calls). *)
C (global) variables in their definition (as the values of let ieqs = Fixpoint.Ieqs.empty in
those variables can change between two function calls). *) let ivar, ieqs, _ = build_ieqs t ieqs [] in
let ieqs = Fixpoint.Ieqs.empty in (* 2) Solve it:
let ivar, ieqs, _ = build_ieqs t ieqs [] in The problem is probably undecidable in the general case.
(* 2) Solve it: Thus we just look for reasonably precise approximations
The problem is probably undecidable in the general case. without being too computationally expensive:
Thus we just look for reasonably precise approximations simply iterate over a finite set of pre-defined intervals.
without being too computationally expensive: See [Fixpoint.solve] for details. *)
simply iterate over a finite set of pre-defined intervals. let chain_of_ivalmax =
See [Fixpoint.solve] for details. *) [| Integer.one; Integer.billion_one; Integer.max_int64 |]
let chain_of_ivalmax = (* This set can be changed based on experimental evidences,
[| Integer.one; Integer.billion_one; Integer.max_int64 |] but it works fine for now. *)
(* This set can be changed based on experimental evidences, in
but it works fine for now. *) Fixpoint.solve ieqs ivar chain_of_ivalmax
in else begin (* non-recursive case *)
let i = Fixpoint.solve ieqs ivar chain_of_ivalmax in (* add the arguments to the context *)
i List.iter2
else begin (fun lv arg ->
List.iter2 try
(fun lv arg -> let i = infer arg in
try Env.add lv i
let i = interv_of_typ_containing_interv (infer arg) in with Not_an_integer ->
Env.add lv i ())
with Not_an_integer -> li.l_profile
()) args;
li.l_profile let i = infer t' in
_args; (* remove arguments from the context *)
let i = List.iter (fun lv -> Env.remove lv) li.l_profile;
try infer t' i
with Not_an_integer -> Ival.inject_range None None end
in
List.iter (fun lv -> Env.remove lv) li.l_profile;
i
end
in
i
| LBnone -> | LBnone ->
Error.not_yet "logic functions with no definition nor reads clause" Error.not_yet "logic functions with no definition nor reads clause"
| LBreads _ -> | LBreads _ ->
......
...@@ -20,7 +20,7 @@ typedef struct mystruct mystruct; ...@@ -20,7 +20,7 @@ typedef struct mystruct mystruct;
/*@ logic mystruct t1(mystruct m) = m; */ /*@ logic mystruct t1(mystruct m) = m; */
/*@ logic integer t2(mystruct m) = m.k + m.l; */ /*@ logic integer t2(mystruct m) = m.k + m.l; */
// To test function call in other than assert: // To test function call in other clauses than assert:
/*@ predicate k_pred(integer x) = x > 0; */ /*@ predicate k_pred(integer x) = x > 0; */
/*@ requires k_pred(x); */ /*@ requires k_pred(x); */
void k(int x) {} void k(int x) {}
...@@ -68,4 +68,4 @@ int main (void) { ...@@ -68,4 +68,4 @@ int main (void) {
/*@ assert f2(d) > 0; */ ; /*@ assert f2(d) > 0; */ ;
/*@ assert p_notyet(27); */ ; /*@ assert p_notyet(27); */ ;
/*@ assert f_notyet(27) == 27; */ ; /*@ assert f_notyet(27) == 27; */ ;
} }
\ No newline at end of file
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
[eva] using specification for function __gmpz_clear [eva] using specification for function __gmpz_clear
[eva:alarm] tests/gmp/functions.c:44: Warning: [eva:alarm] tests/gmp/functions.c:44: Warning:
function __e_acsl_assert: precondition got status unknown. function __e_acsl_assert: precondition got status unknown.
[eva:alarm] tests/gmp/functions.c:47: Warning:
function __e_acsl_assert: precondition got status unknown.
[eva:alarm] tests/gmp/functions.c:48: Warning: [eva:alarm] tests/gmp/functions.c:48: Warning:
accessing uninitialized left-value. accessing uninitialized left-value.
assert \initialized((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3); assert \initialized((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3);
......
...@@ -17,19 +17,19 @@ int __gen_e_acsl_p1(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg); ...@@ -17,19 +17,19 @@ int __gen_e_acsl_p1(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg);
*/ */
int __gen_e_acsl_p2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg); int __gen_e_acsl_p2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg);
int __gen_e_acsl_p2_3(int __gen_e_acsl_x_arg, long __gen_e_acsl_y_arg);
int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg, int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg); __e_acsl_mpz_struct * __gen_e_acsl_y_arg);
/*@ logic ℤ f1(ℤ x, ℤ y) = x + y; /*@ logic ℤ f1(ℤ x, ℤ y) = x + y;
*/ */
void __gen_e_acsl_f1_3(__e_acsl_mpz_struct * __retres_arg, void __gen_e_acsl_f1_4(__e_acsl_mpz_struct * __retres_arg,
__e_acsl_mpz_struct * __gen_e_acsl_x_arg, __e_acsl_mpz_struct * __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg); __e_acsl_mpz_struct * __gen_e_acsl_y_arg);
void __gen_e_acsl_f1_2(__e_acsl_mpz_struct * __retres_arg, int __gen_e_acsl_f1_2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg);
void __gen_e_acsl_f1_3(__e_acsl_mpz_struct * __retres_arg,
int __gen_e_acsl_x_arg, int __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg); __e_acsl_mpz_struct * __gen_e_acsl_y_arg);
...@@ -126,59 +126,59 @@ int main(void) ...@@ -126,59 +126,59 @@ int main(void)
} }
/*@ assert p2(x, f1(3, 4)); */ /*@ assert p2(x, f1(3, 4)); */
{ {
long __gen_e_acsl_f1_tapp_2; int __gen_e_acsl_f1_tapp_2;
int __gen_e_acsl_p2_tapp_3; int __gen_e_acsl_p2_tapp_3;
__gen_e_acsl_f1_tapp_2 = __gen_e_acsl_f1(3,4); __gen_e_acsl_f1_tapp_2 = __gen_e_acsl_f1_2(3,4);
__gen_e_acsl_p2_tapp_3 = __gen_e_acsl_p2_3(x,__gen_e_acsl_f1_tapp_2); __gen_e_acsl_p2_tapp_3 = __gen_e_acsl_p2(x,__gen_e_acsl_f1_tapp_2);
__e_acsl_assert(__gen_e_acsl_p2_tapp_3,(char *)"Assertion", __e_acsl_assert(__gen_e_acsl_p2_tapp_3,(char *)"Assertion",
(char *)"main",(char *)"p2(x, f1(3, 4))",47); (char *)"main",(char *)"p2(x, f1(3, 4))",47);
} }
/*@ assert f1(9, 99999999999999999999999999999) > 0; */ /*@ assert f1(9, 99999999999999999999999999999) > 0; */
{ {
__e_acsl_mpz_t __gen_e_acsl__4; __e_acsl_mpz_t __gen_e_acsl__3;
__e_acsl_mpz_t __gen_e_acsl_f1_tapp_3; __e_acsl_mpz_t __gen_e_acsl_f1_tapp_3;
__e_acsl_mpz_t __gen_e_acsl__5; __e_acsl_mpz_t __gen_e_acsl__4;
int __gen_e_acsl_gt_3; int __gen_e_acsl_gt_2;
__gmpz_init_set_str(__gen_e_acsl__4,"99999999999999999999999999999",10); __gmpz_init_set_str(__gen_e_acsl__3,"99999999999999999999999999999",10);
__gmpz_init(__gen_e_acsl_f1_tapp_3); __gmpz_init(__gen_e_acsl_f1_tapp_3);
/*@ assert /*@ assert
Eva: initialization: Eva: initialization:
\initialized((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3); \initialized((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3);
*/ */
__gen_e_acsl_f1_2((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3,9, __gen_e_acsl_f1_3((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_3,9,
(__e_acsl_mpz_struct *)__gen_e_acsl__4); (__e_acsl_mpz_struct *)__gen_e_acsl__3);
__gmpz_init_set_si(__gen_e_acsl__5,0L); __gmpz_init_set_si(__gen_e_acsl__4,0L);
__gen_e_acsl_gt_3 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_tapp_3), __gen_e_acsl_gt_2 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_tapp_3),
(__e_acsl_mpz_struct const *)(__gen_e_acsl__5)); (__e_acsl_mpz_struct const *)(__gen_e_acsl__4));
__e_acsl_assert(__gen_e_acsl_gt_3 > 0,(char *)"Assertion",(char *)"main", __e_acsl_assert(__gen_e_acsl_gt_2 > 0,(char *)"Assertion",(char *)"main",
(char *)"f1(9, 99999999999999999999999999999) > 0",48); (char *)"f1(9, 99999999999999999999999999999) > 0",48);
__gmpz_clear(__gen_e_acsl__4); __gmpz_clear(__gen_e_acsl__3);
__gmpz_clear(__gen_e_acsl_f1_tapp_3); __gmpz_clear(__gen_e_acsl_f1_tapp_3);
__gmpz_clear(__gen_e_acsl__5); __gmpz_clear(__gen_e_acsl__4);
} }
/*@ assert /*@ assert
f1(99999999999999999999999999999, 99999999999999999999999999999) ≡ f1(99999999999999999999999999999, 99999999999999999999999999999) ≡
199999999999999999999999999998; 199999999999999999999999999998;
*/ */
{ {
__e_acsl_mpz_t __gen_e_acsl__6; __e_acsl_mpz_t __gen_e_acsl__5;
__e_acsl_mpz_t __gen_e_acsl_f1_tapp_4; __e_acsl_mpz_t __gen_e_acsl_f1_tapp_4;
__e_acsl_mpz_t __gen_e_acsl__7; __e_acsl_mpz_t __gen_e_acsl__6;
int __gen_e_acsl_eq; int __gen_e_acsl_eq;
__gmpz_init_set_str(__gen_e_acsl__6,"99999999999999999999999999999",10); __gmpz_init_set_str(__gen_e_acsl__5,"99999999999999999999999999999",10);
__gmpz_init(__gen_e_acsl_f1_tapp_4); __gmpz_init(__gen_e_acsl_f1_tapp_4);
__gen_e_acsl_f1_3((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_4, __gen_e_acsl_f1_4((__e_acsl_mpz_struct *)__gen_e_acsl_f1_tapp_4,
(__e_acsl_mpz_struct *)__gen_e_acsl__6, (__e_acsl_mpz_struct *)__gen_e_acsl__5,
(__e_acsl_mpz_struct *)__gen_e_acsl__6); (__e_acsl_mpz_struct *)__gen_e_acsl__5);
__gmpz_init_set_str(__gen_e_acsl__7,"199999999999999999999999999998",10); __gmpz_init_set_str(__gen_e_acsl__6,"199999999999999999999999999998",10);
__gen_e_acsl_eq = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_tapp_4), __gen_e_acsl_eq = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_f1_tapp_4),
(__e_acsl_mpz_struct const *)(__gen_e_acsl__7)); (__e_acsl_mpz_struct const *)(__gen_e_acsl__6));
__e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main", __e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main",
(char *)"f1(99999999999999999999999999999, 99999999999999999999999999999) ==\n199999999999999999999999999998", (char *)"f1(99999999999999999999999999999, 99999999999999999999999999999) ==\n199999999999999999999999999998",
49); 49);
__gmpz_clear(__gen_e_acsl__6); __gmpz_clear(__gen_e_acsl__5);
__gmpz_clear(__gen_e_acsl_f1_tapp_4); __gmpz_clear(__gen_e_acsl_f1_tapp_4);
__gmpz_clear(__gen_e_acsl__7); __gmpz_clear(__gen_e_acsl__6);
} }
/*@ assert g(x) ≡ x; */ /*@ assert g(x) ≡ x; */
{ {
...@@ -309,51 +309,58 @@ long __gen_e_acsl_f1(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg) ...@@ -309,51 +309,58 @@ long __gen_e_acsl_f1(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg)
return __retres; return __retres;
} }
void __gen_e_acsl_f1_2(__e_acsl_mpz_struct * __retres_arg, void __gen_e_acsl_f1_3(__e_acsl_mpz_struct * __retres_arg,
int __gen_e_acsl_x_arg, int __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg) __e_acsl_mpz_struct * __gen_e_acsl_y_arg)
{ {
__e_acsl_mpz_t __gen_e_acsl_y_3; __e_acsl_mpz_t __gen_e_acsl_y_2;
__e_acsl_mpz_t __gen_e_acsl_x_2;
__e_acsl_mpz_t __gen_e_acsl_add_2;
__gmpz_init_set(__gen_e_acsl_y_2,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_arg));
__gmpz_init_set_si(__gen_e_acsl_x_2,(long)__gen_e_acsl_x_arg);
__gmpz_init(__gen_e_acsl_add_2);
__gmpz_add(__gen_e_acsl_add_2,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_2),
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_2));
__gmpz_init_set(__retres_arg,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_add_2));
__gmpz_clear(__gen_e_acsl_y_2);
__gmpz_clear(__gen_e_acsl_x_2);
__gmpz_clear(__gen_e_acsl_add_2);
return;
}
int __gen_e_acsl_f1_2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg)
{
long __retres;
__retres = (int)(__gen_e_acsl_x_arg + (long)__gen_e_acsl_y_arg);
return __retres;
}
void __gen_e_acsl_f1_4(__e_acsl_mpz_struct * __retres_arg,
__e_acsl_mpz_struct * __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg)
{
__e_acsl_mpz_t __gen_e_acsl_x_3; __e_acsl_mpz_t __gen_e_acsl_x_3;
__e_acsl_mpz_t __gen_e_acsl_y_3;
__e_acsl_mpz_t __gen_e_acsl_add_3; __e_acsl_mpz_t __gen_e_acsl_add_3;
__gmpz_init_set(__gen_e_acsl_x_3,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_arg));
__gmpz_init_set(__gen_e_acsl_y_3, __gmpz_init_set(__gen_e_acsl_y_3,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_arg)); (__e_acsl_mpz_struct const *)(__gen_e_acsl_y_arg));
__gmpz_init_set_si(__gen_e_acsl_x_3,(long)__gen_e_acsl_x_arg);
__gmpz_init(__gen_e_acsl_add_3); __gmpz_init(__gen_e_acsl_add_3);
__gmpz_add(__gen_e_acsl_add_3, __gmpz_add(__gen_e_acsl_add_3,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_3), (__e_acsl_mpz_struct const *)(__gen_e_acsl_x_3),
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_3)); (__e_acsl_mpz_struct const *)(__gen_e_acsl_y_3));
__gmpz_init_set(__retres_arg, __gmpz_init_set(__retres_arg,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_add_3)); (__e_acsl_mpz_struct const *)(__gen_e_acsl_add_3));
__gmpz_clear(__gen_e_acsl_y_3);
__gmpz_clear(__gen_e_acsl_x_3); __gmpz_clear(__gen_e_acsl_x_3);
__gmpz_clear(__gen_e_acsl_y_3);
__gmpz_clear(__gen_e_acsl_add_3); __gmpz_clear(__gen_e_acsl_add_3);
return; return;
} }
void __gen_e_acsl_f1_3(__e_acsl_mpz_struct * __retres_arg,
__e_acsl_mpz_struct * __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg)
{
__e_acsl_mpz_t __gen_e_acsl_x_4;
__e_acsl_mpz_t __gen_e_acsl_y_4;
__e_acsl_mpz_t __gen_e_acsl_add_4;
__gmpz_init_set(__gen_e_acsl_x_4,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_arg));
__gmpz_init_set(__gen_e_acsl_y_4,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_arg));
__gmpz_init(__gen_e_acsl_add_4);
__gmpz_add(__gen_e_acsl_add_4,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_4),
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_4));
__gmpz_init_set(__retres_arg,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_add_4));
__gmpz_clear(__gen_e_acsl_x_4);
__gmpz_clear(__gen_e_acsl_y_4);
__gmpz_clear(__gen_e_acsl_add_4);
return;
}
int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg, int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg,
__e_acsl_mpz_struct * __gen_e_acsl_y_arg) __e_acsl_mpz_struct * __gen_e_acsl_y_arg)
{ {
...@@ -380,31 +387,6 @@ int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg, ...@@ -380,31 +387,6 @@ int __gen_e_acsl_p2_2(int __gen_e_acsl_x_arg,
return __retres; return __retres;
} }
int __gen_e_acsl_p2_3(int __gen_e_acsl_x_arg, long __gen_e_acsl_y_arg)
{
int __retres;
__e_acsl_mpz_t __gen_e_acsl_x_2;
__e_acsl_mpz_t __gen_e_acsl_y_2;
__e_acsl_mpz_t __gen_e_acsl_add_2;
__e_acsl_mpz_t __gen_e_acsl__3;
int __gen_e_acsl_gt_2;
__gmpz_init_set_si(__gen_e_acsl_x_2,(long)__gen_e_acsl_x_arg);
__gmpz_init_set_si(__gen_e_acsl_y_2,__gen_e_acsl_y_arg);
__gmpz_init(__gen_e_acsl_add_2);
__gmpz_add(__gen_e_acsl_add_2,
(__e_acsl_mpz_struct const *)(__gen_e_acsl_x_2),
(__e_acsl_mpz_struct const *)(__gen_e_acsl_y_2));
__gmpz_init_set_si(__gen_e_acsl__3,0L);
__gen_e_acsl_gt_2 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl_add_2),
(__e_acsl_mpz_struct const *)(__gen_e_acsl__3));
__retres = __gen_e_acsl_gt_2 > 0;
__gmpz_clear(__gen_e_acsl_x_2);
__gmpz_clear(__gen_e_acsl_y_2);
__gmpz_clear(__gen_e_acsl_add_2);
__gmpz_clear(__gen_e_acsl__3);
return __retres;
}
int __gen_e_acsl_p2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg) int __gen_e_acsl_p2(int __gen_e_acsl_x_arg, int __gen_e_acsl_y_arg)
{ {
int __retres; int __retres;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment