[kernel] Parsing share/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing tests/spec/acsl_by_example.c (with preprocessing)
tests/spec/acsl_by_example.c:3:[kernel] warning: parsing obsolete ACSL construct '\valid_range(addr,min,max)'. '\valid(addr+(min..max))' should be used instead.
tests/spec/acsl_by_example.c:5:[kernel] warning: parsing obsolete ACSL construct '\valid_range(addr,min,max)'. '\valid(addr+(min..max))' should be used instead.
/* Generated by Frama-C */
/*@
predicate is_valid_int_range{L}(int *p, int n) =
  \at(0 ≤ n ∧ \valid{L}(p+(0 .. n-1)),L);
 */
/*@
lemma foo{L}:
  ∀ int *p, int n; is_valid_int_range{L}(p, n) ⇔ \valid{L}(p+(0 .. n-1));
 */
/*@ requires is_valid_int_range(a, n);
    requires is_valid_int_range(b, n);
    assigns \nothing;
    
    behavior all_equal:
      assumes ∀ int i; 0 ≤ i < n ⇒ *(a+i) ≡ *(b+i);
      ensures \result ≡ 1;
    
    behavior some_not_equal:
      assumes ∃ int i; 0 ≤ i < n ∧ *(a+i) ≢ *(b+i);
      ensures \result ≡ 0;
    
    complete behaviors all_equal, some_not_equal;
    disjoint behaviors all_equal, some_not_equal;
 */
int equal(int const *a, int n, int const *b)
{
  int __retres;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≡ *(b+k);
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) != *(b + i)) {
        __retres = 0;
        goto return_label;
      }
      i ++;
    }
  }
  __retres = 1;
  return_label: return __retres;
}

/*@ requires is_valid_int_range(a, n);
    assigns \nothing;
    
    behavior some:
      assumes ∃ int i; 0 ≤ i < n ∧ *(a+i) ≡ val;
      ensures 0 ≤ \result < \old(n);
      ensures *(\old(a)+\result) ≡ \old(val);
      ensures ∀ int i; 0 ≤ i < \result ⇒ *(\old(a)+i) ≢ \old(val);
    
    behavior none:
      assumes ∀ int i; 0 ≤ i < n ⇒ *(a+i) ≢ val;
      ensures \result ≡ \old(n);
    
    complete behaviors some, none;
    disjoint behaviors some, none;
 */
int find(int const *a, int n, int val)
{
  int __retres;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≢ val;
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) == val) {
        __retres = i;
        goto return_label;
      }
      i ++;
    }
  }
  __retres = n;
  return_label: return __retres;
}

/*@
predicate found{A}(int *a, int n, int val) =
  ∃ int i; 0 ≤ i < n ∧ *(a+i) ≡ val;

*/
/*@ requires is_valid_int_range(a, n);
    assigns \nothing;
    
    behavior some:
      assumes found(a, n, val);
      ensures 0 ≤ \result < \old(n);
      ensures *(\old(a)+\result) ≡ \old(val);
      ensures ¬found(\old(a), \result, \old(val));
    
    behavior none:
      assumes ¬found(a, n, val);
      ensures \result ≡ \old(n);
    
    complete behaviors some, none;
    disjoint behaviors some, none;
 */
int find2(int const *a, int n, int val)
{
  int __retres;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant ¬found(a, i, val);
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) == val) {
        __retres = i;
        goto return_label;
      }
      i ++;
    }
  }
  __retres = n;
  return_label: return __retres;
}

/*@
predicate found_first_of{A}(int *a, int m, int *b, int n) =
  ∃ int i; 0 ≤ i < m ∧ found{A}(b, n, \at(*(a+i),A));

*/
/*@ requires is_valid_int_range(a, m);
    requires is_valid_int_range(b, n);
    assigns \nothing;
    
    behavior found:
      assumes found_first_of(a, m, b, n);
      ensures 0 ≤ \result < \old(m);
      ensures found(\old(b), \old(n), *(\old(a)+\result));
      ensures ¬found_first_of(\old(a), \result, \old(b), \old(n));
    
    behavior not_found:
      assumes ¬found_first_of(a, m, b, n);
      ensures \result ≡ \old(m);
    
    complete behaviors found, not_found;
    disjoint behaviors found, not_found;
 */
int find_first_of(int const *a, int m, int const *b, int n)
{
  int __retres;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ m;
        loop invariant ¬found_first_of(a, i, b, n);
        loop variant m-i;
    */
    while (i < m) {
      int tmp;
      { /* sequence */
        tmp = find(b,n,*(a + i));
        ;
      }
      if (tmp < n) {
        __retres = i;
        goto return_label;
      }
      i ++;
    }
  }
  __retres = m;
  return_label: return __retres;
}

/*@ requires is_valid_int_range(a, n);
    assigns \nothing;
    
    behavior empty:
      assumes n ≡ 0;
      ensures \result ≡ 0;
    
    behavior not_empty:
      assumes 0 < n;
      ensures 0 ≤ \result < \old(n);
      ensures
        ∀ int i; 0 ≤ i < \old(n) ⇒ *(\old(a)+i) ≤ *(\old(a)+\result);
      ensures
        ∀ int i; 0 ≤ i < \result ⇒ *(\old(a)+i) < *(\old(a)+\result);
    
    complete behaviors empty, not_empty;
    disjoint behaviors empty, not_empty;
 */
int max_element(int const *a, int n)
{
  int __retres;
  int max;
  if (n == 0) {
    __retres = 0;
    goto return_label;
  }
  max = 0;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant 0 ≤ max < n;
        loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≤ *(a+max);
        loop invariant ∀ int k; 0 ≤ k < max ⇒ *(a+k) < *(a+max);
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + max) < *(a + i)) max = i;
      i ++;
    }
  }
  __retres = max;
  return_label: return __retres;
}

/*@ requires n > 0;
    requires \valid(p+(0 .. n-1));
    ensures ∀ int i; 0 ≤ i ≤ \old(n)-1 ⇒ \result ≥ *(\old(p)+i);
    ensures ∃ int e; 0 ≤ e ≤ \old(n)-1 ∧ \result ≡ *(\old(p)+e);
    assigns \nothing;
 */
int max_seq(int const *p, int n)
{
  int __retres;
  int tmp;
  { /* sequence */
    tmp = max_element(p,n);
    ;
  }
  __retres = *(p + tmp);
  return __retres;
}

/*@
axiomatic counting_axioms {
  logic ℤ counting{L}(int *a, ℤ n, int val) 
    reads *(a+(0 .. n-1));
  
  axiom counting_empty{L}:
    ∀ int *a, ℤ n, int val; n ≤ 0 ⇒ counting{L}(a, n, val) ≡ 0;
  
  axiom counting_hit{L}:
    ∀ int *a, ℤ n, int val;
      n ≥ 0 ∧ *(a+n) ≡ val ⇒
      counting{L}(a, n+1, val) ≡ counting{L}(a, n, val)+1;
  
  axiom counting_miss{L}:
    ∀ int *a, ℤ n, int val;
      n ≥ 0 ∧ *(a+n) ≢ val ⇒
      counting{L}(a, n+1, val) ≡ counting{L}(a, n, val);
  
  }

*/
/*@ requires is_valid_int_range(a, n);
    ensures \result ≡ counting(\old(a), \old(n), \old(val));
    assigns \nothing;
 */
int count(int const *a, int n, int val)
{
  int cnt;
  cnt = 0;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant 0 ≤ cnt ≤ i;
        loop invariant cnt ≡ counting(a, i, val);
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) == val) cnt ++;
      i ++;
    }
  }
  return cnt;
}

/*@ requires \valid(p);
    requires \valid(q);
    ensures *\old(p) ≡ \old(*q);
    ensures *\old(q) ≡ \old(*p);
    assigns *p, *q;
 */
void swap(int *p, int *q)
{
  int save;
  save = *p;
  *p = *q;
  *q = save;
  return;
}

/*@ requires is_valid_int_range(a, n);
    requires is_valid_int_range(b, n);
    ensures ∀ int k; 0 ≤ k < \old(n) ⇒ *(\old(a)+k) ≡ \old(*(b+k));
    ensures ∀ int k; 0 ≤ k < \old(n) ⇒ *(\old(b)+k) ≡ \old(*(a+k));
    assigns *(a+(0 .. n-1)), *(b+(0 .. n-1));
 */
void swap_ranges(int *a, int n, int *b)
{
  int i;
  i = 0;
  /*@ loop invariant 0 ≤ i ≤ n;
      loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≡ \at(*(b+k),Pre);
      loop invariant ∀ int k; 0 ≤ k < i ⇒ *(b+k) ≡ \at(*(a+k),Pre);
      loop assigns *(a+(0 .. i-1)), *(b+(0 .. i-1));
      loop variant n-i;
  */
  while (i < n) {
    swap(a + i,b + i);
    i ++;
  }
  return;
}

/*@ requires is_valid_int_range(a, n);
    ensures ∀ int i; 0 ≤ i < \old(n) ⇒ *(\old(a)+i) ≡ \old(val);
    assigns *(a+(0 .. n-1));
 */
void fill(int *a, int n, int val)
{
  int i;
  i = 0;
  /*@ loop invariant 0 ≤ i ≤ n;
      loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≡ val;
      loop variant n-i;
  */
  while (i < n) {
    *(a + i) = val;
    i ++;
  }
  return;
}

/*@ requires is_valid_int_range(a, n);
    requires is_valid_int_range(b, n);
    ensures ∀ int i; 0 ≤ i < \old(n) ⇒ *(\old(b)+i) ≡ *(\old(a)+i);
    assigns *(b+(0 .. n-1));
 */
void copy(int const *a, int n, int *b)
{
  int i;
  i = 0;
  /*@ loop invariant 0 ≤ i ≤ n;
      loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≡ *(b+k);
      loop assigns *(b+(0 .. i-1));
      loop variant n-i;
  */
  while (i < n) {
    *(b + i) = *(a + i);
    i ++;
  }
  return;
}

/*@ requires is_valid_int_range(a, n);
    requires is_valid_int_range(b, n);
    ensures
      ∀ int j;
        0 ≤ j < \old(n) ⇒
        (*(\old(a)+j) ≡ \old(old_val) ∧ *(\old(b)+j) ≡ \old(new_val)) ∨
        (*(\old(a)+j) ≢ \old(old_val) ∧ *(\old(b)+j) ≡ *(\old(a)+j));
    ensures \result ≡ \old(n);
    assigns *(b+(0 .. n-1));
 */
int replace_copy(int const *a, int n, int *b, int old_val, int new_val)
{
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant
          ∀ int j;
            0 ≤ j < i ⇒
            (*(a+j) ≡ old_val ∧ *(b+j) ≡ new_val) ∨
            (*(a+j) ≢ old_val ∧ *(b+j) ≡ *(a+j));
        loop assigns *(b+(0 .. i-1));
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) == old_val) *(b + i) = new_val; else *(b + i) = *(a + i);
      i ++;
    }
  }
  return n;
}

/*@ requires is_valid_int_range(a, n);
    requires is_valid_int_range(b, n);
    ensures
      ∀ int k; \result ≤ k < \old(n) ⇒ *(\old(b)+k) ≡ \old(*(b+k));
    ensures ∀ int k; 0 ≤ k < \result ⇒ *(\old(b)+k) ≢ \old(val);
    ensures
      ∀ int x;
        x ≢ \old(val) ⇒
        counting(\old(a), \old(n), x) ≡ counting(\old(b), \result, x);
    ensures \result ≡ \old(n)-counting(\old(a), \old(n), \old(val));
    ensures 0 ≤ \result ≤ \old(n);
    assigns *(b+(0 .. n-1));
 */
int remove_copy(int const *a, int n, int *b, int val)
{
  int j;
  j = 0;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ j ≤ i ≤ n;
        loop invariant ∀ int k; j ≤ k < n ⇒ *(b+k) ≡ \at(*(b+k),Pre);
        loop invariant ∀ int k; 0 ≤ k < j ⇒ *(b+k) ≢ val;
        loop invariant
          ∀ int x; x ≢ val ⇒ counting(a, i, x) ≡ counting(b, j, x);
        loop invariant j ≡ i-counting(a, i, val);
        loop assigns *(b+(0 .. j-1));
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) != val) {
        int tmp;
        { /* sequence */
          tmp = j;
          j ++;
          *(b + tmp) = *(a + i);
        }
      }
      i ++;
    }
  }
  return j;
}

/*@ requires is_valid_int_range(a, n);
    requires val+n < (1<<31)-1;
    ensures ∀ int k; 0 ≤ k < \old(n) ⇒ *(\old(a)+k) ≡ \old(val)+k;
    assigns *(a+(0 .. n-1));
 */
void iota(int *a, int n, int val)
{
  int i;
  i = 0;
  /*@ loop invariant 0 ≤ i ≤ n;
      loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+k) ≡ val+k;
      loop assigns *(a+(0 .. i-1));
      loop variant n-i;
  */
  while (i < n) {
    *(a + i) = val + i;
    i ++;
  }
  return;
}

/*@
predicate adjacent_found{Label}(int *a, int n) =
  ∃ int i; 0 ≤ i < n-1 ∧ *(a+i) ≡ *(a+(i+1));

*/
/*@ requires is_valid_int_range(a, n);
    assigns \nothing;
    
    behavior some:
      assumes adjacent_found(a, n);
      ensures 0 ≤ \result < \old(n)-1;
      ensures *(\old(a)+\result) ≡ *(\old(a)+(\result+1));
      ensures ¬adjacent_found(\old(a), \result);
    
    behavior none:
      assumes ¬adjacent_found(a, n);
      ensures \result ≡ \old(n);
    
    complete behaviors some, none;
    disjoint behaviors some, none;
 */
int adjacent_find(int *a, int n)
{
  int __retres;
  if (0 == n) {
    __retres = n;
    goto return_label;
  }
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i < n;
        loop invariant ¬adjacent_found(a, i);
        loop invariant 0 < i ⇒ *(a+(i-1)) ≢ *(a+i);
        loop variant n-i;
    */
    while (i < n - 1) {
      if (*(a + i) == *(a + (i + 1))) {
        __retres = i;
        goto return_label;
      }
      i ++;
    }
  }
  __retres = n;
  return_label: return __retres;
}

/*@ requires is_valid_int_range(a, n);
    assigns \nothing;
    
    behavior empty:
      assumes n ≡ 0;
      ensures \result ≡ 0;
    
    behavior not_empty:
      assumes 0 < n;
      ensures 0 ≤ \result < \old(n);
      ensures
        ∀ int i; 0 ≤ i < \old(n) ⇒ *(\old(a)+\result) ≤ *(\old(a)+i);
      ensures
        ∀ int i; 0 ≤ i < \result ⇒ *(\old(a)+\result) < *(\old(a)+i);
 */
int min_element(int *a, int n)
{
  int __retres;
  int min;
  if (0 == n) {
    __retres = n;
    goto return_label;
  }
  min = 0;
  {
    int i;
    i = 0;
    /*@ loop invariant 0 ≤ i ≤ n;
        loop invariant 0 ≤ min < n;
        loop invariant ∀ int k; 0 ≤ k < i ⇒ *(a+min) ≤ *(a+k);
        loop invariant ∀ int k; 0 ≤ k < min ⇒ *(a+min) < *(a+k);
        loop variant n-i;
    */
    while (i < n) {
      if (*(a + i) < *(a + min)) min = i;
      i ++;
    }
  }
  __retres = min;
  return_label: return __retres;
}


