计算机科学哲学(一)

1. 计算系统

1.1 软件和硬件

1.2 抽象层次方法

2. 意图和规范

2.1 意图

2.2 定义和规范

2.3 规范和功能

3. 算法

3.1 经典方法

3.2 形式化方法

3.3 非正式方法

4. 程序

4.1 程序作为理论

4.2 程序作为技术工件

4.3 程序及其与世界的关系

5. 实施

5.1 作为语义解释的实施

5.2 作为规范-工件关系的实施

5.3 LoAs 的实施

5.4 物理计算

6. 验证

6.1 模型和理论

6.2 测试和实验

6.3 解释

7. 正确性

7.1 数学正确性

7.2 物理正确性

7.3 错误计算

7.4 实用正确性

8.计算机科学的认识论地位

8.1 计算机科学作为一门数学学科

8.2 计算机科学作为一门工程学科

8.3 计算机科学作为一门科学学科

参考书目

学术工具

其他互联网资源

相关条目

1. 计算系统

计算系统在日常生活中广泛存在。它们的设计、开发和分析是计算机科学学科的正确研究对象。计算机科学哲学将它们视为理论分析的对象。它的首要目标是定义这样的系统,即开发计算系统的本体。文献提供了两种关于该主题的主要方法。第一种方法是将计算系统理解为由软件和硬件的不同本体定义的,通常被视为其基本组件。另一种观点认为,计算系统由软件-硬件二分法周围的几个其他元素组成:在第二种观点下,计算系统是基于抽象层次的层次结构来定义的,将硬件层次安排在这种层次结构的底部,向上延伸到设计元素,向下延伸到用户。下面我们将介绍这两种方法。

1.1 软件和硬件

通常,计算系统被视为由两个本体论上不同的实体组成:软件和硬件。算法、源代码和程序属于第一类抽象实体;微处理器、硬盘和计算机是具体的物理实体。

Moor (1978) 认为,这种二元性是计算机科学的三大神话之一,因为软件/硬件二分法具有实用意义,但没有本体论意义。计算机程序是计算机可以执行的一组指令,既可以在符号层面(编码指令)进行检查,也可以在物理层面(存储在物理介质中的一组指令)进行检查。Moor 强调,没有程序以纯粹的抽象实体存在,也就是说,没有物理实现(闪存驱动器、服务器上的硬盘,甚至一张纸)。早期的程序甚至是直接硬连线的,在计算机时代初期,程序仅由物理杠杆模式组成。根据软件/硬件的对立,人们通常将软件与程序的符号层联系起来,将硬件与相应的物理层联系起来。然而,这种区别只能在实用上得到证明,因为它界定了开发人员的不同任务。对他们来说,软件可能是算法和实现它们的源代码,而硬件则是机器代码和能够执行它的微处理器。相比之下,实现实现硬连线程序的电路的工程师可能倾向于将软件称为计算机的许多物理部件。换句话说,对于一个专业人士来说算作软件的东西,对于另一个专业人士来说可能算作硬件。

Suber (1988) 甚至走得更远,认为硬件是一种软件。软件被定义为任何可以读取和执行的模式:一旦人们意识到所有物理对象都显示模式,人们就不得不接受这样的结论:硬件作为物理对象,也是软件。 Suber 将模式定义为“任何明确的结构,而不是狭义上的需要某种重复、规律或对称的结构”(1988,90),并认为任何这样的结构确实可以读取和执行:对于任何没有关联意义的明确模式,总是可以设想一种赋予意义的语法和语义,从而使该模式成为可执行程序。

Colburn (1999,2000) 在将软件和硬件区分开来的同时,强调前者具有双重性质,它是一种既抽象又具体的“具体抽象”。要定义软件,需要参考“描述媒介”,即用于表达算法的语言,以及“执行媒介”,即组成硬件的电路。虽然软件总是具体的,因为没有在某种物理媒介中具体化就没有软件,但它仍然是抽象的,因为程序员在活动中不考虑实施机器:他们宁愿开发任何机器都可以执行的程序。科尔伯恩 (1999) 将此方面称为“内容的扩大”,它将计算机科学中的抽象定义为“内容的抽象”:内容被扩大而不是删除,就像数学抽象一样。

Irmak (2012) 批评了科尔伯恩 (1999, 2000) 提出的软件的双重性质。他认为抽象实体是缺乏时空属性的实体,而具体意味着具有这些属性。因此,将软件定义为具体的抽象意味着软件具有矛盾的属性。软件确实具有时间属性:作为人类创造的对象,它在构思和实施后开始存在;并且它可以在随后的某个时间停止存在。当所有副本都被销毁、作者去世并且没有人记得相应的算法时,软件将不复存在。作为人类创造的对象,软件是一种人工制品。但是,软件缺乏空间属性,因为它无法与它的任何具体实现联系起来。如上所述,销毁给定软件的所有物理副本并不意味着特定软件不复存在,出于同样的原因,删除使用某种高级语言实现软件算法的所有文本也不会不复存在。因此,软件是一种具有时间属性的抽象实体。出于这些原因,Irmak (2010) 将软件定义为抽象人工制品。

Duncan (2011) 指出,区分软件和硬件需要比涉及简单的抽象/具体二分法的本体更精细的本体。Duncan (2017) 旨在通过关注 Turner (2011) 的规范概念来提供这样的本体,该规范是为程序提供正确性条件的表达式(见 §2)。Duncan (2017) 强调程序也是实施机器的规范,这意味着程序指定了机器需要执行的所有正确行为。如果机器的行为与程序不一致,则机器被称为故障,同样,与其规范不符的程序被称为有缺陷或包含错误。定义软件/硬件区别所需的另一个本体类别是人工制品,Duncan (2017) 将其定义为物理的时空实体,其构造是为了实现某些功能,并且有一个社区承认该人工制品服务于该目的。也就是说,软件被定义为一组用某种编程语言编码的指令,这些指令充当能够读取这些指令的工件的规范;硬件被定义为一种工件,其功能是执行指定的计算。

1.2 抽象层次方法

如上所示,软件和硬件之间的区别并不明显。计算系统的不同本体论方法依赖于抽象的作用。抽象是计算机科学中的关键要素,它有多种不同的形式。Goguen & Burstall (1985) 描述了其中的一些,以下示例就是其中的实例。在编程过程中,可以通过命名文本和参数来重复代码,这种做法称为过程抽象。此操作的形式基础是 lambda 演算的抽象操作(参见 lambda 演算条目),它允许一种称为多态性的形式机制(Hankin 2004)。另一个例子是类型,这是函数式编程的典型特征,它为语言的句法构造函数提供了一个富有表现力的表示系统。或者,在面向对象设计中,模式(Gamma 等人,1994)是从软件系统中发现的通用结构中抽象出来的,并用作对象实现与其规范之间的接口。

所有这些示例都共享抽象层次(以下称为 LoA)中的底层方法,该方法也用于数学(Mitchelmore 和 White,2004)和哲学(Floridi,2008)。数学中的抽象层层堆叠,永无止境地寻找越来越多的抽象概念。同样,计算机科学中的抽象是一个动态的、分层的过程,从以前的抽象层次中创建新的抽象层次(Turner,2021)。考虑抽象数据类型的情况,它们仅基于从任何具体类型的物理属性中抽象出的操作来定义。例如,列表作为一种抽象类型,可以通过 nil(返回空列表)、cons(构造列表)、head(返回第一个元素)和 tail(返回列表的其余部分)等操作来定义。对列表执行的进一步抽象会导致创建新的抽象数据类型。两个列表之间的置换函数 (perm) 允许定义类型 bag,在执行操作 Dup(删除重复项)和 Ord(删除顺序)时,可以获得类型 finiteset (Turner 2021)。

因此,抽象是自足的:抽象的数学对象仅从定义它的系统中获取其含义,​​唯一的约束是新对象必须在一致的系统中相互关联,该系统可以在不参考先前或外部含义的情况下进行操作。有人认为,至少在这方面,计算机科学中的抽象与数学中的抽象有着根本的不同:​​计算抽象必须留下实现的痕迹,这意味着信息被隐藏但不会被破坏(Colburn & Shute 2007)。在某一 LoA 中被忽略的任何细节都不能被较低的 LoA 之一忽略:例如,程序员不必担心与特定变量相关的内存中的精确位置,但虚拟机需要处理所有内存分配。这种对不同层次抽象的依赖反映在计算系统依赖于实现存在的属性中:例如,即使类隐藏了其方法的细节,它们也必须有实现。因此,计算抽象既保留了抽象的外表,也保留了实现。

Primiero (2016) 设计了数字计算系统本体的 LoA 的完整公式,包括:

意图

规范

算法

高级编程语言指令

汇编/机器代码操作

执行

意图是定义要解决的计算问题的认知行为:它制定创建计算过程以执行某项任务的请求。此类请求通常由参与给定软件开发项目的客户、用户和其他利益相关者提供。规范是制定解决手头计算问题所需的一组要求:它涉及通过称为需求引出的过程正式确定软件必须执行的操作。算法表达了为所提出的计算问题提供解决方案的过程,该解决方案必须满足规范的要求。高级编程语言(如 C、Java 或 Python)指令构成了所提出算法的语言实现,通常称为源代码,它们可以被训练有素的程序员理解,但不能由机器直接执行。用高级语言编写的指令由编译器编译(即翻译)为汇编代码,然后组装成处理器可执行的机器代码操作。最后,执行 LoA 是运行软件的物理层,即执行指令的计算机架构的物理层。

根据这种观点,任何单独的 LoA 都无法定义什么是计算系统,也无法确定如何区分软件和硬件。计算系统是由整个抽象层次定义的;每个 LoA 本身都表达了与实现相关的语义级别,无论是语言的还是物理的。

2. 意图和规范

意图是指计算系统之外的认知状态,它表达了要解决的计算问题的公式。规范描述了要开发的计算系统必须实现的功能。虽然意图本身在计算机科学哲学中不会引起特定的哲学争议,但问题出现在规范的定义及其与意图的关系上。

2.1 意图

意图阐明了确定计算系统是否合适(即是否正确,参见第 7 节)的标准,因此它被视为适合该问题的计算系统的第一个 LoA。例如,客户和用户可能需要一个能够过滤掉呼叫中心烦人的电话的智能手机应用程序;这种要求构成了开发能够执行此类任务的计算系统的意图 LoA。在非幼稚系统的软件开发过程中,意图通常通过头脑风暴、调查、原型设计甚至焦点小组(Clarke and Moreira 1999)等技术收集,旨在定义各种利益相关者意图的结构化集合。在这个 LoA 中,没有提到如何解决计算问题,而只提供了必须解决的问题的描述。

在当代文献中,意图至少自 Anscombe(1963)以来一直是哲学研究的对象。哲学家们研究过“执行行动的意图”(Davidson 1963)、未来做某事的意图(Davidson 1978)和有意图的行动(Anscombe 1963、Baier 1970、Ferrero 2017)。问题在于,这三种意图中哪一种是主要的,它们如何联系,意图与信念之间的关系,意图是否是或预设了特定的心理状态,以及意图是否充当行动的原因(参见意图条目)。更正式的问题涉及代理拥有不一致的意图但仍然被认为是理性的机会(Bratman 1987、Duijf 等人 2019)。

作为计算系统本体论中的第一个 LoA,意图当然可以被视为未来的意图,因为它们表达了构建能够执行某些所需计算任务的系统的目标。如上所述,由于意图仅限于定义要解决的计算问题,而不指定其计算解决方案,因此它们的本体论和认识论分析与哲学文献中提到的分析并无不同。换句话说,在定义计算系统的意图中,没有任何特定的计算性,这值得在计算机科学哲学中单独处理。这里重要的是意图和规范之间的关系,因为意图为规范提供了正确性标准;规范被要求表达如何解决意图提出的计算问题。

2.2 定义和规范

再次考虑呼叫过滤应用程序的示例;规范可能需要创建与呼叫中心相关的电话号码黑名单;每 n 天更新一次列表;在来电时检查号码是否在黑名单上;通知呼叫管理系统,在肯定回答的情况下不允许来电,在否定回答的情况下允许来电。

后者是一个成熟的规范,尽管是用自然语言表达的。规范通常以自然语言提出,以更接近利益相关者的意图,然后才以适当的形式语言形式化。规范可以通过图形语言(如 UML(Fowler 2003))或更正式的语言(如 TPL(Turner 2009a)和 VDM(Jones 1990))来表达,使用谓词逻辑,或 Z(Woodcock and Davies 1996),专注于集合论。例如,类型谓词逻辑 (TPL) 使用谓词逻辑公式表达计算系统的要求,其中指定了量化变量的类型。变量类型的选择允许人们在更合适的抽象级别定义规范。规范是以非正式还是正式的形式表达通常取决于所遵循的开发方法,在正式开发方法的背景下,通常首选正式规范。此外,正式规范有助于验证计算系统的正确性(参见§6)。

Turner (2018) 询问模型和规范之间有什么区别,这两者都广泛应用于计算机科学。区别在于 Turner (2011) 所说的意向立场:模型描述了要开发的预期系统,如果两者不匹配,则需要改进模型;规范规定了如何构建系统以符合预期的功能,如果不匹配,则需要改进系统。因此,模型和规范在信息内容上可以是等同的,但在治理方向上有所不同(Turner 2020)。模型和系统之间的匹配反映了意图(描述根据系统必须能够解决的计算问题构建什么系统)与规范(确定如何构建系统,根据解决计算问题所需的一组要求,如呼叫过滤应用程序所示)之间的对应关系。用 Turner (2011) 的话来说,“当某物被赋予对某个工件的正确性管辖权时,它就是规范”:规范为计算系统提供了正确性标准。因此,当计算系统符合其规范时,即当它们按照规范运行时,它们就是正确的。相反,它们提供了故障标准(§7.3):当计算系统的行为不符合其规范时,它就会发生故障。 Turner (2011) 谨慎地指出,这种规范定义是一种理想化:在某些情况下,规范本身也会被修改,例如当指定的计算系统由于物理定律约束或成本限制而无法实现时,或者当发现高级规范不是客户和用户意图的正确形式化时。

更一般地说,正确性问题不仅涉及规范,还涉及任何两个定义计算系统的 LoA,下一小节将对此进行探讨。

2.3 规范和功能

完全实现和构建的计算系统是技术工件,即设计和实现的人造系统,其明确目的是实现特定功能(Kroes 2012)。如此定义的技术工件包括桌子、螺丝刀、汽车、桥梁或电视机,它们既不同于非人造的自然物体(例如岩石、猫或一氧化二氢分子),也不同于不实现功能的艺术品。因此,计算系统的本体属于技术制品(Meijers 2000)的本体,其特点是二元性,因为它们由功能和结构属性定义(Kroes 2009,另见技术哲学条目)。功能属性指定制品需要执行的功能;结构属性表达制品执行这些功能的物理属性。考虑一把螺丝刀:功能属性可能包括拧紧和松开的功能;结构属性可以指能够插入螺丝头的金属片和允许顺时针和逆时针运动的塑料手柄。功能可以通过其结构对应物以多种方式实现。例如,螺丝刀的功能可以由全金属螺丝刀实现,也可以由由非常不同的结构属性定义的电动螺丝刀实现。

计算系统的分层本体以许多不同的 LoA 为特征,似乎扩展了定义技术制品的双重本体(Floridi 等人,2015 年)。 Turner (2018) 认为,计算系统仍然是 (Kroes 2009, 2012) 意义上的人工制品,因为每个 LoA 对于较低的 LoA 来说都是一个功能级别,对于较高的 LoA 来说都是一个结构级别:

意图表达了系统必须实现的功能,并由规范实现;

规范起着功能性的作用,详细说明了软件必须实现的具体功能,并由算法(其结构级别)实现;

算法表达了高级语言程序(其结构级别)必须实现的过程;

高级语言中的指令为实现这些功能的机器语言代码定义了功能属性;

最后,机器代码表达了执行级别实现的功能属性,而执行级别则表达了物理结构属性。

因此,根据 Turner (2018) 的说法,结构级别不一定是物理级别,抽象人工制品的概念在计算机科学中是成立的。因此,Turner (2011) 将高级语言程序本身定义为技术工件,因为它们构成了实现规范的结构级别作为其功能级别(见§4.2)。

第一个结果是,每个 LoA(表达要完成的功能)都可以通过多种潜在的结构级别来实现,这些结构级别表达了这些功能的实现方式:预期的功能可以通过多种方式通过规范实现;规范表达的计算问题可以通过多种不同的算法来解决,这些算法可能在某些重要属性上有所不同,但都同样有效(见§3);一个算法可以在不同的程序中实现,每个程序都用不同的高级编程语言编写,如果它们实现相同的算法,则所有程序都表达相同的程序(Angius 和 Primiero 2019);源代码可以用多种机器语言编译,采用不同的 ISA(指令集架构);可执行代码可以在多台机器上安装和运行(前提是这些机器共享相同的 ISA)。

第二个结果是,每个 LoA 作为一个功能级别,为较低级别提供了正确性标准 (Primiero 2020)。不仅在实施级别,从规范到执行的任何 LoA 都需要正确性,故障原因可能位于任何未正确实施其适当功能级别的 LoA(参见 §7.3 和 Fresco, Primiero (2013))。根据 Turner (2018) 的说法,尽管很难验证其正确性,但可以说规范级别在意图方面是正确的或不正确的。任何非物理层的正确性都可以通过形式验证在数学上进行验证,而执行物理层可以通过测试(§6)在经验上进行验证。验证规范相对于客户意图的正确性将需要访问所涉及代理的心理状态。

(本章完)

相关推荐