Anda di halaman 1dari 8

1

Influencias de la Lógica Matemática en las Ciencias de la Computación

Martin DAVIS
Courant Institute of Mathematical Sciences
New York University

______________________________________________________________________

El siguiente texto es una traducción parcial de la conferencia que David ofreció con el
título “Influences of Mathematical Logic on Computer Science” en ocasión de los 50
años del célebre artículo de Alan Turing sobre teoría de la computabilidad, “On
Computable Numbers, with an Application to the Entscheidungssproblem”, en 1987.
La traducción castellana es de Facundo García Valverde
______________________________________________________________________

Cuando yo era estudiante, hasta los topólogos consideraban que los lógicos
matemáticos vivían en el espacio exterior. Hoy en día, las conexiones entre la lógica y
la computación son un asunto de práctica ingenieril en cada nivel de la organización
computacional: abundan compañías con nombres como Logical Devices o Logicsoft;
uno puede ingresar en un negocio y pedir “una prueba lógica”. De ninguna manera esto
es sólo una cuestión de términos. Los temas y conceptos que surgieron por primera vez
en las investigaciones técnicas llevadas a cabo por los lógicos están estrechamente
vinculados con muchos aspectos de la Ciencia de la Computación.
¿Hasta qué punto el trabajo previo de los lógicos influyó en los científicos e
ingenieros en computación? ¿Usaron lo ya hecho o simplemente “inventaron la
pólvora” como algo necesario? Lamentablemente, es mucho más sencillo señalar las
confluencias de ideas que trazar rigurosamente un camino desde el trabajo original hasta
sus aplicaciones. Cuando las ideas en cuestión son verdaderamente fundamentales y,
por lo tanto, finalmente simples (del mismo modo en que tantos conceptos
fundamentales resultan serlo) la gente olvida fácilmente lo sorprendente que fueron esas
ideas cuando se enunciaron por primera vez. Tales ideas pueden transformarse de algo
absurdo a una trivialidad en pocos años. En Davis (1987) se discuten extensamente
algunos de estos temas y se relacionan con el rol que jugó el descubrimiento de la
máquina universal de calcular, realizado por Alan Türing, en el desarrollo actual de las
modernas computadoras electrónicas. En este ensayo, seguiremos el camino de un
conjunto de conceptos que surgieron en el trabajo de los lógicos y que encontraron su
lugar en la teoría y práctica computacional.

Sintaxis formal

Una de las primeras cosas que un usuario principiante debe aprender es que la
computadores tienden a ser totalmente implacables con errores “menores” en la
notación. ¿Quién no se ha sentido frustrado al verse obligado a reingresar una larga
línea de texto únicamente porque una coma debía ser un punto? Podríamos afirmar que
los lenguajes de computadoras (lenguajes de programación, sistemas operativos,
sistemas para bases de datos, etc.) tienen una sintaxis formal totalmente prescripta. La
noción de que un lenguaje creado artificialmente podría ser útil para extender el ámbito
2

de lo que podía ser logrado por el cálculo se retrotrae a Leibniz1. Sin embargo, el primer
ejemplo efectivo de un lenguaje formal fue presentado por Gottlob Frege, en su
Begriffsschrift.2
Frege puede ser considerado el fundador del movimiento logicista en la
justificación teórica de la matemática. El logicismo es la tesis según la cual la
matemática y la lógica son literalmente el mismo asunto: todas las entidades que
aparecen en matemática pueden ser tomadas legítimamente como construcciones
puramente lógicas y la prueba matemática es simplemente una deducción lógica. De tal
modo, un logicismo minucioso debería estar preparado para brindar una rigurosa
formulación de la lógica deductiva. Frege contó con los descubrimientos previos de
George Boole acerca de la posibilidad de tratar la deducción lógica como una rama de
las matemáticas. Pero, ¿no es esto caer en un círculo vicioso? Si la lógica es
desarrollada usando la matemática, ¿cómo puede ser ella, a su vez, el fundamento
subyacente para todas las matemáticas?. La solución de Frege a este problema fue la
sintaxis formal. Creó un lenguaje artificial, su Begriffsschrift –literalmente “escritura de
conceptos” o “conceptografía”–, caracterizado como un Formelsparache des reinen
Denken, un “lenguaje formal del puro pensamiento”. En este lenguaje, la deducción es
reemplazada por la derivación formal, la cual depende exclusivamente de la
manipulación simbólica. De tal forma, la circularidad es evitada. El sistema fregeano
terminó siendo formalmente inconsistente –de lo cual el propio Frege se dio cuenta al
recibir la famosa carta de Bertrand Russell que contenía las “paradojas de Russell”– y,
por consiguiente, su programa no fue, ciertamente, un éxito. No obstante, sus logros
fueron muy importantes. Su Begriffsschrift contuvo, por primera vez, una formulación
de lo que luego se denominó lógica de primer orden (LPO). Pero lo que resultó más
importante para las Ciencias de la Computación fue la clara demostración fregeana de
cómo construir y tratar rigurosamente con un lenguaje formal.
Cuán importante fue el trabajo de Frege resulta evidente cuando se lo compara
con el de sus sucesores. Si bien E. Schröder, G. Peano y Bertrand Russel realizaron
importantes contribuciones, sus trabajos, en gran parte realizados durante las primeras
décadas del siglo veinte, carecían del nivel de rigor de Frege. Así, uno puede encontrar
en Bertrand Russell3 una lista de “axiomas” –llamados por él “proposiciones
primitivas”– con expresiones meramente simbólicas como

q→pvq

conjuntamente con la afirmación en inglés

A proposition implied by a true premise is true4

Frege nunca habría permitido tal confusión entre el lenguaje formal en el que
trabajaba y las afirmaciones en el lenguaje natural acerca de ese lenguaje formal. Esta
misma formulación aparece en Principia Mathematica, el edificio de tres volúmenes
construido por A. Whitehead y Russell como una encarnación de su visión logicista.
La disertación de Emil Post5 marcó una vuelta a los estándares de rigor de Frege.
Sin embargo, el énfasis de Post era bastante diferente. A diferencia de lógicos como

1
ver, p.e. Davis (1987)
2
Frege, 1879
3
Russel, 1908
4
Una proposición implicada por una premisa verdadera es verdadera
5
Post, 1921
3

Frege y Russell, la preocupación principal de Post no era utilizar sistemas formales de


lógica como fundamentación de las matemáticas. Antes bien, él observó que una vez
formulados, esos sistemas podían ser investigados por métodos matemáticos ordinarios.
En particular, Post estudió el problema de hallar algoritmos que permitieran determinar
mecánicamente si una fórmula particular en el lenguaje de Principia Mathematica podía
ser derivada usando las reglas del lenguaje. Para este propósito, reemplazó el oscuro
concepto de “proposición primitiva” por el principio puramente sintáctico de modus
ponens (que era el que realmente habían utilizado Whitehead y Russell)

“├ P” y “├P → Q” produce “├Q”

Desde esta perspectiva, lo interesante del programa logicista es que suponía que el
éxito en el hallazgo de tales algoritmos podría conducir a la mecanización de extensas
partes de la matemática. Post resolvió sólo la primera parte del problema: encontró
algoritmos para la parte de Principia Mathematica que llamamos ahora cálculo
proposicional. Sus esfuerzos para extender esos resultados lo llevaron a considerar
operaciones formales en un contexto más general, a las cuales denominó producciones.
Como sabemos ahora y como el mismo Post se dio cuenta rápidamente, el problema, en
su totalidad, no tiene solución: el problema de hallar un algoritmo de decisión para el
sistema completo de Principa Mathematica es, como diríamos hoy, indecidible6.
Las producciones de Post son ubicuas en las ciencias de la computación. Su
primera aplicación fue la que llevó a cabo Noam Chomsky, quien encontró en ellas
exactamente lo que necesitaba para su revolucionaria teoría de las gramáticas de los
lenguajes naturales. Esto condujo a Chomsky a su ahora famosa clasificación o
jerarquía de lenguajes basada en la clase específica de producciones que Post permitía
en su gramática de definición. La conexión con las Ciencias de la Computación se hizo
manifiesta cuando resultó que una de las clases de Chomsky consistía en la misma clase
de lenguajes que podían ser reconocidos por un autómata finito y que otra –los llamados
lenguajes independientes del contexto– consistía en lenguajes reconocibles por un
autómata finito equipado con una pila auxiliar (finite automata equipped with an
auxiliary pushdown stack). De forma aparentemente independiente del trabajo
chomskiano, John Backus utilizó las producciones de Post para proveer una sintaxis
apropiada para el desarrollo del lenguaje de programación ALGOL 58; allí resultó que
los lenguajes que podían ser describirse en términos de la sintaxis de Backus eran
exactamente los lenguajes independientes del contexto de Chomsky!.
Estuve particularmente interesado en leer la explicación de Backus respecto a
cómo se le había ocurrido su sintaxis porque, para mi sorpresa, mencionaba mi nombre:

“En cuanto al origen de esta idea, surgió en una clase de Martin Davis que
pude presenciar. Él estaba dictándola en la Universidad de Atlanta State, hablando
acerca de Emil Post y de su noción de producción. Cuando trató de describir el
ALGOL 58 me di cuenta de que existía un problema en la descripción de la
sintaxis. Era obvio que las producciones de Post eran precisamente lo que
necesitaba y me apresuré a adaptarlas a ese uso…7”

El placer que me produjo haber jugado, aparentemente, algún papel en este


problema fue, sin embargo, malogrado al darme cuenta de que nunca había puesto un
pie en “Atlanta State”: de hecho, al chequear con bibliotecarios referencistas
6
ver Davis, 1982b, para una amplia discusión del trabajo de Post en los años 20.
7
Backus, 1981, p.162
4

descubrimos que no existía esa institución. Pero pronto fui capaz de resolver el misterio.
Había brindado un curso de conferencias para IBM durante el año académico 1960-61
con John Backus entre el público. Las conferencias fueron brindadas en el “The Lamb
State” en el condado de Westchester, estado de Nueva York, donde muchos de los
investigadores de IBM trabajaban en ese momento. Contento con mi explicación,
publiqué lo que pensé era una pequeña pero ingeniosa nota explicando el error en los
“Annals of the History of Computing”8. Poco tiempo después me topé con otro texto de
Backus9 en donde una vez más me daba créditos por ser el canal transmisor por el cual
se había enterado del trabajo de Post. Fue entonces que al examinar la lista de
referencias en su texto, me di cuenta, con cierta desazón, de que Backus ya había dado
una charla sobre su “forma normal” durante el verano de 1959, ¡mucho antes de que él
escuchara mis conferencias! Las discusiones con Backus en los últimos años no han
logrado echar luz sobre este tema.
Esta anécdota personal puede servir para subrayar la dificultad en el trazado del
camino por el cual una idea se transfiere de la teoría a la práctica. Tengo pocas dudas de
que el recuerdo de Backus acerca de las influencias de Post sea correcto. Pero él no era
un lógico. ¿Cómo hizo para enterarse del trabajo de Post? Mi libro (Davis, 1958) fue
una fuente posible, así como los primeros trabajos de Chomsky. Otra posibilidad son los
lógicos que trabajaban con Backus en IBM en el proyecto FORTRAN.
Por supuesto, lo importante e interesante es la transmisión de ideas. Tratar de
establecer el camino “real” sólo es interesante en cuanto ayuda a establecer si la
transmisión ocurrió realmente. Sin embargo, este ejemplo, en el cual todos los
involucrados están vivos y donde no existen asperezas –condiciones que no son, de
ninguna manera, típicas–, demuestran cuán difícil puede ser esta empresa.

Lógica Booleana

“Verdadero” y “falso”; “sí” o “no”; 0 y 1. Se ha vuelto una perogrullada afirmar


que la misma dualidad sugerida por estos pares es responsable de la íntima conexión
entre la lógica proposicional ordinaria y el sistema de circuitos digital binario. El
álgebra que suele asociarse con este punto de vista es el mismo que desarrolló George
Boole en 1840. Aunque la idea de representar el razonamiento lógico como cálculo
matemático ya había sido concebida por Leibniz, fue el trabajo de Boole el que la asentó
firmemente como una realidad.
Aun cuando el logro de Boole fue inmenso, su trabajo presentaba serias
limitaciones. Su visión de la lógica estaba condicionada por la tradición –derivada de
Aristóteles– de analizar las oraciones en forma de sujeto y predicado. En consecuencia,
su lógica venía a ser un cálculo de predicados o conjuntos. Boole reconoció que las
reglas algebraicas que había descubierto también tenían otra interpretación
“proposicional”, en la cual las variables representaban oraciones o sus valores de
verdad. Sin embargo, quedó pendiente para Frege, en su Begriffschrift, la misión de
escapar de la limitación del análisis sujeto-predicado y reconocer la primacía del cálculo
proposicional.
La observación de suma importancia, aunque esencialmente simple, de que cada
circuito eléctrico contiene contactos que pueden ser interpretados como una fórmula de
cálculo proposicional fue realizada por Claude Shannon en su tesis de “master of
science”10. La meta era interpretar “verdadero” y “falso” como si correspondiesen a un

8
Davis, 1982a
9
Backus, 1980
10
Shannon, 1938
5

contacto que se apagaba o se encendía, respectivamente. Las conectivas boolenas “y” y


“o” correspondían, entonces, a contactos que eran conectados en serie y en paralelo,
respectivamente. Como advirtió Herman Goldstine11, “esto ayudó a que el diseño de
circuitos fuera una ciencia y ya no un arte.” Durante muchos años, los ingenieros
eléctricos aprendieron rutinariamente las leyes de la lógica booleana en sus cursos de
“Teoría de Circuitos”. Así, los modos abstractos de pensar fueron alentados a realizar
una transición natural hacia las nuevas tecnologías (de regular la corriente de tubos al
vacío a transistores y a circuitos integrados). De cualquier forma, sin el análisis
sistemático posibilitado por los métodos booleanos, la construcción de computadoras
digitales a gran escala sería virtualmente inconcebible.
Las conexiones entre la lógica y las ciencias de la computación son de ida y
vuelta. La comprensión de que la complejidad lógica de una fórmula booleana está
íntimamente relacionada con el número de elementos necesarios en los circuitos
correspondientes –y, por lo tanto, con su costo– condujo al filósofo y lógico W. V.
Quine a trabajar en el difícil problema combinatorio de hallar la fórmula más pequeña
posible que pueda representar una fórmula booleana dada12. La investigación de Quine
fue proseguida y extendida por muchos investigadores. No pasó mucho tiempo antes de
que este material se convirtiera en manual estándar13. Más recientemente, los circuitos
booleanos están jugando un rol importante en alguno de los más difíciles problemas en
la teoría contemporánea de las ciencias de la computación: por ejemplo, el de minimizar
las limitaciones en la complejidad de la computación.

Lenguajes de programación

Los lenguajes de programación son simplemente el vehículo por medio del cual
los usuarios pueden establecer exactamente qué pasos computacionales desean que se
lleven a cabo. Al utilizar las primeras máquinas con programas de almacenamiento
(stored-programs) de los años 50, el único lenguaje de programación disponible para el
usuario de una computadora determinada era el propio de esa máquina, el “lenguaje de
la máquina”. Las “instrucciones” que conformaban un programa consistían,
comúnmente, en “órdenes” de traer desde la memoria cadenas binarias que
representaban números hacia una unidad “aritmética”, donde ellas podían ser operadas
mediante estrategias aritméticas ordinarias y luego devueltas a la memoria. El
programa, en sí, era almacenado en la misma memoria, codificado en forma binaria, y
las instrucciones eran puestas consecutivamente en movimiento en la unidad aritmética.
La secuencia de operaciones aritméticas podía ser interrumpida por un “test”, en general
consistente en determinar si alguna cantidad específica en la unidad aritmética era
positiva o negativa; tal test podía resultar en un “salto” hacia la próxima instrucción
fuera de la secuencia.
Aunque actualmente día los lenguajes de las máquinas no son tan diferentes de los
descriptos, los programadores rara vez trabajan de una manera tan rígida. En el peor de
los casos, trabajan en un lenguaje “ensamblador” (assembly language) en el cual las
señas mnemotécnicas y simbólicas proveen, por lo menos, una interfaz mínimamente
orientada hacia lo humano. Pero más comúnmente, los programadores trabajan en un
lenguaje de “nivel superior” que debe ser “recopilado” – es decir, traducido de una vez
para siempre en el lenguaje de la máquina – o “interpretado” –esto es, operado paso por
paso por un programa especial que realiza cada paso a medida que lo encuentra. Cabe

11
Goldstine, 1972
12
Quine, 1952
13
Ver, p.e., Dietmeyer, 1971
6

señalar que el desarrollo de estos lenguajes ha introducido cada vez más estructuras
lógicas. FORTRAN fue, quizás, el primer lenguaje serio de programación y usado
masivamente con fines múltiples14. […] Su deuda con los lenguajes formales
desarrollados por lógicos puede observarse en este fragmento del manual original de
FORTRAN:
“Si E y F son expresiones de la misma forma y si el primer símbolo de F no
es + o ¬, entonces

E+F
E–F
E≠F
E/F

son expresiones de la misma forma.”

PASCAL es, hoy en día, el lenguaje de programación con el cual se inician los
estudiantes universitarios de Ciencias de la Computación. PASCAL presenta la clase
“booleana” como una de las más fundamentales: esta clase consiste en dos valores
(“verdadero” y “falso”). Los valores booleanos pueden combinarse utilizando las
operaciones “y”, “o”, y “no”. Las condiciones booleanas pueden utilizarse no sólo para
controlar “saltos” por medio de construcciones del estilo “si… entonces” y “si…
entonces… de lo contrario” (if-then-else), sino también para determinar el punto final de
complejos y reiterados “bucles” (loops) utilizando construcciones del tipo “mientras…
hacer…” y “repetir… hasta…”. Facilidades de este tipo existen en la mayoría de los
lenguajes de programación utilizados actualmente. Por ejemplo, el BASIC que provee
IBM conjuntamente con su línea de computadoras personales tiene, esencialmente, estas
mismas facilidades.
El primer lenguaje de programación con medios lógicos extensivos fue,
probablemente, el LISP desarrollado por John McCarthy a fines de los 50 y que se
continúa usando15. La característica especial del LISP es que los objetos básicos de
información con los que trata no son tanto números sino listas asociativas. Las
facilidades booleanas están disponibles aquí bajo la forma de lo que McCarthy
denomina “expresiones condicionales”, el descendiente directo de las estructuras “si…
entonces… en otro caso” mencionadas anteriormente. A decir verdad, el propio
McCarthy formó parte del grupo que desarrolló ALGOL 60, en el cual se incluyó la
estructura “si… entonces… de lo contrario”, fue esta influencia del ALGOL la que
probablemente motivó la inclusión de tal estructura en todos los lenguajes de
programación serios. […]

Programación lógica

La programación es una tarea sumamente exigente. Un problema debe ser


reducido a la ejecución de una secuencia explícita de pasos y luego estos pasos deben
ser traducidos al lenguaje de programación. La programación lógica sugiere una
alternativa: el problema será simplemente descripto en términos puramente lógicos. Se
suministrará a la computadora un motor lógico que lleve a cabo todas las deducciones
lógicas posibles que surjan de esa descripción y, luego, se obtendrá la solución

14
Para una discusión detallada de la historia pre-Fortran de los lenguajes de programación, ver
el comprometido ensayo Knuth y Pardo, 1981
15
ver McCarthy, 1981 para un interesante relato de la primera historia de Lisp
7

esperada. El motor lógico puede ser un programa para realizar deducciones en LPO (la
lógica introducida por Frege que se obtiene de añadir los cuantificadores “todo” y
“algún” al cálculo proposicional). Tales programas, llamados comúnmente
“demostradores de teoremas” (theorem-provers), han sido largamente estudiados16. En
Kowalski 1980, se argumenta apasionademente que la programación lógica es la clave
del desarrollo futuro de software.
Los principales sistemas de programación disponibles son los varios dialectos del
lenguaje de programación PROLOG, del cual Colmerauer ha sido su principal artífice.
La conocida ineficiencia de los “testeadores de teoremas” –no totalmente desligada de
la indecibilidad de la lógica de primer orden– es tratada en PROLOG mediante el uso de
una forma brutalmente minimalista de LPO, la autodenominada cláusula lógica “horn”.
Una cláusula “horn” (horn clause) es un enunciado de la forma
p1 ^ p2 ^… ^ pn→ q

Aquí, p1, p2, … pn, q pueden contener variables, pero ellas deben ser atómicas, en el
sentido de no contener en sí mismas otras operaciones lógicas (en particular ésta es una
lógica sin negación). Un programa en PROLOG es, esencialmente, una lista de
cláusulas “horn”. El intérprete de PROLOG es, entonces, básicamente un demostrador
de teoremas de cláusulas horn. Un gran interés ha suscitado tanto PROLOG como la
programación lógica; de hecho, actualmente existe una revista especializada
exclusivamente en estos temas. Los intérpretes y recopiladores de PROLOG son
asequibles para muchos sistemas computacionales, incluyendo el ubicuo IBM-PC/DOS.
Aunque PROLOG ha sido utilizado con bastante efectividad, todavía no ha
llegado a cumplir con todas las expectativas. La estrategia utilizada por el demostrador
de teoremas de la cláusula horn es tan drástica que los resultados dependen críticamente
del orden en el cual se han dado las cláusulas. Aun así, algunas “impurezas” deben ser
añadidas a su lógica para disponer de un sistema operable, particularmente la operación
de corte por medio de la cual el programador impide que el demostrador de teoremas
siga líneas de deducción poco promisorias. A pesar de todo, PROLOG representa un
ejemplo importante y palpable de la asociación entre la lógica y la computación.

Conclusiones

Este volumen conmemora el 50º aniversario del descubrimiento de la máquina


universal de Turing en conexión con su prueba de la indecibilidad de LPO. Esto
representa, por sí solo, un ejemplo notable de la conexión que hemos estado analizando.
Sin embargo, el trabajo de Turing exhibe la relación de numerosas formas. Su máquina
universal es, al mismo tiempo, un intérprete programado (para máquinas de Turing
concebidas como lenguajes de programación) y, de tal forma, su primer ejemplo. La
intercambiabilidad lógica del software y del hardware que este trabajó demostró es, hoy
en día, un hecho de la realidad; incluso en la forma en que Turing asociaba las
condiciones lógicas con partes separadas de un programa –durante su prueba de la
indecibilidad de LPO–, él presagiaba el uso de tales condiciones en los intentos para
certificar, mediante una prueba matemática, la corrección de un programa de
computadora. ¿Quién puede decir que nos depararán los próximos cincuenta años?.

16
ver Davis, 1983 y Loveland, 1984, para la historia.
8

BIBLIOGRAFÍA

John Backus, 1980, “Programming in America in the 1950s – Some personal


impressions”, en Metropolis, Howlett y Rota (eds.), 1980, pp.125-35
John Backus, 1981, “The history of Fortran I, II and II”. Transcript of discussion, en
Wexelblat (ed.), 1981
Martin Davis, 1958, “Computability and Unsolvability”, McGraw-Hill. Reimpreso en,
Dover, 1983
Martin Davis, 1982a, “Lectures at “Atlanta State”, en Annals of the History of
Computing, vol. 4, pp. 370-1
Martin Davis, 1982b, “Why Gödel Didn’t Have Church’s Thesis”, en Information and
Control, vol. 54, pp. 3-24
Martin Davis, 1983, “The Prehistory and Early History of Automated Deduction”, en
Automation of Reasoning, vol. 1, Jörg Siekman y Graham Wrightson (eds.), pp. 1-
28. Springer
Martin Davis,1987, “Mathematical Logic and the Origins of Modern Computers”, en
Studies in the History of Mathematics, pp.137-65, Math. Assoc. America
Donald Dietmeyer, 1971, “Logical Design of Digital Systems”, Allyn and Bacon
Gottlob Frege, 1879, “Begriffsschrift, eine er arithmetischen nach gebildete
Formelsprache des reinen Denkens“, Halle. Reimpreso en Ignacio Angelelli, (ed.),
Begriffsschrift und andere Aufsätze, Olms, Hildesheim. Traducción inglesa en van
Heijenoort (ed.)
Heman H. Goldstine, 1972, “The Computer from Pascal to Von Neumann”, Princeton.
Stephen C. Kleene, 1981, “Origins of Recursive Function Theory”, en Annals of the
History of Computing, vol. 3, pp. 52-67
Donald. E. Knuth y Luis Trabb Pardo, 1980, “The Early Development of Programming
Languages”, en Metropolis, Howlett y Rota, (eds.), 1980, pp.125-35
R. A. Kowalski, 1980, “Logic for Problem Solving”, North Holland.
Donald Loveland, 1984, “Automated Theorem Proving: a Quarter Century Review”, en
Contemporary Mathematics, vol. 29, pp.1-45
John McCarthy, 1981, “History of LISP”, Discusión en Wexelblat, 1981
N. Metropolis, J. Howlett y Gian-Carlo Rota (eds.), 1980, “A History of Computing in
the Twentieth Century”, Academic
Emil L. Post, 1921, “Introduction to a General Theory of Elementary Propositions”, en
American Journal of Math., vol. 43, pp. 163-85. Reimpreso en van Heijenoort (ed.),
pp. 264-83
W. V. Quine, 1952, “The Problem of Simplifying Truth Functions”, en Amer. Math.
Monthly, vol. 59, pp .521-31
J. Barkley Rosser, 1984, “Highlights of the History of the Lambda Calculus”, en Annals
of the History of Computing, vol. 4, pp. 337-49
Bertrand Russell, 1908, “Mathematical Logic as Based on the Theory of Types”, en
American Journal of Math., vol. 30, pp. 222-62. Reimpreso en van Heijenoort (ed.)
C. E. Shannon, 1938, “A Symbolic Analysis of Relay and Switching Circuits”, en
Trans. AIEE, vol. 57, pp. 713 ss.
Jean van Heijenoort (ed.),” From Frege to Gödel: A Source Book in Mathematical
Logic, 1879- 1931”, Harvard University Press.
Richard Wexelblat, 1981, “History of Programming Languages”, Academic

Anda mungkin juga menyukai