在另一个线程上,Andrej Bauer将指称语义定义为:
程序的含义是程序各部分含义的函数。
使我困扰的是该定义,它似乎并未从通常被认为是非名词性语义的东西(即结构操作语义)中分离出通常被认为是指称语义的东西。
更准确地说,这里的关键要素是语义的模块化或组合性,或者换句话说,它们是根据程序的抽象结构定义的。
由于当今大多数(全部?)形式语义趋向于结构化,这是否是必需的定义?
所以,我的问题是:什么是指称语义?
在另一个线程上,Andrej Bauer将指称语义定义为:
程序的含义是程序各部分含义的函数。
使我困扰的是该定义,它似乎并未从通常被认为是非名词性语义的东西(即结构操作语义)中分离出通常被认为是指称语义的东西。
更准确地说,这里的关键要素是语义的模块化或组合性,或者换句话说,它们是根据程序的抽象结构定义的。
由于当今大多数(全部?)形式语义趋向于结构化,这是否是必需的定义?
所以,我的问题是:什么是指称语义?
Answers:
我个人在指称语义和操作语义之间做出的区分是这样的:
有时差异可能非常微妙,并且很难分辨出仅仅是风格上或本质上的差异。
但是,我们可以从名词定义中看到Andrej的成分定义如何更自然地遵循,并且我们还可以轻松地想象仍然符合操作定义的非融合,非成分语义。
如果我想猜达纳·斯科特(Dana Scott)会说些什么,他可能会说指称语义是构成性的(就像我声称的那样),程序的含义必须是真正的数学对象,而不是某些语法或形式主义实体。当然,这样的观点需要区分语法的形式操纵和“真实”数学。这必然是非数学上的区别。
事后想到,在两个观察上不同的程序接收的含义不相同的意义上,人们可能希望该含义足够。当然,这种充分性取决于人们所承认的“观察”。
在这种观点下,可以说结构操作语义不是指称语义,因为它使一个句法实体的含义与另一个句法实体(一个值或一个归约序列)相等。
我同意鲍尔(A. Bauer)对具有组合性的指称语义的识别(在编程语言语义学书籍中)并不能很好地表征传统上指称语义的含义,因为显然操作语义和程序逻辑(公理语义)都是组合的。
我建议最好从社会历史角度来理解该术语,因为它泛指某种理论传统(认真地从Scott提出无类型Lambda微积分的晶格理论模型起),并使用了某些首选工具(有序理论,定点定理) ,拓扑,类别理论)和首选目标语言(纯功能性和顺序性)。我认为,除了纯粹的智力兴趣之外,名词指称语义的发明主要是因为:
过去很难对操作语义进行推理。
过去常常给非平凡的语言赋予公理语义。
因此,总而言之,我认为“名词语义”已变得不太精确,因此用途也越来越少。语义社区朝着更好的术语汇聚可能会有所帮助。
我对Adrej的回答感到满意,但我想进一步深入研究。
首先,指称语义要说诸如“这种表示法的意思就是那样”之类的东西。一个真正的语义学家会想像这些含义就是我们脑海中存在的意义,而这些符号仅仅是表达这些含义的一种方式。由此产生了指称语义应具有构成性的要求。如果意义是主要的,符号是次要的,那么我们别无选择,只能将较大的符号的含义定义为其成分的含义的函数。
如果我们接受这种观点,那么就需要一种良好的指称语义来捕捉我们认为在脑海中的含义。任何组成语义都不一定符合要求。如果我提出了一个组合语义定义,但没有人同意它陈述了他们头脑中的任何含义,那么它就没什么用了。当前的游戏语义处于这种情况。它是一个组合定义,在技术上很强大,但是很少有人同意它与他们脑海中的含义有任何关系。
也就是说,任何成分定义都具有各种技术优势。我们可以通过归纳术语语法来使用它来验证等价性或其他属性。再次通过对术语语法的归纳,我们可以使用它来验证证明系统的健全性。我们可以验证编译器或程序分析技术(根据其性质,是通过对语法的归纳定义的)的正确性。完全抽象的语义定义具有更多的技术优势。您可以使用它来表明两个程序不等效,您无法使用任何任意的组合语义。完全可定义的语义定义甚至更好。在这里,语义域具有您可以在编程语言中表达的确切内容(有一些限制)。因此,您可以枚举域中的值以查看存在的值,而使用语法符号很难做到这一点。基于所有这些理由,游戏语义学得分很高。
然而,这些年来,组合语义定义一直失去其优势。罗宾·米尔纳(Robin Milner)和安迪·皮茨(Andy Pitts)开发了许多“ 操作推理 ”技术,这些技术仅在语法上起作用,但是在谈论行为所需的地方都使用操作语义。这些操作推理技术是低技术的。没有花哨的数学。没有无限的对象。我们可以教他们给本科生,任何人都可以使用它们。因此,许多人问这个问题,为什么我们根本需要指称语义。(马丁·伯格(Martin Berger)可能在这个营地。)
就个人而言,我在工具箱中拥有许多工具没有问题。称谓技术在某些问题上的得分可能更高,而在其他问题上的操作技术则可能更高。开发该理论的研究人员可能会更好地适应一种方法或另一种方法。通常,我们可以采用一种方法来开发见解,然后将这些见解转移给另一种方法。(很多Andy Pitts的工作都是这种类型。关系参数性是在指称环境下开发的,但是他能够弄清楚如何将其重述为操作推理。当我看着它时,我说“哇,我永远不会“分离逻辑也是如此。”史蒂夫·布鲁克斯(Steve Brookes)使用指称语义为并发分离逻辑提供了60页的合理性证明。
当编程语言非常流行时,使用各种循环高阶类型的操作方法也能获得出色的成绩。我们可能不知道如何在数学上建模此类事物。或者,标准数学模型在循环压力的作用下可能会变得不一致。(例如,请参见Reynolds的“多态性不是集合论”。)纯粹基于语法的操作方法可以巧妙地避开所有这些数学问题。
介于操作和指称方法之间的另一种方法是可实现性。与其像在操作方法中那样使用句法术语,不如通过使用其他形式的数学表示形式来部分否定。这些代表可能没有资格成为真正的指称“含义”,但它们至少比句法术语更抽象。例如,对于多态Lambda演算,我们可以首先给未类型化的术语赋予含义(在未类型化的Lambda演算的某些模型中),然后将它们用作代表(“实现器”),以稍作一些形式的“操作推理”更抽象的层次。
因此,在指称方法,操作方法和可实现性方法之间要进行一些健康的竞争。没有伤害。
另一方面,不同的方法之间可能还会出现一些“不健康的”竞争。使用一种方法的人们可能是如此紧密地结合在一起,以至于他们可能看不到另一种方法的意义。理想情况下,即使它们不是我们个人的最爱,我们都应该意识到不同方法的优缺点,并对它们采取科学态度。
[另一个答案。堆积几个答案可能是不明智的。但是,这是一个很深的问题。]
我说我同意安德烈的回答,但是似乎我并不完全同意。它们是有区别的。
我说过,指称语义必须说“这种表示法的意思是”。我的意思是,必须为符号分配含义,它们是某种形式的概念实体,而不是其他某些符号。相比之下,安德烈(Andrej)也用斯科特(Scott)的话解释道,含义必须是“数学”对象。我不认为数学上的必要。
例如,从我的角度来看,将符号的含义设为物理过程是完全可以的。在所有计算机程序使您的汽车刹车后,请飞行飞机,投下炸弹,然后执行其他操作。这些是物理过程,而不是某些数学空间中的元素。您不能投下炸弹,看看它是否杀死了某人,否则就将其收回。计算机程序无法做到这一点。但是数学函数可以。(它们被称为“快照”操作。)因此,目前尚不清楚数学函数是否对计算机程序具有良好的意义。
另一方面,我们真的还不知道如何抽象地讨论物理过程。因此,我们确实可以使用一些数学上的过程描述来表达我们的想法。但是这些数学描述仅仅是“描述”。它们不是意义。真正的意义只是我们从概念上想象的物理过程。
Hoare在SIGPLAN奖的获奖感言(不久之后会在youtube上)中说,ACP使用“代数方法”,CSP使用“指示性方法”,CCS使用“操作方法”来描述过程。奥哈德和我一起坐在会议上,我们互相看着对方,说:“那真的很有趣”。因此,这里有很多概念空间正在探索中。我认为,斯科特后来的许多工作,涉及邻域系统和信息系统等,的确是为了将功能解释为某种形式的“过程”。吉拉德的互动几何和后来的游戏语义也在努力将功能解释为过程。我想说,建立扎实的过程理论可能是计算机科学可以为21世纪数学做出的巨大贡献。我不会接受数学能够解决所有问题的信念,我们应该尝试将计算现象简化为数学概念,以便理解它们。
令我惊讶的是,信息隐藏在状态计算(命令式编程和过程计算)中的工作方式多么精美,而在数学/函数形式主义中却笨拙而复杂。是的,我们具有关系参数性,它使我们可以很好地克服数学形式主义的局限性。但是它不符合命令式编程的简单性和优雅性。因此,我不认为数学形式主义是正确的答案,尽管我承认它们是我们目前的最佳答案。但是我们应该继续寻找。有一种很好的过程理论可以击败传统的数学方法。
[希望这是我对这个问题的最后回答!]
Ohad最初提出的问题是有关指称语义与结构操作语义的区别。他认为他们两个都是组成。实际上,这是不正确的。结构操作语义作为步骤序列给出。每个步骤都是用结构表示的(Plotkin的发现很可能做到这一点很了不起!),但是整个行为并未按结构定义。这是普洛特金(Plotkin)在他对SOS文章的介绍中所强调的内容[重点添加]:
在指称语义学中,人们遵循一种理想的构词性,即复合短语的含义是其组成部分含义的函数。在操作语义的情况下,应考虑程序短语的行为,这只是它可以进行的转换的集合。但是,当考虑到程序短语的功能时,这种行为并不是组成性的。但是,规则确实在语法上从结构上(即,递归地)给予它; ...
每个步骤都以组合方式表示的事实并不意味着整个行为都以组合方式表示。
卡尔·冈特(Carl Gunter)撰写的一篇不错的文章叫做《形式规范的语义规范》,其中对指定语义的不同方法进行了比较和对比。该材料的大部分内容也都在他的“编程语言语义学”文本的第一章中进行了复制。希望这可以澄清图片。
关于“操作语义学”的另一个词。在早期,术语“可操作的”用于指代涉及详细评估步骤的任何语义定义。指称语义学家和公理支持者都看不起“操作”语义,认为它是低级且面向机器的。我认为这实际上是基于他们的信念,即更高层次的描述是可能的。一旦考虑了并发性,这些信念就被粉碎了。de Bakker和Zucker的过程和并发的指称语义包含以下有趣的段落:
我们将使用指称语义学的方法。这里应将“表示性”与“可操作性”进行对比:前一种方法的关键思想是,编程语言中的表达式表示配备了适当结构的数学域中的值,而在后者中,语言构造所规定的操作是通过一些合适的抽象机执行的步骤来建模。
数学模型包含各种概念,尽管它们在风格上是指称的,但在精神上是可操作的 [强调增加]。这些包括过程本身概念的“历史”特征,以及在处理同步和递归时使用所谓的静默动作。
在这里,我们看到作者在“操作”的两个概念中挣扎,一个是技术概念,即使用句法操纵表达的行为,另一个是概念概念,这是低级且详细的。归功于Plotkin和Milner修复了“操作”语义,使其尽可能地高级,并表明它可能是优雅而有见地的。
尽管如此,过程的操作概念还是与过程的概念性概念大不相同,后者是由de Bakker和Hoare及其团队共同开发的。而且,我认为关于否定过程的概念还有很多神秘而美丽的地方,尚待理解。
这种额外的响应是为了放大指称语义模型旨在“解释”计算现象的观点。我将从命令式编程语言(也称为“类似于Algol”的语言)的语义中给出一系列示例。
首先是Scott和Strachey制定的语义模型。(参见Gordon:对编程语言的描述性描述-我一直以来最喜欢的书或Winskel的书。)此模型假定存在一个全局状态,该状态由程序分配的所有位置的状态组成。从全局状态到全局状态,每个命令都被解释为某种功能。
雷诺兹表示,它没有对局部变量的堆栈规则进行建模。输入本地范围后,将分配其变量,并在退出范围时将其释放。基本上,这是一个问题,“局部变量在什么意义上是局部的?” 语义如何捕获局部性?为了解释这一点,他发明了函子类别模型。(参见雷诺兹:Algol和Tennent的本质:编程语言的语义学)。
Tennent希望对雷诺规范逻辑(Hoare Logic对高阶过程的扩展)中制定的推理原理建模。逻辑具有类似表达式的(只读)计算,不像命令的表达式和类似表达式的计算之间的干扰以及一些数据抽象推理原理的思想。他改进了雷诺兹的函子类别模型,以找到新的模型。Tennent的书中也提到了这种称为“ SASL”的模型。
Meyer和Sieber以及O'Hearn和Tennent都指出,这些模型中没有一个仍然可以完全捕捉局部变量的局部性。当抽象数据类型或类的两个实现的局部变量不同,但从外部观察时,它们以具有相同行为的方式操纵它们时,它们在观察上是等效的。指称语义应等同于它们。为了对此建模,O'Hearn和Tennent在Reynolds的函子类别模型的变体中添加了关系参数。
当我同时研究问题时,我不相信函子类别方法。我还认为这过于技术性,因此认为必须有一个更简单的模型。这导致我发明了“全局状态被认为是不必要的”模型,该模型类似于CSP跟踪模型,但使用的是高级语言。此外,此模型还捕获了状态更改的不可逆性,这是早期模型中所没有的。
我的模型仅适用于行为良好的Algol子语言,称为干扰的语法控制。Abramsky和McCusker使用游戏语义学思想扩展了我的模型,以便它可以用于完整的Algol。因此,他们的模型解释了与我的现象相同的现象,只是用了更大的语言。
在每种情况下,我们都能够证明新模型捕获了表现出上述计算现象的观测等价物(或其他形式的逻辑公式),而早期模型并未对此进行验证。因此,这些模型在“解释”计算现象方面有一种非常精确的意义。