操作系统形式化验证实践教程(7) - C代码的自动验证
上一节教程不知道大家看晕了没有,其实虽然细节很多还没有讲清楚,但是从结构上大家可以看到,其实是很模式化的工作。
那么能不能让这个模式化的工作自动化起来,也能降低一点入门的学习门槛?这时就该AutoCorres工具出马了。

AutoCorres
既然回到人间,不用再看着一排的simp, vcg之类的,咱们的难度又回到第一讲加减法的时代。

先实现一个C语言实现加法的函数:

unsigned int plus(unsigned int a, unsigned int b)
{
return a + b;
}
1
2
3
4
下面开始写HOL,先引入AutoCorres:

imports
“AutoCorres.AutoCorres”
1
2
然后还是把C源文件读进来,并且install了:

external_file “plus.c”
install_C_file “plus.c”
1
2
然后给c文件autocorres一下:

autocorres “plus.c”
1
按照惯例locale一下:

context plus begin
1
实际上执行的是:

locale Plus.plus
fixes symbol_table :: “char list ⇒ 32 word”
1
2
万事俱备,我们现在已经能读懂C代码了。

通过by eval验证具体例子
先写个case验证下:

lemma “plus’ 128 127 = 255”
1
C代码既然懂了,就直接unfold一下:

unfolding plus’_def
1
验证对不对,执行一下by eval,完整代码如下:

lemma “plus’ 128 127 = 255”
unfolding plus’_def
by eval
1
2
3
演绎验证
例子只能证明在这一种情况下是正确的,但无法证明在所有情况下都正确。我们有没有办法证明所有情况下都正确呢?
可以的,我们不用by eval了,换个apply的规则就好了:

lemma plus_correct: “plus’ a b = a + b”
unfolding plus’_def
apply (rule refl)
done

我们来看下目标:

proof (prove)
goal (1 subgoal):

  1. a + b = a + b

这真的也没啥可以证的了。。。

自动生成定理和证明
我们乘胜追击,再来搞个最大值的:

unsigned max(unsigned a, unsigned b)
{
if (a <= b) {
return b;
}
return a;
}

后面没啥惊喜的,一条龙:imports AutoCorres, external_file, install_C_file, autocorres, unfolding:

imports
“AutoCorres.AutoCorres”
begin

external_file “simple.c”

install_C_file “simple.c”

autocorres “simple.c”

context simple begin

lemma “max’ a b = max a b”
unfolding max’_def max_def
by (rule refl)

下面我们来个更强大的,自动生成定理和证明:

thm simple.max’_def simple.max’_ac_corres
1
生成的结果如下:

simple.max’ ?a ?b ≡ if ?a ≤ ?b then ?b else ?a
ac_corres (simple.lift_global_heap ∘ globals) True
simple_global_addresses.Γ ret__unsigned_’
((λs. a_’ s = ?a’) and (λs. b_’ s = ?b’) and
(λx. abs_var ?a id ?a’ ∧ abs_var ?b id ?b’) ∘
simple.lift_global_heap ∘
globals)
(L2_gets (λ_. simple.max’ ?a ?b) [’‘ret’’])
(Call max_'proc)

虽然autocorres不会知道max跟库中的max有啥关系,但是可以生成if ?a ≤ ?b then ?b else ?a这样的定理。

验证并非是重复代码逻辑
刚才我们看到加法还有最大值,已经都被autocorres轻松消解掉了,连定理和证明都可以自动生成了。
但是,实际上,形式化验证并没有这么简单。
我们看个求最大公约数的例子:

unsigned gcd(unsigned a, unsigned b)
{
unsigned c;
while (a != 0) {
c = a;
a = b % a;
b = c;
}
return b;
}

这个如何验证?

自动生成下:

thm simple.gcd’_def simple.gcd’_ac_corres
1
结果如下:

simple.gcd’ ?a ?b ≡
do (a, b) <- whileLoop (λ(a, b) b. a ≠ 0)
(λ(a, b). return (b mod a, a))
(?a, ?b);
return b
od
ac_corres (simple.lift_global_heap ∘ globals) True
simple_global_addresses.Γ (unat ∘ ret__unsigned_’)
((λs. a_’ s = ?a’) and (λs. b_’ s = ?b’) and
(λx. abs_var ?a unat ?a’ ∧ abs_var ?b unat ?b’) ∘
simple.lift_global_heap ∘
globals)
(liftE (simple.gcd’ ?a ?b)) (Call gcd_'proc)

这重复了下实现逻辑没错,但是没有体验中最大公约数的本质。

我们来看下seL4中的实现吧:

lemma gcd_to_return [simp]:
“gcd’ a b = return (gcd a b)”
apply (subst monad_to_gets [where v=“λ_. gcd a b”])
apply (wp gcd_wp)
apply simp
apply (clarsimp simp: gcd’_def)
apply (rule empty_fail_bind)
apply (rule empty_fail_whileLoop)
apply (clarsimp simp: split_def)
apply (clarsimp simp: split_def)
apply (clarsimp simp: split_def)
done

其中,monad_to_gets是一个辅助定理:

lemma monad_to_gets:
“⟦ ⋀P. ⦃ P ⦄ f ⦃ λr s. P s ∧ r = v s ⦄!; empty_fail f ⟧ ⟹ f = gets v”
apply atomize
apply (monad_eq simp: validNF_def valid_def no_fail_def empty_fail_def)
apply (rule conjI)
apply clarsimp
apply (drule_tac x=“λs’. s = s’” in spec)
apply clarsimp
apply force
apply clarsimp
apply (drule_tac x=“λs’. s’ = t” in spec)
apply clarsimp
apply force
done

求最弱前置条件gcd_wp为:

lemma gcd_wp [wp]:
“⦃ P (gcd a b) ⦄ gcd’ a b ⦃ P ⦄!”
(* Unfold definition of “gcd’”. *)
apply (unfold gcd’_def)

(* Annoate the loop with an invariant and measure. *)
apply (subst whileLoop_add_inv [where
I=“λ(a’, b’) s. gcd a b = gcd a’ b’ ∧ P (gcd a b) s”
and M=“λ((a’, b’), s). a’”])

(* Solve using weakest-precondition. *)
apply (wp; clarsimp)
apply (metis gcd.commute gcd_red_nat)
using gt_or_eq_0 by fastforce

这种水平的验证我们暂时还写不出来,大家只要有个概念就好,后面针对常见算法的验证方法我们用到再讲。

原文链接:https://blog.csdn.net/lusing/article/details/107943362?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-8.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-8.nonecase&request_id=5f3387ec8c9fb674c6724168

操作系统形式化验证实践教程(7) - C代码的自动验证(转载)相关推荐

  1. 操作系统形式化验证实践教程(7) - C代码的自动验证

    操作系统形式化验证实践教程(7) - C代码的自动验证 上一节教程不知道大家看晕了没有,其实虽然细节很多还没有讲清楚,但是从结构上大家可以看到,其实是很模式化的工作. 那么能不能让这个模式化的工作自动 ...

  2. 操作系统形式化验证实践教程(10) - 一阶直觉逻辑

    操作系统形式化验证实践教程(10) - 一阶直觉逻辑 前面我们用了九讲的篇幅把seL4验证操作系统的地图给大家迅速过了一遍,基础好的同学已经可以基于前面的知识开始自己的工作了. 对于只学过离散数学,而 ...

  3. 操作系统形式化验证实践教程(11) - 结构化证明语言Isar(转载)

    操作系统形式化验证实践教程(11) - 结构化证明语言Isar 结构化证明语言Isar基本语法 apply方法和by方法虽然可以完成功能,但是看起来更像是命令式语言.使用Isar语言,还可以写得更加形 ...

  4. 操作系统形式化验证实践教程(11) - 结构化证明语言Isar

    操作系统形式化验证实践教程(11) - 结构化证明语言Isar 结构化证明语言Isar基本语法 apply方法和by方法虽然可以完成功能,但是看起来更像是命令式语言.使用Isar语言,还可以写得更加形 ...

  5. ​网页图表Highcharts实践教程之图表代码构成

    ​网页图表Highcharts实践教程之图表代码构成 Highcharts第一个实例 下面我们来实现本书的第一个Highcharts实例. [实例1-1]下面来制作北京连续一周最高温度折线图.操作过程 ...

  6. 网页图表Highcharts实践教程之图表代码构成

    网页图表Highcharts实践教程之图表代码构成 Highcharts第一个实例 下面我们来实现本书的第一个Highcharts实例. [实例1-1]下面来制作北京连续一周最高温度折线图.操作过程如 ...

  7. java jwt 验证_教程:用Java创建和验证JWT

    java jwt 验证 "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多 ...

  8. php 自动验证表单类,thinkPHP 表单自动验证功能

    昨天晚上我们老大叫我弄表单自动验证功能,愁了半天借鉴了好多官网的知识,才出来,诶,总之分享一下我自己的成果吧! thinkphp 在Model基类为我们定义了自动验证的函数和正则表达式,我们只需要在对 ...

  9. Playmaker全面实践教程之简单的使用Playmaker示例

    Playmaker全面实践教程之简单的使用Playmaker示例 简单的使用Playmaker示例 通过本章前面部分的学习,相信读者已经对Playmaker有了一个整体的认识和印象了.在本章的最后,我 ...

最新文章

  1. Java并发之synchronized关键字
  2. TCL withSNPS info existscreate_cellcreate_netconnect_net
  3. python怎么只打印其中一行_如何在Python中让两个print()函数的输出打印在一行内?...
  4. leetcode之回溯backtracing专题4
  5. 16个SNS网站常用JS组件
  6. 从头到尾谈一下HTTPS
  7. error LNK2005: DllMain 已经在MSVCRT.lib中定义
  8. 基于MATLAB的无线视频传输
  9. centos7修改mysql默认端口号_修改mysql默认端口方法(linux centos 7)
  10. python 直播源地址_斗鱼直播间真实rtmp地址获取(含工具类下载)
  11. 数据架构选型必读:2021上半年数据库产品技术解析
  12. 小米造车follow苹果路线?智能驾驶能力是个关键问题
  13. 相机模型(针孔、广角)
  14. SpringBoot集成onlyoffice实现word文档编辑保存
  15. 高等数学上学习总结(集合,邻域,函数)
  16. 【查找算法】折半查找法
  17. android学习步骤
  18. 【Qt】实现一个计算器
  19. 【笔记】《算法设计与分析(第三版)》-王晓东著-第3章-动态规划
  20. 安装python包时报‘HTMLParser‘ object has no attribute ‘unescape‘

热门文章

  1. 正则表达式的贪婪型,勉强型,占有型
  2. 统计学习的基本概念和分类
  3. 代码合乱了,git怎么强制覆盖分支?
  4. mathtype一步将word自带的公式编辑器的公式换成mathtype类型
  5. 雷林鹏分享:Ruby 字符串(String)
  6. (精)反激式开关电源
  7. Windows server 2012R2下流媒体服务器的配置与管理
  8. 第一次亲密接触IT技术(第一天)
  9. 10组团队项目-Alpha冲刺-5/6
  10. 驾校学车VIP班和普通班区别是什么?