形式化验证工具(PAT)羊车门代码学习
首先介绍一下PAT工具,下图是PAT工具的图标

PAT工具全称是Process Analysis Toolkit,可以做一些简单的验证。
今天我们分析一下例子里面的Monty Hall Problem
这个问题不知道大家知不知道,这里简单介绍一些这个问题(羊车门问题)。话说有一个国外的电视节目,有三个门(A,B,C门),其中两个门后面放的是羊,另一个门后面放的是车,说一天,一个参与者选中了A这个门,主持人从另外两个门里面选中一个门,打开一看是羊。问参与者要不要换选的门,换门得到车的概率是多大。
我们来简单分析一下这个问题,首先参与者第一个门里面是羊的概率为2/3,是车的概率为1/3,因为另一扇门被打开而且里面是羊,那么如果想换门得到车必须是第一个门是羊,就是概率为2/3,也就是说,在这种情况下,换门得到车的概率是2/3,不换门得到车的概率是1/3。
我们加大一点点难度,假设在参与者选中车之后,有1/3的概率主持人会把车放到参与者选中的门里面,有2/3的概率什么都不做。这种情况下我们看换门得到车的概率是多少。
首先第一次参与者选门,选中车的概率为1/3,选中羊的概率是2/3,先来看看选中车的情况,这时无论主持人动不动手脚,车都在参与者选中的门里面,然后参与者换门,得到车的概率为0。然后来看第一次选中羊的情况,有1/3的概率主持人会把车放到参与者选中的门里面,有2/3的概率什么都不做,换门得到车的情况必须是主持人什么都不做,就是2/3*2/3=4/9。
好,现在我们回到PAT中来。我们来看看PAT能帮我们做什么。
先看代码:
//=======================Model Details===========================
//枚举门1,门2,门3,值分别为0,1,2
enum{Door1, Door2, Door3}; //定义变量
var car = -;
var guess = -;
var goat = -;
var final = false; #define goal guess == car && final;
//放车,门1车等于0,门2车等于1,门3车等于2
PlaceCar = []i:{Door1,Door2,Door3}@ placecar.i{car=i} -> Skip;
//选中一个门
Guest = pcase {
: guest.Door1{guess=Door1} -> Skip
: guest.Door2{guess=Door2} -> Skip
: guest.Door3{guess=Door3} -> Skip
};
//开门行为,开的门不能是有车,而且不能是选中的门
Goat = []i:{Door1,Door2,Door3}@
ifb (i != car && i != guess) {
hostopen.i{goat = i} -> Skip
};
//换门行为,换的门不能是选中的门,也不能是主持人已经打开的门
TakeOffer = []i:{Door1,Door2,Door3}@
ifb (i != guess && i != goat) {
changeguess{guess = i; final = true} -> Stop
};
//不换门行为,
NotTakeOffer = keepguess{final = true} -> Stop;
//换门
Sys_Take_Offer = PlaceCar; Guest; Goat; TakeOffer; #assert Sys_Take_Offer reaches goal with prob;
//不换门
Sys_Not_Take_Offer = PlaceCar; Guest; Goat; NotTakeOffer; #assert Sys_Not_Take_Offer reaches goal with prob;
//先猜,后放车
Sys_With_Dishonest_Program = Guest; PlaceCar; Goat; NotTakeOffer; //place after guessing #assert Sys_With_Dishonest_Program reaches goal with prob;
//主持人偷偷换车位置,1/3的概率换车,2/3的概率不换车
HostSwitch = pcase {
: switch{car = guess} -> Skip
: Skip
};
//放车,猜车,开羊门,换车位置,换门
Sys_With_Cheating_Host_Switch = PlaceCar; Guest; Goat; HostSwitch; TakeOffer; #assert Sys_With_Cheating_Host_Switch reaches goal with prob; Sys_With_Cheating_Host_Not_Switch = PlaceCar; Guest; Goat; HostSwitch; NotTakeOffer; #assert Sys_With_Cheating_Host_Not_Switch reaches goal with prob;
代码可能需要解释一下,首先是枚举三个门,Door1, Door2, Door3,这三个门的值就是0,1,2。然后定义了三个变量,car表示车在哪个门,car=0就表示car在第一个门,guess表示参与者选中某个门,guess=Door1(也就是guess=0)就表示选中第一个门,goat就表示主持人中间开的门,goat=1就表示主持人打开的是2号门。final表示程序是否进行到最后。final=true就表示程序进行到最后。
接下来定义了一个goal,这个goal是一个bool判断,guess==car&&final。就是表示程序进行到最后且得到车。
接下来定义了几个行为,分别是放车,参与者选门,主持人开门,换门,不换门。
放车:
PlaceCar = []i:{Door1,Door2,Door3}@ placecar.i{car=i} -> Skip;
英文中括号表示选择,就是那个i在Door1,Door2,Door3里面选择,选择之后开始放车(就是给车赋值),然后结束。
参与者选门:
Guest = pcase {
: guest.Door1{guess=Door1} -> Skip
: guest.Door2{guess=Door2} -> Skip
: guest.Door3{guess=Door3} -> Skip
};
pcase表示概率选择,看到有三种情况,概率都是1/3(这里需要注意一下,这里都是1,所以都为1/3,但是有些同学可能就会问了,都写成0.5行不行,这里是不行的,在PAT里面小数点是有含义的,所以不能使用小数,这里都写成2是可以的,但是写成2是不是有点太2了,所以约定俗称的都写成1,但是如果每种情况的概率不一样,就可以写各种不同的数字)。
主持人开门行为:
Goat = []i:{Door1,Door2,Door3}@
ifb (i != car && i != guess) {
hostopen.i{goat = i} -> Skip
};
主持人开门肯定是在三个门里面选择一个门,而且这个门不能是有车的门,也不能是参与者选中的门。然后结束。
参与者换门行为:
TakeOffer = []i:{Door1,Door2,Door3}@
ifb (i != guess && i != goat) {
changeguess{guess = i; final = true} -> Stop
};
参与者换门也是在三个门里面选一个,而且这个门不能是他当前选中的门,也不能是主持人已经打开的门,然后换门,然后游戏结束(guess = i; final = true)。
参与者不换门行为:
NotTakeOffer = keepguess{final = true} -> Stop;
这里就是直接结束(final = true)。
接下来给了几个行为和对行为的分析:
放车,猜门,开羊门,换门,前面分析过,这个过程得到车的概率是2/3.
Sys_Take_Offer = PlaceCar; Guest; Goat; TakeOffer;
下面这个是对这个行为的验证:
#assert Sys_Not_Take_Offer reaches goal with prob;
我们来看分析结果
点击Verification

然后弹出来一个窗口:

点击第一个,然后进行验证

我们接着看后面的代码:
不换门:
Sys_Not_Take_Offer = PlaceCar; Guest; Goat; NotTakeOffer;
分析结果为:

下面来看一个坑爹的行为:
Sys_With_Dishonest_Program = Guest; PlaceCar; Goat; NotTakeOffer; //place after guessing
用户先猜,猜完了猜放车,然后主持人开门,然后不换门,大家觉得这个能中车的概率是多少,必须是从0到1啊。

接下来就是加大难度了,就是主持人有可能换车的位置。
HostSwitch = pcase {
: switch{car = guess} -> Skip
: Skip
};
看到有1/3可能把车放到参与者选中门上。
从上面的分析可以知道这样换门得到车的概率是4/9。不换门得到车的概率是5/9。
如下验证可以看到我们的结果是对的。


可以看到,PAT工具可以做一些简单的概率方面的验证工作。
下次有机会在分享。
形式化验证工具(PAT)羊车门代码学习的更多相关文章
- 形式化验证工具(PAT)Reader-Writers Problem学习
经过前几次的学习,我们应该对PAT有一点点的了解了,我们加下来就直接看例子中的一个问题,这个问题比较简单. 看代码: //The classic Readers/Writers Example mod ...
- 形式化验证工具(PAT)Perterson Algorithm学习
今天学习一下Perterson Algorithm. 这个算法是使用三个变量来实现并发程序的互斥性算法. 具体看一下代码: Peterson算法是一个实现互斥锁的并发程序设计算法,核心就是三个标志位是 ...
- 形式化验证工具(PAT)2PC协议学习
今天我们来看看2PC协议,不知道大家对2PC协议是不是了解,我们先简单介绍一下. 两阶段提交协议(two phase commit protocol, 2PC)可以保证数据的强一致性,许多分布式关系型 ...
- RChain的一键形式化验证:关于RCast 33 – LADL话题的讨论摘要
作者/Atticbee 在这一集,Greg和RChain的研究人员Isaac,Christian讨论了TLA(Temporal Logic of Actions)和RChain的LADL(Logic ...
- 羊车门问题(Python)
羊车门问题(结对作业) 在完成本题之前,请仔细阅读下面内容: 题目描述:有3扇关闭的门,一扇门后面停着汽车,其余门后是山羊,只有主持人知道每扇门后面是什么.参赛者可以选择一扇门,在开启它之前,主持人会 ...
- 《形式化分析工具Scyther性能研究》------摘抄整理
本篇论文的主要创新点在--------使用 Scyther工具发现对部分 KCI攻击搜索出现漏报的现象,并给出了存在的原因, 介绍了 形式化分析工具 AVispa全称是 Automated V ...
- 3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习
3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习 Hello小崔 华为技术有限公司 Linux内核开发 2 人赞同了该文章 LTP代码学习方法主要介绍两个步骤, ...
- 《SystemVerilog验证-测试平台编写指南》学习 - 第2章 数据类型
<SystemVerilog验证-测试平台编写指南>学习 - 第2章 数据类型 2.1 内建数据类型 2.2 定宽数组 2.2.1 声明 2.2.2 常量数组 2.2.3 基本的数组操作 ...
- LinqPad工具:帮你快速学习Linq
LinqPad工具:帮你快速学习Linq 参考: http://www.cnblogs.com/li-peng/p/3441729.html ★:linqPad下载地址:http://www.linq ...
随机推荐
- [独孤九剑]Oracle知识点梳理(三)导入、导出
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- (转载)Windows: "net use" command introduction
1)建立空连接: net use ""IP"ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立 ...
- MQTT事件回调流程
TLS 如下强调: 1.每个IOT设备应该有一对独有的公钥/私钥 2.SERVER的认证通过SERVER的"root certificate" SSL产生过程: $ openssl ...
- 蓝桥杯 算法训练 ALGO-122 未名湖边的烦恼
算法训练 未名湖边的烦恼 时间限制:1.0s 内存限制:256.0MB 问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都 ...
- 聊聊 SQL Joins
SQL 中的 Join 有以下几种类型: 1.Cross Join 交叉连接,没有条件筛选,返回笛卡尔积. 如果以 ,(逗号)分隔表名进行查询如 select * from tbl_name1, tb ...
- 杂项:Grunt
ylbtech-杂项:Grunt GRUNTJavaScript 世界的构建工具 1. 返回顶部 1. 为何要用构建工具? 一句话:自动化.对于需要反复重复的任务,例如压缩(minification) ...
- [置顶]
制作开机LOGO就是这么简单!
转自: http://mp.weixin.qq.com/s?__biz=MzAxNTAyOTczMw==&mid=2649328522&idx=1&sn=64107695fef ...
- 环形缓冲区的应用ringbuffer
在嵌入式开发中离不开设备通信,而在通信中稳定性最高的莫过于环形缓冲区算法, 当读取速度大于写入速度时,在环形缓冲区的支持下不会丢掉任何一个字节(硬件问题除外). 在通信程序中,经常使用环形缓冲区作为数 ...
- “百度杯”CTF比赛 十一月场(Misc)
签到题: 题目提示: 文件在i春秋的ctf2群里,加群下载文件 下载下来之后发现有压缩密码 题目提示有提示解压密码:key:ichunqiumemeda 打开文件,得到flag 签到题2: 点击下载附 ...
- Python多进程-进程间数据的共享
不同的进程不能同时修改一份数据,但是不同的进程能对一份数据进行修改 可通过Manager来实现进程间的数据共享 # -*- coding:utf-8 -*- __author__ = "Mu ...