形式语义入门和Isabelle定理证明
引用知乎用户“Jason Hu”的一句话“如果学习编程语言,只学语法,那确实只是工具;学到了语义,你才学到了思想。”。
程序的语义:程序P表示一个状态的转换,而状态是指一个从变量到值得映射。
program P represents a transformation on the state. State means a function from variable to values:e.g. var -> int.
操作语义:操作语义,定义程序如何运行,Operational Semantic包括大步语义(自然语义)和小步语义(结构语义)。
大步语义:给定程序c和状态s和t,$(c,s)\Rightarrow t$ 表示程序c可以把状态s转换到状态t。
1 程序的终止性Termination:程序不存在失败的可能性。
2 程序的确定性Determination:从任何程序开始只有唯一的执行路径。
3 两个程序的等价性:两个程序语法上写起来不一样但是行为是一样的。
大步语义-skip语句、赋值语句和顺序的规则
其中$s( v:= [e]_s )$ 的含义为,该状态和s一样,除了v的值变为$[e]_s$之外。
小步语义,又叫结构语义。(c,s)→(c',t),执行c,从状态s到状态t,c'是剩余需要执行的程序。
Denotational Semantics 指称语义:
1. 为程序赋予数学的Object
2. 应该是递归定义的关系,指称语义应该是递归定义的。
Higher-order Logic
Hoare Logic霍尔逻辑
基于不变式(invariant)证明是容易出错的,Hoare逻辑是一个结构化的形式化证明方法,很容易通过计算机来检验。
Hoare三元组(a Hoare Triple):{P} c {Q},分别为:Precondition Program Postcondition
部分正确性(Partial correctness)指,如果P初始正确,程序如果终止,那么Q在结束的时候正确。
完全正确性(Total correctness):如果P初始正确,那么c终止并且Q在终止状态正确。
显然,完全正确性=部分正确性+终止性。
三元组如下:
{x=5} x:= x+5 {x=10}
{true} x:=10 {x=10}
1. 给定以下Hoare三元组
{a>=0 and c=0}
while a>0 do
a:=a-1
c:=c+b
{c=a·b}
由于终止状态下a=0因此该三元组不成立。
修改为如下 Example 1:
{a=A and c=0 and A>=0}
while a>0 do
a:=a-1
c:=c+b
{c=A·b}
2. 给定如下Hoare三元组
{a=1 and n>=0 and b=1}
while a<=n do
b := b·a
a := a+1
{b=n!}
缺陷是,即使某个程序不是用来计算阶乘的,也会满足这个规约。
改进为如下 Example 2:
{a=1 and n=N and N>=0 and b=1}
while a<=n do
b:=b·a
a:=a+1
{b=N! and n=N}
3. 定义二分搜索能够达到正确值如下:
{array(a, A) and x=X and exists i. X=A[i]}
binary_search(a, x) (return value at b)
{array(a,A) and x=X and A[b]=X}
Hoare逻辑通过一组有限的规则集合定义,例如大步语义和小步语义,例如命题逻辑、谓词逻辑。
Hoare三元组可证明(Provable)是指它可以通过这组规则推导出(derived from)。
Hoare Rules:
Skip:$\vdash$ {P} skip {P}
Assignment:$\vdash$ {P[a/x]} x:=a {P}。把P中x的出现替换为a。
Sequence:$\frac{\vdash{P_1}c_1{P_2} \vdash{P_2}c_2{P_3}}{\vdash{P_1} c_1;c_2{P_3}}$
if:
$\vdash${P1}c1{Q} $\vdash${P2}c2{Q}
$\vdash${if b then P1 else P2} if b then c1 else c2 {Q}
while:
$\vdash${P and b} c {P}
$\vdash${P} while b do c {P and not b}
Consequence rule,该规则允许我们替换前置条件或者后置条件,即可以把前置条件换成更强的条件,或者把后置条件换成更弱的条件:
$P' \to P \vdash${P} c {Q} $Q \to Q'$
$\vdash$ {P'} c {Q'}
{}{}{}
Isabelle语法
文件开头
theory Scratch
imports Main
begin
类型查看
下面分别是:自然数类型,布尔值类型 和 表达式定义的类型,其中5、6一样,表明了类型是右结合的。
typ nat typ bool typ "nat ⇒ bool" typ "(nat ⇒ bool) ⇒ bool" typ "nat ⇒ (bool ⇒bool)" typ "nat ⇒ bool ⇒ bool"
定义变量
term "(1::nat) + 3" term "(1::nat)+(2::int)" term "(1::int)+(2::int)" term "λx::nat. x + 2" term "λx::nat. x+1 > 2" term "λx::nat .λy::nat .x^2+y^2"
第一行代码输出:"1 + 3" :: "nat"
第2行代码报错,因为Isabelle不支持不同类型之间的运算
第3行代码输出:"1 + 2" :: "int"
第4行代码输出:"λx. x + 2" :: "nat ⇒ nat"
第5行代码输出:"λx. 2 < x + 1" :: "nat ⇒ bool"
第6行代码输出:"λx y. x^2 + y^2" :: "nat ⇒ nat ⇒ nat"
计算数值
value "(1::nat)+2" value "((2::nat)+3)*6" term "(λx::nat .x +2) 3" value "(λx::nat .x +2)3"
输出
”3“::nat
"30"::nat
"3+2"::nat
"5"::nat
自然数和整数的区别
value "(5::nat)-3" value "(5::int)-3" value "(2::int)-3" value "(2::nat)-3"
输出:
"2"::nat
"2"::int
"-1"::int
"0"nat
表达式定义
value "if (3::nat)<3 then 2::nat else 3" term "let x=3 in x+(2::nat)" value "let x=3 in x+(2::nat)"
输出:
"3"::"nat"
"let x = 3 in x + 2" :: "nat"
"5"::"nat"
谓词定义
term "plus (2::nat) 3" term "All (λx .x<2)" term "Ex (λx .x<2)"
"5"::nat
全称量词
存在量词
定义自然数类型,进行归纳证明
下述代码含义为,自定义类型my_nat,由zero和my_nat的后继递归定义。
调用其归纳方法
datatype my_nat = zero | suc my_nat thm my_nat.induct
output:“?P zero ⟹ (⋀x. ?P x ⟹ ?P (suc x)) ⟹ ?P ?my_nat”
自定义my_nat的加法(皮亚诺算数定义)
fun add :: "my_nat ⇒ my_nat ⇒ my_nat" where add_zero: "add zero n=n" (* 0 + n = n*) | add_suc: "add (suc m) n = suc (add m n)" (* suc m + n = suc(m + n)*) thm add.simps thm add.simps(2) thm add_zero thm add_suc
下面四个调用,分别是
1.
add zero ?n = ?n
add (suc ?m) ?n = suc (add ?m ?n)
2. add (suc ?m) ?n = suc (add ?m ?n)
3. add zero ?n = ?n
4. add (suc ?m) ?n = suc (add ?m ?n)