1

I have a test Promela program (a model of UI) that can be verified with Spin:

int secrets = 0;
int success = 0;
int fails = 0;
int total = 0;

//variables to control
bool windowLogin = false;
bool windowSecret = false;
bool windowNoSecret = false;

//ltl formulas

ltl secret_to_success_password { [] (secrets<=success)} 
ltl check_total { [] (total == success + fails || total + 1 == success + fails)} 
ltl we_open_nosecret { <> (windowNoSecret) } 
ltl we_open_secret { <> (windowSecret) }
ltl we_open_any { [] <> (windowSecret || windowNoSecret)} 
ltl login_check { <> windowLogin -> <> windowSecret} 
ltl no_secret_nosecret { [] !(windowSecret && windowNoSecret) } 

//channels
chan login=[0] of {short};
chan nonsecret = [0] of {short};
chan secret = [0] of {short};

//main
active proctype MainWindow(){
int buf;
printf("Main started");
do
    //infinite loop
    :: {
    printf("Main: go to Login window");
    login! 1;
    login? buf;
    if 
        :: buf == 1 ->  {//ok
            success++;
            printf("Main: open secret window");
            //"open" secret
            secret ! 1;
            secret ? buf;//и ждем его
        }
        :: buf == 0 ->  {//fail
            fails++;
            printf("Main: open nosecret window");
            //"open" nonsecret
            nonsecret ! 1;
            nonsecret ? buf
        }
    fi
}
od
}

active proctype LoginWindow(){
int buf;
printf("Login started");
do
:: {
    login? buf;
    windowLogin = true;
    if 
        ::true-> { printf("Login fail"); windowLogin = false; login ! 0 }
        ::true-> { printf("Login fail"); windowLogin = false; login ! 0 }
        ::true-> { printf("Login ok!"); windowLogin = false; login ! 1 }//p= 1/3 
    fi
}
od
}

active proctype NonSecretWindow(){
int buf;
printf("Non Secret started");
do
:: {
    nonsecret ? buf;
    printf("Non Secret window opened");
    windowNoSecret = true;
    total++;
    windowNoSecret = false;
    nonsecret ! 1;
    printf("Non Secret window closed");
}
od

}

active proctype SecretWindow(){
int buf;
printf(" Secret started");
do
:: {
    secret ? buf;
    printf("Secret window opened");
    windowSecret = true;
    secrets++;
    total++;
    windowSecret = false;
    secret ! 1;
    printf("Secret window closed");
}
od
}

Then I created a corresponding C program (for first step, without a loop in Main Window):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

bool windowLogin = false;
bool windowNoSecret = false;
bool windowSecret = false;

int total = 0;
int secrets = 0;
int success = 0;
int fails = 0;

int LoginWindow();
int NonSecretWindow();
int SecretWindow();


int MainWindow()  {
    //printf("Main started\n");
    {
        //printf("Main: go to Login window\n");
        int r = LoginWindow();
        if (r == 1) {
            //printf("Main: open secret window\n");
            success++;
            SecretWindow();
        } else {
            //printf("Main: open nosecret window\n");
            fails++;
            NonSecretWindow();
        }
    }
return 0;
}


int LoginWindow() {
    //printf("Login started\n");
    windowLogin = true;
    if (rand() %3 ==0) {
//      windowLogin = false;
        return 1;
    } else {
//      windowLogin = false;
        return 0;
    }
    return 0;
}

int NonSecretWindow() {
    //printf("Non Secret started\n");
    //printf("Non Secret window opened\n");

    windowNoSecret = true;
    total++;
    //windowNoSecret = false; --- aorai will controll the variable change only in the end of function
    //printf("Non Secret window closed\n");
    return 0;
}

int SecretWindow() {
    //printf("Secret window opened\n");
    windowSecret = true;
    secrets++;
    total++;
    //windowSecret = false;
    //printf("Secret window closed\n");
    return 0;
}

int main() {

    MainWindow();

    return 0;
}

I want to try using Aoraï LTL (don't want to create .ya by hand) in Frama-C and WP plugins. First, I created a .ltl file

CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) && 
((_X_ (CALL(NonSecretWindow)))||(_X_ (CALL(SecretWindow)))))))

and can get 2 unknown goals:

[wp] [Alt-Ergo] Goal typed_MainWindow_call_NonSecretWindow_pre : Unknown (Qed:3ms) (81ms)
[wp] [Alt-Ergo] Goal typed_MainWindow_call_SecretWindow_pre : Unknown (Qed:4ms) (79ms)

Also I tried

CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) && 
((_X_ (CALL(NonSecretWindow)||CALL(SecretWindow)))))))

with the same result. This one

CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) && (
(_F_ (CALL(NonSecretWindow)||CALL(SecretWindow)))))))

can be proved, but I belive that that one should be not correct:

CALL(main) && _X_ (CALL (MainWindow) && _X_ (CALL (LoginWindow) && _X_ (RETURN (LoginWindow) && 
((_F_ (CALL(NonSecretWindow)))))))

but it is correct (all goals were proved). Also, I tried to test my LTL formulas like in Promela (without CALL/RETURN/X):

_G_ (windowLogin => _F_ (windowSecret || windowNoSecret))

and I got a lot of unproved goals or even for testing

_G_ (total == success + fails || total + 1 == success + fails)

an internal error

[aorai] Welcome to the Aorai plugin
[aorai] failure: Term cannot be transformed into exp.
[kernel] Current source was: test_ltl.c:112
         The full backtrace is:
         Raised at file "src/libraries/project/project.ml", line 402, characters 50-57
         Called from file "src/plugins/aorai/aorai_register.ml", line 385, characters 4-31
...

I use the commandline

rm test_ltl_annot.c
frama-c test_ltl.c -aorai-ltl test_ltl.ltl
frama-c -wp test_ltl_annot.c

and Frama-C version is Phosphorus-20170501.

How should I use this plugin to verify my test program with respect to LTL?

Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
SeregASM
  • 75
  • 12

0 Answers0