Programming languages 什么是先决条件和后决条件?

Programming languages 什么是先决条件和后决条件?,programming-languages,design-by-contract,preconditions,post-conditions,Programming Languages,Design By Contract,Preconditions,Post Conditions,我正在学习如何编程,但有一件事我不能完全理解,那就是先决条件和后决条件 调用函数之前的if语句是否被视为先决条件,或者在大多数语言中是否有一种更有效的方法来实现这一点 我也在努力寻找任何用我目前的编程知识可以理解的先决条件的例子,如果有人能证明一个简单的先决条件,我会非常感激(任何语言都可以)这是一个计算机科学问题,不是一个编程问题,所以在,但我还是会回答的 考虑一下这个程序,可以大海捞针地找到针的第一个索引。(干草堆可能包含许多针;我们希望在第一个针处停止。)如果干草堆不包含针,则索引等于干草

我正在学习如何编程,但有一件事我不能完全理解,那就是先决条件和后决条件

调用函数之前的if语句是否被视为先决条件,或者在大多数语言中是否有一种更有效的方法来实现这一点


我也在努力寻找任何用我目前的编程知识可以理解的先决条件的例子,如果有人能证明一个简单的先决条件,我会非常感激(任何语言都可以)

这是一个计算机科学问题,不是一个编程问题,所以在,但我还是会回答的

考虑一下这个程序,可以大海捞针地找到针的第一个索引。(干草堆可能包含许多针;我们希望在第一个针处停止。)如果干草堆不包含针,则索引等于干草堆的大小(这不是进入干草堆的有效索引)

(注:
0…i
指所有
j
,因此
0≤ J≤ i

前提条件告诉我们,索引
i
处的所有haystack元素(包括该元素)都不是针


每次程序到达该前提条件时,您都可以使用来证明该前提条件为真。循环在其条件为false时结束,这意味着第一个后置条件为true。(第一个后置条件与循环条件相反。)循环先决条件为真这一事实意味着第二个后置条件也为真。

这一点在本文中得到了很好的阐述

  • 先决条件是一个谓词,它应该在进入一个函数时保持。它表示函数对其参数的期望和/或函数可能使用的对象的状态

  • 后置条件是一个谓词,它应该保持退出函数。它表示函数应确保返回值和/或函数可能使用的对象状态的条件


先决条件和后决条件属于基于合同的编程

在Dlang,基于合同的编程具有良好的设计。提供了一个示例:

long square_root(long x)
in
{
    assert(x >= 0);
}
out (result)
{
    assert(result ^^ 2 <= x && (result + 1) ^^ 2 > x);
}
do
{
    return cast(long)std.math.sqrt(cast(real)x);
}
长平方根(长x)
在里面
{
断言(x>=0);
}
输出(结果)
{
断言(结果^^2 x);
}
做
{
返回铸件(长)标准数学sqrt(铸件(实)x);
}
先决条件
in
块中,后决条件
out
块中

  • 如果满足了先决条件后决条件,则它将愉快地编译,就像将
    9
    传递到函数中一样
  • 如果不满足先决条件,例如将
    -1
    传递到函数中。 core.exception。AssertError@prog.d(8) :断言失败

  • 如果由于我们没有处理
    do
    块中的逻辑(如返回
    square
    而不是
    square root
    )而导致后条件不满足,则后条件将起作用: core.exception。AssertError@prog.d(13) :断言失败

对于课堂,德朗也有很好的工具,通过阅读了解更多


建议是否也有助于理解它们(尽管比D、IMHO丑陋得多)

i = 0
while i < haystack.count && haystack[i] != needle {
    i = i + 1
}
assert(i == haystack.count || haystack[i] == needle) // first postcondition
haystack[0 ..< i].forEach { assert($0 != needle) } // second postcondition
i = 0
while i < haystack.count && haystack[i] != needle {
    haystack[0 ... i].forEach { assert($0 != needle) } // precondition
    i = i + 1
}
assert(i == haystack.count || haystack[i] == needle) // first postcondition
haystack[0 ..< i].forEach { assert($0 != needle) } // second postcondition
long square_root(long x)
in
{
    assert(x >= 0);
}
out (result)
{
    assert(result ^^ 2 <= x && (result + 1) ^^ 2 > x);
}
do
{
    return cast(long)std.math.sqrt(cast(real)x);
}