簡體   English   中英

EACSL Frama-C插件中的無限功能

[英]Unbounded function in EACSL Frama-C plugin

我正在嘗試使用FRAMA-C的E-ACSL插件在C中為以下程序生成合同:

struct lnode {
    int value;
    struct lnode *next;
};

struct set {
    int capacity;
    int size;
    struct lnode *elems;
};

struct set* new(int capacity) {
    struct set *new_set;

    new_set = (struct set*) malloc(sizeof(struct set));
    if(new_set == NULL)
        return NULL; /* no memory left */

    new_set->capacity = capacity;
    new_set->size = 0;
    new_set->elems = NULL;
    return new_set;
}

int insert(struct set *s, int x) {
    struct lnode *new_node;
    struct lnode *end_node;
    struct lnode *n;

    if(s==NULL)
        return 0; /* NULL set */

    if(s->size >= s->capacity)
        return 0; /* no space left */

    end_node = s->elems;    
    n = end_node;
    while(n != NULL) {
        if(n->value == x)
            return 0; /* element already in the set */
        end_node = n;
        n = n->next;
    }

    /* Creation of new node */
    new_node = (struct lnode*) malloc(sizeof(struct lnode));
    if(new_node == NULL)
        return 0; /* no memory left */
    new_node->value = x;
    new_node->next = s->elems;

    s->elems = new_node;
    s->size += 1;

    return 1; /* element added */
}

int isnull(struct set *s) {
    if(s==NULL)
        return 1;
    return 0;
}

int isempty(struct set *s) {
    if(s==NULL)
        return 0; 
    if(s->elems==NULL)
        return 1; /* s is empty */
    return 0; 
}

int isfull(struct set *s) {
    if(s==NULL)
        return 0; 
    if(s->size >= s->capacity)
        return 1; /* s is full */
    return 0; 
}

int contains(struct set *s, int x) {
    struct lnode *n;

    if(s==NULL)
        return 0; /* s is NULL */

    n = s->elems;
    while(n != NULL){
        if(n->value == x)
            return 1; /* element found */
        n = n->next;
    }

    return 0; /* element NOT found */
}

int length(struct set *s) {
    struct lnode *n;
    int count;

    if(s==NULL)
        return 0; /* s is NULL */

    count = 0;
    n = s->elems;
    while(n != NULL){
        count = count + 1;
        n = n->next;
    }

    return count;   
}

ACSL手冊 (第2.3.2節)說正確的方法是在函數前添加注釋。 但是,在我的規范中,我打算包括使用程序函數為insert函數定義最終公理的謂詞。 例如:

@ requires \valid(s);
@ behavior A:
    @ ensures (isfull(s)=0 && length(s)=0 && contains(s,x)=0 && isnull(s)=0 && isempty(s)=1) ==>
(length(s)=1 && contains(s,x)=1 && isnull(s)=0 && isempty(s)=0 && \result==1);

當我嘗試使用e-acsl-gcc.sh進行編譯時, e-acsl-gcc.sh以下錯誤:

user@ubuntu-tmpl:~/Documents/Code$ e-acsl-gcc.sh -c insert.c -O exec
++ frama-c -variadic-no-translation -machdep gcc_x86_64 '-cpp-extra-args= -std=c99 -D_DEFAULT_SOURCE -D__NO_CTYPE -D__FC_MACHDEP_X86_64 ' -no-frama-c-stdlib insert.c axiomTes.c -e-acsl -e-acsl-share=/home/user/.opam/system/bin/../share/frama-c/e-acsl/ -then-last -print -ocode a.out.frama.c
[kernel] Parsing FRAMAC_SHARE/e-acsl//e_acsl_gmp_api.h (with preprocessing)
[kernel] Parsing FRAMAC_SHARE/e-acsl//e_acsl.h (with preprocessing)
[kernel] Parsing insert.c (with preprocessing)
insert.c:31:[kernel] user error: unbound function isempty
[kernel] user error: stopping on file "insert.c" that has errors. Add '-kernel-msg-key pp'
    for preprocessing command.
[kernel] Frama-C aborted: invalid user input.
e-acsl-gcc: fatal error: aborted by Frama-C

這使我認為注釋中不允許使用函數調用,或者具有其他語法規范。 是否可以使用程序的已定義函數來構成謂詞? 仍然適合我的另一種可能性是獲取函數調用結果在其他地方並在批注中使用它。

謝謝!

首先,如果您給出嘗試啟動e-acsl的確切代碼( 包括其注釋) ,對於我們來說,答案要容易得多。 將它們分開放置而未在注釋中正確地包含它們僅意味着重現該問題更為復雜,並且我們無法確定是否完全重現了您的設置。

就是說,這是我通過查看上面的注釋發現的問題(由於前面提到的原因,沒有在其上啟動frama-c)。

  1. 實際上,您不能在CSL注釋中調用C函數。 不過,可以在ACSL中定義邏輯函數和謂詞,然后可以在注釋中使用(當然,在定義它們之后)。 這在ACSL手冊的 2.6節中進行了描述,並且ACSL by Example包含許多示例。

  2. 與C中一樣,在ACSL中,等式由==而不是=

  3. 將您的ensures分為多個子句,而不是使用具有連詞的單個子句,可能是一個好主意:這將使查找未驗證后置條件的哪個部分變得更加容易。

  4. 同樣,除非您想完成合同,否則behavior A:並沒有任何實際用途。

  5. 在樣式方面, @僅是強制性的,以引入注釋(帶有/*@ ... */ )。 您無需在每行上放一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM