Can ACSL denote that an assignment should be hidden? - frama-c

This function mocks a function that returns a continuously rising value until overflow occurs. It is like the millis() function in Arduino.
To prove the implementation, I need to increment (thus, assign) static variables to keep state between invocations. However, a function that calls mock_millis() should still be able to assign \nothing.
Is there a way to make WP ignore the assigns clause?
static int64_t milliseconds = 0;
/*# assigns milliseconds;
behavior normal:
assumes milliseconds < INT64_MAX;
ensures \result == \old(milliseconds) + 1;
ensures milliseconds == \old(milliseconds) + 1;
behavior overflow:
assumes milliseconds == INT64_MAX;
ensures \result == 0;
ensures milliseconds == 0;
complete behaviors normal, overflow;
disjoint behaviors normal, overflow;
*/
int64_t mock_millis() {
if (milliseconds < INT64_MAX) {
milliseconds++;
} else {
milliseconds = 0;
}
return milliseconds;
}
I tried doing this with ghost variables, and noticed that a function that assigns a ghost variable cannot be assigns \nothing. I thought ghost variables were completely independent of the program implementation. Is there a special reason for this?

I assume your static variable is meant to be called milliseconds and not microseconds as it is now.
Your assumption about ghost variables is indeed wrong: ghost code is not supposed to interfere with real code and vice-versa (note that this is not enforced by Frama-C at this point). Hence if you declare milliseconds as ghost, any assignment to it is supposed to occur inside ghost code. But from a specification point of view, such assignments are nevertheless side-effects that need to be mentioned in the assigns clause.

Related

Calculating the average of Sensor Data (Capacitive Sensor)

So I am starting to mess around with Capacitive sensors and all because its some pretty cool stuff.
I have followed some tutorials online about how to set it up and use the CapSense library for Arduino and I just had a quick question about this code i wrote here to get the average for that data.
void loop() {
long AvrNum;
int counter = 0;
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter = 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
}
}
This is my loop statement and in the Serial it seems like its working but the numbers just look suspiciously low to me. I'm using a 10M resistor (brown, black, black, green, brown) and am touching a piece of foil that both the send and receive pins are attached to (electrical tape) and am getting numbers around about 650, give or take 30.
Basically I'm asking if this code looks right and if these numbers make sense...?
The language used in the Arduino environment is really just an unenforced subset of C++ with the main() function hidden inside the framework code supplied by the IDE. Your code is a module that will be compiled and linked to the framework. When the framework starts running it first initializes itself then your module by calling the function setup(). Once initialized, the framework enters an infinite loop, calling your modules function loop() on each iteration.
Your code is using local variables in loop() and expecting that they will hold their values from call to call. While this might happen in practice (and likely does since that part of framework's main() is probably just while(1) loop();), this is invoking the demons of Undefined Behavior. C++ does not make any promises about the value of an uninitialized variable, and even reading it can cause anything to happen. Even apparently working.
To fix this, the accumulator AvrNum and the counter must be stored somewhere other than on loop()'s stack. They could be declared static, or moved to the module outside. Outside is better IMHO, especially in the constrained Arduino environment.
You also need to clear the accumulator after you finish an average. This is the simplest form of an averaging filter, where you sum up fixed length blocks of N samples, and then use that average each Nth sample.
I believe this fragment (untested) will work for you:
long AvrNum;
int counter;
void setup() {
AvrNum = 0;
counter = 0;
}
void loop() {
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter == 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
AvrNum = 0;
}
}
I provided a setup(), although it is redundant with the C++ language's guarantee that the global variables begin life initialized to 0.
your line if (counter = 10) is invalid. It should be if (counter == 10)
The first sets counter to 10 and will (of course) evaluate to true.
The second tests for counter equal to 10 and will not evaluate to true until counter is, indeed, equal to 10.
Also, kaylum mentions the other problem, no initialization of AvrNum
This is What I ended up coming up with after spending some more time on it. After some manual calc it gets all the data.
long AvrArray [9];
for(int x = 0; x <= 10; x++){
if(x == 10){
long AvrMes = (AvrArray[0] + AvrArray[1] + AvrArray[2] + AvrArray[3] + AvrArray[4] + AvrArray[5] + AvrArray[6] + AvrArray[7] + AvrArray[8] + AvrArray[9]);
long AvrCap = AvrMes/x;
Serial.print("\t");
Serial.println(AvrCap);
x = 0;
}
AvrArray[x] = cs_4_2.capacitiveSensor(30);
Serial.println(AvrArray[x]);
delay(500);

Recursive code for maximum height of a binary tree

I came across a recursive code for calculating the maximum height of a binary tree-
int maxDepth(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
/* use the larger one */
if (lDepth > rDepth)
return(lDepth+1);
else return(rDepth+1);
}
}
I'm tried to write the code in another way-
int maxDepth(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = 1+maxDepth(node->left); //notice the change
int rDepth = 1+maxDepth(node->right); //notice the change
/* use the larger one */
if (lDepth > rDepth)
return(lDepth);
else return(rDepth);
}
}
I'm confused whether both versions will work similarly or is there a bug in the second implementation.
I tried out few cases, for which both functions returned same results.
Arithmetically they are the same, it doesn't matter when you add the 1 to the answer because no other arithmetic transformations are being done to the value which gets returned. Technically yours is slightly less efficient because you do two additions, then throw away the smaller of the two values which wastes the work done on that one. In reality I doubt you'd ever notice the difference if you did timings.
These two C functions will behave identically. All you have done in your rewrite of the function maxDepth() is to add 1 to the variables lDepth and rDepth. However, you effectively undo that change by subtracting 1 from these variables in your return value:
int lDepth = 1+maxDepth(node->left); // you added one to lDepth
int rDepth = 1+maxDepth(node->right); // you added one to rDepth
/* use the larger one */
if (lDepth > rDepth)
return(lDepth); // but you subtract one here
else return(rDepth); // and you also subtract one here

assume statement modelling in FramaC

I want to use user assertion of value analysis plugin of Frama-C (Neon version), however I have some problem to come up with the suitable model of assume statement, which is very useful for me to apply particular constraints, for example, here is my test code:
#include "/usr/local/share/frama-c/builtin.h"
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//# assert a == 2;
return 0;
}
I want that the value of selection will be greater than 5 after this assume statement so that the assertion will be valid.
My initial attempt was to write this function
void assume(int a){ while(!a); return;}
, but it was unsuccessful.
Please help me, thanks.
The easiest way to constrain selection would be to use an assert (which of course won't be proved by Value). If you want to distinguish between the assert that are in fact hypotheses you make from the assert that you want to verify, you can use ACSL's naming mechanism, such as
//# assert assumption: selection > 5;
and verify that the only assert that are unknown are the ones named assumption.
Using an assume function cannot work as such, because it will only reduce the possible value of the a parameter to be non-zero. Value is not able to infer the relation between the value of a in assume and the value of selection in main. However, it is possible to help it a little bit. First, -slevel allows to propagate several abstract state in parallel. Second, an assert given in an disjunctive will force Value to split its state (if the -slevel is big enough to do so). Thus, with the following code
#include "builtin.h"
void assume(int a) { while(!a); return; }
int main(void)
{
int selection = Frama_C_interval(0,10);
int a;
/*# assert selection > 5 || selection <= 5; */
assume(selection > 5);
if (selection > 5)
{
a = 2;
}
else
{
a = 1;
}
//# assert a == 2;
return 0;
}
and the following command line:
frama-c -cpp-extra-args="-I$(frama-c -print-share-path)" -val -slevel 2
After the first assert (which obviously valid), Frama-C will propagate separately two states: one in which selection > 5 and one in which selection <= 5. In the first case, assume is called with 1 as argument, thus returns immediately, and the then branch of the if is taken, so that the second assert is valid. In the second state, assume is called with 0, and never returns. Thus for all cases where control reaches the second assert, it is valid.
Note that you really need to add the first assert inside the body of main, and to copy in ACSL the argument you pass to assume. Otherwise, the state split won't occur (more precisely, you will split on a, not on selection).

Understanding Frama-C logic labels

I have some troubles when I try to use the default logic labels LoopEntry and LoopCurrent. Here is a simple example the different provers (alt-ergo, coq, cvc3, z3) I use are not able to prove :
/*# requires n > 0;*/
void f(int n){
int i = 0;
/*# loop invariant \at(i,LoopEntry) == 0;
# loop invariant \at(i,LoopCurrent) >= \at(i,LoopEntry);
# loop invariant 0 <= i <= n;
# loop assigns i;
# loop variant n-i;
*/
while(i < n){
i++;
}
}
In particular, the first and second invariants are not proved (no problem with the others). Now if I modify this simple example by adding a label "label" after the declaration/definition of i and if I refer to that label, and change LoopCurrent by Here (which gives this snippet :
/*# requires n > 0;*/
void f(int n){
int i = 0;
label : ;
/*# loop assigns i;
# loop invariant \at(i,label) == 0;
# loop invariant \at(i,Here) >= \at(i,label);
# loop invariant 0 <= i <= n;
# loop variant n-i;
*/
while(i < n){
i++;
}
}
)
now everything is proved.
I found the documentation about Acsl default logic labels quite easy to understand and I expected the first example to be proved as the second. Could you explain where does the problem come from?
Roo
PS1 : what does Pre refer to when used in a loop clause? The state before first loop iteration or the previous iteration??
PS2 : I'm using Frama-C Fluorine, but maybe I didn't upgrade for every minor updates
LoopCurrent and LoopEntry are indeed not supported by WP in Fluorine. This is fixed in the development version (see http://bts.frama-c.com/view.php?id=1353), and should appear in the next release.
Regarding the other pre-defined labels,
Pre always refers to the state at the beginning of the function.
Old can only be used in a contract, and refers to the pre-state of this contract (i.e. the state in which the requires and assumes clauses are evaluated). It is thus equivalent to Pre for a function contract, but not for a statement contract (unless you make a contract enclosing the main block of your function).
Here means the program point where the corresponding annotation is evaluated. In a contract, its meaning depends on the clause in which it appears.
Post can only be used in ensures, assigns, allocates or frees clauses, and refer to the state at the end of the contract.

Reentrancy and recursion

Would it be a true statement to say that every recursive function needs to be reentrant?
If by reentrant you mean that a further call to the function may begin before a previous one has ended, then yes, all recursive functions happen to be reentrant, because recursion implies reentrance in that sense.
However, "reentrant" is sometimes used as a synonym for "thread safe", which is introduces a lot of other requirements, and in that sense, the answer is no. In single-threaded recursion, we have the special case that only one "instance" of the function will be executing at a time, because the "idle" instances on the stack are each waiting for their "child" instance to return.
No, I recall a factorial function that works with static (global) variables. Having static (global) variables goes against being reentrant, and still the function is recursive.
global i;
factorial()
{ if i == 0 return 1;
else { i = i -1; return i*factorial();
}
This function is recursive and it's non-reentrant.
'Reentrant' normally means that the function can be entered more than once, simultaneously, by two different threads.
To be reentrant, it has to do things like protect/lock access to static state.
A recursive function (on the other hand) doesn't need to protect/lock access to static state, because it's only executing one statement at a time.
So: no.
Not at all.
Why shouldn't a recursive function be able to have static data, for example? Should it not be able to lock on critical sections?
Consider:
sem_t mutex;
int calls = 0;
int fib(int n)
{
down(mutex); // lock for critical section - not reentrant per def.
calls++; // global varible - not reentrant per def.
up(mutex);
if (n==1 || n==0)
return 1;
else
return fib(n-1) + fib(n-2);
}
This does not go to say that writing a recursive and reentrant function is easy, neither that it is a common pattern, nor that it is recommended in any way. But it is possible.

Resources