Mir ist aufgefallen, dass ich es viel einfacher finde, mathematische Beweise fehlerfrei aufzuschreiben, als ein fehlerfreies Computerprogramm aufzuschreiben.
Es scheint, dass dies etwas weiter verbreitet ist als nur meine Erfahrung. Die meisten Leute machen ständig Softwarefehler in ihrer Programmierung und sie haben den Compiler, der ihnen sagt, was der Fehler ist. Ich habe noch nie von jemandem gehört, der ein großes Computerprogramm ohne Fehler auf einmal geschrieben hat, und ich hatte das volle Vertrauen, dass es fehlerfrei sein würde. (In der Tat sind kaum Programme fehlerfrei, selbst viele hochgradig fehlerbeseitigte).
Menschen können jedoch ganze Abhandlungen oder Bücher mit mathematischen Beweisen schreiben, ohne dass ihnen jemals ein Compiler das Feedback gibt, dass sie einen Fehler begangen haben, und manchmal sogar ohne das Feedback von anderen.
Lass mich deutlich sein. Das soll nicht heißen, dass die Leute keine Fehler in mathematischen Beweisen machen, aber selbst für wenig erfahrene Mathematiker sind die Fehler normalerweise nicht so problematisch und können ohne die Hilfe eines "externen Orakels" wie eines Compilers gelöst werden, der auf Ihren zeigt Fehler.
In der Tat, wenn dies nicht der Fall wäre, dann wäre Mathematik für mich kaum möglich.
Dies führte mich zu der Frage: Was ist so anders daran, fehlerfreie mathematische Beweise und fehlerfreien Computercode zu schreiben, dass ersterer so viel besser handhabbar ist als letzterer?
Man könnte sagen, dass es einfach die Tatsache ist, dass die Leute das "externe Orakel" eines Compilers haben, das sie auf ihre Fehler hinweist, was Programmierer faul macht und sie daran hindert, das Notwendige zu tun, um Code rigoros zu schreiben. Diese Ansicht würde bedeuten, dass sie fehlerfrei wären wie Mathematiker, wenn sie keinen Compiler hätten.
Sie mögen das überzeugend finden, aber aufgrund meiner Erfahrung mit dem Programmieren und dem Aufschreiben von mathematischen Beweisen scheint es mir intuitiv, dass dies wirklich keine Erklärung ist. Es scheint etwas grundlegenderes an beiden Bestrebungen zu sein.
Mein erster Gedanke ist, dass der Unterschied darin bestehen könnte, dass ein korrekter Beweis für einen Mathematiker nur die Richtigkeit jedes einzelnen logischen Schritts erfordert. Wenn jeder Schritt korrekt ist, ist der gesamte Beweis korrekt. Andererseits muss für ein fehlerfreies Programm nicht nur jede Codezeile korrekt sein, sondern auch die Beziehung zu jeder anderen Codezeile im Programm.
Mit anderen Worten, wenn Schritt in einem Beweis korrekt ist, wird das Machen eines Fehlers in Schritt Schritt niemals durcheinander bringen . Wenn jedoch eine Codezeile korrekt geschrieben ist, hat ein Fehler in Zeile Einfluss auf die Funktion von Zeile , sodass wir bei jedem Schreiben von Zeile deren Beziehung zu allen anderen Zeilen berücksichtigen müssen. Wir können die Kapselung und all diese Dinge verwenden, um dies einzugrenzen, aber sie kann nicht vollständig entfernt werden.X X Y X X
Dies bedeutet, dass die Prozedur zum Überprüfen auf Fehler in einem mathematischen Beweis in der Anzahl der Beweisschritte im Wesentlichen linear ist, während die Prozedur zum Überprüfen auf Fehler im Computercode in der Anzahl der Codezeilen im Wesentlichen exponentiell ist.
Was denkst du?
Hinweis: Diese Frage enthält eine Vielzahl von Antworten, die sich mit einer Vielzahl von Fakten und Standpunkten befassen. Bevor Sie antworten, lesen Sie bitte alle und antworten Sie nur, wenn Sie etwas Neues hinzuzufügen haben. Überflüssige Antworten oder Antworten, die Meinungen nicht mit Fakten untermauern, können gelöscht werden.
Antworten:
Lassen Sie mich einen Grund und ein Missverständnis als Antwort auf Ihre Frage angeben.
Der Hauptgrund, warum es einfacher ist, (scheinbar) korrekte mathematische Beweise zu schreiben, ist, dass sie auf einem sehr hohen Niveau geschrieben sind. Angenommen, Sie könnten ein Programm wie das folgende schreiben:
Es wäre viel schwieriger zu schief gehen , wenn auf diese Weise der Programmierung, da die Spezifikation des Programms ist viel knapper als seine Umsetzung . In der Tat stößt jeder Programmierer, der versucht, Pseudocode in Code, insbesondere in effizienten Code, umzuwandeln, auf diese große Kluft zwischen der Idee eines Algorithmus und seinen Implementierungsdetails . Mathematische Beweise konzentrieren sich mehr auf die Ideen und weniger auf das Detail.
Das eigentliche Gegenstück zum Code für mathematische Beweise sind computergestützte Beweise . Diese sind viel schwieriger zu entwickeln als die üblichen Textnachweise, und man entdeckt oft verschiedene versteckte Ecken, die für den Leser "offensichtlich" sind (der sie normalerweise nicht einmal bemerkt), für den Computer jedoch nicht so offensichtlich. Da der Computer derzeit nur relativ kleine Lücken füllen kann, müssen die Beweise so ausgearbeitet werden, dass ein Mensch, der sie liest, den Wald vor lauter Bäumen vermisst.
Ein wichtiger Irrtum ist, dass mathematische Beweise oft korrekt sind. In der Tat ist dies wahrscheinlich eher optimistisch. Es ist sehr schwierig, komplizierte Beweise ohne Fehler zu schreiben, und Papiere enthalten oft Fehler. Vielleicht ist die berühmtesten jüngsten Fälle sind Wiles' erster Versuch (ein Spezialfall) die Modularitätssatz (der Fermats letzten Satz impliziert) und verschiedene Lücken in der Klassifizierung der endlichen einfacher Gruppen, einig 1000 Seiten einschließlich quasithin Gruppen waren , die geschrieben 20 Jahre nachdem die Klassifizierung angeblich beendet war.
Ein Fehler in einer Abhandlung von Voevodsky ließ ihn die schriftlichen Beweise so sehr in Zweifel ziehen, dass er damit begann, die Homotopietypentheorie zu entwickeln , ein logisches Gerüst, das für die formale Entwicklung der Homotopietheorie nützlich war, und fortan einen Computer verwendete, um alle seine nachfolgenden Arbeiten (zumindest nach seinen eigenen) zu verifizieren Eintritt). Dies ist zwar eine extreme (und derzeit unpraktische) Situation, aber es ist immer noch so, dass man bei der Verwendung eines Ergebnisses den Beweis durchgehen und prüfen sollte, ob es korrekt ist. In meiner Gegend gibt es einige Papiere, die bekanntermaßen falsch sind, aber nie zurückgezogen wurden, und deren Status von Experten von Mund zu Ohr weitergegeben wird.
quelle
(Ich riskiere hier wahrscheinlich ein paar Ablehnungen, da ich keine Zeit / kein Interesse habe, diese richtig zu beantworten, aber ich finde den zitierten Text (und den Rest des zitierten Artikels) ziemlich aufschlussreich, auch wenn sie geschrieben sind von einem bekannten Mathematiker. Vielleicht kann ich die Antwort später verbessern.)
Die Idee, von der ich annehme, dass sie sich nicht besonders von der bestehenden Antwort unterscheidet, besteht darin, dass ein "Beweis" oder ein Argument einer mathematischen Gemeinschaft übermittelt wird, um sie davon zu überzeugen, dass die (mühsamen) Details im Prinzip ausgefüllt werden können. einen vollständigen formalen Beweis zu erbringen - ohne dies oft zu tun. Ein kritisches Beispiel hierfür ist, dass Sie vorhandene Theoreme verwenden können, indem Sie sie einfach angeben, aber die Wiederverwendung von Code ist im Allgemeinen viel schwieriger. Berücksichtigen Sie auch kleinere "Bugs", die einen Teil des Codes möglicherweise völlig unbrauchbar machen (z. B. SEGFAULTs), ein mathematisches Argument jedoch weitgehend intakt lassen (d. H., Wenn der Fehler enthalten sein kann, ohne dass das Argument zusammenfällt).
ÜBER NACHWEIS UND FORTSCHRITT IN DER MATHEMATIK (S. 9-10), von WILLIAM P. THURSTON https://arxiv.org/pdf/math/9404236.pdf
quelle
(void*)1
undopen('/dev/null')
, die zwischen den verschiedenen Subkulturen nicht einmal tragbar sein kann, geschweige denn übersetzbar in die Zielsprache. (Der Leser muss seine ungefähre Semantik nur aufgrund langjähriger Erfahrung ergründen.) Ich denke, dass mathematische Beweise weniger von dieser Art von "Slang" enthalten. Wenn ein Beweis ein Wort verwendet, wird seine tatsächliche universelle Bedeutung soll irgendwie durch den Leser ableitbar sein. Computerprogramme nicht einmal haben universelle Bedeutung!Gestatten Sie mir, zunächst EW Dijkstra zu zitieren:
Obwohl sich das, was Dijkstra mit "Programmieren" meinte, erheblich von der gegenwärtigen Verwendung unterscheidet, hat dieses Zitat immer noch einen gewissen Wert. Die anderen Antworten haben bereits erwähnt, dass der Abstraktionsgrad in der Mathematik viel höher sein darf als in der Programmierung, was bedeutet, dass wir einige knifflige Teile ignorieren können, wenn wir dies möchten.
Ich glaube jedoch, dass dies lediglich eine Folge eines grundlegenderen Unterschieds zwischen einem Beweis und einem Computerprogramm ist, der deren Zweck ist .
Der Hauptzweck eines mathematischen Beweises besteht unter anderem darin, sich davon zu überzeugen, dass eine mathematische Behauptung richtig und, vielleicht noch wichtiger, verständlich ist . Aus diesem Grund können Sie nur in der mathematischen Welt arbeiten, in der alles so gestaltet ist, dass das Verständnis durch das Design erreicht werden kann (obwohl einige Schüler anfangen, sich zu unterscheiden ...). Genau das meinte Dijkstra mit "reinen Mathematikern", denen, die (fast) nur sich mit mathematischen Fakten beschäftigen und deren Eigenschaften verstehen.
Es sollte Sie also nicht überraschen, dass die Erstellung korrekter Beweise relativ fehlerfrei ist: Es ist der Sinn der gesamten "Übung". (Trotzdem heißt das nicht, dass es keine oder kaum Fehler gibt. Irren ist nur menschlich, sagen sie.)
Nun, wenn wir über Programmierung nachdenken, was ist unser Ziel? Wir suchen nicht wirklich Verständnis, wir wollen etwas, das funktioniert . Aber wann "funktioniert" etwas? Etwas funktioniert, wenn wir erfolgreich etwas erstellt haben, das es einem fremden Computer ermöglicht, die von ihm gewünschte Aufgabe zu erledigen, und das am besten auch ziemlich schnell.
Dies ist, glaube ich, der grundlegende Unterschied, da dies bedeutet, dass unser Ziel nicht einfach als ein Satz ausgedrückt werden kann, den unser Programm "beweist". Wir wünschen uns etwas in der realen Welt (was auch immer das ist), kein mathematisches Artefakt. Dies bedeutet, dass wir unser Ziel rein theoretisch nicht erreichen können (obwohl Dijkstra es ohne Rücksicht darauf versuchen lassen würde), da wir die Maschine beruhigen müssen, hoffen, dass wir tatsächlich wissen, welche Aufgabe wir wollen, und uns auch bewusst sind, was noch nicht in Betracht gezogen wurde irgendwie.
Am Ende gibt es also keine andere Möglichkeit, als es einfach zu versuchen und es wahrscheinlich nicht zu tun, zu reparieren, zu scheitern und erneut zu versuchen, bis wir mit dem Ergebnis einigermaßen zufrieden sind.
Beachten Sie, dass Ihre Hypothese, fehlerfreie Beweise zu schreiben, einfacher ist als fehlerfreie Programme (die in der Tat unterschiedliche Aussagen sind, wie @Ariel hervorhebt ), die tatsächlich falsch sein können, da Beweise auf einer bestimmten Ebene häufig durch Ausprobieren erstellt werden. Dennoch hoffe ich, dass dies etwas Licht auf die implizite Frage wirft: "Was ist wirklich der Unterschied zwischen dem Beweisen eines Theorems und dem Schreiben eines Programms?" (Zu dem ein unvorsichtiger Beobachter der Curry-Howard-Korrespondenz sagen könnte: "Gar nichts!")
Wie in den Kommentaren unter @wvxvw erwähnt, sind die folgenden Absätze aus „Anmerkungen zur strukturierten Programmierung“ (EWD249, Seite 21) sehr relevant:
quelle
Lamport liefert einen Grund für Meinungsverschiedenheiten bezüglich der Häufigkeit von Fehlern in Proofs in So erstellen Sie einen Proof (Seite 8-9) :
quelle
Ein großer Unterschied besteht darin, dass Programme in der Regel so geschrieben sind, dass sie Eingaben verarbeiten, während mathematische Beweise im Allgemeinen von einer Reihe von Axiomen und bekannten Theoremen ausgehen. Manchmal müssen Sie mehrere Eckfälle abdecken, um einen hinreichend allgemeinen Beweis zu erhalten, aber die Fälle und ihre Lösung werden explizit aufgelistet und der Umfang des Ergebnisses ist implizit auf die abgedeckten Fälle beschränkt.
Vergleichen Sie dies mit einem Computerprogramm, das für eine Reihe möglicher Eingaben die richtige Ausgabe liefern muss. Es ist selten möglich, alle Eingaben aufzulisten und alle auszuprobieren. Schlimmer noch, nehmen wir an, das Programm interagiert mit einem Menschen und erlaubt seinen Eingaben, die Funktionsweise zu verändern? Menschen sind notorisch unvorhersehbar und die Anzahl der möglichen Eingaben in ein einigermaßen umfangreiches Programm mit menschlicher Interaktion nimmt mit erstaunlicher Geschwindigkeit zu. Sie müssen versuchen, die verschiedenen Verwendungsmöglichkeiten eines Programms vorherzusehen und alle diese Anwendungsfälle entweder zum Funktionieren zu bringen oder zumindest auf vernünftige Weise zum Scheitern zu bringen, wenn ein Fehler die einzige Option ist. Und das setzt voraus, dass Sie sogar wissen, wie es in all diesen dunklen Eckfällen funktionieren soll .
Schließlich kann ein großes Programm nicht wirklich mit einem einzigen Beweis verglichen werden, auch nicht mit einem komplexen. Ein großes Programm ähnelt wahrscheinlich eher dem Sammeln und Überprüfen einer kleinen Bibliothek mit Literatur, von denen einige möglicherweise Fehler enthalten, die Sie umgehen müssen. Bei Programmen, die eher der Größe eines einzelnen Proofs entsprechen und möglicherweise eine kleine Algorithmusimplementierung darstellen, können beispielsweise erfahrene Software-Ingenieure diese ohne Fehler ausführen, insbesondere wenn sie moderne Tools verwenden, mit denen häufig auftretende triviale Fehler (z. B. Rechtschreibfehler) vermieden bzw. behoben werden ), die den frühen Problemen entsprechen, die Sie beim Korrekturlesen lösen würden.
quelle
Sie sagen, das Problem mit Computern sei, dass sie genau das tun , was Sie ihnen sagen.
Ich denke, das könnte einer der vielen Gründe sein.
Beachten Sie, dass bei einem Computerprogramm der Schreiber (Sie) klug ist, der Leser (die CPU) jedoch dumm.
Aber mit einem mathematischen Beweis ist der Schreiber (Sie) schlau und der Leser (Rezensent) auch schlau.
Dies bedeutet, dass Sie es sich niemals leisten können, mit einem Computer in eine Situation zu geraten, in der Sie wissen, was ich meine . Es macht genau das, was Sie sagen, ohne Ihre Absichten zu kennen.
Angenommen, dies ist ein Beweisschritt:
Wenn Sie einem Computer anweisen, auszuwerten und dann durch dividieren , wird er Ihr Programm blockieren, wenn Sie zulassen . Aber ein Mathematiker würde in diesem Punkt nicht unnötig stecken bleiben. Er würde erkennen, dass dies für den Punkt, den Sie anstreben, höchstwahrscheinlich irrelevant ist und dass es niemandem helfen wird, aufzugeben und sich über dieses kleinere Problem zu beschweren. Er wird verstehen, was du meinst, weil er dir nicht einfach folgt. er versteht dich Es ist schwieriger zu scheitern, wenn Ihr Leser klug ist.x + 3 x = - 3x2+4x+3 x+3 x=−3
quelle
-x
es sich um einen zusammengesetzten Beweis handelt. Die Tatsache , dass dieser Schritt falsch ist , wenn-x = 3
auf die Richtigkeit des fertigen Beweises höchst relevant ist]!Ein Problem, das meiner Meinung nach in Yuvals Antwort nicht angesprochen wurde, ist, dass Sie scheinbar verschiedene Tiere vergleichen.
"Der Code ist korrekt" zu sagen, ist eine semantische Aussage. Sie meinen, dass das von Ihrem Code beschriebene Objekt bestimmte Eigenschaften erfüllt, z. B. für jede Eingabe, die berechnet,. Dies ist in der Tat eine schwierige Aufgabe, und um sie zu beantworten, muss man über die bloße Syntax hinausblicken. Ihre mathematische Analogie dazu lautet "Ist dieser Beweis korrekt?", Was kaum fair ist, da die richtige Analogie lauten sollte: "Ist dieser Satz wahr, und wenn ja, wie können wir ihn beweisen?". Während ersteres eine syntaktische Aussage ist, die "leicht" verifiziert werden kann, ist letzteres viel schwieriger (seine Härte kann formalisiert werden). Denken Sie über den kompliziertesten Code nach, den Sie jemals versucht haben, und vergleichen Sie ihn mit dem Versuch, Poincarés Vermutung (jetzt Theorem) zu beweisen. Dies sollte Ihnen unterschiedliche Proportionen geben.n !n n!
Das Überprüfen der semantischen Eigenschaften von Programmen ist nicht entscheidbar (Theorem von Rice), und in analoger Weise ist das Überprüfen, ob eine Aussage in der Prädikatenlogik erster Ordnung wahr ist, auch nicht entscheidbar. Der Punkt ist, dass es keinen wirklichen Unterschied in der Härte von der Art gibt, wie Sie die Probleme betrachten. Andererseits können wir über syntaktische Eigenschaften von Programmen (Compilern) nachdenken, und dies ist analog zu der Tatsache, dass wir Beweise verifizieren können. Bugs (der Code macht nicht das, was ich will) sind semantisch, also solltest du sie mit ihrem richtigen Gegenstück vergleichen.
Ich werde Yuval stärken und sagen, dass ganze Felder mit der Motivation gewachsen sind, mathematische Beweise zu schreiben, die in einem formalen System geschrieben und verifiziert werden können, so dass selbst der Verifizierungsprozess überhaupt nicht trivial ist.
quelle
Ich glaube, dass die Hauptgründe Idempotenz (gibt die gleichen Ergebnisse für die gleichen Eingaben) und Unveränderlichkeit (ändert sich nicht) sind.
Was wäre, wenn ein mathematischer Beweis andere Ergebnisse liefern könnte, wenn er an einem Dienstag gelesen würde oder wenn das Jahr von 1999 auf 2000 vorrücken würde? Was wäre, wenn ein Teil eines mathematischen Beweises darin bestünde, ein paar Seiten zurückzugehen, ein paar Zeilen neu zu schreiben und dann von diesem Punkt an neu zu beginnen?
Ich bin mir sicher, dass ein solcher Beweis fast genauso fehleranfällig ist wie ein normales Segment von Computercode.
Ich sehe auch andere sekundäre Faktoren:
quelle
Ich stimme dem zu, was Yuval geschrieben hat. Aber haben Sie auch eine viel einfachere Antwort: In der Praxis versuchen Software-Ingenieure in der Regel nicht einmal, die Richtigkeit ihrer Programme zu überprüfen. Sie tun dies einfach nicht. Sie schreiben in der Regel nicht einmal die Bedingungen auf, die definieren, wann das Programm korrekt ist.
Dafür gibt es verschiedene Gründe. Zum einen haben die meisten Softwareentwickler nicht die Fähigkeit, Probleme mathematisch klar zu formulieren, und sie wissen auch nicht, wie man Korrektheitsnachweise schreibt.
Eine andere ist, dass das Definieren von Korrektheitsbedingungen für ein komplexes Softwaresystem (insbesondere ein verteiltes System) eine sehr schwierige und zeitaufwendige Aufgabe ist. Es wird erwartet, dass sie etwas haben, das in wenigen Wochen zu funktionieren scheint.
Ein weiterer Grund ist, dass die Korrektheit eines Programms von vielen anderen von anderen geschriebenen Systemen abhängt, die wiederum keine klare Semantik haben. Es gibt ein Hyrum-Gesetz, das im Wesentlichen besagt, dass jemand davon abhängig sein wird, wenn Ihre Bibliothek / Ihr Dienst ein beobachtbares Verhalten aufweist (das nicht Bestandteil des Vertrags ist). Das heißt im Wesentlichen, dass die Idee, Software in modularer Form mit klaren Verträgen wie Lemmas in der Mathematik zu entwickeln, in der Praxis nicht funktioniert. In Sprachen, in denen Reflexion verwendet wird, wird es noch schlimmer. Selbst wenn ein Programm heute korrekt ist, kann es morgen zusammenbrechen, wenn jemand in einer seiner Abhängigkeiten ein triviales Refactoring vornimmt.
In der Praxis passiert normalerweise, dass sie Tests haben. Tests entsprechen den Erwartungen des Programms. Jedes Mal, wenn ein neuer Fehler gefunden wird, werden Tests hinzugefügt, um ihn zu erkennen. Es funktioniert in gewissem Umfang, ist jedoch kein Korrektheitsnachweis.
Wenn die Leute nicht in der Lage sind, Korrektheit zu definieren oder korrekte Programme zu schreiben oder dies zu erwarten, und dies ziemlich schwierig ist, ist es keine Überraschung, dass Software nicht korrekt ist.
Beachten Sie aber auch, dass die Softwareentwicklung am Ende an besseren Stellen durch Code-Review erfolgt. Das heißt, der Autor eines Programms muss mindestens eine andere Person davon überzeugen, dass das Programm korrekt funktioniert. Das ist der Punkt, an dem einige informelle Argumente auf hoher Ebene vorgebracht werden. Aber auch hier passiert normalerweise nichts, was einer klaren strengen Definition von Korrektheit oder eines Korrektheitsnachweises nahekommt.
In der Mathematik wird auf Korrektheit geachtet. In der Softwareentwicklung gibt es viele Dinge, die ein Programmierer beachten muss, und es gibt Kompromisse zwischen ihnen. Eine fehlerfreie Software oder sogar eine gute Definition der Korrektheit (mit sich im Laufe der Zeit ändernden Anforderungen) zu haben, ist ein Ideal, aber es muss gegen andere Faktoren abgewogen werden, und einer der wichtigsten unter ihnen ist die Zeit, die für die Entwicklung der vorhandenen Software aufgewendet wird Entwickler. In der Praxis an besseren Orten verringern Ziel und Prozesse das Risiko von Fehlern so weit wie möglich, anstatt die Software fehlerfrei zu machen.
quelle
Es gibt bereits viele gute Antworten, aber es gibt noch weitere Gründe, warum Mathematik und Programmierung nicht dasselbe sind.
1 Mathematische Beweise sind in der Regel viel einfacher als Computerprogramme. Betrachten Sie die ersten Schritte eines hypothetischen Beweises:
Soweit ist der Beweis in Ordnung. Lassen Sie uns das zu den ersten Schritten eines ähnlichen Programms machen:
Wir haben bereits unzählige Probleme. Angenommen, der Benutzer hat wirklich eine Ganzzahl eingegeben, müssen wir die Grenzen überprüfen. Ist ein Wert größer als -32768 (oder was auch immer der min int auf Ihrem System ist)? Ist ein kleiner als 32767? Jetzt müssen wir dasselbe überprüfen für b . Und weil wir a und b hinzugefügt haben, ist das Programm nur korrekt, wenn a + bist größer als -32768 und kleiner als 32767. Das sind 5 verschiedene Bedingungen, über die sich ein Programmierer Gedanken machen muss, die ein Mathematiker ignorieren kann. Der Programmierer muss sich nicht nur Sorgen machen, er muss auch herausfinden, was zu tun ist, wenn eine dieser Bedingungen nicht erfüllt ist, und Code schreiben, was immer er beschlossen hat, um mit diesen Bedingungen umzugehen. Mathe ist einfach. Das Programmieren ist schwierig.
2 Der Fragesteller sagt nicht, ob er sich auf Fehler bei der Kompilierung oder auf Laufzeitfehler bezieht, aber Programmierer kümmern sich im Allgemeinen nicht um Fehler bei der Kompilierung. Der Compiler findet sie und sie können leicht repariert werden. Sie sind wie Tippfehler. Wie oft tippen die Leute beim ersten Mal mehrere Absätze ohne Fehler?
3 Schulung.Schon in jungen Jahren wird uns das Rechnen beigebracht und wir werden immer wieder mit den Folgen kleinerer Fehler konfrontiert. Ein ausgebildeter Mathematiker musste anfangen, mehrstufige Algebra-Probleme zu lösen, normalerweise in der Mittelschule, und musste ein Jahr lang jede Woche Dutzende (oder mehr) solcher Probleme lösen. Ein einzelnes negatives Vorzeichen führte dazu, dass ein ganzes Problem falsch war. Nach der Algebra wurden die Probleme länger und schwieriger. Programmierer hingegen haben in der Regel eine weitaus geringere formale Ausbildung. Viele sind Autodidakten (zumindest anfangs) und haben erst an der Universität eine formelle Ausbildung erhalten. Selbst auf Universitätsniveau müssen die Programmierer einige Matheklassen belegen, während die Mathematiker wahrscheinlich ein oder zwei Programmierklassen belegen.
quelle
Ich mag Yuvals Antwort, aber ich wollte ein bisschen darüber reden. Ein Grund, warum Sie es vielleicht einfacher finden, mathematische Beweise zu schreiben, könnte darin bestehen, wie platonisch die mathematische Ontologie ist. Beachten Sie Folgendes, um zu sehen, was ich meine:
Obgleich es fraglich ist, ob die oben genannten Einschränkungen das Schreiben eines Programms erleichtern oder nicht, besteht meines Erachtens weitgehend Einigkeit darüber, dass die oben genannten Einschränkungen das Denken über ein Programm erleichtern. Das Wichtigste, was Sie beim Schreiben eines mathematischen Beweises tun, ist der Grund für den Beweis, den Sie gerade schreiben (da Sie im Gegensatz zum Programmieren keine doppelten Anstrengungen in der Mathematik unternehmen müssen, da die Abstraktionen kostenlos sind). Es lohnt sich also im Allgemeinen, auf dem zu bestehen oben genannten Einschränkungen.
quelle
Grundlegende mathematische Beweise stellen keine reale Anwendung dar, die auf die Bedürfnisse lebender Menschen zugeschnitten ist.
Der Mensch wird seine Wünsche, Bedürfnisse und Anforderungen möglicherweise täglich im Bereich von Computerprogrammen ändern.
Mit einer so klaren Anforderung wie einem mathematischen Problem könnte ein fehlerfreies Programm geschrieben werden. Der Nachweis, dass der Dijkstra-Algorithmus den kürzesten Weg zwischen zwei Punkten in einem Graphen finden kann, ist nicht dasselbe wie die Implementierung eines Programms, das willkürliche Eingaben akzeptiert und die kürzesten Punkte zwischen zwei beliebigen Punkten in einem Graphen findet.
Es gibt Bedenken in Bezug auf Arbeitsspeicher, Leistung und Hardware, die verwaltet werden müssen. Ich wünschte, wir könnten beim Schreiben von Algorithmen nicht an jene denken, die wir mit reinen und funktionalen Konstrukten verwalten könnten, aber Computerprogramme leben in der "realen" Welt der Hardware, während der mathematische Beweis in der "Theorie" liegt.
Oder, um prägnanter zu sein :
quelle
Wenn man es aus einem anderen Blickwinkel betrachtet, kommt es in einem nicht akademischen Umfeld oft auf Geld an.
Wie die anderen Posts gut behaupten, handelt es sich bei Math um eine einzelne abstrakte Spezifikation. Daher muss ein Beweis innerhalb dieser Spezifikation konsistent funktionieren, um bewiesen zu werden. Ein Computerprogramm kann auf vielen Implementierungen der abstrakten Spezifikation von Mathematik ausgeführt werden - das heißt, die Art und Weise, wie eine Sprache oder ein Hardwarehersteller Gleitkommamathematik implementiert, kann sich geringfügig von der anderen unterscheiden, was zu geringfügigen Schwankungen der Ergebnisse führen kann.
Als solches würde das "Prüfen" eines Computerprogramms vor dem Schreiben das Prüfen der Logik auf Hardwareebene, Betriebssystemebene, Treiberebene, Programmiersprache, Compiler, möglicherweise Interpreter usw. für jede mögliche Kombination von Hardware, die das Programm enthält, umfassen Es ist denkbar, dass Daten ausgeführt werden und alle denkbaren Daten aufgenommen werden. Dieses Maß an Vorbereitung und Verständnis werden Sie wahrscheinlich bei Weltraummissionen, Waffensystemen oder Atomkraft-Kontrollsystemen finden, bei denen ein Fehlschlag Dutzende Milliarden verlorener Dollar und möglicherweise viele Menschenleben bedeutet, aber nicht viel anderes.
Für Ihren "alltäglichen" Programmierer und / oder Ihr Unternehmen ist es weitaus kostengünstiger, ein bestimmtes Maß an Genauigkeit für den größtenteils korrekten Code zu akzeptieren und ein verwendbares Produkt zu verkaufen, und die Entwickler können Fehler rückwirkend beheben, wenn sie während dessen aufgedeckt werden Verwendungszweck.
quelle
Ich denke, dass Ihre Argumentation gültig ist, aber Ihre Eingabe ist nicht. Mathematische Beweise sind einfach nicht fehlertoleranter als Programme, wenn beide von Menschen geschrieben wurden. Dijkstra wurde hier bereits zitiert, aber ich werde ein zusätzliches Zitat anbieten.
Dies wurde in den letzten drei Absätzen des ersten Kapitels von Dijkstra's Structured Programming leicht überarbeitet.
Um dies vielleicht anders zu formulieren, um Ihre Frage besser zu beantworten: Korrektheit ist weitgehend eine Funktion der Größe Ihres Beweises. Die Korrektheit langer mathematischer Beweise ist sehr schwer festzustellen (viele veröffentlichte "Beweise" leben in der Schwebe der Unsicherheit, da niemand sie tatsächlich verifiziert hat). Wenn Sie jedoch die Korrektheit von Trivialprogrammen mit trivialen Beweisen vergleichen, ist wahrscheinlich kein Unterschied festzustellen. Automatisierte Proof-Assistenten (im weiteren Sinne ist Ihr Java-Compiler auch ein Proof-Assistent) sorgen jedoch dafür, dass Programme durch die Automatisierung vieler Vorarbeiten gewinnen.
quelle
Wie andere Antworten in ihren Antworten angesprochen haben (ich möchte darauf näher eingehen), aber ein großer Teil des Problems ist die Bibliotheksnutzung. Selbst mit perfekter Dokumentation (so häufig wie fehlerfreier Code) ist es unmöglich, jedem Programmierer, der die Bibliothek verwendet, das vollständige Wissen über eine Bibliothek zu vermitteln. Wenn der Programmierer seine Bibliothek nicht perfekt versteht, kann er Fehler machen, wenn er sie verwendet. Manchmal kann dies zu kritischen Fehlern führen, die entdeckt werden, wenn der Code nicht funktioniert. Aber für kleinere Fehler können diese unbemerkt bleiben.
Eine ähnliche Situation wäre, wenn ein Mathematiker vorhandene Beweise und Lemmas verwendet, ohne sie vollständig zu verstehen; ihre eigenen Beweise wären wahrscheinlich fehlerhaft. Dies kann zwar darauf hindeuten, dass eine Lösung darin besteht, jede verwendete Bibliothek perfekt zu erlernen. Dies ist praktisch sehr zeitaufwendig und erfordert möglicherweise Domänenkenntnisse, die der Programmierer nicht besitzt (ich weiß nur sehr wenig über DNA-Sequenzierung / Proteinsynthese, kann jedoch mit diesen Konzepten unter Verwendung von Bibliotheken arbeiten).
Kurz gesagt, Software-Engineering (Engineering im Allgemeinen) basiert auf der Verkapselung verschiedener Abstraktionsebenen, damit sich die Mitarbeiter auf kleinere Bereiche des Problems konzentrieren können, auf das sie sich spezialisiert haben. Dies ermöglicht es den Mitarbeitern, Fachkenntnisse in ihrem Bereich zu entwickeln, erfordert jedoch auch eine hervorragende Kommunikation zwischen jeder Schicht. Wenn diese Kommunikation nicht perfekt ist, verursacht sie Probleme.
quelle
Nach all den tollen Antworten werde ich versuchen, originell zu sein.
Programme sind Beweise
Der Curry-Howard-Isomorphismus sagt uns, die Typen in Ihrem Programm sind die Theoreme und der tatsächliche Code ist ihr Beweis.
Zugegeben, dies ist eine sehr abstrakte und hochrangige Sichtweise. Das Problem, das Sie wahrscheinlich meinen, ist, dass das Schreiben eines typischen Codes schwieriger ist, weil er zu niedrig wird. In den meisten Fällen müssen Sie "der Maschine mitteilen, was zu tun ist". Oder andersherum: Mathematiker können wirklich gut abstrahieren.
Als Randbemerkung: "Die Musik der Ströme" ist eine der schönsten Brücken zwischen beiden. Es setzt im Grunde der Dinge der Lage sein , zu sagen : „Ich möchte dies in dieser Art und Weise“ und die Maschine tut magisch dies genau nach Wunsch.
quelle
Keine der vielen anderen Antworten weist auf Folgendes hin. Mathematische Beweise funktionieren auf imaginären Computersystemen mit unendlichem Speicher und unendlicher Rechenleistung. Sie können daher beliebig große Zahlen mit unendlicher Genauigkeit speichern und verlieren bei keiner Berechnung an Genauigkeit.
quelle
Es ist nicht. Mathematische Beweise sind von Natur aus genau so fehlerhaft, nur dass ihre Leser eher tolerant sind als ein Compiler. In ähnlicher Weise können die Leser eines Computerprogramms leicht glauben, dass es korrekt ist, zumindest bis sie versuchen, es auszuführen.
Wenn wir beispielsweise versuchen, einen mathematischen Beweis in eine formale Sprache wie ZFC zu übersetzen, enthält er auch Fehler. Das liegt daran, dass diese Beweise sehr lang werden können, sodass wir gezwungen sind, ein Programm zu schreiben, um die Beweise zu erstellen. Nur wenige Menschen machen sich auf eigene Gefahr Mühe, obwohl die Formalisierung grundlegender Beweise derzeit rege erforscht wird.
Und in der Tat kann Mathe BSOD bekommen! Es wäre nicht das erste Mal!
Diese orthodoxe Vorstellung, dass alle mathematischen Beweise, die ausreichend verifiziert wurden, im Wesentlichen korrekt sind oder korrekt ausgeführt werden können, ist dieselbe, die Ihr Softwareprojekt bei der Arbeit motiviert: Solange wir auf der Roadmap bleiben, werden wir alle Fehler beseitigen und die Vollständige Funktionen - ein iterativer Prozess, der zu einem endgültigen Produkt führt.
Hier ist die Kehrseite. Schauen Sie, wir haben bereits die Finanzierung, haben das Geschäftskonzept validiert und alle Dokumente sind hier, damit Sie sie lesen können. Wir müssen Sie nur ausführen und es ist eine sichere Sache!
Lassen Sie uns auch Hilbert nicht zu sehr bemitleiden , er wusste, worauf er sich einließ. Es ist nur ein Geschäft.
Wenn Sie wirklich sicher sein wollen, nehmen Sie alles von Fall zu Fall und ziehen Sie Ihre eigenen Schlussfolgerungen!
quelle
Ich sehe zwei wichtige Gründe, warum Programme fehleranfälliger sind als mathematische Beweise:
1: Programme enthalten Variablen oder dynamische Objekte, die sich im Laufe der Zeit ändern, während mathematische Objekte in Proofs normalerweise statisch sind. Daher kann die Notation in Mathematik als direkte Begründung verwendet werden (und wenn a = b, bleibt dies der Fall), wenn dies in Programmen nicht funktioniert. Außerdem wird dieses Problem noch schlimmer, wenn Programme parallel sind oder mehrere Threads haben.
2: Mathematik geht häufig von relativ genau definierten Objekten aus (Graphen, Mannigfaltigkeiten, Ringe, Gruppen usw.), während die Programmierung sehr chaotische und unregelmäßige Objekte behandelt: endliche Präzisionsarithmetik, endliche Stapel, Zeichen-Ganzzahl-Umrechnungen, Zeiger, zu sammelnder Müll , etc ... Die Erfassung der für die Richtigkeit relevanten Bedingungen ist daher nur schwer vorstellbar.
quelle
Sie sollten zwei verschiedene "Kategorien" unterscheiden:
Wir verwenden Pseudocode seit Tausenden von Jahren (zB Euklid-Algorithmus). Das Schreiben von formalem Code (in formalen Sprachen wie C oder Java) wurde nach der Erfindung von Computern äußerst populär und nützlich. Aber leider sind formale Beweise (in formalen Sprachen wie Principia Mathematica oder Metamath) nicht sehr beliebt. Und da heute jeder Pseudo-Beweise schreibt, streiten sich die Leute oft über neue Beweise. Fehler in ihnen können Jahre, Jahrzehnte oder sogar Jahrhunderte nach der eigentlichen "Prüfung" gefunden werden.
quelle
Ich kann die Referenz nicht finden, aber ich glaube, Tony Hoare hat einmal Folgendes gesagt: Der Unterschied zwischen dem Prüfen eines Programms und dem Prüfen eines Proofs besteht darin, dass ein Proof zwei Zeilen gleichzeitig geprüft werden kann.
Mit einem Wort: Lokalität.
Beweise sind so geschrieben, dass sie leicht überprüft werden können. Programme werden so geschrieben, dass sie ausgeführt werden können. Aus diesem Grund lassen Programmierer normalerweise Informationen aus, die für jemanden nützlich sind, der das Programm überprüft.
Betrachten Sie dieses Programm, in dem x schreibgeschützt ist
Es ist leicht auszuführen, aber schwer zu überprüfen.
Wenn ich jedoch die fehlenden Zusätze wieder hinzufüge, können Sie das Programm lokal überprüfen, indem Sie einfach überprüfen, ob jede Zuweisungssequenz in Bezug auf ihre Vor- und Nachbedingungen korrekt ist und für jede Schleife die Nachbedingung der Schleife durch die impliziert wird Invariante und die Negation des Loop Guard.
Zurück zur ursprünglichen Frage: Warum ist das Aufschreiben von mathematischen Beweisen fehlerfreier als das Schreiben von Computercode? Da Proofs so gestaltet sind, dass sie leicht von ihren Lesern überprüft werden können, können sie leicht von ihren Autoren überprüft werden, und daher neigen warnende Autoren dazu, keine logischen Fehler in ihren Proofs zu machen (oder zumindest zu behalten). Wenn wir programmieren, können wir den Grund für die Richtigkeit unseres Codes oft nicht aufschreiben. Das Ergebnis ist, dass es sowohl für die Leser als auch für den Autor eines Programms schwierig ist, den Code zu überprüfen. Das Ergebnis ist, dass Autoren Fehler machen (und diese dann behalten).
Aber es gibt Hoffnung. Wenn wir beim Schreiben eines Programms auch den Grund für die Richtigkeit des Programms notieren, können wir den Code beim Schreiben überprüfen und so weniger fehlerhaften Code schreiben. Dies hat auch den Vorteil, dass andere unseren Code lesen und selbst überprüfen können.
quelle
Wir könnten fragen, ob es in der Praxis oder im Prinzip schwieriger ist , Beweise oder Code zu schreiben.
In der Praxis ist das Testen viel schwieriger als das Codieren. Nur sehr wenige Leute, die zwei Jahre Mathematik auf College-Niveau absolviert haben, können Beweise schreiben, auch triviale. Unter Menschen, die zwei Jahre lang CS auf Hochschulniveau absolviert haben, können wahrscheinlich mindestens 30% FizzBuzz lösen .
Aber im Prinzip gibt es fundamentale Gründe, warum es umgekehrt ist. Beweise können zumindest prinzipiell durch ein Verfahren auf Richtigkeit überprüft werden, das keinerlei Urteilsvermögen oder Verständnis erfordert. Programme können nicht - wir können nicht einmal durch einen vorgeschriebenen Prozess sagen, ob ein Programm anhält.
quelle
Nur ein kleiner Teil der zutreffenden mathematischen Aussagen kann praktisch bewiesen werden. Insbesondere wäre es unmöglich, eine nicht triviale (*) Menge mathematischer Axiome zu konstruieren, mit deren Hilfe alle wahren Aussagen bewiesen werden könnten. Wenn man nur Programme schreiben müsste, um einen winzigen Bruchteil der Dinge zu tun, die mit Computern möglich wären, wäre es möglich, nachweislich korrekte Software zu schreiben, aber Computer werden häufig aufgefordert, Dinge zu tun, die über den Bereich des nachweislich Richtigen hinausgehen Software kann dies leisten.
(*) Es ist möglich, eine Reihe von Axiomen zu definieren, mit denen alle wahren Aussagen aufgezählt und somit bewiesen werden können, aber diese sind im Allgemeinen nicht sehr interessant. Während es möglich ist, Sätze von Axiomen formal in solche zu kategorisieren, die relativ gesehen nicht trivial sind oder nicht, ist der entscheidende Punkt, dass die nachweisbare Existenz von Aussagen, die wahr sind, aber nicht bewiesen werden können, kein Fehler in einem Satz ist von Axiomen. Das Hinzufügen von Axiomen, um vorhandene wahrheitsgemäße, aber nicht beweisbare Aussagen nachweisbar zu machen, würde dazu führen, dass andere Aussagen wahr werden, aber ohne sie nachweisbar.
quelle
Computerprogramme werden in der realen Welt getestet. Ein kniffliger technischer Fehler in einem langen mathematischen Beweis, den nur eine begrenzte Anzahl von Menschen verstehen kann, hat eine gute Chance, unentdeckt zu bleiben. Dieselbe Art von Fehler in einem Softwareprodukt führt wahrscheinlich zu merkwürdigem Verhalten, das normale Benutzer bemerken. Die Prämisse ist also möglicherweise nicht korrekt.
Computerprogramme führen nützliche Funktionen der realen Welt aus. Sie müssen nicht zu 100% korrekt sein, und hohe Standards für die Korrektheit sind ziemlich teuer. Beweise sind nur dann nützlich, wenn sie tatsächlich etwas beweisen. Das Überspringen des Teils „100% korrekt“ ist für Mathematiker daher keine Option.
Mathematische Beweise sind klar definiert. Wenn ein Beweis fehlerhaft ist, hat der Autor einen Fehler gemacht. Viele Fehler in Computerprogrammen treten auf, weil die Anforderungen nicht richtig kommuniziert wurden oder ein Kompatibilitätsproblem mit etwas vorliegt, von dem der Programmierer noch nie gehört hat.
Viele Computerprogramme können nicht korrekt nachgewiesen werden. Sie können informell definierte Probleme wie das Erkennen von Gesichtern lösen. Oder sie ähneln einer Software zur Börsenprognose und haben ein formal definiertes Ziel, beinhalten jedoch zu viele Variablen der realen Welt.
quelle
Ein großer Teil der Mathematik als menschliche Aktivität bestand in der Entwicklung domänenspezifischer Sprachen, in denen es für einen Menschen leicht ist, Beweise zu überprüfen.
Die Qualität eines Proofs ist umgekehrt proportional zu seiner Länge und Komplexität. Die Länge und Komplexität wird oft reduziert, indem eine gute Notation für die Beschreibung der Situation entwickelt wird, zu der wir eine Aussage machen, zusammen mit den Hilfskonzepten, die innerhalb des jeweiligen Beweises interagieren.
Dies ist kein einfacher Prozess, und die meisten Beweise, die von Personen erbracht wurden, die nicht an der Spitze der Forschung standen, stammen aus mathematischen Gebieten (wie Algebra und Analyse), die Hunderte, wenn nicht Tausende von Jahren hatten, in denen die Notation dieses Gebiets bestand wurde so weit verfeinert, dass das Aufschreiben der Beweise ein Kinderspiel ist.
An der Spitze der Forschung, insbesondere wenn Sie Probleme bearbeiten, die nicht in Bereichen mit gut etablierter oder gut entwickelter Notation liegen, würde ich die Schwierigkeit, auch nur einen korrekten Beweis zu schreiben, der Schwierigkeit nahe bringen, ein korrektes Programm zu schreiben. Dies liegt daran, dass Sie gleichzeitig das Analogon eines programmiersprachlichen Entwurfs schreiben, Ihr neuronales Netzwerk trainieren müssen, um es korrekt zu kompilieren, versuchen, den Beweis darin zu schreiben, nicht genügend Speicher zu haben, versuchen, die Sprache zu optimieren, Iterieren Sie Ihr Gehirn beim Erlernen der Sprache, schreiben Sie den Beweis erneut usw.
Ich bin der Meinung, dass das Schreiben korrekter Beweise die Schwierigkeit annähern kann, korrekte Programme in bestimmten Bereichen der Mathematik zu schreiben, aber diese Bereiche sind notwendigerweise jung und unterentwickelt, da der Begriff des Fortschritts in der Mathematik eng mit der Einfachheit des Beweises verbunden ist Nachprüfung.
Eine andere Möglichkeit, den Punkt zu formulieren, den ich ansprechen möchte, besteht darin, dass sowohl Programmiersprachen als auch Mathematik am Ende des Tages so gestaltet sind, dass Computerprogramme bzw. Proofs kompiliert werden können. Es ist nur so, dass das Kompilieren eines Computerprogramms in einem Computer durchgeführt wird und die syntaktische Korrektheit gewährleistet, was normalerweise wenig mit der Korrektheit des Programms selbst zu tun hat, während das "Kompilieren" eines Beweises von einem Menschen durchgeführt wird und die syntaktische Korrektheit gewährleistet, was dasselbe ist wie Richtigkeit des Beweises.
quelle
Sie vergleichen hier ehrlich Äpfel und Orangen. Ausfallsicher und fehlerfrei sind nicht dasselbe.
Wenn ein Programm die Zahlen vergleicht
2
und ,3
und es sagt , dass2 is greater than 3
, dann könnte es aufgrund einer Buggy Implementierung sein:Das Programm ist jedoch immer noch fehlerfrei. Wenn Sie zwei Zahlen mit
a
und vergleichenb
, können Sie immer feststellen, ob die Zahlb
größer ist als diea
. Es ist einfach nicht das, wozu Sie (der Programmierer) den Computer auffordern sollten.quelle
a) Weil Computerprogramme größer sind als mathematische Beweise
a.1) Ich glaube, dass beim Schreiben komplexer Computerprogramme mehr Leute verwendet werden als beim Schreiben von mathematischen Beweisen. Dies bedeutet, dass die Fehlerquote höher ist.
b) Da CEOs / Anteilseigner mehr Wert auf Geld legen als auf die Behebung kleiner Fehler , müssen Sie (als Entwickler) Ihre Aufgaben erledigen, um einige Anforderungen / Fristen / Demos zu erfüllen
c) Da Sie Programmierer sein können, ohne über "tiefgreifende" Kenntnisse in Comp-Sci zu verfügen, ist es in der Zwischenzeit schwierig, Mathematik zu lernen (glaube ich).
Zusätzlich:
NASA:
https://www.fastcompany.com/28121/they-write-right-stuff
quelle
Grundstufen:
Schauen wir uns die Dinge auf der einfachsten und grundlegendsten Ebene an.Für Mathe haben wir:
2 + 3 = 5
Das habe ich gelernt, als ich sehr, sehr jung war. Ich kann die grundlegendsten Elemente betrachten: zwei Objekte und drei Objekte. Toll.
Bei der Computerprogrammierung verwenden die meisten Menschen eine Hochsprache. Einige übergeordnete Sprachen können sogar in eine der untergeordneten übergeordneten Sprachen "kompiliert" werden, z. B. C. C kann dann in die Assemblersprache übersetzt werden. Die Assemblersprache wird dann in Maschinencode konvertiert. Viele Leute denken, dass die Komplexität dort endet, aber das tut es nicht: Moderne CPUs nehmen den Maschinencode als Anweisungen, führen dann aber "Mikrocode" aus, um diese Anweisungen tatsächlich auszuführen.
Dies bedeutet, dass es auf der einfachsten Ebene (Umgang mit einfachsten Strukturen) jetzt um Mikrocode geht, der in die Hardware eingebettet ist und den die meisten Programmierer nicht einmal direkt verwenden oder aktualisieren. Tatsächlich berühren die meisten Programmierer nicht nur den Mikrocode (0 Ebenen höher als der Mikrocode), sondern auch nicht den Maschinencode (1 Ebene höher als der Mikrocode) und nicht einmal die Baugruppe (2 Ebenen höher als der Mikrocode) ( außer vielleicht für ein bisschen formale Ausbildung während des Studiums). Die meisten Programmierer verbringen Zeit nur 3 oder mehr Ebenen höher.
Wenn wir uns die Baugruppe anschauen (die so niedrig ist, wie es die Leute normalerweise tun), ist jeder einzelne Schritt normalerweise für Leute verständlich, die geschult wurden und über die Ressourcen verfügen, um diesen Schritt zu interpretieren. In diesem Sinne ist Assembly viel einfacher als eine höhere Sprache. Die Montage ist jedoch so einfach, dass die Ausführung komplexer oder mittelmäßiger Aufgaben sehr mühsam ist. Die höheren Sprachen befreien uns davon.
In einem Gesetz über "Reverse Engineering" erklärte ein Richter, dass moderne Programme, auch wenn Code theoretisch byteweise verarbeitet werden kann, Millionen von Bytes umfassen, so dass einige Arten von Datensätzen (wie Kopien von Code) nur für solche erstellt werden müssen eine Anstrengung, machbar zu sein. (Daher wurde die interne Entwicklung nicht als Verstoß gegen die allgemeine Urheberrechtsregel "Keine Kopien erstellen" angesehen.) (Ich denke wahrscheinlich an die Herstellung nicht autorisierter Sega Genesis-Kassetten, denke aber möglicherweise an eine Aussage im Fall Game Genie. )
Modernisierung:
Führen Sie Code für 286s aus? Oder führen Sie 64-Bit-Code aus?
Die Mathematik verwendet Grundlagen, die Jahrtausende zurückreichen. Bei Computern halten die Leute Investitionen in etwas, das zwei Jahrzehnte alt ist, normalerweise für unnütz und ressourcenschonend. Das heißt, Mathematik kann viel gründlicher getestet werden.
Standards der verwendeten Werkzeuge:
Mir wurde von einem Freund beigebracht, dass es keinen fehlerfreien C-Compiler gibt, der die C-Spezifikationen erfüllt. Dies liegt daran, dass die C-Sprache grundsätzlich die Möglichkeit annimmt, unendlichen Speicher für den Zweck eines Stapels zu verwenden. Offensichtlich musste von einer solchen unmöglichen Anforderung abgewichen werden, als versucht wurde, brauchbare Compiler zu erstellen, die mit tatsächlichen Maschinen arbeiteten, die etwas begrenzter waren.
In der Praxis habe ich festgestellt, dass ich mit JScript in Windows Script Host mit Objekten viele gute Ergebnisse erzielen konnte. (Ich mag die Umgebung, weil das Toolset, das zum Testen von neuem Code benötigt wird, in modernen Versionen von Microsoft Windows integriert ist.) Bei Verwendung dieser Umgebung habe ich festgestellt, dass es manchmal keine leicht auffindbare Dokumentation zur Funktionsweise des Objekts gibt. Die Verwendung des Objekts ist jedoch so vorteilhaft, dass ich es sowieso tue. Ich würde also Code schreiben, der möglicherweise als Hornissennest fehlerhaft ist, und zwar in einer schön sandkastenartigen Umgebung, in der ich die Auswirkungen sehen und das Verhalten des Objekts kennenlernen kann, während ich mit ihm interagiere.
In anderen Fällen habe ich manchmal erst festgestellt, nachdem ich herausgefunden habe, wie sich ein Objekt verhält, dass das Objekt (im Lieferumfang des Betriebssystems enthalten) fehlerhaft ist und dass es sich um ein bekanntes Problem handelt, von dem Microsoft absichtlich entschieden hat, dass es nicht behoben wird .
Verlasse ich mich in solchen Szenarien auf OpenBSD, das von meisterhaften Programmierern erstellt wurde, die regelmäßig (zweimal im Jahr) neue Releases mit einem bekannten Sicherheitsrekord von "nur zwei Remote-Lücken" in mehr als 10 Jahren erstellen? (Sogar sie haben Errata-Patches für weniger schwerwiegende Probleme.) Nein, auf keinen Fall. Ich verlasse mich nicht auf ein solches Produkt mit einer so höheren Qualität, weil ich für ein Unternehmen arbeite, das Unternehmen unterstützt, die Menschen mit Computern versorgen, die Microsoft Windows verwenden. Daran muss mein Code also arbeiten.
Praktikabilität / Benutzerfreundlichkeit erfordern, dass ich auf den Plattformen arbeite, die die Leute für nützlich halten, und das ist eine Plattform, die für die Sicherheit bekanntermaßen schlecht ist (obwohl seit den Anfängen des Jahrtausends enorme Verbesserungen vorgenommen wurden, bei denen die Produkte desselben Unternehmens viel schlechter waren). .
Zusammenfassung
Es gibt zahlreiche Gründe, warum Computerprogrammierung fehleranfälliger ist, und dies wird von der Gemeinschaft der Computerbenutzer akzeptiert. Tatsächlich wird der meiste Code in Umgebungen geschrieben, die keine fehlerfreien Bemühungen tolerieren. (Einige Ausnahmen, z. B. die Entwicklung von Sicherheitsprotokollen, sind in dieser Hinsicht möglicherweise etwas aufwändiger.) Abgesehen von den allgemeinen Überlegungen, wonach Unternehmen nicht mehr Geld investieren möchten und künstliche Fristen verpassen, um die Kunden zufrieden zu stellen, hat dies Auswirkungen auf Der technologische Aufschwung besagt einfach, dass Sie, wenn Sie zu viel Zeit verbringen, an einer veralteten Plattform arbeiten werden, da sich die Dinge innerhalb eines Jahrzehnts erheblich ändern.
Schon auf den ersten Blick kann ich mich daran erinnern, wie kurz einige sehr nützliche und beliebte Funktionen waren, als ich Quellcode für strlen und strcpy sah. Zum Beispiel könnte strlen so etwas wie "int strlen (char * x) {char y = x; while ( (y ++)); return (yx) -1;}" gewesen sein.
Typische Computerprogramme sind jedoch viel länger. Viele moderne Programme werden auch anderen Code verwenden, der möglicherweise weniger gründlich getestet wurde oder sogar als fehlerhaft bekannt ist. Heutige Systeme sind weitaus ausgefeilter als das, was man sich leicht vorstellen kann, außer wenn man einen Großteil der Minutien als "Details, die von niedrigeren Ebenen verarbeitet werden" von Hand wegwedelt.
Diese zwingende Komplexität und die Gewissheit, mit komplexen und sogar falschen Systemen zu arbeiten, machen die Computerprogrammierung zu einer größeren Hardware, die überprüft werden muss, als die Mathematik, bei der die Dinge sich in der Regel auf viel einfachere Ebenen beschränken.
Wenn Sie in der Mathematik eine Aufschlüsselung vornehmen, erhalten Sie Einzelteile, die Kinder verstehen können. Die meisten Menschen vertrauen Mathe. zumindest Grundrechenarten (oder zumindest Zählen).
Wenn Sie die Computerprogrammierung wirklich kaputt machen, um zu sehen, was unter der Haube passiert, erhalten Sie defekte Implementierungen von defekten Standards und Code, die letztendlich elektronisch ausgeführt werden, und diese physische Implementierung ist nur einen Schritt unter dem Mikrocode, den die meisten an Universitäten ausgebildeten Informatiker verwenden wage es nicht zu berühren (wenn sie sich dessen überhaupt bewusst sind).
Ich habe mit einigen Programmierern gesprochen, die am College sind, oder mit Absolventen, die direkt gegen die Vorstellung sind, dass fehlerfreier Code geschrieben werden kann. Sie haben die Möglichkeit abgeschrieben, und obwohl sie anerkennen, dass einige eindrucksvolle Beispiele (die ich zeigen konnte) überzeugende Argumente sind, betrachten sie solche Proben als nicht repräsentative seltene Fehler und lehnen die Möglichkeit ab, zählen zu können auf solche höheren Standards. (Eine sehr viel andere Einstellung als die viel zuverlässigere, die wir in Mathe sehen.)
quelle
Mathematische Beweise beschreiben, "was" Wissen und Programme beschreiben, "wie" Wissen ".
Das Schreiben von Programmen ist komplexer, da der Programmierer über die verschiedenen möglichen Zustände und die daraus resultierenden Verhaltensänderungen des Programms nachdenken muss. Beweise verwenden formelhafte oder kategoriale Argumente, um Dinge über andere Definitionen zu beweisen.
Die meisten Fehler werden durch Prozesse verursacht, die Zustände erreichen, mit denen der Programmierer nicht gerechnet hat. In einem Programm haben Sie normalerweise Tausende oder in einem großen System Millionen von möglichen Variablen, die keine statischen Daten sind, sondern die Art und Weise, wie das Programm ausgeführt wird, transformieren. Alle diese Interaktionen zusammen führen zu Verhaltensweisen, die unmöglich vorherzusehen sind, insbesondere in einem modernen Computer, in dem sich die Abstraktionsebenen unter Ihnen ändern.
In einem Beweis gibt es keinen sich ändernden Zustand. Die Definitionen und Diskussionsgegenstände sind festgelegt. Das Beweisen erfordert ein allgemeines Nachdenken über das Problem und das Berücksichtigen vieler Fälle, aber diese Fälle sind durch Definitionen festgelegt.
quelle