没有合适的资源?快使用搜索试试~ 我知道了~
康奈尔 CS4110 编程语言与逻辑讲义.pdf
需积分: 5 0 下载量 10 浏览量
2024-02-03
12:13:15
上传
评论
收藏 3.46MB PDF 举报
温馨提示
试读
111页
康奈尔 CS4110 编程语言与逻辑讲义
资源推荐
资源详情
资源评论
CS 4110 – 程序设计语言与逻辑学
讲座 #2: 语义学导论
程序的意义是什么? 当我们编写程序时,我们使用字符序列来表示它。 但是这些字符串只是具体
的语法,它们并不能告诉我们程序的实际含义。 通过执行程序来定义意义是很诱人的——可以使
用解释器或编译器。 但是解释器和编译器经常会有错误!我们可以查阅规范手册。但是这些手册
通常只提供语言构造的非正式描述。
定义意义的更好方法是开发一种形式化的、数学的语义学定义。 这种方法是明确的、简洁的,
最重要的是,它使得能够对感兴趣的属性进行严格的证明。 主要的缺点是语义学本身可能非常复
杂,特别是如果试图模拟现代完整的编程语言的所有特性。
有三种定义语言含义或语义的方式:
操作语义通过在抽象机器上执行来定义含义。
指称语义通过数学对象(如函数)来定义含义。
公理语义通过在执行过程中满足的逻辑公式来定义含义。
这些方法各有优缺点,涉及到数学上的复杂性、在证明中的使用难度以及在解释器或编译器实现
中的使用难度。 我们将在本课程的后面讨论这些权衡。
1 算术表达式
为了理解语义的一些关键概念,让我们考虑一个非常简单的整数算术表达式与变量赋值的语言。
这种语言中的程序是一个表达式;执行一个程序意味着将表达式求值为一个整数。 为了描述这种
语言的语法结构,我们将使用范围为以下域的变量:
变量
整数
表达式
变量是程序变量的集合(例如, foo, bar, baz, i等)。整数是常量整数的集合(例如, 42, 4
0, 7)。表达式是表达式的域,我们使用BNF(巴科斯-诺尔范式)语法来指定:
::= x
1
+
2
1
*
2
:=
1
;
2
1
非正式地,表达式 :=
1
;
2
表示在评估
2
之前, 被赋予
1
的值。
整个表达式的结果是由
2
描述的值。
这个语法规定了语言的语法。 这里的一个问题是语法是有歧义的。 考虑表达式 1 + 2 * 3。 可以
构建两个抽象语法树:
+
1
*
2 3
*
+
1 2
3
有几种方法来解决这个问题。 一种方法是重新编写相同语言的语法,使其无歧义。 但这会使语法
更复杂,更难理解。 另一种可能性是扩展语法,要求在所有加法和乘法表达式周围加上括号:
::= x
(
1
+
2
)
(
1
*
2
)
:=
1
;
2
然而,这也导致了不必要的混乱和复杂性。 相反,我们将语言的“具体语法”(它指定如何将字符
串无歧义地解析为程序短语)与其“抽象语法”(它描述了可能有歧义的程序短语的结构)分开。
在本课程中,我们将假设已知抽象语法树。 在编写表达式时,我们偶尔会使用括号来表示抽象语
法树的结构,但括号不是语言本身的一部分。 (有关解析、语法和消除歧义的详细信息,请参阅
或参加CS 4120。)
1.1 表示表达式
这种语言中表达式的句法结构可以使用OCaml进行紧凑的表示,使用数据类型:
类型exp = Var of string
| Int of int
| Add of exp
* exp
| Mul of exp
* exp
| Assgn of string
* exp * exp
这与上面的BNF语法非常相似。 表达式的抽象语法树(AST)可以通过在每种情况下应用数据类
型构造函数来获得。 例如,表达式 2 * (foo + 1)的AST是:
Mul(Int(2), Add(Var("foo"), Int(1)))
在OCaml中,当只有一个参数时,可以省略括号,因此上述表达式可以写成:
2
Mul(Int 2, Add(Var "foo", Int 1))
我们可以使用类层次结构在类似Java的语言中表示相同的结构,尽管会稍微复杂一些:
抽象类 Expr { }
类 Var 扩展 Expr { String name; .. }
类 Int 扩展 Expr { int val; ... }
类 Add 扩展 Expr { Expr exp1, exp2; ... }
类 Mul 扩展 Expr { Expr exp1, exp2; ... }
类 Assgn 扩展 Expr { String var, Expr exp1, exp2; .. }
2 操作语义
我们对表达式的含义有直观的概念。 例如, 7 + (4 * 2)的计算结果为 15,
而 := 6 +1 ; 2 * 3 * i的计算结果为 42。 在本节中,我们将准确地形式化这种直觉。
操作语义描述程序在抽象机器上的执行方式。 小步操作语义描述了这样一种执行方式,即通过
连续的规约来进行——在这里,是对表达式的规约,直到达到表示计算结果的值。 抽象机器的状态
通常被称为一个配置。 对于我们的语言,一个配置必须包括两个信息:
一个存储(也称为环境或状态),它将整数值映射到变量。 在程序执行期间,我们将参考存
储来确定与变量相关联的值,并更新存储以反映对变量的新值的赋值。
要评估的表达式。
我们将存储表示为从变量到整数的部分函数,并将配置表示为表达式和存储的对:
存储 ≜ 变量 ⇀整数
配置 ≜ 存储 表达式
我们将使用尖括号表示配置。例如, ⟨ (foo + 2) * (bar + 2)⟩是一个配置,其中 是一个存储, (fo
o + 2) * (bar + 2)是一个使用两个变量 foo和 bar的表达式。 我们语言的小步操作语义是一个关系
配置配置,描述了一个配置如何过渡到一个新的配置。 也就是说,关系 告诉我们如何逐步
评估程序。 我们使用中缀符号表示关系 。
也就是说,给定任意两个配置 ⟨
1
1
⟩和 ⟨
2
2
⟩,如果 (⟨
1
1
⟩ ⟨
2
2
⟩)在关系 中,那么我们写
作 ⟨
1
1
⟩ ⟨
2
2
⟩。 例如,我们有 ⟨ (4 + 2) * y⟩ ⟨ 6 * y⟩。 也就是说,我们可以通过一步评
估配置 ⟨ (4 + 2) * y⟩得到配置 ⟨ 6 * y⟩。
使用这种方法,定义语言的语义归结为定义描述配置之间转换的关系!
这里的一个问题是整数的域是无限的,表达式的域也是无限的。 因此,可能的机器配置有无限
多个,可能的单步转换也有无限多个。 我们需要一种有限的方式来描述无限集合的可能转换。 我
们可以使用推理规则来简洁地描述!。
3
= ()
⟨ x ⟩ ⟨ ⟩
VAR
⟨
1
⟩ ⟨
′
′
1
⟩
⟨
1
+
2
⟩ ⟨
′
′
1
+
2
⟩
LADD
⟨
2
⟩ ⟨
′
′
2
⟩
⟨ +
2
⟩ ⟨
′
+
′
2
⟩
RADD
= +
⟨ + ⟩ ⟨ ⟩
ADD
⟨
1
⟩ ⟨
′
′
1
⟩
⟨
1
*
2
⟩ ⟨
′
′
1
*
2
⟩
LMUL
⟨
2
⟩ ⟨
′
′
2
⟩
⟨ *
2
⟩ ⟨
′
*
′
2
⟩
RMUL
=
⟨ * ⟩ ⟨ ⟩
MUL
⟨
1
⟩ ⟨
′
′
1
⟩
⟨ x :=
1
;
2
⟩ ⟨
′
x :=
′
1
;
2
⟩
ASSGN 1
′
= [ ]
⟨ x := ;
2
⟩ ⟨
′
2
⟩
ASSGN
推理规则的含义是,如果上方的事实成立,则下方的事实也成立。 上方的事实称为前提;下方
的事实称为结论。
没有前提的规则称为公理;有前提的规则称为归纳规则。 我们使用符号 [ ]表示将变量 x映
射到整数 ,并将其他变量映射到 映射的值。更明确地说,如果 是函数 [ ],则有
() =
{
如果 =
否则
3 使用语义
现在让我们看看如何使用这些规则。 假设我们想要评估表达式 (foo + 2) * (bar + 1)使用一个存储器 其中
(foo) = 4和 (bar) = 3。 也就是说,我们想要找到转换的配置 ⟨ (foo + 2) * (bar + 1)⟩。 为此,
我们寻找一个具有这种配置形式的规则在结论中。 通过检查规则,我们发现唯一与我们的配置形
式匹配的规则是LMUL,其中
1
= foo + 2和
2
= bar + 1但
′
1
尚未知道。 我们可以实例化LMUL,
用适当的表达式替换元变量
1
和
2
。
⟨ foo + 2⟩ ⟨
′
1
⟩
⟨ (foo + 2) * (bar + 1)⟩ ⟨
′
1
* (bar + 1)⟩
LMUL
现在我们需要证明前提实际上成立,并找出
′
1
是什么。我们寻找一个规则
其结论与 ⟨ foo + 2⟩ ⟨
′
1
⟩相匹配。 我们发现LA DD是唯一匹配的规则:
⟨ foo⟩ ⟨
′′
1
⟩
⟨ foo + 2⟩ ⟨
′′
1
+ 2⟩
LADD
我们对 ⟨ foo⟩ ⟨
′′
1
⟩和 find 进行了相同的推理,发现唯一适用的规则是公理
VAR:
(foo) = 4
⟨ foo⟩ ⟨ 4⟩
VAR
4
由于这是一个公理,没有前提条件,因此没有剩下的东西需要证明。 因此,
′′
1
= 4 and
′
1
= 4 + 2. 我们可以将上述部分整合起来,构建以下证明:
(foo) = 4
⟨ foo⟩ ⟨ 4⟩
VAR
⟨ foo + 2⟩ ⟨ 4 + 2⟩
LADD
⟨ (foo + 2) * (bar + 1)⟩ ⟨ (4 + 2) * (bar + 1)⟩
LMUL
这证明了,在给定我们的推理规则的情况下,一步转换是可行的
⟨ (foo + 2) * (bar + 1)⟩ ⟨ (4 + 2) * (bar + 1)⟩
是可导出的。 上面的结构被称为“证明树”或“推导”。 请记住,证明树必须是有限的,才能得出有
效的结论。
我们可以使用类似的推理方法来找出下一个评估步骤:
6 = 4 + 2
⟨ 4 + 2⟩ ⟨ 6⟩
ADD
⟨ (4 + 2) * (bar + 1)⟩ ⟨ 6 * (bar + 1)⟩
LMUL
我们可以继续这个过程。 最后,我们可以将所有这些转换放在一起,以获得整个计算的视图:
⟨ (foo + 2) * (bar + 1)⟩ ⟨ (4 + 2) * (bar + 1)⟩
⟨ 6 * (bar + 1)⟩
⟨ 6 * (3 + 1)⟩
⟨ 6 * 4⟩
⟨ 24⟩
计算的结果是一个数字, 24。 包含最终结果的机器配置是评估停止的点;它们被称为最终配置。
对于我们的表达式语言,最终配置的形式为 ⟨ ⟩。
我们写作!
表示关系 的自反传递闭包。也就是说,如果 ⟨ ⟩
⟨
′
′
⟩使用零个或多个步骤,我们可以将配置 ⟨ ⟩评估为 ⟨
′
′
⟩。因此,我们有:
⟨ (foo + 2) * (bar + 1)⟩
⟨ 24⟩
5
剩余110页未读,继续阅读
资源评论
绝不原创的飞龙
- 粉丝: 1w+
- 资源: 1091
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于PHP+swoole实现的微信机器人,依赖vbot和微信网页版的功能,帮助管理微信群/聊天/踢人等+源码+开发文档+运行教程
- com.xunmeng.pinduoduo_Release_cd290ca9_ARM64.apk
- 2788727d-25a0-41b2-b6b4-265d193edb95.doc
- 基于AVR单片机的伺服电机系统研究
- Lab-Electronic Craft Practicum-2-Simulation of a Single Tube Com
- 贪吃蛇基于TypeScript
- CS-CP1-2C3WF固件
- 软件测试测试用例设计方法大全
- 计算机与网络基础知识要点学习
- 移动通信(RC-YDTX-III)实验指导书
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功