Warum ist das Aufschreiben mathematischer Beweise fehlerfreier als das Schreiben von Computercode?


190

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.XX X Y X XYXXYXX

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.


3
Kennen Sie Beweise für die Korrektheit von Programmen, sowohl auf Papier als auch mechanisiert in Theorembeweisen? Beide existieren und widersprechen Ihrem Update. Es stimmt, dass das Programmieren, wie es allgemein gelehrt wird, wenig mit dem Programmieren mit Korrektheitsbeweisen zu tun hat.
Blaisorblade

76
Erinnert mich an ein Knuth-Zitat, ich denke "Vorsicht vor dem obigen Code! Ich habe es nur als richtig erwiesen, ich habe es nie getestet"
Hagen von Eitzen

Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Gilles

7
Suchen Sie mir einen handgeschriebenen mathematischen Beweis, der 100 Millionen Zeilen lang ist und keine "Bugs" enthält, und ich gebe Ihnen alles, was ich besitze.
Davor

Funktionsprogramme können jedoch viel einfacher zu schreiben sein als Beweise, sobald der Status
eintrifft

Antworten:


226

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:

function MaximumWindow(A, n, w):
    using a sliding window, calculate (in O(n)) the sums of all length-w windows
    return the maximum sum (be smart and use only O(1) memory)

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.


Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
DW

1
Ist es möglich, dass in Zukunft Proof-Assistenten verwendet werden, um sowohl Ihren Code als auch den Proof zu überprüfen? Vielleicht ist es Zeit, dir eine Agda beizubringen ? (Entschuldigung ...)
Alex Vong

3
@AlexVong Ein Problem dabei ist, dass das Schreiben einer formalen Spezifikation für nicht-trivialen Code (damit Sie überprüfen können, ob der Code tatsächlich die Spezifikation erfüllt) so gut wie unmöglich ist. Können Sie sich zum Beispiel vorstellen, wie kompliziert eine formale Spezifikation für einen Browser wäre (einschließlich aller Benutzerinteraktionen, aller unterstützten Dateiformate und Protokolle usw.)?
SVICK

2
@svick Du hast Recht, für Benutzerinteraktionen ist manchmal nicht einmal klar, welches Verhalten das richtige sein soll. Wir sollten uns stattdessen auf etwas mit einer angemessenen formalen Spezifikation konzentrieren (z. B. Proof, Compiler).
Alex Vong

1
Tatsächlich. Dies könnte auch eine Erklärung dafür sein, warum das Codieren in untergeordneten Sprachen für viele Menschen viel mühsamer und weniger unterhaltsam ist als das Codieren in übergeordneten, abstrakten Sprachen. Dies kann natürlich auch von Person zu Person unterschiedlich sein (Einige mögen es vielleicht sogar, Hardware / elektronische Schaltkreise auf sehr niedriger Ebene zu bauen, anstatt Software zu schreiben, die auf ihnen ausgeführt wird). Außerdem kann Code auf niedriger Ebene in vielen Fällen immer noch unersetzbar sein und gut geschrieben werden kann eine seltene Fähigkeit / Leistung sein, die es wert ist, von sich aus gelobt zu werden).
xji

77

(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).

Der Standard für Korrektheit und Vollständigkeit, der erforderlich ist, um ein Computerprogramm überhaupt zum Laufen zu bringen, ist um ein paar Größenordnungen höher als der Standard der mathematischen Gemeinschaft für gültige Beweise. Trotzdem scheinen große Computerprogramme, selbst wenn sie sehr sorgfältig geschrieben und getestet wurden, immer Fehler zu haben. [...] Mathematik, wie wir sie praktizieren, ist formal viel vollständiger und präziser als andere Wissenschaften, aber formal viel weniger vollständig und inhaltlich präziser als Computerprogramme. Der Unterschied hängt nicht nur mit dem Aufwand zusammen: Die Art des Aufwands ist qualitativ unterschiedlich. In großen Computerprogrammen muss ein enormer Teil des Aufwands für unzählige Kompatibilitätsprobleme aufgewendet werden: Sicherstellen, dass alle Definitionen konsistent sind, Entwicklung von "gut" Datenstrukturen mit nützlicher, aber nicht umständlicher Allgemeinheit, die über die "richtige" Allgemeinheit für Funktionen usw. entscheiden. Der Anteil der für den Arbeitsteil eines großen Programms aufgewendeten Energie, der sich vom Buchhaltungsteil unterscheidet, ist überraschend gering. Aufgrund von Kompatibilitätsproblemen, die fast unweigerlich von der Hand gehen, weil sich die "richtigen" Definitionen ändern, wenn Allgemeingültigkeit und Funktionalität hinzugefügt werden, müssen Computerprogramme in der Regel häufig, häufig von Grund auf neu geschrieben werden.

ÜBER NACHWEIS UND FORTSCHRITT IN DER MATHEMATIK (S. 9-10), von WILLIAM P. THURSTON https://arxiv.org/pdf/math/9404236.pdf


3
Der Punkt über "Wiederverwendung von Code" ist ziemlich naheliegend. Das Übersetzen eines langen Beweises aus dem Russischen ins Englische erfordert eine Menge Tipparbeit . Aber das Übersetzen eines großen Computerprogramms von C ++ in Java erfordert eine Menge Denkarbeit . Ebenso einfach ist es, einen 3000 Jahre alten Beweis im Altgriechischen wiederzubeleben. Die Wiederbelebung eines 30 Jahre alten Programms in PL / 1 ist genauso schwierig oder schwieriger.
Quuxplusone

2
Das Altgriechisch Beispiel hat mich auch erkennen: Computer - Programmierer eine Verwendung Tonne von lokalen Slang und Umgangssprache, wie (void*)1und open('/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!
Quuxplusone

1
+1, denn als konstruktivistische , die grassierende Vermutung eines unterscheidet sich von einem beliebig großen Wert macht mich verrückt. Dies steigt von einem Trugschluss auf Wertebene zu einem logischen Trugschluss, wenn Mathematiker über unendliche Reihen sprechen und dann auf diesen Reihen basierende Argumente vorbringen, die einen Fehler bewirken, der einem versteckten -Trugschluss gleichkommt . 000
Nat

@Nat können Sie näher erläutern? Ich verstehe es nicht.
Gregory Magarshak

@GregoryMagarshak Diese Antwort demonstrierte einen Fall, in dem die Annahme, dass die Unendlichkeit in der Serienkonstruktion gültig ist, zu einem Irrtum führt, den ich als diesen versteckten Irrtum beschreibe00 (die " getarnte " Version weiter unten in der Wikipedia) Sektion). Ein klassischer Mathematiker könnte sagen, dass der Fehler darin bestand, dass eine unendliche Reihe konvergiert, obwohl ein Konstruktivist den Irrtum als eine uneingeschränkte Unendlichkeitsvermutung beschreiben würde.
Nat

55

Gestatten Sie mir, zunächst EW Dijkstra zu zitieren:

"Das Programmieren ist einer der schwierigsten Zweige der angewandten Mathematik. Die ärmeren Mathematiker sollten lieber reine Mathematiker bleiben." (ab EWD498)

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:

(...) Ein Programm ist niemals ein Ziel an sich; Der Zweck eines Programms besteht darin, Berechnungen auszulösen, und der Zweck der Berechnungen besteht darin, einen gewünschten Effekt zu erzielen. Obwohl das Programm das Endprodukt des Programmierers ist, werden die möglichen Berechnungen, die durch das Programm hervorgerufen werden, der Maschine überlassen. - sind das eigentliche Thema seines Faches. Wenn ein Programmierer zum Beispiel feststellt, dass sein Programm korrekt ist, gibt er wirklich eine Aussage über die Berechnungen, die es möglicherweise hervorruft.

(...) In gewisser Hinsicht ist die Erstellung eines Programms daher schwieriger als die Erstellung einer mathematischen Theorie: Sowohl Programm als auch Theorie sind strukturierte, zeitlose Objekte. Aber während die mathematische Theorie in ihrer jetzigen Form Sinn ergibt, ergibt das Programm nur Sinn durch seine Ausführung.


2
Ich bin nur ein Laie. Worauf bezog sich Dijkstra bei "Programmieren" wirklich?
Ovi

2
@Ovi Ich bin nicht genau sicher, aber der Hauptunterschied ist, dass er über (nicht triviale) algorithmische Probleme spricht, die mehr als "allgemeine" Programmieraufgaben lösen, dh er spricht sicher nicht über ein CRUD-Programm, das einige verbinden muss Bestehende Architekturen oder andere Komponenten usw. Weitere Informationen zu Dijkstras Meinung zur Programmierung finden Sie in dieser Antwort
Diskrete Eidechse

3
Stimmen Sie für das Zitieren von Dijkstra zu, aber Sie haben den falschen Ort gewählt! In den ersten Abschnitten der Strukturierten Programmierung hat er viel über dieses Problem geschrieben. Ich würde Ihre Antwort nicht ändern wollen, indem Sie ein anderes Zitat einreichen, aber ich hoffe, Sie würden mehr von diesem Papier zu Ihrer Antwort hinzufügen!
wvxvw

@Ovi Meine Vermutung zu Ihrer Frage ist, dass das Programmieren in der Zeit von Dijkstra häufiger das Schreiben von Assembler-Code bedeutete als in der modernen Ära der Hochsprachen. Ebenso habe ich die Ausgabe 1974 von Mythical Man-Month lese, sind die Konzepte noch aktuell , aber die technischen Referenzen sind auf Systemebene Assembler oder PL / I, viel anders aus , was die meisten Leute denken , der als Programmierung heute
JimLohse

46

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) :

Vor ungefähr zwanzig Jahren beschloss ich, einen Beweis des Schroeder-Bernstein-Theorems für einen Mathematik-Einführungskurs zu schreiben. Der einfachste Beweis, den ich finden konnte, war Kelleys klassischer allgemeiner Topologietext. Da Kelley für ein anspruchsvolleres Publikum schrieb, musste ich seinem halbseitigen Proof eine Menge Erklärungen hinzufügen. Ich hatte fünf Seiten geschrieben, als mir klar wurde, dass Kelleys Beweis falsch war. Kürzlich wollte ich einen Vortrag über meinen Beweisstil mit einem überzeugenden falschen Beweis illustrieren, also wandte ich mich an Kelley. Ich konnte an seinem Beweis nichts falsches finden; es schien offensichtlich richtig! Das Lesen und nochmalige Lesen des Beweises überzeugte mich, dass entweder mein Gedächtnis versagt hatte oder ich vor zwanzig Jahren sehr dumm war. Trotzdem war Kelleys Beweis kurz und würde als gutes Beispiel dienen, also fing ich an, ihn als strukturierten Beweis umzuschreiben.

... Der Stil wurde zuerst auf Beweise gewöhnlicher Theoreme in einer Arbeit angewendet, die ich mit Martin Abadi schrieb. Er hatte bereits konventionelle Beweise geschrieben - Beweise, die gut genug waren, um uns und vermutlich die Schiedsrichter zu überzeugen. Beim Umschreiben der Beweise in einem strukturierten Stil stellten wir fest, dass fast jeder schwerwiegende Fehler aufwies, obwohl die Theoreme korrekt waren. Jede Hoffnung, dass falsche Beweise nicht zu falschen Theoremen führen könnten, wurde in unserer nächsten Zusammenarbeit zerstört. Immer wieder machten wir eine Vermutung und schrieben eine Beweisskizze an die Tafel - eine Skizze, die leicht zu einem überzeugenden konventionellen Beweis hätte werden können -, um dann zu entdecken, dass die Vermutung falsch war, indem wir versuchten, einen strukturierten Beweis zu schreiben. Seitdem habe ich kein Ergebnis ohne einen sorgfältigen, strukturierten Beweis geglaubt.


6
Gleiches Papier: "Anekdoten weisen darauf hin, dass ein Drittel aller in mathematischen Fachzeitschriften veröffentlichten Arbeiten Fehler enthält - nicht nur geringfügige Fehler, sondern auch falsche Theoreme und Beweise." Nun, das war in den 90ern, aber ist es heute so anders? Wahrscheinlich gibt es die Papiere von damals noch und alles stapelt sich ... Also bin ich nicht ganz davon überzeugt, dass die in Papieren enthaltenen mathematischen Beweise weniger Fehler enthalten.
MarkokraM

Faszinierende Anekdote, aber ich sehe nicht, dass sie direkt auf die Frage antwortet oder sich damit beschäftigt. Möchten Sie Ihre Antwort bearbeiten, um die gestellte Frage direkter zu beantworten? Argumentieren Sie, dass mathematische Beweise genauso fehlerhaft sind wie das Schreiben von Computercode? Haben Sie weitere Beweise dafür, dass Sie zur Verfügung stellen können? Eine oder zwei Anekdoten zeigen das nicht wirklich, oder?
DW

@DW Ich schicke Leslie eine E-Mail, wenn er weitere Beweise für die Behauptung vorlegen kann.
MarkokraM

3
@DW Leslie sagte in seiner aufrichtigen Antwort, dass sein Kollege eine Untersuchung mit 51 Beweisen durchführte, die zu dieser Zeit auf Math Reviews veröffentlicht wurden. Seiner Meinung nach ist es mehr als anekdotisch, aber aufgrund mehrerer Tatsachen nicht für starke Beweise geeignet. Der Fall war komplizierter, weil einige Fehler bei Proofs auftraten, weil sie fehlerhafte Proofs für zuvor veröffentlichte Artikel usw. verwendeten. Wäre ein großartiges Forschungsthema, erfordert aber so viel Arbeit. Wie man mathematische Beweise programmatisch überprüft, ist immer noch eine große Frage. Apps für die interaktive Proofunterstützung befinden sich in einem sehr frühen Stadium. Zumindest die Schnittstelle von ihnen.
MarkokraM

@DW Die eine oder andere Anekdote zeigt, wie ein mathematischer Beweis "korrekt" erscheinen könnte, aber tatsächlich nicht stichhaltig ist. Für jeden, der sowohl einen komplexen Computeralgorithmus geschrieben als auch einen mathematischen Beweis erbracht hat und versucht hat, einen Computeralgorithmus wie einen mathematischen Beweis zu schreiben und dann herauszufinden, wie der "Algorithmus" auf hoher Ebene von vielen, vielen Fehlern im Detail verraten wird, ist das Ergebnis ist überhaupt nicht überraschend.
Yakk

39

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.


14
+1 für deinen letzten Absatz. Während mathematische Beweise im Prinzip aufeinander aufbauen, sind die Grundlagen in der Regel gut verstanden, das Analogon von Computer-Bibliotheken (obwohl sie auch Fehler aufweisen ...), und der tatsächliche Beweis ist nicht zu lang. Im Gegensatz dazu ist Consumer-Software langwierig und kompliziert und bietet daher noch viel mehr Möglichkeiten zum Scheitern.
Yuval Filmus

6
In der Praxis besteht das andere Problem bei Consumer-Software darin, dass das „richtige“ Verhalten im Vorfeld häufig schlecht definiert ist und das, was früher richtig war, später falsch wird. Es wäre, als würde man versuchen, einen Beweis zu schreiben, nur um herauszufinden, dass die Leute beschlossen haben, die Axiome zu ändern. Sie können das in der Notation beheben, richtig?
Dan Bryant

2
@DanBryant Diese Situation tritt in der Mathematik auf. Insbesondere die Definitionen von Begriffen ändern sich im Laufe der Zeit und sind oftmals nicht eindeutig, selbst wenn sie richtig verwendet werden. Imre Lakatos '"Beweise und Widerlegungen" beschreibt dies mit dem Begriff "Polygon". Ähnliches ist mit "Funktion" und in geringerem Maße mit "Integral" geschehen. Noch heute ist "Kategorie" nicht eindeutig und Beweise und Theoreme können fehlschlagen, je nachdem, was Sie genau meinen.
Derek Elkins

25

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:

x2+4x+3x+3=(x+1)(x+3)x+3=x+1

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+3x+3x=3


3
Gute Antwort! mit der Ausnahme, dass ich als Computer Ihrer Verwendung des Wortes "unnötig" widerspreche. ;) [Angenommen, dies war nur ein Schritt in einem größeren Beweis, der beweisen soll, dass -xes sich um einen zusammengesetzten Beweis handelt. Die Tatsache , dass dieser Schritt falsch ist , wenn -x = 3auf die Richtigkeit des fertigen Beweises höchst relevant ist]!
Quuxplusone

@Quuxplusone: = P
Mehrdad

Computer können auch symbolische mathematische und nicht-deterministische Umschreibungsregeln verwenden. Die Sprachen, die wir wie C ++ verwenden, sind alle sehr niedrig und basieren auf alten Technologien (C hatte zum Beispiel weniger Funktionen als Algol 60). Die einzigen Ausnahmen sind die Prüfsprachen wie Idris / Agda, Lisp mit symbolischen Lösern und Mathematica. ja.wolframalpha.com/input/…
aoeu256

23

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 !nn!

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.


18

Was ist so anders daran, fehlerfreie mathematische Beweise und fehlerfreien Computercode zu schreiben, wodurch ersterer so viel besser handhabbar ist als letzterer?

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:

  1. Mathematiker sind in der Regel viel besser ausgebildet, bevor sie versuchen, einen aussagekräftigen / publizierbaren Beweis zu verfassen. 1/4 der selbsternannten professionellen Entwickler haben vor weniger als 6 Jahren mit dem Programmieren begonnen (siehe SO-Umfrage 2017 ), aber ich gehe davon aus, dass die meisten Mathematiker über ein Jahrzehnt formalen Mathematikunterrichts verfügen.
  2. Mathematische Beweise werden selten auf dem gleichen Prüfungsniveau wie Computercode geführt. Ein einzelner Tippfehler kann / wird ein Programm unterbrechen, aber Dutzende Tippfehler können möglicherweise nicht ausreichen, um den Wert eines Proofs zu zerstören (nur seine Lesbarkeit).
  3. Der Teufel steckt im Detail und der Computercode kann keine Details überspringen. Beweise können Schritte überspringen, die als einfach / routinemäßig angesehen werden. Es gibt einige nette syntaktische Zucker in modernen Sprachen, aber diese sind hartcodiert und im Vergleich ziemlich begrenzt.
  4. Mathematik ist älter und hat ein solideres Fundament. Es gibt sicherlich eine Vielzahl neuer und glänzender Teilfelder in der Mathematik, aber die meisten Kernprinzipien werden seit Jahrzehnten angewendet. Dies führt zu Stabilität. Auf der anderen Seite sind sich die Programmierer immer noch nicht einig über die grundlegende Codierungsmethode (fragen Sie einfach nach der Agile-Entwicklung und ihrer Akzeptanzrate).

Erwähnenswert ist, dass die Entsprechung von "Wiedergutmachung" für die Programmierung die funktionale Reinheit ist, die in einigen Sprachen wie Haskell anerkannt und unterstützt wird.
Pharap

12

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.


Ich bin mir nicht sicher, wer zwischen Programmierern und Mathematikern formal (dh maschinengeprüft) schlechter dran ist , wenn es darum geht, Richtigkeitsspezifikationen zu formulieren und den Code für z. B. ein 10KLOC oder größeres Programm als richtig zu erweisen. Einerseits haben Sie völlig Recht, dass die meisten Programmierer keine gut entwickelten Theorembeweisfähigkeiten haben. Auf der anderen Seite sind große formale Beweise wie große Programme und erfordern zum Verwalten im Wesentlichen Software-Engineering-Kenntnisse. Ich bin völlig zuversichtlich, dass ein informeller Beweis für die Richtigkeit eines solchen Programms keine Hoffnung auf Richtigkeit haben würde.
Derek Elkins

Vielleicht. In jedem Fall gehe ich in meiner Antwort nicht auf formelle Beweise ein, sondern nur auf informelle Beweise auf der Ebene, die wir in Algorithmenpapieren finden.
Kaveh

11

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:

Sei a eine ganze Zahl

Sei b eine ganze Zahl

Sei c = a + b

Soweit ist der Beweis in Ordnung. Lassen Sie uns das zu den ersten Schritten eines ähnlichen Programms machen:

Sei a = input ();

Sei b = input ();

Sei c = a + b;

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.


10

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:

  • Funktionen in Math sind rein (das gesamte Ergebnis des Aufrufs einer Funktion ist vollständig im Rückgabewert gekapselt, der deterministisch ist und vollständig aus dem Eingabewert berechnet wird).
  • Mathematik hat keine Mutation oder Neuzuweisung (wenn Sie solche Dinge modellieren müssen, werden Funktionen und Sequenzen verwendet).
  • Mathematik ist referenziell transparent (z. B. keine Zeiger, keine Vorstellung von Call-by-Name oder Call-by-Wert), und mathematische Objekte haben eine erweiterte Gleichheitssemantik (wenn "zwei" Dinge in jeder beobachtbaren Weise gleich sind, dann sind sie tatsächlich gleich) das gleiche).

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.


7

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.

Was ist so anders daran, fehlerfreie mathematische Beweise und fehlerfreien Computercode zu schreiben, wodurch ersterer so viel besser handhabbar ist als letzterer?

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 :

Bildbeschreibung hier eingeben


4

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.


3
Sie scheinen eine enge Vorstellung davon zu haben, was Mathematik ist, und eine viel zu weitreichende Vorstellung davon, was das "Beweisen" eines Computerprogramms mit sich bringt. Sie müssen nicht das gesamte System als korrekt beweisen, um ein Programm als korrekt zu beweisen. Sie müssen nur nachweisen, dass es korrekt ist, vorausgesetzt, die anderen Komponenten erfüllen ihre Spezifikationen. Andernfalls liegt es nicht an Ihrem Programm. Wenn Ihr Programm jedoch aufgrund von Details, die nicht Teil der Spezifikation dieser Komponenten sind, z. B. Variationen von Implementierungen von IEEE754, nicht funktioniert, ist dies Ihre Schuld.
Derek Elkins

Gerechter Kommentar. Ich missbrauche wahrscheinlich eine Terminologie, da dies nicht mein akademischer Hintergrund ist. Obwohl ich der Meinung bin, dass es aufgrund meiner vorherigen Kommentare nicht ratsam ist, anzunehmen, dass andere Komponenten fehlerfrei sind.
navigator_

4

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.

Wir müssen die Berechnungen jedoch so organisieren, dass unsere begrenzten Befugnisse ausreichen, um zu gewährleisten, dass die Berechnung den gewünschten Effekt erzielt. Diese Organisation beinhaltet die Zusammenstellung des Programms und dort stehen wir vor dem nächsten Problem der Größe, nämlich. die Länge des Programmtextes, und wir sollten dieses Problem auch explizit anerkennen. Wir sollten uns der Tatsache bewusst sein, dass das Ausmaß, in dem wir einen Text lesen oder schreiben können, stark von seiner Größe abhängt. [...]

In der gleichen Stimmung möchte ich den Leser auf die Tatsache aufmerksam machen, dass "Klarheit" quantitative Aspekte aufweist, die viele Mathematiker merkwürdigerweise nicht zu kennen scheinen. Ein Satz, der die Gültigkeit einer Schlussfolgerung bestätigt, wenn zehn Seiten voller Bedingungen erfüllt sind, ist kaum ein geeignetes Werkzeug, da alle Bedingungen überprüft werden müssen, wenn der Satz in Frage gestellt wird. In der euklidischen Geometrie gilt der Satz von Pythagoras für drei beliebige Punkte A, B und C, sodass durch A und C eine gerade Linie orthogonal zu einer geraden Linie durch B und C gezogen werden kann oder fallen alle Punkte A, B und C zusammen? Dies scheint jedoch weitgehend für die Zweckmäßigkeit verantwortlich zu sein, mit der der Satz von Pythagoras verwendet werden kann.

Zusammenfassend: Als ein langsamer Mensch habe ich einen sehr kleinen Kopf und ich sollte besser lernen, damit zu leben und meine Grenzen zu respektieren und ihnen volle Anerkennung zu schenken, anstatt zu versuchen, sie zu ignorieren, denn letztere Mühe wird vergeblich sein durch Misserfolg bestraft.

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.


Was meinen Sie mit "langen mathematischen Beweisen"? Der Beweis des Graph-Minor-Theorems ist ziemlich lang, wird aber von niemandem wirklich bestritten. Das Feit-Thompson-Theorem hat einen ziemlich langen Beweis, war aber nie wirklich in der Schwebe. Wie vergleicht man die Länge von Proofs und Programmen? Anzahl der Wörter? Gibt es wirklich keine erkennbaren Unterschiede zwischen Proofs und Programmen, wenn Sie Proofs und Programme mit ähnlicher Komplexität (Länge) vergleichen?
Yuval Filmus

@YuvalFilmus genau wie im Zitat: Zehn Seiten Behauptungen sind für Menschen lang. Wie bewerte ich die Länge eines Programms? Nun, Dikstra bot eine Metrik an: die Länge seines Textes. Ich denke, dass es zu simpel ist, aber es ist trotzdem eine gute Heuristik. Es gibt andere, interessantere Metriken, wie zum Beispiel die zyklomatische Komplexität
wvxvw

3

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.


3
Warten Sie, warum glauben Sie, dass Mathematiker die von ihnen verwendeten Beweise und Lemmas "vollständig verstehen"? Ich bin mir nicht sicher, welchen Unterschied Sie zwischen Mathematikern und Programmierern machen wollen.
Derek Elkins

3

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.


Ich verstehe nicht ganz, ob dies die Frage anspricht. Das OP gab keinen Hinweis darauf, dass es sich um Programmiersprachen mit leistungsfähigen Typsystemen handelt, und ich denke, dass es sich um allgemeinere Typsysteme handelt. Also ist Curry-Howard in diesem Fall ein bisschen trivial.
6005

Ich weiß, dass es für C oder ähnliche Dinge ein bisschen weit hergeholt ist. Aber mein Punkt ist: Mathe ist näher, als ein typischer CS-Anfänger denken könnte!
Oleg Lobachev

1
Sie scheinen ein "unvorsichtiger Beobachter" des Curry-Howards-Isomorphismus zu sein, auf den ich mich in meiner Antwort bezog. Selbst wenn wir einen Isomorphismus zwischen Programmen und Beweisen haben, folgt daraus nicht, dass das Schreiben von Programmen und Beweisen überhaupt ähnlich ist. Tatsächlich kann es sogar vorkommen, dass alle "interessanten" oder "typischen" Programme keinem typischen Beweis entsprechen und umgekehrt.
Diskrete Eidechse

@Discretelizard Es ist nachweislich nicht der Fall, dass "interessante" Programme keinem "typischen Beweis" entsprechen. Hier ist ein Beispiel, in dem ich einen "typischen Beweis" nehme und eine (Skizze) eines unbestreitbar interessanten Programms (etwas, das eng mit der Gaußschen Eliminierung zusammenhängt) erstelle. Ausgestattet mit entsprechend präzisen Typen, denke ich, dass die meisten "interessanten" Programme nützliche Lemmata oder Theoreme sind, aber viele (konstruktive) Beweise haben keine wirkliche rechnerische Bedeutung - sie verifizieren nur Nebenbedingungen - obwohl es sehr viele sind.
Derek Elkins

3

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.

π


2
"Mathematische Beweise funktionieren auf imaginären Computersystemen mit unendlichem Speicher und unendlicher Rechenleistung." Die meisten mathematischen Beweise „funktionieren“ auf formalen algebraischen Systemen, z. B. auf reellen Zahlen (wo wir „unendliche Präzision“ haben). Dies kann auch in Programmen geschehen: Es gibt sogenannte Computeralgebrasysteme (CAS), die genau dies tun! Darüber hinaus befassen sich ganze Bereiche der Mathematik mit der Tatsache, dass wir nicht alle reellen Zahlen exakt als endliche Gleitkommazahlen darstellen können. Ich denke, Sie unterscheiden zwischen Mathematik und Programmierung, wo es keine gibt.
Diskrete Eidechse

1
@Discretelizard, ja, spezielle Pakete existieren mit willkürlicher Genauigkeit, aber selbst dann wird der verfügbare Speicher die tatsächlich erreichbare Genauigkeit einschränken. Sie sind auch spezielle Pakete. Mit solchen Paketen wird nur ein winziger Teil der Programmierung durchgeführt, und zwar meist im akademischen Umfeld.
Crobar

π

@Discretelizard, ich denke mein Standpunkt steht noch, die meisten Programmierer verwenden solche CAS-Systeme nicht. Sie sind viel zu langsam für echte Programmierung. Das meiste Programmieren beinhaltet im Grunde Operationen mit Zahlen mit begrenzter Genauigkeit. Die Hauptsprachen sind C, C ++, Python, Java usw. Standardmäßig wird keine Darstellung im CAS-Stil verwendet (obwohl Pakete dafür möglicherweise in ihnen erstellt werden). Ihr Gegenbeispiel ist eine winzige Untergruppe von Computersprachen / -systemen.
Crobar

2
@crobar Das Problem mit Ihrer Antwort ist, dass die überwiegende Mehrheit der erkannten Fehler nicht auf Gleitkommafehler oder Ganzzahlüberläufe zurückzuführen ist (obwohl diese eine anständige Zahl beitragen und diese Aspekte die vollständige Korrektheit eines Programms auf jeden Fall viel unwahrscheinlicher machen). Sie könnten jedoch die allgemeinere Behauptung aufstellen, dass Mathematikern viele Bedenken von Programmierern fehlen, wie z. B. Leistung, Time-to-Market, Wartbarkeit und die eingeschränkte Fähigkeit, die Anforderungen zu ändern, wenn sie sich als zu schwierig erweisen.
Derek Elkins

3

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!

Bildbeschreibung hier eingeben

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!


3

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.


3

Sie sollten zwei verschiedene "Kategorien" unterscheiden:

  • Pseudo-Beweise (oder Pseudo-Code) - das sehen Sie in Büchern. Es ist in natürlicher Sprache verfasst (zB in Englisch). Das sollten Sie verwenden, um Mathematik (oder Algorithmen) zu lernen.
  • Formale Beweise (oder formaler Code) - Sie schreiben ihn, wenn Ihr Beweis (oder Code) mechanisch überprüfbar (oder ausführbar) sein muss. Eine solche Darstellung erfordert keine "menschliche Intelligenz". Es kann mechanisch überprüft (oder ausgeführt) werden, indem einige vordefinierte Schritte befolgt werden (die heute normalerweise von Computern ausgeführt werden).

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.


3

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

    assume x >= 0
    p := 0 ;
    var pp := 0 ;
    while( x >= pp + 2*p + 1 ) 
    {
        var q := 1 ;
        var qq := q ;
        var pq := p ;
        while(  pp + 4*pq + 4*qq <= x )
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

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.

    assume x >= 0
    p := 0 ;
    var pp := 0 ; 
    while( x >= pp + 2*p + 1 ) 
        invariant p*p <= x 
        invariant pp == p*p
        decreases x-p*p 
    {
        var q := 1 ;
        var qq := q ; 
        var pq := p ; 
        while(  pp + 4*pq + 4*qq <= x )
            invariant (p+q)*(p+q) <= x
            invariant q > 0 
            invariant qq == q*q 
            invariant pq == p*q 
            decreases x-(p+q)*(p+q)
        {
            q, pq, qq := 2*q, 2*pq, 4*qq ;
        }
        assert (p+q)*(p+q) <= x and pp==p*p and pq==p*q and qq==q*q and q>0
        p, pp := p + q, pp + 2*pq + qq ;
    }
    assert  p*p <= x < (p+1)*(p+1)

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.


2

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.


3
Zwei Jahre College-Niveau Mathematik bedeutet nicht , zwei Jahren konzentrierte sich auf das Schreiben Beweise (oder verbringen jede Zeit mit dem Schreiben Beweise). Mein Eindruck ist jedoch, dass es in Mittel- / Frühklassen der Highschool-Geometrie üblich ist, Beweise einzuschließen, sodass wir anscheinend davon ausgehen können, dass auch 13-Jährige einfache Beweise mit weniger als einem Schuljahr schreiben können Thema. Schrittweise algebraische Berechnungen sind ebenfalls wesentliche Beweise. Ich denke, Sie legen die Messlatte für "trivial", weil Sie viel zu niedrig programmieren und sich als viel zu hoch erweisen.
Derek Elkins

3
Wir könnten Programme auf die gleiche Weise schreiben. Sie können sich vorstellen, dass jede Funktion / Prozedur, die Sie schreiben, eine formale Spezifikation und einen Beweis (etwa in Coq) liefern muss, dass sie der Spezifikation entspricht. Es gibt dann Möglichkeiten, diesen Beweis auf Richtigkeit zu prüfen, ohne dass ein Urteil oder Verständnis erforderlich ist.
DW

@DW: Sie gehen davon aus, dass (1) das gewünschte Verhalten in allen Fällen vollständig spezifiziert werden kann, (2) der erforderliche Beweis existiert (dh das Problem ist nicht unentscheidbar) und (3) wenn der Beweis existiert, dann wir kann es finden. Ich denke, dass alle drei dieser Annahmen zumindest in einigen Fällen (wahrscheinlich fast in allen Fällen) falsch sind. Zu 3 ist anzumerken, dass einige Beweise zwar einfach sind, viele jedoch sehr schwer zu finden sind.
Ben Crowell

@DerekElkins: Meine Behauptung, dass nur sehr wenige Studenten sogar triviale Beweise schreiben können, basiert auf meinen eigenen Erfahrungen mit meinen Studenten. Dies ist an einem Community College, also YMMV. Die Tatsache, dass einige Highschool-Geometrieklassen eine hohe Dosis an Korrekturen enthalten, bedeutet nicht, dass alle College-Studenten Korrekturen schreiben können. Sie sollen auch wissen, wie man grundlegende Algebra macht, aber an meiner Schule kann ungefähr die Hälfte der Schüler mit Erstsemester-Kalk nicht - was erklärt, warum so viele scheitern.
Ben Crowell

Das wäre eine gute Erklärung, um die Antwort zu ergänzen und zu erklären, warum Sie nicht auf die gleiche Weise das Programm auf Richtigkeit prüfen können. Im Allgemeinen (2) und (3) sind selten ein Problem, entweder in der Praxis oder im Prinzip (wenn Sie das Programm korrekt nicht beweisen können, schreiben Sie auf eine andere Weise , bis Sie können beweisen , dass es richtig ist ). Ihr (1) ist jedoch ein wichtiger Punkt, und ich denke, es würde die Antwort stärken, um zu erklären, warum es schwierig ist, für Programme dasselbe zu tun wie für Beweise.
DW

2

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.


1
"Nur ein kleiner Teil der mathematischen Aussagen, die wahr sind, kann praktisch bewiesen werden." - Wie messen Sie "Portion"? Liegt dies unter einer Wahrscheinlichkeitsverteilung? Haben Sie Beweise für diese Aussage?
DW

"Computer werden oft aufgefordert, Dinge zu tun, die über das hinausgehen, was nachweislich korrekte Software leisten kann." - Haben Sie Beweise dafür? Hast du ein Beispiel? Behauptest du "über das hinaus, was im Prinzip als richtig erwiesen werden kann" oder "über das hinaus, was wir uns vernünftigerweise vorstellen können, in der Praxis zu beweisen"?
DW

@DW: Wenn X und Y orthogonale Aussagen sind, die wahr, aber nicht beweisbar sind, dann gibt es für jede beweisbare Aussage P mindestens zwei orthogonale Aussagen (P und X) und (P und Y), die wahr, aber nicht beweisbar sind -nachweisbar. Wenn es um unendliche Mengen geht, muss eine solche Logik nichts beweisen, da man mit einer ähnlichen Logik zeigen könnte, dass es doppelt so viele gerade Ganzzahlen wie ungerade Ganzzahlen gibt, da man für jede ungerade Ganzzahl zwei gerade Ganzzahlen (4x) und (4x) identifizieren kann (4x + 2), die keinen anderen ungeraden Ganzzahlen zugeordnet sind, aber natürlich haben gerade und ungerade Ganzzahlen die gleiche Kardinalität.
Supercat

@DW: Der Ausdruck "kleiner Teil" mag daher nur dann wirklich Sinn machen, wenn er den Bruchteil wahrer Aussagen beschreibt, die praktisch bewiesen werden können, aber ich halte es für nützlich, zu verstehen, dass die Unfähigkeit, alle wahren Aussagen zu beweisen, kein "Fehler" ist. Bei Computern verwenden viele Felder routinemäßig Algorithmen mit einer extrem geringen Ausfallwahrscheinlichkeit, die jedoch nicht Null ist, und stimmen sie dann so ab, dass die Wahrscheinlichkeit akzeptabel niedrig ist (z. B. unter der Wahrscheinlichkeit, dass ein Meteor auf das Gerät auftrifft). In vielen Fällen sind verschiedene
Fehlermodi

... um die Wahrscheinlichkeiten verschiedener Fehlerkombinationen zu bestimmen. Wenn man die Wahrscheinlichkeit eines Ausfalls während eines beliebigen Zeitraums von einer Minute auf eins zu 10 ^ -500 schätzt, könnte man um Hunderte von Größenordnungen versetzt sein und immer noch ein zuverlässiges System haben, aber wenn man um 494 Größenordnungen versetzt ist Das System würde ungefähr alle paar Jahre einmal ausfallen.
Supercat

2
  1. 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.

  2. 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.

  3. 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.

  4. 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.


2

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.


1

Sie vergleichen hier ehrlich Äpfel und Orangen. Ausfallsicher und fehlerfrei sind nicht dasselbe.

Wenn ein Programm die Zahlen vergleicht 2und , 3und es sagt , dass 2 is greater than 3, dann könnte es aufgrund einer Buggy Implementierung sein:

# Buggy implementation
function is_a_greater_than_b(a,b):
  return b > a

Das Programm ist jedoch immer noch fehlerfrei. Wenn Sie zwei Zahlen mit aund vergleichen b, können Sie immer feststellen, ob die Zahl bgrößer ist als die a. Es ist einfach nicht das, wozu Sie (der Programmierer) den Computer auffordern sollten.


2
Was ist Ihre Definition von "Fehler" in einem Programm dann?
user56834

0

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:

Diese Software ist fehlerfrei. Es ist perfekt, so perfekt wie die Menschen es erreicht haben. Betrachten Sie diese Statistiken: Die letzten drei Versionen des Programms - jeweils 420.000 Zeilen lang - hatten jeweils nur einen Fehler. Die letzten 11 Versionen dieser Software hatten insgesamt 17 Fehler.

Nehmen Sie das Upgrade der Software vor, damit das Shuttle mit Global Positioning Satellites navigieren kann. Diese Änderung betrifft nur 1,5% des Programms oder 6.366 Codezeilen. Die Spezifikationen für diese Änderung umfassen 2.500 Seiten, ein Volumen, das dicker ist als ein Telefonbuch. Die Spezifikationen für das aktuelle Programm füllen 30 Bände und umfassen 40.000 Seiten.

https://www.fastcompany.com/28121/they-write-right-stuff


"Computerprogramme sind viel größer als mathematische Beweise" Das hängt vom Programm und dem Beweis ab. Und vieles davon scheint sehr spekulativ zu sein.
David Richerby

@DavidRicherby gut hatte ich auf den Geist Dinge wie Last Satz von Fermat und Apollo NASA github.com/chrislgarry/Apollo-11 math.wisc.edu/~boston/869.pdf - und wir aint sprechen auch über Betriebssysteme und so weiter.
Exeus

0

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.)


1
Während Sie ein gutes Argument für die Komplexität der Programmierung sind, denken Sie kaum an Mathematik! Tatsächlich scheinen Sie die Komplexität der formalen Mathematik zu unterschätzen: "Wenn Sie die Dinge in der Mathematik aufschlüsseln, kommen Sie zu einzelnen Teilen, die Kinder verstehen können", wirklich ? Das Gleiche gilt übrigens auch für ausreichend „High-Level“ -Programme (z. B. Scratch ist für Kinder gedacht). Beachten Sie auch, dass, obwohl die vollständige C-Spezifikation nicht implementiert werden kann, ein Compiler, der eine wichtige Teilmenge unterstützt, mit computergestützten Beweisen formal korrekt dargestellt wurde.
Diskrete Eidechse

2+3=5

Meta-Hinweis: Wenn Sie ein Experte in einer Sache und ein Experte Anfänger (oder niedriger) in einer anderen Sache sind, sind Sie in der schlechtesten Position, um die beiden zu vergleichen.
Raphael

Diskrete Echse - das ist die Computer Science SE. Nachdem ich vor dem Posten andere Antworten gelesen hatte, hatte ich das Gefühl, dass sie die Mathematik viel mehr berührten als die Computer. Ich fand meine Antwort besser, indem ich es nicht länger machte, nur Wörter hinzuzufügen, die weitestgehend überflüssig waren mit dem, was anderswo geschrieben wurde. /// Was Scratch betrifft, ist High Level nicht einfacher, sondern komplexer (wenn man die Perspektive betrachtet, alle beweglichen Teile vollständig zu verstehen). In dieser Perspektive, aus der ich geschrieben habe, ist Assembly einfacher als Scratch auf anderen Ebenen (mit elektronischen NAND-Gattern noch einfacher)
TOOGAM

0

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.


2
Ich würde sagen, dass mathematische Beweise vollständig in der Lage sind, „was“ Wissen zu beschreiben: Nehmen Sie beispielsweise jeden Beweis, der ein Beispiel zum Nachweis der Existenz oder eine Methode zum Berechnen eines Wertes erstellt. Trotzdem stimme ich zu, dass der Zustand in Beweisen etwas abwesend ist, in dem Sinne, dass es keinen anderen Zustand gibt als den, der ausdrücklich vom Autor (oder Leser!) Beschrieben wird. Genau in diesem Zustand kann ein Programm etwas tun, von dem der Leser / Autor nichts weiß, während dies in einem Beweis unmöglich ist. (Sicher, Beweise können unbeabsichtigte Merkmale oder Ergebnisse haben, aber es sind noch einige aktive Überlegungen erforderlich, um sie zu erhalten.)
Diskrete Eidechse

@ Discretelizard Dies ist ein hilfreicher Kommentar. Ich denke, die Grenze zwischen dem "Was" und dem "Wie" ist sicherlich verschwommen. Wenn Sie beweisen, dass ein Algorithmus das tut, was Sie denken, beschreibt er in meinen Augen nicht das "Wie", sondern garantiert nur, dass bestimmte Eigenschaften erhalten bleiben. Aus philosophischer Sicht denke ich, dass "How to" -Wissen eine Korrespondenz mit der Welt erfordert. Programme tun immer das, was Sie ihnen sagen. Wenn Sie einen Fehler haben, entspricht das, was Sie ihm gesagt haben, nicht der Welt (was Sie modellieren). Mathematik scheint unabhängig von einer Anwendung (wie bei physikalischen Problemen) von Kohärenz abhängig zu sein.
Justin Meiners
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.