Die Antwort von DW ist großartig , aber ich möchte auf einen Punkt eingehen. Eine Spezifikation ist nicht nur eine Referenz, anhand derer der Code überprüft wird. Einer der Gründe für eine formale Spezifikation ist die Validierung durch den Nachweis einiger grundlegender Eigenschaften. Natürlich kann die Spezifikation nicht vollständig validiert werden - die Validierung wäre so komplex wie die Spezifikation selbst und daher ein endloser Prozess. Durch die Validierung erhalten wir jedoch eine stärkere Garantie für einige kritische Eigenschaften.
Angenommen, Sie entwerfen einen Autopiloten. Dies ist eine ziemlich komplexe Sache, die viele Parameter beinhaltet. Zu den Korrektheitseigenschaften des Autopiloten gehören Dinge wie "Das Auto stößt nicht gegen eine Wand" und "Das Auto fährt dahin, wo es sein soll". Eine Eigenschaft wie „das Auto stößt nicht gegen eine Wand“ ist wirklich sehr wichtig, deshalb möchten wir das gerne beweisen. Da das System in der physischen Welt betrieben wird, müssen Sie einige physische Einschränkungen hinzufügen. Die eigentliche Eigenschaft des Rechensystems wird so etwas wie "Unter diesen Annahmen in Bezug auf die Materialwissenschaften und diesen Annahmen in Bezug auf die Wahrnehmung von Hindernissen durch die Sensoren des Autos wird das Auto nicht gegen eine Wand prallen" sein. Das Ergebnis ist jedoch eine relativ einfache Eigenschaft, die eindeutig wünschenswert ist.
Könnten Sie diese Eigenschaft aus dem Code beweisen? Letztendlich ist es das, was passiert, wenn Sie einen vollständig formalen Ansatz verfolgen¹. Aber der Code hat viele verschiedene Teile; Die Bremsen, die Kameras, der Motor usw. werden alle autonom gesteuert. Eine Korrektheitseigenschaft der Bremsen wäre so etwas wie "Wenn das Signal" Bremsen betätigen "eingeschaltet ist, werden die Bremsen betätigt". Eine Korrektheitseigenschaft des Motors wäre "Wenn das Kupplungssignal ausgeschaltet ist, treibt der Motor die Räder nicht an". Es bedarf einer sehr hochrangigen Sichtweise, um sie alle zusammenzufügen. Durch eine Spezifikation werden Zwischenschichten erstellt, in denen die verschiedenen Komponenten des Systems miteinander verknüpft werden können.
Tatsächlich würde ein so komplexes System wie ein Autopilot mehrere Spezifikationsebenen mit unterschiedlichen Verfeinerungen aufweisen. Bei der Konstruktion wird häufig ein Verfeinerungsansatz verwendet: Beginnen Sie mit einigen Eigenschaften auf hohem Niveau wie „das Auto stößt nicht gegen eine Wand“, und stellen Sie dann fest, dass hierfür Sensoren und Bremsen erforderlich sind, und ermitteln Sie einige grundlegende Anforderungen an die Sensoren, die Bremsen und die Pilotsoftware, dann verfeinern Sie diese grundlegenden Anforderungen erneut in einem Design der Komponente (für den Sensor benötige ich ein Radar, einen DSP, eine Bildverarbeitungsbibliothek usw.). In einem formalen Entwicklungsprozess Jede Spezifikationsebene erfüllt nachweislich die Anforderungen der darüber liegenden Ebene, von den Eigenschaften der höchsten Ebene bis hin zum Code.
Es ist unmöglich, sicher zu sein, dass die Spezifikation korrekt ist. Wenn Sie beispielsweise die Physik falsch verstanden haben, sind die Bremsen möglicherweise nicht wirksam, obwohl die Mathematik, die den Bremsencode mit den formalen Anforderungen in Beziehung setzt, korrekt ist. Es ist nicht gut zu beweisen, dass die Pausen bei 500 kg Belastung effektiv sind, wenn Sie tatsächlich 5000 kg haben. Aber es ist einfacher zu erkennen, dass 500 kg falsch sind, als im Code der Bremsen zu erkennen, dass sie für die physikalischen Parameter des Autos nicht gut genug sind.
¹ Das Gegenteil eines vollständig formalen Ansatzes ist „Ich denke, das funktioniert, aber ich kann nicht sicher sein“. Wenn du dein Leben darauf setzt, scheint das nicht so toll zu sein.