我正在阅读《工作中的编码器》,其中有很多关于不变式的讨论。据我了解,不变量是在表达式之前和之后均保持的条件。如果我正确记得我的逻辑课程,那么它们对于证明循环正确是很有用的。
我的描述是正确的,还是我错过了什么?您在程序中使用过它们吗?如果是这样,他们如何受益?
我正在阅读《工作中的编码器》,其中有很多关于不变式的讨论。据我了解,不变量是在表达式之前和之后均保持的条件。如果我正确记得我的逻辑课程,那么它们对于证明循环正确是很有用的。
我的描述是正确的,还是我错过了什么?您在程序中使用过它们吗?如果是这样,他们如何受益?
Answers:
在OOP中,不变量是一组声明,它们必须在对象的生存期内始终成立,以使程序有效。每当对象当前未执行更改其状态的方法时,从构造函数的末尾到析构函数的开头,它均应为true。
不变的一个例子可能是两个成员变量之一恰好为空。或者说,如果一个具有给定值,那么另一个允许的值就是这个或那个...
我有时使用对象的成员函数检查不变量是否成立。如果不是这种情况,则会引发一个断言。并且该方法在更改对象的每个方法的开始和退出处调用(在C ++中,这仅是一行...)
好吧,我在该线程中看到的东西都很棒,但是我有一个“不变式”的定义,这对我的工作非常有帮助。
不变性是程序执行期间必须遵守的任何逻辑规则,可以传达给人类,但不能传达给编译器。
此定义很有用,因为它将条件分为两类:可以信任编译器的强制执行条件,以及必须记录,讨论,评论或以其他方式传达给贡献者的条件,以便他们与代码库进行交互而不会引入错误。
另外,此定义很有用,因为它允许您使用概括性“不变式不好”。
例如,手动变速箱中的换挡器经过精心设计,可以避免产生不变量。如果需要的话,我可以为每个档建立一个变速杆。该杠杆可以向前(“接合”)或向后(“分离”)。在这样的系统中,我创建了一个“不变式”,可以这样记录:
“至关重要的是,在接合不同的齿轮之前,先将当前接合的齿轮断开。要同时接合任何两个齿轮,将导致机械应力,从而将变速器撕裂。在接合另一个齿轮之前,请始终分离当前接合的齿轮。”
因此,有人可能将变速箱损坏归咎于马虎驾驶。但是,现代汽车只使用一根可在齿轮之间旋转的棍棒。它的设计方式使现代变速杆汽车无法同时接合两个齿轮。
通过这种方式,我们可以说变速箱已被设计为“删除不变式”,因为它不允许以违反逻辑规则的方式对其进行机械配置。
从代码中删除的每种此类不变式都是一种改进,因为它降低了使用它的认知负担。
基于以下来自Coders At Work的报价...
但是,一旦您知道它保持不变,就可以看到啊,如果我们保持不变,那么我们将获得日志查找时间。
...我想“ invariant” =“您要维持以确保达到预期效果的条件”。
似乎不变式有两种微妙的不同含义:
所以1就像一个断言;我认为2就像是证明正确性,性能或其他属性的工具。有关2的示例,请参阅Wikipedia文章(证明MU拼图解决方案的正确性)。
实际上,第三种不变性是:
.3。程序(或模块或功能)应该做什么?换句话说,它的目的。
来自同一位“工作中的程序员”访谈:
但是,使大型软件易于管理的原因是,它具有一些全局不变性或关于其应做的事情以及应做的事情是真实的大体陈述。
不变性就像可以用来支配程序逻辑的规则或假设。
例如,假设您有一些跟踪用户帐户的软件应用程序。还假设用户可以有多个帐户,但是出于任何原因,您都需要区分用户的主帐户和“别名”帐户。
这可能是数据库记录或其他记录,但是现在让我们假设每个用户帐户都由一个类对象表示。
class userAccount {private char * pUserName; 私人字符* pParentAccountUserName;
...}
不变的假设是,如果pParentAccountUserName为NULL或为空,则此对象为父帐户。您可以使用该变量来区分不同类型的帐户。可能有更好的方法来区分不同类型的用户帐户,因此请记住,这只是一个示例,说明了如何使用不变式。
从物理学的背景来看,在物理学中,我们有不变量,它们本质上是数量,在整个计算/模拟过程中不会变化。例如,在物理学中,对于一个封闭的系统,总能量是守恒的。还是在物理学上,如果两个粒子碰撞,则产生的碎片必须完全包含它们开始时的能量以及完全相同的动量(矢量)。通常,没有足够的不变式来完全指定结果。例如,在2粒子碰撞中,我们有四个不变量,三个动量分量和一个能量分量,但是系统具有六个自由度(六个数字来描述其状态)。不变量应在舍入误差内保守,但其保守性不能证明解是正确的。
因此,通常情况下,这些内容作为健全性检查很重要,但它们本身无法证明正确性。