为什么不变式在计算机科学中很重要


16

我从字面上理解“不变式”。当我键入代码时,我也会识别它们。但是我认为我不理解这个术语在计算机科学中的重要性。

每当我阅读著名程序员\计算机科学家的有关语言设计的对话\白皮书时,“不变”一词就会不断冒出来。那是我不理解的部分。有什么特别之处?


我经常使用断言...并不是为了保证正确性,而是为了减少错误的可能性。
Job

Answers:


7

算法是可重复的过程。如果它是可重复的,则它必须具有不会随重复而改变的属性。这些是您的不变式。这些不变量与(可能)变化的数据组合和/或对其进行操作,这些数据将被馈送到您的算法中。

因此,编程的全部重点是要确定哪些没有变化-本质上就是您的程序。

在面向对象的程序中,有一个概念,即每个对象都应该做一件事情。从本质上讲,这意味着(对于基于类的OOP),一个类定义单个算法的不变量,以及其对象可能需要的任何变体数据的占位符(变量)。理想情况下,在OO中,您将尽可能多地隔离变化,以便每个对象大部分都是不变的。


27

不变的概念与“副作用”密切相关。我相信它是由Bertrand Meyer的“按合同设计(DbC)设计”方法促进软件设计的。

DbC通过3个重要的概念,前提条件,后置条件和不变量来丰富抽象数据类型(类的主干)。在引用过程时,它很容易解释,因此,我将尝试对其进行解释:

  1. 前提表示条件输入数据的程序必须以调用该程序的尊重。该特定过程的客户必须遵守并执行此先决条件。但是,过程设计者可以通过将条件声明为过程中的第一行来抵御那些不尊重前提条件的客户端。例如,拥有一个方法double divide(double dividend, double divisor)的前提可能是divisor != 0

  2. 后置条件表示在过程返回后的输出数据的条件; 只要遵守前提条件,流程设计者的全部工作就是尊重该前提条件。在返回之前可以以防御编程风格进行声明,可以声明后置条件。

  3. 一个不变量可以被看作是双方的先决条件和后置条件,但是从上述概念的先决条件和后置条件不同的理解。不变式基本上说,如果输入具有在调用过程之前满足的特定条件,则该特定条件在调用过程之后才有效。例如,过程的有效不变量boolean search(int term, int array[])可能表示array调用之前的状态与调用之后的状态相同。

在过程(不仅是过程)上执行不变式是一件好事,因为它可以减少副作用。这是有用的,因为副作用在编程中是一个极大的弊端。特定过程可能会更改输入自变量的状态,或更改某些全局变量的状态,或依赖于某些全局变量。这可能会导致令人讨厌的情况,其中在相同过程(具有相同输入)上的两个相同调用可能会产生不同的输出。这导致了解调用的历史记录,并且很难调试,尤其是在多线程上下文中。


2

不变式是某些操作保留的逻辑属性。

  • 您需要不变量来推断循环。由于您事先不知道会有多少次迭代(或者您不需要循环),因此每次迭代都必须保留不变式,以便最后可以证明有关循环的一些有用属性。

  • 您需要不变量来推断封装数据的属性。通常,模块或对象中的各种数据需要满足某些属性才能正确操作(例如,代表集合的列表必须始终排序)。您希望对数据进行操作的每个函数或方法都保留这些属性,因此它们也是不变的。


0

据我所知,不变性的重要性来自这样一个事实,即它是证明算法确实可以计算特定功能的基础。例如,您已经开发了一种新的排序算法,但是如何确保它确实对每个输入或每个正确的输出进行排序。下一步是构造与算法流程相对应的不变量,并证明它使用不变量进行排序。


0

在编程语言的类型系统的上下文中,不变类型是不可转换的类型。例如在Java中,当重载方法时,所有参数都是不变的,而返回类型是协变的(可以是相同的或子类型)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.