You are on page 1of 6

Frama-C​ - ​Handling Recursion

(Adapted from lectures by Dr. Bharat Jayaraman)

Prepared by: K.P. Jevitha


Need for Functional Axioms
1. Factorial of a number
#include <stdio.h>
/*@
axiomatic Factorial {
logic integer fact(integer n);

axiom case_n:
\forall integer n;
n >= 1 ==> fact(n) == n*fact(n-1);
axiom case_0:
fact(0) == 1;
}
*/
/*@
requires n >= 0;
ensures \result == fact(n);
assigns \nothing ;
*/
int factorial(int n) {
int i = 1;
int f = 1;
​/*@
loop invariant f == fact(i-1);
loop invariant 0 < i <= n+1;
loop assigns i, f;
loop variant (n+1)-i;
*/
while (i <= n) {
f = f * i;
i = i + 1;
}
return f;
}
i f (n+1)-i (n=5)
1 1 5 (Before 1st iteration)
2 1 4 (Before 2nd iteration)
3 2 3 (Before 3rd iteration)
4 6 2 (Before 4th iteration)
5 24 1 (Before 5th iteration)
6 120 0 (End of 5th iteration)

Fact (5) = 5 * fact(4)


Fact (4) = 4 * fact(3)
Fact(3) = 3 * fact (2)
Fact(2) = 2 * fact(1)
Fact(1) = 1

Fact(n) = n * fact(n-1)
Fact(1) = 1

2. Sum of squares of numbers


3. GCD of two numbers

#include <stdio.h>
/*@
axiomatic GCD {
logic integer Gcd(integer p, integer q);

axiom Gcd1:
\forall integer m, n;
m > n ==> Gcd(m,n) == Gcd(m-n, n);
axiom Gcd2:
\forall integer m, n;
n > m ==> Gcd(m,n) == Gcd(m, n-m);
axiom Gcd3:
\forall integer m, n;
m == n ==> Gcd(m,n) == m;
}
*/
/*@
requires p >= 1;
requires q >= 1;
ensures \result == Gcd(\old(p), \old(q));
assigns \nothing;
*/

int gcd(int p, int q) {


/*@ loop invariant Gcd(p,q) == Gcd(\at(p,Pre), \at(q,Pre));
loop assigns p, q;
*/
while (p != q) {
if (p > q)
p = p - q;
if (q > p)
q = q - p;
}

return p;
}
Exercise:

1. Write the code and ACSL contracts using axioms for “a power x”.

/*@
axiomatic power {
logic integer power(integer a, integer x);

axiom case_x:
\forall integer a,x;
x >= 1 ==> power(a,x) == a*power(a,x-1);

axiom case_0:
\forall integer a;
power(a,0) == 1;
}
*/
/*@ requires x >= 0;
ensures \result == power(a,x);
assigns \nothing;
*/

int pow(int a, int x){


int i=1, pow=1;
/*@
loop invariant pow == power(a, i-1);
loop invariant 1 <= i <= x+1;
loop assigns i, pow;
loop variant ((x+1) - i) ;

*/
while(i <= x){
pow = pow*a;
i++;
}
return pow;
}
a = 3, x=4

i pow
1 1 ⇐ Before 1st iteration
2 3 ← Before 2nd iteration
3 9 ← Before 3rd iteration
4 27 ← Before 4th iteration
5 81 ← End of 4th iteration

pow(3,4) = 3 * pow(3,3)
pow(3,3) = 3* pow(3,2)
pow(3,2) = 3*pow(3,1)
pow(3,1) = 3*pow(3,0)
pow(3,0)= 1
2. Write the code and ACSL contracts using axioms for “counting the
number of positive elements in an array”.
int a[5] = {0, -1, 2, 4, -2}; ⇒ result = 2

3. Write the code and ACSL contracts using axioms for “Sum of negative
elements in the array.”.
4. ​Write the code and ACSL contracts using axioms for “Return the max
of (Sum of negative elements in an array , sum of positive elements in an
array)”.

You might also like