函数式编程语言、编程和程序验证 计算机科学与技术学院 陈意云 2010.7.

Slides:



Advertisements
Similar presentations
完美殺人筆記簿 【爸!我受夠了!】 第七組組員: 林正敏 陳筱涵 李蓓宇 許純宜 羅玉芬 謝文軒.
Advertisements

揭日本人让人理解不了的20件事 今天先来看看日本人的自我剖析︰日本人的20个“为什么”?这“20个为什么”的内容来源于日本影视名人北野武所主持的一个节目。虽然不是网友来信中提出过的问题,但看看日本人自己对自己的分析,是挺有意思的。而且,仔细看看下面这“日本人的20个为什么”,会发现其实有些东西对于中国人来说并不陌生。毕竟汉字圈里的文化,是有共融之处的。
审核评估释义 余国江 教学质量监控与评估处.
股指期货的风险及防范.
2017/3/12 儿童常见病防治 XX XX XX 公司名称 第一季度工作报告 潍坊市妇幼保健院.
本章重點 認識衣物的基本保養程序 處理不同污漬的方法 不同布料的保養方法
程序设计语言理论 计算机科学与技术学院 陈意云,
产学研项目财务管理若干问题 鲁春艳
班級:醫管3B 組別:第二組 組員:王品媛、郭雅瑄、謝淑玲、蔡孟蔙
电子成绩单项目实现.
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
自信心训练教材 如何提高自己的自信心 -Jerrywang.
十五條佛規 後學:張慈幸
贵州分公司 工作总结报告 发起人: 山大鲁能.
请说出牛顿第一定律的内容。.
本章重點 認識香港不同年代時裝的特色 透過對服裝歷史的認識,了解香港的穿衣文化 透過服裝歷史加強對時裝潮流循環的洞悉力
九阳通过社会化媒体开卖面条机.
肺 痨.
道路交通管理 授课教师:于远亮.
作文教学如何适应高考的要求 漳州市普教室 李都明
心痛 中医内科学.
植物的繁殖方式与育种 第2章.
第一节 产后出血 了解:了解产后出血的概述。 熟悉:产后出血的病 因病机。 掌握:产后出血诊断处理及 预防调摄。 教学目标.
跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾. 跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾.
关注品德与生活课的 探究性学习和微课程的发展
第三章 鏈結串列 Linked List.
特殊教育課程與教學調整現場實務 特教小組 執行秘書 林坤燦.
电话联系.
迎宾员礼仪 包头机电工业职业学校管理系 白琳 1.
形式化验证的非正式介绍 南京大学计算机系 赵建华.
看图找关系.
3.1.2 概率的意义.
主讲:江西财经职业学院傅文清 联系电话: 教学模式与课程教学设计 主讲:江西财经职业学院傅文清 联系电话:
22 第 课 增强自我保护的意识和能力.
在课题探索中成长 东风东路小学 王洁华 全国红领巾示范学校 广东省一级学校
关注女职工劳动保护,维护女职工合法权益 ——《女职工劳动保护特别规定》解读
逃出生天游戏介绍 胡永泽 高振卓 答辩人:.
慈禧药方(人参健脾丸) 【简介】:清代太医院的设制基本上沿袭了明朝的旧制,顺治1644年设太医院为独立的中央医事机构,为帝后及宫内人员诊视疾病、配制药物,也担负其他医药事务。此为宫廷处方,内容如下: 老佛爷 人参健脾丸 党参七钱 白术二钱 怀山药七钱 炒 薏米五钱六分 欠实五钱六分 广皮一钱.
财 务 会 计 第四篇:供应链会计实务 制作人:谌君、熊瑜.
C 程式設計— 結構 台大資訊工程學系 資訊系統訓練班.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.
Chap 2 用C语言编写程序 2.1 在屏幕上显示 Hello World! 2.2 求华氏温度 100°F 对应的摄氏温度
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
第六章 运行时存储空间的组织和管理 术语 本章内容 讨论一个活动记录中的数据布局 程序执行过程中,所有活动记录的组织方式 过程的活动
第10章 子定型 子定型是类型上的一种关系,该关系隐含一个类型的值可以代替另一个类型的值
C 程式設計— 結構 台大資訊工程學系 資訊系統訓練班.
第四章 程序语言的性质.
第6章 继承和接口设计 6.1 继 承 6.2 多态性 6.3 抽象类 6.4 接口 6.5 接口在集合排序中的应用.
第 8 章 过程.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
语义分析概述 符号表 第六章 语义分析.
給你講一個故事 ﹕ 獻給所有未婚,將要結婚,和已婚的好朋友!!
第11章 指称语义的原理与应用 指称语义学是Christopher Strachey和Dana Scott在1970年提出的。指称语义学是Christopher Strachey和Dana Scott在1970年提出的。指称语义学是Christopher Strachey和Dana Scott在1970年提出的。
第5章 函数式程序设计语言 过程式程序设计语言由于数据的名值分离, 变量的时空特性导致程序难于查错、难于修改
OOP6 結構Struct 黃兆武.
第六章 语法制导的翻译 本章内容 介绍一种语义描述方法:语法制导的翻译,介绍语法制导的翻译的实现方法。
形式语义学 Formal Semantics
四川农业大学 第二十二期团校课程 第四讲:校团委日常公文与写作 主讲人:刘瀛锴.
北投溫泉博物館 建築特色 ★小組成員:高103林孟璇、林念儀、施妤柔★.
保留字與識別字.
习题课
水利绿色发展问题与建议 姜文来 中国农业科学院农业资源与农业区划研究所.
資料結構簡介 綠園.
第三章 世界文明的蛻變與互動 第一節 歐洲社會的蛻變 第二節 世界文明的交匯 第三節 亞洲大帝國的發展 1.
單元名稱:結構化程式設計 報告人 劉洲溶.
第18讲 从C到C++ 计算机与通信工程学院.
由一个佯谬看涡旋电流的存在 PB 田鸿翔 指导老师 万树德.
此处添加标题 汇报人:宝藏PPT.
安排座位.
Presentation transcript:

函数式编程语言、编程和程序验证 计算机科学与技术学院 陈意云 2010.7

内 容 提 要 学习函数式语言是因为课程实践所用工具中, 需要用函数式风格编程。另外,需要对比函数式 程序和命令式程序在程序验证上的区别 内 容 提 要 学习函数式语言是因为课程实践所用工具中, 需要用函数式风格编程。另外,需要对比函数式 程序和命令式程序在程序验证上的区别 函数式编程语言概述 演算简介 函数式语言SML及编程简介 函数式语言SML的模块系统 函数式程序的验证

函数式编程语言概述 函数式编程是一种编程范型 它把计算看作是对数学函数的求值,避免了状态和易变数据结构 函数是构造程序的基本成分,语言还提供构造更为复杂的函数的机制,语言禁止使用赋值语句 函数式编程的根基是演算 演算是1930年代在调查函数定义、函数应用和递归时研发的一个形式系统,是等价于图灵机的一种抽象的计算模型 许多函数式编程语言都可看成是在演算基础上精心制作出的结果 3

函数式编程语言概述 函数式与命令式的比较 函数式编程强调函数应用,而命令式编程风格强调状态的改变 命令式程序的“函数”有副作用,如改变全局变量 命令式程序缺乏引用透明性,副作用是其根源 引用透明性:可自由地将(子)表达式替换为它的值而不改变程序(表达式) 函数式程序中,函数的结果仅依赖于提供给它的参数 没有副作用使得理解程序和预测程序的行为变得容易,这是研究函数式语言的一个关键动机 4

函数式编程语言概述 函数式语言的用途 历史上,(纯)函数式语言一直被学术界(而不是商用软件研发)重视 现在,Scheme, OCaml和Haskell等函数式语言已经出现在工业和商业应用中 通过领域专用编程语言,函数式编程有更广阔的天地,如Mathematica(符号数学)、R(统计)、J和K(金融分析) 函数式编程的风格也可用于不是专为函数式编程设计的语言中,如Javascript融入了函数式编程的功能,类似的还有Perl语言 5

 演 算 简 介 1、表示法 表示法的主要特征 抽象的例子 (自然数类型上的几个例子) 表示法写出的表达式叫做表达式或项  演 算 简 介 1、表示法 表示法的主要特征 抽象:用于定义函数 应用:将所定义的函数作用于变元 抽象的例子 (自然数类型上的几个例子) 恒等函数:x : nat.x // 命令式表示Id(x : nat) = x 后继函数:x : nat.x  1 // 函数式无需给函数命名 常函数:x : nat.10 x : nat.x  true 不是良形的表达式 表示法写出的表达式叫做表达式或项 6

 演 算 简 介 项x : .M 和谓词演算公式x : A. 的比较 应用:用项的并置来表示函数应用,例: 是一个约束算子  演 算 简 介 项x : .M 和谓词演算公式x : A. 的比较 是一个约束算子 x是一个占位符,约束变元,可以重新命名约束变元而不改变表达式的含义 在x:.x + y中,x的出现是约束的, y的出现是自由的 不含自由变元的表达式称为闭表达式 应用:用项的并置来表示函数应用,例: (x : nat.x) 5 (x : nat.x) 5  5 /*应用下页介绍的公理*/ 7

 演 算 简 介 2、演算 演算是关于表达式的一个推理系统,下面用等式公理系统(公理语义)来描述 约束变元改名公理(公理)  演 算 简 介 2、演算 演算是关于表达式的一个推理系统,下面用等式公理系统(公理语义)来描述 约束变元改名公理(公理) x:.M  y:.yxM,M中无自由出现的y NxM表示M中自由出现的x用表达式N代换的结果 例如 x:.x  y:.y 函数应用公理(公理) (x:.M)N  [N/x]M 例如 (x:nat.x+4) 4  [4/x](x+4)  4 + 4 8

 演 算 简 介 自反公理、对称性规则、传递性规则 同余规则 等式证明规则允许推导任何一组等式前提的逻辑推论  演 算 简 介 自反公理、对称性规则、传递性规则 同余规则 相等的函数作用于相等的变元产生相等的结果 等式证明规则允许推导任何一组等式前提的逻辑推论 还可以定义演算的操作语义和指称语义 M1 = M2, N1 = N2 M1 N1 = M2 N2 9

 演 算 简 介 简单例子 ( x. ( y. z. ( x + y ) + z ) 3 ) 4 5  演 算 简 介 简单例子 ( x. ( y. z. ( x + y ) + z ) 3 ) 4 5 = ( x. z. ( x + 3 ) + z ) 4 5 = ( z. ( 4 + 3 ) + z ) 5 = ( 4 + 3 ) + 5 = 12 10

 演 算 简 介 复杂例子:高阶函数应用到函数,得到函数 该例体现函数式语言区别命令式语言的优点  演 算 简 介 复杂例子:高阶函数应用到函数,得到函数 Curry,  f :  . x:. y:. f x, y add  p:nat  nat. (Proj1 p) + (Proj2 p) Curry(add) = x:nat. y:nat. x + y 演算过程在下页,给Curry加上角标是避免引入多态 该例体现函数式语言区别命令式语言的优点 函数作为编程语言的第一类实体,即对它们的使用没有限制 可以动态地构造新函数 11

 演 算 简 介 复杂例子:高阶函数应用到函数,得到函数 Curry(add)  演 算 简 介 复杂例子:高阶函数应用到函数,得到函数 Curry(add)  (f:nat  nat  nat. x:nat. y:nat. f x, y) add = x:nat. y:nat. add x, y  x:nat. y:nat. (p:nat  nat. (Proj1 p) + (Proj2 p)) x, y = x:nat. y:nat. Proj1x, y + Proj2 x, y = x:nat. y:nat. x + y 12

函数式语言SML及编程简介 使用Standard ML语言,简称SML 例1(整型): 辗转相除法求最大公约数 fun gcd(m, n) = /*函数声明表达式 */ if m = 0 then n else gcd(n mod m, m); > val gcd = fn : int  int -> int /* SML的回应 */ gcd(13, 78) /*函数应用表达式*/ > 13 : int 程序由一个或多个表达式构成 程序都可以翻译成类型化的表达式,在此不介绍 SML还有其他基本类型:real, bool, string等 13

函数式语言SML及编程简介 例2(积类型):把分数n/d约分到最简分式 fun fraction(n, d) = /*(n, d)是int  int的元素 */ let val com = gcd(n, d) in (n div com, d div com) end; > val fraction = fn : int  int -> int  int 引入let后,表达式的一般形式是 let D1 D2 … Dn in E end let 引入的声明相当于命令式语言的局部声明,let声 明可以嵌套,联立的let可用来声明相互递归的函数 使用let可使程序简洁,免去重复计算公共子表达式 14

函数式语言SML及编程简介 例3(记录类型) type student = { name : string; age : int; score : real } > type student 记录是具有标签的元组 15

函数式语言SML及编程简介 例4(多态类型) fun gcd(m, n) = if m = 0 then n else gcd(n mod m, m); 其中的if … then …else 是一个内部定义的多态函数 if … then …else = fn : bool  a  a  a 其中a是类型变量,类型变量以撇号开始 16

函数式语言SML及编程简介 例4(多态函数)取二元组的第1元和第2元 fun fst(x, y) = x; > val fst = fn : a  b  a fun snd(x, y) = y; > val snd = fn : a  b  b 17

函数式语言SML及编程简介 表的简介 表(list)是相同类型元素的有限序列 如:[3, 5, 9], [ (1, “one”), (2, “two”), (3, “three”) ] 表的构造符 空表:[ ] 在已有的表前加入一个元素::: 9 :: [ ] = [9], 5 :: [9] = [5, 9] 基本的表函数 null(测试空表)、hd(返回表头元素)、tl(返回非空表的表尾)、length(返回表长) 18

函数式语言SML及编程简介 例5(表类型)计算表的长度 fun length [ ] = 0 | length (x :: xs) = 1 + length xs; > val length = fn : a list -> int length [3, 5, 9] length [“one”, “two”, “three”] > 3 : int > 3 : int 竖线“ | ”将函数声明分成两子句,各处理一个模式 length是一个多态类型的函数 list相当于一个类型构造符 19

函数式语言SML及编程简介 例6(表类型)插入排序 fun insert(x, [ ]) : real list = [ x ] | insert(x, y :: ys) = if x <= y then x :: y :: ys else y :: insert(x, ys); > val insert = fn : real  real list -> real list 排序需要用到两个变元的比较运算,关系运算“<=”不是多态的,因此insert不是多态函数 在第1行上给出函数的结果类型就是为了避免类型推断出现错误 20

函数式语言SML及编程简介 例7(表类型)基于表的一个高阶函数 fun map f [ ] = [ ] | map f (x :: xs) = (f x) :: map f xs; > val map = fn : (a -> b) -> (a list -> b list) 算子map把函数 f 应用到表的每个元素上,即 map f [x1, …, xn] = [f x1, …, f xn] map f的结果是一个新函数 21

函数式语言SML及编程简介 例8 静态作用域(静态绑定) let val x = 2 例8 静态作用域(静态绑定) let val x = 2 fun f y = x + y /* x是函数f的非局部变量*/ fun F (g, x) = g 2 in F(f, 1) 按静态作用域和动态作用域,结果分别为4和3 f函数所引用的x绑定到2,这样的绑定成为f的环境 在计算F(f, 1)时,必须把f和它的环境ef一起传递,以保证f不管在何处计算都有正确的计算环境 二元组(f, ef) 称为闭包,是语言实现中的概念 22

函数式语言SML的模块系统 模块化关心的是程序的组织,而不是计算本身,模块 化结构使得程序易于理解、编写和维护等 结构:由一组类型、值和结构的声明组成 基调:是结构的“类型”或“界面”,规范结构必须包含的声明 函子:从结构到结构的函数 类比:(模块化) 结构 ~(核心语言) 值 基调 ~ 类型 函子 ~ 函数 23

函数式语言SML的模块系统 例9:使用模块系统的一个简单例子 signature SIG = /* 描述有类型t和值x的结构类 */ sig type t val x : t end; structure S : SIG = /* 符合上述基调的一个结构*/ struct type t = int val x : t = 3 可以用基调来规范结构的部分成员 24

函数式语言SML的模块系统 例9:使用模块系统的一个简单例子 structure S : SIG = /* 符合上页基调的一个结构*/ type t = int val x : t = 3 end; functor F(S : SIG) : SIG = type t = S.t  S.t val x : t = (S.x, S.x) end 25

函数式程序的验证 程序验证就是证明程序具有所期望的性质,它是提高软件可信程度的重要方法 1、模型检测 通过遍历系统所有状态空间,能够对有穷状态系统进行自动验证,并自动构造不满足验证性质的反例 问题:难以解决状态空间爆炸问题,不能输出显式的证据 2、形式程序验证(formal program verification) 命令式语言的程序验证起源于Hoare逻辑 函数式程序验证因不涉及程序状态,要简单得多 26

函数式程序的验证 例10:用数学归纳法验证计算阶乘的函数 fun facti(n, p) = if n = 0 then p else facti(n -1, n * p); 要证明的性质是p. facti(n, p) = n!  p 1、基本情况,要证p. facti(0, p) = 0!  p 因为facti(0, p) = p = 1  p = 0!  p,成立 2、归纳步骤,要证p. facti(n+1, p) = (n+1)!  p facti(n+1, p) = facti(n, (n+1) * p) [facti] = n!  ((n+1)  p) [归纳假设] = (n!  (n+1))  p [结合律] = (n+1)!  p [阶乘] 和已经熟悉的证明方式没有什么区别 27

函数式程序的验证 例11:用结构归纳验证表并置前后的表长关系 fun length [ ] = 0 | length(x::xs) = 1 + length xs; fun [ ] @ ys = ys /*@是中缀的函数名*/ | (x::xs) @ ys = x :: (xs@ys); 要证的性质是length(xs@ys) = length(xs) + length(ys) 1、基本情况 length([ ]@ys) = length ys [@] = 0 + length ys [算术] = length [ ] + length ys [length] 成立 28

函数式程序的验证 例11:用结构归纳验证表并置前后的表长关系 fun length [ ] = 0 | length(x::xs) = 1 + length xs; fun [ ] @ ys = ys | (x::xs) @ ys = x :: (xs@ys); 要证的性质是length(xs@ys) = length(xs) + length(ys) 2、归纳步骤 length((x::xs)@ys) = length(x::(xs@ys)) [@] = 1 + length(xs@ys) [length] = 1 + length xs + length ys [归纳假设] = (1 + length xs) + length ys [结合律] = length(x::xs) + length ys [length] 成立 29

函数式程序的验证 良基关系 例:在自然数上,如果j  i +1,则i  j,则这个关系是一个良基关系 良基关系的一些特点 集合A的良基关系是A上的二元关系,它具有这样的性质:A上不存在无穷递减序列a0  a1  a2  … 例:在自然数上,如果j  i +1,则i  j,则这个关系是一个良基关系 良基关系的一些特点 良基关系不一定有传递性 良基关系都是非自反的,即对任何aA,a  a不成立;否则会出现无穷递减序列a  a  a  … 每个非空子集都有一个极小元 30

函数式程序的验证 良基归纳 令是集合A上的一个良基关系, 令P是A上的某个性质, 若每当所有的P(b) (b  a)为真则P(a)为真,即 a.( b. (b  a  P(b))  P(a) ) 那么,对所有的aA,P(a)为真 31

函数式程序的验证 例12:用良基归纳法 y. facti(n, p) = fact(n)  p 其中 fun facti(n, p) = if n = 0 then p else facti(n -1, n  p); fun fact(n) = if n = 0 then 1 else fact(n -1)  n; 自然数集合,使用的良基关系是: 若i = j – 1,则i  j 按良基归纳的概念进行证明 32

函数式程序的验证 fun facti(n, p) = if n = 0 then p else facti(n -1, n  p); fun fact(n) = if n = 0 then 1 else fact(n -1)  n; 待证:y. facti(n, p) = fact(n)  p 证明: 1、若n=0,则 facti(n, p) = p = 1  p = fact(n)  p 2、若n>0,则 facti(n, p) = facti(n -1, n  p) [facti] = fact(n-1)  (n  p) [归纳假设] = (fact(n-1)  n)  p [结合律] = fact(n)  p [fact] 33