【问题标题】:frama-c / ACSL / WP : Cardinality of a setframa-c / ACSL / WP : 集合的基数
【发布时间】:2020-03-20 09:46:43
【问题描述】:

我经常在其他正式规范中使用集合的基数,我想知道是否可以通过 WP frama-c 插件在 ACSL 中使用它。

例如,我觉得写起来更清楚 assumes card({*a, *b, *c}) == 3 而不是 assumes *a != *b && *a != *c && *b != *c

【问题讨论】:

    标签: frama-c acsl


    【解决方案1】:

    好的,我找到了一个解决方案(我警告你一个缓慢的解决方案,必须将超时从 10 秒更改为 30 秒,仅用于以下示例)。此外,它在 Frama-C 版本的 Calcium 中被破坏,声称它找不到 Qed 库(该错误似乎是在尝试调用 logic boolean 类型的 Frama-C 函数)。它在 Frama-C 版本的 Chlorine 中正常工作(没有测试其他版本)。

    /* "set" appears to be a reserved word in frama-c */
    
    /*@ predicate full_card{L}(unsigned int* the_set, integer set_size) =
      \forall integer a, b; 0 <= a < set_size && 0 <= b < set_size && a != b ==> the_set[a] != the_set[b];
    */
    
    /*@ logic boolean in_set_bool{L}(unsigned int* the_set, integer set_size, unsigned int element) =
      set_size == 0 ? \false : element == the_set[0] || in_set_bool(the_set + 1, set_size - 1, element);
    */
    
    /*@ logic integer card{L}(unsigned int* the_set, integer set_size) =
      set_size == 0 ? 0 : (
        in_set_bool(the_set + 1, set_size - 1, the_set[0])
          ? card(the_set + 1, set_size - 1)
          : card(the_set + 1, set_size - 1) + 1);
    */
    
    int main(int argc, char** argv) {
      unsigned int set[] = { 1, 2, 3 };
      unsigned int set_size = 3;
    
      /*@ assert full_card(&set[0], set_size); */
      /*@ assert card(&set[0], set_size) == 3; */
    
      unsigned int set_two[] = { 3, 2, 1, 3 };
      unsigned int set_two_size = 4;
    
      /*@ assert card(&set_two[0], set_two_size) == 3; */
      /*@ assert !full_card(&set_two[0], set_two_size); */
    }
    

    【讨论】:

    • 好的,谢谢您的回答。如果我理解正确:ACSL 语言本身并没有提出表达集合基数的可能性。您必须自己构建解决方案。据我了解,SMT 求解器不能很好地处理递归逻辑定义。也许这解释了为什么证明需要时间。是否有一个已经证明的公理库来指定主要的抽象数据结构及其属性?这可能是一个有效的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多