lunar hat geschrieben:@pillmuncher: Da diejenigen, die nicht Informatik oder Mathematik studieren, später eigentlich nur rechnen müssen, legt das Gymnasium folglich auch nur die Grundlagen zum Rechnen, im Bezug auf Funktionen eben Differential- und Integralrechnung. Philosophie- oder Chemie-Studenten, ja nicht einmal Programmierer, brauchen zum Leben und Arbeiten nun mal weder formale Logik noch eine genaue Vorstellung vom Funktionsbegriff ...
Als Programmierer braucht man, meine ich, die Fähigkeit, logisch schließen zu können. Eigentlich sollte man das in der Schule trainieren, und es sollte IMO zur allg. Hochschulreife gehören. Rechnen lernt man, indem man es immer und immer wieder trainiert. Warum macht man das nicht auch bei der Logik? Wo man doch in der Logik ebenso rechnen kann? Ein Beispiel:
Was ist das Gegenteil von "wenn es regnet, dann ist die Straße nass" = ~(p -> q)?
a) "wenn es NICHT regnet, dann ist die Straße nass" = (~p -> q)
b) "wenn es regnet, dann ist die Straße NICHT nass" = (p -> ~q)
c) "wenn es NICHT regnet, dann ist die Straße NICHT nass" = (~p -> ~q)
d) was anderes.
Die richtige Antwort ist d):
Code: Alles auswählen
a) ~(p -> q) == (~p -> q)
~(T -> q) == (~T -> q) | ~(F -> q) == (~F -> q)
~q == T | ~T == q
F | F
F
b) ~(p -> q) == (p -> ~q)
~(T -> q) == (T -> ~q) | ~(F -> q) == (F -> ~q)
~q == ~q | ~T == T
T | F
F
c) ~(p -> q) == (~p -> ~q)
~(T -> q) == (~T -> ~q) | ~(F -> q) == (~F -> ~q)
~q == T | ~T == ~q
F | F
F
d) ~(p -> q) == (p & ~q)
~(T -> q) == (T & ~q) | ~(F -> q) == (F & ~q)
~q == ~q | ~T == F
T | T
T
Zurückübersetzt in normales Deutsch: "Es regnet, aber die Straße ist nicht nass".
Das Rechenverfahren stammt von
Van "The Man" Quine und ist recht einfach. Man schreibt die zu testende Formel auf und setzt darunter auf der linken Seite für irgendeine Variable durchgehend T ein und auf der rechten Seite für dieselbe Variable durchgehend F. Dann vereinfacht man:
1.
~~x wird zu
x.
2.
~T wird zu
F.
3.
~F wird zu
T.
4.
T & x oder
x & T wird zu
x.
5.
F & x oder
x & F wird zu
F.
6.
T v x oder
x v T wird zu
T.
7.
F v x oder
x v F wird zu
x.
8.
T -> x wird zu
x.
9.
F -> x wird zu
T.
10.
x -> T wird zu
T.
11.
x -> F wird zu
~x.
12.
x == x wird zu
T.
13. Alles andere wird zu F.
Bei mehr als zwei Variablen macht man ggf. neue Unter-Spalten auf und wendet das Verfahren rekursiv an. Genauso wie beim arithmetischen Rechnen kann man abkürzen und muss nicht für jeden Schritt eine eigene Zeile aufmachen. Am Schluss jedes Blocks kommt immer T oder F raus. Wenn bei allen Blocks T rauskommt ist das Ergebnis T, sonst F. Wenn man den Punkt 13 abändert, lässt sich nicht nur Allgemeingültigkeit feststellen, sondern auch Erfüllbarkeit und Unerfüllbarkeit. Die Einzelheiten sind nicht so wichtig. Das logische Rechnen sollte für Abiturienten nicht zu schwierig sein, und für Hochschüler auch nicht. Der Nutzen liegt einerseits in der Anwendbarkeit des Verfahrens selbst und andererseits in der Schulung des logischen Denkens.
Philosophen und Logik: Quine war Philosoph. Sein Schüler Donald Davidson hat den Davidson'schen Slingshot erfunden. Dazu eine kurze Vorgeschichte:
Die Philsophen fragen sich seit jeher aus was die Welt besteht. Die vorsokratischen Philosophen schlugen ua. Die Vier Elemente vor, und stritten darüber, ob und wie man die verschiedenen Elemente aufeinander zurückühren konnte. Die Erfahrung der Griechen war, dass Wasser zu Eis werden konnte, und umgekehrt, weswegen sie glaubten es handle sich dabei um unterschiedliche Substanzen (feste und flüssige), die wechselweise ineinander überführt werden konnten. Das war übrigens keine Philosophische Theorie, sondern Allgemeinwissen. Die damaligen Philosophen arbeiteten mit den alltäglichen Überzeugungen ihrer Zeitgenossen, so wie die heutigen das auch tun. Der erste Philosoph, der systematisch die Alltagsweisheit als inadäquat ansah und sie deswegen permanent angriff, war Sokrates. Bei dessen Schüler Platon wandelte sich die Substanz-Diskussion ua. dahingehend, dass er Grade der Existenz zu sehen glaubte, und das aller-realste, und mithin substantiell reinste, in den abstrakten Ideen. Seinem Schüler Aristoteles, der Details liebte und ein großer Systematiker war, war das wohl etwas zu mystisch. Er gliederte die Modi des Seins entlang der griechisch/indogermanischen Grammatik und systematisierte so erstmals die Logik und die Linguistik. Die Verwandschaft ist heute noch sichtbar, wenn sowohl Philosophen als auch Linguisten Logik lernen müssen. Im scholastischen Mittelalter kam durch den Rückgriff auf Aristoteles der Substanz-Begriff wieder in die Diskussion, und zwar im Rahmen des Nominalismus-Streits, den IMO Occam gewonnen hat. Die dabei gewonnene Perspektive auf das Problem überlebte die anti-scholastische Revolution durch Descartes und so wurde die Substanz-Diskussion in der Neuzeitlichen Philosophie wiederbelebt. Hegel meinte, die grundlegendste Substanz sei die Vernunft selbst. Marx meinte, die Materie. Schopenhauer, der Wille. Wittgenstein, die Satzartigkeit. Was soll das sein? Nun, Wittgenstein wollte die durch Frege und Peirce erfundene Prädikatenlogik zur Fundamental-Philosophie modeln und postulierte deswegen, die basalen Elemente der Wirklichkeit seien den basalen Elementen der Logik isomorph. In der Logik ist die kleinste unabhängige Einheit der Satz. Worte haben nur in Sätzen Bedeutung (Frege-Prinzip), und analog sollten Dinge nur in Tatsachen vorkommen können. Wittgestein postuliert also im
Tractatus Logico-Philosophicus: Die Welt
zerfällt in Tatsachen, womit er meint, die Welt bestehe in ihren kleinsten unabhängigen Einheiten aus Tatsachen. "Der Hund bellt", "Die Katze sitzt auf der Matte", "Angela Merkel ist Bundeskanzlerin", usw. sind Sätze, denen, damit sie wahr sind, etwas in der Welt korrespondieren muss, nämlich die Tatsachen, die sie ausdrücken.
Die Frage ist nun, hat W. recht? Gibt es Tatsachen wirklich, und wenn ja, sind sie der Wirklichkeit kleinste Einheiten und den Sätzen isomorph? Ich kenne Hunde, auch solche die bellen, aber ein satzartiges Ding, das Bestandteil der Welt ist und isomorph zum Satz "der Hund bellt" ...? Um wahr zu sein, müsste diese Theorie mindestens das liefern, dass für jeden Satz 'p' gilt:
(a) Der Satz 'p' stimmt mit der Tatsache überein, dass p.
Ich rekonstruiere jetzt mal Davidsons Argument:
(b) Der Satz, dass München in Bayern liegt, stimmt mit der Tatsache überein, dass München in Bayern liegt.
(c) Der Satz, dass München in Bayern liegt, stimmt mit der Tatsache überein, dass (der x derart, dass x == Diogenes, und München in Bayern liegt) == (der x derart, dass x == Diogenes).
(d) Der Satz, dass München in Bayern liegt, stimmt mit der Tatsache überein, dass (der x derart, dass x == Diogenes, und Frankfurt in Hessen liegt) == (der x derart, dass x == Diogenes).
(e) Der Satz, dass München in Bayern liegt, stimmt mit der Tatsache überein, dass Frankfurt in Hessen liegt.
Die Ersetzungen folgen dabei diesen formal-logischen Gesetzen:
Code: Alles auswählen
(x)(fx) & p ==> (x)(fx & p)
(x)(fx & p) ==> (x)(fx)
(ix)(fx) & p ==> (ix)(fx & p)
(ix)(fx & p) ==> (ix)(fx)
wobei (x) der Allquantor ist und (ix) der jota-Operator, also "der/die/das x derart, dass ...".
Die Annahme, dass wahren Sätzen Tatsachen entsprechen, führt also offenbar zu der grotesken Konsequenz, dass jedem wahren Satz alle Tatsachen entsprechen. Wenn man aber sprachlich die einzelnen Tatsachen nicht mehr unterscheiden kann, dann braucht man auch nicht anzunehmen, dass sie sich überhaupt unterscheiden. Somit genügt es, eine einzige Tatsache anzunehmen, die alle Sätze wahr macht, nennen wir sie DIE GROSSE TATSACHE. Dann brauchen wir aber (a) nicht mehr und können statt dessen schreiben:
(f) Der Satz, dass p, stimmt mit DER GROSSEN TATSACHE überein.
Für 'p' dürfen wir jeden Satz einsetzen, sofern er nur wahr ist.
Damit ist die Theorie Wittgensteins, dass die Welt in Tatsachen zerfällt, ad absurdum geführt. Damit ist natürlich nicht bewiesen, dass es keine Tatsachen gibt und statt dessen alles Einbildung ist. Nur eben die Möglichkeit der Konstruktion Satz <=> Tatsache ist ausgeschaltet. Mit solcherlei Überlegungen ist man als Philosoph beschäftigt, und ohne Logik ist man dabei verloren. Interessant an dieser Geschichte ist übrigens, dass der
Tractatus Logico-Philosophicus soz. die Gründungsschrift der Analytischen Philosophie ist, deren Vertreter Davidson war. Und Wittgenstein hatte diese Position längst aufgegeben als Davidson das Slingshot-Argument brachte, er lebte sogar nicht mal mehr. Es richtete sich also letztlich nicht gegen Wittgenstein, sondern gegen diejenigen, die an Wittgensteins Früh-Philosophie kleben geblieben waren.
lunar hat geschrieben:LISP ist auch nicht perfekt, unter anderem auch deswegen, weil sich damit wirklich jeder seine eigene DSL für sein Problem zimmert, und dabei soweit abstrahiert, dass die Lösung hinter all der Abstraktion oft genug überhaupt nicht mehr zu erkennen ist. In Python oder Haskell käme niemand auf die Idee, die Fakultät über Church-Numerale zu implementieren, weil damit so schick von konkreten Zahlen abstrahieren kann, und nur noch Funktionen braucht. In LISP aber scheint derlei geradezu Qualitätsmerkmal eines guten Programmierers zu sein, mit dem Resultat, dass es oftmals unmöglich ist, fremde Programme unmittelbar zu verstehen.
Zuletzt hatte ich eine BoundingBox Klasse geschrieben, mit der man zB. sowas machen konnte:
Code: Alles auswählen
boxes = []
for x, y in some_points():
rect = x, y, x + n, y + m
for box in boxes:
if box.overlaps(rect):
box.enclose(rect)
break
else:
boxes.append(BoundingBox(rect))
Weil $Kollege die aber nicht hernehmen wollte, sah das bei ihm dann in etwa so aus:
Code: Alles auswählen
boxes = []
for x, y in some_points():
rect = x, y, x + n, y + m
for box in boxes:
if not ( box[0] > rect[2] or box[2] < rect[0] or box[1] > rect[3] or box[3] < rect[1] ):
box[0] = min(box[0], rect[0])
box[1] = min(box[1], rect[1])
box[2] = max(box[2], rect[2])
box[3] = max(box[3], rect[3])
break
else:
boxes.append(rect)
Natürlich war das nur eine von vielen Stellen im Code, wo bounding boxes aufgespannt wurden, und es sah überall so aus. Nur schlimmer. Das verstößt eklatant gegen DRY. Aber $Kollege liebt top down Entwurf und ist großer MDA Fan. Big Design Upfront. Kleine Tools die einem das Leben leichter machen, wie eine BoundingBox Klasse, die einfache Tests für Überschneidung und einfache Operationen zum Aufspannen etc. mitbringen, sind ihm völlig fremd, weil das ja nicht von oben nach unten entworfen wurde. Ist jedenfalls meine Interpretation seines Verhaltens.
Dagegen nehme ich den LISPer jederzeit.
lunar hat geschrieben:@pillmuncher: Man kann endrekursive Aufrufe in Python nicht so einfach optimieren. In Python kann jeder Namen zu jedem beliebigen Zeitpunkt neu gebunden werden. Es ist folglich nicht garantiert, dass das ein gegenwärtig ausgeführtes Funktionsobjekt beim rekursiven Abstieg noch an denselben Namen gebunden ist.
Dieses Problem betrifft aber den expliziten rekursiven Aufruf genauso. Mir geht es übrigens weniger um Endrekursion, als um Continuations als flexible Kontroll-Struktur. Die funktionieren letztlich nur mit tail calls, oder mit unendlich großem call stack.
Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.