Предварительные условия обычно пересекаются с инвариантами?

У меня проблемы с их дифференциацией. Если они обычно не перекрываются, чем они отличаются? Что является примером чего-то, что было бы предварительным условием, но не инвариантом?

1

Решение

Некоторые другие ответы пытаются определить термины «предварительное условие» и «инвариант». Я думаю, например Википедия намного лучше справляется с этой задачей, поэтому вместо этого я просто связался с Википедией для определений. Во всяком случае, если бы вопрос был исключительно об определениях, то это было бы прочти чертову документацию вопрос, и я бы проголосовал, чтобы закрыть его, вместо того, чтобы отвечать.


«Если [предварительные условия и инварианты] обычно не пересекаются, чем они отличаются?»

методПредпосылки всегда можно рассматривать как единое целое предварительное условие формируется из совокупности отдельных подусловий, и поэтому мы часто говорим и рассуждаем о «предварительном» условии.

Для публичный метод одним из подусловий всегда является инвариант класса, так что да, есть довольно часто перекрытие

Все становится сложнее при рассмотрении внутренних (private а также protected) методы. Часто открытый метод работает, временно нарушая инвариант класса и затем восстанавливая его. В течение периода недопустимого инварианта класса он может вызывать некоторые внутренние вспомогательные методы, и эти внутренние вспомогательные методы не могут иметь инвариант класса, включенный в их предварительные условия.

Все становится еще сложнее, когда кто-то пытается четко различить общедоступный интерфейс и детали реализации, и предыдущая попытка представить Eiffel-как Дизайн по контракту (DBC) Утверждения в C ++ застряли на этом.

Однако на практике это достаточно просто, потому что на практике можно просто избежать очень сложных случаев, так сказать, дизайна вокруг него.


«Что является примером чего-то, что было бы предварительным условием, но не инвариантом?»

Например,

class Foo
{
public:
void add( Bar* p )
{
assert( p != 0 );    // Precondition unrelated to the class invariant
// ... whatever
}
};
2

Другие решения

Предварительным условием является то, что должно быть верно до, но не обязательно во время или после. Инвариант, как следует из названия, не изменится ни в какой момент времени. Например, допустим, я хочу нормализовать вектор. Предварительным условием может быть то, что его текущая норма не должна быть равна 0 (потому что это приведет к делению на ноль). Операция нормализации изменила бы норму вектора, что означает, что это будет предварительным условием, но не инвариантом.

1

Инвариант — это обычно какое-то свойство вашего состояния. Например, вы можете утверждать, что 1 <= x <= 100 всегда.

Предварительное условие применяется к вызову метода. Например, если класс, содержащий x выше есть метод Foo(int y, int z) предварительным условием может быть y < x а также z > 10000 чтобы вызов функции был действительным.

0

Короткий ответ: да. Предварительные условия, постусловия и инварианты — это, по сути, разные аспекты одной и той же вещи.

Предварительным условием является «мгновенная» проверка перед завершением операции.
Постусловие — это «мгновенная» проверка после завершения операции.
Инвариант — это проверка, которая сохраняется в течение некоторого времени.

Например, если у вас есть функция квадратного корня, для которой аргумент должен быть> = 0, это является предварительным условием, поскольку это проверка, проводимая перед операцией.

С другой стороны, если у вас есть класс с членами х & y, такой что x> y всегда, это инвариант, так как условие сохраняется в течение некоторого времени (в течение жизни вашего объекта). Аналогично, если у вас есть цикл, и какое-то условие должно выполняться на каждой итерации цикла, это тоже является инвариантом, так как проверка сохраняется в течение некоторого времени. Как правило, термины инвариант класса и цикл-инвариант будут использоваться для указания типа инварианта.

0