1 / 82

指称语义简介

指称语义简介. 西安电子科技大学 软件工程研究所 刘 坚. 形式化语义(动态语义). 语义的形式化描述(形式化语义)对程序设计语言的设计与实现均具有重要意义; 形式化语义从数学的角度 ( 用数学的方法 ) 研究程序设计语言的语义 ( 最初也被称为数学语义 ) ,使得: 全面、准确了解 ( 规定 ) 程序设计语言的语义 预测程序的行为 对程序进行推理 ( 如一程序与另一程序是否相等 ) 形式化语义的应用 语义设计 程序验证 程序自动生成 ( 编译器自动构造 ) 形式化描述语义的方法 操作语义 公理语义 指称语义. 指称语义.

hedia
Download Presentation

指称语义简介

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 指称语义简介 西安电子科技大学 软件工程研究所刘 坚

  2. 形式化语义(动态语义) • 语义的形式化描述(形式化语义)对程序设计语言的设计与实现均具有重要意义; • 形式化语义从数学的角度(用数学的方法)研究程序设计语言的语义(最初也被称为数学语义),使得: • 全面、准确了解(规定)程序设计语言的语义 • 预测程序的行为 • 对程序进行推理(如一程序与另一程序是否相等) • 形式化语义的应用 • 语义设计 • 程序验证 • 程序自动生成(编译器自动构造) • 形式化描述语义的方法 • 操作语义 • 公理语义 • 指称语义

  3. 指称语义 • 赋予程序的每个短语(如每个表达式、命令、声明等)意义 ,即将语言的语义结构强加给对应的语法结构; • 每个短语的意义由它的子短语来定义; • 每个短语的意义被称为指称,从而发展出指称语义 。 • 本章内容 • 指称语义的基本概念; • 指称语义的基本技术:如何用指称语义描述程序设计语言的特性,如存贮、环境、抽象与参数、原子类型与组合类型、以及失败等。 本节内容 指称语义的基本概念:短语、指称、域、语义函数、函数定义的符号表示等。

  4. 1.1 语义函数 语义函数: • 用适当的数学实体表示每个短语的意义。 • 实体被称为短语的指称(denotation)。 • 通过将短语映射到其指称的函数,来规定程序设计语言的语义。 • 这些函数被称为语义函数(semantic functions)。 语义函数:短语→指称 语法与语义的关系: • 语义是依附于语法的; • 语义是独立于语法的,反映语言的真实含意; • 语法、语义是多对多的映射。 回顾属性文法: • 属性(如.type、.val等) • 语义规则

  5. 例1 语法与语义的关系 • 考虑二进制数,如"110"和"10101"。 • 数字"110"欲表示数值6, • 而数字"10101"欲表示数值21。 • 数字是一个语法实体,而数值是一个语义实体。数值是一个抽象概念,它不依赖于任何特别的语法表示。 • 数字"110":数值:6、110等 • 数值6: 数字:"110"、"6"、"Ⅵ"、"六"、"陆"等 • 数值110: 数字:"110"、"6E"、"壹佰壹拾"等

  6. 例2 二进制数的语法与语义 语法: 域: 语义函数: 语义方程: 计算: Numeral ::= 0 | 1 | N0 | N1 Natural = { 0, 1, 2, 3, ... } valuation : N → Natural valu[0]= 0 valu[1]= 1 valu[N0]= 2×valu N+0 = 2×valu N valu[N1]= 2×valu N+1 valu[110] = 2×valu[11] = 2×(2×valu[1]+1) = 2×(2×1+1) = 6 valu[110] = 10×valu[11] = 10×(10×valu[1]+1) = 10×(10×1+1) = 110 N::=i|Ni (i=0, 1, 2... base-1) base进制:valu[i]= i (i=0, 1, 2... base-1) valu[Ni]= base×valu[N]+i

  7. 例3 一个计算器的语法与语义 文法: 域: 语义函数: 辅助函数: 语义方程: • Command ::= Expr = (6.4) • E ::= Numeral (6.5a) • | E + E (6.5b) • | E - E (6.5c) • | E * E (6.5d) • int = { ..., -3, -2, -1, 0, 1, 2, 3, ... } • execute : Command → int (6.6) • evaluate : E → int (6.7) • valuation : Numeral → Natural (6.8) • sum : int×int→ int • diff : int×int→ int • prod : int×int→ int • exec[E=]= eval E (6.9) • eval[N]= valu N (6.10a) • eval[E1+E2]= sum(eval E1, eval E2) (6.10b) • eval[E1-E2]= diff(eval E1, eval E2) (6.10c) • eval[E1*E2]= prod(eval E1, eval E2) (6.10d)

  8. 例3 一个计算器的语法与语义(续) 语义方程: 计算: exec[E=]= eval E (6.9) eval[N]= valu N (6.10a) eval[E1+E2]= sum(eval E1, eval E2) (6.10b) eval[E1-E2]= diff (eval E1, eval E2) (6.10c) eval[E1*E2]= prod(eval E1, eval E2) (6.10d) 执行命令“40-3*9=” ,其中减法优先级高于乘法: exec[40-3*9=] = eval[40-3*9] by(6.9) = prod(eval[40-3],eval[9]) by(6.10c) = prod(diff(eval[40], eval[3]), eval[9]) by(6.10d) = prod(diff(valu[40], valu[3]), valu[9]) by(6.10a) = prod(diff(40,3), 9)= 333

  9. 定义1.1 • 每个短语p的意义被规定为一个在某域中的值d。称d是短语p的指称。或者说短语p由d来指称; • 规定域D作为短语类P的指称,并且引入一个语义函数f,它把P中的每个短语映射到它在D中的域。记为: • f : P → D; • 通过若干语义方程来定义语义函数,每个函数对应P中的一个可区分的短语。如果P中的一个短语有子短语Q和R,则相应的语义方程式就类似如下表示: • f[...Q ...R ...]= ... f' Q ... f'' R ... • 此处f'和f''分别是Q和R的语义函数。 ■ 换句话说,每个短语的指称(仅)由它们子短语的指称定义,从而使得整个程序的意义自下而上得以完整定义。

  10. 1.2 函数定义的符号表示 • 使用符号“let ... in ...”引入新的(数学意义的)变量或函数,其含意可以非形式地解释为:“将…引入…”或“将…代入…”。 • 例:let s=0.5*(a+b+c) in sqrt(s*(s-a)*(s-b)*(s-c)) • let succ n=n+1 in … succ m, … succ(succ i)) … • 其中的s是变量,而succ是函数。 • 使用函数的匿名表示忽略函数名而仅关注其实际意义。用匿名函数λn.n+1表示n→n+1,则下述均可表示为匿名函数: • succ = λn.n+1 • pred = λn.n-1 • odd = λn.true-value • 于是succ可以表示为:let succ = λn.n+1 in ...

  11. 3. 多个参数与let ... in ...结构的嵌套(或组合)。 1.2 函数定义的符号表示(续) • 例:let triangle-area(a,b,c) = • let s = 0.5*(a+b+c)in • if s>0.0 • then sqrt(s*(s-a)*(s-b)*(s-c)) • else 0.0 • in triangle-area(0.3, 0.4, 0.5) 函数triangle-area的域是real×real×real→real,可以将triangle-area看作一个三元组的单一参数,a,b,c分别是它的三个分量。

  12. 1.3 域(Domains) 域是一个值的集合,这些值被称为域的元素。指称语义中所使用的域结构有下述几种。 • <1> 原子域(Primitive domains) • 原子域是这样的域,它的元素是原子的值,而不是可以由更简单的值组合而来的值。原子域包括: • Character- 元素来自字符集合 • Integer- 元素是零、正整数、负整数 • Natural- 元素是非负整数 • Truth-Value- 元素是真值false和true • Unit- 唯一元素是零元组,记为:0-tuple() 也可以用枚举的方法来定义原子域,例如: Denomination = { dollars, cents } 或者:Denomination = { 元、角、分}等

  13. <2> 迪卡尔积域(Cartesian product domains) 1.3 域(Domains)(续1) a.迪卡尔积域D1×D2×...×Dn的元素是有序n元组,(x1, x2, ..., xn),其中xi∈Di。当n=2时,域中元素是有序对。 例1Money=Natural×Denomination的元素可以取: (1,dollars)、(2,cents)等。 b.元组的构造与分解 用let x=(...) in ...构造元组; 用let (...)=x in ...分解元组。 例2构造一个money类型的元组: let pay = (payrate×hours,dollars) in ... 例3将money类型分解为两个分量的乘积: let (amount,denom) = pay in amount×(if denom=dollars then 100 else 1)

  14. <3> 异或域(Disjoint union domains) 1.3 域(Domains)(续2) a.异或域D1+D2+...+Dn的元素选自分量的域:x∈Di(i=1,2...n)。 异或域的各分量域应被标记(命名),以明确取自的分量。 例1异或域Shape=rectangle(Real×Real)+circle Real+point的元素:rectangle(0.3,0.4)、cirle 5.0或point(point Unit) • b.异或域分解也用let ... in ...,但需多重函数分情况定义 • 例2let sheet = rectangle(lgth,lgth/sqrt 2.0) in -- sheet:Shape • ... • let area(rectangle(w,d)) = w*d -- area:Shape→Real • area(circle r) = pi*(r*r) • area(point) = 0.0 • in • ... • area(sheet) area由三个独立的公式定义

  15. <4> 函数域(Function domains) 1.3 域(Domains)(续3) a.函数域的元素是函数或映射。每个函数域D→D'的元素是一个函数,它把D中的元素映射到D'中的元素。 例1域Integer→Truth-Value的元素,是把整型数映射到真值的函数,如odd,even,positive,negative,prime,composite等。 回顾:odd=λn.true-value b.域D→D'上的一个偏(partial)函数是这样一个函数,它可以仅成功地作用于D中的部分参数。经常用偏函数来规定语义。 例2若除法函数的参数对中的第二个数值是0,就不能成功地应用除法函数。 假设每个域都包括一个特殊的元素fail,它可以用来作为偏函数的结果。

  16. <5> 序列域(Sequence domains) 1.3 域(Domains)(续4) a.序列域D*中的每个元素是从D中选出的零个或多个元素的有限序列。每个序列或者是空序列nil,或者是把序列s∈D*加上前缀x∈D而得到。 例1域String=Character*的元素是零个或若干个字符的序列,即任何长度的字符串。例如: nil -- 习惯上写为“” 'a'.nil -- 习惯上写为“a” 'S'. 'u'. 's'. 'y'.nil -- 习惯上写为“Susy” • b.使用由两个序列定义的函数来分解序列。 • 例2 • let length(nil) = 0 -- length : D*→Integer • length(x.s) = 1 + length s • in • ...

  17. 本节主要内容 1 指称语义的基本概念:短语 → 指称 2 语义函数与指称语义的基本过程 ① 语法(短语) ② 域(指称) ③ 语义函数(短语→指称) ④ 语义方程与辅助函数 3 函数定义的符号表示 ① 使用符号“let ... in ...”引入新的变量与函数; ② 匿名函数λn.n+1 ③ 多个参数与let…in…结构的嵌套 4 域 ① 原子域 ② 迪卡尔积域 ③ 异或域 ④ 函数域 ⑤ 序列域

  18. 参考书目 David A. Watt “Programming Language Syntax and Semantics”, Prentice Hall,1991 习题 • 分别用二进制和十进制的指称语义,确定: (a) valuation[11]; (b) valuation[0110]; (c) valuation[10101]。 • 为计算器增加一个求平方操作,在它的操作数之后键入“sq”键,如命令“7+2sq=”(它的结果是81)。修改相应的指称语义。 • (a)用head与tail定义串的组合与分解; (b)如何定义substring、prefix、postfix等?

  19. 结 束(2005年5月20日)

  20. 存储模型与环境模型 西安电子科技大学 软件工程研究所刘 坚

  21. 上节内容回顾 • 指称语义的基本概念:将语言的意义施加于语言的结构 • 语义函数与指称语义的基本过程 ① 语法(短语) ② 域(指称) ③ 语义函数(短语→指称) ④ 语义方程与辅助函数 • 函数定义的符号表示 ① 使用符号“let ... in ...”引入新的变量与函数; ② 匿名函数λn.n+1 ③ 多个参数与let…in…结构的嵌套 • 域 ① 原子域 ② 迪卡尔积域 ③ 异或域 ④ 函数域 ⑤ 序列域

  22. 本节主要内容 一、存储(Storage) 1.1 存储模型 1.2 存储模型举例 二、环境(Environment) 2.1 环境模型 2.2 环境模型举例 • 掌握 • 如何用指称语义描述存储与环境的动态特性和建立动态模型; • 如何用存储模型和环境模型描述具体的存储与环境。

  23. 一、存储(Storage) 存储是计算机的重要基础概念之一 计算机模型:程序存储+程序执行 程序设计语言:内容可更改的变量x 数学模型:内容可更改的配置(location或cell) 第一类值(first-class values):可以参与语言所有操作而不受限制的值(如赋值、参数传递等),简称为值(Value)。

  24. 1.1 存储模型 定义1.2简单存储模型是若干配置(location)的集合,每个配置有一个状态: ① 未使用(unused),没有被分配给任何变量。 ② 未定义(undefined),已经被分配,但是没有值。 ③ 含有一个值(stored storable)。 可存储在配置中的值被称为可存储值(storable)。某一时刻存储的全体被称为存储瞬象(storage snapshots),用术语存贮(store)表示。 ■ 定义1.2可以用一个公式表示为: Store=Location→(stored Storable + undefined + unused) (6.16) 可以通过命令来改变存贮,如n:=13将sto映射到sto’。 二者的区别是sto’中含有了值13。

  25. ① 描述存储基本特性的辅助函数 • 称配置域为Location,可存储域为Storable,存贮域为Store。则存储特性可表示为下述映射: • empty-store : Store (6.11) • allocate : Store → Store×Location (6.12) • deallocate : Store×Location→Store (6.13) • update : Store×Location×Storable→Store (6.14) • fetch : Store×Location →Storable (6.15) • empty-store给出一个存贮,其中每一个配置都是未使用。 • allocate(sto)=(sto',loc):sto'与sto相同,但是配置loc在sto中是未使用,而在sto'中是未定义。 • deallocate(sto,loc)=sto'意思是:sto'与sto相同,但是配置loc在sto'中未使用。 • update(sto,loc,stble)=sto'意思是:sto'与sto相同,但是sto'中的配置loc含有stble。 • fetch(sto,loc)给出存放在sto中配置loc里的可存储值,如果loc未定义或者是未使用,给出值fail。

  26. 辅助函数的符号表示 empty-store =λloc.unused (6.17) • allocate sto = let loc=any-unused-location(sto) (6.18) • in (sto[loc→undefined],loc) • (sto[loc→state]= • λloc'.if loc'=loc then state else sto(loc') • 即loc被修改为state,其它保持状态不变 ) • 找到任何一个“未使用”的配置loc,将其置为“未定义” deallocate(sto,loc) = sto[loc→unused] (6.19) update(sto,loc,stble) = sto[loc→stored stble] (6.20) fetch(sto,loc) = (6.21) let stored-value(stored stble) = stble stored-value(undefined) = fail stored-value(unused) = fail in stored-value(sto(loc))

  27. ③举例 一个具有四个配置loc1,loc2,loc3,loc4(从左到右)的存贮,其中数字、‘?’和‘$’分别表示配置的值、未定义和未使用状态。 fetch(3?$$,loc1) = 3 fetch(3?$$,loc2) = fail fetch(3?$$,loc3) = fail update(3?$$,loc2,7) = 37$$ deallocate(3?$$,loc2) = 3$$$ allocate(3?$$) = (3??$,loc3) 或者(3?$?,loc4) 可以看出:deallocate(allocate sto) = sto fetch(update(sto,loc,stble),loc) = stble 例如: deallocate(allocate (3?$$)) = (3?$$) fetch(update(3?$$,loc2,7),loc2) = 7 但是: allocate(deallocate(sto, loc)) ≠ sto 因为可以:allocate(deallocate(3?$$,loc2)) ≠ 3?$$

  28. 文法:Command ::= E = (6.4) E ::= Numeral (6.5a) | E + E (6.5b) | E - E (6.5c) | E * E (6.5d) 域:int = { ..., -2, -1, 0, 1, 2, ... } 辅助函数: sum : int×int→ int diff : int×int→ int prod : int×int→ int 1.2 存储模型实例-无存储的计算器 语义函数:execute : Command → int (6.6) evaluate : E → int (6.7) valuation : Numeral → Natural (6.8) 语义方程: 计算: exec[E=]= eval E (6.9) eval[N]= valu N (6.10a) eval[E1+E2]= sum(eval E1, eval E2) (6.10b) eval[E1-E2]= diff(eval E1, eval E2) (6.10c) eval[E1*E2]= prod(eval E1, eval E2) (6.10d) exec[40-3*9=] = eval[40-3*9] by(6.9) = prod(eval[40-3],eval[9]) by(6.10d) = prod(diff(eval[40], eval[3]), eval[9]) by(6.10c) = prod(diff(valu[40], valu[3]), valu[9]) by(6.10a) = prod(diff(40,3), 9)= 333

  29. 将计算器扩充为具有存储功能,它包括两个寄存器(cells)x和y。将计算器扩充为具有存储功能,它包括两个寄存器(cells)x和y。 • 可以键入如下形式的命令序列: • “3*37=x” • “9+x=” • 第一条命令计算3和37的乘积,显示结果,并把结果存放在寄存器x中。 • 第二条命令计算9和x中内容的和,并显示结果。 1.2 存储模型实例-有存储的计算器 ① 文法 Command ::= Expression = (6.22a) | E = Register (6.22b) | C C (6.22c) E ::= Numeral (6.23a) | E + E (......) (6.23b) | R (6.23e) R ::= x (6.24a) | y (6.24b) Command ::= E = (6.4) E ::= Numeral (6.5a) | E + E (6.5b) | E - E (6.5c) | E * E (6.5d)

  30. 1.2 存储模型实例-有存储的计算器(续1) ② 域 Storable = Integer (6.25) Location = {loc1,loc2} (6.26) ③ 语义函数 a.命令的执行: execute : C → (Store → Store×Integer) (6.28) (命令的指称是一个把存贮映射到存贮和整型数的函数) b.表达式的计算: evaluate : E → (Store → Integer) (6.27) (表达式的指称是一个把存贮映射到整型数的函数(结果依赖于存贮)) c.寄存器的定位: location : R → Location (6.29) (寄存器的指称是一个配置)

  31. ③语义方程 1.2 存储模型实例-有存储的计算器(续2) a.寄存器的定位: loca[x]=loc1 (6.32a) loca[y]=loc2 (6.32b) • b.表达式的计算(E→(Store→Integer) ) • eval[N]sto = valu N (6.30a) • eval[E1+E2]sto = sum(eval E1sto,eval E2sto) (6.30b) • eval[R]sto = fetch(sto,loca R) (6.30e) • c.命令的执行 • exec[E=]sto = let int = eval E sto in (sto,int)(6.31a) • (在不变的存贮sto中计算E得到的值int) • exec[E=R]sto= • let int = eval E sto in (6.31b) • let sto' = update(sto,loca R,int) in (sto',int) • (给出改变了的存贮sto'和在sto中计算E得到的值int) • exec[C1C2]sto = (6.31c) • let(sto',int) = exec C1 sto in exec C2 sto' • (在存贮sto中执行C1,在改变了的存贮sto'中执行C2) 下一页 下下页

  32. 1.2 存储模型实例-有存储的计算器(续3) 用存储模型给出命令序列3*37=x 9+x=(C1 C2)的解。 解:首先在sto中执行命令3*37=x,得到一个值和一个改变了的sto',然后在sto'中执行命令9+x=,得到一个值且sto'保持不变。一开始,sto=(loc1,loc2)=(未使用,未使用) • exec[3*37=x]sto • = let int=eval[3*37]sto in • let sto'=update(sto,loca x,int)in(sto',int) (by 6.31b) • = let int=prod(eval[3]sto, eval[37]sto) • in let sto'=update(sto, loca x, int) in (sto', int) • = let int=111 in let sto'=update(sto,loca x,int)in(sto',int) • = let sto'=update(sto,loca x,111) in (sto', 111) • = let sto'=update(sto, loc1, 111) in (sto', 111) (by 6.32a) • = ((111,未使用), 111) (by 6.20) 即执行3*37=x之后,sto'=(111,未使用),x获得值111且屏幕显示值111。

  33. 1.2 存储模型实例-有存储的计算器(续4) 然后在sto'=(111,未使用)中执行9+x=: • exec[9+x=]sto' • = let int=eval[9+x]sto' in (sto', int) (by 6.31a) • = let int=sum(eval[9]sto', eval[x]sto') in (sto', int) • = let int=sum(9,fetch(sto',loca x))in(sto', int) (by 6.30e) • = let int=sum(9,fetch(sto',loc1))in(sto', int) (by 6.32a) • = let int=sum(9,111) in (sto', int) (by 6.32a) (by 6.21) • = let int=120 in (sto', int) • = (sto', 120) • = ((111,未使用), 120) 最终结果是x中获得值111,屏幕显示值120。■

  34. 二、环境(Environment) 声明建立标识符和某种实体之间的绑定(bindings)。每个绑定具有一个确定的作用域(scope),如含有建立绑定的声明的块(block)。 通俗地讲,环境是在一定的作用域范围内的一组绑定。可以表示为:{A→B, ...}。 例1开发环境:{Computer→PC,OS→Unix,PL→C++,DBMS→Oracle} 例2按语法let D in E书写的表达式如下: ① let val m=10 in ② let val n=m*m in m+n 假设在空环境{ }中计算表达式① ,第一个声明建立绑定m→10,它的作用域是表达式②。 然后在环境{m→10}中计算②的子表达式"m*m",得到结果100,因为m的每个应用出现都指称10。 第二个声明建立绑定n→100,它的作用域是表达式"m+n"。于是m+n在环境{m→10,n→100}中计算并得到110。

  35. 例3作用域的嵌套: 二、环境(Environment)(续) ③ let val n=1 in ④ n+(let val n=2 in 7*n)+n 同样,空环境中计算表达式③,建立环境{n→1},在此环境中计算表达式④, ④中有一个被嵌套的子表达式let val n=2 in 7*n,其中声明将环境改变为{n→2}。因此7*n=7*2=14,而: n+(let val n=2 in 7*n)+n=1+14+1=16 ■ 定义3.3环境是一组与作用域有关的标识符到实体的绑定。标识符在一个作用域中最多有一个绑定,被绑定的实体称为可绑定体。■ 定义3.3可表示为公式: Environ=Identifier→(bound Bindable + unbound) (6.37) 可绑定体的简化:通常需要经过两步才能将名字映射到它所代表的值,此处简化为一步,并且仅有integer是可绑定体。

  36. 2.1 环境模型① 描述环境基本特性的辅助函数 若令环境域为Environ,标识符域为Identifier,可绑定体域为Bindable,则环境特性可表示为下述映射: empty-environ : Environ (6.33) bind : Identifier×Bindable → Environ (6.34) overlay : Environ×Environ → Environ (6.35) find : Environ×Identifier → Bindable (6.36) • empty-environ给出一个空环境{}。 • bind(Id,bdble)给出由单一绑定组成的环境{Id→bdble}。 • overlay(env’,env)给出一个组合环境env和env’绑定的环境;若任何标识符既被env也被env’绑定,则它在env’的绑定重置在env的绑定。 • find(env,Id)给出环境env中Id的可绑定体,若无就给出fail。 例如:设env = {i→1,j→2}, 则: bind(k,3) = {k→3} overlay({j→3,k→4},env) = {i→1,j→3,k→4} find(env,j) = 2,而find(env,k) = fail

  37. ②辅助函数符号表示 empty-environ =λId.unbound (6.38) bind(Id,bdble) = (6.39) λId'.if Id'=Id then bound bdble else unboud overlay(env',env) = (6.40) λId.if env'(Id)≠unbound then env'(Id) else env(Id) find(env,Id) = (6.41) let bound-value(bound bdble) = bdble bound-value(unbound) = fail in bound-value(env(Id)) 与存储模型对应:empty-store、allocate、update、fetch。 问题:deallocate?

  38. 2.2 环境模型实例-含有声明的语言 ①文法 E ::= N (6.42a) | E + E (6.42b) | ... | Id (6.42c) | let Declaration in E (6.42d) D ::= val Id = E (6.43) ② 域:Bindable = Integer (6.44) ③ 语义函数: evaluate : E → (Environ → Integer) (6.45) (表达式的指称是一个从环境到整型数的映射;) elaborate : D → (Environ → Environ) (6.46) (声明的指称是一个环境到环境的映射。)

  39. 2.2 环境模型实例-含有声明的语言(续1) ④ 语义方程 eval[N]env = valu N (6.47a) eval[E1+E2]env = sum(eval E1 env,eval E2 env) (6.47b) eval[Id]env = find(env,Id) (6.47c) eval[let D in E]env = (6.47d) let env'=elab D env in eval E(overlay(env',env)) elab[val Id=E]env = bind(Id,eval E env) (6.48) • 计算env中数字N组成的表达式的结果就是N的值; • 计算env中表达式"E1+E2"的结果,是在各自env中计算E1和E2结果的和; • 计算env中引用标识符Id的结果是Id绑定到env的值; • 计算在env中形如"let D in E"表达式的结果,是计算E在一个新环境中的结果。新环境是由在env中详细描述D产生的绑定env'所覆盖得到的; • 详细描述在env中形如"val Id = E"声明的结果,是一个从Id到由计算env中E得到的值的绑定。

  40. 2.2 环境模型实例-含有声明的语言(续2) ⑤例:空环境env中计算:let val n=1 in n+(let val n=2 in 7*n)+n 解: eval[let val n=1 in n+(let val n=2 in 7*n)+n]env = let env'=elab[val n=1]env (by 6.47d) in eval[n+(let val n=2 in 7*n)+n]overlay(env', env) = let env'=bind(n,eval[1]env) (by 6.48) in eval[n+(let val n=2 in 7*n)+n]overlay(env', env) = let env'= bind(n, 1) in eval[n+(let val n=2 in 7*n)+n]overlay(env', env) = let env'={n→1} (by 6.39) in eval[n+(let val n=2 in 7*n)+n]overlay(env', env) = eval[n+(let val n=2 in 7*n)+n]env' (因为env={ }, 所以overlay(env', env)=env'={n→1})

  41. 2.2 环境模型实例-含有声明的语言(续3) = sum(eval[n+(let val n=2 in 7*n)]env', eval[n]env') = sum(sum(eval[n]env',eval[let val n=2 in 7*n]env'), eval[n]env') = sum(sum(find(n, env'), let env''= elab[val n=2]env' in eval[7*n]overlay(env'',env'),find(n,env')) (by 6.47c,6.47d) = sum(sum(1, let env''= bind(n, eval[2]env') (by 6.48) in eval[7*n]overlay(env'', env'),1) = sum(sum(1, let env''=bind(n, 2) eval[7*n]overlay(env'', env'),1) = sum(sum(1, let env''={n→2} eval[7*n]overlay(env'', env'),1) = sum(sum(1, eval[7*n]overlay(env'', env'),1) = sum(sum(1, eval[7*n]env'', 1) (overlay(env'', env')={n→2}=env'') = sum(sum(1, prod(eval[7]env'', eval[n]env'')), 1) = ... = sum(sum(1, 14), 1) = sum(15, 1) = 16 ■

  42. 内容回顾 • 存储模型 • Store=Location→(stored Storable + undefined + unused) (6.16) 辅助函数的符号表示: empty-store =λloc.unused (6.17) allocate sto = let loc=any-unused-location(sto) (6.18) in (sto[loc→undefined],loc) deallocate(sto,loc) = sto[loc→unused] (6.19) update(sto,loc,stble) = sto[loc→stored stble] (6.20) fetch(sto,loc) = (6.21) let stored-value(stored stble) = stble stored-value(undefined) = fail stored-value(unused) = fail in stored-value(sto(loc)) • 举例-带存储的计算器: • 文法的修改; • 域、语义函数、语义方程的设计

  43. 内容回顾(续) • 环境模型 • Environ=Identifier→(bound Bindable + unbound) (6.37) • 辅助函数的符号表示: empty-environ =λId.unbound (6.38) bind(Id,bdble) = (6.39) λId'.if Id'=Id then bound bdble else unboud overlay(env',env) = (6.40) λId.if env'(Id)≠unbound then env'(Id) else env(Id) find(env,Id) = (6.41) let bound-value(bound bdble) = bdble bound-value(unbound) = fail in bound-value(env(Id)) 环境强调作用域,离开作用域,绑定自然消失,故没有去绑定 • 举例-含有声明的语言: • 文法的修改; • 域、语义函数、语义方程的设计

  44. 习题 1. 用带寄存器的计算器的指称语义(假设寄存器初值均为0): (a)执行命令“x+7=”; (b)执行命令“x+7=y y*y=”。 2*. 拓广计算器使得它有一个大存贮的寄存器,R0,R1,R2等(x和y键由单一的R键所代替)。 3. 使用带声明表达式的指称语义: (a) 计算环境{ m→10,n→15 }中的表达式“m+n”; (b) 计算空环境中的表达式 “let val n=1 in n+(let val n=2 in 7*n)+n”。

  45. 结 束(2005年5月27日)

  46. 本节主要内容 • 抽象 • 函数抽象 • 过程抽象 • 参数 • 组合类型 • 失败 • 了解 • 抽象的种类,抽象的数学模型; • 参数的种类,参数的数学模型; • 组合类型的构造,组合类型的存取; • 失败的数学模型,失败的传播。

  47. 一、抽象(Abstractions) 抽象是一个体现了计算的值(如函数抽象或过程抽象)。用户称计算为抽象,因为他们只能“看到”计算的结果(如有函数抽象所产生的值,或由过程的作用所改变的存储等),而不是计算结果的方法。 我们首先分别考察函数和过程抽象的语义。为简单起见,假设每个抽象具有单一(常量)参数。 然后再详细地考察参数。

  48. 1.1 函数抽象(Function abstractions)(不改变存储的抽象) • 函数抽象的使用者提供一个实参,并且只能“看到”结果值。因此函数抽象的意义应该是从实参到结果值的映射。 • 更一般地,在规定的语言中,令Argument是实参域,Value是第一类值域。则有: • Function = Argument→Value (6.62) • <1> 语法 • 扩展语法,加入函数调用(6.63)和函数声明(6.64): • Expression ::= ... • | Identifier ( Actual-Parameter) (6.63) • Declaration ::= ... • | fun Id ( Formal-Parameter ) = E (6.64) • FP ::= Id : Type-denoter (6.65) • AP ::= E (6.66)

  49. 1.1 函数抽象(续1) <2> 指称 假设有上下文限制:标识符必须已被声明为一个函数,并且实参必须与对应形参具有相同类型。 在算术表达式中,只有整型数可以作为参数传递,并且只有整型数可以作为函数结果返回: Argument = Integer (6.67) Function = Argument → Integer (6.68) 值声明绑定一个标识符到一个整型数,而函数声明绑定一个标识符到一个函数抽象。因此整型数和函数抽象均是可绑定体: Bindable = integer Integer + function Function (6.69) 标记 域

  50. 1.1 函数抽象(续2) • <3> 语义函数 • evaluate : E → (Environ →Integer) (3.45) • elaborate : Dec → (Environ→Environ) (3.46) • bind-parameter: FP → (Argument→Environ) (6.70) • give-argument: AP → (Environ→Argument) (6.71) • 函数调用的指称和实参的指称,均象表达式一样,是一个环境到整型数的映射; • 函数的声明是一个绑定的集合,即环境到环境的映射; • 形参的指称是一个从实参到环境的函数。

More Related