使用 NuSMV 进行模型检查

Model checking with NuSMV

NuSMV中真的没有像NULL、nil、None这样的值吗?

我们不应该为过程制作模型,因为模型应该代表电子电路?

我的场景是,我有一个UART连接器,一个主存和一个进程,后者读写主存和读写UART。在主内存中有一个名为 K 的数据应该保持不变。我们想证明如果进程不写入 K' then the value ofK` 等于它的下一个值。

我想知道我的模型是否足够细粒度或是否过于抽象。另外,如果我使用了正确的数据类型。

MODULE UART (proc, output, input)
VAR state : {idle, receive, transmit};
    Rx : unsigned word [ 8 ]; --vector of bytes
    Tx : unsigned word [ 8 ];
ASSIGN
    next (Rx) :=
        case
            proc = read : input; TRUE : (Rx);
        esac;
    next (Tx) :=
        case
            proc = write : output; TRUE : (Tx);
        esac;
    next (state) :=
        case
            proc = write : receive; proc = read : transmit; TRUE : idle;
        esac;
TRANS
    proc != read -> next (Rx) = Rx;
MODULE MEM (proc, input, output)
VAR K : unsigned word [ 8 ]; data : array 0 .. 7 of array 0 .. 7 of unsigned word [ 8 ];
ASSIGN
    init (data[1][0]) := K; 
    next (K) :=
        case
            output = data[1][0] : output;
            TRUE : K;
        esac;
MODULE main
VAR proc : {idle, read, write}; input : unsigned word [ 8 ]; 
    output : unsigned word [ 8 ]; 
    memory : MEM (proc, input, output); 
    uart0 : UART (proc, input, output); 
ASSIGN init (input) := memory.data[0][0]; init (output) := memory.data[0][0];
LTLSPEC G (output != memory.data[1][0]) -> G (memory.K = next (memory.K))

在你的post中你涉及了很多话题,我不确定你的主要问题是哪个。

Is it true that in NuSMV there is no value like NULL, nil, None?

在 C 语言中也是如此。Nil 只是给定数据类型允许的值中的一个值。看你的例子,好像你真的不需要它,不是吗?

And that we should not make a model for a process because the models should represent electronic circuits?

没有。只要您不需要创建动态对象(例如,C 中的 malloc),您就可以表示任何您想要的东西。另一个问题是关于进程的 synchronicity/concurrency。您仍然可以对异步进程建模,但它需要显式编码调度程序。

关于代码:我没有 运行 它,但很多事情看起来很可疑。我建议您尝试使用 NuSMV 模拟命令来查看模型的行为方式。

  • UART 模块:您只能同时写入 Rx 和 Tx。这些值永远不会被读取。
  • UART 模块:我建议不要混合使用 ASSIGN 和 TRANS。这是在模型中引入死锁的简单方法。此外,您编写的 TRANS 已包含在 ASSIGN
  • UART 模块:为什么需要 state 变量?
  • MEM 模块:我不明白你为什么要使用数组的数组,因为你只查看两个值。我觉得你可以把这部分再抽象一些。从您的非正式描述来看,您似乎不需要它。
  • LTL:我不确定 属性 是否符合您的想法。我会写: G ( proc != write -> (memory.K = next(memory.K)) )

如果您将此示例用其他语言(例如 C)编码,或者您可以修改问题描述,那么我可以为您提供更多信息。