通过例子学TLA+(一)-- HourClock

前言

刚接触TLA+,将学习过程中的理解整理记录下来,用于加深理解和备忘。有对TLA+感兴趣的可以私信我,一起学习。

TLA+简介

TLA+ 是一门形式规格说明语言(formal specification language),主要用来验证系统的设计和算法的正确性。它可以用来对几乎任何形式的离散系统进行精确的、正式的描述,特别适合于描述异步系统。

TLA+提供了一个工具用来编写TLA+,同时提供了语法检查,参数设置,程序运行等功能,该工具就是TLA+ Toolbox,下载路径为:https://github.com/tlaplus/tlaplus/releases/latest

第一个例子:时钟

先从一个非常简单的时钟例子着手。先忽略时钟表示与实际时间的关系,一个时钟将表示为从1到12的周期性运动,即时钟的状态变化为【hour=1】=> 【hour=2】=>【hour=3】… =>【hour=12】=>【hour=1】。因此可以理解为时钟的状态总共有12个,即从1到12,其变化趋势是,当hour小于12时,下一个状态为hour+1,当hour等于12时,下一个状态为1。

用TLA+表示出来,代码如下:

----------------------------- MODULE HourClock -----------------------------
EXTENDS Naturals   

VARIABLES hr

HCini == hr \in (1 .. 12)   \* .. defined in Naturals

HCnxt == hr' = IF hr # 12 THEN hr + 1 ELSE 1

HC == HCini /\ [][HCnxt]_hr

THEOREM HC => []HCini

=============================================================================

可以打开TLA+ Toolbox将上述代码粘贴进去运行。具体步骤如下:

File -> Open Spec -> Add New Spec -> 选择Root-module file路径并输入文件名HourClock -> finish

时钟TLA+解析

上述例子中,

----------------------------- MODULE HourClock -----------------------------

表示module的起始,其中HourClock是module名称,module名与文件名相同。任何module的起始都是同样的开始与结尾。结尾是最后一行采用 ====== 表示。

在TLA+中,注释一般 使用 \* 来表示

EXTENDS Naturals  \* 涉及到数学运算的都会用到Naturals (TLA+内置module)
                  \* EXTENDS 是关键字,相当于其他语言中的import, include

VARIABLES hr      \* 定义一个变量hr,用来表示时钟的当前值

HCini == hr \in (1 .. 12)   \* 定义HCini为程序的初始状态,其中初始状态为hr,值的范围是1到12,
							\* (1 .. 12) 中的 .. 在Naturals module 中定义							                    \* 如果没有 EXTENDS Naturals,此处将报错,找不到..的定义
							\* == 表示等价的意思


HCnxt == hr' = IF hr # 12 THEN hr + 1 ELSE 1  
\* 用HCnxt表示时钟的下一状态,下一状态hr'为如果hr 不等于 12,这 hr'= hr+1 ,否则 hr'=1
\* 在TLA+中用 # 表示不等于,写成 /= 也是可以的
\* IF,THEN,ELSE跟其他语言中的意义相同
\* + 也是在 Naturals module中定义的

\* 代码至此已经定义了时钟的初始状态和基于初始状态的下一状态动作,实际上已经可以运行了。

Check & Run

在Spec Explorer 右键models,选择new model,输入model名称,点击OK,会出现Model Overview页面和TLC Errors页面,TLC Errors check 提示 No error information。

在What is the behavior spec 选项卡中 init 输入 HCini, Next 输入HCnxt。
在这里插入图片描述

然后点击左上角的运行按钮。运行完成后,可以在Model Checking Results页面看到Statistics中 HCnxt 的StatesFound是12,从数量上看是正确的。
在这里插入图片描述

但是目前的问题是,HCnxt的状态数量是正确的,但不代表状态值是正确的。因此需要增加不可变检查,在Model Overview 页面的 What to check -》 Invariants 中增加HCini,用来进行不可变检查。
在这里插入图片描述

然后点击左上角的run,运行后没有产生任何错误提示,即意味着状态都是正确的。

为了展示错误状态是如何呈现的,将代码中HCnxt 修改为以下代码:

HCnxt == hr' = IF hr # 12 THEN hr + 1 ELSE 0

即,当hr为12时,hr’的变更为0,这就超出了正确的时钟应该表示的值{1 … 12}。重新运行,会看到TLC Errors错误提示,在Error-trace中还能追踪到是当hr为12时出的错误。
在这里插入图片描述

遗留问题

代码中还遗留了以下两行代码,从上述的运行情况来看,注释掉以下两行代码对程序的检查和运行都没有影响。

HC == HCini /\ [][HCnxt]_hr

THEOREM HC => []HCini

因此,以上两行代码的真实作用目前还不清楚。后面搞清楚后再来补充。但从代码描述上看,HC是一个时序表达式,可以添加到Properties选项卡中进行检查,从运行情况看,没有看出来添加或者不添加的区别。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值