it-swarm.dev

Was sind Invarianten, wie können sie verwendet werden und haben Sie sie jemals in Ihrem Programm verwendet?

Ich lese Coders at Work und darin wird viel über Invarianten gesprochen. Soweit ich es verstanden habe, ist eine Invariante eine Bedingung, die sowohl vor als auch nach einem Ausdruck gilt. Sie sind unter anderem nützlich, um zu beweisen, dass die Schleife korrekt ist, wenn ich mich richtig an meinen Logikkurs erinnere.

Ist meine Beschreibung korrekt oder habe ich etwas verpasst? Haben Sie sie jemals in Ihrem Programm verwendet? Und wenn ja, wie haben sie davon profitiert?

54
gablin

In OOP ist eine Invariante eine Reihe von Aussagen, die während der Lebensdauer eines Objekts immer zutreffen müssen, damit das Programm gültig ist. Es sollte vom Ende des Konstruktors bis zum Anfang des Destruktors gelten, wenn das Objekt derzeit keine Methode ausführt, die seinen Status ändert.

Ein Beispiel für eine Invariante könnte sein, dass genau eine von zwei Mitgliedsvariablen null sein sollte. Oder dass, wenn einer einen bestimmten Wert hat, die Menge der zulässigen Werte für den anderen dies oder das ist ...

Ich benutze manchmal eine Mitgliedsfunktion des Objekts, um zu überprüfen, ob die Invariante gilt. Ist dies nicht der Fall, wird eine Zusicherung erhoben. Und die Methode wird am Anfang und am Ende jeder Methode aufgerufen, die das Objekt ändert (in C++ ist dies nur eine Zeile ...)

47
Xavier Nodet

Nun, das Zeug, das ich in diesem Thread sehe, ist alles großartig, aber ich habe eine Definition einer "Invariante", die mir bei der Arbeit enorm geholfen hat.

Eine Invariante ist eine logische Regel, die während der Ausführung Ihres Programms eingehalten werden muss und die einem Menschen, aber nicht Ihrem Compiler mitgeteilt werden kann.

Diese Definition ist hilfreich, da sie die Bedingungen in zwei Gruppen unterteilt: diejenigen, deren Durchsetzung dem Compiler vertraut werden kann, und diejenigen, die dokumentiert, diskutiert, kommentiert oder auf andere Weise an Mitwirkende kommuniziert werden müssen, damit sie mit der Codebasis interagieren können, ohne Fehler einzuführen .

Diese Definition ist auch hilfreich, da Sie damit die Verallgemeinerung "Invarianten sind schlecht" verwenden können.

Beispielsweise ist der Schalthebel in einem Auto mit Schaltgetriebe so konstruiert, dass eine Invariante vermieden wird. Wenn ich wollte, könnte ich ein Getriebe mit einem Hebel für jeden Gang bauen. Dieser Hebel kann vorwärts ("eingerückt") oder rückwärts ("ausgerückt") sein. In einem solchen System habe ich eine "Invariante" erstellt, die als solche dokumentiert werden könnte:

"Es ist wichtig, dass das aktuell eingelegte Zahnrad ausgeschaltet wird, bevor ein anderes Zahnrad eingelegt wird. Das gleichzeitige Einlegen von zwei Gängen führt zu mechanischer Beanspruchung, die das Getriebe zerreißt. Schalten Sie das aktuell eingelegte Zahnrad immer aus, bevor Sie ein anderes einlegen."

Und so könnte man defektes Getriebe auf schlampiges Fahren zurückführen. Moderne Autos verwenden jedoch einen einzigen Steuerknüppel, der zwischen den Gängen schwenkt. Es ist so konzipiert, dass bei einem modernen Schaltauto nicht zwei Gänge gleichzeitig eingelegt werden können.

Auf diese Weise können wir sagen, dass die Übertragung so konstruiert wurde, dass sie die Invariante entfernt, da sie sich nicht mechanisch so konfigurieren lässt, dass sie gegen die logische Regel verstößt.

Jede Invariante dieser Art, die Sie aus Ihrem Code entfernen, ist eine Verbesserung, da sie die kognitive Belastung bei der Arbeit damit verringert.

15
Daniel Burbank

Basierend auf dem folgenden Zitat von Coders At Work ...

Aber sobald Sie die Invariante kennen, die sie verwaltet, können Sie sehen, ah, wenn wir diese Invariante beibehalten, erhalten wir die Zeit für die Protokollsuche.

... Ich denke "invariant" = "Bedingung, die Sie beibehalten möchten, um einen gewünschten Effekt sicherzustellen".

Es scheint, dass Invariante zwei Sinne hat, die sich auf subtile Weise unterscheiden:

  1. Etwas, das gleich bleibt.
  2. Etwas, das Sie versuchen, gleich zu halten, um Ziel X zu erreichen (z. B. eine "Protokollsuchzeit" oben).

Ich bin also wie eine Behauptung; 2 ist wie ein Werkzeug zum Nachweis von Korrektheit, Leistung oder anderen Eigenschaften - denke ich. Im Wikipedia-Artikel finden Sie ein Beispiel für 2 (um die Richtigkeit der Lösung des MU-Puzzles zu beweisen).

Tatsächlich ist ein dritter Sinn für Invariante:

.3. Was das Programm (oder Modul oder Funktion) tun soll; mit anderen Worten, sein Zweck.

Aus dem gleichen Coders At Work-Interview:

Aber was große Software handhabbar macht, sind einige globale Invarianten oder umfassende Aussagen darüber, was sie tun soll und welche Dinge wahr sein sollen.

3
Jonathan Aquino

Eine Invariante (im gesunden Menschenverstand) bedeutet einige Bedingungen, die zu einem bestimmten Zeitpunkt oder sogar immer während der Ausführung Ihres Programms erfüllt sein müssen. z.B. PreConditions und PostConditions können verwendet werden, um einige Bedingungen zu bestätigen, die beim Aufrufen und Zurückgeben einer Funktion erfüllt sein müssen. Objektinvarianten können verwendet werden, um zu behaupten, dass ein Objekt während seiner gesamten Existenz einen gültigen Status haben muss. Dies ist das Design-by-Contract-Prinzip.
Ich habe Invarianten informell verwendet, indem ich Code-Checks verwendet habe. Aber in jüngerer Zeit spiele ich mit dem Code Vertragsbibliothek für .Net , der Invarianten direkt unterstützt.

3
softveda

Eine Invariante ist wie eine Regel oder eine Annahme, die verwendet werden kann, um die Logik Ihres Programms zu diktieren.

Angenommen, Sie haben eine Softwareanwendung, die Benutzerkonten verfolgt. Angenommen, der Benutzer kann mehrere Konten haben, aber aus irgendeinem Grund müssen Sie zwischen dem Hauptkonto eines Benutzers und den "Alias" -Konten unterscheiden.

Dies kann ein DB-Datensatz oder etwas anderes sein, aber nehmen wir zunächst an, dass jedes Benutzerkonto durch ein Klassenobjekt dargestellt wird.

klasse userAccount {private char * pUserName; private char * pParentAccountUserName;

...}

Eine Invariante könnte die Annahme sein, dass dieses Objekt das übergeordnete Konto ist, wenn pParentAccountUserName NULL oder leer ist. Sie können diese Invariante verwenden, um verschiedene Kontotypen zu unterscheiden. Es gibt wahrscheinlich bessere Methoden zur Unterscheidung verschiedener Arten von Benutzerkonten. Beachten Sie also, dass dies nur ein Beispiel ist, um zu zeigen, wie eine Invariante verwendet werden kann.

1
Pemdas

Aus der Physik stammend, haben wir in der Physik Invarianten, bei denen es sich im Wesentlichen um Größen handelt, die während einer gesamten Berechnung/Simulation nicht variieren. In der Physik wird beispielsweise für ein geschlossenes System Gesamtenergie eingespart. Oder wieder in der Physik, wenn zwei Teilchen kollidieren, müssen die resultierenden Fragmente genau die Energie enthalten, mit der sie begonnen haben, und genau den gleichen Impuls (eine Vektorgröße). Normalerweise gibt es nicht genügend Invarianten, um das Ergebnis vollständig anzugeben. Zum Beispiel haben wir bei der 2-Teilchen-Kollision vier Invarianten, drei Impulskomponenten und eine Energiekomponente, aber das System hat sechs Freiheitsgrade (sechs Zahlen, um seinen Zustand zu beschreiben). Die Invarianten sollten innerhalb eines Rundungsfehlers konserviert werden, aber ihre Konservierung beweist nicht, dass die Lösung korrekt ist.

Normalerweise sind diese Dinge für die Überprüfung der geistigen Gesundheit wichtig, aber sie allein können die Richtigkeit nicht beweisen.

1
Omega Centauri