Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Matemáticas discretas

Libro de Favio Miranda y Elisa Viso, de la Facultad de Ciencias de la UNAM

Matemáticas discretas Favio E. Miranda Elisa Viso G. Facultad de Ciencias, UNAM Índice general I Lógica Matemática 1 1. Introducción 3 1.1. Expresiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Mecanismos formales para descripción de expresiones . . . . . . . . . . . 6 1.3. Gramáticas y árboles de derivación . . . . . . . . . . . . . . . . . . . . . . 10 2. Lógica proposicional 2.1. El lenguaje de la lógica proposicional . . . . 2.1.1. Argumentos lógicos . . . . . . . . . 2.1.2. Proposiciones . . . . . . . . . . . . . 2.1.3. Sintaxis de la lógica proposicional . . 2.1.4. Semántica de la lógica proposicional . 2.1.5. Tautologı́as y contradicciones . . . . 2.1.6. Argumentos correctos . . . . . . . . 2.2. Evaluación de expresiones . . . . . . . . . . 2.2.1. Estados y evaluación . . . . . . . . . 2.2.2. Precedencia y asociatividad . . . . . 2.2.3. Sustitución textual . . . . . . . . . . 2.3. Análisis sintáctico de expresiones lógicas . . 2.3.1. Esquemas . . . . . . . . . . . . . . . 2.3.2. Rango y conectivo principal . . . . . 2.3.3. Análisis de proposiciones compuestas 2.3.4. Tautologı́as y sustitución . . . . . . . 2.4. Equivalencia lógica . . . . . . . . . . . . . . 2.4.1. Razonamiento ecuacional . . . . . . 2.4.2. Álgebra de equivalencias lógicas . . . 2.5. Conceptos semánticos importantes . . . . . . 2.5.1. Interpretaciones . . . . . . . . . . . . 2.5.2. Consecuencia lógica . . . . . . . . . 2.6. Análisis de argumentos . . . . . . . . . . . . 2.6.1. Tablas de Verdad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 19 21 24 26 35 37 42 42 44 46 50 51 53 55 57 61 63 68 74 75 77 80 80 2.6.2. Uso de interpretaciones . . . . . . . . . 2.6.3. Derivaciones . . . . . . . . . . . . . . 2.7. Tableaux en cálculo proposicional . . . . . . . 2.7.1. El concepto de tableau . . . . . . . . . 2.7.2. Eliminación de ramas del tableau . . . 2.7.3. Reglas para los tableaux . . . . . . . . 2.7.4. Modelo de una fórmula . . . . . . . . . 2.7.5. Algoritmos para la lógica proposicional 3. Lógica de predicados 3.1. Introducción . . . . . . . . . . . . . . 3.1.1. Predicados . . . . . . . . . . 3.1.2. Variables y cuantificadores . . 3.2. Sintaxis de la lógica de predicados . . 3.2.1. Términos . . . . . . . . . . . 3.2.2. Fórmulas . . . . . . . . . . . 3.2.3. Fórmulas cuantificadas . . . . 3.2.4. Variables libres y ligadas . . . 3.3. Especificación formal . . . . . . . . . 3.3.1. Juicios aristotélicos . . . . . . 3.3.2. Negaciones . . . . . . . . . . 3.3.3. Contando objetos . . . . . . . 3.3.4. Micromundos . . . . . . . . . 3.4. Semántica informal . . . . . . . . . . 3.4.1. Dominios de interpretación . . 3.4.2. Noción informal de verdad . . 3.4.3. Verdad en micromundos . . . 3.4.4. Algunas equivalencias lógicas 3.4.5. Algunos argumentos correctos 3.5. Predicados y tipos . . . . . . . . . . . II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 88 98 98 103 105 107 108 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 113 114 116 118 118 119 121 123 128 130 131 132 133 139 139 142 144 147 155 156 Inducción y recursión 4. Inducción y recursión 4.1. Introducción . . . . . . . . . . . . . . . . 4.2. Los números naturales . . . . . . . . . . 4.2.1. Axiomas de Peano . . . . . . . . 4.3. Inducción en los números naturales . . . . 4.3.1. Cambio de la base de la inducción 4.3.2. Inducción completa . . . . . . . . 4.4. Definiciones recursivas . . . . . . . . . . 161 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 163 164 165 166 170 172 178 4.4.1. Definición de funciones recursivas 4.5. Inducción estructural . . . . . . . . . . . 4.5.1. Inducción en listas . . . . . . . . 4.5.2. Inducción en fórmulas . . . . . . 4.5.3. Inducción en árboles . . . . . . . III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Teorı́a de Gráficas 199 5. Conceptos de teorı́a de gráficas 5.1. Motivación . . . . . . . . . . . . . . . . . . . . 5.1.1. Tiempo para completar un proyecto . . . 5.1.2. Asignación óptima de recursos . . . . . . 5.2. Conceptos y formalización . . . . . . . . . . . . 5.3. Representación de gráficas para su manipulación 5.3.1. Matriz de adyacencias . . . . . . . . . . 5.3.2. Matriz de incidencias . . . . . . . . . . . 5.3.3. Listas de adyacencias . . . . . . . . . . . 5.3.4. Listas de incidencias . . . . . . . . . . . 5.4. Isomorfismo entre gráficas . . . . . . . . . . . . 6. Exploración en gráficas 6.1. Circuitos eulerianos . . . . . . . 6.2. Trayectorias hamiltonianas . . . 6.3. Distancias en una gráfica . . . . 6.4. Trayectorias más cortas . . . . . 6.5. Número de caminos . . . . . . . 6.5.1. Matrices de adyacencias 6.5.2. Colofón . . . . . . . . . 181 186 187 190 192 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 201 203 210 215 228 228 230 231 233 236 . . . . . . . 243 243 261 269 275 284 284 291 7. Modelado con gráficas 295 7.1. Coloración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 8. Árboles 8.1. Caracterización . . . . . . . . . . . . . . . . . . . . . . . 8.2. Árboles generadores . . . . . . . . . . . . . . . . . . . . 8.3. Búsqueda en profundidad (DFS) . . . . . . . . . . . . . . 8.4. Árboles generadores de peso mı́nimo . . . . . . . . . . . . 8.4.1. Algoritmo de Prim para árboles de peso mı́nimo . 8.4.2. Algoritmo de Kruskal para árboles de peso mı́nimo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 311 318 322 328 329 346 9. Multigráficas y gráficas dirigidas 9.1. Multigráficas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2. Gráficas dirigidas . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3. Circuitos eulerianos . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4. Distancias en una gráfica dirigida . . . . . . . . . . . . . . . . . . . 9.4.1. BFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4.2. Algoritmo de Dijkstra para trayectorias dirigidas más cortas 9.4.3. Número de caminos . . . . . . . . . . . . . . . . . . . . . 9.4.4. Árboles . . . . . . . . . . . . . . . . . . . . . . . . . . . . Índice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 353 356 361 366 366 367 368 369 375 Parte I Lógica Matemática Introducción 1 El libro está dividido fundamentalmente en tres partes: Lógica Matemática, Inducción y Recursión, y Teorı́a de Gráficas . De la inducción y recursión tal vez no hemos oı́do pero de lógica y gráficas sı́, cuando por ejemplo hemos hecho gráficas desde la secundaria (aunque esta interpretación de “gráficas” no es la que vamos a atacar en este curso) y el término lógica lo usamos de manera bastante liberal en nuestra vida diaria en frases como las que siguen: • No es lógico lo que estás diciendo. • No entiendo la lógica de este asunto. • Presentas un argumento que no es coherente. • Es falso lo que estás suponiendo. Todos nosotros sabemos que existe más precisión cuando estamos en el terreno matemático que cuando estamos hablando de experiencias de la vida común. Realmente, en el lenguaje natural1 dejamos mucho a la subjetividad de los hablantes y al contexto que se supone conocen ambos. Decimos que este tipo de lenguaje es informal mientras que el lenguaje que se usa en matemáticas o los lenguajes de programación son lenguajes formales. Distinguimos entre un objeto informal y uno formal porque este último está claramente definido y especificado por un conjunto de reglas. Uno de los atractivos del formalismo es el poder expresar ideas de forma concreta, breve y precisa. Pero no nada más nos interesan estos aspectos del formalismo sino su aplicación, la cual nos obliga a formalizar nuevas 1 Llamaremos ası́ al lenguaje que habla cualquier ser humano, en nuestro caso el español. 4 Introducción ideas o experiencias y, en este proceso, precisar y encontrar contradicciones que pudieran causar mucho daño, como en el caso de un programa de computadora que pudiese contener ambigüedades. Si nos referimos a un objeto de manera formal, podemos construir un modelo de ese objeto. Algunas de las ventajas de los modelos matemáticosson las siguientes: • Un modelo matemático es, por lo general, más preciso, entendible, conciso y riguroso que una descripción informal escrita en lenguaje natural. • A través de un modelo matemático podemos calcular directamente respuestas a problemas sobre el objeto modelado. • Las matemáticas, y en particular la lógica, nos proporcionan métodos de razonamiento: para manipular objetos, para demostrar propiedades de y sobre objetos, y para obtener resultados nuevos a partir de resultados ya conocidos, lo cual genera una extensión del conocimiento. Este último punto es, tal vez, uno de los aspectos más importantes de los modelos matemáticos, que tiene una enorme utilidad en ciencias de la computación: tener la seguridad cientı́fica de que algo funciona como esperamos; poder extender las posibilidades de una computadora, un lenguaje de programación o un algoritmo para usos distintos que para los que fue creado; en fin, para poder continuar con el impresionante desarrollo que han tenido las ciencias de la computación en este siglo. 1.1. Expresiones La lógica, y en particular la lógica matemática, juega un papel muy importante en el desarrollo de las matemáticas en general y de las ciencias de la computación en particular. En el ámbito de las ciencias de la computación es importante poder distinguir entre argumentos válidos o inválidos, es decir, entre aquellos que son sólidos lógicamente hablando y los que no lo son. La lógica presenta ciertos elementos de estudio que no son tan distintos a los que estamos acostumbrados en matemáticas. Durante muchos años hemos manipulado expresiones numéricas con incógnitas, es decir, ecuaciones con variables y constantes, para obtener un resultado final. Mientras que en el álgebra estamos trabajando con números fundamentalmente, en lógica trabajamos con proposiciones lógicas o simplemente proposiciones. Al igual que en álgebra, utilizamos variables (sı́mbolos que nos sirven para representar a los objetos elementales), constantes (true, false) y operadores, que también son sı́mbolos pero con un significado especial. Cuando tenemos una expresión aritmética hablamos de los operadores y operandos, entendiendo a los operadores como operaciones que se tienen que realizar, utilizando para 1.2 Mecanismos formales para descripción de expresiones 5 ello a los operandos. Los operadores pueden ser unarios, cuando utilizan o actúan sobre un único operando; binarios cuando actúan sobre dos operandos y, en general, n-arios2 cuando actúan sobre n operandos. Entre los operadores unarios aritméticos que conocemos está el signo de menos − y en algunas ocasiones también podemos considerar el signo de más + (nos tendremos que poner de acuerdo antes de empezar a cuál aceptamos y a cuál no). Entre los operadores binarios podemos mencionar a la multiplicación (que la podemos representar con · , × o con ∗ como se acostumbra en los lenguajes de programación), la división ( ÷ , / ). Un ejemplo de operador ternario puede ser entre(a, b, c) que decide cuál de los tres números a, b, c se encuentra entre los otros dos o el operador raı́ces(a, b, c) que devuelve las raı́ces del polinomio cuadrático ax2 + bx + c. Hay tres estilos para escribir expresiones, los cuales se distinguen por cómo se coloca al operador en relación a sus operandos. Si el operador es unario o n-ario únicamente tenemos dos opciones: Notación prefija: El operador se coloca antes del operando −a (+ a b c) Notación sufija o polaca: El operador se coloca después del operando a↑ (a b ∗) apuntador en Pascal Si el operador es binario, además de estas dos formas tenemos la que es más usual: Notación infija: Es aquella donde el operador se encuentra entre sus operandos. a+b 3 · (7 + 5) Las diferencias entre estas tres notaciones no son nada más de forma, pues cada una de ellas tiene propiedades particulares que veremos después. Por lo pronto, trabajaremos con la notación infija que, como ya mencionamos, es la más usual. Estas maneras de escribir expresiones tienen que ver con su sintaxis, término que se refiere a la forma que deben tener las cadenas de letras y sı́mbolos para que califiquen como expresiones bien construidas. Aún no hemos hablado del significado de una expresión, aunque pronto lo haremos. Los aspectos relacionados con el significado conforman la semántica de las expresiones. 2 Se lee “enario”. 6 Introducción 1.2. Mecanismos formales para descripción de expresiones Cuando describimos una expresión aritmética podemos hacerlo de varias maneras. Una de ellas es dando tantos ejemplos como podamos y dejando al lector que encuentre patrones que describan al mayor número posible de expresiones. Es claro que con este método no vamos a poder describir a todas las expresiones aritméticas posibles, ya que tenemos un número infinito de ellas. Una segunda manera es dando reglas para construir expresiones aritméticas correctas. Estas reglas de formación pertenecen, queremos insistir, a la sintaxis de las expresiones aritméticas. A continuación formalizamos reglas para construir expresiones aritméticas sencillas, para posteriormente contrastar con lo que es una expresión lógica: Definición 1.1 Una expresión aritmética es alguna de las que siguen: 1. Un objeto elemental: un número (una constante ) o una variable . 2. Si E es una expresión aritmética, (E) es una expresión aritmética. 3. Si ⊲ es un operador unario y E es una expresión aritmética, entonces ⊲E es una expresión aritmética. 4. Si ⋄ es un operador binario infijo y E y F son dos expresiones aritméticas, entonces E ⋄ F es una expresión aritmética. 5. Si ⋆ es un operador n-ario y E1 , E2 , . . . , En son expresiones aritméticas, entonces ⋆(E1 , E2 , . . . , En ) es una expresión aritmética. 6. Éstas y sólo éstas son expresiones aritméticas válidas. A primera vista esta definición parece incorrecta pues en algunas partes se utiliza el mismo concepto de expresión que se está definiendo. Esta clases de definiciones, llamadas definiciones recursivas, son omnipresentes en ciencias de la computación. Más adelante las estudiaremos con detalle. Estamos suponiendo que sabemos cuáles son los operadores unarios: + (positivo), − (negativo); cuáles los binarios: − (resta), + (suma), ×, ·, ∗ (multiplicación), ÷, ∗∗ (ˆ, exponenciación); y conocemos algunos n-arios: f (x1 , x2 , . . .), max(. . .), min(. . .) . . .. Veamos a continuación algunos ejemplos de construcción de expresiones aritméticas enfatizando su proceso de construcción. Ejemplo 1.1. Cada uno de los siguientes es un objeto elemental: a i x 3.0 1 7 1.2 Mecanismos formales para descripción de expresiones Por lo tanto también son expresiones aritméticas. Ejemplo 1.2. Considérese los siguientes operadores unarios, que representan el signo de un número en aritmética: + y −: −17 +a − reemplaza ⊲ y 17 es una expresión, por ser un número. + reemplaza a ⊲ y a es una expresión, por ser una variable. Podemos también ir encerrando en cuadrados contenidos uno dentro del otro, con una anotación de la regla a la que corresponden, a las distintas expresiones que conforman la expresión original. Cada rectángulo encierra a una expresión.Veamos a continuación: 3 3 1 − 1 + 17 a Ejemplo 1.3. Considérese los operadores binarios · y ÷. a ÷ (2 · b) a + (−b) ÷ y · son operadores binarios; a y (2 · b) son expresiones. + es un operador binario; a y (−b) son expresiones. 4 1 1 ÷ a 4 ( 4 a + ( b 2 3 1 1 • 2 1 − b 2 ) ) 8 Introducción Ejemplo 1.4. Supongamos que tenemos dos operadores, máx y mı́nn. máx(a · b, a + (−b), a ÷ b) máx es un operador n-ario con n = 3; a · b es una expre- sión; a + (−b) es una expresión. a ÷ b es una expresión. 5 4 máx( a 1 · 4 b 1 mı́n(1, máx(a + b, a − b, 3)) mı́n( 1 1 , , a 1 2 3 + ( − b 1 4 ) , a 1 ÷ b 1 ) mı́n es un operador n-ario con n = 2, es decir, binario; 1 es una expresión; máx(a + b, a − b, 3) es una expresión. a 1 5 4 + b 1 , a 1 4 − b 1 , 3 1 ) Ejemplo 1.5. La expresión −(a + (b · c)) es una expresión aritmética porque: • Como b y c son expresiones, por ser variables y · es un operador binario, entonces b · c es una expresión. • Como b · c es una expresión, entonces (b · c) es una expresión. • Como a y (b · c) son expresiones y + es un operador binario entonces a + (b · c) es una expresión. • Como a + (b · c) es una expresión, entonces (a + (b · c)) es una expresión. • Como (a + (b · c)) es una expresión y − es un operador unario, entonces −(a + (b · c)) es una expresión. 3 2 4 2 4 1 1 1 − ( a + ( b · c ) ) 9 1.3 Gramáticas y árboles de derivación Ejemplo 1.6. Observemos la expresión (a · b) − (4 · a cot b − 2 · b). • a y b son variables, por lo que a su vez son expresiones. • · es un operador binario, por lo que, junto con el inciso anterior, a · b es una expresión. • Como a · b es una expresión, también lo es (a · b). • Como 4 es una constante y a una variable, 4 · a es una expresión. Hasta acá vamos bien. Pero ninguna de nuestras reglas indica que cot sea un operador binario y no existe la posibilidad de que haya una sucesión de variables sin nada entre ellas. Por lo que ésta no es una expresión aritmética bien construida. Ejemplo 1.7. La expresión a · − + b es una expresión aritmética que utiliza el uso de las siguientes reglas para su construcción: • a es una expresión • b es una expresión • +b es una expresión pues b es una expresión y + es un operador unario. • − + b es una expresión pues +b es una expresión y − es un operador unario. • a · − + b es una expresión pues tanto a como − + b son expresiones y · es un operador binario. 4 1 a · 3 − + 3 1 b Ejemplo 1.8. La sucesión de sı́mbolos · − +a b no es una expresión aritmética correcta , pues no se puede obtener a partir de las reglas anteriores. ¿Por qué? De los ejemplos anteriores se observa que para mostrar que una sucesión dada de sı́mbolos s es una expresión aritmética, debemos identificar cada uno de sus componentes y asociarlos con alguna de las reglas de formación de expresiones. Este método puede resultar demasiado tedioso de aplicar por lo que debemos buscar métodos más sencillos y susceptibles de ser automatizados. 10 Introducción 1.3. Gramáticas y árboles de derivación Otra manera de mostrar cómo se construyen las expresiones es mediante lo que se conoce como una gramática formal, que es un mecanismo sencillo de especificación de reglas de construcción, llamadas producciones o reglas de reescritura, con las cuales se pueden generar expresiones de un lenguaje. Las formas que pueden tomar estas reglas de rescritura son muy variadas, pero nos ocuparemos sólo de una de éstas. Lass reglas de reescritura de las que nos ocuparemos tienen la siguiente forma: sı́mbolo ::= cadena El sı́mbolo “::=” se lee “se puede reescribir como” y al aplicar una regla particular sustituimos el lado izquierdo de este sı́mbolo por la cadena que se encuentra del lado derecho. Para las expresiones aritméticas, por ejemplo, tendrı́amos las reglas de reescritura que aparecen en la tabla 1.1. En ellas, los sı́mbolos que aparecen en gris o azul (con este tipo de letra) son aquellos que ya no pueden ser reescritos, pues no aparecen del lado izquierdo de ninguna regla de reescritura. A estos sı́mbolos les llamamos sı́mbolos terminales, pues son los que terminan las cadenas de reescritura. A los sı́mbolos que pueden ser reescritos les llamamos no terminales o variables. El sı́mbolo “|” juega el papel de separador de opciones, para ahorrar trabajo. Tabla 1.1 Reglas de reescritura para expresiones aritméticas S ::=E E ::=var E ::=const E ::= ⊲ E E ::=E ⋄ E E ::=(E) var ::=a | b | . . . const ::=0 | 1 | 2 | 17 | 3.5 | . . . ⊲ ::=+ | − ⋄ ::=+ | − | · | ÷ (1.1) (1.2) (1.3) (1.4) (1.5) (1.6) (1.7) (1.8) (1.9) (1.10) A una colección de reglas de reescritura como la anterior le llamamos gramática porque nos describe la forma o reglas sintácticas que deben tener las expresiones aritméticas bien construidas. Para producir “oraciones” (cadenas, palabras, expresiones) correctas de acuerdo a las reglas de la gramática, empezamos con el sı́mbolo a la izquierda del ::= de la 11 1.3 Gramáticas y árboles de derivación primera regla, y utilizamos las reglas de reescritura, que nos dicen que en cualquier momento podemos sustituir parte de (o toda) la expresión, si en ella localizamos una subexpresión3 que corresponda al lado izquierdo de cualquiera de las reglas y la sustituimos por el lado derecho. Cada vez que hacemos una sustitución, encontramos en la frase el primer sı́mbolo desde el extremo izquierdo que aparece a la izquierda de ::= de alguna de las reglas y lo sustituimos por la cadena a la derecha de ::= en esa regla. En cada paso únicamente sustituimos a un sı́mbolo. Decimos entonces que estamos haciendo una sustitución por la izquierda. Es importante mencionar que el orden en que se hagan las sustituciones no es obligatoriamente por la izquierda y no afecta el resultado final, aunque es bueno convenir en hacerlo por la izquierda en aras de obtener un método único de construcción, es decir un método determinista. Veamos algunos ejemplos en la figura 1.1 a continuación. Figura 1.1 Proceso de generación de expresiones aritméticas (1/2) −(a · (b + c)) Frase Regla usada S inicio (—) E S ::= E (1.1) ⊲E E ::= ⊲E (1.4) −E ⊲ ::=− (1.9) E ::=(E) (1.6) E ::= E ⋄ E (1.5) −(var ⋄ E) E ::= var (1.2) −(var · E) ⋄ ::=· −(E) −(E ⋄ E) −(var · (E)) (1.10) E ::=(E) (1.6) E ::= E ⋄ E (1.5) var ::=a (1.7) −(a · (var ⋄ E)) E ::= var (1.2) −(a · (var+ E )) ⋄ ::=+ −(var · (E ⋄ E)) −(a · (E ⋄ E)) −(a · (var+ var)) E ::= var S E E E E E var const ⊲ ⋄ ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= E (1.1) var (1.2) const (1.3) ⊲E (1.4) E⋄E (1.5) (E) (1.6) a|b| ... (1.7) 0 | 1 | 2 | 17 | 3.5 | . . . (1.8) +|− (1.9) +|−|·|÷ (1.10) (1.10) (1.2) −(a · (b+ var)) var ::=b (1.7) −(a · (b + c)) var ::=c (1.7) 3 Gramática: Una subexpresión es una expresión que aparece dentro de otra. Esto implica que debe estar bien construida. 12 Introducción Figura 1.1 Proceso de generación de expresiones aritméticas a Frase S E var a Regla usada inicio (—) S ::= E (1.1) E ::= var (1.2) var ::= a (1.7) (2/2) (3.0 + 21) Frase S E (E ) (E ⋄ E) (const ⋄ E ) (const + E ) (const + const ) (3.0+ const ) (3.0 + 21) Regla usada inicio (—) S ::= E (1.1) E ::=(E) (1.6) E ::= E ⋄ E (1.5) E ::= const (1.3) ⋄ ::=+ (1.10) E ::= const (1.3) const ::=3.0 (1.8) const ::=21 (1.8) Una secuencia de aplicación de reglas de reescritura, como las que se muestran en la figura 1.1 se conoce como una derivación de una expresión; esta expresión es la que figura en el último de sus renglones. Estas derivaciones pueden presentarse ası́ o gráficamente utilizando un árbol. Un árbol es una gráfica que remeda a un árbol biológico, excepto que elegimos pintarlo “de cabeza”. Nuestro árbol tiene un nodo inicial llamado raı́z, que corresponde al origen de las sustituciones, y va creciendo de la siguiente manera: • Cada nodo tiene un sı́mbolo asociado. • Para que de un nodo salgan flechas (o simplemente lı́neas o aristas, ya que la dirección es siempre hacia abajo) se requiere que el sı́mbolo que está en ese nodo aparezca del lado izquierdo de alguna producción. • Las flechas (o lı́neas) apuntan a cada uno de los sı́mbolos que aparecen del lado derecho de la producción utilizada. • Es importante observar que un nodo tiene un único sı́mbolo asociado. • Si el sı́mbolo en un nodo se reescribe en una sucesión de tres sı́mbolos, entonces deberán salir tres lı́neas de él, una por cada sı́mbolo. • Aquellos nodos de los que no salen lı́neas les llamamos hojas. • Para determinar cuál es la expresión que corresponde a un determinado árbol, vamos listando las hojas del árbol de izquierda a derecha. A la cadena que se obtiene de esta manera le vamos a llamar el resultado del árbol. En el árbol se pierde el orden en que se hacen las sustituciones; en cada nivel se muestran las sustituciones elegidas, de entre las posibles, en la frase que se encuentra en ese 13 1.3 Gramáticas y árboles de derivación nivel. Aquellos elementos que aparecen en gris (o en azul o con este tipo de letra) son los que no aparecen del lado izquierdo de ninguna regla y se encuentran colocados en las hojas del árbol. A estos sı́mbolos les llamamos sı́mbolos terminales y son los únicos que pueden aparecer en una expresión correcta. Los niveles intermedios no corresponden a expresiones, sino a descripciones de lo que puede convertirse en una expresión si se hacen los reemplazos necesarios. Veamos este proceso en las figuras 1.2 en esta página y 1.3 en la siguiente. Figura 1.2 Ejemplos de árboles de derivación (a) a (b) (3.0 + 21) S S E E var a ( ) E const ⋄ E 3.0 + const 21 En este contexto, decimos que una expresión aritmética está bien construida o que es correcta si podemos construir el árbol que representa a su derivación. Este proceso de construcción consiste de las sustituciones que fuimos realizando en cada nivel hasta llegar a un árbol donde todas sus hojas son sı́mbolos terminales. En otras palabras, una expresión aritmética es válida si es el resultado de algún árbol de derivación. Una vez que tenemos bien escrita una expresión aritmética, queremos obtener su valor. Éste se obtiene reemplazando cada una de las variables que aparecen en la expresión por algún valor permitido y realizando las operaciones correspondientes. Si la expresión es 14 Introducción aritmética, el resultado consistirá de algún número. Figura 1.3 Otro ejemplo de árbol de derivación (a) −(a · (b + c)) S E ⊲ − E ( ) E E ⋄ var · a E ( E ) E ⋄ E var + var b c Expresiones de paréntesis balanceados Como otro ejemplo del uso de gramáticas y árboles de derivación presentamos las expresiones de paréntesis balanceados. Este lenguaje es parte esencial de cualquier lenguaje de programación. La gramática que lo define se encuentra en la tabla 1.2. Tabla 1.2 Gramática que define a paréntesis bien balanceados E ::=() E ::=(E) E ::=EE (1.11) (1.12) (1.13) 15 1.3 Gramáticas y árboles de derivación Obsérvese que esta gramática produce expresiones que constan únicamente de paréntesis balanceados, no hay números ni otra clase de objetos que no sean paréntesis. La regla 1.11 corresponde a la expresión más simple de paréntesis balanceados () mientras que la regla 1.12 corresponde a encerrar entre paréntesis una expresión anterior. Por otra parte la regla 1.13 representa la generación de una nueva expresión con paréntesis balanceados al “pegar” o concatenar dos expresiones previas. Veamos un par de ejemplos. Figura 1.4 Expresiones de paréntesis balanceados (()) Frase E (E) (()) (()()) Regla usada inicio (—) E ::=(E ) (1.12) E ::=() (1.11) Frase E (E) (EE ) (()E) (()()) Regla usada inicio (—) E ::= (E) (1.12) E ::= EE (1.13) E ::= () (1.11) E ::= () (1.11) Figura 1.5 Ejemplos de árboles de derivación para expresiones de paréntesis balanceados (a) (()) (b) ((())()) E E ( ) E ( ( ) E ) E ( E ) E ( ) ( ) 16 Introducción Ejercicios 1.3.1.- Dadas las producciones para construir expresiones aritméticas, para cada una de las siguientes expresiones decir si se pueden o no construir con esas producciones. Justifica tu respuesta. a) − + −a b) 2(b · b) c) 1 (a 2 + b) 1.3.2.- Usando la gramática que dimos para expresiones aritméticas, dibujar los árboles que corresponden a cada una de las expresiones que siguen: a) −a · b + c b) (−b + (b · b − 4 · a · c)) ÷ (2 · a) c) −a + b 1.3.3.- Dadas las expresiones aritméticas del ejercicio 1.3.2, da la secuencia de producciones que usas, haciendo siempre la sustitución por la izquierda. 1.3.4.- Dada las siguientes producciones: S S S S ::= ::= ::= ::= aSb ab bSa ba (1.14) (1.15) (1.16) (1.17) Da 3 expresiones que se puedan derivar de esta gramática. 1.3.5.- Para cada uno de los árboles de la figura 1.6, da las producciones que tuvieron que utilizarse para construirlos: 17 1.3 Gramáticas y árboles de derivación Figura 1.6 Ejercicio 1.3.5 (b) 145 × 541 (a) 01001 C S 1 C 1 4 C 4 5 C 5 S 0 S 1 S 0 × S 0 1 (c) Juan y Pedro van al cine orac suj compl verbo sust conj sujto Juan y sust Pedro van prep a fs art sust el cine 1.3.6.- Para cada uno de los árboles del ejercicio 1.3.5, da otras dos expresiones o frases distintas a la dada que se puedan construir usando las mismas producciones. Lógica proposicional 2 2.1. El lenguaje de la lógica proposicional En esta sección nos dedicamos a definir la sintaxis y semántica del lenguaje formal de la lógica proposicional, empezando con una discusión acerca de argumentos lógicos. 2.1.1. Argumentos lógicos Uno de los aspectos más importantes de la lógica matemática es el decidir si un argumento es correcto o no. Entre nuestros objetivos está el de utilizar la lógica como una herramienta para evidenciar o (deducir) la solidez o correctud de un argumento lógico. Pero para empezar debemos contestar ¿qué es un argumento lógico? En general un argumento o argumentación se da en lenguaje natural presentando ciertos hechos – “alegatos”, verdades, situaciones – ası́ como una conclusión que, si la argumentación es correcta, debe ser evidente de los hechos anteriores a los cuales llamamos premisas. Veamos algunos ejemplos: Si llueve, me quedo en casa. Si me quedo en casa, leo un libro. Por lo tanto, si llueve, leo un libro 20 Lógica proposicional Si me gusta el curso, pongo atención; si pongo atención, entiendo el material. Luego entonces, si me gusta el curso, entiendo el material x es mayor o igual que y o bien x es menor que y. x no es mayor o igual que y. De manera que x es menor que y Ahora bien, ¿cómo distinguimos entre las premisas y la conclusión del argumento? Esto depende de ciertas frases del lenguaje natural que nos dan la pauta para hacer la distinción, frases como por lo tanto, luego entonces, de manera que, etc. Una vez identificadas la conclusión y las premisas se puede reescribir el argumento de una forma estructurada omitiendo ciertas frases del lenguaje natural, como en los siguientes ejemplos: (a) 1. Si llueve, me quedo en mi casa 2. Si me quedo en mi casa, leo un libro 3. Si llueve, leo un libro (b) 1. Si me gusta el curso, pongo atención 2. Si pongo atención, entiendo el material 3. Si me gusta el curso, entiendo el material (c) 1. x es mayor o igual que y o bien x es menor que y 2. x no es mayor o igual que y 3. x es menor que y (d) 1. Los libros son baratos o son caros 2. Los libros no son caros 3. Los libros son baratos (e) 1. Este programa funciona mal o los datos son incorrectos 2. Los datos son correctos 3. Este programa funciona mal Obsérvese que la conclusión está separada de las premisas mediante una lı́nea horizontal. Además, de acuerdo a nuestra intuición, todos los argumentos anteriores parecen correctos, pero formalmente ¿cuándo un argumento es correcto? o ¿cómo decidimos si un argumento es correcto?. Para responder a esta pregunta nos serviremos de la lógica matemática, la cual nos proporcionará un conjunto de reglas operacionales, que en particular permitirán obtener – deducir, encontrar, conformar, derivar – un nuevo hecho a partir de ciertos hechos dados. Un argumento lógico será correcto o sólido si la verdad de sus premisas causan necesaria y obligatoriamente la verdad de su conclusión, lo cual puede 21 2.1 El lenguaje de la lógica proposicional mostrarse mediante las reglas lógicas de operación. Aristóteles fue el primero que para poder manipular argumentos lógicos optó por asignarles letras a ciertas frases consideradas de estructura lógica simple, llamadas proposiciones o fórmulas atómicas. De esta manera podemos ver en forma concisa los argumentos lógicos. Procedamos a hacer esto con los argumentos anteriores para poderlos mostrar a la manera aristotélica. (b) p Me gusta el curso (a) p llueve q pongo atención q me quedo en mi casa r entiendo el material r leo un libro (c) 1. 2. Si p, q Si q, r 1. 2. Si p, q Si q, r 3. Si p, r 3. Si p, r p q r x es mayor y x es igual a y x es menor que y p q Los libros son baratos Los libros son caros (d) 1. p o q 2. no q 1. p o q o r 2. no (p o q) 3. p 3. r (e) p Este programa funciona mal q Los datos son correctos 1. p o no q 2. q 3. p Se observa que el uso de letras deja ver patrones o esquemas comunes, aunque aún tenemos algunas palabras del español. Para deshacernos de ellas y formalizar completamente el estudio de argumentos lógicos introducimos ahora el lenguaje formal de la lógica proposicional. Observen que en el inciso (c), cuando decimos “no (p o q)” estamos manifestando “ni p ni q”. 2.1.2. Proposiciones De manera similar a como construimos expresiones aritméticas, vamos ahora a definir y construir expresiones lógicas. Empecemos por ver cuáles son los objetos elementales de la lógica. En la aritmética tenı́amos valores numéricos (constantes) y de forma similar 22 Lógica proposicional la lógica tiene constantes, pero sólo dos: 0 (falso) y 1 (verdadero). Estas constantes se conocen como valores lógicos o booleanos. Usar los valores de 0 y 1 como sinónimos de falso y verdadero es una libertad que nos damos las personas dedicadas a computación. También podemos hablar de los valores F y T (false y true respectivamente), aunque a lo largo de este texto usaremos 0 y 1 pues es ası́ como se van a representar en la computadora. Las expresiones lógicas se conocen también como proposiciones y son enunciados u oraciones a las que les podemos asociar un valor lógico (tienen valor de 0 o 1). En general las proposiciones se dan en lenguaje natural; un enunciado es una proposición solamente si se puede decir, en un contexto dado, si es falso o verdadero. En el ejemplo (a) que acabamos de dar, la proposición p=llueve es falsa o verdadera dependiendo del momento en que se diga, de si en ese momento está lloviendo o no. Cuando decimos que una proposición es falsa o verdadera, estamos determinando el valor de dicha proposición. De manera similar para las expresiones aritméticas, podemos hablar del valor de la expresión aritmética, que nos va a dar una constante numérica calculada a partir de los valores de cada una de las variables y constantes involucradas en la expresión. A este conjunto de valores le llamamos el estado en el que se evalúa la expresión – a lo que anteriormente llamamos el contexto de una proposición –. Podemos definir entonces un estado como un conjunto de parejas, donde cada pareja tiene el nombre de una variable y el valor de esa variable. Un ejemplo de cómo especificamos un estado se encuentra a continuación.  estado = (x, 5), (y, 7), (p, f also) En este estado tenemos los valores para tres variables, dos numéricas y la tercera lógica. Cada elemento del conjunto es una pareja ordenada, donde primero se da el nombre de la variable y después el valor de esa variable en el estado. Regresando a las expresiones lógicas, son proposiciones: ✌ Está lloviendo ✌ Juan es más grande que Pedro ✌ x≥z ✌ El libro es rojo ✌ Roberto es el asesino ✌ Esta materia es fácil ☞ ☞ ☞ ☞ No son proposiciones: ¡Mario, llévate esto! ¿Estás seguro? x+y Ni modo 2.1 El lenguaje de la lógica proposicional 23 ☞ ¡Viva Pancho Villa! Intuitivamente a las proposiciones se les puede evaluar, es decir, decidir si son falsas o verdaderas. Pero como mencionamos antes, este valor depende del estado que tomen sus variables. Por ejemplo, la tercera proposición de la lista que dimos es verdadera si el estado es {(x, 5.6), (z, 3.0)}. En este estado particular, la proposición tiene el valor de verdadero. Evaluada en el estado {(x, 2.3), (y, 4.0)} la proposición tiene el valor de falso. La cuarta proposición tendrá el valor de verdadero en el caso de que el libro de que estemos hablando sea rojo, es decir cuando estemos en el estado {(color del libro, rojo)}. Más adelante hablaremos formalmente de estados y del proceso de evaluación. Por ahora sigamos con el estudio de las proposiciones Definición 2.1 Una proposición es un enunciado que puede calificarse como falso (0) o verdadero (1), dependiendo del estado en que se evalúe. Decimos que una proposición es atómica si no puede subdividirse en proposiciones más simples. Las proposiciones anteriores son todas atómicas. En contraste, las siguientes proposiciones no son atómicas: ☞ ☞ ☞ ☞ Juan y Pedro están hambrientos Está nublado, por lo que va a llover, entonces no saldremos 0 ≤ x ≤ 10 El libro es rojo o azul Estas proposiciones se llaman compuestas pues cada una de ellas se puede descomponer en dos o más proposiciones atómicas como a continuación se muestra: • Juan y Pedro están hambrientos ☞ Juan está hambriento y ☞ Pedro está hambriento • Está nublado, por lo que va a llover; entonces no saldremos ☞ Está nublado, por lo que ☞ va a llover entonces ☞ no saldremos 24 Lógica proposicional • 0 ≤ x ≤ 10 ☞ 0≤x y ☞ x ≤ 10 • El libro es rojo o azul ☞ el libro es rojo o ☞ el libro es azul Las proposiciones atómicas son aquellas que están a continuación de ☞ y hasta el final del renglón. Encerramos en un marco a la palabra o frase que relaciona a la primera proposición atómica con la siguiente y ası́ sucesivamente. A estas palabras les llamamos conectivos. A continuación vamos a pasar de las proposiciones en lenguaje natural al estudio de un lenguaje formal de expresiones lógicas. En el proceso de traducción o especificación de lenguaje natural al formal se acostumbra asociar identificadores (letras) a las proposiciones atómicas, para poder escribir de manera más fluida y ası́ representar y manipular adecuadamente a las proposiciones. Obsérvese que esto ya lo hicimos en la semi formalización de argumentos en la introducción de este capı́tulo. A estos identificadores se les conoce como variables proposicionales. Ya tenemos entonces variables, pero para construir expresiones más complejas necesitamos de constantes y operadores lógicos y que corresponden estos últimos a las frases en lenguaje natural que hemos llamado conectivos. 2.1.3. Sintaxis de la lógica proposicional En esta sección definimos un lenguaje formal para la lógica proposicional mediante una gramática para expresiones lógicas. Las reglas para construir proposiciones son las siguientes: 25 2.1 El lenguaje de la lógica proposicional P ::=V arP rop P ::= ConstLog P ::= ⊲P P ::= P ⋄ P P ::= (P ) V arP rop ::= a, b, . . . p, q, . . . ConstLog ::= false, true ⊲ ::= ¬ ⋄ ::= ∧, ∨, →, ↔ variables proposicionales constantes lógicas negación (not) y, además, pero (and) o (or) implica, si . . . entonces, por lo que, de. . . se sigue (implies) si y sólo si, sii, syss, iff (if and only if ) (2.1) (2.2) (2.3) (2.4) (2.5) (2.6) (2.7) (2.8) (2.9) (2.10) (2.11) (2.12) (2.13) Veamos ahora el paso del español al lenguaje formal de proposiciones mediante algunos ejemplos. Considérese la siguiente asignación de significados a variables proposicionales: Proposición atómica Juan está hambriento Pedro está hambriento está nublado va a llover saldremos 0<x x < 10 el libro es rojo el libro es azul Variable proposicional a b c d e p q r s Las proposiciones no atómicas de los ejemplos anteriores son representadas de la siguiente manera: • Juan y Pedro están hambrientos a∧b • Está nublado por lo que va a llover; entonces no saldremos 26 Lógica proposicional (c → d) → ¬ e • 0 < x < 10 p∧q • El libro es rojo o el libro es azul r∨s Veamos ahora el árbol de derivación para alguna de estas expresiones, digamos (c → d) → ¬ e, en la figura 2.1. Figura 2.1 Derivación de (c → d) → ¬e P ⋄ P ( P ) P ⋄ P V arP rop → V arP rop c → P ⊲ P ¬ V arP rop e d Nuevamente, los sı́mbolos terminales están en distinto tipo y color. 2.1.4. Semántica de la lógica proposicional Una vez que hemos discutido informalmente qué es una proposición ası́ como la sintaxis de un lenguaje formal para proposiciones, es momento de hablar de su significado. Los aspectos relacionados con el significado de cualquier clase de expresiones forman lo que se conoce como la semántica del lenguaje. En nuestro caso ya conocemos el significado intuitivo de las proposiciones, de hecho le hemos dado a los operadores lógicos un nombre relativo a su significado. Por ejemplo la proposición ¬p se lee “no p” y representa a la negación de la información especificada por p. En analogı́a a las expresiones aritméticas cuyo significado es un número, calculado al hacer las operaciones dadas en la expresión de acuerdo a un estado particular de sus variables, cada proposición tiene como significado 27 2.1 El lenguaje de la lógica proposicional un valor booleano que depende tanto del valor particular de sus variables proposicionales como del significado de las constantes y operadores lógicos. De manera que para poder entender el significado de una proposición debemos empezar por definir el significado o funcionamiento de cada constante u operador lógico. El significado de las constantes lógicas debe ser claro, la constante true significa verdadero (1) y la constante false significa falso (0). La manera más fácil para definir el significado de un operador lógico es mediante lo que se conoce como tablas de verdad. En lo que sigue se usan mayúsculas para denotar proposiciones que pueden ser compuestas. A continuación analizamos cada operador lógico. La negación La negación de una proposición P se denota de alguna de las siguientes formas: ¬P, ∼ P, P , P ′ Nosotros usaremos ¬P exclusivamente. Su significado en español es: ¬P no P no es cierto que P es falso que P Su tabla de verdad es: negación P ¬P 1 0 0 1 Este tipo de tablas merece algunas observaciones. Para calcular la tabla de verdad de una proposición cualquiera E es necesario considerar todos los estados posibles de los operandos de la expresión E. Cada operando puede estar en uno de dos estados posibles, 1 para verdadero y 0 para falso. Cada renglón de la tabla corresponde a un estado particular de los operandos. En este caso nuestra expresión es ¬P , que tiene como único operando a P , que independientemente de que sea una proposición atómica o no, sólo puede estar en dos estados posibles, por lo que la tabla de verdad sólo tiene dos renglones. En esta tabla, la primera columna es la que indica el estado del operando P mientras que la segunda nos indica el resultado de la evaluación de la expresión deseada, en este caso ¬P . Como se ve en la tabla anterior, el operador ¬ lo que hace es “invertir” o negar el valor original de la proposición dada. Veamos a continuación la semántica de los operadores lógicos binarios. 28 Lógica proposicional La conjunción La conjunción de dos proposiciones P y Q se denota de alguna de las siguientes formas: P ∧ Q, P & Q, P · Q, P Q Nosotros usaremosenP español ∧ Q exclusivamente. Su significado es: P ∧Q P y Q P además de Q P pero Q Puede observarse aquı́ cierta incapacidad de la lógica para representar al español: ciertamente al usar la palabra pero se le está dando cierta intensión a una afirmación que no corresponde a la simple conjunción, como en la frase Te llevo al cine, pero haces la tarea, la cual sólo puede representarse con una conjunción que corresponde a Te llevo al cine y haces la tarea. Desafortunadamente, en lógica la única posibilidad para representar un pero es la conjunción. Su tabla de verdad es: P Q Conjunción P ∧Q 1 1 0 0 1 0 1 0 1 0 0 0 En esta ocasión, al haber dos operandos (P y Q), tenemos cuatro posibles estados para el sistema: • Que ambas proposiciones valgan 1 • Que P valga 0 y Q valga 1 • Que P valga 1 y Q valga 0 • Que ambas proposiciones valgan 0 29 2.1 El lenguaje de la lógica proposicional La disyunción La disyunción de dos proposiciones P y Q se denota de alguna de las siguientes formas: P ∨ Q, P | Q, P + Q Nosotros usaremos P ∨ Q exclusivamente. Su significado en español es: P ∨Q P o Q oP o Q Su tabla de verdad es: P Q Disyunción P ∨Q 1 1 0 0 1 0 1 0 1 1 1 0 Observando el primer renglón de la tabla de verdad nos damos cuenta de que este uso de la disyunción es inclusivo, es decir, la disyunción es cierta también en el caso en que ambos operandos sean ciertos. La implicación La implicación o condicional de dos proposiciones P y Q se denota de alguna de las siguientes formas: P → Q, P ⇒ Q, P ⊃ Q Nosotros usaremos P → Q exclusivamente. Su significado en español es: 30 Lógica proposicional P →Q si P entonces Q P implica Q P es (condición) suficiente para Q Q, si P P sólo si Q Q se sigue de P Q es (condición) necesaria para P Su tabla de verdad es la que sigue: P Q Implicación o condicional P →Q 1 1 0 0 1 0 1 0 1 0 1 1 Nos sorprende en esta tabla la evaluación del primer y segundo renglones, pues parece, a primera vista, contrario a la intuición. Veamos un ejemplo: Ejemplo 2.1. p q es es una botella contiene ácido la botella tiene una calavera en la etiqueta p→q es si una botella tiene ácido, entonces tiene una calavera en la etiqueta Como se ve en este ejemplo, la verdad de p (que la botella contenga ácido) nos permite garantizar la verdad de q (que hay una calavera en la etiqueta). Pero si la botella no contiene ácido, pudiera ser que la botella contenga algún otro compuesto venenoso y que de todos modos tenga una calavera en la etiqueta, estado representado por el tercer renglón de la tabla; pero también pudiera ser que la botella no tenga ácido y que no tenga calavera en la etiqueta, estado representado por el último renglón de la tabla. Lo que no puede suceder (el resultado es 0) es que la botella, conteniendo ácido no tenga una calavera en la etiqueta, estado representado por el segundo renglón de la tabla. 2.1 El lenguaje de la lógica proposicional 31 Veamos otro ejemplo, esta vez en matemáticas. Considérese la siguiente proposición1 : ((x > y) ∧ (y > z)) → (x > z) Evaluemos esta expresión en el estado {(x, 8), (y, 6), (z, 4)}.  En este estado, el antecedente de la implicación es verdadero (8 > 6) y (6 > 4) , por lo que podemos garantizar que x > z, pues en efecto, 8 > 4. Sin embargo, veamos que sucede en el estado {(x, 7), (y, 8), (z, 6)}. En este caso el antecedente es falso pero el consecuente es verdadero. El valor de la proposición es, de acuerdo a la definición en su tabla de verdad, verdadero. Otro estado que ilustra el primer caso es {(x, 4), (y, 6), (z, 5)}. También este estado hace que la proposición se evalúe a verdadero, porque una vez que el antecedente es falso, el estado del consecuente puede ser cualquiera. Por otra parte, si el antecedente es verdadero, no puede suceder que el consecuente sea falso, es decir, no existe un estado en el cual (x > y) y (y > z) y que sin embargo tengamos (x ≤ z). Los valores de verdadero y falso de la implicación simplemente nos dicen cuáles estados pueden presentarse y cuáles no. En el primer ejemplo que dimos, si llueve es seguro que me quedo en casa, pero si no llueve, el estado del consecuente puede ser cualquiera. Recordemos que sólo hay dos estados posibles para las proposiciones lógicas, falso o verdadero. Cada implicación P → Q tiene asociadas otras implicaciones que involucran a las mismas proposiciones P y Q que a continuación definimos: • La recı́proca o inversa de P → Q es la fórmula Q → P . • La contrapositiva de P → Q es la fórmula ¬Q → ¬P . • La contrarrecı́proca de P → Q es la fórmula ¬P → ¬Q Ejemplo 2.2. Considérese la oración si tengo un triángulo entonces tengo un polı́gono, formalizada como t → p. Sus implicaciones asociadas son: • Recı́proca: p → t que significa si tengo un polı́gono entonces tengo un triángulo. • Contrapositiva: ¬p → ¬t que significa si no tengo un polı́gono entonces no tengo un triángulo. • Contrarrecı́proca: ¬t → ¬p que significa si no tengo un triángulo entonces no tengo un polı́gono Más adelante veremos la relación existente entre una implicación y sus implicaciones asociadas. 1 Usamos aquı́ tantos paréntesis como se requieran para definir sin ambigüedades la estructura de la expresión lógica. 32 Lógica proposicional La equivalencia La equivalencia o bicondicional de dos proposiciones P y Q se denota de alguna de las siguientes formas: P ↔ Q, P ⇔ Q, P ≡ Q Nosotros usaremos P ↔ Q exclusivamente. Su significado en español es: P ↔Q P si y sólo si Q P es equivalente a Q P es (condición) necesaria y suficiente para Q Su tabla de verdad es: P Q Equivalencia o bicondicional P ↔Q 1 1 0 0 1 0 1 0 1 0 0 1 En este caso, la equivalencia es verdadera si ambas proposiciones se evalúan a lo mismo: ambas se evalúan a falso o ambas se evalúan a verdadero. Tablas de verdad para proposiciones compuestas Al conocerse el significado de cada conectivo lógico mediante su tabla de verdad es posible obtener el significado de cualquier fórmula mediante una tabla de verdad que combine las tablas de cada subfórmula componente de la fórmula original. Veamos un ejemplo. 33 2.1 El lenguaje de la lógica proposicional P Q R (P → ¬Q) ∨ (Q ∧ ¬R) → (¬P ↔ R) 0 0 0 1 0 0 0 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 Como se observa, las tablas de verdad crecen tanto en columnas como en renglones, al volverse más compleja la fórmula en cuestión. ¿Cuántos renglones tiene la tabla de verdad de una fórmula que tiene n variables proposicionales? Propiedades de los conectivos lógicos Vimos en las secciones anteriores lo que constituye una proposición, ası́ como el significado de los principales operadores o conectivos lógicos. De conocer las tablas de verdad para estos conectivos, podemos observar algunas de sus propiedades importantes. Conmutatividad: Esta propiedad nos dice que el orden en que aparecen las proposiciones relacionadas por el conectivo lógico no afecta el resultado de la operación. Por ejemplo, la evaluación de p ∧ q da siempre el mismo resultado que la evaluación de q ∧ p. Esta propiedad la tienen asimismo los operadores aritméticos de suma y multiplicación. De las expresiones aritméticas sabemos, por ejemplo, que ni la resta ni la división son operadores conmutativos: No es lo mismo 7 − 5 que 5 − 7; tampoco se evalúa a lo mismo 8 ÷ 2 que 2 ÷ 8. También en el caso de los conectivos lógicos no todos son conmutativos. Los conectivos ∨, ∧, ↔ son conmutativos pues: El valor de: es el mismo que el de: p∨q p∧q p↔q q∨p q∧p q↔p De su tabla de verdad es fácil ver que la implicación (→) no es conmutativa. Asociatividad: En aritmética es claro que (a + b) + c = a + (b + c). Decimos entonces que la suma es asociativa. En el caso de los conectivos lógicos no todos tienen esta 34 Lógica proposicional propiedad llamada asociatividad. Mientras que en la aritmética la suma y la multiplicación son asociativos, esto no es ası́ con la resta y la división. Por ejemplo, en el estado {(a, 5), (b, 7), (c, 3)}, a − (b − c) = 1, mientras que (a − b) − c = −5. También, (a ÷ b) ÷ c = 5/21 ≈ 0.24, mientras que a ÷ (b ÷ c) = 15/7 ≈ 2.1. En el caso de la lógica matemática los conectivos que son asociativos son la conjunción (∧), la disyunción (∨ ) y la equivalencia (↔). Nuevamente, la condicional (→) tampoco presenta esta propiedad. El valor de: es el mismo que el de: (p ∧ q) ∧ r (p ∨ q) ∨ r (p ↔ q) ↔ r p ∧ (q ∧ r) p ∨ (q ∨ r) p ↔ (q ↔ r) Elemento identidad: En general, un elemento identidad para un operador ⋆ es aquel valor que al operarlo con una expresión el resultado es esa misma expresión, es decir e es una identidad para ⋆ si e ⋆ x = x = x ⋆ e para cualquier expresión x. (Noten que estamos suponiendo la conmutatividad del operador con respecto al elemento identidad y cualquier otro elemento.) En el caso de la suma, el elemento identidad es el 0 puesto que a + 0 = a = 0 + a, mientras que en el caso de la multiplicación el elemento identidad es el 1 ya que a · 1 = a = 1 · a. Como se ve, el elemento identidad va a depender del operador o conectivo particular. En el caso de los conectivos lógicos, los elementos identidad de cada operador se dan a continuación. Para ver que, en efecto, son elementos identidad, sugerimos desarrollar las tablas de verdad correspondientes. Operador Identidad El valor de es el valor de ∧ ∨ ↔ true false true p ∧ true p ∨ false p ↔ true p p p Elemento neutro: También conocido como dominante, es aquella constante que al operar con cualquier otro valor, el resultado es la constante misma. Es decir, e es un elemento neutro para el operador ⋆ si x ⋆ e = e = e ⋆ x para cualquier expresión x. En el caso de la aritmética, el 0 (cero) con el producto tiene ese efecto. Hay que notar que la suma, la resta y la división no tienen elemento neutro (el elemento nulo tiene que ser el mismo para todos los valores que puedan participar en la operación). En el caso de las proposiciones lógicas, el elemento neutro de la disyunción (∨) es la constante true y de la conjunción (∧) es la constante false. 35 2.1 El lenguaje de la lógica proposicional El valor de: es el valor de: p ∨ true true p ∧ false false Idempotencia: Esta propiedad habla de un operador que al tener dos operandos iguales el resultado es el operando mismo. Por ejemplo, si tenemos la proposición p ∧ p podemos observar de la tabla de verdad, que su valor es el mismo que el de p. Los operadores ∧ y ∨ son idempotentes: p p∧p p∨p 1 1 1 0 0 0 Para la implicación hay otras proposiciones interesantes que vale la pena notar. Se caracterizan porque al operar con la constante false o true dan siempre como resultado el valor de 1: p false → p p → true 2.1.5. 1 1 1 0 1 1 Tautologı́as y contradicciones Las tablas de verdad nos permiten observar el valor de una fórmula en todos sus posibles estados. Esto nos permite clasificar a las fórmulas de la siguiente manera: tautologı́as Aquellas fórmulas que se evalúan a verdadero en todos los estados posibles contradicciones Aquellas fórmulas que se evalúan a falso en todos los posibles estados fórmulas contingentes o contingencias Aquellas fórmulas que no son ni tautologı́as ni contradicciones Conocemos ya varias tautologı́as, como es el caso de p∨¬ p , p → p∨q , p∧p ↔ p . Para convencernos, veamos sus tablas de verdad en la siguiente página: 36 Lógica proposicional p q 1 1 0 0 1 0 1 0 p∨¬p ∨ ¬ 1 1 1 1 0 0 1 1 p→p∨q → ∨ 1 1 1 1 1 1 1 0 p∧p↔p ∧ ↔ 1 1 0 0 1 1 1 1 Como las tautologı́as son muy importantes, se elige una notación especial para representarlas. Para ello utilizamos un metalenguaje, el cual nos sirve para decir algo respecto al lenguaje formal que estamos utilizando. Ya nos encontramos con metalenguajes con anterioridad. Por ejemplo, nuestras gramáticas con sus producciones corresponden a un metalenguaje, ya que si bien nos describen perfectamente lo que es una expresión, las producciones en sı́ no son expresiones. Podemos pensar también en los esquemas de fórmula que utilizamos (E, P ∨ Q, A → B, etc.) como metaexpresiones , ya que los usamos para describir a objetos de nuestro lenguaje particular, pero ellos no forman parte del lenguaje. Más adelante hablaremos de esquemas con más detalle. Volviendo al cálculo proposicional, si A es una proposición que es tautologı́a, escribimos |= A. Insistimos en que el sı́mbolo |= no es un operador de la lógica proposicional y la expresión |= P no es una proposición, sino que nos habla acerca de la proposición P , diciéndonos que P es una tautologı́a. Como ejemplos de tautologı́as de gran importancia tenemos: p∨¬p Ley del tercero excluido, nos dice que toda proposición tiene que evaluarse a falso o verdadero, que no hay ningún otro valor posible. false → p Falso implica cualquier cosa. Cuando el antecedente es falso, se puede concluir cualquier proposición. p → true Cuando el consecuente es verdadero, cualquier proposición lo implica (lo “justifica”). Contradicciones Una contradicción es una expresión que se evalúa a falso en todos los estados posibles. Podemos cotejar que una expresión es una contradicción utilizando para ello tablas de verdad, como en el caso de las tautologı́as. Por ejemplo, P ↔ ¬ P y P ∧ ¬P son ambas contradicciones, como se muestra en las tablas de verdad correspondientes. 37 2.1 El lenguaje de la lógica proposicional P ¬P P ↔¬P P ∧¬P 1 0 0 0 0 1 0 0 Las contradicciones están ı́ntimamente relacionadas con las tautologı́as. Si A es una tautologı́a, entonces ¬ A es una contradicción y viceversa. 2.1.6. Argumentos correctos Una vez que hemos definido la sintaxis y la semántica de las fórmulas de la lógica proposicional, ası́ como el concepto de tautologı́a, podemos dar la definición formal de argumento lógico e introducir formalmente la noción de argumento correcto. Definición 2.2 Un argumento lógico es una sucesión de fórmulas A1 , . . . , An llamadas premisas y una fórmula B llamada conclusión. Dicha sucesión se escribe usualmente como A1 .. . An ∴B o bien A1 , . . . , An / ∴ B Nuestro problema fundamental es decidir cuándo un argumento es correcto o válido, lo cual sucederá, como ya mencionamos anteriormente, si y sólo si suponiendo que sus premisas son verdaderas, entonces necesariamente la conclusión también lo es. Obsérvese que esta definición corresponde a los llamados argumentos deductivos. En contraste, en un argumento inductivo se aceptan como válidas conclusiones basadas en observación o probabilidad. Nosotros nos dedicaremos sólo a los argumentos deductivos. Como ya tenemos a nuestra disposición la definición de tautologı́a, nos servimos de ésta para dar una definición formal de argumento correcto. Definición 2.3 El argumento A1 , A2 , . . . , An / ∴ B es correcto si y sólo si |= A1 ∧ A2 . . . An → B. A la fórmula A1 ∧ A2 . . . An → B se le llama fórmula asociada al argumento lógico. 38 Lógica proposicional Por lo tanto, verificar la correctud de un argumento es equivalente a verificar que su fórmula asociada es tautologı́a, para lo cual basta construir su tabla de verdad. Veamos algunos ejemplos Ejemplo 2.3. El argumento p → q, p/ ∴ q, es correcto. La fórmula a analizar es p ∧ (p → q) → q. p q p ∧ (p → q) → q 1 1 1 1 1 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 1 1 Como muestra la tabla, tenemos una tautologı́a y el argumento es correcto. Ejemplo 2.4. Analizar el siguiente argumento. Si hoy es viernes entonces mañana es sábado; mañana es sábado, por lo tanto hoy es viernes. Frases como “por lo tanto”, “ası́ que”, “luego entonces”, “de forma que”, entre otras, señalan la conclusión del argumento. La representación formal del argumento es: v→s s ∴v De manera que el argumento es correcto si y sólo si |= (v → s) ∧ s → v. La tabla de verdad es: v s (v → s) ∧ s → v 1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 0 El tercer renglón de la tabla muestra que la fórmula no es una tautologı́a por lo que el argumento es incorrecto. 39 2.1 El lenguaje de la lógica proposicional Ejemplo 2.5. Mostrar la correctud del siguiente argumento: p∧q →r p ∴q→r La tabla de verdad de la fórmula asociada al argumento es: p q r (p ∧ q → r) ∧ p → (q → r) 1 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 1  Por lo que |= (p ∧ q) → r ∧ p → (q → r) y el argumento es correcto. El ejemplo anterior deja ver que el método de tablas de verdad para mostrar la correctud de un argumento puede resultar complicado al crecer el número de variables involucradas en el mismo. Por esta razón resulta mandatorio buscar métodos alternativos, cosa que haremos más adelante. Ejercicios 2.1.1.- ¿Cuáles de las siguientes oraciones son proposiciones atómicas, cuáles proposiciones no atómicas y cuáles no son proposiciones? Justifica tu respuesta. a) El cielo está nublado b) Por favor ven a verme √ −b ± b2 − 4ac c) 2a d) 0 ≤ x ≤ 10 e) Juan y Pedro van al cine f ) Estoy a dieta porque es necesario para bajar de peso 40 Lógica proposicional 2.1.2.- Expresa los siguientes enunciados en el lenguaje de la lógica proposicional: a) b) c) d) e) Un triángulo equilátero tiene sus tres ángulos iguales. Siempre que come fresas le da alergia. 0 ≤ x ≤ y ≤ 15 Todo número par es divisible entre 2. Para que vayas al cine tienes que hacer tu tarea. 2.1.3.- Usa variables proposicionales p, q y r para formalizar los siguientes argumentos lógicos. Lista cómo asignas las variables a las proposiciones atómicas. a) Si hay exámenes cada semana, los estudiantes se quejan; y si no hay exámenes cada semana, los estudiantes se quejan; de cualquier forma los estudiantes se quejan. b) Si n es número primo, no puede ser divisible entre 2; sabemos que 24 es divisible entre 2, por lo que no es número primo. c) Si lo mató, fue un crimen pasional; y si es un crimen pasional, el asesino sale corriendo; sabemos que ella no salió corriendo; entonces no lo mató. d) No hay otra manera de pasar la materia más que estudiando. e) Hay que llegar temprano para agarrar buen lugar. 2.1.4.- Usando las variables proposicionales ℓ y s para denotar a las proposiciones atómicas Juan es muy listo y Juan está satisfecho respectivamente, denota con estas variables proposicionales y los conectivos lógicos a las siguientes proposiciones: a) b) c) d) e) f) Juan es muy listo y está satisfecho. Si Juan no fuera listo, no estarı́a satisfecho. Juan es listo o está satisfecho. Juan está satisfecho únicamente si es listo. Si Juan es listo entonces está satisfecho. Juan es listo pero no está satisfecho. 2.1.5.- En los siguientes enunciados, identifica las proposiciones atómicas y ası́gnales variables proposicionales. Una vez hecho esto, convierte los enunciados a proposiciones lógicas. a) b) c) d) e) Si Juan fue al cine, seguro que Lupe fue también. Las noticias no son buenas. Te darán clave para la red sólo si estás inscrito en el curso. Si asistió a las clases, debió pasar la materia. El asesino era de tez blanca o clara. 2.1.6.- Formaliza las siguientes implicaciones y construye sus implicaciones asociadas. a) Si un número es divisible entre 2 entonces es par. b) Si Elke es austriaca entonces es europea. 41 2.1 El lenguaje de la lógica proposicional c) Una condición necesaria para que Lourdes lleve el curso de algoritmos es que apruebe matemáticas discretas. d) El programa es legible sólo si está bien estructurado. e) La audiencia dormirá si el ponente diserta sobre lógica medieval. 2.1.7.- Para el siguiente enunciado, asigna variables proposicionales a las proposiciones atómicas y escribe la proposición completa usando esas variables proposicionales. (a) Marı́a fue al teatro el lunes en la noche sólo en el caso de que no tuviera clase el martes temprano. (b) Si Juan llevó su Mustang al desfile es porque le cambió el amortiguador el dı́a anterior. (c) Si los tres lados de un triángulo son congruentes, entonces los tres ángulos del triángulo son congruentes. (d) Si x es mayor que 3 entonces también es mayor que 2. (e) Nunca ha nevado en Cuernavaca. (f) Si n es un entero, entonces n3 − n es par. 2.1.8.- Para cada pareja de enunciados que se listan, escribe las fórmulas para la disyunción de ambos y la conjunción de ambos. Para cada fórmula, indica si es verdadera o no. (a) p : Uno es un entero par q : Nueve es un entero positivo (b) p : Chihuahua está en la frontera con EEUU q : Brasil está en África (c) p : La naranja es una fruta q : La papa es una verdura (d) p : Los pájaros tienen cuatro patas q : Los conejos vuelan (e) p : Los cardenales son rojos q : Los ruiseñores son azules 2.1.9.- Para cada uno de los siguientes enunciados, asigna variables proposicionales y escribe la fórmula o argumento lógico correspondiente al enunciado. (a) Si hoy es viernes, iré al cine. (b) Si termino la tarea voy a tomar un descanso. (c) Si Pepito compite en natación va a ganar el primer lugar. Si Juanito compite en natación va a ganar el primer lugar. Alguno de los dos no va a quedar en primer lugar en la competencia de natación. Por lo tanto o Pepito no compite o Juanito no compite. (d) Los perros son mamı́feros. Los mamı́feros no tienen agallas. Por lo tanto los perros no tienen agallas. 42 Lógica proposicional (e) Voy a comer tacos o quesadillas. Decidı́ no comer quesadillas. Entonces comeré tacos. 2.1.10.- Elabora la tabla de verdad para el operador nand , donde p nand q está definido como ¬ (p ∧ q). 2.1.11.- Elabora las tablas de verdad para p ∧ p, p ∨ ¬ p, p ∨ p, p ∧ true, p ∧ false, p ∨ true y p ∨ false. Observa cada una de estas tablas de verdad y di la relación que tienen con la variable p original. 2.1.12.- Construye la tabla de verdad para cada una de las siguientes fórmulas, clasificando si se trata de una tautologı́a, contradicción o contingencia. a) b) c) d) e) f) (p ∧ q) → ¬(r ∧ q) (p ∧ (r ∧ q)) → r ((p → q) ∧ ¬q) → p (s ∨ t) ↔ (s ∧ t) (r → s) ∧ ¬t (q ∨ p) → (¬p → q) 2.1.13.- Analizar mediante tablas de verdad la correctud de los siguientes argumentos. a) b) c) d) e) p, q / ∴ p ∧ q q, r, s / ∴ q ∧ t p → q, ¬q / ∴ ¬p p → q ∨ r, ¬q / ∴ p → r p → q, ¬p / ∴ ¬q 2.2. Evaluación de expresiones Si bien el proceso de evaluación de una expresión nos queda intuitivamente claro y en muchos casos es un proceso mental completamente automático, vamos a formalizarlo en esta sección. El objetivo de esta formalización radica principalmente en la necesidad de la misma para un estudio en abstracto de la evaluación y sus propiedades mediante el cual se podrá automatizar el proceso de evaluación más fácilmente. 2.2.1. Estados y evaluación Regresamos al concepto de estado que, como dijimos en la sección anterior, está ı́ntimamente relacionado con la evaluación de expresiones (o, en nuestro caso, de proposiciones). 43 2.2 Evaluación de expresiones Definición 2.4 Un estado es una función que asigna a una variable dada x un valor v elegido de entre aquellos que pueden asignarse a esa variable. Un estado se representa usualmente mediante un conjunto de parejas ordenadas (x, v) (o bien x = v), donde en cada pareja el primer elemento x es una variable y el segundo elemento v es un valor. Definición 2.5 La evaluación de una expresión E en un cierto estado se logra reemplazando todas las variables en E por los valores que éstas tienen en ese estado y calculando después el valor de la expresión resultante, dictada por el significado de los operadores que figuran en la expresión. Esta definición, si bien debe ser intuitivamente clara, no es completamente formal; más adelante definiremos formalmente qué significa reemplazar una variable por un valor o una expresión. Veamos algunos ejemplos en la siguiente página. Expresión Estado Evaluación m÷n { m = 63, n = 7} 9 m÷n { m = 8, n = 48} 1 6 i=1 { i = 2, j = 1} 0 i=1 { i = 1} 1 i=1 { j = 1} i=1 a + (b · c) { a = 3, b = 5, c = 2} 13 a + (b · c) { a = 4, b = 5, c = 7, d = 8} 39 a + (b · c) { a = 13, b = 11, d = 2} 13 + (11 · c) (p ∧ q) ∨ r { p = 0, q = 1, r = 1 } 1 (p ∧ q) ∨ r { p = 1, q = 0, r = 0 } 0 (p → q) → r { p = 0, q = 0, r = 0 } 0 (p → q) → r { p = 1, q = 0, r = 0 } 1 44 Lógica proposicional Si sucede que hay variables en la expresión que no aparecen en el estado (es decir, que no tienen un valor asignado), entonces la evaluación de la expresión incluirá presencias de esas variables a las que no les podemos asignar valor (quedarán con incógnitas, como les hemos llamado a este tipo de variables). En estos casos lo más común es que la expresión obtenida mediante esta evaluación parcial interactúe más adelante con otro estado para terminar su evaluación. Sin embargo, en algunos casos se puede evaluar completamente una expresión aun cuando el valor de alguna de sus variables no esté definido en el estado. Estos casos son aquellos en los que el valor de la expresión no depende de dicha variable. Por ejemplo, si llegamos a una expresión como 0 · (a + b) es irrelevante el valor ya sea de a o de b, porque esta expresión se evalúa a 0 (cero); lo mismo para las expresiones 0 → p o bien p → 1, pues sabemos que el resultado de ambas expresiones es verdadero (1). Es útil, entonces, para ahorrarnos algo de trabajo, conocer las propiedades de los operadores y de algunas expresiones en las que están involucradas constantes. 2.2.2. Precedencia y asociatividad Hemos utilizado paréntesis en expresiones. Los paréntesis nos indican agregación. Por ejemplo, en la expresión 3 + (4· 5) los paréntesis agregan la expresión 4 · 5 como el segundo operando de la suma para indicar que la operación que queremos realizar es la suma de 3 con el producto de 4 y 5, cuyo resultado es 23. Si la expresión tuviera los paréntesis (3 + 4) · 5, se estarı́a agregando la suma de 3 y 4 como operando del producto, dando como resultado 35. Para reducir el número de paréntesis en una expresión se asignan precedencias a los operadores. En particular, los lenguajes de programación hacen esto, pues el uso excesivo de paréntesis resulta ser una carga para el programador y obscurece el significado de la expresión para el lector humano. Si el operador op1 tiene mayor precedencia que el operador op2 , eso quiere decir que primero evaluamos la operación de op1 y después la de op2 . Por ejemplo, como usualmente la multiplicación tiene mayor precedencia que la suma, en la expresión 3 + 4 · 7 se debe evaluar primero el producto 4 · 7, y ese resultado usarlo para la suma con 3. En otras palabras, es como si los paréntesis aparecieran alrededor del producto, 3 + (4 · 7) y, de hecho, una vez definido el orden de precedencia, es posible restaurar los paréntesis originales siguiendo este orden. Otro concepto, que se relaciona en particular con el orden de evaluación de una expresión, es el de asociatividad. Esta propiedad nos permite decidir, si tenemos al mismo operador más de una vez en una expresión y en ausencia de paréntesis para indicar el orden de evaluación, cuál de las presencias del operador debe evaluarse primero. Por ejemplo, en la expresión p → q → r, ¿cuál de los dos debe evaluarse primero, el de la izquierda o el de la derecha? El resultado de la evaluación es distinta, dependiendo de la asociatividad que tengamos: 45 2.2 Evaluación de expresiones p q r (p → q) → r V alor p → (q → r) V alor 0 0 0 1→0 0 0→1 1 Como se puede ver, tanto la precedencia como la asociatividad determinan, en ausencia de paréntesis, el orden de evaluación de las subexpresiones. Los paréntesis se usan, como ya dijimos, para alterar la precedencia y asociatividad natural o bien para que quede explı́cita la precedencia y asociatividad que deseamos. A continuación damos una tabla de precedencias y asociatividades de los operadores aritméticos y lógicos más comunes. En el orden en que aparecen, la precedencia va de mayor a menor. Los operadores que tienen la misma precedencia aparecen en el mismo renglón de la tabla. Operador Descripción Asociatividad + − ¬ operadores unarios prefijos izquierda ∗∗ exponenciación derecha producto, división, módulo y máximo común divisor izquierda suma y resta binarias izquierda comparadores izquierda ∧ ∨ conjunción y disyunción izquierda → implicación derecha ↔ bicondicional izquierda · / ÷ mod + − = < > gcd Como podemos observar de la tabla anterior, en ausencia de paréntesis la evaluación de p → q → r debe realizarse asociando p → (q → r), ya que el operador → asocia a la derecha. Esto quiere decir que evaluamos de derecha a izquierda, como si hubiera paréntesis alrededor de q → r. En el caso de la expresión 3 + 4 · 7, la precedencia de · es mayor que la de + binario, por lo que se evalúa a 31 3 + (4 · 7) . Sin embargo, esta tabla no nos ayuda a determinar los paréntesis implı́citos en expresiones como P ∧ Q ∨ R, ya que ∧ y ∨ tienen la misma precedencia, pero no son el mismo operador, por lo que no podemos utilizar la asociatividad para dirimir el conflicto. En este tipo de expresiones es costumbre poner siempre paréntesis para indicar la precedencia, ya que de otra manera la evaluación de la expresión es ambigua. Por lo tanto debemos escribir (P ∧ Q) ∨ R o bien P ∧ (Q ∨ R), dependiendo de cuál es la precedencia deseada. 46 Lógica proposicional Puede haber estados en los que la evaluación sea la misma. Veamos la evaluación de estas dos asociatividades en un estado en el que no se obtiene el mismo valor, para corroborar que en ese estado no producen el mismo resultado y por lo tanto las dos expresiones no son equivalentes. P Q R (P ∧ Q) ∨ R valor P ∧ (Q ∨ R) valor 0 0 1 0 1 1 1 0 0 1 0 Insistimos en que el concepto de asociatividad sólo se puede aplicar cuando se trata de dos o más presencias consecutivas del mismo operador; no son los niveles de precedencia los que definen la asociatividad. 2.2.3. Sustitución textual Supongamos que tenemos dos expresiones2 E y R, y sea x una variable (usualmente x presente en E). Usamos la notación E[x := R] o E R para denotar la expresión que es la misma que E, pero donde cada presencia (ocurrencia) de x en la expresión E ha sido sustituida por la expresión (R). Llamamos sustitución textual al acto de sustituir todas las presencias de x en E por (R). Cuál de las dos notaciones utilizar no es relevante, excepto que se debe elegir una de ellas y mantener esa elección. La notación E[x := R] es más x apropiada para computación, pero la notación E R es la utilizada por los profesionales de la lógica matemática. Tabla 2.4 Ejemplos de sustitución textual (1/2) Expresado como Expresado como E[x := R] x ER 1. a + b[a := x + y] a + bax+y 2. (a + b)[a := x + y] (a + b)xx+y 3. (x · y)[x := z + 2] 2 Nos referimos a expresiones de cualquier tipo. (x · y)xz+2 Resultado a+b ((x + y) + b) ((z + 2) · y) 47 2.2 Evaluación de expresiones Tabla 2.4 Ejemplos de sustitución textual (2/2) Expresado como Expresado como E[x := R] x ER Resultado 4. (4 · a · b)[a := b] (4 · a · b)ab (4 · (b) · b) 5. (p → q)[p := 0] (p → q)p0 ((0) → q) 6. (p → p ∨ q)[p := p ∨ q] (p → p ∨ q)pp∨q ((p ∨ q) → (p ∨ q) ∨ q) 7. (5 · x)[x := 2 + 6] (5 · x)x2+6 (5 · (2 + 6)) Es conveniente notar que la sustitución textual es una operación y podemos considerar x a [x := R], o bien R , como el operador. En este caso no es una operación de números a números como la suma y el producto, o de proposiciones a proposiciones como la negación o conjunción, sino que se trata de una operación de expresiones cualesquiera en expresiones cualesquiera. A este operador se le asigna la precedencia más alta de todos los operadores y su asociatividad es a la izquierda. Esto debe tomarse en cuenta cuando veamos a cuál a expresión es a la que afecta la sustitución: no es lo mismo a + b[a := x + y] (a + bx+y )  a que (a + b)[a := x + y] (a + b)x+y , pues en el primer caso la única expresión a la que se refiere la sustitución es b, mientras que en el segundo caso es (a + b). En ambos casos, y dado que la sustitución textual es lo primero que se va a ejecutar, toma como operando al grupo que se encuentra a su izquierda, que en el primer caso consiste únicamente de b mientras que en el segundo caso, dado que se usaron paréntesis, consiste de (a + b). Podemos ver algunos ejemplos en la tabla 2.4 de la página anterior, utilizando ambas notaciones por el momento, aunque después usaremos la que indicamos como la más adecuada para computación. Deseamos hacer hincapié sobre los siguientes puntos: • Debe quedar claro el porqué la sustitución se define poniendo entre paréntesis a R dentro de E: si no lo hiciésemos ası́ corremos el riesgo de alterar los paréntesis implı́citos de la expresión. En la sustitución 7 del ejemplo, si evaluamos la expresión resultante obtenemos 40, pero si no pusiéramos los paréntesis alrededor de 2 + 6, la expresión se evaluarı́a a 16, de acuerdo con la precedencia de los operadores en la expresión resultante. • R, la expresión por la que vamos a sustituir, puede o no tener presencias de x, la variable a la que vamos a sustituir. • Si E no tiene ninguna presencia de x, la expresión queda exactamente igual a como estaba, es decir E[x := R] = E. 48 Lógica proposicional • Si hay varias presencias de x en E, como es el caso del ejemplo 6, se piensa en la sustitución hecha simultáneamente a cada presencia de x en E. Es como si marcáramos las posiciones de x en E, después ponemos una caja en lugar de la variable y después colocamos en esas cajas a (R). Si es que x aparece en R, no regresamos a sustituir estas presencias de x en el resultado. • Es común que en el resultado queden paréntesis que no aportan nada, por ejemplo aquellos que rodean a una variable sola. En este caso, y cuando la eliminación de los paréntesis no afecte la precedencia y asociatividad del resultado, éstos pueden eliminarse. Esto también se refiere a los paréntesis que utilizamos para rodear a la expresión sobre la que queremos hacer la sustitución. En adelante mantendremos los paréntesis sólo en aquellos casos en que sean estrictamente necesarios, es decir, cuando quitarlos altere la precedencia y asociatividad de la expresión resultante. Si tenemos una lista de variables x : x1 , x2 , . . . , xn distintas y una lista de expresiones R : R1 , R2 , . . . , Rn (no forzosamente distintas), podemos definir la sustitución textual six multánea E[x := R] E R como el reemplazo simultáneo de cada una de las variables de la lista x por su correspondiente expresión en la lista R. Esto es, x1 se reemplaza  con R1 , x2 con R2 , y ası́ sucesivamente. Por ejemplo, (p ∧ q)[p, q := 1, 0] es (1) ∧ (0) , cuyo valor es 0, mientras que (p ∧ q)[p, q := 1, p] es (1 ∧ p), ya que no se puede “regresar” a hacer la sustitución textual de la variable x que aparece en la expresión R, en la expresión resultante. Un punto mucho muy importante a notar es que la sustitución textual se utiliza únicamente para sustituir presencias de variables, no de expresiones ni de constantes. Como ya mencionamos, la asociatividad de la sustitución textual es izquierda, por lo que E[x := R][z := S] se asocia E[x := R] [z := S], donde E, R y S son expresiones y x y z son variables; esta operación se define como una copia de E en la que las presencias de x fueron sustituidas por R, y en esa copia las presencias de z fueron sustituidas por S. Es importante notar que, en general, E[x := R][z := S] es distinto a E[x, z := R, S], como se puede ver en las siguientes sustituciones: (p → p ∨ q)[p := q][q := p] es p→p∨p (p → p ∨ q)[p, q := q, p] es q →q∨p Variables escondidas en la sustitución textual Es usual asignar una variable a una expresión para que sea más sencillo manipularla. Por ejemplo, podemos decidir Q: −b + √ b2 − 4 · a · c 2·a 49 2.2 Evaluación de expresiones y utilizar esta asociación para, en lugar de escribir √ x = (−b + b2 − 4 · a · b)/(2 · a) podamos escribir x = Q. Pero entonces Q tiene tres variables escondidas, a, b y c, y una sustitución de la forma Q[a := 3] se debe interpretar como   √ ( −b + b2 − 4 · a · b )/(2 · a) [a := 3] √ √ cuyo resultado es (−b + b2 − 4 · 3 · b )/(2 · 3) = (−b + b2 − 12 · b )/6 Queremos hacer notar que la evaluación de una expresión consiste en, simplemente, hacer una sustitución textual en la expresión, donde por cada variable definida en el estado en que se desea evaluar a la expresión se le sustituye por el valor de la variable en ese estado. Después, si es posible, se ejecutan las operaciones necesarias para obtener el valor de la expresión en ese estado. Ejercicios 2.2.1.- Coloca los paréntesis en las siguientes expresiones de acuerdo a la precedencia y asociatividad de los operadores, sin preocuparte por la evaluación de la expresión: a) −b + b ∗ ∗2 − 4 · a · c/2 · a b) p ∧ q ∨ r → s ↔ p ∨ q c) a < b ∧ b < c → a < b d) a · b < a · c ↔ a > 0 ∧ b > c 2.2.2.- Para cada expresión que se da a continuación, evalúa la expresión en cada uno de los estados que se proporcionan: Expresión a) a2 + (b · c) Estados {a = 5, b = 3, c = 6} {a = −2, b = 1, c = 11, d = 3} {d = 3, b = 4, c = 10} {a = 3, b = 0} b) p → q ↔ q → r {p = 1, q = 0, r = 1} {p = 0, r = 1} {p = 1, r = 0} {p = 1, q = 1, r = 1} Evaluación 50 Lógica proposicional 2.2.3.- Ejecuta las siguientes sustituciones textuales, fijándote bien en la colocación de los paréntesis. Quita los paréntesis que no sean necesarios. a) x[x := b + 2] b) (x + y · x)[x := b + 2] c) (x + x · 2)[y := x · y] d) (x + x · y + x · y · z)[x := x + y] 2.2.4.- Ejecuta las siguientes sustituciones textuales simultáneas, fijándote bien en la colocación de los paréntesis. Quita los paréntesis que no sean necesarios. a) x + y · x[x, y := b + 2, x + 2] b) (x + y · x)[x, y := x · y, x · y] c) (x + y · 2)[y, x := x · y, x · x] d) (x + x · y + x · y · z)[x, y := y, x] 2.2.5.- Ejecuta las siguientes sustituciones textuales, fijándote bien en la colocación de los paréntesis. Quita los paréntesis que no sean necesarios. a) x + y · x[x := y + 2][y := y · x] b) (x + y · x)[x := y + 2][y := y · x] c) (x + x · 2)[x, y := x, z][x := y] d) (x + x · y + x · y · z)[x, y := y, x][y := 2 · y] 2.2.6.- Expresa la evaluación de las expresiones en la pregunta 2.2.2 utilizando sustitución textual simultánea. 2.3. Análisis sintáctico de expresiones lógicas En general, una expresión es una cadena o palabra construida mediante sı́mbolos de un alfabeto dado. Sin embargo no todas las cadenas que construyamos simplemente pegando sı́mbolos van a ser expresiones útiles, sino únicamente aquellas construidas de acuerdo a una gramática diseñada con ese propósito particular. El proceso de evaluación descrito anteriormente requiere que la expresión a evaluar sea sintácticamente válida; por ejemplo, no podemos ni debemos intentar evaluar una cadena de sı́mbolos como p¬q, puesto que ésta no es una expresión válida y el intento de evaluarla fracasará. En nuestro caso a las expresiones generadas de manera legı́tima por la gramática de la lógica proposicional les llamamos expresiones lógicas, proposiciones o bien fórmulas. Por ejemplo, P ∧ Q es una fórmula si es que garantizamos que P y Q son, a su vez, fórmulas. El proceso de evaluación de una expresión debe ser precedido por el proceso de reconocer cuándo una cadena de sı́mbolos es una fórmula bien construida o formada; este proceso se conoce como análisis sintáctico. En nuestro caso particular la pregunta que nos interesa responder es ¿cuándo una cadena de sı́mbolos es una expresión lógica? Hasta ahora la 2.3 Análisis sintáctico de expresiones lógicas 51 única manera de responder es derivando dicha cadena mediante las reglas de la gramática; sin embargo, este proceso puede ser largo y tedioso, y si bien esta es la manera usual de implementar el proceso de análisis sintáctico, nos gustarı́a tener un proceso más simple y directo para nuestro uso. A continuación nos serviremos de la operación de sustitución textual para verificar cuándo una cadena de sı́mbolos es una fórmula bien formada. 2.3.1. Esquemas En matemáticas es común asociar identificadores a ciertas expresiones con el propósito de abreviar su escritura; podemos escribir por ejemplo A para denotar a la fórmula p ∨ q. Sin embargo, A no es una variable proposicional, pues para obtener su valor es necesario evaluar la fórmula p ∨ q, a partir de los valores de las variables proposicionales p y q. Un identificador es entonces una especie de variable informal, conocida entre los lógicos como metavariable. A continuación fijamos una definición de esquema. Definición 2.6 Un esquema es una expresión construida de manera similar a las fórmulas pero usando, en algunos casos, identificadores en vez de variables proposicionales. Si bien esta definición es informal pues el concepto de identificador no ha sido definido con precisión, con ella nos basta. Ejemplo 2.6. Si A y B son identificadores, entonces A ∧ B es un esquema. Ejemplo 2.7. La expresión (A → B) es un esquema, y si A = (p ∧ q) y B = (p ∨ q) entonces nos proporciona una forma más concisa de escribir  (p ∧ q) → (p ∨ q) Ejemplo 2.8. Si p es una variable proposicional y A = (p → q), la fórmula (p ∧ ¬ A) es un esquema que proporciona una forma más concisa de escribir p ∧ ¬ (p → q) . La sustitución textual en combinación con el concepto de esquema proporcionan una manera simple para decidir si una expresión es una fórmula bien formada. Por ejemplo, ¿cómo podemos verificar si la expresión p ∧ ¬q → r ∧ s es una implicación?; basta ver que dicha fórmula se obtiene a partir del esquema de implicación A → B, en el caso particular en que los identificadores se sustituyan (instancien) con A = p ∧ ¬q y B = r ∧ s. 52 Lógica proposicional Definición 2.7 Instanciar un esquema consiste en hacer una sustitución textual simultánea de cero o más identificadores en el esquema, por fórmulas bien construidas, que pueden o no involucrar a identificadores que aparecen originalmente en el esquema. Un esquema tiene tantas instancias como fórmulas bien formadas podamos usar en la sustitución textual simultánea, esto es, un número infinito de instancias. Todo esquema es una instancia de sı́ mismo, ya que resulta de la sustitución textual simultánea de cero identificadores en el esquema o, visto de otra manera, donde cada identificador que aparece en el esquema es sustituido por sı́ mismo. Si bien existen una infinidad de esquemas, basta identificar con nombre a los siguientes, llamados básicos: 1. 2. 3. 4. 5. Llamamos a una expresión de la forma negación conjunción disyunción condicional equivalencia (¬ A) (A ∧ B) (A ∨ B) (A → B) (A ↔ B) Obsérvese que toda fórmula debe ser atómica, o bien corresponder a una o varias sustituciones textuales simultáneas de uno de estos cinco esquemas. Ahora veamos ejemplos de fórmulas bien construidas. Utilizaremos paréntesis para presentar las distintas fórmulas y procederemos a comprobar que están bien construidas mediante esquemas. Haremos uso de la precedencia y asociatividad para eliminar paréntesis, cuando esto no afecte el significado de la fórmula. Ejemplo 2.9. La expresión ((p ∧ q) → (p ∨ q)) es una condicional. Para ver por qué se le asigna este nombre, veamos la sucesión de sustituciones textuales que se fueron realizando: (p → q)[p, q := p ∧ q, p ∨ q] = ((p ∧ q) → (p ∨ q)) que quitando los paréntesis superfluos queda p ∧ q → p ∨ q. Como el esquema original del que partimos es el de la implicación, la instanciación dada es por ende una implicación. Ejemplo 2.10. El esquema ¬A → P ∨ Q es una condicional, porque al restaurar los paréntesis implı́citos en la expresión, dada la precedencia y asociatividad de los distintos operadores 2.3 Análisis sintáctico de expresiones lógicas 53 que aparecen, obtenemos ((¬A) → (P ∨ Q)). (P → Q)[P, Q := A, P ∨ Q][A := ¬A] = = ((A) → (P ∨ Q)[A := ¬A] = ((¬A) → (P ∨ Q)), donde quitando los paréntesis superfluos, queda ¬A → P ∨ Q. Como el esquema original del que partimos es una condicional, decimos que el esquema ¬A → P ∨ Q también es una condicional. Ejemplo 2.11. La fórmula (p ↔ q) ∧ (r ↔ p) ↔ (p ↔ q) ∧ (r ↔ q) es una equivalencia. Nuevamente veamos los paréntesis implı́citos, de acuerdo a las reglas de precedencia y asociatividad:    (p ↔ q) ∧ (r ↔ p) ↔ (p ↔ q) ∧ (r ↔ q) y veamos la sucesión de sustituciones textuales a partir del esquema (A ↔ B). (A ↔ B)[A, B := P ∧ Q, P ∧ R][P, Q, R := p ↔ q, r ↔ p, r ↔ q] = = ((P ∧ Q) ↔ (P ∧ R))[P, Q, R := p ↔ q, r ↔ p, r ↔ q] = (((p ↔ q) ∧ (r ↔ p)) ↔ ((p ↔ q) ∧ (r ↔ q))), donde quitando los paréntesis superfluos, nos lleva a: (p ↔ q) ∧ (r ↔ p) ↔ (p ↔ q) ∧ (r ↔ q). Obsérvese que en este ejemplo primero transformamos el esquema básico de implicación en un esquema más cercano a la fórmula original, para después instanciar con las fórmulas adecuadas y obtener el resultado deseado. Del último ejemplo podemos concluir que el proceso de análisis mediante sustituciones textuales empieza a resultar complicado, por lo que nos gustarı́a dar una definición del proceso, susceptible de aplicarse mecánicamente, algo que desarrollamos a continuación. 2.3.2. Rango y conectivo principal Para mecanizar el proceso de análisis sintáctico de una expresión nos serviremos, además de la sustitución textual y el uso de esquemas, de un proceso de descomposición en expresiones sintácticamente más simples, las cuales son más sencillas de analizar. Dicha descomposición utiliza los conceptos de rango de un conectivo lógico y conectivo principal de una fórmula que a continuación definimos. 54 Lógica proposicional Definición 2.8 El concepto de rango o alcance de un conectivo en una fórmula o esquema E se define, con base en los esquemas básicos, como sigue: • Si E es instancia de ¬A, entonces el rango de ¬ en E es A. • Si E es instancia de uno de los esquemas básicos binarios A ⋆ B, donde ⋆ es un conectivo lógico binario, entonces el conectivo ⋆ en E tiene un rango izquierdo que es A y un rango derecho que es B. Obsérvese que el rango o rangos de un conectivo (operador) en una expresión corresponden a los operandos; en caso de que no estén explı́citamente indicados se obtienen tomando en cuenta las reglas de asociatividad y precedencia ya estudiadas. Por ejemplo: • En el esquema ¬ A ∧ B el rango del operador ¬ es únicamente el identificador A. Si queremos que el rango sea A ∧ B debemos encerrar este esquema entre paréntesis, obteniendo ¬ (A ∧ B). • En la fórmula A ∧ B ∧ C el rango izquierdo del segundo conectivo ∧ es la fórmula (A ∧ B), ya que como no hay paréntesis, las reglas de precedencia y asociatividad hacen que la colocación de los paréntesis implı́cita de la fórmula sea ((A ∧ B) ∧ C). Otro concepto importante es el de conectivo principal. Si una expresión E resulta ser instancia de uno de los esquemas básicos, entonces el conectivo que observamos en el esquema correspondiente será también el conectivo principal de E. Por ejemplo, si E = (p ∨ q) ∧ C, entonces el conectivo principal de E es ∧, puesto que E = (A ∧ B)[A, B := p ∨ q, C]. Veamos un ejemplo más elaborado. Ejemplo 2.12. Consideremos el esquema (A ∧ B ∧ C) ∨ (A → B → C). El análisis sintáctico de este esquema es el siguiente: • Para el esquema original: ◦ ◦ ◦ El conectivo principal es ∨ . El rango izquierdo es (A ∧ B ∧ C). El rango derecho es (A → B → C). • Para el rango izquierdo: ◦ ◦ ◦ ◦  Los paréntesis implı́citos son (A ∧ B) ∧ C . El conectivo principal es el segundo ∧ . El rango izquierdo corresponde a (A ∧ B). El rango derecho corresponde a C. • Para el rango derecho, podemos observar que: 2.3 Análisis sintáctico de expresiones lógicas ◦ ◦ ◦ ◦ 55  Los paréntesis implı́citos son A → (B → C) . El conectivo principal es el primer →. El rango izquierdo es A. El rango derecho es (B → C). Este proceso puede seguir hasta que ya tengamos esquemas o fórmulas que no correspondan a los esquemas básicos, es decir esquemas que consistan de un único identificador o bien variables proposicionales, en las que no tienen ningún significado los conceptos de conectivo principal o rango. Estos casos corresponden al fin del proceso de análisis sintáctico. Como toda fórmula consiste de una combinación de conectivos y proposiciones atómicas, la descomposición en rangos no puede durar para siempre. 2.3.3. Análisis de proposiciones compuestas Existen dos clases de métodos para el análisis de una expresión, los métodos generadores que construyen la expresión deseada a partir de sı́mbolos o esquemas iniciales utilizando ciertas reglas u operaciones; y los métodos analı́ticos que consisten en partir de la supuesta expresión dada y realizar un proceso de descomposición hasta llegar a expresiones básicas, donde el proceso de análisis es directo. Los métodos de gramáticas y árboles de derivación y de instanciación de esquemas básicos son generadores. A continuación veremos un método analı́tico basado en la descomposición de una expresión utilizando su conectivo principal y rangos correspondientes. Haremos explı́cita esta descomposición usando un árbol, cuya raı́z consistirá de la fórmula completa. En cada nivel que bajemos del árbol, identificaremos al conectivo principal de la fórmula y procederemos a colgar de la fórmula al conectivo y a su(s) rango(s). La idea principal es que si E es una expresión compuesta, los rangos del conectivo principal son expresiones, a las que les podemos aplicar el mismo procedimiento. Veamos un ejemplo: Ejemplo 2.13. Si el equipo mexicano llega a cuartos de final del Mundial, todo mundo lo admirará y los jugadores se volverán ricos; pero si no llega, nada pasará. Hagamos una asignación a variables proposicionales: p: el equipo mexicano llega a cuartos de final q: todo mundo admira al equipo mexicano r: los jugadores se vuelven ricos s: nada pasará Hagamos la traducción a una fórmula con paréntesis: ((p → (q ∧ r)) ∧ ((¬ p) → s)) 56 Lógica proposicional y veamos cómo queda el árbol producto del análisis sintáctico de esta fórmula en la figura 2.2 de la siguiente página. En este caso hemos elegido presentar el árbol con las frases en español de manera que se pueda observar la descomposición directamente con enunciados más simples. Obsérvese que las hojas de este árbol corresponden a proposiciones atómicas que ya no pueden descomponerse. El proceso de analizar una expresión es un proceso recursivo, que consiste de los siguientes pasos: 1. Si la proposición es atómica, el análisis termina. 2. Si la proposición no es atómica: a) Definir el conectivo principal b) Si el conectivo es unario, analizar la proposición que corresponde al rango derecho. c) Si el conectivo es binario, analizar la proposición que corresponde al rango izquierdo y la proposición que corresponde al rango derecho. Figura 2.2 Análisis de proposición compuesta Si el equipo mexicano llega a cuartos de final del Mundial, todo mundo lo admirará y los jugadores se volverán ricos; pero si no llega, nada sucederá Si el equipo mexicano llega a cuartos de final del Mundial, todo mundo lo admirará y los jugadores se volverán ricos pero todo mundo los El equipo admira y los mexicano llega a entonces jugadores se cuartos de final volverán ricos todo mundo lo admira y si no llega, nada sucederá No llega los jugadores se volverán ricos entonces no nada sucederá llega Veamos otro ejemplo, esta vez sin remitirnos en el árbol a las frases en español. Ejemplo 2.14. Si el anuncio tiene éxito, toda la producción se va a vender y el dueño se volverá rico; pero si el anuncio no tiene éxito, la inversión se habrá perdido. 57 2.3 Análisis sintáctico de expresiones lógicas Variables proposicionales: p: el anuncio tiene éxito q: toda la producción se vende r: el dueño se vuelve rico s: la inversión se pierde Podemos ver el árbol, usando las variables proposicionales y los conectivos lógicos, en la figura 2.3, que se encuentra en la siguiente página. Figura 2.3 Análisis de una proposición (p → (q ∨ r)) ∧ (¬p → s) p → (q ∧ r) p ¬p → s ∧ → q∧r q ∧ r ¬p → ¬ q s En este momento resulta claro que dada una expresión sintácticamente válida, se puede construir el árbol de análisis sintáctico partiendo directamente de ella; si la expresión está completamente expresada con paréntesis (todos los paréntesis que definen precedencia y asociatividad son explı́citos), el proceso es inmediato, mientras que si no es ası́ habrá que usar los criterios de precedencia y asociatividad. Los niveles del árbol se van construyendo de adentro hacia afuera (de abajo hacia arriba) y de izquierda a derecha para aquellos operadores que asocien a la izquierda, y de derecha a izquierda para aquellos que asocien a la derecha. Más aún, el proceso de análisis sintáctico facilita el proceso de evaluación puesto que una vez construido el árbol, las hojas corresponden a fórmulas atómicas, las cuales se pueden evaluar directamente continuando el proceso de evaluación según lo dictado por las tablas de verdad de los conectivos principales. 2.3.4. Tautologı́as y sustitución Hasta ahora la única manera de verificar si una fórmula dada A es una tautologı́a es construyendo su tabla de verdad. Sin embargo, al crecer el número de variables la tabla de 58 Lógica proposicional verdad contiene cada vez más renglones y su construcción se vuelve complicada, ineficiente y eventualmente imposible. Como ejemplo considérese el esquema A ∧ B → B. Es fácil ver mediante una tabla de verdad de cuatro renglones que |= A ∧ B → B. Por otra parte considérese la expresión p1 ∧p2 ∧. . .∧p99 ∧p100 → p100 , ¿cómo mostrar que se trata de una tautologı́a? La tabla de verdad tendrá 2100 renglones, ası́ que resulta imposible construirla. Afortunadamente la operación de sustitución permite generar más tautologı́as a partir de tautologı́as conocidas. Una vez que se conoce que |= A, no importa si en A sustituimos cualquier variable proposicional por una expresión, el resultado va a seguir siendo una tautologı́a. Esto se formaliza en el siguiente teorema, cuya demostración omitimos. Teorema 2.1 (Propiedad de sustitución) Sea A una fórmula o esquema tal que |= A y sean p1 , p2 , . . . , pn variables proposicionales. Si B1 , B2 , . . . , Bn son expresiones lógicas o esquemas arbitrarios, entonces |= A[p1 , p2 , . . . , pn := B1 , B2 , . . . , Bn ]; es decir, las sustituciones textuales en tautologı́as generan tautologı́as. Usando este resultado y observando que (A ∧ B → B)[A, B := p1 ∧ p2 ∧ . . . ∧ p99 , p100 ] = p1 ∧ p2 ∧ . . . ∧ p100 → p100 concluimos que |= p1 ∧ p2 ∧ . . . ∧ p100 → p100 . Veamos otros ejemplos. Ejemplo 2.15. Demostrar que |= (p ∧ q) ∨ ¬ (p ∧ q). Identificamos en el ejemplo una disyunción de una expresión y su negación, por lo que buscamos algún esquema tautológico que tenga esta misma forma. Sabemos que p ∨ ¬ p es una tautologı́a. Entonces (p ∨ ¬ p)[p := p ∧ q] = (p ∧ q) ∨ ¬ (p ∧ q) por lo que esta expresión es también una tautologı́a. Ejemplo 2.16. Demostrar que |= R → (P ∨ Q) ∨ R. Debemos buscar un esquema para “deshacer” las sustituciones que se hayan hecho. En el nivel más alto el esquema es A → B. Busquemos ahora una tautologı́a que involucre implicación y que en el rango derecho tenga una conjunción, sabemos que |= p → p ∨q es una tautologı́a (mostramos su tabla de verdad 2.3 Análisis sintáctico de expresiones lógicas 59 al inicio de la sección). Como la disyunción tiene la propiedad de conmutatividad, tenemos que p → p ∨ q es lo mismo que p → q ∨ p. Por el Teorema de sustitución, tenemos: (p → q ∨ p)[p, q := q, p] = q → p ∨ q. Este último esquema tautológico nos sirve, pues lo que buscamos es que el rango derecho de la disyunción coincida con el rango izquierdo de la condicional. A continuación observamos que el rango izquierdo de la disyunción es una subexpresión compuesta, no nada más una fórmula atómica, por lo que ahı́ también se llevó a cabo una sustitución textual, que si la “deshacemos” queda como sigue: (q → p ∨ q)[q, p := R, P ∨ Q] = = (R) → (P ∨ Q) ∨ (R) = R → (P ∨ Q) ∨ R Reglas de inferencia Una vez que se ha mostrado la correctud de un argumento lógico, éste se convierte en un esquema de argumento que sigue siendo correcto al sustituir algunos de sus identificadores por fórmulas arbitrarias, puesto que el esquema correspondiente a su fórmula asociada es una tautologı́a, que se preserva bajo sustituciones como lo asegura el teorema 2.1. En tal caso hablamos ya no de un argumento correcto sino de una regla de inferencia. Definición 2.9 Una regla de inferencia es un esquema de argumento correcto. Por ejemplo, dado que los argumentos de los ejemplos 2.3 y 2.5 – el primero conocido como modus ponens – son correctos podemos enunciarlos como esquemas: A→B A B A∧B →C A B→C Obsérvese que una vez que un argumento correcto se transforma en regla de inferencia, al ser correcto, el sı́mbolo ∴ desaparece en la conclusión. 60 Lógica proposicional Ejercicios 2.3.1.- Clasifica a las siguientes proposiciones en alguna de las siguientes categorı́as, justificando la respuesta mediante el uso de esquemas: (a) negación (b) disyunción (c) conjunción (d) condicional (e) bicondicional Fórmula Categorı́a ¬P →¬Q P ↔ Q ↔ (P → Q) ∧ (Q → P ) Q∧P →Q→P (P → Q) ∧ (¬ P → Q) → Q P →Q↔¬Q→¬P 2.3.2.- Para las siguientes proposiciones, di a cuál esquema básico corresponden, rehaciendo las sustituciones textuales que se hayan llevado a cabo. En caso de ambigüedad respecto a la asociatividad de dos operadores distintos con la misma precedencia, se debe asociar desde la izquierda. (a) p → q ∧ q → p (b) r ∧ ¬ q ↔ ¬ r ∧ q (c) p → q → r (d) p ∨ q ∧ ¬ p ∧ q → q ∧ ¬ q (e) ¬ (p ∨ ¬ q ∧ p) (f) ¬ p → q (g) ¬ (p ∧ ¬ q)  (h) ¬ p ∧ (¬ p ∧ q) ∨ p ∧ (p ∧ ¬ q) 2.3.3.- De los siguientes enunciados, define el conectivo principal. Para cada operador: si el operador es binario especifica su rango izquierdo y su rango derecho; si el operador es unario, especifica su rango (derecho). (a) p ∨ (¬ p ∧ q) → p ∨ q (b) ¬ (p ∧ q → p ∨ q) 61 2.4 Equivalencia lógica (c) ¬ p ∧ (q ∨ p) ∧ ¬ q (d) (p → q) → p ∨ q → q (e) ¬(p ∨ q → r) 2.3.4.- Da el árbol de análisis sintáctico de cada una de los siguientes esquemas: a) P ∧ Q ∧ R → P b) P → Q ↔ ¬ Q → ¬ P c) P → Q → R ∨ S ∨ P d) P → Q ∧ R → S → P → S 2.3.5.- Construye el árbol de análisis sintáctico para cada una de las siguientes fórmulas a) ¬¬p ∧ ¬q → s ↔ ¬s → ¬p ∨ q b) ¬p ∨ q → p ∧ ¬q → ¬p ∨ ¬q → ¬p ∧ ¬q c) p ∧ q → p ∨ q → ¬p ∧ q 2.4. Equivalencia lógica El concepto de expresiones equivalentes es imprescindible para todo tipo de razonamiento. Decimos que dos expresiones son equivalentes si y sólo si en todos y cada uno de sus posibles estados se evalúan a lo mismo. Por ejemplo, podemos comprobar usando una tabla de verdad, que las expresiones ¬ ¬ P y P son equivalentes: P ¬P ¬ (¬ P ) 1 0 1 0 1 0 Lo que debemos observar es que, renglón por renglón, el valor correspondiente a P es el mismo que el valor correspondiente a ¬ ¬ P . No se interprete esta definición como que estamos exigiendo tener el mismo valor en todos los renglones, esto es, que todos los renglones valieran 0 o todos los renglones valieran 1. En el caso de expresiones lógicas el concepto de equivalencia está relacionado con un tipo particular de tautologı́a. Si tenemos una bicondicional (A ↔ B) que es una tautologı́a, entonces decimos que tenemos una equivalencia lógica : 62 Lógica proposicional Definición 2.10 (Equivalencia lógica) Sean A, B dos fórmulas. Si A ↔ B es una tautologı́a, entonces decimos que A y B son lógicamente equivalentes y lo denotamos por A ≡ B. Esto es lo mismo que decir A≡B |= A ↔ B. si y sólo si La tabla 2.5 resume algunas equivalencias lógicas de importancia, las cuales pueden comprobarse mediante el uso de tablas de verdad. Tabla 2.5 Leyes de equivalencia de la lógica proposicional Asociatividad: (P ∧ Q) ∧ R ≡ P ∧ (Q ∧ R) (P ∨ Q) ∨ R ≡ P ∨ (Q ∨ R) (2.14) (2.15) Identidad: P ∨ false ≡ P P ∧ true ≡ P (2.16) (2.17) Idempotencia: P ∨P ≡ P P ∧P ≡ P (2.18) (2.19) Dominación (o elemento nulo): P ∨ true ≡ true P ∧ false ≡ false (2.20) (2.21) Conmutatividad: P ∨Q ≡ Q∨P P ∧Q ≡ Q∧P (2.22) (2.23) Tercero excluido: P ∨ ¬ P ≡ true (2.24) Contradicción: P ∧ ¬ P ≡ false (2.25) Doble negación: ¬¬P ≡ P (2.26) Distributividad: P ∨ (Q ∧ R) ≡ (P ∨ Q) ∧ (P ∨ R) P ∧ (Q ∨ R) ≡ (P ∧ Q) ∨ (P ∧ R) (2.27) (2.28) De Morgan: ¬ (P ∧ Q) ≡ ¬ P ∨ ¬ Q ¬ (P ∨ Q) ≡ ¬ P ∧ ¬ Q (2.29) (2.30) Eliminación de operadores: P P P P (2.31) (2.32) (2.33) (2.34) →Q ↔Q ↔Q ↔Q ≡ ≡ ≡ ≡ ¬P ∨Q (¬ P ∨ Q) ∧ (P ∨ ¬ Q) (P ∧ Q) ∨ (¬ P ∧ ¬ Q) (P → Q) ∧ (Q → P ) 63 2.4 Equivalencia lógica A continuación mostraremos el uso de equivalencias lógicas en particular como herramienta auxiliar imprescindible en el análisis de un argumento lógico. 2.4.1. Razonamiento ecuacional Consideremos la igualdad aritmética x + y + x + z = y + 2x + z. Probablemente ninguno de nosotros dudarı́a de su validez, debido a la experiencia con números que tenemos desde nuestra educación básica. Más aún, si se nos pidiera una demostración formal tal vez darı́amos la siguiente: x + y + x + z = y + x + x + z = y + 2x + z; y si se nos pidiera nuevamente una justificación tal vez apeları́amos a las igualdades x+y =y+x y x + x = 2x. Este tipo de razonamiento se conoce como razonamiento ecuacional y será parte importante del proceso de análisis de un argumento lógico. Por lo general las fases de razonamiento ecuacional nos son tan familiares que no se mencionan explı́citamente dentro del análisis de un argumento; de hecho, nosotros respetaremos esta costumbre. Sin embargo, en nuestro curso nos conciernen no sólo los aspectos puramente matemáticos de un tema, sino también el proceso de implementación, el cual es esencialmente sintáctico dado que las computadoras no entienden de significados ni son capaces de razonar como nosotros. A continuación discutimos las propiedades de la igualdad, en particular la llamada regla de Leibniz que involucra a la sustitución textual, y que nos brindará una manera posible de implementar el razonamiento ecuacional. Si consideramos a la igualdad como un operador (cuyo resultado es 0 o 1), podemos observar que tiene las siguientes propiedades: Reflexividad Conmutatividad Transitividad X=X X=Y Y =X X=Y Y =Z X=Z Las últimas dos propiedades las dimos como reglas de inferencia, puesto que corresponden a argumentos correctos. Finalmente, veamos una propiedad, conocida con el nombre de regla de Leibniz, que nos va a permitir sustituir expresiones iguales en expresiones que 64 Lógica proposicional resultarán iguales nuevamente y proporciona una manera de implementar nuestro razonamiento ecuacional usual. X=Y Leibniz E[z := X] = E[z := Y ] Lo que esta regla de inferencia nos dice es que si suponemos que X = Y, entonces es posible tomar dos copias de la expresión E (en la que tenemos presencias de una variable z), en una de ellas sustituir a la variable z por la expresión X, y en la otra copia sustituir a la misma variable z por la expresión Y , obteniendo que las expresiones E[z := X] y E[z := Y ] son iguales nuevamente. Es decir, la sustitución de expresiones iguales en expresiones iguales genera expresiones iguales. Es importante notar que en el caso de expresiones lógicas el concepto de igualdad que se utiliza es el de equivalencia lógica, es decir, si decimos que dos expresiones lógicas A y B son iguales, queremos decir que A ≡ B. De manera que en este caso podemos reescribir el argumento de Leibniz de la siguiente forma: X≡Y Leibniz E[z := X] ≡ E[z := Y ] Veamos unos ejemplos de la aplicación de esta regla de inferencia. Ejemplo 2.17. Supongamos que b + 3 = c + 5, y sea E la expresión aritmética d + e. Entonces, tenemos la siguiente instancia de la regla de Leibniz: b+3=c+5 (d + e)[e := b + 3] = (d + e)[e := c + 5] , lo que nos permite concluir que d + (b + 3) = d + (c + 5) es verdadero en aquellos estados en los que b + 3 = c + 5 se evalúe a verdadero. Como la suma es asociativa y podemos eliminar paréntesis superfluos, esto es lo mismo que decir d + b + 3 = d + c + 5. Las situaciones en las que usualmente se usa la regla de Leibniz se dan como sigue: • Tenemos una expresión E[z := X] = G. Esto quiere decir que dada una expresión cualquiera G, localizamos en ella una subexpresión a la que denotamos con X. Esta subexpresión puede aparecer más de una vez, ya que la variable “original” z también puede ocurrir más de una vez en E. • Buscamos una expresión Y que nos convenga, tal que X = Y . • Podemos entonces obtener una nueva expresión G′ = E[z := Y ]. 65 2.4 Equivalencia lógica • La regla de Leibniz nos permite concluir que G = G′ A continuación discutimos el ejemplo introductorio de esta sección. Ejemplo 2.18. Sabemos que • x+y = y+x • x+x = 2·x (2.35) (2.36) Sea E = x + y + x + z. Si deseamos simplificar esta expresión, debemos poder aplicar los dos hechos que sabemos – equivalencias (2.35) y (2.36) –. Por lo pronto, únicamente podemos aplicar la equivalencia (2.35), con dos lugares (en la expresión que queremos manipular) donde podemos hacerlo, considerando que tratamos de localizar a cualquiera de los dos lados de la igualdad: • x+y + x + z (primer acomodo) • x + y+x + z (segundo acomodo) Si utilizamos el primer acomodo, entonces X = x + y e Y = y + x, y sustituimos lo que está en la caja por la expresión equivalente: y+x + x + z Pero ahora tenemos la siguiente expresión, en la que, nuevamente, podemos localizar varias subexpresiones: • y+x + x + z (tercer acomodo) • y + x+x + z (cuarto acomodo) Pero si elegimos el tercer acomodo, regresamos a donde estábamos, por lo que no nos conviene. Mejor elegimos el cuarto acomodo, utilizando la equivalencia (2.36) y tenemos X = x + x, Y = 2 · x, quedándonos nuestra expresión de la siguiente forma: y+ 2·x +z El lector puede comprobar que también eligiendo el segundo patrón que reconocimos en la expresión original hubiésemos podido llegar al mismo resultado. Veamos otro ejemplo aritmético en detalle. Ejemplo 2.19. Supongamos que queremos demostrar (a + b) − b = a 66 Lógica proposicional y que conocemos las siguientes equivalencias: (x + y) − z = x + (y − z) y−y =0 x+0=x (2.37) (2.38) (2.39) Entonces, podemos pensar en la siguiente demostración, utilizando la propiedad de sustitución (teorema 2.1), la regla de Leibniz, y lo que ya conocemos. Como queremos demostrar que (a + b) − b = a, y dado que el lado izquierdo de la igualdad presenta más estructura, lo indicado es “salir” de ese lado y tratar, mediante la aplicación de la propiedad de sustitución y la regla de Leibniz, llegar a a. Es obvio que cada vez que pasamos a una nueva instancia de una regla de inferencia cualquiera, estamos utilizando la propiedad de transitividad para “encadenar” las igualdades: Paso 1: Aplicar el Teorema 2.1.  (x + y) − z = x + (y − z) [x, y, z := a, b, b] = = (a + b) − b = a + (b − b) La propiedad que estamos utilizando es la de sustitución: sabemos que la premisa es una igualdad válida, una tautologı́a, (x+y)−z = x+(y −z) y elegimos las sustituciones  que necesitamos para obtener la expresión con la que queremos trabajar (a + b) − b . De la regla de inferencia tenemos lo siguiente: E es E[x, y, z := a, b, b] es (x + y) − z = x + (y − z) (a + b) − b = a + (b − b) También utilizamos este mismo teorema de sustitución para pasar de la expresión que tenemos (y − y = 0) a la forma que queremos (b − b = 0). Paso 2: Volver a aplicar el Teorema 2.1. y−y =0 (y − y = 0)[y := b] Y como (y − y = 0)[y := b] tenemos ya: es (b − b = 0), 67 2.4 Equivalencia lógica (a + b) − b = a + (b − b) (por la aplicación del paso 1) b−b=0 (por la aplicación del paso 2) Podemos ahora utilizar la regla de Leibniz de la siguiente manera: Paso 3: Aplicar la regla de Leibniz. b−b=0 a + (b − b) = a + 0 donde: X es b−b Y 0 E a+z E[z := X] (a + z)[z := b − b] = E[z := 0] (a + z)[z := 0] = (a + (b − b)) (a + (0)), que cuando quitamos los paréntesis superfluos nos dejan a + (b − b) = a + 0 También sabemos que x + 0 = x es una igualdad válida. Entonces podemos aplicarle sustitución textual y seguir teniendo una igualdad válida: x+0=x Paso 4: (x + 0 = x)[x := a] . Pero como (x + 0 = x)[x := a] es a + 0 = a, tenemos la siguiente sucesión de igualdades válidas: (a + b) − b = a + (b − b) b−b=0 a + (b − b) = a + 0 a+0=a (a + b) − b = a Decimos entonces que hemos demostrado que (a + b) − b = a es una igualdad válida. 68 Lógica proposicional 2.4.2. Álgebra de equivalencias lógicas Análogamente al hecho de que el razonamiento aritmético ecuacional es la base del álgebra que conocemos desde hace tiempo, en el caso de las expresiones lógicas se genera un álgebra que manipula variables y constantes que representan valores de verdad; en particular podemos emplear equivalencias lógicas para deducir o simplificar nuevas expresiones a partir de otras ya conocidas. Ilustremos esto mediante algunos ejemplos. Ejemplo 2.20. Sabemos que • P ∧P ≡P • P ∧Q≡Q∧P (2.40) (2.41) Supongamos que queremos “simplificar” la siguiente expresión: q∧r∧q∧s Para poder aplicar el argumento de Leibniz, hagamos primero sustitución textual sobre las variables, para tener los mismos términos: (q ∧ r ∧ q ∧ s)[q, r, s := P, Q, R] = P ∧ Q ∧ P ∧ R. Ahora tratemos de identificar alguno de los lados de las equivalencias dentro de la expresión que tenemos. Existen dos posiciones que podemos reconocer: • P∧ Q ∧ P ∧ R • P ∧ Q∧ P ∧ R – lado izquierdo de (2.41) – lado derecho de (2.41) Si aplicamos a la primera elección la igualdad, X = Y con X = P ∧ Q y Y = Q ∧ P , la regla de Leibniz nos lleva a la expresión: P ∧Q≡Q∧P . P∧ Q ∧ P ∧ R ≡ Q∧ P ∧ P ∧ R Enseguida localizamos el otro esquema que corresponde a la equivalencia dada en (2.40), al principio de esta sección, donde X = P ∧P y Y = P . La sustitución se hace como sigue: P ∧P ≡P Q ∧ P∧ P ∧ R ≡ Q ∧ P ∧ R , 69 2.4 Equivalencia lógica por lo que terminamos con la siguiente expresión: Q ∧ P ∧ R ≡ P ∧ Q ∧ R; de las dos aplicaciones de Leibniz y usando la regla de transitividad podemos concluir que P ∧ Q ∧ P ∧ R ≡ P ∧ Q ∧ R. Si nos quedamos con la expresión de la derecha y hacemos la sustitución de las variables de regreso a q, r y s, tenemos: (P ∧ Q ∧ R)[P, Q, R := q, r, s] = q ∧ r ∧ s y esta última es la simplificación final de la original. Ejemplo 2.21. Consideremos ahora la siguiente expresión lógica (P ∧ Q) ∧ ¬Q. El objetivo es simplificarla lo más posible. Tenemos que: 1. (A ∧ B) ∧ C ≡ A ∧ (B ∧ C) Propiedad asociativa de ∧ 2. (P ∧ Q) ∧ ¬ Q ≡ P ∧ (Q ∧ ¬ Q) Sustitución textual en 1) 3. P ∧ ¬ P ≡ false X = P ∧ ¬ P e Y = false 4. P ∧ (Q ∧ ¬ Q) ≡ P ∧ false Leibniz y como P ∧ false ≡ false Elemento nulo ya terminamos. De esta manera hemos demostrado que (P ∧Q)∧¬ Q ≡ false, con la siguiente sucesión de equivalencias, utilizando la propiedad de transitividad de la equivalencia lógica: (P ∧ Q) ∧ ¬ Q ≡ P ∧ (Q ∧ ¬ Q) ≡ P ∧ false ≡ false 70 Lógica proposicional En la tabla 2.5 (página 62) mostramos la lista inicial de equivalencias que vamos a utilizar para nuestro razonamiento ecuacional. Sin embargo existen muchas otras equivalencias que se pueden derivar de las anteriores y son de gran importancia. A continuación obtenemos algunas de ellas. Leyes de absorción: P ∨ (P ∧ Q) ≡ P P ∧ (P ∨ Q) ≡ P (2.42) (2.43) Leyes de simplificación: (P ∧ Q) ∨ (¬ P ∧ Q) ≡ Q (P ∨ Q) ∧ (¬ P ∨ Q) ≡ Q (2.44) (2.45) Debemos demostrar estas nuevas leyes, ya que no aparecen en nuestro conjunto inicial de equivalencias. Lo haremos con cuidado y detalle en uno de los casos, dejando el otro como ejercicio. Ejemplo 2.22. Absorción frente a ∨: P ∨ (P ∧ Q) ≡ P . Utilizaremos el método de tomar a uno de los equivalentes y derivar, a partir de él, al otro. Como el de la izquierda tiene más estructura, es el que tomamos como punto de partida. Punto de partida. Localizaremos este esquema en alguno de los axiomas o teoremas que ya hayamos demostrado. En este momento únicamente contamos con (2.14) a (2.33). P ∨ (P ∧ Q) Usando Identidad (2.17) y Leibniz. P ≡ P ∧ true ≡ (P ∧ true) ∨ (P ∧ Q) ≡ P ∧ (true ∨ Q) P ∨ (P ∧ Q) ≡ (P∧ true) ∨ (P ∧ Q) Distributividad de ∧ (2.28) (P ∧ Q) ∨ (P ∧ R) ≡ P ∧ (Q ∨ R) Usando sustitución [Q, R := true, Q] tenemos: (Continúa en la siguiente página) 71 2.4 Equivalencia lógica (Continúa de la página anterior) (de la página anterior) ≡ P ∧ (true ∨ Q) ≡ P ∧ true ≡ P Usando dominación (2.20) y Leibniz: Q ∨ true ≡ true P ∧ (Q ∨ true) ≡ P ∧ true Usando identidad de ∧ (2.17) Ejemplo 2.23. Simplificación: (P ∨ Q) ∧ (¬ P ∨ Q) ≡ Q. Nuevamente tenemos que demostrar una equivalencia lógica, por lo que trataremos de transformar a uno de los equivalentes en el otro. Como el equivalente de la izquierda tiene mayor estructura, partiremos de él. Dado que el número que le corresponde a este teorema  es el (2.44), podemos utilizar en este caso las leyes (2.14) a (2.43) . Punto de partida. Localizaremos este esquema en alguno de los axiomas o teoremas que ya hayamos demostrado. Vemos un esquema similar en el rango derecho de (2.28): (P ∨ Q) ∧ (¬P ∨ Q) Usando Conmutatividad (2.22). (P ∨ Q) ∧ (¬ P ∨ Q) ≡ (Q ∨ P ) ∧ (Q ∨ ¬ P ) ≡ (Q ∨ P ) ∧ (Q ∨ ¬P ) Instanciando (2.28) (P ∨ Q) ∧ (P ∨ R) ≡ P ∨ (Q ∧ R) (Q ∨ P ) ∧ (Q ∨ ¬ P ) ≡ Q ∨ (P ∧ ¬ P ) ≡ Q ∨ (P ∧ ¬ P ) Contradicción: (2.25) P ∧ ¬P ≡ false ≡ Q ∨ false (Continúa en la siguiente página) 72 Lógica proposicional (Continúa de la página anterior) (de la página anterior) ≡ Q ∨ false Identidad: (2.16) Q ∨ false ≡ Q ≡ Q Se deja como ejercicio la demostración de (2.43). En todos los ejemplos de esta sección marcamos e hicimos explı́citos todos los usos de las reglas. Sin embargo, en la práctica muchas de estas reglas se usan de manera implı́cita. A continuación damos algunos atajos que se pueden tomar al hacer álgebra de equivalencias lógicas. 1. La Ley de Conmutatividad se aplica directamente, “sin avisar”. 2. La Ley de Asociatividad se aplica directamente, “sin avisar”. 3. Se puede desechar directamente lo siguiente: a) Copias duplicadas de una subexpresión en una expresión que es una disyunción o una conjunción (Ley de Idempotencia). b) La constante true en una conjunción (Ley de Identidad para ∧ ). c) La constante false en una disyunción (Ley de Identidad para ∨ ). 4. De igual manera, se puede simplificar haciendo lo siguiente: a) Sustituir el esquema A ∧ ¬A por false (Ley de Contradicción). b) Sustituir el esquema A ∨ ¬A por true (Ley del Tercero Excluido). c) Sustituir el esquema ¬¬A por A (Ley de Doble Negación). En esta sección hemos mostrado cómo es posible justificar formalmente el razonamiento ecuacional usual. Esta justificación, que se hizo apelando al uso de la regla de Leibniz, además de proporcionar un fundamento matemático formal a un razonamiento al que estamos acostumbrados desde hace mucho, nos da una pauta para una posible automatización del proceso. En adelante el uso de razonamiento ecuacional será, por lo general, intuitivo, sin requerir el uso explı́cito de la regla de Leibniz. Para terminar probaremos la equivalencia lógica entre una implicación y su contrapositiva, usando algunos de los atajos anteriores. Esto justifica el método de demostración por contrapositivo, usual en Matemáticas. Ejemplo 2.24. Contrapositiva: P → Q ≡ ¬Q → ¬P . Usaremos la ley de eliminación de la 73 2.4 Equivalencia lógica implicación mediante disyunción, ası́ como las leyes de De Morgan. P →Q ≡ ≡ ≡ ≡ ≡ ¬P ∨ Q ¬(P ∧ ¬Q) ¬(¬(Q ∨ ¬P )) Q ∨ ¬P ¬Q → ¬P Ejercicios 2.4.1.- Para las siguientes expresiones E, dadas z, X e Y , obtener E[z := X] y E[z := Y ]. (a) z p E p (b) p (c) p p∧p↔p (d) q p ∧ (¬ p ∧ q) (p ∨ q) ∧ (p ∨ r) X p∧q Y q∧p true p↔p p∨q p∨¬q ↔p p ∨ (q ∧ r) (p ∨ q) ∧ (p ∨ r) 2.4.2.- La regla de Leibniz se refiere a cualquier combinación de expresiones E, X e Y y a cualquier variable z. A continuación damos varios razonamientos que siguen el patrón de Leibniz y que están incompletos. El orden no es forzosamente el dado por la expresión, esto es, abajo de X no forzosamente está E[z := X]. Llena las partes que faltan y escribe en qué consiste la expresión E. Los últimos dos ejercicios tienen tres respuestas. Dalas todas. a) p ↔ p∨0 p∨0∨q ↔ ? 7 = y+1 b) 7·x+7·y = ? 74 Lógica proposicional x = b+c p→q ↔ ¬q→¬p c) d) p→q→p ↔ ? x+y+w = ? x+1 = y b·c = y+w f) e) 3 · (x + 1) + 3 · x + 1 = ? x+y+w = ? x = y g) x+x = ? 2.4.3.- El objetivo de este ejercicio es reforzar las habilidades en el uso del argumento de Leibniz para demostrar que dos expresiones son iguales. Vamos a dar las expresiones E[z := X] y E[z := Y ] y deberás localizar respectivamente a X y a Y . (a) (b) (c) (d) (e) E[z := X] E[z := Y ] (x + y) · (x + y) (x + y) · (x + y) x+y+w+x x·y·x x·y·x (x + y) · (y + x) (y + x) · (y + x) x+y·w+x (y + w) · y · x y·x·x 2.4.4.- Elimina los operadores → y ↔ de cada una de las siguientes proposiciones: a) (P → Q ∧ R) ∨ ((R ↔ S) ∧ (Q ∨ S)) b) (P → Q) ∧ (Q → R) c) ¬ P → ¬ Q d) (P → Q) ↔ ((P ∧ Q) ↔ Q) 2.5. Conceptos semánticos importantes Una vez que hemos estudiado el análisis sintáctico de una fórmula lógica pasamos a estudiar ciertos conceptos de importancia relacionados con su semántica. 75 2.5 Conceptos semánticos importantes 2.5.1. Interpretaciones La noción de interpretación presentada en esta sección será de gran importancia para evitar el uso de tablas de verdad en las pruebas de correctud. Definición 2.11 Un estado de las variables proposicionales es una función I que asigna a cada variable proposicional el valor de falso o verdadero: I : V ariables proposicionales → {0, 1} Cada estado genera una función de interpretación sobre todas las fórmulas, definida como se explica a continuación. Definición 2.12 Cada estado I determina una interpretación de las fórmulas – denotada también por I – definida como sigue: I(true) = 1 I(false) = 0 I(¬P ) = 1 si y sólo si I(P ∧ Q) = 1 si y sólo si I(P ↔ Q) = 1 si y sólo si I(P ∨ Q) = 0 si y sólo si I(P → Q) = 0 si y sólo si I(P ) = 0 I(P ) = 0 = I(Q) I(P ) = 1 = I(Q) I(P ) = 1 e I(Q) = 0 I(P ) = I(Q) Si I(P ) = 1 entonces decimos que • I satisface a P , o bien • P es satisfacible en I, o bien • P se satisface en I, o bien • I es un modelo de P . Ejemplo 2.25. Si tenemos la fórmula A = p → q ∨ r, la siguiente asignación de estado I1 (p) = 1, I1 (q) = 0, I1 (r) = 0, hace I1 (p → q ∨ r) = 0, por lo que I1 no es un modelo para la fórmula. Por otro lado, el estado I2 (p) = 1, I2 (q) = 0, I2 (r) = 1 76 Lógica proposicional hace que I2 (p → q ∨ r) = 1, por lo que sı́ es un modelo para la fórmula. Dada una fórmula P podemos preguntarnos ¿cuántas interpretaciones hacen verdadera a P ? Las posibles respuestas llevan a las siguientes definiciones: Definición 2.13 Sea P una fórmula. Entonces • Si I(P ) = 1 para toda interpretación I, decimos que P es una tautologı́a o fórmula válida y escribimos |= P . • Si I(P ) = 1 para alguna interpretación I, decimos que P es satisfacible, que P es verdadera en I o que I es modelo de P y escribimos I |= P • Si I(P ) = 0 para alguna interpretación I, decimos que P es falsa o insatisfacible en I o que I no es modelo de P y escribimos I 6|= P • Si I(P ) = 0 para toda interpretación I, decimos que P es una contradicción o fórmula no satisfacible. Similarmente, si Γ es un conjunto de fórmulas decimos que: • Γ es satisfacible si tiene un modelo, es decir, si existe una interpretación I tal que I(P ) = 1 para toda P ∈ Γ, lo cual denotamos a veces, abusando de la notación, con I(Γ) = 1. • Γ es insatisfacible o no satisfacible si no tiene un modelo, es decir, si no existe una interpretación I tal que I(P ) = 1 para toda P ∈ Γ. Para el último ejemplo se cumple lo siguiente, de acuerdo a la definición anterior, I1 6|= A, I2 |= A, 6|= A. Veamos otro ejemplo. Ejemplo 2.26. Sean Γ1 = {p → q, r → s, ¬s}, Γ2 = {p → q, ¬(q ∨ s), s ∨ p}. Entonces • Si I(s) = I(r) = I(p) = 0, entonces I(Γ1 ) = 1 por lo que Γ1 es satisfacible. • Γ2 resulta insatisfacible pues supóngase que existe una interpretación I tal que I(Γ2 ) = 1. Entonces, se tiene que I(¬(q ∨ s)) = 1 por lo que I(¬q) = I(¬s) = 1. Además como I(p → q) = 1 entonces I(p) = 0 puesto que el antecedente de la implicación es falso. De esto último se tiene I(s) = 1 dado que I(s ∨ p) = 1. De manera que se tiene I(¬s) = 1 = I(s) lo cual es imposible. Por lo tanto no puede existir una interpretación I que satisfaga a Γ2 Con respecto a las tablas de verdad tenemos las siguientes observaciones: 2.5 Conceptos semánticos importantes 77 • Una fórmula P es satisfacible si en alguna lı́nea de la tabla de verdad, P toma el valor 1. En caso contrario, es decir si en todas las lı́neas toma el valor 0, entonces es insatisfacible (contradicción). • Un conjunto de fórmulas Γ es satisfacible si existe alguna lı́nea de la tabla de verdad en la que todas las fórmulas de Γ toman el valor 1. 2.5.2. Consecuencia lógica La definición matemática formal de argumento deductivo correcto se sirve del concepto de consecuencia o implicación lógica que discutimos aquı́. Definición 2.14 (consecuencia lógica) Sean Γ = {A1 , . . . , An } un conjunto de fórmulas y B una fórmula. Decimos que B es consecuencia lógica de Γ si toda interpretación I que satisface a Γ también satisface a B. Es decir, si todo modelo de Γ es modelo de B. En tal caso escribimos Γ |= B. Nótese que la relación de consecuencia lógica está dada por una implicación de la forma Si I(Γ) = 1 entonces I(B) = 1. De manera que no se afirma nada acerca de la satisfacibilidad del conjunto Γ, sino que simplemente se supone que es satisfacible y, en tal caso, se prueba que la fórmula B también lo es con la misma interpretación. Obsérvese la sobrecarga del sı́mbolo |= que previamente utilizamos para denotar satisfacibilidad I |= A y tautologı́as |= A. Ejemplo 2.27. Considerese el siguiente conjunto Γ = {q → p, p ↔ t, t → s, s → r}. Muestre que Γ |= q → r. Sea I un modelo de Γ. Tenemos que demostrar que I(q → r) = 1. Si I(q) = 0 entonces I(q → r) = 1 y terminamos. En otro caso se tiene I(q) = 1 de donde I(p) = 1 pues I(q → p) = 1. Entonces se tiene I(t) = 1, pues I es modelo de p ↔ t, de donde I(s) = 1 dado que I también es modelo de t → s. Finalmente, como I(s → r) = 1 e I(s) = 1 entonces I(r) = 1. Por lo tanto I(q → r) = 1. Para terminar la sección discutimos algunas propiedades importantes de la relación de consecuencia lógica. Proposición 2.1 La relación de consecuencia lógica cumple las siguientes propiedades: (a) Si A ∈ Γ entonces Γ |= A. (b) Principio de refutación: Γ |= A si y sólo si Γ ∪ {¬A} es insatisfacible. (c) Γ |= A → B si y sólo si Γ ∪ {A} |= B. 78 Lógica proposicional (d) Insatisfacibilidad implica trivialidad: Si Γ es insatisfacible entonces Γ |= A para toda fórmula A. (e) Si Γ |= false entonces Γ es insatisfacible. (f) A ≡ B si y sólo si A |= B y B |= A. (g) |= A (es decir A es tautologı́a) si y sólo si ∅ |= A (es decir A es consecuencia lógica del conjunto vacı́o). Demostración. Procedemos a justificar algunos de los incisos: (a) Si I(Γ) = 1 quiere decir que existe un modelo para Γ y, por lo tanto, para cada una de las fórmulas de Γ, en particular para A. (b) Supongamos que toda interpretación que satisface a Γ también satisface a A (definición de Γ |= A). Si una interpretación satisface a Γ, dado que satisfacı́a también a A, entonces no satisface a ¬A. Por lo tanto, es imposible satisfacer a Γ y a ¬A al mismo tiempo, lo cual implica que Γ ∪ {¬A} es insatisfacible. En sentido contrario, supongamos que Γ ∪ {¬A} es insatisfacible. Para mostrar que Γ |= A, consideremos I una interpretación cualquiera tal que I(Γ) = 1. En tal caso, necesariamente tenemos que I(A) = 1 puesto que de lo contrario I(A) = 0, por lo que I(¬A) = 1 y ası́ Γ ∪ {¬A} serı́a satisfacible mediante I, lo cual por hipótesis no puede suceder. (c) Supongamos Γ |= A → B. Por la definición de consecuencia lógica, tenemos que si I(Γ) = 1 entonces I(A → B) = 1. Para mostrar que Γ ∪ {A} |= B sea I una interpretación tal que I(Γ ∪ {A}) = 1; en esta interpretación se tiene que I(A) = 1; como además I(A → B) = 1 por hipótesis, porque estamos suponiendo I(Γ) = 1, entonces por definición de la interpretación de una implicación, dado que para el antecedente A se tiene I(A) = 1, entonces necesariamente I(B) = 1. Por lo tanto Γ ∪ {A} |= B. En sentido contrario, supongamos que Γ ∪ {A} |= B. Esto es que si I(Γ ∪ {A}) = 1 entonces I(B) = 1. Sea I una interpretación tal que I(Γ) = 1. Tenemos los siguientes casos: • I(A) = 1. Entonces I(B) = 1, pues se cumple que I(Γ ∪ {A}) = 1; con lo que I(A → B) = 1 y tenemos que Γ |= A → B. • I(A) = 0. En este caso, independientemente de cuál sea el valor de I(B), tenemos I(A → B) = 1, por lo que nuevamente Γ |= A → B. Por lo tanto, Γ |= A → B si y sólo si Γ ∪ {A} |= B. (d) Si Γ es insatisfacible, quiere decir que para toda interpretación I, se tiene I(Γ) = 0. Si esto es ası́, se cumple trivialmente que si I(Γ) = 1 entonces I(A) = 1. Es decir Γ |= A. 2.5 Conceptos semánticos importantes 79 (e) Si Γ |= false, por la definición de consecuencia lógica tenemos que I(Γ) = 1 implica I(false) = 1. Sin embargo, I(false) = 0 siempre sucede; por lo que, como Γ |= false tenemos necesariamente que I(Γ) = 0 para toda posible interpretación de Γ, es decir, Γ es insatisfacible. Se deja la justificación de los incisos restantes al lector. Es importante disponer de métodos algorı́tmicos para decidir la consecuencia lógica, que nos permitirán, en particular, analizar argumentos del lenguaje natural y establecer su correctud formalmente. En las siguientes secciones presentaremos algunos de estos métodos. Ejercicios 2.5.1.- Para cada una de las fórmulas que siguen, determina si son o no satisfacibles. Si lo son, muestra un modelo para cada una de ellas. (a) p ∧ q ↔ ¬ p ∧ q (b) (¬ p ∨ q) ∧ p (c) p ∧ q ∧ ¬ p (d) (p → q) ∧ (q → p) 2.5.2.- Usa interpretaciones para determinar si las siguientes fórmulas son tautologı́as, contradicciones o contingentes. Si son contingentes, da una interpretación en la que la fórmula no se evalúa a verdadero.    (p ∨ q) ∨ r ∧ p ∨ (q ∨ r) → p ∨ q (a)   (b) p ∧ (q ∧ r) → p → (q → r) (c) p ∨ q → p ∨ r  (d) p → (p → q) → p 2.5.3.- Decide si los siguientes conjuntos son satisfacibles. a) b) c) d) e) Γ = {(¬q ∧ r) ∨ p ∨ q, p ∧ r} Γ = {p ∧ ¬q, ¬(q ∨ ¬p), (q ∧ p) ∨ q ∨ ¬p} Γ = {q ∨ r ∨ s, ¬(q ∨ r), ¬(r ∨ s), ¬(s ∨ q)} Γ = {¬(p ∧ q) ∧ ¬(p ∧ r), q ∨ r, ¬(p ∨ ¬r)} Γ = {p ↔ q, q ↔ s, p, ¬s} 80 Lógica proposicional 2.5.4.- Demuestra la consecuencia lógica en cada caso. a) b) c) d) e) f) {p, q} |= p ∧ q {p, ¬q} |= ¬(p → q) {p ∨ q p → r, q → r} |= r {p → q, p → ¬q} |= ¬p {r ∧ s → t, ¬t} |= t → q {¬q → ¬r, ¬r → ¬p, ¬p → ¬q} |= q ↔ r 2.6. Análisis de argumentos En esta sección aplicamos todos los conocimientos previos de lógica matemática estudiados hasta ahora para cumplir con nuestro propósito fundamental: el análisis de correctud de un argumento lógico proposicional. 2.6.1. Tablas de Verdad Como ya discutimos antes, un argumento es correcto si y sólo si su fórmula asociada es una tautologı́a; para decidir esta situación podemos construir la tabla de verdad correspondiente tal y como lo hicimos en la sección 2.1.6. Veamos un ejemplo más. Ejemplo 2.28. El argumento P → Q, Q → R/ ∴ P → R es correcto. Basta ver que |= (P → Q) ∧ (Q → R) → (P → R) . La tabla de verdad se muestra en la tabla 2.8 a continuación. Tabla 2.8 P → Q, Q → R/ ∴ P → R P Q R (P → Q) ∧ (Q → R) → (P → R) 1 1 1 1 1 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 0 0 1 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 81 2.6 Análisis de argumentos Como se observa de los valores en la quinta columna, en negritas, la fórmula es una tautologı́a, por lo que este argumento, conocido como silogismo hipotético, es correcto. Este ejemplo, junto con los de la sección 2.1.6, deja ver que la tabla de verdad se vuelve más complicada al aumentar el número de variables proposicionales involucradas. La construcción de la tabla de verdad completa, aunque plausible desde el punto de vista teórico, es de “fuerza bruta”. En la práctica pues nos obliga, en los casos interesantes y no triviales, a evaluar un número muy grande de estados para determinar si tenemos o no una tautologı́a (o una contradicción). Aun si lo hiciésemos con una computadora, y suponiendo que a la computadora le llevara un milisegundo evaluar cada estado, si la expresión es muy grande tenemos el crecimiento en el número de estados que vemos en la tabla 2.9. Tabla 2.9 Crecimiento en el número de estados con respecto a número de variables Número de Número de Tiempo variables estados (segundos) 1 2 3 .. . .002 .004 .008 .. . 1, 024 2, 048 1 2 .. . 1, 048, 576 1, 048 (= 17min) .. . .. . 10 11 .. . .. . 20 .. . 2 4 8 .. . Como se puede observar en la tabla 2.9, cada vez que se agrega una variable a la expresión, el tiempo que lleva calcular todos sus estados se duplica, siguiendo, como ya mencionamos, a la función 2n , donde n es el número de variables3 . Esta ineficiencia surge en la práctica, por ejemplo, en problemas de calendarización o búsqueda de rutas donde ciertas fórmulas lógicas involucradas tienen usualmente cientos de variables. Para estimar la ineficiencia considérese una fórmula con 500 variables, cuya tabla de verdad tendrá 2500 renglones, número aproximadamente igual a 10150 , los cuales, de acuerdo a nuestra suposición anterior respecto a la velocidad de la computadora, se calcuları́an en 10147 milisegundos. Dado que en un año hay 3.1536 × 1010 milisegundos, la tabla terminarı́a de calcularse en aproximadamente 3.2 × 10139 años; considerando que la edad de nuestro planeta es 3 Cuando tenemos este tipo de cálculo, decimos que la función crece con 2n , o que tiene un crecimiento exponencial. Este tipo de cálculos, en la práctica, no pueden ser evaluados en una computadora cuando la n no es pequeña. 82 Lógica proposicional aproximadamente 109 años, podemos corroborar que el tiempo estimado del método es inadmisible. Dada esta situación, vamos a utilizar tablas de verdad únicamente para verificar expresiones pequeñas y cuando no podamos recurrir a otras técnicas. Obsérvese que el método de tablas de verdad puede evitarse al usar esquemas: una vez que se prueba que un argumento es correcto, él mismo genera un esquema, llamado regla de inferencia y cada instancia de estaregla será, a su vez, un argumento correcto. Ejemplo 2.29. Mostrar la correctud del argumento r → s ∨ ¬t (r → s ∨ ¬t) → ¬p ∧ (q ∨ w) ∴ ¬p ∧ (q ∨ w) La tabla de verdad para este análisis tendrı́a 26 = 64 renglones, dado que tenemos seis variables. Sin embargo, no es necesario el análisis puesto que el argumento corresponde al esquema del modus ponens que ya mostramos que es correcto. Formalmente tenemos que   P ∧(P → Q) → Q P, Q := r → s ∨ ¬t, ¬p ∧ (q ∨ w) = = ((r → s ∨ ¬t) ∧ (r → s ∨ ¬t) → (¬p ∧ (q ∨ w)) → (¬p ∧ (q ∨ w)) y como |= P ∧ (P → Q) → Q podemos concluir que |= ((r → s ∨ ¬t) ∧ (r → s ∨ ¬t) → (¬p ∧ (q ∨ w)) → (¬p ∧ (q ∨ w)). Este método es útil en algunos casos en los que ya se conoce de antemano un esquema de argumento correcto; sin embargo no es siempre efectivo ni fácil de implementar. 2.6.2. Uso de interpretaciones Ya estamos convencidos de que el uso de una tabla de verdad para analizar la correctud de un argumento es una muy mala idea en general. Construir la tabla de verdad para una fórmula de la forma A1 ∧ . . . ∧ An → B, en su totalidad, resulta, en la mayorı́a de los casos, innecesario. Por ejemplo, al observar nuevamente la tabla 2.8, podemos darnos cuenta de que sólo nos interesa la mitad de ésta, a saber los renglones donde la conjunción de las premisas es verdadera. El resto de la tabla puede desecharse puesto que si la conjunción de las premisas no es verdadera, la implicación será verdadera automáticamente. El concepto de consecuencia lógica toma en cuenta esta observación al suponer que las premisas son ciertas y bajo este supuesto mostrar que, bajo la misma interpretación, la conclusión también lo es. 2.6 Análisis de argumentos 83 Para mostrar la correctud del argumento lógico A1 , . . . , An / ∴ B mediante el uso de interpretaciones, nos servimos de la siguiente proposición cuya demostración dejamos como ejercicio. Proposición 2.2 El argumento A1 , . . . , An / ∴ B es lógicamente correcto si y sólo si {A1 , . . . , An } |= B, es decir, si la conclusión es consecuencia lógica de las premisas. De acuerdo a las propiedades de la consecuencia lógica, existen básicamente dos formas para demostrar la correctud de un argumento, el método directo y el indirecto. Método directo: Probar la consecuencia A1 , . . . , An |= B. Para esto se supone la existencia de una interpretación I que sea modelo de todas las premisas y se argumenta, usando esta información y la definición de interpretación, que la conclusión B también se satisface con I. Método indirecto (refutación o contradicción): Probar que es insatisfacible el conjunto {A1 , . . . , An , ¬B}. Para esto se supone que hay una interpretación I que hace verdaderas a todas las premisas y a la negación de la conclusión ¬B o bien, equivalentemente, hace falsa a la conclusión B. Apelando a este supuesto y a la definición de interpretación, se trata de mostrar que tal interpretación no puede existir; esto se logra mostrando que cierta fórmula está forzada a ser verdadera y falsa al mismo tiempo. Es de importancia observar que estos métodos son la base de los métodos usuales de demostración en matemáticas. En un curso cualquiera de matemáticas, cuando se dice que la demostración de un teorema de la forma A → B es directa es porque estamos probando la consecuencia A |= B con el método directo. Similarmente si hablamos de una demostración indirecta o por contradicción o reducción al absurdo es porque estamos probando A |= B con el método indirecto. Veamos algunos ejemplos. Ejemplo 2.30. Mostrar la correctud del argumento {p, s ∨ ¬s, ¬p ∨ q, ¬q ↔ r}/ ∴ ¬r. Sean Γ = {p, s ∨ ¬s, ¬p ∨ q, ¬q ↔ r}; debemos mostrar que Γ |= ¬r, para lo cual tomamos una interpretación I tal que I es modelo de Γ. Debemos mostrar que I(¬r) = 1. Como I es modelo de Γ entonces I(p) = 1 e I(¬p ∨ q) = 1, de donde I(q) = 1 puesto que I(¬p) = 0. Como I(q) = 1 e I(¬q ↔ r) = 1 entonces I(r) = 0, de donde finalmente se obtiene I(¬r) = 1. Obsérvese que la prueba no determina un valor para s ya que con esta interpretación el argumento es correcto independientemente del valor de s. En particular, la única fórmula que involucra a s es la tautologı́a s ∨ ¬s. 84 Lógica proposicional Este método puede resultar tedioso o intrincado pero puede escribirse de manera más clara enunciando cada paso de razonamiento, como en el siguiente ejemplo. Ejemplo 2.31. Mostrar la correctud del argumento p → q, ¬q/ ∴ ¬p, conocido como Modus Tollens, al que se hace referencia más adelante. Para lograr esto mostramos la consecuencia lógica p → q, ¬q |= ¬p. 1. 2. 3. 4. I(p → q) = 1 Hipótesis I(¬q) =1 Hipótesis I(q) =0 por 2, ya que I(¬q) = 1 I(p) =0 por 1 y 3, ya que si I(p → q) = 1 e I(q) = 0, ∴ I(p) no puede ser 1. De manera que el argumento es correcto. El razonamiento paso a paso permite una mayor claridad en el proceso de análisis. Por supuesto que cada paso debe tener una justificación exacta. El análisis terminó aquı́ al llegar a que la conclusión es verdadera, por lo que se probó la consecuencia lógica de manera directa. Ejemplo 2.32. Si hoy tirila y Chubaka es kismi entonces Chubaka es borogrove y si hoy no tirila entonces hay fefos. Más aún sabemos que no hay fefos y que Chubaka es kismi, luego entonces Chubaka es borogrove. La formalización es: Variable Proposicional t k b f Enunciado hoy tirila Chubaka es kismi Chubaka es borogrove hay fefos y el argumento queda como sigue: t∧k →b ¬t → f ¬f ∧ k ∴ b Si hoy tirila y Chubaka es kismi entonces Chubaka es borogrove si hoy no tirila entonces hay fefos sabemos que no hay fefos y que Chubaka es kismi de donde Chubaka es borogrove Queremos demostrar que {t ∧ k → b, ¬t → f, ¬f ∧ k} |= b. 85 2.6 Análisis de argumentos 1. 2. 3. 4. 5. I(t ∧ k → b) = 1 I(¬t → f ) = 1 I(¬f ∧ k) = 1 I(b) = 0 I(k) = 1 Hipótesis. Hipótesis. Hipótesis. Refutación. por 3, I(p ∧ q) = 1 si y sólo si I(p) = 1 e I(q) = 1 6. I(t ∧ k) = 0 por 4 y 1. Como I(b) = 0 y la implicación en 1 es verdadera, entonces la única posibilidad para t ∧ k es que valga 0. 7. I(t) = 0 por 5 y 6. Por 5, I(k) = 1; si I(t ∧ k) = 0 (por 6) es porque I(t) = 0 8. I(¬t) = 1 por 7. 9. I(f ) = 1 por 2 y 8. Como el antecedente es verdadero en (2), para que la implicación sea verdadera el consecuente tiene que serlo. 10. I(¬f ) = 1 por 3, Tenemos que I(¬f ∧ k) = 1 y esta interpretación exige I(¬f ) = 1 e I(k) = 1. 11. I(f ) = 0 por 10, lo que nos lleva a una contradicción con 9. Los pasos 9 y 11 generan una contradicción explı́cita, de manera que por el principio de refutación el conjunto Γ ∪ {¬b} es insatisfacible y el argumento es correcto. Ejemplo 2.33. Mostrar la correctud del siguiente argumento conocido como dilema constructivo simple: p → r, ¬p → r/ ∴ r. 1. I(p → r) = 1 Hipótesis 3. I(r) = 0 Refutación 2. I(¬p → r) = 1 Hipótesis 4. I(p) = 0 5. I(¬p) = 0 6. I(p) = 1 por 3 y 1. Como I(p → r) = 1 e I(r) = 0, I(p) tiene que ser 0. por 3 y 2, argumento similar a 4 por 5, pero hay contradicción con 4 Por lo tanto el argumento es correcto. Es importante observar lo siguiente acerca del uso del método de interpretaciones para analizar argumentos: 86 Lógica proposicional • Si se usa el método directo, el análisis termina una vez que se logra asignar a la conclusión el valor de verdadero. • Si se usa el método indirecto, el análisis termina una vez que se logre forzar a que una fórmula tome los dos valores posibles de verdad. Esta fórmula es generalmente una variable proposicional, aunque esto no es la única opción. • Forzar un valor v para una fórmula A significa que, de acuerdo a la definición de interpretación y a los valores previamente obtenidos de variables o fórmulas, el valor para A es necesariamente y sin lugar a dudas el valor v, que puede ser 1 o 0. Por ejemplo, si sabemos que I(p → q) = 1 e I(q) = 0, entonces necesariamente I(p) = 0, puesto que si tuviésemos I(p) = 1, la definición de interpretación para la implicación nos llevarı́a a I(p → q) = 0, lo cual sabemos que no sucede. De esta manera el valor de p está forzado a ser 0. Es error común asignar valores que no están forzados; por ejemplo, si sólo sabemos que I(r → s) = 1, entonces es un error decir que el valor I(s) = 0 está forzado puesto que no hay suficiente información para descartar la posibilidad de que I(r) = 0, en cuyo caso s podrı́a ser verdadero sin afectar el valor conocido de r → s. • Si al usar el método indirecto no es posible hallar una contradicción o si en el método directo no se forzó a que la conclusión sea verdadera, entonces el argumento resulta incorrecto y la interpretación asignada será un contraejemplo a la correctud del argumento, puesto que las premisas serán ciertas y la conclusión falsa. Analizaremos ahora un par de argumentos incorrectos. Ejemplo 2.34. Analizar el argumento q → p, r ∨ s/ ∴ r → p. Procedemos directamente: 1. I(q → p) = 1 Hipótesis 2. I(r ∨ s) = 1 Hipótesis En este momento no hay manera de forzar ningún valor puesto que tanto la implicación como la disyunción son verdaderas en tres estados. Esta libertad nos permite asignar valores que causen que la conclusión sea falsa, lo que sucede como sigue: 3. I(r) = 1 Supuesto 4. I(p) = 0 Supuesto Aún no terminamos, puesto que debemos dar valores a q y s, los cuales pueden obtenerse como sigue: 5. I(q) = 0 por 1 y 4 6. I(s) = 0 Supuesto 87 2.6 Análisis de argumentos De manera que la interpretación dada por I(p) = I(q) = I(s) = 0 e I(r) = 1 es un contraejemplo al argumento, pues con esta interpretación I(r → p) = 0, ya que 1 → 0 es 0. Esto es, en el estado {p = 0, q = 0, s = 0, r = 1}, tenemos que ((q → p) ∧ (r ∨ s)) → (r → p) se evalúa a 0. (2) (3) (1) (5) (4) p q r s q →p ∧ r∨s → r →p 0 0 1 0 1 1 1 0 0 Obsérvese que s también pudo haber sido verdadero, lo cual habrı́a generado otro contraejemplo. El método indirecto puede ser de más ayuda en algunos casos, pues obliga desde el principio a forzar algunos valores como en el siguiente ejemplo. Ejemplo 2.35. Analizar el argumento q → p, r → p/ ∴ r ∨ s. Procedemos indirectamente: 1. 2. 3. 4. 5. I(q → p) = 1 I(r → p) = 1 I(r ∨ s) = 0 I(r) = 0 I(s) = 0 Hipótesis Hipótesis Refutación por 3 por 3 Obsérvese que falta asignar los valores de p y q. Puede ser que con la asignación I(r) = 0 ya aseguramos que la segunda premisa se mantiene cierta, por lo que el valor de p está libre. Asimismo, el valor de q sólo afecta a la primera premisa y puede elegirse libremente. Un contraejemplo es entonces I(r) = I(s) = I(q) = I(p) = 0. Con estos valores aseguramos que las premisas son verdaderas pero que la conclusión es falsa, por lo que el argumento no es correcto. Otro contraejemplo es I(r) = I(s) = I(q) = 0, I(p) = 1, como se puede verificar de manera muy sencilla. Algunas observaciones son pertinentes. • Al usar valores supuestos – no forzados – no es posible afirmar la correctud del argumento al llegar al valor verdadero para la conclusión o al llegar a una contradicción. En este caso esto sólo indica que el valor supuesto debe reconsiderarse. Si se llega al mismo resultado para todos los posibles valores supuestos entonces podremos afirmar la correctud del argumento y sólo hasta ese momento. 88 Lógica proposicional • En el caso de llegar a un contraejemplo con un valor supuesto, con éste basta. No es necesario reconsiderar valores supuestos pues el contraejemplo ya está construido. El método de interpretaciones, si bien es más eficiente en general que el uso de tablas de verdad, requiere de una gran interacción con el usuario, por lo que se antoja difı́cil de automatizar; es un método muy cercano al razonamiento humano. Más aún, los pasos de razonamiento no siempre son únicos, por ejemplo al usar supuestos, lo cual añade una dificultad más, la elección o no determinismo. La noción de consecuencia lógica es un concepto semántico de gran importancia que permite analizar argumentos lógicos y además puede generalizarse a otros sistemas lógicos, en contraste con las tablas de verdad. Más aún, el uso de interpretaciones proporciona la base para la búsqueda de contraejemplos a argumentos incorrectos. Sin embargo, no es un método eficiente para encontrar consecuencias dado un conjunto de premisas. Para este propósito es más conveniente construir pruebas o derivaciones de manera sintáctica, es decir, sin apelar al concepto de interpretaciones. Haremos esto en la siguiente sección. 2.6.3. Derivaciones Muchos argumentos lógicos correctos pueden obtenerse mediante composición de otros argumentos correctos previamente obtenidos, en el sentido de que la conclusión de un argumento previo puede servir como premisa para un siguiente argumento, y ası́ sucesivamente, hasta llegar a una conclusión deseada. Obsérvese que esta composición de argumentos es un mecanismo puramente sintáctico, al no apelar a la noción de verdad o interpretación. Veamos un par de ejemplos. Ejemplo 2.36. Queremos demostrar que el siguiente fragmento de programa deja el valor de la variable x de tal forma que después de la ejecución es imposible que x > Max, esto es (x > Max) ≡ false. i f x > Max then x : = Max ; Formalizamos con las siguientes variables proposicionales: p : x > Max antes de la ejecución q : x = Max después de la ejecución r : x > Max después de la ejecución Tenemos que distinguir entre x > Max antes y después de la ejecución, pues la asignación modifica el valor de la variable x, es decir, x tiene un valor distinto antes y después de la ejecución del programa. Vamos a hacer primero un análisis intuitivo del problema: hay dos casos, correspondientes a p y ¬p. Si p sucede entonces la asignación se lleva a cabo y q se vuelve válida, es decir la implicación p → q se cumple. Además, si q es válida entonces ¬r también, pues si los dos 89 2.6 Análisis de argumentos números x y Max son iguales entonces x > Max es falso, ası́ que la implicación q → ¬r es válida. Por otro lado, si ¬p es válida, entonces la asignación no se lleva a cabo y claramente ¬r es cierta, pues en este caso p es equivalente a r, por lo que la implicación ¬p → ¬r es válida. Formalmente queremos concluir que ¬r, lo cual es posible usando como hipótesis las implicaciones anteriores y aplicando los esquemas de silogismo hipotético (SH) y dilema constructivo simple (DCS), (ver ejemplos 2.4 y 2.33. Procedemos paso a paso como sigue: Fórmula Justificación Comentario 1. p→q Hipótesis Si x > Max antes de la ejecución entonces x = Max después de la ejecución 2. q → ¬r Hipótesis Si x = Max después de la ejecución entonces x > Max no es cierta después de la ejecución. 3. ¬p → ¬r Hipótesis Si x > Max no es cierta antes de la ejecución entonces tampoco después de la ejecución 4. p → ¬r SH 1,2 Si x > Max antes de la ejecución entonces x > Max no es cierta después de la ejecución. 5. ¬r DCS 3,4 Por lo tanto, sin importar si x > Max es cierta o falsa antes de la ejecución, después de la ejecución x > Max es falsa. Se observa que el paso 4, que es la conclusión de una instancia del silogismo hipotético, fue usado además como premisa para lograr una instancia del dilema constructivo simple. Más aún, en ningún momento se apela a la noción de interpretación. Ejemplo 2.37. Uno de los más reconocidos pensadores “lógicos” es Sherlock Holmes, el detective creado por Arthur Conan Doyle. Veamos una de sus argumentaciones más famosas, que aparece en el libro “Estudio en Escarlata”: Y ahora llegamos a la gran pregunta del motivo. El robo no fue la razón del asesinato, ya que nada fue sustraı́do. Entonces, ¿fue la polı́tica o fue una mujer? Esta es la pregunta a la que me enfrenté. Me incliné desde un principio a la segunda suposición. Los asesinos polı́ticos hacen su trabajo lo más rápido posible y huyen en cuanto terminan. Este asesinato, en cambio, fue hecho de manera deliberada y el asesino dejó sus huellas en todo el cuarto, mostrando que permaneció ahı́ mucho tiempo. Para expresar esta cita, utilizaremos las siguientes variables proposicionales: 90 Lógica proposicional r: s: p: m: h: c: fue un robo algo fue sustraı́do fue la polı́tica (motivos polı́ticos) fue una mujer el asesino huyó inmediatamente el asesino dejó sus huellas en todo el cuarto Veamos la derivación que llevó a cabo Sherlock Holmes, y que lo llevó a concluir que fue una mujer, en la tabla 2.11. Tabla 2.11 Análisis dado por Sherlock Holmes Derivación Regla Comentario 1. r → s Premisa Si fue un robo entonces algo debió ser sustraı́do 2. ¬ s Premisa Nada fue sustraı́do 3. ¬ r Modus Tollens 1, 2 No fue un robo 4. ¬ r → p ∨ m Premisa Si no fue un robo, debió ser motivo polı́tico o una mujer 5. p ∨ m Modus Ponens 3, 4 Fue motivo polı́tico o una mujer 6. p → h Premisa Si fue motivo polı́tico, el asesino debió huir inmediatamente 7. c → ¬ h Premisa Si el asesino dejó huellas en todo el cuarto, no huyó inmediatamente 8. c Premisa El asesino dejó huellas en todo el cuarto 9. ¬ h Modus Ponens 7, 8 El asesino no huyó inmediatamente 10. ¬ p Modus Tollens 6, 9 El motivo no fue polı́tico 11. m Silogismo Disyun- Por lo tanto debió ser una mujer tivo 5, 10 La secuencia de argumentos utilizados se muestra en la lista a continuación. En ella se puede observar claramente como las conclusiones que se van obteniendo de los argumentos, se pueden utilizar como premisas en argumentos sucesivos. 91 2.6 Análisis de argumentos 1. r → s 2. ¬ s 3. ¬ r Modus Tollens 3. ¬ r 4. ¬ r → p ∨ m Modus Ponens 7. c → ¬ h 8. c Modus Ponens 5. p ∨ m 9. ¬ h 6. 9. p→h ¬h Modus Tollens 10. ¬ p 5. p ∨ m 10. ¬ p Silogismo Disyuntivo 11. m Las secuencias de composición de argumentos que acabamos de mostrar en los ejemplos anteriores se llaman derivaciones , pruebas o deducciones formales. A continuación las estudiamos de manera formal. Sistemas para derivaciones Los aspectos de la lógica relacionados con el estudio de las derivaciones conforman lo que se llama teorı́a de la demostración en contraste con los aspectos semánticos cuyo estudio se conoce como teorı́a de modelos. En esta sección describimos formalismos para desarrollar pruebas o derivaciones en lógica proposicional de manera sistemática, los cuales se conocen como cálculos deductivos o sistemas para derivaciones. Aunque existen diversos sistemas para desarrollar derivaciones, todos tienen las siguientes caracterı́sticas en común: 1. Hay un conjunto de argumentos lógicos admisibles, que definimos ya como reglas de inferencia. Nos referiremos a este conjunto con L. Formalmente cada elemento de L es en realidad un esquema de argumento, el cual debe ser un argumento correcto. En algunos casos se aceptan argumentos sin premisas los cuales se llaman axiomas. 92 Lógica proposicional 2. La derivación es en sı́ misma una lista de expresiones lógicas. Originalmente, la lista está vacı́a y una expresión puede agregarse a la lista si es una premisa, o si se puede obtener como conclusión de alguna de las reglas de inferencia de L a partir de expresiones que se encuentran previamente en la lista. Este proceso continúa hasta que se llega a la fórmula B que se desea obtener como conclusión. En tal caso decimos que la lista completa es una derivación de B. Estas caracterı́sticas describen el conocido método axiomático introducido por Euclides en sus “Elementos” donde están las bases de la geometrı́a euclideana. La siguiente definición es de importancia. Definición 2.15 Sean Γ = {A1 , . . . , An } un conjunto de fórmulas. Si existe una derivación de B a partir de Γ, es decir, donde las premisas son fórmulas del conjunto Γ, entonces decimos que B es derivable a partir de Γ y escribimos Γ ⊢L B, o simplemente Γ ⊢ B si el conjunto de reglas de inferencia válidas ya es conocido. Por lo general el conjunto de reglas de inferencia L está fijo desde un principio, de manera que únicamente pueden usarse reglas de inferencia que figuran en él. En nuestro caso no seremos tan estrictos y permitiremos usar cualquier regla previamente derivada, aunque esencialmente usaremos las siguientes: Tabla 2.13 Principales reglas de inferencia (1/2) Regla Nombre Notación A B /A∧B Introducción de ∧ I∧ A∧B /B Eliminación de ∧ E∧ A∧B /A Eliminación de ∧ E∧ A /A ∨ B Introducción de ∨ I∨ B /A∨B I∨ A A→B/B Modus Ponens MP ¬B A→B/¬A Modus Tollens MT A→B B→C/A→C Silogismo Hipotético SH (Continúa en la siguiente página) 93 2.6 Análisis de argumentos Tabla 2.14 Principales reglas de inferencia (2/2) (Continúa de la página anterior) Regla Nombre Notación A∨B ¬A/B Silogismo Disyuntivo SD A→B ¬A→B/B Casos simple CS A↔B/A→B Eliminación de equivalencia E↔ A→B B→A/A↔B Introducción de Equivalencia I↔ Inconsistencia Inc A∨B ¬B /A A↔B/B→A A, ¬ A / B SD E↔ Es momento de desarrollar algunos ejemplos. Ejemplo 2.38. Mostrar la correctud del siguiente argumento: p → r, r → s, t ∨ ¬s, ¬t ∨ u, ¬u/ ∴ ¬p. Vamos a desarrollar una derivación de ¬p con premisas Γ = {p → r, r → s, t ∨ ¬s, ¬t ∨ u, ¬u}. Derivación: 1. p → r 2. r → s 3. t ∨ ¬s 4. ¬t ∨ u 5. ¬u 6. p → s 7. ¬t 8. ¬s 9. ¬r 10. ¬p Premisa Premisa Premisa Premisa Premisa (SH) Silogismo hipotético con 1, 2 (SD) Silogismo disyuntivo con 4, 5 (SD) Silogismo disyuntivo con 7, 3 (MT) Modus tollens con 2, 8 (MT) Modus tollens con 9, 1 Ejemplo 2.39. Mostrar la correctud del siguiente argumento p → q, q → r ∧ s, ¬r ∨ ¬t ∨ u, p ∧ t/ ∴ u 94 Lógica proposicional 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. p→q q →r∧s ¬r ∨ ¬t ∨ u p∧t p→r∧s p r∧s r ¬t ∨ u t u Premisa Premisa Premisa Premisa SH 1,2 E∧ 4 MP 5,6 E∧ 7 SD 8,3 E∧ 4 SD 9,10 Ejemplo 2.40. Mostrar la correctud del siguiente argumento: Si la banda no puede tocar cumbia o las cervezas no llegan temprano, entonces la fiesta de fin de semestre se canceları́a y Menelao montarı́a en cólera. Si la fiesta se cancela, hay que devolver las entradas. No se devolvieron las entradas. Luego entonces la banda pudo tocar cumbia. Se asignan las siguientes variables proposicionales: b: c: f: m: d: La banda pudo tocar cumbia Las cervezas llegan temprano La fiesta se cancela Menelao monta en cólera Hubo que devolver el dinero El argumento a verificar es: ¬b ∨ ¬c → f ∧ m, f → d, ¬d/ ∴ b. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ¬b ∨ ¬c → f ∧ m f →d ¬d ¬f ¬f ∨ ¬m ¬(f ∧ m) ¬(¬b ∨ ¬c) ¬¬b ∧ ¬¬c b∧c b Premisa Premisa Premisa MT 2, 3 I∨ 4 RE 5 MT 6,1 RE 7 RE 8 E∧ 9 2.6 Análisis de argumentos 95 Se observa en los pasos 6, 8 y 9 el uso de razonamiento ecuacional (RE); muchas veces éste se da por sobreentendido y no se menciona, por lo que podrı́amos haber pasado del paso 5 al 7 o del paso 7 al 9 directamente. Estrategias para la construcción de derivaciones En esta sección presentamos algunas estrategias o métodos para la derivación de argumentos correctos. La meta es construir una derivación Γ ⊢ B. De acuerdo al conectivo principal de la conclusión B de un argumento, podemos simplificar la derivación del mismo. Conjunción Para derivar una conjunción Γ ⊢ P ∧Q basta derivar ambos operandos por separado. Es decir, • Si Γ ⊢ P y Γ ⊢ Q, entonces Γ ⊢ P ∧ Q Esta propiedad es inmediata de la regla de inferencia (∧I). Obsérvese que la afirmación recı́proca también es cierta. Disyunción De acuerdo a la regla de introducción de la disyunción (∨I), para mostrar Γ ⊢ P ∨Q basta mostrar alguno de los dos operandos. Es decir, • Si Γ ⊢ P o bien Γ ⊢ Q, entonces Γ ⊢ P ∨ Q. En este caso la afirmación recı́proca no es necesariamente cierta; por ejemplo, tenemos p ∨ q ⊢ p ∨ q pero no es posible derivar p ∨ q ⊢ p ni p ∨ q ⊢ q. Implicación Cuando tratamos de derivar una implicación basta suponer como premisa adicional el antecedente y derivar a partir de ello el consecuente. Esto se debe a que para mostrar la verdad de una implicación basta examinar aquellos casos en que el antecedente es verdadero y corroborar que de ese antecedente se infiere el consecuente; si el antecedente es falso, la implicación es verdadera no importando el valor del consecuente. Esto se expresa en la siguiente propiedad conocida como el metateorema de la deducción : 96 Lógica proposicional • Si Γ, P ⊢ Q entonces Γ ⊢ P → Q. Obsérvese que esta regla se usa prácticamente siempre en las demostraciones matemáticas en general. Ejemplo 2.41. Supongamos que deseamos demostrar ⊢P →P ∨Q Utilizando la propiedad anterior basta encontrar una derivación P ⊢P ∨Q la cual es inmediata de la regla de introducción de la disyunción (∨I). Equivalencia Para derivar una equivalencia P ↔ Q basta probar ambas implicaciones. • Si Γ ⊢ P → Q y Γ ⊢ Q → P , entonces Γ ⊢ P ↔ Q. Nuevamente esta propiedad es muy común en demostraciones matemáticas. Negación Para derivar una negación no hay estrategia general. En algunos casos podemos usar equivalencias lógicas, por ejemplo si deseamos Γ ⊢ ¬(P ∧ Q) entonces basta mostrar Γ ⊢ ¬P ∨¬Q; para demostrar esto último podemos usar la estrategia para la disyunción y probar alguna de Γ ⊢ ¬P o bien Γ ⊢ ¬Q. Un sistema de derivación L debe ser tal que no se puedan derivar resultados que no son sólidos. Esto es, L no debe contener ninguna falacia, una regla de inferencia que permite concluir algo que no está implicado por las premisas y que por lo tanto no es válido. Un sistema de derivación también debe ser completo, esto es, que sea posible derivar absolutamente a todas las conclusiones que se puedan inferir de las premisas. Por ejemplo, la tabla 2.13 no nos da un sistema completo, pues hay leyes, como la del Tercero Excluido, que no se puede derivar de ellas. Y como no hay forma de derivar esta ley a partir de las que se dan en la tabla, debemos agregarla como premisa: ⊢P ∨¬P 2.6 Análisis de argumentos 97 Ejercicios 2.6.1.- Usa los identificadores P y Q para formalizar los siguientes argumentos. Además indica de cuál de las reglas de inferencia son instancia. a) Si 10 es primo, 10 no puede ser igual a 2 veces 5. 10 es 2 veces 5. Por lo tanto, 10 no puede ser primo. b) Si llueve frecuentemente, los agricultores se quejan; si no llueve frecuentemente, los agricultores se quejan. En conclusión, los agricultores se quejan. 2.6.2.- Para los siguientes argumentos decide si son correctos y en caso de no serlo da un interpretación que haga verdaderas a las premisas y falsa a la conclusión. (a) (p → q) ∧ (p → r)/ ∴ q → r (b) p ∨ q → r, s → p, s/ ∴ r (c) p ∨ q, ¬ (p ∧ r), ¬ q/ ∴ r → s (d) p → q, p ∨ r, ¬ (r ∧ s)/ ∴ (p → q) → (q ∨ ¬ s) 2.6.3.- Da un ejemplo, en español, para cada uno de las siguientes reglas de inferencia a) Silogismo hipotético. b) Silogismo disyuntivo. c) Eliminación de ∧. d) Introducción de ∨. e) Inconsistencia. 2.6.4.- Identifica qué regla de inferencia corresponde a los siguientes argumentos en español. a) Si vamos al cine, nos desvelamos. No me quiero desvelar. Entonces no vamos al cine. b) ¡Me pagas la deuda o te quito la televisión! No me pagaste la deuda. Entonces te quito la televisión. c) Si el número de visitas es a lo más 15, estarán todos en la sala. Hay visitas en la recámara. Es porque vinieron más de 15. d) Ese muchacho se llama Juan o Pedro. No se llama Juan. Entonces se llama Pedro. 98 Lógica proposicional 2.6.5.- Construye las siguientes derivaciones (a) p → q, r → s, ¬ q ∨ ¬ s ⊢ ¬ p ∨ ¬ r (b) ⊢ p ∨ (p ∧ ¬ q → r) (c) ⊢ p ∨ (¬ p ∧ q) → p ∨ q (d) ⊢ (p → q) → (p ∨ q → q) (e) ⊢ (¬ p ∧ (¬ p ∧ q)) ∨ (p ∧ (p ∧ ¬ q)) ↔ (¬ p ∧ q) ∨ (p ∧ ¬ q) 2.7. Tableaux semánticos para el cálculo proposicional Una de las preocupaciones de la lógica proposicional (y de la de predicados que veremos más adelante) es la de determinar si una fórmula bien formada4 (fbf ) es o no razonable. Esto último quiere decir que deseamos determinar si existe algún estado en el que la fórmula se evalúe a verdadero; o dicho de otra manera, si hay alguna asignación posible a las variables proposicionales que participan en la fórmula de tal manera que ésta se evalúa a verdadera (dicho de una tercera forma, si la fórmula tiene modelo). Uno de los mecanismos que podemos utilizar para determinar si una fórmula es razonable es la de elaborar la tabla de verdad de la misma. Sin embargo, como ya hemos mencionado, la tarea de elaborar tablas de verdad cuando estamos hablando de fórmulas de más de tres o cuatro variables se vuelve un problema intratable, ya que tendremos que examinar 2n posibles estados. Un mecanismo que permite de manera eficiente y segura determinar si una fórmula es tautologı́a, contradicción o contingencia, y encontrar un estado para el cual la fórmula se evalúa a verdadera son los tableaux. 2.7.1. El concepto de tableau Un tableau corresponde a un árbol cuya función es buscar una interpretación para determinada fórmula. Los tableaux toman la forma de un árbol, parecido a los árboles de derivación. Las fórmulas que van a ser representadas en un tableau deben consistir únicamente de conjunciones y disyunciones de literales, que son fórmulas atómicas (true, false, p, q, r, . . .) o negaciones de ellas (¬true, ¬false, ¬p, ¬q, ¬r, . . .). Estas fórmulas no pueden tener ningún otro operador, pero esto no nos debe preocupar ya que vimos que es posible eliminar la implicación y la bicondicional sustituyéndolas por disyunciones y conjunciones. También podemos eliminar la negación de una fórmula disyuntiva o conjuntiva (¬(p ∧ q)) utilizando 4 En inglés well-formed formula (wff ) 99 2.7 Tableaux en cálculo proposicional  las leyes de De Morgan ¬(p ∧ q) ≡ ¬ p∨¬q . Es importante, sin embargo, mantener la asociatividad de los operadores dada por la fórmula original (preservar la precedencia original o sea trabajar con fórmulas donde todos los paréntesis que indican precedencia son explı́citos). La construcción de tableaux tiene realmente muy pocas reglas. Veámoslas: 1. La fórmula para la que deseamos construir el tableau aparece como raı́z del árbol. 2. Si el esquema de la fórmula es una disyunción (A ∨ B), de la raı́z del subárbol se abren dos ramas, una para la fórmula A y otra para la fórmula B, como podemos ver en la figura 2.4. Figura 2.4 Construcción de tableau para la disyunción (a) (b) ¬(p ∨ q) ∨ (p → q) A∨B ¬(p ∨ q) p→q A (c) p ∨ ¬q ∨ r B p ∨ ¬q r Como el operador ∨ es conmutativo y asociativo, se pueden intercambiar el orden de las ramas de los árboles. También utilizamos la propiedad asociativa de la disyunción en el caso de la fórmula del tableau 2.4(c) y decidimos “abrir” primero la segunda disyunción. Por lo pronto, dejamos a los tableaux desarrollados únicamente en el primer nivel, lo que deja ramas que deben ser expandidas en el primer y tercer caso. Más adelante veremos cuándo y cómo conviene extender un tableau. Conforme se avanza en la fórmula, se va “componiendo” con el árbol que se tiene hasta ese momento. Lo que debe quedar claro es que en la fórmula 2.4(a) no podemos extender, tal como están, a ninguna de las fórmulas en el segundo nivel del árbol, ya que no corresponden a esquemas de disyunción o conjunción; en esta expresión, la fórmula de la izquierda corresponde a un esquema de negación, mientras que la segunda es una condicional; ası́ que por lo pronto posponemos su extensión hasta que demos las reglas de transformación para tableaux. En cambio, en la fórmula 2.4(c) sı́ tenemos en la rama izquierda un esquema de disyunción, por lo que ya podemos expandirla, quedando el 100 Lógica proposicional tableau como se muestra en la figura 2.5. Figura 2.5 Desarrollo completo del tableau de la fórmula 2.4(c) p ∨ ¬q ∨ r p ∨ ¬q p r ¬q 3. Si el esquema de la fórmula es una conjunción (A ∧ B) se pone a uno de los operandos como hijo del otro (como el operador ∧ es conmutativo, el orden no importa). Podemos ver tres ejemplos en las figuras 2.6 a 2.8. En la fórmula de la figura 2.6 tenemos un esquema de conjunción, donde cada uno de los operandos es una variable proposicional. Figura 2.6 Primer ejemplo de tableau para representar conjunciones p∧q p q 101 2.7 Tableaux en cálculo proposicional En la fórmula de la figura 2.7 abajo, tenemos un esquema de conjunción donde cada operando es, a su vez, una disyunción. Entonces, listamos los dos operandos, uno abajo del otro (el orden no importa) y procedemos a construir el tableau para uno de ellos, en este caso el primero. Una vez que tenemos en el tableau como hojas únicamente variables proposicionales que ya no pueden descomponerse más, colgamos de cada una de las ramas al otro operando y procedemos a abrirlo. Mostramos en el tableau de la figura 2.7(b) el nivel intermedio para la fórmula r ∨ q, aunque esto no es necesario, sino que podrı́amos haber colgado directamente la conjunción, como se ve en el tercer tableau de esta fórmula. Figura 2.7 Segundo ejemplo de tableau para representar conjunciones (a) (b) (c) (p ∨ ¬q) ∧ (r ∨ q) (p ∨ ¬q) ∧ (r ∨ q) (p ∨ ¬q) ∧ (r ∨ q) p r∨q r∨q r∨q p ∨ ¬q p ∨ ¬q p ∨ ¬q ¬q r p ¬q r∨q r∨q q r p r ¬q q r q q Para la tercera fórmula tenemos también un esquema de conjunción. Como la con junción es asociativa, podemos asociar (¬p ∨ q) ∧ (¬ q ∨ r) ∧ (¬p ∨ r), que es como lo hicimos, o pudiéramos usar también la conmutatividad de este operador. Listamos los tres operandos uno abajo del otro y desarrollamos el tableau del último (¬ p ∨ r) como primer paso. A continuación colgamos de todas las ramas de este tableau al segundo operando (¬ q ∨ r) y lo tachamos – ya no pusimos la subfórmula original explı́citamente en el árbol –. Una vez que tenemos únicamente variables proposicionales como hojas del tableau, como tercer paso colgamos de cada una de las ramas a la primera fórmula (¬ p ∨ q). El tableau construido de esta manera es el último en la figura 2.8. 102 Lógica proposicional Figura 2.8 Tercer ejemplo de tableaux con disyunción (¬p ∨ q) ∧ (¬q ∨ r) ∧ (¬p ∨ r) (b) (a) (c) ¬p ∨ q ¬p ∨ q ¬p ∨ q ¬p ∨ r ¬p ∨ r ¬p ∨ r ¬q ∨ r ¬p ¬q ∨ r r ¬p ¬q ∨ r ¬p r ¬q r ¬q r ¬q ¬p r ¬q r q ¬p q ¬p r q ¬p q Este caso es, claramente, un poco más complicado que el caso de la bifurcación. La intención con la que se construyeron los árboles (tableaux) es la de que, como se trata de una conjunción, cualquier “camino” en el árbol debe contemplar a todos los operandos de la conjunción. En el primer ejemplo, simplemente tenemos dos variables proposicionales, por lo que las ponemos en el árbol a una de ellas como descendiente de la otra. En el segundo ejemplo, desarrollamos uno de los operandos de la disyunción y de cada hoja, en la que hay únicamente variables proposicionales, “colgamos” a la otra proposición desarrollada como tableau. Como el tableau para r ∨ q es un tableau con dos ramas, éste se cuelga tanto de p como de ¬ q. El tercer ejemplo consiste de dos operadores ∧ (tres operandos). En el primer nivel colocamos (es arbitraria esta elección) al tercer operando. Una vez que lo desarrollamos completo, colgamos de cada una de las ramas el segundo operando, a su vez desarrollado ya en un tableau; por último, tenemos que colocar el operando que nos falta, ¬ p∨q, colgándolo de cada una de las ramas que llevamos hasta el momento. El orden no es importante, siempre y cuando hayamos incluido para desarrollar a todas las subfórmulas en la manera en que indicamos. Dado que únicamente tenemos reglas de construcción para la disyunción y la conjunción, debemos decidir qué hacer con aquellas fórmulas que involucren otros operadores. Tenemos dos opciones: transformar la fórmula antes de construir el tableau, usando propiedades de los operadores, asociatividad, conmutatividad y las Leyes de De Morgan, y 103 2.7 Tableaux en cálculo proposicional proceder después a desarrollar el tableau de la fórmula resultante. Otra opción es ir transformando las subfórmulas durante la construcción del tableau. Esta estrategia nos puede ahorrar trabajo por razones que no tardaremos en explicar. Además, es la que más se beneficia del uso de tableaux. 2.7.2. Eliminación de ramas del tableau Como dijimos antes, vamos a utilizar los tableaux para determinar si una fórmula es satisfacible o no. Por como están construidos, si seguimos un camino dentro del tableau vamos a tener la conjunción de variables proposicionales. Por ejemplo, en el caso del tableau de la figura 2.6 simplemente tenemos que el único camino en el árbol es salir de p y llegar a q. Pero en el caso del tableau de la figura 2.7, el camino (p∨¬q)∧(r ∨q) nos indica la subfórmula ¬q ∧ q, que es una contradicción, por lo que “siguiendo” esa rama ya no va a satisfacer a la fórmula (la conjunción será evaluada a falso). Cada vez que encontramos, en un camino (una rama) dentro del árbol, una literal y su literal complementaria5 , podemos cerrar esa rama y ya no extenderla más, pues no importa qué fórmulas le colguemos a ese camino tendremos una conjunción con falso, lo que hace a la fórmula representada por ese camino falsa. Denotamos que un camino está cerrado colocando el sı́mbolo ⊗. En la figura 2.7 se habrı́a eliminado una rama, como se puede observar en la figura 2.9. Figura 2.9 Cierre de ramas en la figura 2.7 p ∨ ¬q p r ¬q q r q ⊗ Por ejemplo, el tableau de la figura 2.8 no presenta ninguna rama cerrada que nos ahorre trabajo – ver figura 2.10 –. 5 La literal complementaria de una literal dada L se define como A si L es ¬A y como ¬A, si L es A. 104 Lógica proposicional Figura 2.10 Cierre de ramas en un tableau ¬p∨r ¬p r ¬q ¬p ¬q r q ⊗ ¬p q ¬p r q ⊗ ¬p q Sin embargo, hasta ahora únicamente hemos podido cerrar ramas que ya están totalmente desarrolladas, y lo que queremos es ahorrar trabajo, esto es, cerrar ramas lo antes posible. Si hubiésemos seguido otro orden en la doble conjunción en la fórmula de la figura 2.8, buscando que aparezcan lo antes posible una literal y su complementaria, habrı́amos podido llevar a cabo menos trabajo. Por ejemplo, si el orden en que colgamos del tableau es (¬ p ∨ q), (¬ q ∨ r) y por último (¬ p ∨ r), tenemos lo antes posible la contradicción, como se muestra en la figura 2.11. Figura 2.11 Orden de armado del tableau para cerrar lo más pronto posible ¬p∨r ¬q∨r ¬p ∨ q q ¬p ¬q ¬p ¬q ⊗ r r ¬p r r ¬p r Las ramas que cerremos ya no tiene sentido seguir expandiéndolas y eso nos va a ahorrar trabajo. Si todas las ramas quedan cerradas la fórmula es una contradicción; sin em- 105 2.7 Tableaux en cálculo proposicional bargo, el que todas las ramas queden abiertas no significa que tenemos una tautologı́a. Como ejemplo veamos la fórmula de la figura 2.6, donde todas sus ramas (exactamente una) quedaron abiertas y, sin embargo, esta fórmula sólo será verdadera en el caso en que I(p) = I(q) = 1; en caso de que algunas ramas queden abiertas y otras cerradas se trata de una fórmula contingente . Para determinar si una fórmula es tautologı́a tenemos que construir el tableau para su negación; si en este tableau se cierran todas las ramas, tenemos que la negación de la fórmula es contradicción y por lo tanto la original es tautologı́a. 2.7.3. Reglas para los tableaux Vamos a optar por ir “abriendo” las fórmulas conforme las vamos incluyendo en el tableau; la razón para ello es que si nos encontramos con ramas cerradas antes de agregar alguna conjunción, nos ahorramos el trabajo de transformar la regla. Como en el caso del razonamiento ecuacional y de la sustitución textual, es muy importante determinar cuál es el esquema principal que estamos procesando: cuál es el operador que domina. Las reglas que podemos usar para transformar las fórmulas y poderlas agregar al tableau en desarrollo se encuentran a continuación. • α-reglas: 1. De A ∧ B se deduce A y B. 2. De ¬(A ∨ B) se deduce ¬A y ¬B. 3. De ¬(A → B) se deduce A y ¬B. α(1) α(2) α(3) • β-reglas: 1. De A ∨ B se deduce A y, en una rama separada, B. 2. De ¬(A ∧ B) se deduce ¬A y, en una rama separada, ¬B. 3. De A → B se deduce ¬A y, en una rama separada, B. β(1) β(2) β(3) • σ-reglas: 1. De ¬¬A se deduce A. 2. De ¬false se deduce true. 3. De ¬true se deduce false. σ(1) σ(2) σ(3) Las reglas σ son auxiliares y pueden evitarse usando razonamiento ecuacional. • Reglas de cierre: 1. Cerrar cualquier rama que tenga A y ¬A (para cualquier A), o bien tenga ¬ true, o false. Veamos algunos ejemplos de construcción de tableaux. (cierre) 106 Lógica proposicional Ejemplo 2.42.    Demostrar ⊢ (p → q) → p → p , construyendo el tableau correspondiente a su negación. De lo anterior, usando α(3) tenemos:       ¬ (p → q) → p → p = (p → q) → p ∧ ¬ p , por lo que pasamos a desarrollar el tableau de esta conjunción en la figura 2.12. Figura 2.12 Construcción del tableau para el ejemplo 2.42 Fórmula:  ¬ Regla usada:   (p → q) → p → p ≡  (p → q) → p   (p → q) → p ∧ ¬ p  α(3) α(1) ¬p  (p → q) → p ¬ (p → q) ∨ p ¬ (p → q) p ⊗ p∧¬q p ⊗ β(3) α(3) cierre cierre Vemos que no queda ninguna rama abierta, lo que denota a una contradicción. Como el tableaux se armó para la negació n de la fórmula original y tenemos una contradicción para esta fórmula, podemos deducir que la fórmula original es una tautologı́a. Ejemplo 2.43. Demostrar que el silogismo hipotético es una tautologı́a:    (P → Q) ∧ (Q → R) → (P → R) Para demostrar que esta fórmula es tautologı́a trabajamos con su negación:    ¬ (P → Q) ∧ (Q → R) → (P → R) Ver figura 2.13 en la siguiente página para el desarrollo del tableau correspondiente. 107 2.7 Tableaux en cálculo proposicional Figura 2.13 Construcción del tableau para el ejemplo 2.43 Regla usada: Fórmula:  (P → Q) ∧ (Q → R) ∧ ¬ (P → R) α(3) ¬ (P → R) P ∧¬R ¬ (P → R) a P ∧¬R α(3) P ¬R Q ¬P ⊗ ¬Q ⊗ P →Q a ¬P ∨Q β(3) Q→R β(3) a ¬Q∨R R ⊗ Como todas las ramas están cerradas la fórmula es una contradicción y, por lo tanto, la fórmula original es tautologı́a (lo que ya sabı́amos). 2.7.4. Modelo de una fórmula Al desarrollar un tableau para una fórmula dada trataremos de trabajar lo menos posible, esto es, abrir el menor número de ramas posibles. Ya vimos que una rama cerrada no tiene sentido seguirla extendiendo; las estrategias usadas deberán ir en la dirección de cerrar lo antes posible una rama. Estas estrategias las podemos resumir de la siguiente manera: 1. Descomponer primero las fórmulas que no abran ramas; es decir, usar las α-reglas y las σ-reglas antes que las β-reglas. 2. Dar prioridad a la descomposición de fórmulas que cierren ramas. 3. Parar cuando el problema esté resuelto (para demostrar satisfacibilidad basta con encontrar una rama abierta completa). 4. Cuando no sirvan las estrategias anteriores, empezar por las fórmulas más complejas (habrá luego menos ramas en las que desarrollar la fórmula compleja). 108 Lógica proposicional El tableau de una fórmula también nos proporciona una interpretación para la fórmula que es modelo de la misma. De hecho, cada rama completa que queda abierta corresponde a una interpretación de la fórmula. Por lo tanto, para encontrar un modelo de una fórmula basta encontrar una rama abierta completa. La interpretación que corresponde a esa rama es como sigue: 1. Las variables que aparecen negadas en esa rama se les asigna el valor 0. 2. Las variables que aparecen sin negar en esa rama se les asigna el valor 1. 3. Aquellas variables que aparecen en la fórmula pero no en esa rama pueden tener cualquier asignación. Nótese que no puede haber ninguna variable a la que se tuviera que asignar 0 y 1 en una misma rama, porque esto querrı́a decir que aparece negada y sin negar, en cuyo caso la rama se habrı́a cerrado. 2.7.5. Algoritmos para la lógica proposicional Los tableaux son muy útiles en lógica proposicional pues proporcionan diversos algoritmos de decisión, algunos de los cuales enunciamos a continuación. ¿Es A una tautologı́a? Objetivo: Definir si A es tautologı́a. Entrada: A. Salida: La decisión de si A es o no tautologı́a. Método: • Construir el tableau T para ¬A. • Si T se cierra entonces A es tautologı́a. • En otro caso existe una rama abierta y completa en T la cual genera un modelo de ¬ϕ, por lo que ϕ no es tautologı́a. Para saber si una fórmula es tautologı́a (o para demostrarlo), construimos el tableau de la negación de la fórmula; si este tableau corresponde a una contradicción, entonces la fórmula es tautologı́a. Este algoritmo se puede adaptar fácilmente para obtener uno que decida si A es una contradicción, observando que una fórmula es una contradicción si y sólo si todas las ramas de su tableau se cierran. Sin embargo, obsérvese que no podemos decir que una fórmula es tautologı́a si todas sus ramas quedan abiertas, porque pudiera haber interpretaciones que no fueran modelo. Por ejemplo, la fórmula p ∨ q, cuyo tableau aparece a continuación, 109 2.7 Tableaux en cálculo proposicional p∨q p q es un tableau (muy simple) en el que todas las ramas quedaron abiertas y sin embargo no es tautologı́a. Lo único que podemos concluir, respecto a interpretaciones, es que I1 (p) = 1 e I2 (q) = 1 son modelos de esta fórmula (la variable que no se menciona en cada una de las interpretaciones puede tomar cualquier valor). Si se desea clasificar una fórmula en tautologı́a, contradicción o contingencia se usa el siguiente algoritmo. Objetivo: Clasificar una fórmula A. Entrada: Una fórmula A que deseamos clasificar como tautologı́a, contradicción o contingencia. Salida: El dictamen de si la fórmula es tautologı́a, contradicción o contingencia. Método: • Construir el tableau T de A. • Si T se cierra entonces A es contradicción. • En otro caso, existe una rama abierta y completa en T que proporciona un modelo I de A. • Construir el tableau T ′ para ¬A. • Si T ′ se cierra entonces A es tautologı́a. • En otro caso T ′ tiene una rama abierta y completa que proporciona un modelo I ′ de ¬A. • Las interpretaciones I e I ′ muestran que A es contingente. Con respecto a conjuntos de fórmulas tenemos los siguientes algoritmos. Satisfacibilidad de un conjunto de fórmulas Γ. Objetivo: Decidir la satisfacibilidad de un conjunto de fórmulas Γ Entrada: Un conjunto de fórmulas Γ = {A1 , . . . , An }. Salida: La decisión de si Γ es o no satisfacible. Método: • Construir el tableau T para A1 ∧ A2 ∧ . . . ∧ An . • Si T se cierra entonces Γ es insatisfacible. • En otro caso existe una rama abierta y completa en T , la cual genera un modelo de Γ, por lo que este conjunto es satisfacible. ¿Es A consecuencia lógica de Γ? 110 Lógica proposicional Objetivo: Decidir la consecuencia lógica Γ |= A. Entrada: Un conjunto de fórmulas Γ y una fórmula A. Salida: La decisión de si A es consecuencia lógica de Γ (sı́ o no). Método: • Construir el tablero T para el conjunto Γ ∪ {¬A}. • Si T se cierra entonces la consecuencia lógica Γ |= A se da y el argumento que representa es correcto. • En otro caso, existe una rama abierta y completa en T por lo que la consecuencia es inválida y se genera un modelo de las premisas Γ donde la conclusión A es falsa. Como ya se ha visto, los tableaux son un mecanismo para derivación de fórmulas y demostración de teoremas que resulta mucho más económico, en términos de trabajo, que el razonamiento ecuacional, por interpretaciones o mediante derivaciones; adicionalmente, es algorı́tmico, ya que siempre termina y no hay que ser creativos en el orden de abrir los tableaux; en el peor de los casos, haremos un poco más de trabajo, pero está garantizado que terminamos con la respuesta correcta. Ejercicios 2.7.1.- Construye el tableau correspondiente a cada una de las fórmulas, sin cerrar ramas. Para poder hacerlo, primero transforma a la fórmula para que tenga únicamente conjunciones y disyunciones de literales.  (a) (p ∨ q) ∧ (r → ¬ p) → (r → q)  (b) (p → q) → p → (q → p)  (c) (p ∨ q) ∧ (p ∨ r) → p  (d) (p → q) ∧ (q → r) → (¬ r → ¬ p)   (e) (r ∨ ¬ s) ∨ t ∧ ¬ ((p ∨ ¬ q) ∧ (¬ q ∨ ¬ p)  (f) ¬ (p → q) ∧ (q → p) (g) (p → q) ∨ r 2.7.2.- Usando tableaux, determina cuál de las siguientes fórmulas es tautologı́a, contradicción o contingente.    (a) (p ∨ q) ∨ r ∧ p ∨ (q ∨ r) → p ∨ q   (b) p ∧ (q ∧ r) → p → (q → r) 2.7 Tableaux en cálculo proposicional 111 (c) p ∨ q → p ∨ r  (d) p → (p → q) → p 2.7.3.- Demuestra que las siguientes fórmulas son tautologı́as usando tableaux: (a) (p → q) ∧ ( r → s) ∧ (¬ q ∨ ¬ s) → ¬ p ∨ ¬ r (b) p ∨ (p ∧ ¬ q → r) (c) p ∨ (¬ p ∧ q) → p ∨ q (d) (p → q) → (p ∨ q → q) (e) (¬ p ∧ (¬ p ∧ q)) ∨ (p ∧ (p ∧ ¬ q)) ↔ (¬ p ∧ q) ∨ (p ∧ ¬ q) 2.7.4.- Para los ejercicios 2.7.2 y 2.7.3, usando los tableaux construidos, da un modelo para las fórmulas y para sus negaciones en el caso de que sean contingentes, ası́ como un modelo contraejemplo para los argumentos incorrectos. 2.7.5.- Determinar si los siguientes conjuntos de fórmulas Γ son satisfacibles en cuyo caso dar un modelo. a) b) c) d) e) Γ = {¬p ∧ q, (r → p ↔ ¬q) ∨ ¬r, ¬(r ∨ ¬p)}  Γ = {r → ¬(p ∧ ¬q), (p → r) → (¬q ↔ r) ∧ ¬r, ¬(q ∧ q)} Γ = {(p ∧ r) ∨ (¬r → q), (q ↔ r) → (¬q → r), ¬p ∧ q ∧ ¬r} Γ = {p ∧ ¬q → ¬r, (¬p → ¬q) ∧ ¬r, r ∧ q ∧ ¬r} Γ = {¬q → ¬r, p, (¬q → p) → q, ¬r → p, s → q, r ∨ p} 2.7.6.- Usando tableaux, determina la correctud de los siguientes argumentos. (a) (p → q) ∧ (p → r)/ ∴ q → r (b) p ∨ q → r, s → p, s/ ∴ r (c) p ∨ q, ¬ (p ∧ r), ¬ q/ ∴ r → s (d) p → q, p ∨ r, ¬ (r ∧ s)/ ∴ (p → q) → (q ∨ ¬ s) 2.7.7.- ¿Por qué es que se pueden cerrar ramas si es que aparece una literal y la literal complementaria en un camino dentro del tableau? 2.7.8.- Explica en tus propias palabras por qué los tableaux no se pueden construir para fórmulas que tienen otros operadores que no sean la conjunción y la disyunción. Lógica de predicados 3 3.1. Introducción Hemos utilizado fórmulas de la lógica proposicional siempre que se trata de representar proposiciones en español, esto es, enunciados que son falsos o verdaderos. Analicemos los siguientes enunciados: • • • • • Todo plátano es amarillo. Algunas especies de pájaros migran. Todos los vaqueros usan sombrero. Ningún perro maúlla. Baja California Sur es el único estado de la República Mexicana con mar en tres de sus cuatro bordes. Se puede observar que todos y cada uno de los enunciados anteriores es una proposición pues tiene un valor de falso o verdadero. Sin embargo difieren de las estudiadas anteriormente pues no reconocemos en los enunciados palabras correspondientes a conectivos lógicos, por lo que la única manera que tenemos, por el momento, de formalizarlos es simplemente con una sola variable proposicional asignada a todo el enunciado. El lenguaje de la lógica proposicional estudiado en el capı́tulo anterior no tiene suficiente poder expresivo para analizar proposiciones y argumentos que requieren de una clase de 114 Lógica de predicados enunciados como los anteriores, que contienen referencias a colectividades de objetos. Considérese por ejemplo el siguiente razonamiento: Algunas personas van al teatro. Todos los que van al teatro se divierten. De manera que algunas personas se divierten. La intuición dice que el argumento es correcto. Sin embargo la representación correspondiente en lógica proposicional es: p, q / ∴ r ¡Incorrecto! Esta situación nos permite concluir únicamente que el argumento en lógica proposicional es incorrecto en el sentido de que la conclusión no es consecuencia lógica de las premisas. Sin embargo, a partir de este hecho no es posible concluir que el argumento en lenguaje natural sea incorrecto, pues podrı́a ser que lo sea en base a ciertos principios lógicos más fuertes. Tal posibilidad requiere el desarrollo de un lenguaje de especificación formal más poderoso, ası́ como una lógica adecuada al mismo, llamada lógica de predicados. 3.1.1. Predicados Consideremos los siguientes enunciados: • Cualquier empleado tiene un jefe. • Algunos programas usan ciclos. • Hay una lista que está ordenada. Como acabamos de argumentar, para representar a cada uno de estos enunciados la única forma de hacerlo, con las herramientas que tenemos hasta el momento, es mediante fórmulas proposicionales atómicas, es decir, mediante una simple variable proposicional para cada una de ellos. De los dos ejemplos anteriores vemos que esta representación no es adecuada, ya que no es capaz de reflejar la estructura interna del enunciado, algo de lo que no debemos sustraernos. Buscamos una herramienta lógica que tome en cuenta, de alguna manera, a esa estructura interna. Por ejemplo, el enunciado algunos programas usan ciclos trata acerca de programas, ciclos y la acción de usar. Estas componentes de la estructura interna de un enunciado se clasifican como individuos (u objetos) y propiedades (o relaciones) atribuibles a los individuos; a estas últimas es a las que llamamos predicados. Tanto los individuos como los predicados se definen en un contexto particular dependiendo del problema que queramos representar. Este contexto se conoce como universo de discurso, el cual es una colección de todas las personas, ideas, cosas, estructuras de datos, etcétera, necesarios para analizar una fórmula o argumento lógico. Veamos algunos ejemplos para hacer la distinción entre predicados e individuos en universos de discurso. En cada caso los individuos se encuentran encerrados en una caja y los predicados son las partes del enunciado que describen las relaciones entre ellos, ası́ como las acciones que los individuos llevan a cabo; por ejemplo, ser colegas; ser padre de; ser canario; ser la suma de; usar; visitar; ir; jugar; etcétera. 115 3.1 Introducción El universo de discurso son personas: • Isabel y Marı́a son colegas. • Pedro es el padre de Juan . El universo de discurso son los animales: • Piolı́n es un canario. • Claudio es un gallo. El universo son números: La suma de 2 y 3 es 5 . El producto de 10 y -2 es negativo. El universo consta de lenguajes de programación, algoritmos y programas: • Haskell es un lenguaje funcional con el que se puede escribir el algoritmo quicksort en una lı́nea. • Este programa en Java usa clases . El universo puede constar de diversas clases de individuos, como en el caso de que los siguientes enunciados se usen en un mismo contexto: • La infanta Christina visita museos . • El teatro al que la condesa Karla Michelle fue ayer tiene asientos cómodos. • Su majestad Martha Elena III y el perro imperial Bu juegan en el jardı́n de palacio. En el caso de estos enunciados, el universo tiene al menos personas, animales y lugares. Aunque parezca que podemos utilizar lógica proposicional para representar a los individuos y relaciones, esto no es ası́. Por ejemplo, no tiene sentido decir que el primer enunciado se formaliza como p ∧ q donde p significa Isabel es colega y q significa Marı́a es colega, ya que la conjunción de estos dos enunciados no consigue explicar la relación de colegas entre Isabel y Marı́a. En lógica de predicados utilizamos la notación P (t1 , t2 , . . . , tn ) para describir que la propiedad o relación P se da entre los individuos t1 , t2 , . . . , tn . Expresemos algunos de los ejemplos que dimos arriba con esta nueva notación: 116 Lógica de predicados • Colegas(Isabel,Marı́a), con P =ser colegas, t1 =Isabel y t2 =Marı́a. • P adre(Pedro,Juan), con P = padre de, t1 =Pedro y t2 =Juan. • Canario(Piolı́n), con P = ser canario y t1 = Piolı́n. • Suma(2, 3, 5), con P = suma, t1 = 2 y t2 = 3 son los sumandos y t3 = 5 es el resultado. Podemos ver de estos ejemplos que cada predicado P recibe un número distinto de argumentos de entrada t1 , . . . , tn – escribimos el nombre de los predicados con mayúsculas para distinguirlos de las funciones –. Al número de argumentos de un predicado le llamamos el ı́ndice o aridad del predicado. También vemos que el orden, en muchos de ellos, es importante. Por ejemplo, el predicado P adre tiene un significado muy distinto si cambiamos el orden de los argumentos, lo mismo que el predicado Suma. Una vez que se ha definido un predicado con un determinado ı́ndice, queda prohibido cambiarle el ı́ndice posteriormente. Por ejemplo, en el primer predicado, Colegas, el ı́ndice es 2, lo cual impide formar expresiones como Colegas(Juan, Lupe, Rosa), aun cuando esto tenga sentido desde nuestra intuición. Si se desea utilizar un número de argumentos distinto al definido inicialmente por el ı́ndice, es necesario definir otro predicado, por ejemplo Colegas′ (Juan, Lupe, Rosa). Los predicados de ı́ndice uno, es decir de un solo argumento, reciben el nombre especı́fico de propiedades. 3.1.2. Variables y cuantificadores Hasta ahora el uso de predicados en lugar de variables proposicionales podrı́a parecer simplemente otra manera de escribir enunciados. Por ejemplo, la proposición Anastasia recita poesı́a nórdica, se representa con predicados como Recita(Anastasia, poesı́a nórdica), lo cual parece ser simplemente una manera distinta de escribir el mismo enunciado en español. La principal diferencia es que el predicado puede cambiar de argumentos, como en Recita(Licantro, odas en sánscrito). Más aún, podemos sustituir individuos por variables, como en Recita(x, y). De esta manera podemos definir predicados de manera más formal, como los que siguen: • F (x, y) significa que x es padre de y. • E(x) significa que x es un estudiante • J(x, y) significa que x es más joven que y. 117 3.1 Introducción Es de importancia remarcar que los nombres de las variables no importan siempre y cuando se usen de forma consistente. Sin embargo, obsérvese que las expresiones anteriores no corresponden a proposiciones, puesto que los valores de x e y están indeterminados, por lo que resulta imposible verificar si el predicado Recita se cumple. Las variables juegan el papel de representantes de valores concretos, como un estudiante, un número o un programa particular. Obsérvese entonces que un mismo predicado puede representar un número potencialmente infinito de proposiciones, una por cada individuo que pueda tomar el lugar de cada una de las variables del predicado. Consideremos ahora los siguientes enunciados: • • • • • • • • • • Hay un gato rayado. Algunas personas van al teatro. Todos los programas en Java usan clases. Todos los estudiantes trabajan duro. Algunos estudiantes se duermen en clase. Ocho de cada diez gatos lo prefieren. Nadie es más tonto que yo. Al menos seis estudiantes están despiertos. Hay una infinidad de números primos. Hay más computadoras PC que Mac. Todos estos enunciados tienen en común el hecho de que no involucran a ningún individuo en particular. Aun cuando tenemos predicados a nuestra disposición, necesitamos un mecanismo para formalizar las partes de los enunciados que se refieren a una cantidad, como todos, algunos, hay, nadie, cualquiera, . . . . A estas cantidades es a lo que llamamos cuantificadores. Por ejemplo, para el enunciado Todos los estudiantes son más jóvenes que algún profesor, entendiendo que el universo de discurso son las personas de la Facultad de Ciencias, serı́a inoperante escribir todos los posibles predicados para estudiante, profesor y ser más joven, E(Karla), E(Hugo), . . . , P (Elisa), P (Favio), J(Karla,Favio),. . . . Más aún, en algunos casos esto resulta imposible, como con la frase hay una infinidad de números primos. Este problema se soluciona al emplear operadores de cuantificación sobre individuos indeterminados, ∀ (se lee para todo) y ∃ (se lee existe), los cuales siempre van seguidos de una variable que representa a los individuos de la colectividad que se está especificando. Por ejemplo, para decir todos hablan español escribimos ∀xE(x) donde E(x) significa que x habla español. Similarmente, si C(x) significa que x es cuervo, entonces para especificar que hay un cuervo escribimos ∃xC(x). Más aún, usando cuantificadores en combinación con la lógica proposicional, podemos representar enunciados más complejos, como por ejemplo todos los estudiantes son más jóvenes que algún profesor cuya especificación es 118 Lógica de predicados como sigue: ∀x(E(x) → ∃y(P (y) ∧ J(x, y))), donde queda claro que P (x) significa x es profesor; E(x) significa que x es estudiante y J(x, y) significa que x es más joven que y. A continuación vamos a definir el lenguaje formal de la lógica de predicados que incluye todos los elementos discutidos hasta ahora, para después volver al tema de especificación formal. 3.2. Sintaxis de la lógica de predicados En esta sección definimos formalmente lo que se conoce como un lenguaje de la lógica de predicados de primer orden, el cual, a diferencia del caso proposicional, varı́a dependiendo del universo de discurso particular y de las relaciones y propiedades de los individuos que se deseen especificar. 3.2.1. Términos Los términos son la categorı́a sintáctica que representa individuos del universo de discurso. Definición 3.1 Un término es una constante, una variable o bien un sı́mbolo de función aplicado a otros términos. Los términos se generan mediante la siguiente gramática. En los casos en que aparezca una coma (“,”), ésta es parte de la sintaxis. El metası́mbolo “. . .” significa “más de los anteriores” y no forma parte de los sı́mbolos terminales de la gramática. term term term var var var var const ::= ::= ::= ::= ::= ::= ::= ::= var const func(lista-de-term) x y z ... a (3.1) (3.2) (3.3) (3.4) (3.5) (3.6) (3.7) (3.8) ::= ::= ::= ::= ::= ::= ::= lista-de-term ::= lista-de-term ::= const const const func func func func b c ... f g h ... term term, lista-de-term (3.9) (3.10) (3.11) (3.12) (3.13) (3.14) (3.15) (3.16) (3.17) 3.2 Sintaxis de la lógica de predicados 119 Cada sı́mbolo de la categorı́a func tiene asociado un número fijo de argumentos (el ı́ndice o aridad del sı́mbolo). A veces escribimos f (n) para indicar que el sı́mbolo f tiene ı́ndice n. Veamos a continuación algunos ejemplos. Ejemplo 3.1. Supongamos que el universo consta de los paı́ses del mundo. • Las variables x e y denotan a paı́ses cualesquiera. • La constante a denota a Alemania y la constante b a Brasil. • El sı́mbolo funcional f de ı́ndice 1 denota a la operación que recibe un paı́s y devuelve su ciudad capital. Es decir, f (x) es la capital de x. Esto es posible dado que cada paı́s tiene una única capital de manera que dicha asociación es funcional. En particular f (a) denota a Berlı́n y f (b) a Brasilia. Ejemplo 3.2. Si el universo consta de números naturales, entonces: • La constante a denota al individuo 0 y la constante b al individuo 1. • Los términos funcionales f (2) (x, y) y g (2) (x, y) denotan a los individuos x + y y x ∗ y respectivamente. • En tal caso, los individuos 2 y 4 se representan mediante f (b, b) y g(f (b, b), f (b, b)) respectivamente. 3.2.2. Fórmulas Una vez definidos los términos podemos construir las fórmulas del lenguaje, las cuales representan a las relaciones entre individuos, ası́ como a los enunciados generales del lenguaje. Empecemos con las fórmulas más simples, las atómicas. Definición 3.2 Una fórmula atómica es una expresión de la forma P (t1 , . . . , tn ), donde P es un sı́mbolo de predicado de ı́ndice n y t1 , . . . , tn son términos. Ejemplo 3.3. Definimos los sı́mbolos de predicado P (2) , R(3) , Q(1) , los sı́mbolos de función f (1) y g (2) y las constantes a, b y c. Las siguientes son fórmulas atómicas: • P (b, f (y)) • Q(g(f (a), c)) • R(z, f (g(a, c)), b) 120 Lógica de predicados Ahora que tenemos fórmulas atómicas, podemos combinarlas con los conectivos proposicionales para obtener fórmulas más complejas. Ejemplo 3.4. En el universo de discurso de los números naturales, si a + b = c + b entonces a = c. Definimos las constantes a, b, c y los siguientes sı́mbolos de función: f (x, y) para representar igual(x, y) para representar x+y x=y Y la especificación queda como sigue: igual(f (a, b), f (c, b)) → igual(a, c) Ejemplo 3.5. En la expresión Bombón es un gato que araña tenemos lo siguiente: a) El universo de discurso son los animales (los mamı́feros, los felinos, cualquier conjunto, raza o familia que incluya a los gatos). b) Los predicados que definimos son: G(x) x es un gato A(x) x araña Siendo Bombón uno de los individuos concretos del universo de discurso, estará representado por una constante, su propio nombre. La expresión lógica queda como sigue: G(Bombón) ∧ A(Bombón) Otros ejemplos son: P erro(x) → T ienecola(x) M adre(x, y) ∧ M adre(x, z) → Hermanos(y, z) Calif (x) → x ≥ 0 ∧ x ≤ 10 Obsérvese que en el último ejemplo los predicados ≥, ≤ se usan de manera infija como es usual en matemáticas. ¿Cual es el universo de discurso en cada caso? De los ejemplos anteriores se observa que las fórmulas con predicados se generan de la misma manera que las fórmulas de la lógica proposicional, sólo que las fórmulas atómicas 3.2 Sintaxis de la lógica de predicados 121 han cambiado de simples variables proposicionales a predicados que involucran términos. Veamos la gramática formal, en la que usamos el metası́mbolo “|” para separar alternativas de sustitución para un mismo sı́mbolo no terminal de manera abreviada, y el metası́mbolo “. . .” para denotar “más como los anteriores”. E ::= pred(lista-de-term) (3.18) E ::= ¬E (3.19) E ::= E → E (3.20) E ::= E ∨ E (3.21) E ::= E ∧ E (3.22) E ::= E ↔ E (3.23) E ::= (E) (3.24) pred ::= P | Q | R | . . . (3.25) lista-de-term ::= term (3.26) lista-de-term ::= term, lista-de-term (3.27) Nuevamente cada sı́mbolo de la categorı́a pred tiene asociado un número fijo de argumentos. 3.2.3. Fórmulas cuantificadas Finalmente definimos las fórmulas que involucran cuantificadores, las cuales proporcionan una gran expresividad al lenguaje. Definición 3.3 Sea E una fórmula. La expresión ∀xE es la cuantificación universal de E con respecto a x y representa al enunciado para todo x se cumple E. Análogamente, la expresión ∃xE es la cuantificación existencial de E con respecto a x y representa al enunciado existe un x que cumple E. En ambos casos la fórmula E se conoce como el alcance de la cuantificación y la variable que figura inmediatamente después del cuantificador se conoce como variable del cuantificador. Una pregunta común es el porqué en la cuantificación universal se prefiere el formato P (x, . . .) → Q(x, . . .), mientras que en la cuantificación existencial se prefiere la forma P (x) ∧ Q(x). Cuando tenemos una cuantificación universal, examinaremos a todo el universo de discurso para comprobar que todo aquel que cumple P (x, . . .), también cumple Q(x, . . .). Si el individuo que estamos examinando no cumple P (x, . . .) no nos interesa qué pasa con Q(x, . . .), por lo que queremos que la cuantificación sea verdadera fijándonos únicamente en aquellos individuos que cumplen P (x, . . .). Si usáramos el esquema 122 Lógica de predicados P (x, . . .) ∧ Q(x, . . .), la cuantificación serı́a falsa si en el universo de discurso hubiese individuos que no cumplen con P (x, . . .). En el caso de la cuantificación existencial deseamos encontrar en el universo de discurso al menos a un individuo que cumpla con P (x, . . .) y Q(x, . . .). Su usamos la fórmula P (x, . . .) → Q(x, . . .), al examinar al primer individuo que no cumpla con P (x, . . .) darı́amos por buena la cuantificación, pues en el caso de que el antecedente sea falso, la condicional es verdadera; no seguirı́amos revisando el universo de discurso para ver si encontramos a un individuo que cumpla con P (x, . . .); la cuantificación se evaluarı́a a verdadero aun cuando no existiese ningún individuo como el que queremos. Con la conjunción garantizamos que tiene que existir al menos un individuo que cumpla con ambos predicados. Pasemos a ver algunos ejemplos. Ejemplo 3.6. Supongamos que el universo de discurso es el universo astronómico. Sea S(x) el predicado ser sol y P (x) el predicado ser planeta. Vamos a traducir algunos enunciados sencillos que involucran cuantificadores. • • • • ∀xS(x) ∀yP (y) ∃x∃y(P (x) ∧ S(y)) ∀z(P (z) ∨ S(z)) Todo es un sol: Todo es un planeta: Existe un planeta y un sol: Cualquiera es sol o planeta: En la sección 3.3 discutiremos el proceso de especificación más ampliamente. A continuación ejemplificamos el concepto de alcance. Ejemplo 3.7. Veamos un ejemplo de los alcances de cuantificaciones. Encerraremos en un cuadro los alcances, marcando a la variable de las cuantificaciones correspondientes. x ∀x  x>i∧i>j  → ∃ i∃j i, j   x>i∧x>j El recuadro de guiones marca el alcance de la cuantificación ∀x mientras que el recuadro de lı́nea sólida marca el alcance de las cuantificaciones ∃i y ∃j. Agregamos a la gramática que acabamos de dar para la lógica de predicados las reglas que describen a la cuantificación universal y existencial como fórmulas lógicas: E ::= ∀ var E E ::= ∃ var E (3.28) (3.29) 123 3.2 Sintaxis de la lógica de predicados con lo cual nuestra gramática para fórmulas de la lógica de predicados queda completa. 3.2.4. Variables libres y ligadas Consideremos el enunciado todos son blancos; si deseamos especificarlo formalmente, primero debemos definir un predicado B(x) cuyo significado es x es blanco, para después cuantificar universalmente, obteniendo la fórmula ∀xB(x). Ahora bien, consideremos la fórmula ∀yB(y), ¿qué enunciado en español se especifica ahora? Fácilmente nos damos cuenta de que su significado es nuevamente todos son blancos, es decir, el nombre particular de la variable utilizada, en este caso x o y, es irrelevante para entender el significado de la fórmula. Por esta razón a la variable de un cuantificador se le conoce también como variable artificial o monigote1 , porque únicamente marca el lugar o la posición. En contraste, consideremos las fórmulas B(x) y B(y), y supongamos que el universo son los números naturales, siendo B el predicado ser par. Con esta información no es posible entender el significado2 de estas fórmulas, pues hace falta saber el valor de sus variables. Por ejemplo, si x es 3 entonces B(x) significa 3 es par, mientras que si y vale 8 entonces B(y) significa 8 es par, de donde claramente B(x) y B(y) no significan lo mismo, pues su significado depende del valor particular de sus variables. La pregunta inmediata es: ¿cuándo es relevante el valor particular de una variable para conocer el significado y valor de verdad de una fórmula? Para responderla introducimos los conceptos de variable libre y ligada. Definición 3.4 Se dice que una presencia especı́fica de una variable x en una fórmula A está libre si no es la variable artificial de un cuantificador ni figura dentro del alcance de una cuantificación cuya variable artificial también es x. En la siguiente tabla presentamos algunas fórmulas y la lista de variables libres de cada una de ellas. Cuantificación  ∀x (x > i ∧ i > j) → (x > j) ∃x x > i ∧ i > j) Variables libres i, j i, j  ∀i∀j (x > i ∧ i > j) → (x > j)  ∀i (x > i ∧ i > j) → (x > j) x, j ∃j x > i ∧ i > j) i, x ∃i∃j x > i ∧ i > j) x x Las variables que no figuran libres en una fórmula se denominan ligadas o acotadas. Veamos una definición más detallada. 1 2 En inglés dummy El valor de verdadero o falso 124 Lógica de predicados Definición 3.5 Decimos que una presencia determinada de una variable x en una fórmula A es ligada o acotada si x es una variable artificial de A o cae dentro del alcance de un cuantificador con la misma variable artificial x. Los enunciados en español se formalizan mediante fórmulas que no tienen variables libres, a las cuales llamamos también enunciados, sentencias o fórmulas cerradas. Definición 3.6 Un enunciado es una fórmula A que no contiene presencias libres de variables. Ejemplo 3.8. En la expresión (1) (2) (3) (4) i > 0 ∨ ∀ i (0 ≤ i → x· i = 0) tenemos cuatro presencias de i. La primera presencia de i, anotada con (1), es una presencia libre, pues no se encuentra dentro de ninguna cuantificación. El valor que contribuya a la expresión dependerá del estado en el que se la evalúe. La segunda presencia es la variable artificial de un cuantificador por lo que es ligada. Las otras dos presencias de i también son ligadas, el valor de la cuantificación no depende del valor particular que tenga i. Finalmente, la presencia de x es una presencia libre y su contribución a la expresión dependerá también del estado en el que se evalúe la expresión. Ejemplo 3.9. En la expresión (1) (2) (3) (4) (5) (6) ( k + j ) > 0 ∧ ∃ j (0 ≤ j ≤ 5∧ k < j ) las presencias (1) y (5) de k son presencias libres, pues en el primer caso la k se encuentra fuera de la cuantificación y aunque en el segundo caso se encuentra dentro de una cuantificación, la variable artificial es j, no k. La presencia (2) de j es distinta que las presencias (3), (4) y (6), pues mientras la primera se encuentra fuera de una cuantificación y es, por lo tanto, presencia libre, las otras tres se encuentran dentro de una cuantificación donde la variable artificial es ella misma, por lo que son presencias acotadas. El valor de esta fórmula dependerá del estado en el que se evaluen los valores libres de j y k. Puede suceder que el usar una misma variable (j en el ejemplo anterior) para dos papeles distintos – el papel de presencia libre en (2) y de presencia acotada en (4) y (6) – lleve al lector a confusión. En estos casos es recomendable cambiar el nombre a todas las presencias ligadas de la variable en cuestión que participan directamente en la cuantificación para eliminar confusiones. De hacer esto, la expresión que dimos arriba quedarı́a como sigue: (1) (2) (3) (4) (5) (6) ( k + j ) > 0 ∧ ∃ i (0 ≤ i ≤ 5∧ k < i ) 3.2 Sintaxis de la lógica de predicados 125 El concepto de variables libres o acotadas es similar al que presentan los lenguajes de programación con estructura de bloques. En ellos tenemos la posibilidad de anidar pedazos de código de la siguiente manera: 1 2 3 4 5 6 7 var i : i n t e g e r ; procedure p ( var x : i n t e g e r ) ; var i : i n t e g e r ; begin i := x * x ; x := 2 * i ; end La presencia de i en la lı́nea 1 es libre, ya que no se encuentra dentro de un bloque. La presencia de x en 2 es ligada y hace el papel de una declaración, pues le da nombre a una variable artificial. Las presencias de x en 5 y 6, ası́ como las presencias de i dentro del procedimiento son acotadas (lı́neas 5 y 6), ya que estos identificadores sólo tienen significado dentro del procedimiento. Si cambiáramos los identificadores de x a y en todas las presencias acotadas, y de i a k también en las presencias acotadas, el procedimiento obtenido es 1 2 3 4 5 6 7 var i : i n t e g e r ; procedure p ( var y : i n t e g e r ) ; var i : i n t e g e r ; begin k := y * y ; y := 2 * k ; end y hace exactamente lo mismo que el original. Para terminar esta sección deseamos hacer hincapié en lo siguiente: • Al trabajar con predicados es muy importante que el universo de discurso esté bien definido y sea claro. • Los términos y las fórmulas son ajenos, es decir ningún término es fórmula y ninguna fórmula es término. • Los términos denotan exclusivamente a individuos u objetos. • Las fórmulas atómicas (predicados) denotan únicamente proposiciones o propiedades acerca de los términos. • Únicamente los individuos u objetos son cuantificables. Esta caracterı́stica justifica la denominación primer orden que se le da a la lógica de predicados que estamos estudiando. 126 Lógica de predicados Ejercicios 3.2.1.- Sean f (2) y g (3) sı́mbolos de función y d una constante. ¿Cuáles de las siguientes expresiones son términos? Justifica tu respuesta. a) g(d, d) b) f (x, g(y, z), d) c) g(x, f (y, z), d) d) f (d, x) e) g(d, g(x, y, f (z, d)), f (f (d, x), w)) f ) g(g(y, y, f (d, d)), f (w, g(d, x, y))) 3.2.2.- Sean a una constante, f (1) un sı́mbolo de función y P (2) , Q(2) y R(1) sı́mbolos de predicado. ¿Cuáles de las siguientes expresiones son fórmulas? Justifica tu respuesta. a) P (a, x) b) Q(a, f (a)) c) f (a) d) Q(Q(a, x), x) e) R(Q(x, x)) f ) P (f (y), a) g) R(f (w)) h) Q(¬R(x), w) i) P (x, y) → ∃zQ(z, y) j) ∀f Q(f (y), y) k) ¬R(f (z)) ∨ ¬Q(a, f (w)) l) ∀x∃yQ(x, y) ∧ R(w) 3.2.3.- Sean c y d constantes, f (1) , g (2) y h(3) sı́mbolos de función y P (3) y R(2) sı́mbolos de predicado. ¿Cuáles de las siguientes expresiones son fórmulas? Justifica tu respuesta. a) Q(c, d, c) b) ∀xP (f (d), h(g(c, x), d, y)) c) ∀xP (f (d), h(R(y, y), d)) d) ∃wP (g(h(x, f (d), x), g(w, w)), h(x, x, x), c) 3.2 Sintaxis de la lógica de predicados 127 e) ∃u(Q(z, z, z) → R(y, y)) f ) ∀x∀y(g(x, y) → P (x, y, x)) 3.2.4.- Para cada una de las siguientes fórmulas, clasifica todas las presencias de variables en libres o ligadas. Además da el alcance de cada cuantificador. a) R(x, y) ∧ L(y) b) ∀xR(x, f (y, z)) ∧ L(y) c) R(f (x, y), z) ∧ ∃yR(f (y, x), z) → ∀wI(x, y) d) ∀x(C(x, z) ∧ R(f (y, x), f (x, y))) → C(y, z) e) ∃x∃yR(x, y) ∧ C(x, y) f ) C(f (x, y), z) ∧ ∃yC(f (y, x), z) → ∀x(L(x) ∧ L(y) ∧ I(x, y)) g) ∃yC(x, y) ∨ ∃zR(x, z)  h) ∀x L(x) → R(f (x, a), x) ∧ C(f (x, a), a) i) ∃yC(a, y) ∨ L(a)  j) ∃y I(f (x, y), f (y, x)) ∧ D(r(x)) . k) D(f (x, y)) ∨ ∀zC(z, r(y)).  l) ∃y C(x, f (y, z)) ∧ D(y) ∧ ∀xI(z, r(y)) . m) ∀x∃zI(z, r(x)) → C(z, y) ∧ D(y). 3.2.5.- Para cada una de las siguientes fórmulas, clasifica todas las presencias de variables en libres o ligadas. Además da el alcance de cada cuantificador.  a) ∀x∃z Q(z, y) ∧ ∃yR(x, f (x)) b) P (x, a, y) ∨ ∃y(P (x, y, a) ∧ R(a, z)) c) W (f (x, a), g(y)) ∧ ∀x∃yS(f (x, a), g(z)) d) ¬R(f (x, x), w, g(x)) ∧ ∀x∃yT (x, y, g(z)) e) ∀wT (w, x, g(y)) → ¬∃zR(x, f (w, y)) 3.2.6.- Construye para cada inciso una fórmula A que cumpla las condiciones dadas. a) A es un enunciado que es una cuantificación de una implicación donde el consecuente es una fórmula existencial. b) A es un enunciado y es una cuantificación existencial de una conjunción. c) A es una fórmula que incluye cuantificadores pero tiene al menos tres presencias libres de exactamente dos variables. 128 Lógica de predicados d) A es un enunciado y una disyunción de un enunciado atómico con una fórmula existencial cuyo alcance es un predicado ternario. e) A es una fórmula que no es un enunciado y tiene dos cuantificadores universales con variables distintas, un cuantificador existencial y además se convierte en un enunciado al cuantificarla universalmente. 3.3. Especificación formal El proceso de especificación o traducción del español a la lógica formal no es siempre sencillo. Algunas frases del español no se pueden traducir de una manera completamente fiel a la lógica de predicados, como veremos en algunos ejemplos. Sin embargo, el proceso es de gran importancia pues es la base de muchos métodos de especificación formal utilizados en inteligencia artificial o ingenierı́a de software (como ejemplo tenemos el lenguaje de especificación Z). A continuación presentamos algunos consejos, observaciones y ejemplos que pretenden facilitar la especificación del español en términos de la lógica. • Únicamente podemos especificar afirmaciones o proposiciones; no es posible traducir preguntas, exclamaciones, órdenes, invitaciones, etcétera. • La idea básica es extraer predicados a partir de los enunciados dados en español, de manera que el enunciado completo se construya al combinar fórmulas atómicas mediante conectivos y cuantificadores. Por ejemplo, la frase me gustan los tacos y las pizzas debe traducirse como me gustan los tacos y me gustan las pizzas. Análogamente iré de vacaciones a la playa o a la montaña significa iré de vacaciones a la playa o iré de vacaciones a la montaña. • La conjunción “y” se traduce como ∧. La palabra “pero” también, aunque el sentido original del español se pierde. Por ejemplo te doy dulces pero haces la tarea sólo puede traducirse en Te doy dulces y haces la tarea, lo cual es diferente en el lenguaje español. • La disyunción es incluyente: comeremos pollo o vegetales incluye el caso en que se coman ambos. • Con la implicación hay que ser cautelosos, sobre todo en el caso de frases de la forma A sólo si B lo cual es equivalente con Si no B entonces no A, que a su vez es equivalente con Si A entonces B. Es un error común intentar traducir dicha frase inicial mediante B → A. • Si en el español aparecen frases como para todos, para cualquier, todos, cualquiera, los, las, debe usarse el cuantificador universal ∀. 3.3 Especificación formal 129 • Si en el español hay frases como para algún, existe un, alguno, alguna, uno, una, alguien, generalmente se usa el cuantificador existencial ∃. Importante: En ciertas ocasiones, frases en español que involucran alguien, algo deben especificarse con un cuantificador universal y no un existencial. Por ejemplo, el enunciado si hay alguien demasiado alto entonces se pegará con el marco de la puerta se puede reescribir en español como cualquiera demasiado alto chocará con el marco de la puerta, lo cual nos lleva a ∀x(A(x) → C(x)). El lector debe convencerse de que no es posible traducir esta oración usando un cuantificador existencial. • Pronombres como él, ella, eso no se refieren a un individuo particular sino que se usan como referencia a algo o alguien mencionado previamente, por lo que obtienen significado del contexto particular. Cuando un pronombre aparezca en un enunciado debe uno averiguar primero a quién o qué se refiere. Por ejemplo, en el enunciado Martha es amiga de Lupita pero ella no es amiga de Karla debe traducirse como Martha es amiga de Lupita y Lupita no es amiga de Karla. Similarmente, cuando necesitamos de variables, como en hay un perro con manchas y él ladra en las mañanas es un error tratar de traducir por separado hay un perro con manchas y él ladra en las mañanas puesto que lo que existe está ligado con lo que ladra por la conjunción, de manera que debe utilizarse una variable que modele esta conexión. • Las variables no se mencionan en español sino que son sólo un formalismo para representar individuos. Por ejemplo, la fórmula ∀x(M (x) → T (x)) puede traducirse como Cualquier minotauro es troyano y no como para cualquier x, si x es minotauro entonces x es troyano. Enunciados de esta forma sólo sirven como pasos intermedios en el proceso de traducción pues no forman parte del español correcto ni de la lógica formal. A este mismo respecto es prácticamente imposible que en una traducción del español figuren variables libres. • Los esquemas ∀x(A → B) y ∃x(A ∧ B) son de gran utilidad y bastante comunes. Menos comunes, aunque también adecuados, son los esquemas ∀x(A∧B), ∀x(A∨B) y ∃x(A∨B) . • El esquema ∃x(A → B), si bien es una fórmula sintácticamente correcta, es extremadamente raro que figure en una traducción del español. • El hecho de que se usen dos o más variables distintas no implica que éstas representen a elementos distintos del universo, de manera que para especificar dos individuos distintos no es suficiente contar simplemente con variables distintas. Las fórmulas ∃xP (x) y ∃x∃y(P (x)∧P (y)) expresan ambas lo mismo, a saber que algo cumple P . Se debe agregar explı́citamente que x e y tienen la propiedad de ser distintos, es decir x 6= y. 130 Lógica de predicados 3.3.1. Juicios aristotélicos Una gran parte de las especificaciones en lenguaje natural pueden formalizarse mediante instancias de alguno de los cuatro juicios aristotélicos básicos, los cuales se refieren a dos relaciones y expresan las posibilidades de que éstas se cumplan o no en ciertos individuos. Ejemplo 3.10. Tomemos como universo de discurso al reino animal. Vamos a construir los llamados juicios aristotélicos fundamentales a partir de las propiedades ser perico y ser feo. Primero definimos los predicados necesarios: P (x) x es perico F (x) x es feo (a) Juicio universal afirmativo: Todos los pericos son feos, ∀x(P (x) → F (x)). (b) Juicio existencial afirmativo: Algunos pericos son feos, ∃x(P (x) ∧ F (x)). (c) Juicio existencial negativo: Algunos pericos no son feos, ∃x(P (x) ∧ ¬F (x)). (d) Juicio universal negativo: Ningún perico es feo, lo cual es equivalente a decir que cualquier perico no es feo o bien todos los pericos no son feos; de manera que las dos siguientes especificaciones son correctas: ¬∃x(P (x) ∧ F (x)), ∀x(P (x) → ¬F (x)). En el siguiente ejemplo nos servimos de juicios aristotélicos para obtener especificaciones más complejas. Ejemplo 3.11. Tenemos los siguientes predicados en el universo de discurso de los habitantes de la Ciudad de México: I(x) x es inteligente E(x) x es estudiante de la Facultad de Ciencias M (x) a x le gusta la música Especificar con cuantificaciones los siguientes enunciados: • Todos los estudiantes de la Facultad de Ciencias son inteligentes. ∀x(E(x) → I(x)) 131 3.3 Especificación formal • A algunos estudiantes inteligentes les gusta la música. ∃x(E(x) ∧ I(x) ∧ M (x)) • Todo aquel a quien le gusta la música es un estudiante que no es inteligente. ∀x(M (x) → E(x) ∧ ¬ I(x)) Ejemplo 3.12. En este ejemplo observamos el significado de las distintas combinaciones de dos cuantificaciones. Sea Q(x, y) el predicado x quiere a y. ∀x∃yQ(x, y) • Todos quieren a alguien: ∃x∀yQ(x, y) • Alguien quiere a todos: ∃x∀yQ(y, x) • Alguien es querido por todos: • Todos se quieren, o bien, todos quieren a todos: • Algunos se quieren entre sı́, o bien alguien quiere a alguien: ∃x∃yQ(x, y) ∃x∀y¬Q(y, x) • Alguno no es querido por nadie: ∃x∀y¬Q(x, y) • Alguien no quiere a nadie: ∀x∃y¬Q(x, y) • Todos no quieren a alguien: ¬∃x∀yQ(x, y) • Nadie quiere a todos: ∀x∀y¬Q(x, y) • Nadie quiere a nadie: 3.3.2. ∀x∀yQ(x, y) Negaciones Con frecuencia necesitaremos traducir la negación de una cuantificación, lo cual ejemplificamos a continuación. Ejemplo 3.13. La negación de una cuantificación puede obtenerse simplemente anteponiendo el operador de negación, por ejemplo: • No todos son leones se traduce como ¬∀xL(x). • No existen leones se traduce como ¬∃xL(x). Sin embargo, estas traducciones no proporcionan información suficiente y pueden mejorarse usando equivalencias intuitivas del español, como sigue: • No todos son leones es lo mismo que existe algo que no es león cuya traducción es: ∃x¬L(x) 132 Lógica de predicados • No existen leones es lo mismo que cualquiera no es león cuya traducción es: ∀x¬L(x) Por supuesto que en los dos casos ambas traducciones deben ser equivalentes en la lógica pues lo son en español. Analizaremos esto con más detalle en la subsección 3.4.4. Veamos un ejemplo más elaborado. Ejemplo 3.14. Traducir el enunciado no todos los planetas tienen una luna. Definimos los predicados P (x), L(x), T (x, y) para ser planeta, ser luna y x tiene a y respectivamente. • Lo más simple es especificar primero la cuantificación universal y anteponer la negación, obteniendo  ¬∀x P (x) → ∃y(L(y) ∧ T (x, y)) . • Otra opción es transformar la frase a una equivalente en español que permita una estructura lógica que nos dé más información. En este caso el enunciado original es equivalente a existe un planeta que no tiene lunas, cuya especificación es:  ∃x P (x) ∧ ¬∃y(L(y) ∧ T (x, y)) . • Es posible refinar aún más la traducción si observamos que la frase no existe una luna tal que x la tenga se puede reescribir como para toda luna, x no la tiene, obteniendo ası́ la especificación más refinada posible.  ∃x P (x) ∧ ∀y(L(y) → ¬T (x, y)) . 3.3.3. Contando objetos Como ya mencionamos al principio de esta sección, el hecho de usar variables diferentes no implica que se refieran necesariamente a individuos distintos, de manera que para representar cantidades particulares se requiere especificar explı́citamente que ciertos individuos no son iguales. Veamos algunos ejemplos. Ejemplo 3.15. En las siguientes especificaciones se utiliza el predicado binario de igualdad = de manera infija. Además las fórmulas del esquema ¬(t = s) se escriben como t 6= s, como es usual en matemáticas. • Hay al menos una luna, esto resulta equivalente a hay una luna: ∃xL(x). 133 3.3 Especificación formal • Hay más de una luna, es decir, existen al menos dos lunas: ∃x∃y(L(x) ∧ L(y) ∧ x 6= y). Obsérvese que se hace explı́cito el hecho de que las lunas denotadas por x e y son diferentes. • Hay al menos tres lunas. De manera similar al enunciado anterior usamos tres variables y hacemos explı́cito el hecho de que denotan a tres individuos diferentes: ∃x∃y∃z(L(x) ∧ L(y) ∧ L(z) ∧ x 6= y ∧ x 6= z ∧ y 6= z). En general es posible definir el enunciado hay al menos n objetos de manera análoga. Sin embargo es imposible especificar que existe una infinidad de objetos. ¿Por qué? • Existe un único sol. Lo usual aquı́ es especificar que hay un sol y que cualesquiera dos soles en realidad son iguales:  ∃x S(x) ∧ ∀y∀z(S(y) ∧ S(z) → y = z) . Este esquema es de gran utilidad en matemáticas y suele abreviarse como ∃! xP (x) para cualquier predicado P . • Hay a lo más un sol, lo cual es equivalente a Cualesquiera dos soles son el mismo. ∀x∀y(S(x) ∧ S(y) → x = y). Obsérvese que esta especificación incluye el caso en que no haya soles. Otra posibilidad es especificar que No es cierto que existen al menos dos soles. 3.3.4. Micromundos En inteligencia artificial un micromundo es un modelo artificialmente simple de una situación real; por ejemplo, si se desea programar un robot para que mueva objetos de manera inteligente, basta modelar los movimientos deseados sin tomar en cuenta sus dimensiones reales ni la cantidad total de objetos en juego, para lo cual basta considerar una idealización del mundo real con pocos objetos. A continuación especificamos algunas descripciones para dos micromundos similares a los utilizados en inteligencia artificial. El micromundo de cubos En este micromundo hay cubos de color amarillo, azul o rojo. Un cubo puede estar sobre otro o en el piso. Definimos los predicados S(x, y) representando que el cubo x 134 Lógica de predicados está sobre el cubo y; A(x), Az(x) y R(x) que representan que un cubo puede ser de color amarillo, azul o rojo respectivamente; L(x) significa que el cubo x está libre, es decir que ningún cubo está sobre el cubo x; y la constante p representa al piso. Veamos algunas especificaciones. • Ningún cubo amarillo está libre: ∀x(A(x) → ¬L(x)). • Hay un cubo azul libre y un cubo rojo libre:  ∃x∃y Az(x) ∧ L(x) ∧ R(y) ∧ (y) . • Cualquier cubo amarillo tiene un cubo sobre él:   ∀x A(x) → ∃y S(y, x) ∧ x 6= y . • No todos los cubos azules están libres: ∃x(Az(x) ∧ ¬L(x)) . • Hay un cubo azul sobre el piso con un cubo amarillo sobre él y un cubo rojo sobre el amarillo:   ∃x∃y∃w Az(x) ∧ A(y) ∧ R(w) ∧ S(x, p) ∧ S(y, x) ∧ S(w, y) . Un mundo de triángulos, cı́rculos y cuadrados El micromundo consta de una cuadrı́cula de cualquier tamaño donde en cada cuadro puede haber figuras que son cı́rculos, cuadrados o triángulos, las cuales pueden ser pequeñas, medianas o grandes. También se tienen las relaciones dadas por la posición: sur, norte, este, oeste; y las relaciones dadas por estar en la misma columna y en el mismo renglón. Los predicados para las figuras son: T (x), C(x) y S(x) para triángulo, cı́rculo y cuadrado respectivamente; para tamaño tenemos P (x), M (x) y G(x) para pequeño, mediano y grande. Para la posición tenemos Su(x, y), N (x, y), E(x, y) y O(x, y); por ejemplo N (x, y) significa x está al norte de y. Finalmente tenemos Co(x, y) y R(x, y) para indicar que x está en la misma columna o renglón que y, respectivamente. Hagamos algunas descripciones para este micromundo. • Hay cı́rculos medianos y cuadrados grandes:   ∃x C(x) ∧ M (x) ∧ ∃y S(y) ∧ G(y) . 135 3.3 Especificación formal • No hay cuadrados pequeños:  ∀x S(x) → ¬P (x) . • Hay un triángulo al sur de todos los cı́rculos:   ∃x T (x) ∧ ∀y C(y) → Su(x, y) . • No hay dos triángulos en el mismo renglón:  ¬∃y∃x T (x) ∧ T (y) ∧ R(x, y) . • Hay un cı́rculo tal que todos los cı́rculos al oeste de él son grandes:   ∃x C(x) ∧ ∀y C(y) ∧ O(y, x) → G(y) . Con esto terminamos esta sección y a continuación nos ocupamos brevemente de algunos aspectos semánticos de la lógica de predicados. Regresaremos a los micromundos después de revisar algunos conceptos relacionados. Ejercicios 3.3.1.- Para los siguientes predicados propón un universo de discurso adecuado: (a) (b) (c) (d) (e) A(x) menor(x, M ÍNIMO) P (x, y) R(x) mayor(x, 0) x tiene los pétalos amarillos x es menor que el mı́nimo x es padre de y x ruge x es mayor que 0 3.3.2.- Considera los siguientes enunciados donde se usan predicados. Determina cuáles son los predicados necesarios y escribe cada uno de los enunciados en cálculo de predicados. El universo de discurso es el conjunto de todas las personas. (a) (b) (c) (d) Los enemigos de mis enemigos son mis amigos. Los amigos van y vienen; los enemigos se acumulan. Juan aprecia a Marı́a y Marı́a aprecia a Lupita; entonces Juan aprecia a Lupita. Juan es familiar de Rosa; Rosa es familiar de Guillermo; entonces Juan es familiar de Guillermo. 136 Lógica de predicados 3.3.3.- Considera los siguientes enunciados donde se usan predicados. Determina cuáles son los predicados necesarios y escribe cada uno de los enunciados en cálculo de predicados. El universo de discurso es el conjunto de todos los animales. (a) (b) (c) (d) (e) (f) Los leones comen carne cruda. Sólo los leones rugen. El piquete de abejas duele mucho. La boa constrictora no es venenosa. La vı́bora de cascabel es venenosa. No hay mamı́feros venenosos. 3.3.4.- Considera los siguientes enunciados donde se usan predicados. Determina cuáles son los predicados necesarios y escribe el argumento lógico usándolos. El universo de discurso son los animales de la selva. (a) (b) (c) (d) Los leones son feroces. Los elefantes asustan a los leones. Los ratones asustan a los elefantes. De esto, los ratones asustan a animales feroces. 3.3.5.- Considera los siguientes enunciados donde se usan predicados. Determina cuáles son los predicados necesarios y escribe el argumento lógico usándolos. El universo de discurso son las computadoras asignadas a Ciencias de la Computación. La computadora x ha sido invadida (hackeada) desde la computadora y. La computadora x funciona con el sistema operativo Linux. La computadora x funciona con el sistema operativo Windows. El servidor del taller de Lenguajes de Programación, que funciona con Linux, no fue hackeado. (e) El servidor del taller de Ingenierı́a de Software, que funciona con Windows, sı́ fue hackeado. (f) Si una computadora tiene el sistema Linux no puede ser hackeada. (a) (b) (c) (d) 3.3.6.- Traduce los siguientes enunciados a cuantificaciones universales y (o) existenciales, donde el universo de discurso son los dı́as de la semana y suponiendo los predicados y constantes que siguen: • S(x) el dı́a x está soleado • N (x) el dı́a x está nublado • L la constante ”Lunes” • M la constante “Martes” 137 3.3 Especificación formal (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) Todos los dı́as están soleados. Algunos dı́as no están nublados. Todo dı́a que está soleado no está nublado. Algunos dı́as están soleados y nublados. Ningún dı́a es al mismo tiempo soleado y nublado. Siempre está soleado sólo si está nublado. Ningún dı́a es soleado. El lunes estuvo soleado, por lo que todos los dı́as estarán soleados. Se nubló el lunes y el martes. Si algún dı́a está nublado, entonces todos los dı́as estarán soleados. 3.3.7.- Escribe las fórmulas con cuantificadores de los siguientes enunciados, suponiendo que el universo de discurso son las personas y usando la siguiente asignación para los predicados: • • • • • (a) (b) (c) (d) (e) (f) J(x) A(x) M (x) Q(x) R(x, y) x es juez x es abogado x es mujer x es quı́mico x respeta a y Hay algunas abogados mujeres que son quı́micos. Ninguna mujer es abogado y quı́mico. Algunos abogados sólo respetan jueces. Los jueces respetan sólo a los jueces. Todas las abogados mujeres respetan a algún juez. Algunas mujeres no respetan a ningún abogado. 3.3.8.- Sea T (x, y) el predicado x puede tomarle el pelo a y, donde el dominio consiste de todos los seres humanos. Usa cuantificadores para expresar cada uno de los siguientes enunciados: (a) (b) (c) (d) (e) (f) Todo mundo puede tomarle el pelo a Juan. Marı́a puede tomarle el pelo a cualquiera. Cualquiera puede tomarle el pelo a alguien. Nadie puede tomarle el pelo a cualquiera. Siempre hay alguien que le puede tomar el pelo a cualquiera. Hay exactamente una persona a quien cualquiera puede tomarle el pelo. 138 Lógica de predicados (g) Hay alguien que puede tomarle el pelo a exactamente una persona distinta de sı́ mismo. 3.3.9.- Sea S(x) el predicado x es un estudiante, P (x) el predicado x es un maestro y Q(x, y) el predicado x le hace una pregunta a y, donde el dominio consiste de toda la comunidad de la Facultad de Ciencias. Traduce los siguientes enunciados a cuantificaciones: (a) Luisa le preguntó al Profesor Miguel una pregunta. (b) Cada estudiante le hizo una pregunta al Profesor Garcı́a. (c) Todo profesor ha hecho una pregunta al Profesor López o bien el Profesor Pérez les ha hecho una pregunta. (d) Algún estudiante no le ha hecho preguntas a ningún profesor. (e) Hay un profesor a quien ningún estudiante le ha hecho nunca ninguna pregunta. (f) Un estudiante le ha hecho preguntas a todos los profesores. (g) Hay un profesor que le ha hecho preguntas a cada uno de los profesores. (h) Hay un estudiante al que ningún profesor le ha hecho preguntas. 3.3.10.- Hacer las siguientes traducciones, definiendo previamente el universo de discurso y los predicados necesarios. (a) (b) (c) (d) (e) (f) Los perros muerden a los carteros. Existe un perro que muerde a los carteros. Existe un cartero que es mordido por todos los perros. Hay un perro que no muerde carteros. Hay un cartero que no es mordido por perros. Hay un perro que es cartero y se muerde a sı́ mismo. 3.3.11.- Traduce las siguientes oraciones a fórmulas, donde el universo de discurso son las novelas, usando los siguientes predicados: • S(x) x es una novela de espı́as • M (x) x es una novela de misterio • L(x) x es larga • M (x, y) x es mejor que y (a) (b) (c) (d) (e) Todas las novelas de espı́as son largas. No todas las novelas de misterio son una novela de espı́as. Sólo las novelas de misterio son largas. Algunas novelas de espı́as son de misterio. Las novelas de espı́as son mejores que las de misterio. 3.4 Semántica informal 139 (f) Sólo las novelas de espı́as son mejores que las de misterio. 3.3.12.- Traduce los siguientes argumentos a la lógica de predicados. Especifica el universo de discurso y explica el significado de cada predicado usado. (a) A algunos pacientes les caen bien todos los doctores. A ningún paciente le cae bien una enfermera. Por lo tanto ningún doctor es enfermera. (b) Todos los empleados de la empresa INC deben de saber usar Cobol. Todos los empleados de INC que escriben aplicaciones deben de saber Excel. Roxana trabaja para la empresa INC, pero ella no sabe Excel. Ingrid sabe Excel pero no Cobol. Por lo tanto Roxana no escribe aplicaciones e Ingrid no trabaja para INC. 3.3.13.- Expresa las siguientes especificaciones de un sistema de cómputo usando lógica de predicados. Declara previamente los predicados que vas a utilizar. (a) Si hay menos de 30 megabytes libres en el disco duro, se envı́a un mensaje de advertencia a todos los usuarios. (b) Ningún directorio puede abrirse ni ningún archivo puede cerrarse si se han detectado errores en el sistema. (c) El sistema de archivos no puede respaldarse si hay algún usuario con sesión activa. (d) Pueden recibirse archivos de video cuando hay al menos 8 megabytes de memoria disponible y la velocidad de conexión es al menos de 56 kilobits por segundo. 3.4. Semántica informal En esta sección nos dedicaremos a dar ciertas ideas acerca de la semántica de la lógica de predicados. Lo haremos de manera informal e intuitiva, dado que la semántica formal requiere de mecanismos matemáticos sofisticados que caen fuera del alcance de este libro. 3.4.1. Dominios de interpretación Antes de poder determinar cuándo una fórmula de la lógica de predicados es verdadera debemos formalizar el concepto de universo de discurso; eso se hace mediante un dominio de interpretación, el cual es un conjunto no vacı́o en el que se definirán matemáticamente los significados de los sı́mbolos de constante, predicado y función usados en las especificaciones formales, de manera que un sı́mbolo de constante será un individuo y los predicados y funciones serán operadores entre elementos del universo, que devuelven otro elemento 140 Lógica de predicados del universo en el caso de una función, o bien un valor booleano en el caso de un predicado. Veamos algunos ejemplos. Tabla 3.1 Distintos universos y dominios Con: Se representa a Operadores N Los números naturales 0, 1 + × mod div >, <, par?, primo? Los números naturales tienen definidas la suma y el producto. También tienen residuo entero (mod) y cociente entero (div). Como interpretación de constantes tenemos la identidad 1 y elemento nulo 0, ası́ como los operadores de decisión para orden, par y primo que corresponden a predicados. Z Los enteros + − × mod div neg?, | Los operadores para los números naturales siguen siendo válidos y agregamos la operación de resta, el operador de decisión ser negativo y el operador de divisibilidad. Q Números racionales Aquı́ ya es posible usar la división; tenemos además operadores que devuelven el numerador o denominador de un racional y el operador de simplificación que elimina factores comunes. R Los números reales ÷, num den simp etc. √ B Los booleanos {1, 0} ⌊ ⌋ ⌈ ⌉ rac? π e ∧, ∨ →, ↔ ¬ Comentarios: Agregamos las operaciones de raı́z cuadrada (válida sólo para reales positivos), mayor entero menor o igual, menor entero mayor o igual, el predicado ser racional y las constantes π y e B es el tipo booleano, que recibe su nombre del matemático inglés George Boole (1815-1864) que creó las bases algebraicas para la lógica. Los operadores son los mismos definidos en el capı́tulo dos. Continúa en la siguiente página 141 3.4 Semántica informal Tabla 3.1 Distintos universos y dominios Continúa de la página anterior Con: Se representa a Operadores Comentarios: MB Micromundo de cubos El universo es heterogéneo pues tiene al piso. Aquı́ se tienen predicados para los colores; si se desea tener una función que devuelva el color de un objeto es necesario añadir los colores al dominio y también predicados para decidir si un individuo es color o cubo. H Los seres vivos que pertenecen al reino Fungi FC La Facultad de Ciencias inscribir Un dominio donde hay personas, saloestudiar nes, clases, números de cuenta, libros, calificar apuntes, etc.. estudiante? profesor? reprueba? etc. MF Micromundo de figuras cuadrado? cı́rculo? triángulo? pequeño? al-norte? etc. En este dominio sólo hay figuras pero no es completamente homogéneo pues las figuras son de tres clases diferentes, por lo que necesitamos de los predicados para cuadrado, cı́rculo y triángulo. Sin embargo, y a diferencia de otros mundos heterogéneos, el dominio está claramente partido en tres clases distintas de objetos. MiBiblio Una biblioteca elegir prestar ordenar está? etc. El dominio es heterogéneo y debe contener libros, libreros, personas, etc. piso azul? verde? libre? sobre? arriba? mover etc. comestible? venenoso? =-familia? mismo? etc. Si se desean operaciones que devuelvan lugar de origen o dimensiones, por ejemplo, el dominio debe volverse heterogéneo para incluir lugares y números. 142 3.4.2. Lógica de predicados Noción informal de verdad Si el dominio de interpretación (universo de discurso) que esté en uso es finito, entonces podemos asignar el valor de falso o verdadero a cada predicado analizando todas las posibles combinaciones de individuos en dicho universo de discurso. Por ejemplo, si tenemos el predicado > (mayor que) y nuestro universo de discurso consiste de los enteros 1, 2, 3 y 4, entonces podemos hacer una tabla que asigne los valores de falso o verdadero a cada pareja de individuos, como podemos observar en la tabla 3.2 en la siguiente página. Tabla 3.2 Asignación para el predicado > (mayor que) > 1 2 3 4 1 0 0 0 0 2 1 0 0 0 3 1 1 0 0 4 1 1 1 0 Por supuesto que esto resulta más complicado si el universo es demasiado grande, como en el caso en que el universo conste de los enteros 1, . . . , 1000. Por otra parte, si el universo en cuestión consta de todos los números naturales, resulta imposible construir la tabla pues tendrı́a un número infinito de columnas y un número infinito de renglones: > 1 2 3 4 5 6 7 8 10 11 12 13 14 15 16 17 18 19 20 . . . . . . . . . 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ... 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ... 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ... 4 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ... .................. .................. Si el ı́ndice de un predicado es uno o dos y el universo finito, también es fácil ver la asignación en una tabla. Sin embargo, si el ı́ndice es tres o más, aunque el universo sea relativamente pequeño, ya no es fácil visualizar dicha asignación. De manera que el uso de 3.4 Semántica informal 143 tablas de verdad para la lógica de predicados es inadecuado. Esto es de esperarse, ya que la noción de verdad en lógica de predicados es mucho más complicada puesto que depende de un mundo en particular, al contrario de lo que sucedı́a en la lógica de proposiciones, donde en el fondo el único mundo o universo de discurso es el de los valores booleanos cierto o falso. En esta nueva lógica, el universo de discurso puede incluir literalmente cualquier cosa: números, conjuntos, piedras, flores, árboles, palabras, galaxias, etcétera. De manera que la noción de verdad dependerá del mundo que hayamos fijado de antemano. Por supuesto que al cambiar éste, el valor de verdad de una fórmula también puede hacerlo. Antes de dar una definición de verdad analicemos el caso de los cuantificadores con un ejemplo sencillo en el micromundo de figuras: • Todos son cı́rculos: ∀xC(x). Esto será cierto si y sólo si al revisar cada objeto del micromundo, el objeto resulta ser un cı́rculo. Si suponemos que hay n objetos, denotados por las constantes a1 , . . . , an , entonces ∀xC(x) será cierto si y sólo si C(a1 ) es cierta y C(a2 ) es cierta y . . . y C(an ) es cierta; es decir, si y sólo si la conjunción C(a1 ) ∧ . . . ∧ C(a1 ) es cierta. Obsérvese que esto no puede ser una definición, pues en el caso en que el universo sea infinito es imposible formar la conjunción de todos los objetos. • Existe algo pequeño: ∃xP (x). Similarmente a la cuantificación universal, esta fórmula es cierta si y sólo si alguno de los objetos a1 , . . . , an resulta ser pequeño, es decir, si la disyunción P (a1 ) ∨ . . . ∨ P (an ) es cierta. Esta idea intuitiva nos lleva a una definición informal de verdad para cualquier fórmula de la lógica de predicados, la cual damos a continuación. Definición 3.3.16 Dada una fórmula A de la lógica de predicados, definimos cuándo A es verdadera en un mundo o universo de discurso dado M, de acuerdo a su forma sintáctica, como sigue: • Si A es una fórmula atómica, digamos P (t1 , . . . , tn ), entonces A es verdadera en M si y sólo si los valores de los términos t1 , . . . , tn como individuos de M están en la relación del universo definida por P . • Si A es una fórmula proposicional3 , entonces usamos los criterios de verdad de la lógica proposicional. • Si A = ∀xB es una fórmula universal, entonces A es verdadera en M si y sólo si B es verdadera en M para todos los posibles valores de x como individuo de M. • Si A = ∃xB es una fórmula existencial, entonces A es verdadera en M si y sólo si B es verdadera en M para algún valor de x como individuo de M. 3 Es decir una fórmula que pertenece a algún esquema de la lógica proposicional, con predicados en lugar de variables proposicionales 144 Lógica de predicados Esta definición es informal puesto que en el caso en que el universo de discurso sea infinito, no queda claro en general cómo mostrar que la fórmula ∀xB es cierta para todos los valores posibles de x. 3.4.3. Verdad en micromundos A continuación regresamos a nuestros dos micromundos particulares empezando con el mundo de los cubos para ejemplificar la definición informal de semántica que acabamos de enunciar. Nos referiremos al mundo particular que se encuentra en la figura 3.1, a continuación. Figura 3.1 Micromundo de cubos rojo amarillo azul Queremos ahora determinar la semántica de algunas fórmulas en este micromundo. • Cualquier cubo rojo está libre:  ∀x R(x) → L(x) . Verdadero, pues los cubos rojos en la primera y cuarta torre, que son todos los cubos rojos en este micromundo, están libres. • Todos los cubos sobre el piso son azules:  ∀x S(x, p) → Az(x) . Falso, pues la primera y segunda torre tienen cubos amarillos sobre el piso, por lo que no todos los cubos sobre el piso son azules. • Cualquier cubo que esté sobre un cubo amarillo es rojo o azul:   ∀x ∃y(A(y) ∧ S(x, y)) → R(x) ∨ Az(x) . Cierto, ya que los cubos amarillos de la primera y cuarta torre tienen a un cubo rojo encima; y el cubo amarillo de la segunda torre tiene encima a un cubo azul. 145 3.4 Semántica informal • Hay un cubo rojo sobre un cubo rojo:  ∃x∃y R(x) ∧ R(y) ∧ S(x, y) . Falso. Los dos cubos rojos, en la primera y cuarta torre, son libres, por lo que no tienen encima a ningún cubo, en particular a uno rojo. • Hay un cubo amarillo libre sobre el piso:  ∃x A(x) ∧ L(x) ∧ S(x, p) . Falso. No hay ningún cubo libre sobre el piso, en particular que sea amarillo, por lo que la fórmula es falsa. • Ningún cubo está sobre el piso: ∀x ¬S(x, p) . Falso, pues el cubo amarillo en la primera torre sı́ está sobre el piso. • Hay un cubo amarillo que está sobre uno azul y hay un cubo azul sobre él:   ∃x∃y A(x) ∧ Az(y) ∧ S(x, y) ∧ ∃w Az(w) ∧ S(w, x) . Falso. No hay una torre que contenga una secuencia de cubo azul, cubo amarillo y cubo azul. • Todos los cubos están sobre algo: ∀x∃yS(x, y). Verdadera. Todos los cubos están o sobre el piso o sobre algún otro cubo. Veamos ahora un micromundo particular de figuras geométricas, en la figura 3.2 de la siguiente página, con los predicados que ya definimos para los mundos de figuras geométricas, y decidamos cuáles de las fórmulas que le siguen son falsas o verdaderas. Arriba del mundo observamos los tres tamaños de figuras disponibles. Además usaremos coordenadas para renglón y columna como un auxiliar para señalar cada cuadro en particular. • Hay cı́rculos medianos y cuadrados grandes:   ∃x C(x) ∧ M (x) ∧ ∃y S(y) ∧ G(y) . Falso, pues no hay ningún cı́rculo mediano. • No hay cuadrados pequeños:  ∀x S(x) → ¬P (x) . En (R3C2) hay un cuadrado pequeño, por lo tanto la fórmula es falsa. 146 Lógica de predicados Figura 3.2 Mundo particular de figuras geométricas R5 R4 R3 R2 R1 C1 C2 C3 C4 C5 C6 C7 C8 C9 • Ningún cuadrado está al norte de un cı́rculo grande:   ¬∃x S(x) ∧ ∃y C(y) ∧ G(y) ∧ N (x, y) . Falso, pues el cuadrado en (R3C5) sı́ está al norte del cı́rculo grande en (R2C3). • Todos los cı́rculos medianos están al oeste de un mismo triángulo grande:   ∃x T (x) ∧ G(x) ∧ ∀y C(y) ∧ M (y) → O(y, x) . Como sı́ hay un triángulo grande en (R4C5) pero no hay cı́rculos medianos, la implicación tiene antecedente falso y la fórmula se evalúa a verdadera. • Todos los cuadrados pequeños están al sur de cualquier triángulo:   ∀x S(x) ∧ P (x) → ∀y T (y) → Su(x, y) Los cuadrados pequeños están en (R3), pero no están al sur del triángulo en (R2C8), por lo que la fórmula es falsa. • Si dos cuadrados están en el mismo renglón, entonces cualquier triángulo al sur de ambos es mediano:   ∀x∀y S(x) ∧ S(y) ∧ R(x, y) → ∀z T (z) ∧ Su(z, x) ∧ Su(z, y) → M (z) . La fórmula es falsa pues para los dos cuadrados en (R3), ninguno de los triángulos al sur es mediano. 3.4 Semántica informal 147 • No hay dos triángulos medianos en la misma columna; y si un triángulo es grande, entonces hay un circulo pequeño al este de él:    ¬∃x∃y T (x) ∧ T (y) ∧ Co(x, y) ∧ ∀z T (z) ∧ G(z) → ∃w C(w) ∧ P (w) ∧ E(w, z) . El primer operando de la conjunción es verdadero, porque como no hay triángulos medianos, cualquier cosa que se diga de ellos es verdadera; tanto para el triángulo grande en (R4C5) como el de (R1C3), hay dos cı́rculos pequeños, (R4C7) y (R3C8), que se encuentran al este de cualquiera de ellos. Por lo tanto, el segundo operando de la conjunción es verdadero y la fórmula completa también. 3.4.4. Algunas equivalencias lógicas Con frecuencia un enunciado en español puede reescribirse de manera que la estructura lógica sea más clara, tal como lo hicimos en algunos ejemplos de la sección 3.3. En este caso ambos enunciados deben ser equivalentes, en el sentido de que cualquier conclusión obtenida con uno de ellos debe seguir siendo válida usando el otro. Esta situación se formaliza mediante el concepto de equivalencia lógica, que ya estudiamos para la lógica proposicional, y que en la lógica de predicados tiene el mismo significado: dos fórmulas A y B son lógicamente equivalentes, denotado A ≡ B, si y sólo si ambas son verdaderas exactamente en los mismos mundos o interpretaciones. A continuación discutimos algunas equivalencias lógicas de utilidad. Equivalencias proposicionales Todas las equivalencias lógicas para la lógica proposicional siguen siendo válidas en la lógica de predicados y pueden usarse también dentro de una cuantificación. Ejemplo 3.17. Las siguientes fórmulas son equivalentes debido al uso de una ley proposicional de equivalencia lógica. • Hay un cı́rculo grande es equivalente a hay alguna figura grande que es cı́rculo:   ∃x C(x) ∧ G(x) ≡ ∃x G(x) ∧ C(x) . • Cualquier figura o es triángulo o es mediana equivale a que toda figura que no es triángulo es mediana:   ∀x T (x) ∨ M (x) ≡ ∀x ¬T (x) → M (x) . • No es cierto que hay un cuadrado y que todas las figuras sean pequeñas significa lo mismo que o bien no hay cuadrados o bien no todas las figuras son pequeñas:  ¬ ∃xS(x) ∧ ∀yP (y) ≡ ¬∃xS(x) ∨ ¬∀yP (y). 148 Lógica de predicados • Si todas las figuras son cuadrados entonces no hay figuras grandes equivale a si existen figuras grandes entonces no todas son cuadrados: ∀xS(x) → ¬∃yG(y) ≡ ∃yG(y) → ¬∀xS(x). Negación de cuantificadores Volviendo a la idea de que una cuantificación puede entenderse como una conjunción o disyunción en el caso de un universo finito, podemos analizar de qué forma interactúan los cuantificadores con la negación. Por ejemplo, la fórmula ¬∀xC(x) (no todos son cı́rculos) es cierta si y sólo si la negación de la conjunción de todos los objetos del universo, dada  por ¬ C(a1 ) ∧ . . . ∧ C(a1 ) , es cierta; es decir, usando las leyes de De Morgan, ¬C(a1 ) ∨ . . . ∨ ¬C(a1 ) es cierta, lo cual equivale a la fórmula existencial ∃x¬C(x); o lo que es lo mismo, a existe algo que no es cı́rculo. Similarmente podemos analizar la negación de una fórmula existencial. Por esta razón es que las leyes de negación, que enunciamos enseguida, también se conocen como leyes de De Morgan generalizadas. Leyes de negación: ¬ ∀xA ≡ ∃x¬ A ¬ ∃xA ≡ ∀x¬ A (3.30) (3.31) Obsérvese que estas equivalencias permiten mover una negación hacia el alcance de un cuantificador, intercambiando cuantificadores. Ejemplo 3.18. Mostramos aquı́ el uso de las leyes de negación para transformar una fórmula de manera que la negación se aplique únicamente a predicados. • No es cierto que si hay un triángulo entonces todas los figuras son medianas.  ¬ ∃xT (x) → ∀yM (y) ≡ ∃xT (x) ∧ ¬∀yM (y) ≡ ∃xT (x) ∧ ∃y¬M (y). Hay un triángulo y no todas las figuras son medianas, lo que equivale asimismo a hay un triángulo y hay una figura que no es mediana. En lo que sigue, el dominio de interpretación son los habitantes de la Ciudad de México, los lapsos de tiempo y los exámenes; utilizaremos los siguientes predicados: F (x) : A(x) : E(x, y) : C(x) : x es estudiante de la Facultad de Ciencias x es alumno x estudia en el tiempo y el examen x fue calificado I(x) : T (x) : R(x) : P (x) : x es inteligente x es un tiempo x reprueba x es un examen 149 3.4 Semántica informal • No es cierto que todos los estudiantes de la Facultad de Ciencias sean inteligentes:   ¬∀x F (x) → I(x) ≡ ∃x¬ F (x) → I(x)  ≡ ∃x F (x) ∧ ¬I(x) Hay un estudiante inscrito en la Facultad de Ciencias que no es inteligente. • No hay alumnos que estudien todo el tiempo:   ¬∃x A(x) ∧ ∀y T (y) → E(x, y)   ≡ ∀x¬ A(x) ∧ ∀y T (y) → E(x, y)   ≡ ∀x ¬A(x) ∨ ¬∀y T (y) → E(x, y)   ≡ ∀x ¬A(x) ∨ ∃y¬ T (y) → E(x, y)   ≡ ∀x ¬A(x) ∨ ∃y T (y) ∧ ¬E(x, y)   ≡ ∀x A(x) → ∃y T (y) ∧ ¬E(x, y) Para cualquier alumno hay un tiempo en el que no estudia. • No es cierto que o algún examen no se calificó o todos los alumnos reprobaron el curso:    ¬ ∃x P (x) ∧ ¬C(x) ∨ ∀y A(y) → R(y)   ≡¬∃x P (x) ∧ ¬C(x) ∧ ¬∀y A(y) → R(y)   ≡∀x¬ P (x) ∧ ¬C(x) ∧ ∃y¬ A(y) → R(y)   ≡∀x ¬P (x) ∨ C(x) ∧ ∃y A(y) ∧ ¬R(y)   ≡∀x P (x) → C(x) ∧ ∃y A(y) ∧ ¬R(y) Todos los exámenes se calificaron y algún alumno no reprobó. Distributividad Una vez que hemos visto como interactúan los cuantificadores con la negación, resulta natural preguntarse qué sucede con los demás conectivos proposicionales frente a los cuantificadores. Para esto presentamos algunas leyes distributivas entre cuantificadores y conectivos. ∀x(A ∧ B) ≡ ∀xA ∧ ∀xB (3.32) 150 Lógica de predicados El lado izquierdo nos dice que para todo objeto x se cumple A∧B, lo cual equivale a que para todo individuo se cumplen tanto A como B. ¿Qué sucede si cambiamos la conjunción por disyunción? Para el cuantificador existencial tenemos la siguiente equivalencia: ∃x(A ∨ B) ≡ ∃xA ∨ ∃xB (3.33) Si un individuo cumple A∨B, entonces o cumple A o cumple B, de donde la disyunción de la derecha es válida. ¿Qué sucede si cambiamos la disyunción por conjunción? Cuantificación vacua Consideremos el siguiente enunciado: para cualquier individuo, Berlı́n es la capital de Alemania, el cual se especifica como ∀xC(b, a); consideremos también el enunciado existe un individuo tal que todos son leones, representado con ∃x∀yL(y) o inclusive con ∃x∀xL(x), donde la variable x de la cuantificación existencial es ocultada por la de la cuantificación universal, lo que hace que L(x) haga referencia a la variable de la cuantificación universal. Este tipo de cuantificaciones, donde la variable cuantificada no figura libre en el alcance de la cuantificación, se conoce como cuantificación vacua o nula. Con respecto a su valor de verdad, de acuerdo a nuestra definición, ∀xC(b, a) es verdadera si y sólo si C(b,a) es verdadera para cualquier valor de x como un individuo particular, pero como x no figura en C(b, a), basta mostrar la verdad de esta última fórmula, es decir, la cuantificación no aporta nada a la evaluación de la fórmula original y por lo tanto puede eliminarse mediante las siguientes equivalencias: Cuantificadores vacuos: si x no figura libre en A entonces ∀xA ≡ A, ∃xA ≡ A, (3.34) (3.35) donde A puede ser, a su vez, una cuantificación con la misma variable cuantificadora o con una distinta. En particular estas equivalencias permiten eliminar cuantificadores múltiples, puesto que ∀x∀xA ≡ ∀xA y ∃x∃xA ≡ ∃xA. Prenexación El proceso de prenexación permite manipular un esquema proposicional binario, donde uno de los operandos es una cuantificación y la variable cuantificada en este operando no figura libre en el otro operando. El objetivo de la manipulación es “factorizar” el cuantificador, sumergiendo al operando proposicional en la cuantificación, de manera que la fórmula resultante ya no corresponde a un esquema proposicional sino a un esquema de cuantificación. Las equivalencias para el proceso de prenexación son: 151 3.4 Semántica informal Prenexación de cuantificadores: si x no figura libre en A entonces, A ∧ ∀xB ≡ ∀x(A ∧ B) (3.36) A ∨ ∀xB ≡ ∀x(A ∨ B) (3.37) A ∧ ∃xB ≡ ∃x(A ∧ B) (3.38) A ∨ ∃xB ≡ ∃x(A ∨ B) (3.39) Prenexación de cuantificadores: si x no figura libre en A entonces, A → ∀xB ≡ ∀x(A → B) (3.40) A → ∃xB ≡ ∃x(A → B) (3.41) Prenexación de cuantificadores: si x no figura libre en B entonces, ∀xA → B ≡ ∃x(A → B) (3.42) ∃xA → B ≡ ∀x(A → B) Veamos un ejemplo del proceso de prenexación. (3.43) Ejemplo 3.19. • Para cualquier objeto, es azul o München es la capital de Baviera : ∀x(A(x) ∨ C(m, b)) ≡ ∀xA(x) ∨ C(m, b). Todos los objetos son azules o München es la capital de Baviera. • Hay algo tal que los gorriones son bonitos y ese algo es la capital de Francia: ∃x(∀y(G(y) → B(y)) ∧ C(x, f )) ≡ ∀y(G(y) → B(y)) ∧ ∃xC(x, f ). Los gorriones son bonitos y algo es la capital de Francia. Ejercicios 3.4.1.- Si P (x) denota al enunciado x > 4, di cuál es el valor de (a) P (0) (b) P (4) (c) P (6) 3.4.2.- Sea C(x, y) el enunciado x es la capital de y. Di cuál es el valor de verdad de: (a) C(T oluca, M éxico) (c) C(Quito, Bolivia) (b) C(Grenoble, F rancia) (d) C(Cd. Juárez, N uevo León) 152 Lógica de predicados 3.4.3.- Encuentra el valor de verdad de las siguientes fórmulas si el universo son los números reales R y los predicados se interpretan como sigue: • Q(x) x es un número par • P (x) x es un número primo • R(x) x es divisible por 6 • G(x) x es menor o igual a 5 • L(x, y) x es menor que y  (a) ∃x R(x) ∧ P (x) (b) ∃xR(x) ∧ ∃xP (x)  (c) ∀x P (x) → ¬Q(x)   (d) ∀x R(x) → ∃y L(x, y) ∧ R(y)  (e) ∀x∃y L(x, y) ∧ L(y, x)  (f) ∃xP (x) → ∃x P (x) ∧ R(x) 3.4.4.- Da un micromundo de triángulos, cuadrados y cı́rculos donde todas las fórmulas lógicas que siguen sean verdaderas:  • ∃x∃y∃z T (x) ∧ C(y) ∧ S(z) ∧ (G(x) ∧ G(y) ∧ G(z)) ∨ (M (x) ∧ M (y) ∧ M (z))  ∨ (P (x) ∧ P (y) ∧ P (z))  ∧R(x, y) ∧ R(y, z) .  • ∃x∃y C(x) ∧ P (x) ∧ C(y) ∧ M (y) ∧ E(x, y) .  • ∃x ∃y ∃z T (x) ∧ P (x) ∧ T (y) ∧ M (y) ∧ T (z) ∧ G(z) . 3.4.5.- Para cada una de las siguientes fórmulas, da un micromundo de figuras donde estas fórmulas sean verdaderas o, en su defecto, justificar por qué no existe tal mundo.  (a) ∀x∃y T (x) → S(y) ∧ O(x, y) .  (b) ∀x∃y C(x) ∧ (T (y) ∨ S(y)) ∧ (Co(x, y) .  (c) ∃x∃y R(x, y) ∨ Co(x, y) .  (d) ∃x∃y∃z C(x) ∧ M (x) ∧ N (z, x) ∧ O(y, x) . 153 3.4 Semántica informal (e) ∀x∃yN (y, x) ∧ ∃zC(z). 3.4.6.- Para cada fórmula da dos micromundos de figuras, uno donde la fórmula sea verdadera y otro donde sea falsa. (a) ¬∀x(C(x) → G(x)) ∧ ∃z(P (z) ∧ ¬∃y(T (y) ∧ O(y, z)).  (b) ∀x∀y T (x) ∧ C(y) ∧ N (x, y) → ∃z(S(z) ∧ P (z) ∧ Z(z, x) ∧ Z(y, z)) .  (c) ∃w(S(w) ∨ G(w)) ∧ ∀x T (x) ∧ M (x) ∧ ∃yZ(y, x) → ∃z(G(z) ∧ N (z, x) .   (d) ∀w G(w) → ∃y(P (y) ∧ N (y, w)) ∨ ∃x∃z T (z) ∧ M (x) ∧ O(z, x) .   (e) ∃x T (x) ∧ ∀y(N (y, x) → P (y) ∨ S(y)) ∧ ∀w C(w) → ∃y(G(y) ∧ E(y, w) . 3.4.7.- Da un micromundo de cubos donde las siguientes fórmulas sean verdaderas al mismo tiempo.  • ∃x ∃y ∃z Az(x) ∧ L(x) ∧ A(y) ∧ L(y) ∧ R(z) ∧ L(z) .  • ∃x ∃y ∃z Az(x) ∧ S(x, p) ∧ A(y) ∧ S(y, p) ∧ R(z) ∧ S(z, p) .   • ∃x∃y Az(x) ∧ A(y) ∧ S(x, y) ∧ ∃x∃y R(x) ∧ Az(y) ∧ S(x, y) . 3.4.8.- Considera las siguientes fórmulas e interpretaciones para los predicados: • • • • • • F (x) O(x) P (x) C(x) I(x) T (x) x está fuera de servicio x está ocupada x se ha perdido x está en la cola x es impresora x es trabajo Construye micromundos de impresoras y trabajos que hagan verdaderas a las fórmulas. La descripción de un micromundo puede ser mediante constantes y tablas de verdad para predicados. (a) ∃x(I(x) ∧ F (x) ∧ O(x)) → ∃y(T (y) ∧ P (y)). (b) ∀x(I(x) → O(x)) → ∃y(T (y) ∧ C(y)). (c) ∃y(T (y) ∧ C(y) ∧ P (y)) → ∃y(I(y) ∧ F (y)). (d) ∀x(I(x) → O(x)) ∧ ∀y(T (y) → C(y)) → ∃z(T (z) ∧ P (z)). 3.4.9.- Da las negaciones de las siguientes cuantificaciones de manera que el sı́mbolo de negación sólo afecte a predicados. Por ejemplo, la negación de ∀x P (x) ∧ Q(x) es ∃x ¬P (x)∨¬Q(x) , donde puedes notar que no hay negación frente al cuantificador ni frente a una fórmula que consista de más de un predicado. 154 Lógica de predicados (a) ∀x(x2 > x). (b) ∃x(x2 = x).  (c) ∀x P (x) → Q(x) .  (d) ∀x x3 < x → x < 0 .  (e) ∃x P (x) ∧ Q(x) → R(x) . 3.4.10.- Para los siguientes enunciados, di cuál o cuáles son las negaciones correctas de los predicados: (a) A todo el mundo le gusta el helado. i. A nadie le gusta el helado ii. A todo mundo le disgusta el helado iii. Alguien no adora el helado (b) Algunas fotografı́as están viejas y deslavadas. i. Todas las fotografı́as ni están viejas ni están deslavadas ii. Algunas fotografı́as no están viejas o deslavadas iii. Todas las fotografı́as no son viejas ni deslavadas    3.4.11.- Muestra que ∀x P (x) ∧ Q(x) y ∀x P (x) ∧ ∀x Q(x) son lógicamente equivalentes.   3.4.12.- Muestra que ¬∀x P (x) → Q(x) y ∃x P (x) ∧ ¬Q(x) son lógicamente equivalentes. 3.4.13.- Transforma las siguientes fórmulas mediante equivalencias lógicas, de manera que las negaciones sólo figuren frente a predicados. (a) ∀x∃y¬∀z∃w(P (x, w) ∨ Q(z, y)) → ¬∃v∀u¬R(u, v)  (b) ¬∀x∃y¬∀w∃z P (x, y) ∨ ¬Q(x) → ∃w¬T (a, w)  (c) ¬∃x∀y¬∃w∀z¬ ¬P (x, y) ∧ Q(x) → ∀wT (x, w)    (d) ¬ ¬∃x∀y ¬T (y) ∧ R(z, x) → G(x, z) → ∀w¬∃vP (v, a, w)    (e) ¬ ∀x∃w¬ ¬P (a, x) ∨ R(c, w) ∧ ∃z¬∀y T (b, z) ∧ ¬Q(y, a) 155 3.4 Semántica informal 3.4.5. Algunos argumentos correctos Ya hemos mencionado con anterioridad que nuestro propósito principal para estudiar lógica consiste en obtener métodos formales para mostrar la correctud de argumentos lógicos. Si bien podemos generalizar algunos de los métodos estudiados en la lógica de proposiciones para la lógica de predicados, estos métodos no son infalibles, debido a un importante resultado de la Lógica Matemática, demostrado por Alonzo Church, que nos dice que no puede existir un algoritmo para decidir si un argumento dado es correcto o no. A pesar de este resultado, el problema de analizar un argumento de la lógica de predicados para intentar decidir su correctud sigue siendo de gran importancia en la práctica, puesto que la lógica de predicados es una herramienta de gran importancia para la especificación formal en computación. Si bien no hay un algoritmo general, la correctud de un argumento puede decidirse en muchos casos mediante métodos sintácticos o semánticos que quedan fuera del alcance de este libro. Sin embargo, dado que el proceso de argumentación es relevante en la práctica tanto en matemáticas como en ciencias de la computación, enunciamos a continuación algunos argumentos correctos de la lógica de predicados, los cuales surgen naturalmente en matemáticas. • Generalización Universal: Sea A una fórmula y x una variable que no figura libre en la argumentación actual. Entonces el siguiente argumento es correcto: A ∀xA Este argumento permite concluir la validez de la fórmula ∀xA al mostrar la validez de A, cerciorándonos de que x no figura libre en ninguna de las premisas usadas para llegar a A. Esta restricción implica que en la argumentación no se usó ninguna propiedad particular de x, por lo que ésta denota a cualquier individuo posible del universo de discurso, lo cual permite realizar la generalización. Este argumento es indispensable en pruebas por inducción, como se verá en el siguiente capı́tulo. • Instanciación Universal: ∀xA A[x := t] La correctud de este argumento es intuitivamente clara: si la fórmula ∀xA se supone verdadera, entonces uno deberı́a poder concluir A[x := t] para cualquier individuo particular del universo de discurso, denotado por el término t. Sin embargo, hay que 156 Lógica de predicados tener cuidado, puesto que en A pueden figurar otros cuantificadores y en t otras variables, se corre el peligro de capturar alguna variable de t, que por supuesto estaba libre, mediante algún cuantificador de A causando un problema semántico importante. Es por esta razón que la sustitución en lógica de predicados no es una sustitución textual como la estudiada antes en este libro, sino que debe vigilar no cambiar presencias libres por ligadas y viceversa. • Generalización Existencial: A[x := t] ∃xA Nuevamente, la correctud de este argumento es intuitivamente clara: si sabemos que un individuo particular t cumple la propiedad A entonces podemos concluir que alguien cumple A, es decir, podemos concluir ∃xA. • Instanciación Existencial: Sea A una fórmula y c una constante nueva en la argumentación actual. Entonces el siguiente argumento es correcto: ∃xA A[x := c] Este argumento permite concluir la validez de A para un individuo particular c del universo de discurso a partir de la verdad de ∃xA. La restricción acerca de que c sea una constante nueva se debe al hecho de que no es posible saber cuál individuo particular es el que cumple A a partir de la única información que tenemos, que es ∃xA. 3.5. Predicados y tipos Frecuentemente un dominio de interpretación se compone de diversas clases bien determinadas de objetos, por ejemplo cı́rculos y cuadrados, alumnos y profesores, animales y vegetales. En estos casos, cuando se quiere especificar algo acerca de todos los individuos de cierta clase de objetos del universo, es conveniente hacer explı́cita su pertenencia a dicha clase particular mediante el uso de predicados llamados calificadores o tipos, los cuales denotan clases de objetos. Para expresar propiedades de un tipo especı́fico de objeto se usa un juicio universal afirmativo. Por ejemplo, si el universo son los mamı́feros y queremos hablar de una propiedad universal P (x) de los felinos, como pudiese ser maullar o ser cuadrúpedo, la especificación ∀xP (x) no da la suficiente información y es preferible usar un tipo F (x) para felinos, con lo que la especificación serı́a ∀x(F (x) → P (x)). Similarmente, si la especificación es existencial, utilizamos un juicio existencial afirmativo, como en algunos felinos beben leche que se formaliza con ∃x F (x) ∧ BL(x) . 3.5 Predicados y tipos 157 El uso de tipos permite restringir o dirigir el rango de valores de una variable dada mediante el uso de un juicio afirmativo. Sin embargo, dado que su uso resulta muy frecuente y útil, es conveniente introducir una notación especial para tipos como sigue: ∀x : A. P (x) en lugar de ∀x(A(x) → P (x)) ∃x : A. P (x) en lugar de ∃x(A(x) ∧ P (x)) A esta notación la denominamos de tipos abreviados. Por ejemplo, si el universo son los números reales, el enunciado para todo número real existe un natural mayor que él puede expresarse como sigue: • Sin tipos: ∀x∃y(x < y) (inconveniente pues no da suficiente información).   • Con juicios afirmativos: ∀x R(x) → ∃y N (y) ∧ x < y . • Con tipos abreviados: ∀x : R.∃y : N.x < y. Cuando un lenguaje tiene reglas sintácticas que manejen los tipos de las variables decimos que tenemos un lenguaje fuertemente tipificado o tipado. Entre los lenguajes de programación que son fuertemente tipificados tenemos a Pascal, C++, Java, C#, C y Haskell. En general, un lenguaje fuertemente tipificado nos da reglas muy estrictas respecto a cómo podemos combinar distintos tipos en una misma expresión. Otros lenguajes, como Lisp, Prolog y Scheme, son lenguajes que no observan el concepto de tipo, de manera que las variables pueden tener distintos tipos durante la ejecución, dependiendo del estado de las mismas. El concepto de tipo que se presenta corresponde únicamente a los tipos primitivos de un lenguaje. La lógica de predicados que estudiamos aquı́ es una lógica sin tipos en el sentido de que los sı́mbolos funcionales y de predicado, que se interpretan como operadores o relaciones, no tienen tipos explı́citos. En nuestro caso, el uso de tipos es un mecanismo de ayuda y simplificación en la escritura de ciertas especificaciones. Terminamos esta sección con otros ejemplos. Ejemplo 3.20. Vamos a especificar el tipo de los números naturales N (x) con sus operaciones más comunes. N (0) o bien 0:N   El sucesor de un natural es un natural: ∀x:N. N s(x) o bien ∀x:N. s(x):N  La suma de dos naturales es un natural: ∀x:N.∀y:N. N (x + y)  El producto de dos naturales es un natural: ∀x:N.∀y:N. N (x · y)  El sucesor es una función inyectiva: ∀x:N.∀y:N. s(x) = s(y) → x = y Hay un natural menor o igual que todos los ∃y:N.∀x:N.y ≤ x naturales. • El cero es un número natural: • • • • • 158 Lógica de predicados Por último un ejemplo más cercano a las especificaciones usuales en computación. Ejemplo 3.21. Se desean especificar propiedades de un sistema de archivos de computadora. Consideremos que el universo consta de archivos y directorios para lo cual definimos los tipos A(x) y D(x) (o simplemente A y D), con el predicado C(x, y) como el objeto x está contenido en el objeto y y la función n(x) que devuelve el nombre del objeto. • Ningún directorio se contiene a sı́ mismo: ∀x:D. ¬C(x, x) • Si un directorio está contenido en otro, entonces el segundo no puede estar contenido en el primero (es decir, no hay directorios cı́clicos):  ∀x:D.∀y:D . C(x, y) → ¬C(y, x) • Existe un directorio que no está contenido en ningún otro directorio (el directorio raı́z): ∃x:D . ∀y:D . ¬C(x, y) • Existe un directorio vacı́o: ∃x:D . ∀y¬C(y, x) • Todo archivo está contenido en algún directorio: ∀x:A . ∃y:D . C(x, y) • Si dos archivos están en el mismo directorio entonces deben tener nombres distintos.   ∀x:A . ∀y:A . ∃z:D . C(x, z) ∧ C(y, z) → n(x) 6= n(y) Ejercicios 3.5.1.- Formaliza las siguientes especificaciones acerca de un tipo A(x) y el tipo de listas de elementos de A, denotado L(x). Debes agregar cualquier predicado, función o constante necesaria. (a) La lista vacı́a es una lista de elementos de A. (b) La operación de agregar un elemento de A al inicio de una lista dada es nuevamente una lista. 159 3.5 Predicados y tipos (c) La concatenación de dos listas es nuevamente una lista. (d) La cabeza de una lista es un elemento de A. (e) La cola de una lista es nuevamente una lista. (f) La longitud de una lista es un número natural. 3.5.2.- Formaliza las siguientes especificaciones acerca de un tipo A(x) y el tipo de pilas de elementos de A, denotado P (x). Debes agregar cualquier predicado, función o constante necesaria. (a) Hay una pila vacı́a. (b) La operación de agregar un elemento de A al tope de una pila es una pila. (c) El tope de la pila es un elemento de A. (d) La operación de eliminar el elemento en el tope de la pila devuelve una pila. Parte II Inducción y recursión Inducción y recursión 4 4.1. Introducción Existen muchos universos o dominios que contienen un número ilimitado de elementos que sin embargo pueden ser contados. Por ejemplo, el universo de números naturales, el dominio de expresiones lógicas (tomadas con las variables proposicionales de un alfabeto) y el dominio de programas escritos en ciertos lenguajes de programación. Estos universos se conocen como conjuntos infinitos numerables y son de gran utilidad en Ciencias de la Computación y Matemáticas Discretas. Numerable en este caso significa que se pueden contar en el sentido de que dado un elemento del conjunto, es posible determinar cuál es el elemento siguiente. Sin embargo, por ser infinitos, no es posible describirlos elemento por elemento pues nunca terminarı́amos, ni tampoco podemos probar alguna propiedad acerca de ellos tratando de mostrarla para cada elemento particular. En este capı́tulo tratamos dos técnicas muy relacionadas entre sı́, la inducción y la recursión, las cuales sirven para probar y definir propiedades sobre dominios infinitos numerables. Iniciamos el capı́tulo definiendo de manera formal a los números naturales, mostrando algunas definiciones recursivas de funciones sobre los mismos y discutiendo el llamado método de inducción matemática y algunas de sus variantes. Posteriormente nos ocuparemos de las definiciones recursivas de conjuntos y funciones en un ámbito más general. Estas definiciones recursivas son generalizaciones de las utilizadas en números naturales a cual- 164 Inducción y recursión quier dominio infinito numerable y que además esté bien fundado1 . En la última sección nos ocupamos en generalizar el principio de inducción matemática mediante la llamada inducción estructural en algunas estructuras de datos muy necesarias en programación como son árboles y cadenas o listas finitas. 4.2. Los números naturales El conjunto de números naturales2 N = {0, 1, 2, . . .} es quizás el ejemplo más sencillo de un conjunto infinito numerable, pero siendo infinito, ¿cómo podemos justificar su construcción y manejo en computación? Empecemos con su construcción. En la vida diaria utilizamos los sı́mbolos 0, . . . , 9 para representar los primeros diez números naturales, llamados dı́gitos, mientras que los siguientes números se definen a partir de los dı́gitos mediante ciertas reglas. Formalmente sólo utilizaremos el dı́gito 0 ya que los demás números se construirán utilizando la función sucesor. El sucesor de un número n, escrito s(n), es simplemente el número que le sigue a n en la sucesión de números naturales o, equivalentemente, s(n) = n + 1, pero como aún no definimos la suma evitaremos su uso. Obsérvese que la función sucesor es general y no depende del dominio de los números naturales; por ejemplo los dı́as y meses tienen sucesor. La definición de números naturales será nuestro primer ejemplo de definición recursiva. • 0 es un número natural. • Si n es un número natural, entonces s(n) es un número natural. • Éstos y sólo éstos. Esta definición es recursiva pues en la segunda cláusula se está usando a n, que suponemos es un natural, para poder concluir que s(n) también lo es, es decir, estamos usando lo definido en la misma definición; en la siguiente sección trataremos con detalle este tipo de definiciones. La tercera cláusula puede parecer extraña y con frecuencia se omite en las definiciones. Sin embargo es necesaria para garantizar que un objeto es un número natural únicamente si fue construido usando las cláusulas anteriores. Esto es necesario para que funcionen los principios de inducción. Según la definición anterior el conjunto de números naturales es N = {0, s(0), s(s(0)), . . .} De esta manera hemos construido un conjunto infinito en el sentido de que siempre podremos construir cualquier número de sus elementos y en particular cualquier elemento. 1 dominio bien fundado se refiere, en términos muy generales, a que podemos encontrar un primer elemento 2 La inclusión del 0 en los naturales no es aceptada universalmente, especialmente por matemáticos; sin embargo, aquellos académicos que cultivan la investigación en lógica, postulan que 0 ∈ N. 165 4.2 Los números naturales Diferencia entre sintaxis y semántica Estructuralmente es claro que el conjunto de números naturales recién definido es infinito; sin embargo, si le damos cierto significado a la función sucesor pudiera darse el caso de que los elementos s(s(. . . s(n) . . .)) no sean todos distintos. Por ejemplo, si hablamos de los dı́as de la semana, s(s(s(s(s(s(s(s(lunes)))))))) = lunes. Para indicar que el conjunto es infinito es necesario postular dos propiedades más que garanticen que todos los naturales son distintos. • ∀n(s(n) 6= 0). • ∀n∀m(s(n) = s(m) → n = m). Estas dos propiedades aseguran que el 0 no es sucesor de nadie y que la función sucesor es inyectiva. A continuación nos gustarı́a definir las operaciones básicas suma y producto; esto se hará nuevamente usando recursión. Para la suma tenemos la siguiente definición: • ∀n(n + 0 = n). • ∀n∀m(m + s(n) = s(m + n)). La importancia de una definición recursiva es que podemos extraer de ella un programa para calcular dicha función; veamos un ejemplo sencillo: 3+2 = = = = = s(s(s(0))) + s(s(0))  s s(s(s(0))) + s(0)  s s s(s(s(0))) + 0  s s s(s(s(0))) 5 Finalmente, el producto de dos naturales se define recursivamente como sigue: • ∀n(n × 0 = 0). • ∀n∀m(n × s(m) = n × m + n). Más adelante daremos más ejemplos de funciones definidas recursivamente. 4.2.1. Axiomas de Peano Las fórmulas lógicas definidas anteriormente constituyen los llamados axiomas de Peano; éstos fueron propuestos por el matemático italiano Giuseppe Peano en 1889 y cons- 166 Inducción y recursión tituyen una definición abstracta del conjunto de los números naturales. A continuación los resumimos. • 0 es un número natural. • Si n es un número natural entonces s(n) es un número natural. • ∀n(s(n) 6= 0).    • ∀m∀n s(n) = s(m) → n = m . (P-1) (P-2) (P-3) • ∀m(m + 0 = m). (D-1) (P-4) También contamos, en este mismo formato, con las definiciones recusivas de las operaciones de suma y producto de los números naturales recién discutidas y que recapitulamos a continuación:  • ∀m∀n m + s(n) = s(m + n) . • ∀n(n × 0 = 0). (D-2) (D-3)  • ∀m∀n m × s(n) = m × n + m . (D-4)   P (0) ∧ ∀n P (n) → P s(n) → ∀n P (n) . (P-5) El último axioma de Peano es el llamado axioma de inducción y nos dice que para cualquier predicado P la siguiente expresión es válida:  Esta expresión formaliza el principio de inducción para números naturales. Este principio es muy conocido y de gran importancia en matemáticas discretas y ciencias de la computación y, en general, en todas las matemáticas. A continuación discutimos su validez y desarrollamos algunos ejemplos de su uso. 4.3. Inducción en los números naturales Dada una propiedad P acerca de números naturales, tal que P (n) ha sido probada para un natural cualquiera n, es fácil cerciorarse de la validez de la propiedad para el siguiente número, es decir la validez de P (s(n)); si además podemos probar P (0), entonces el axioma (P-5) nos permite concluir que nuestra propiedad es válida para todos los números naturales. Esto se justifica al existir para cada número natural n0 una derivación de P (n0 ) construida como sigue, usando 1, 2, 3, . . . en lugar de s(0), s(s(0)), . . .: 167 4.3 Inducción en los números naturales 1. 2. 3. 4. 5. 6. 7. 8. P (0) ∀n(P (n) → P (s(n))) P (0) → P (1) P (1) P (1) → P (2) P (2) P (2) → P (3) P (3) .. . Hipótesis. Hipótesis. Instanciación n := 0 en 2. Modus Ponens 1, 3. Instanciación n := 1 en 2. Modus Ponens 4, 5. Instanciación n := 2 en 2. Modus Ponens 6, 7. k. P (n0 ) Estas derivaciones generan la siguiente regla de inferencia, la cual también se deriva del axioma (P-5): P (0) ∀n(P (n) → P (s(n)) ∀n(P (n)) donde P es un predicado acerca de números naturales. Veamos algunos ejemplos de su uso: Ejemplo 4.1. Mostrar que 0 es identidad por la izquierda de la suma; esto es ∀n(0 + n = n). Demostración. Base: Demostrar P (0): (0 + 0) = 0. Esto se cumple por (D-1). Hipótesis de inducción: Suponemos P (n): 0 + n = n. Paso inductivo: Demostrar P (s(n)): 0 + s(n) = s(n). (0 + s(n)) = s(0 + n) = s(n) (D-2) (hipótesis de inducción) Ejemplo 4.2. Mostrar que la suma es conmutativa, esto es: ∀m(∀n(n + m = m + n)). Demostración. Demostrar n + m = m + n. Haremos inducción sobre m (no se puede hacer sobre ambas variables). 168 Inducción y recursión Base: Demostrar P (0): 0 + n = n + 0. 0+n=n =n+0 (ejemplo (4.1)) (D-1) Hipótesis de inducción: Suponemos P (m): m + n = n + m.  Paso inductivo: Demostrar P s(m) : s(m) + n = n + s(m). Tomando el lado derecho: n + s(m) = s(n + m) = s(m + n) (D-2) (hipótesis de inducción) Quisiéramos que el siguiente paso fuera s(m + n) = s(m) + n. Pero esto no es consecuencia de los axiomas ni de resultados anteriores. Por lo tanto, lo tenemos que demostrar. Lo haremos usando inducción natural sobre n ahora. Base: Demostrar P (0): s(m + 0) = s(0 + m) = 0 + s(m) = s(m) + 0. Esto se cumple porque ambos lados son iguales a s(m). Hipótesis de inducción: Suponemos P (n): s(m + n) = s(m) + n.  Paso inductivo: Demostrar P s(n) : s(m + s(n)) = s(m) + s(n). s(m + s(n)) = s(s(m + n)) = s(s(m) + n) = s(m) + s(n) (D-2) (hipótesis de inducción) (D-2) Generalización Universal: ∀n(s(m + s(n)) = s(m) + s(n) Generalización universal sobre m: ∀m(∀n(m + n = n + m)). Ejemplo 4.3. Sea Hn = 0 para n = 0, y Hn+1 = 1 + 2Hn para n > 0. Demostrar que Hn = 2n − 1. Demostración. Verificamos primero para la base, que en este caso es 0: Base: Demostrar, usando la definición dada, P (0): H0 = 0 = 20 − 1. H0 =20 − 1 =1 − 1 =0 (por la definición de Hn con n = 0 ) (por aritmética) √ Hipótesis de inducción: Suponemos P (n): Hn = 1 + 2Hn−1 = 2n − 1. 169 4.3 Inducción en los números naturales Paso inductivo: Verificar que Hn+1 = 2n+1 − 1. Hn+1 = 1 + 2Hn = 1 + 2(2n − 1) = 1 + 2 · 2n − 2 · 1 = 1 + 2n+1 − 2 = 2n+1 − 1 (definición de Hn+1 ) (hipótesis de inducción) (aritmética) (aritmética) √ (aritmética) Ejemplo 4.4. Muestra que para toda n, 2(n + 2) ≤ (n + 2)2 . Demostración. Base: Para n = 0, 2(0 + 2) = 2 + 2 = 4 ≤ 4 = 22 = (0 + 2)2 Hipótesis de inducción: Suponemos P (n): 2(n + 2) ≤ (n + 2)2 . Paso inductivo: Corroborar que se cumple P (n + 1): 2((n + 1) + 2) = 2n + 2 + 4 = 2(n + 2) + 2 < (n + 2)2 + 2 = n2 + 4n + 4 + 2 (definición y aritmética) (aritmética) (hipótesis de inducción) (aritmética) Buscamos acercarnos al lado derecho: (n + 3)2 = n2 + 6n + 9 < n2 + 4n + 6 + 2n + 3 = (n + 3)2 = ((n + 1) + 2)2 n > 0 (por lo que al agregarlo se mantiene la desigualdad) (aritmética) √ Ejemplo 4.5. Demuestra que n3 + 2n es divisible por 3. Demostración. Que n3 + 2n sea divisible entre 3 quiere decir que se puede expresar como n3 + 2n = 3 · k para algún entero k. Base: Para n = 0, 03 + 2n = 0 + 0 = 0 = n, por lo que n3 + 2n es divisible por 3. Hipótesis de inducción: Suponemos P (n): n3 + 2n = 3k para alguna k. Paso inductivo: Tomemos n + 1 y veamos cómo se expresa (n + 1)3 + 2(n + 1). 170 Inducción y recursión (n + 1)3 + 2(n + 1) = n3 + 3n2 + 3n + 1 + 2n + 2 = (n3 + 2n) + 3n2 + 3n + 3 = 3k + 3(n2 + n + 1) (álgebra) (asociatividad y conmutatividad) (hipótesis de inducción) sea k ′ = n2 + n + 1 = 3(k + k ′ ) Conclusión: De esto, ∀n(n3 + 2n es múltiplo de 3). 4.3.1. (factorización) Cambio de la base de la inducción En algunos casos la base de la inducción no es necesariamente el cero o el uno; esto no es una falla en el método de inducción, sino que la propiedad utilizada es válida a partir de cierto numero n0 , lo cual genera un principio similar, presentado aquı́ como regla de inferencia: P (n 0 )  ∀n n ≥ n0 → P (n) → P s(n)  ∀n n ≥ n0 → P (n) Ejemplo 4.6. Mostrar que 2n < n!, para n ≥ 4. Demostración. Base: P (4): 24 = 16 < 24 = 4!. Hipótesis de inducción: Suponer P (n): 2n < n!. Paso inductivo: Demostrar P (n + 1): 2n+1 < (n + 1)!. 2n+1 = 2 × 2n < 2 × n! < (n + 1) × n! = (n + 1)! (aritmética) (hipótesis de inducción) 2 < n + 1, (pues n ≥ 4) (definición de (n + 1)! ) Ejemplo 4.7. Mostrar que cualquier cantidad mayor a 3 pesos puede pagarse usando únicamente monedas de 2 y 5 pesos. 4.3 Inducción en los números naturales 171 Demostración. Base: P (4): 4 = 2 · 2 de manera que $4 puede pagarse con dos monedas de $2. Hipótesis de inducción: P (n): Suponemos que $n pueden pagarse con monedas de $2 y $5. Paso inductivo: P (n + 1): Demostrar que $(n + 1) pueden pagarse con monedas de $2 y $5. Por la hipótesis de inducción tenemos que $n = k · 2 + m · 5. Es decir, $n se pagan con k monedas de $2 y m monedas de $5. Tenemos dos casos: • m = 0. Es decir, $n se pagaron solamente con monedas de $2. En este caso, n + 1 = k · 2 + 1 = (k − 2) · 2 + 2 · 2 + 1 = (k − 2) · 2 + 5. de donde si $n se pagaron con k monedas de $2, tenemos que $(n + 1) se pagan con k − 2 monedas de $2 y una moneda de $5. Obsérvese que estamos separando dos monedas de $2 para completar $5; esto puede hacerse debido a que k ≥ 2 ya que n ≥ 4. • m > 0. Es decir, $n se pagaron con al menos una moneda de $5. n + 1 = k · 2 + m · 5 + 1 = k · 2 + (m − 1) · 5 + 5 + 1 = (k + 3) · 2 + (m − 1) · 5 de donde $(n + 1) se pagan con k + 3 monedas de $2 y m − 1 monedas de $5. Obsérvese que separamos una moneda de $5 para obtener $6 que se pagan con tres monedas de $2; esto puede hacerse pues m ≥ 1. De los ejemplos anteriores podemos obtener un esquema general para una prueba por inducción: 1. Enunciar el uso del principio de inducción. De esta manera el lector comprenderá de qué tipo de prueba se trata. 2. Definir un predicado apropiado P (n), de manera que la meta a probar sea ∀nP (n). Con frecuencia este predicado puede extraerse de la afirmación en español que se desea probar. 3. Mostrar que la base de la inducción P (0) (o P (n0 )) es cierta. 4. Enunciar la hipótesis de inducción P (n). 5. Probar la implicación P (n) → P (n + 1); esto se conoce como paso inductivo. 6. Invocar el principio de inducción y concluir que ∀nP (n). Cualquier prueba por inducción debe tener todos estos pasos y en este orden. 172 Inducción y recursión 4.3.2. Inducción completa Si pensamos en una prueba por inducción de acuerdo al principio original (P-5) y a la derivación lógica dada en la página 167 para justificar el método, al probar P (m) para un número cualquiera m tuvimos que probar antes P (0), P (1), . . . , P (m − 1), es decir, la propiedad P tuvo que verificarse para todos los números anteriores a m. Esta información podrı́a ser útil y necesaria para probar P (m + 1), ya que en algunos casos no basta con la información inmediata anterior P (m). Esta observación da lugar al principio de inducción fuerte o completa que enunciamos aquı́ como regla de inferencia.    ∀n ∀m m < n → P (m) → P (n)  ∀n P (n) Obsérvese que en este caso no hay una base explı́cita de la inducción. Si instanciamos n = 0 entonces la premisa de la regla resulta equivalente a P (0), puesto que la fórmula ∀m(m < 0 → P (m)) es cierta al tratarse de una implicación con antecedente falso (m < 0) con m ∈ N . Al probar el paso inductivo para n = 0 no hay hipótesis disponible para usarse, por lo que P (0) debe ser probado como en casos anteriores. Sin embargo, esto no es necesario en la mayorı́a de los casos. Este principio permite partir la prueba del paso inductivo en dos o más casos más pequeños, cualesquiera que éstos sean. Ejemplo 4.8. Sea d el cero del operador ◦, es decir ∀x(x ◦ d = d ◦ x = d). Mostrar que cualquier expresión que contenga una o más presencias de d debe ser igual a d. Sea P (n) la proposición de que cualquier expresión con n presencias de ◦ y al menos una presencia de d es igual a d. Base: Veamos las posibles expresiones con una presencia de ◦ y al menos una presencia de d: (a) x ◦ d (b) d ◦ x. Por la definición del operador ◦ tenemos ∀x(x ◦ d = d ◦ x = d). por lo que P (1) se cumple. Hipótesis de inducción: Supongamos P (m) para m < n. Es decir, cualquier expresión con m < n presencias de ◦ y al menos una presencia de d es igual a d. 4.3 Inducción en los números naturales 173 Paso inductivo: Sea x una expresión con n > 0 operadores que contiene al menos una presencia de d; entonces x = x1 ◦ x2 donde x1 , x2 son expresiones con menos de n operadores ◦ y alguna de x1 , x2 contiene una presencia de d, digamos que es x1 . En tal caso, por la hipótesis de inducción se tiene x1 = d, de donde tenemos x = x1 ◦x2 = d◦x2 . Como d◦x tiene menos de n presencias de ◦ (eliminamos todas las presencias de ◦ en x1 ) presencia de d, tenemos que d◦x2 = d, lo cual completa el paso inductivo. Obsérvese que la prueba es totalmente análoga si es x2 quien contiene una presencia de d. Ejemplo 4.9. Demostrar que cualquier n ≥ 2 es primo o es producto de primos. Sea P (n) la proposición: n es primo o producto de primos. Queremos probar que ∀n(n ≥ 2 → P (n)). Base: P (2): Para n = 2 tenemos que 2 es primo, por lo que se cumple P (2). Hipótesis de inducción: Supongamos P (m) para m < n. Es decir, cualquier número m < n es primo o producto de primos. Paso inductivo: Si n es primo hemos terminado. Si no lo es, n se puede escribir como n = m·q con 1 < m, q < n y por la hipótesis de inducción, ambos, m y q, son primos o producto de primos, de donde n = m·q también lo es. Obsérvese que en este ejemplo se combinan la inducción completa y el cambio de base al iniciar en n = 2. Ejercicios 4.3.1.- Demuestra, usando las definiciones de suma y producto dadas al inicio de esta sección, que s(0) es la identidad para la multiplicación; esto es  ∀m m × s(0) = m 4.3.2.- Demuestra las siguientes propiedades de la suma y el producto:  • Asociatividad de la suma: ∀m∀n∀k m + (n + k) = (m + n) + k .  • Asociatividad del producto: ∀m∀n∀k m × (n × k) = (m × n) × k .  • Neutro izquierdo del producto: ∀n 0 × n = 0 .  • Conmutatividad del producto: ∀m∀n m × n = n × m . 174 Inducción y recursión 4.3.3.- Demuestra, usando las definiciones de suma y producto dadas al inicio de esta sección, que  ∀m∀n s(m) × s(n) = m × n + s(m) + n 4.3.4.- Demuestra que para toda n, n X k= k=1 4.3.5.- Demuestra que para toda n, n X 3 k = k=1 4.3.6.- Demuestra que para toda n, n(n + 1) . 2  n(n + 1) 2 2 . 5+8+11+· · ·+(3n+2) =  1 3n2 + 7n . 2 4.3.7.- Usa inducción ası́ como las leyes de conmutatividad y asociatividad para demostrar que a1 + (a2 + (a3 + . . . + (an−1 + an ) . . .)) = an + (an−1 + (. . . + (a2 + a1 ) . . .)) 4.3.8.- Sea n > 3 un número natural. Sea m el entero mayor que es menor o igual que (n + 2)/2 o sea, m = ⌊(n + 2)/2⌋ . Veamos una pequeña tabla con los valores de n y m: n (n + 2)/2 m 2 5 6 7 2 3.5 4 4.5 2 3 4 4 Entonces, dados más de m enteros en el conjunto {1, 2, . . . , n}, tres de los enteros en este conjunto tienen la propiedad de que alguno de los tres es la suma de los otros dos. 4.3.9.- Demuestra que para toda n ≥ 0, n X k=0 9 · 10k = 10n+1 − 1. 4.3.10.- Usa inducción matemática para demostrar que para todo entero n, n < 2n . 4.3.11.- Demuestra que para todo entero positivo n existe un entero positivo con n dı́gitos que es divisible entre 5n y tal que todos sus dı́gitos son impares. Que un entero p sea 175 4.3 Inducción en los números naturales divisible entre otro entero q, denotado p | q, quiere decir que al dividir p entre q, el residuo es 0, o dicho de otra manera: Dados p, q ∈ Z+ , p|q → ∃m ∈ Z+ tal que p = q · m Veamos algunos ejemplos de la proposición: n Entero con n dı́gitos P (1) P (2) P (3) P (4) 5 75 375 9375 p=q·m 5 = 51 (1) 75 = 52 (3) = 25 · 3 375 = 53 (3) = 125 · 3 54 (15) = 625 · 15 4.3.12.- Demuestra que para todo entero n ≥ 0 y z 6= 1, n X k=0 zk = z n+1 − 1 z−1 4.3.13.- Demostrar que para todo entero n > 6, 3n < n!. 4.3.14.- Para todo natural n, n X k=1 k(k!) = (n + 1)! − 1 4.3.15.- Los autómatas finitos son un modelo muy útil para dispositivos en software o hardware. Un autómata finito es un dispositivo que se puede encontrar, en un momento dado, en un número finito de estados. El objetivo de los estados es recordar una porción relevante de la historia del sistema. Como sólo hay un número finito de estados, la historia completa no puede ser registrada, por lo que se deberá diseñar con cuidado para recordar los aspectos relevantes. En cada estado, el autómata recibe posibles señales, que lo pueden hacer cambiar de estado. El autómata inicia siempre en un estado designado como inicial, y dependiendo del estado en el que está, puede emitir una señal. Podemos modelar un apagador muy sencillo con un autómata finito. El autómata tiene dos estados, el de apagado y el de prendido, que es lo que el autómata tiene que recordar. Cuando se oprime el apagador, dependiendo en cuál de los dos estados esté, va a pasar al otro: Si está en apagado pasa a prendido y si está en prendido pasa a apagado. El estado inicial es apagado. Podemos modelar el autómata con lo que se conoce como un diagrama de transiciones, como se muestra en la figura 4.1. Como se puede ver en esta figura, los estados están representados por cı́rculos, mientras que el resultado de oprimir el apagador, que corresponde a una transición, se representa 176 Inducción y recursión con una flecha que va de un estado al otro. El estado inicial es al que llega la flecha identificada con inicio. Figura 4.1 Autómata correspondiente a un apagador oprimir inicio A P oprimir Debemos demostrar que los siguientes enunciados para describir el comportamiento del autómata se cumplen: S1 (n) : El autómata está en el estado A (de apagado) después de haber oprimido el botón n veces, si y sólo si n es par. S2 (n) : El autómata está en el estado P (de prendido) si y sólo si n es impar. Se tiene que hacer una demostración doble de inducción, ya que hay que hacer inducción sobre los dos casos posibles de la definición. 4.3.16.- Un poliominó es una pieza formada por cuadrados iguales unidos entre sı́ por al menos una arista (se excluyen los que estén unidos sólo por un vértice). Los poliominós se clasifican según el número de cuadrados que los forman; ası́, tenemos los monominós son aquéllos formados por un cuadrado, los dominós por dos cuadrados, triminós por tres, tetraminós por cuatro, pentaminós con cinco, los hexaminós con seis, los heptaminós con siete, . . . . En ciencias de la computación a este tipo de uniones donde se requiere que cuadrados adyacentes compartan un lado se conoce también como 4-conectividad. Al número de cuadrado que tiene el poliominó se le llama el orden de la figura. Según el número de cuadrados en el poliominó tendremos un número distinto de figuras con ese número de cuadrados. En la siguiente tabla consideraremos el número de poliominós libres, donde dos poliominós son diferentes si uno no es el reflejo, la rotación o la traslación del otro. En la tabla 4.1 en la siguiente página mostramos los poliominós libres de orden 1 a 5. Tabla 4.1 Poliominós libres de orden 1 a 5 Nombre monominó Número Figuras 1 (Continúa en la siguiente página) 177 4.4 Definiciones recursivas Tabla 4.1 Poliominós libres de orden 1 a 5 Nombre Número dominós 1 triminós 2 tetraminós 5 pentaminós 12 (Continúa de la página antereior) Figuras Consideremos el triminó en forma de L. Consideremos un tablero de 2n × 2n cuadros en el que eliminamos un cuadro. Demostrar que el resto del tablero puede ser cubierto con triminós en forma de L. 178 Inducción y recursión 4.4. Definiciones recursivas Una definición recursiva es aquella en la cual el concepto definido figura en la definición misma. Esto puede parecer problemático y de hecho introduce problemas matemáticos profundos si dicho uso o autoreferencia se utiliza sin cuidado. Sin embargo, usado bajo ciertas restricciones, este principio de autoreferencia, al que llamaremos en adelante recursión, proporciona un método de definición sumamente útil tanto en matemáticas como en ciencias de la computación. En particular, todos los tipos de datos usuales en programación como listas o árboles, ası́ como diversas funciones sobre los mismos, pueden definirse recursivamente. Para que una definición recursiva sea válida, en el sentido de que genere tipos de datos o funciones que no causen ciclos infinitos de evaluación, debe constar de dos partes: • Un conjunto de casos base, los cuales son casos simples donde la definición se da directamente, es decir, sin usar autoreferencia. • Un conjunto de reglas recursivas donde se define un nuevo elemento de la definición en términos de anteriores ya definidos. Además de estas dos partes, la definición debe constar de una cláusula que asegure que las dos anteriores son las únicas formas de obtener el concepto, objeto o función definida. Esta cláusula puede omitirse en el entendido de que siempre está presente. La definición en los casos base nos da un punto de partida al proporcionar una definición directa, mientras que las reglas recursivas nos permiten construir nuevos casos a partir de los básicos de una manera iterativa. Es muy importante observar que las únicas definiciones recursivas que consideramos válidas son aquellas donde las reglas recursivas se definen en términos de elementos anteriores. Por ejemplo, la siguiente definición de una función f (0) = 1 f (n + 1) = f (n + 2) no es válida, puesto que la definición en n + 1 está dada en términos de un elemento posterior a n + 1, a saber n + 2. En particular, f resulta indefinida en cualquier valor distinto de cero. Definiciones como la anterior se llaman recursivas generales y por lo general causan ciclos infinitos en programación. Ya hemos visto definiciones recursivas del conjunto de números naturales, ası́ como de algunas funciones sobre este mismo tipo de datos como la suma o el producto. Veamos algunos ejemplos más Ejemplo 4.10. Dada una persona x, la relación ser descendiente de x en el dominio de las personas se define como sigue: 4.4 Definiciones recursivas 179 i. Si y es hijo de x entonces y es descendiente de x. ii. Si y es descendiente de x y z es hijo de y entonces z es descendiente de x. iii. Nadie más es descendiente de x. Ejemplo 4.11. Dados dos números naturales n y m, la relación n es menor que m, denotada n < m, se define como sigue: i. 0 < s(k). ii. s(n) < s(k), si n < k iii. Ningún otro par de números está en la relación <. Obsérvese que en el ejemplo anterior la recursión se hace sobre el número n dejando a m fijo y declarándolo explı́citamente como un número sucesor s(k), puesto que la relación n < 0 no sucede nunca. Ejemplo 4.12. El conjunto de fórmulas bien construidas de la lógica proposicional se define como sigue: i. Una variable proposicional es una fórmula bien construida. ii. Las constantes lógicas true y false son fórmulas bien construidas. iii. Si A y B son fórmulas bien construidas, entonces (¬ A), (A∨B), (A∧B) y (A → B) son fórmulas bien construidas. iv. Ninguna expresión que no sea construida con estas reglas es una fórmula bien construida. Ejemplo 4.13. El conjunto de expresiones aritméticas se define como sigue: i. Todos los enteros y todos los nombres de variables son expresiones aritméticas. ii. Si A y B son expresiones aritméticas entonces (−A), (A + B), (A − B), (A × B) y (A/B) son expresiones aritméticas. iii. Sólo éstas son expresiones aritméticas. Ejemplo 4.14. El tipo de datos de listas finitas [a1 , . . . , an ] con elementos ai en un conjunto A se define de la siguiente forma: i. La lista vacı́a es una lista y se denota por [ ]. ii. Si a ∈ A y ℓ es una lista entonces cons(a, ℓ) es una lista. A a se le llama la cabeza y a ℓ la cola de la lista. iii. Sólo éstas son listas. Frecuentemente se usa la notación (a : ℓ) para cons(a, ℓ). Por ejemplo, si consideramos al conjunto A = {1, 3, 6, 10, 15, 21, 28}, la lista [10, 6, 1, 6] que contiene a los elementos 10, 6, 1, 6 en ese orden, se representa de la siguiente manera: ( 10 : ( 6, ( 1, ( 6, [ ] ) ) ) ) 180 Inducción y recursión Es conveniente notar que en las listas se admiten repeticiones, a diferencia de lo que sucede con los conjuntos. Tenemos varias opciones para representar a una lista con un único elemento. cons(a, [ ]) corresponde a una lista con un primer elemento a y donde la cola de la lista es la lista vacı́a. También podemos denotar a una lista con un solo elemento, de manera abreviada, como [a], cosa que haremos más adelante. Ejemplo 4.15. El tipo de datos de árboles binarios con todos los nodos etiquetados por elementos de un conjunto A se define como sigue: i. Un árbol vacı́o es un árbol binario y se denota por void. ii. Si T1 y T2 son árboles binarios y a es un elemento de A, entonces tree(T1 , c, T2 ) es un árbol binario, donde T1 es el subárbol izquierdo y T2 es el subárbol derecho. Al nodo etiquetado con c se le llama la raı́z del árbol. iii. Nada más es un árbol binario. Por ejemplo, la expresión tree(T1 , c, T2 ) corresponde a la siguiente figura c T1 T2 ¿A qué expresión corresponde cada uno de los siguientes árboles? c d a e c b f d e f Los ejemplos anteriores muestran definiciones recursivas de tipos de datos usuales en computación como números naturales, expresiones lógicas o aritméticas, listas o árboles, o bien de relaciones como el orden usual entre números. En la siguiente sección mostramos definiciones recursivas de funciones que involucran a los tipos de datos recien definidos. 4.4 Definiciones recursivas 4.4.1. 181 Definición de funciones recursivas La definición recursiva de tipos de datos permite definir funciones sobre los mismos utilizando la técnica de casamiento o apareamiento de patrones3 : cada cláusula de la definición del tipo de datos introduce un patrón, el cual es un esquema sintáctico bien definido que se utiliza para definir un caso de la función en cuestión. Listamos a continuación los patrones básicos de cada tipo de datos definido previamente: • Números naturales: 0, s(n). • Expresiones lógicas: p, true, false, ¬A, A ∧ B, A ∨ B, A → B • Expresiones aritméticas: n, x, (−A), (A + B), (A − B), (A × B) y (A/B) • Listas: [ ], (a : ℓ) • Árboles binarios: void, tree(T1 , c, T2 ) De esta manera, para definir, por ejemplo, una función f sobre las listas, es suficiente definir los casos para f ([ ]) y para f ((a : ℓ)). Veamos a continuación algunos ejemplos de funciones definidas sobre los tipos de datos recién definidos y cuyas implementaciones se dan mediante apareamiento de patrones. En cada caso se da primero una especificación que proporciona una definición directa, seguida de una implementación mediante una función recursiva f definida mediante patrones. En algunos ejemplos nos puede resultar claro que la definición recursiva de f cumple con la especificación dada en cada caso. Sin embargo, debemos mostrar esto formalmente para cada ejemplo, proceso que discutiremos en la siguiente sección. Ejemplo 4.16. Exponenciación de números naturales. Especificación: pot(n, m) = nm Implementación recursiva: • f (n, 0) = 1 • f (n, s(m)) = f (n, m) · n Ejemplo 4.17. Factorial de un número natural. Especificación: f ac(n) = n · (n − 1) · . . . · 2 · 1, donde además f ac(0) = 1. 3 En inglés pattern matching 182 Inducción y recursión Implementación recursiva: • f (0) = 1 • f (s(n)) = s(n) · f (n) Ejemplo 4.18. Especificación: suma de los elementos de una lista de números. suml ( [a1 , . . . , an ] ) = a1 + a2 + . . . + an Implementación recursiva: • f ([ ]) = 0 • f ((a : ℓ)) = a + f (ℓ) Ejemplo 4.19. Especificación: producto de los elementos de una lista de números. prodl ( [a1 , . . . , an ] ) = a1 · a2 · . . . · an Implementación recursiva: • f ([ ]) = 1 • f ((a : ℓ)) = a · f (ℓ) Ejemplo 4.20. Especificación: longitud de una lista. long([a1 , . . . , an ]) = n Implementación recursiva: • f ([ ]) = 0 • f ((a : ℓ)) = 1 + f (ℓ) 183 4.4 Definiciones recursivas Ejemplo 4.21. Especificación: el operador binario ⊔ devuelve la concatenación de dos listas. [a1 , . . . , ak ] ⊔ [b1 , . . . , bj ] = [a1 , . . . , ak , b1 , . . . , bj ] Implementación recursiva: • f ([ ], ℓ2 ) = ℓ2  • f ((a : ℓ1 ), ℓ2 ) = a : f (ℓ1 , ℓ2 ) Ejemplo 4.22. Especificación: reversa de una lista. rev([a1 , . . . , ak ]) = [ak , . . . , a1 ] Implementación recursiva: • f ([ ]) = [ ] • f ((a : ℓ)) = f (ℓ) ⊔ [a] En algunos casos, la especificación de una función no puede darse de forma directa mediante una ecuación como en los casos anteriores, sino que tiene que darse con palabras como en los siguientes ejemplos. Ejemplo 4.23. Especificación: nc es la función que calcula el número de conectivos en una fórmula de la lógica proposicional. Por ejemplo nc(p → ¬q ∨ r) = 3. Implementación recursiva: • • • • • • f (p) = 0 f (true) = f (false) = 0 f (¬A) = 1 + f (A) f (A ∧ B) = 1 + f (A) + f (B) f (A ∨ B) = 1 + f (A) + f (B) f (A → B) = 1 + f (A) + f (B) 184 Inducción y recursión Ejemplo 4.24. Especificación: ccd es la función que recibe una fórmula proposicional A y devuelve la fórmula obtenida a partir de A al intercambiar los conectivos ∧ y ∨ en A. Por ejemplo ccd(¬p ∨ q → r ∧ s) = ¬p ∧ q → r ∨ s. Implementación recursiva: • f (p) = p • f (true) = true • f (false) = false • f (¬A) = ¬f (A) • f (A ∧ B) = f (A) ∨ f (B) • f (A ∨ B) = f (A) ∧ f (B) • f (A → B) = f (A) → f (B) Ejemplo 4.25. Especificación: at es la función que calcula el número de presencias de fórmulas atómicas que figuran en una fórmula. Por ejemplo: at(q ∧ ¬p → r ∨ p) = 4. at(q ∧ (true ∨ ¬(r → false ∧ t))) = 5. Implementación recursiva: • f (p) = 1 • f (true) = f (false) = 1 • f (¬A) = f (A) • f (A ∧ B) = f (A) + f (B) • f (A ∨ B) = f (A) + f (B) • f (A → B) = f (A) + f (B) El ejemplo en la siguiente pagina involucra a dos tipos de datos, el de las fórmulas proposicionales y el de listas de fórmulas. 4.4 Definiciones recursivas 185 Ejemplo 4.26. Especificación: sf es la función que devuelve la lista de subfórmulas de una fórmula pro- posicional A. Por ejemplo, sf(¬(p → q) ∧ r) = [¬(p → q) ∧ r, ¬(p → q), p → q, p, q, r]. sf(p ∨ ¬(p → s)) = [p ∨ ¬(p → s), p, ¬(p → s), p → s, p, s] Implementación recursiva: • f (p) = [p] • f (true) = [true] • f (false) = [false] • f (¬A) = (¬A : f (A))  • f (A ∧ B) = (A ∧ B) : (f (A) ⊔ f (B)  • f (A ∨ B) = (A ∨ B) : (f (A) ⊔ f (B)  • f (A → B) = (A → B) : (f (A) ⊔ f (B) Ejemplo 4.27. Especificación: nn es la función que recibe un árbol binario t y calcula el número de nodos que hay en t. Implementación recursiva: • f (void) = 0 • f (tree(T1 , c, T2 )) = 1 + f (T1 ) + f (T2 ) Ejemplo 4.28. Especificación: la profundidad o altura de un nodo x en un árbol binario T se define como la distancia (número de lineas) existente entre x y la raiz de T en la representación gráfica de T . La profundidad o altura de un árbol T se define como la altura máxima de un nodo de T más uno. ht es la función que calcula la profundidad de un árbol binario. Implementación recursiva: • f (void) = 0 186 Inducción y recursión • f (tree(T1 , c, T2 )) = 1 + máx{f (T1 ), f (T2 )} Como ya mencionamos, en cada caso debemos cerciorarnos formalmente que la definición recursiva dada por f realmente cumple con la especificación dada. Para el caso de funciones que involucren a los números naturales esto puede lograrse mediante el principio de inducción matemática. Como ejemplo, veamos que la definición recursiva del factorial en verdad cumple la especificación. Ejemplo 4.29. La definición recursiva de f en el ejemplo 4.17 calcula a la función factorial. Es decir, para todo número natural n, se cumple f (n) = f ac(n). Base: n = 0. Tenemos f (0) = 1 = f ac(0). Hipótesis de inducción: f (n) = f ac(n). Paso inductivo: queremos demostrar que f (s(n)) = f ac(s(n)). f (s(n)) = s(n) · f (n) = s(n) · f ac(n) = (n + 1) · n · (n − 1) · . . . · 2 · 1 = f ac(s(n)) (definición de f ) (hipótesis de inducción) (definición de f ac(n)) (definición de f ac(s(n))) En conclusión f (n) = f ac(n) para todo número natural n. Ahora bien, para el caso de funciones definidas sobre otro tipo de datos ¿Cómo podemos probar que la especificación se satisface con la implementación recursiva? De las definiciones y pruebas por inducción de las operaciones de suma y producto, ası́ como de la prueba del ejemplo anterior, se observa una fuerte relación entre el principio de inducción matemática y las definiciones recursivas que involucran números naturales. Cada propiedad de la definición recursiva, como cumplir con una especificación dada, puede mostrarse mediante el principio de inducción. Esta relación puede generalizarse a distintas estructuras o tipos de datos definidos recursivamente, lo que haremos a continuación. 4.5. Inducción estructural Para demostrar propiedades acerca de estructuras definidas recursivamente en el sentido descrito en la página 178, es posible recurrir a la inducción matemática, definiendo una medida en la estructura en cuestión, lo que se hace mediante un número natural. Entre 4.5 Inducción estructural 187 las medidas que podemos mencionar están la longitud de una lista, la profundidad de un árbol o el número de conectivos en una fórmula proposicional. Esto es posible debido a que las reglas recursivas de la definición en cuestión se dan en términos de elementos estructuralmente más simples, por lo que su medida será menor y la hipótesis de inducción podrá emplearse. Sin embargo, en la mayorı́a de los casos, el uso de una medida complica las pruebas, además de que la elección de una medida incorrecta podrı́a resultar en una prueba fallida. Otra posibilidad es generalizar el principio de inducción completa mediante la definición de un orden en los tipos de datos, el cual debe ser bien fundado, es decir, no debe contener sucesiones descendentes infinitas. Sin embargo, el problema de decidir si una estructura particular es bien fundada no siempre es fácil de resolver. En lugar de las alternativas anteriores es posible utilizar los llamados principios de inducción estructural, basados en las reglas base y recursivas de la definición de un tipo de datos, ası́ como en el análisis de los patrones básicos introducidos por éstas. El esquema general del principio de inducción estructural es el siguiente: Sean A un conjunto o tipo de datos definido recursivamente y P una propiedad acerca de los elementos de A. Para probar que P (x) es válida para todo elemento de A deben seguirse los siguientes pasos: • Base de la inducción: Si a es un elemento de A generado por una regla básica, entonces debemos probar directamente la validez de P (a). • Si x es un elemento de A construido mediante alguna regla recursiva a partir de elementos anteriores4 x1 , . . . , xn , entonces procedemos como sigue: Hipótesis de inducción: Suponer P (x1 ), . . . , P (xn ). Paso inductivo: Probar P (x). • En este caso, el principio de inducción estructural permite concluir que ∀xP (x). Este principio debe adaptarse a cada conjunto o tipo de datos en particular. En las siguientes secciones lo ejemplificamos para los casos de listas, árboles y fórmulas proposicionales. 4.5.1. Inducción en listas El tipo de datos lista es uno de los más comúnes en ciencias de la computación. Este tipo de datos se definió recursivamente en el ejemplo 4.14, y genera el siguiente principio de inducción estructural: Sea P una propiedad acerca de listas; si se desea probar P (xs) para toda lista xs, basta proceder como sigue: Base de la inducción: Probar P ([ ]) directamente. 4 Es decir, elementos estructuralmente más simples. 188 Inducción y recursión Hipótesis de inducción: Suponer P (xs) . Paso inductivo: Probar P ((a : xs)). Si este es el caso, el principio de inducción para listas permite concluir P (xs) para cualquier lista xs. Para ilustrar el uso de la inducción en listas probamos enseguida algunas propiedades de las operaciones en listas. Proposición 4.1 La función recursiva f dada en el ejemplo 4.21 calcula la concatenación de dos listas. Es decir, para cualesquiera listas xs, ys, f (xs, ys) = xs ⊔ ys. Demostración. Inducción sobre xs. Base de la inducción: xs = [ ]. Tenemos [ ] ⊔ ys = ys = f ([ ], ys). Hipótesis de inducción: f (xs, ys) = xs ⊔ ys. Paso inductivo: Debemos mostrar que f ((a : xs), ys) = (a : xs) ⊔ ys. (a : xs) ⊔ ys = a : (xs ⊔ ys) = a : f (xs, ys) = f ((a : xs), ys) (razonamiento directo) (hipótesis de inducción) (definición recursiva de f ) En conclusión f (xs, ys) = xs ⊔ ys para cualesquiera listas xs, ys. De manera similar podemos probar la correctud de todas definiciones recursivas dadas en los ejemplos de la sección 4.4.1. Como ya probamos que la implementación de la concatenación ⊔ es correcta, podemos usarla de ahora en adelante, como en el caso de la siguiente proposición. Proposición 4.2 La operación de concatenación ⊔ en listas cumple las siguientes propiedades: • Asociatividad: xs ⊔ (ys ⊔ zs) = (xs ⊔ ys) ⊔ zs • Longitud: long(xs ⊔ ys) = long(xs) + long(ys) Demostración. Probamos la asociatividad mediante inducción sobre la lista xs. Sea P (xs) la propiedad xs ⊔ (ys ⊔ zs) = (xs ⊔ ys) ⊔ zs 189 4.5 Inducción estructural Base de la inducción: xs = [ ], debemos mostrar que [ ] ⊔ (ys ⊔ zs) = ([ ] ⊔ ys) ⊔ zs [ ] ⊔ (ys ⊔ zs) = ys ⊔ zs = ([ ] ⊔ ys) ⊔ zs (def. rec. de ⊔) (ys = [ ] ⊔ ys) Hipótesis de inducción: xs ⊔ (ys ⊔ zs) = (xs ⊔ ys) ⊔ zs. Paso inductivo: sea a un elemento de A, debemos mostrar que   (a : xs) ⊔ ys ⊔ zs = (a : xs) ⊔ ys ⊔ zs   (a : xs) ⊔ ys ⊔ zs = a : xs ⊔ (ys ⊔ zs)  = a : (xs ⊔ ys) ⊔ zs  = a : (xs ⊔ ys) ⊔ zs  = (a : xs) ⊔ ys ⊔ zs (def.rec. de ⊔) (hipótesis de inducción) (def.rec. de ⊔) (def.rec. de ⊔) Ası́ que por el principio de inducción para listas, concluimos que la operación app es asociativa. La propiedad de longitud se demuestra similarmente. Proposición 4.3 La operación reversa rev en listas cumple las siguientes propiedades: • Longitud: long(rev(xs)) = long(xs) • Concatenación: rev(xs ⊔ ys) = rev(ys) ⊔ rev(xs) • Idempotencia: rev(rev(xs)) = xs Demostración. Mostramos la propiedad de idempotencia mediante inducción sobre la lista xs, dejando las restantes como ejercicio. Base de la inducción: xs = [ ]. Como rev([ ]) = [ ] entonces rev(rev([ ])) = rev([ ]) = [ ]. Hipótesis de inducción: rev(rev(xs)) = xs 190 Inducción y recursión Paso inductivo: Sea a un elemento de A; mostraremos que rev(rev((a : xs))) = (a : xs).  rev(rev((a : xs))) = rev rev(xs) ⊔ [a] (definición recursiva de rev) = rev([a]) ⊔ rev(rev(xs) (proposición anterior) = rev([a]) ⊔ xs (hipótesis de inducción) = [a] ⊔ xs (rev([a]) = [a]) = (a : [ ]) ⊔ xs ([a] = (a : [ ])) = a : ([ ] ⊔ xs) (definición recursiva de ⊔) = (a : xs) (definición recursiva de ⊔) Conclusión: Ası́ que por el principio de inducción para listas se cumple rev(rev(xs)) = xs para toda lista xs. Pasamos ahora a ilustrar la inducción estructural en fórmulas proposicionales. 4.5.2. Inducción en fórmulas El conjunto de fórmulas de la lógica proposicional se definió ya mediante una gramática, ası́ como mediante la definición recursiva del ejemplo 4.12. Esta última forma de definirlo habilita un principio de inducción estructural de gran utilidad en lógica matemática. El principio de inducción estructural para fórmulas es el siguiente: Sea P una propiedad acerca de fórmulas proposicionales. Si se desea probar P (A) para toda fórmula A, basta proceder como sigue: Base de la inducción: probar P (q) directamente para cada variable proposicional q; probar P (true) y probar P (false) Hipótesis de inducción: suponer P (A) y P (B). Paso inductivo: probar P (¬A), P (A ∧ B), P (A ∨ B) y P (A → B). Conclusión: En tal caso el principio de inducción para fórmulas permite concluir P (A) para cualquier fórmula A. En este caso, debido a nuestros conocimientos de equivalencias lógicas, el paso inductivo puede simplificarse a probar P (¬A) y alguno de los casos para un operador binario, el cual se elige dependiendo de la propiedad P particular. Demostramos a continuación algunas propiedades de las fórmulas proposicionales. 191 4.5 Inducción estructural Proposición 4.4 Sea comp la siguiente función recursiva: comp(p) = ¬p comp(true) = false comp(false) = true comp(¬A) = ¬comp(A) comp(A ∨ B) = comp(A) ∧ comp(B) comp(A ∧ B) = comp(A) ∨ comp(B) (i) (ii) (iii) (iv) (v) (vi) Entonces, para toda fórmula C, se cumple comp(C) ≡ ¬C. Demostración. Inducción sobre las fórmulas. Base: C es atómica. Si C = p entonces hay que mostrar comp(p) ≡ ¬p. comp(p) = ¬p ≡ ¬p (por (i)) (reflexividad de ≡) Los casos para C = true y C = false son similares. Hipótesis de inducción Supongamos que comp(A) ≡ ¬A y comp(B) ≡ ¬B. Paso inductivo: Dado nuestro conocimiento de las equivalencias lógicas, basta mostrar la propiedad para ¬A y A ∧ B. comp(¬A) = ≡ comp(A ∧ B) = ≡ ≡ ¬comp(A) (por (iv)) ¬¬A (hipótesis de inducción y equivalencia lógica) comp(A) ∨ comp(B) (por (vi)) ¬A ∨ ¬B (hipótesis de inducción y equivalencia lógica) ¬(A ∧ B) (De Morgan) Conclusión: Por el principio de inducción para fórmulas, podemos concluir que comp(C) ≡ ¬C, para cualquier fórmula C. Por último demostramos una propiedad que relaciona a las funciones definidas en los ejemplos 4.20, 4.23 y 4.25. Proposición 4.5 Si A es una fórmula proposicional, entonces la longitud de la lista de subfórmulas de A es igual a la suma del número de presencias de variables proposicionales de A con el número de conectivos que figuran en A. Es decir, long(sf (A)) = at(A) + nc(A) 192 Inducción y recursión Demostración. Inducción sobre la fórmula A. Base de la inducción: Sea A = p. Tenemos en A una presencia de la fórmula atómica p y ningún conectivo. Por lo tanto, long(sf (p)) = long([p]) = 1 = 1 + 0 = at(p) + nc(p) Para A = true o A = false, la prueba es similar. Hipótesis de inducción: Supongamos que long(sf (A)) = at(A) + nc(A) long(sf (B)) = at(B) + nc(B). Paso inductivo: Probamos la propiedad para ¬A y A → B.  long(sf (¬A)) = long (¬A : sf (A)) = 1 + long(sf (A)) = 1 + (at(A) + nc(A)) = at(A) + (1 + nc(A)) = at(¬A) + (1 + nc(A)) = at(¬A) + nc(¬A) (definición de sf ) (definición recursiva de long) (hipótesis de inducción) (aritmética) (definición recursiva de at) (definición recursiva de nc)  long(sf (A → B)) = long ((A → B) : sf (A) ⊔ sf (B)) (definición de sf ) = 1 + long(sf (A) ⊔ sf (B)) (definición recursiva de long) = 1 + long(sf (A)) + long(sf (B)) (proposición de ⊔) = 1 + (at(A) + nc(A)) + (at(B) + nc(B)) (hipótesis de inducción) = (at(A) + at(B)) + (1 + nc(A) + nc(B)) (aritmética) = at(A → B) + (1 + nc(A) + nc(B)) (definición recursiva de at) = at(A → B) + nc(A → B) (definición recursiva de nc) Conclusión: Por lo tanto, por el principio de inducción para fórmulas, para cualquier fórmula A se cumple long(sf (A)) = at(A) + nc(A) Para finalizar este capı́tulo discutimos el principio de inducción para árboles binarios. 4.5.3. Inducción en árboles La definición recursiva del tipo de datos de árboles binarios dada en el ejemplo 4.15 genera la siguiente versión del principio de inducción estructural: 4.5 Inducción estructural 193 Sea P una propiedad acerca de árboles binarios. Si se desea probar P (T ) para todo árbol T , basta proceder como sigue: Base de la inducción: Probar P (void) directamente. Hipótesis de inducción: Suponer P (T1 ) y P (T2 ). Paso inductivo: Probar P (tree(T1 , c, T2 )). Conclusión: En tal caso el principio de inducción para árboles permite concluir P (T ) para cualquier árbol T . Veamos a continuación un par de ejemplos de pruebas mediante este principio de inducción. Proposición 4.6 Cualquier árbol binario T con n nodos contiene exactamente n+1 subárboles vacı́os. Demostración. Inducción sobre T . Base: T = void. El número de nodos de T es 0, y el número de subárboles vacı́os es 0 + 1 = 1, pues T mismo es un subárbol binario vacı́o. Hipótesis de inducción: Si los árboles binarios T1 y T2 tienen n1 y n2 nodos respectivamente, entonces tienen n1 + 1 y n2 + 1 subárboles vacı́os respectivamente. Paso inductivo: Sea T = (T1 , c, T2 ) un árbol binario no vacı́o. El número de nodos de T es 1 + n1 + n2 . Queremos demostrar que T tiene n1 + n2 + 2 árboles vacios. Es claro que los subárboles vacı́os de T son subárboles de T1 o de T2 , por lo que se tiene que el número de subárboles vacı́os de T es igual a la suma de los números de subárboles vacı́os de T1 y de T2 ; pero por la hipótesis de inducción dicha suma es igual a (n1 + 1) + (n2 + 1) = n1 + n2 + 2. Conclusión: Todos los árboles binarios con n nodos tienen n + 1 subárboles vacı́os. Una hoja a de un árbol es aquel nodo del que cuelgan únicamente árboles vacı́os, representado por tree(void, a, void). Definimos la altura de un árbol general como uno más de la distancia de la raı́z a la hoja más lejana, donde la distancia es el número de aristas que se tienen que recorrer desde la raı́z para llegar al nodo en la representación gráfica del árbol. Proposición 4.7 Si T es un árbol binario con altura n, entonces tiene a lo más 2n − 1 nodos. Es decir, nn(T ) ≤ 2n − 1 Demostración. Inducción sobre T . Base: T = void. En este caso la altura de T es 0 y nn(T ) = 0 pues T no tiene nodos ; por otro lado, 20 − 1 = 1 − 1 = 0, con lo que queda demostrada la base de la inducción. Hipótesis de inducción: Si el árbol Ti tiene altura ni entonces tiene a lo más 2ni − 1 nodos, donde i = 1, 2. 194 Inducción y recursión Paso inductivo: Sea T = tree(T1 , c, T2 ). Recordemos que la altura de T es igual a 1 + máx{n1 , n2 }, por lo que debemos demostrar que el máximo número de nodos en T es 21+máx{n1 n2 } − 1, es decir que nn(T ) ≤ 21+máx{n1 n2 } − 1. nn(T ) = nn(T1 ) + nn(T2 ) + 1 ≤ 2n1 − 1 + 2n2 − 1 + 1 (Definición recursiva de nn) (hipótesis de inducción) ≤ 2máx{n1 ,n2 } − 1 + 2máx{n1 ,n2 } − 1 + 1 = 2 · 2máx{n1 ,n2 } − 1 = 21+máx{n1 ,n2 } − 1 (aritmética) (aritmética) (leyes de exponentes) Este resultado particular es muy utilizado en computación. Ejercicios 4.5.1.- Para cada ejemplo de la sección 4.4.1 demuestra mediante el principio de inducción estructural correspondiente que la función especificada cumple con la implementación recursiva. 4.5.2.- Considera las siguientes especificaciones de dos funciones spar y simp cuyo dominio y codominio son los números naturales. spar(n) = 2 + 4 + 6 + . . . + 2n simp(n) = 1 + 3 + 5 + . . . + (2n + 1) a) Propone implementaciones recursivas f y g para spar y simp, respectivamente. b) Muestra que f (n) = n(n + 1) c) Muestra que g(n) = (n + 1)2 . 4.5.3.- Definimos al conjunto de cadenas am bam de la siguiente manera: i. b, la cadena representada por a0 ba0 , está en el conjunto. ii. Si w es una cadena en este conjunto, entonces awa también está en el conjunto. iii. Éstas son las únicas formas de construir cadenas que cumplan con ser am bam . Demuestra que todas las cadenas que pertenecen a este conjunto tienen un número impar de carácteres, utilizando los siguientes métodos: a) Inducción sobre la longitud de las cadenas. b) Definiendo y utilizando un principio de inducción estructural adecuado. 4.5.4.- Considera la definición recursiva de las expresiones aritméticas dada en el ejemplo 4.13. Enuncia el principio de inducción estructural correspondiente y utilı́zalo para demostrar que toda expresión aritmética tiene el mismo número de paréntesis izquierdos que derechos. 195 4.5 Inducción estructural 4.5.5.- Una cadena de caracteres es palı́ndroma si es de la forma wwR , donde wR es w escrita de atrás hacia adelante. Algunos ejemplos son 0110 y aabaabaa. Define al conjunto de las cadenas palı́ndromas en forma recursiva y demuestra mediante inducción estructural que todas las cadenas palı́ndromas de este tipo tiene un número par de sı́mbolos. 4.5.6.- Demuestra mediante inducción para listas lo siguiente: a) La propiedad de longitud enunciada en la proposición 4.2 b) Las propiedades de concatenación e idempotencia para la reversa, enunciadas en la proposición 4.3 4.5.7.- La función snoc en listas se define como sigue: snoc c [x1 , . . . , xn ] = [x1 , . . . , xn , c] a) Da una definición recursiva para snoc. b) Demuestra que: snoc c (xs ⊔ ys) = xs ⊔ (snoc c ys) c) Demuestra la siguiente propiedad que relaciona a snoc con la operación reversa rev: rev (snoc c xs) = c : (rev xs) 4.5.8.- Considera la siguiente función misteriosa mist: mist [ ] ys = ys mist (x : xs) ys = mist xs (x : ys) a) ¿Qué hace mist? b) Muestra que rev xs = mist xs [ ] 4.5.9.- Este ejercicio concierne a la operación de sustitución textual para las fórmulas de la lógica proposicional. a) Define recursivamente la operación de sustitución textual A[p := B]. b) Demuestra las siguientes propiedades mediante inducción para fórmulas: • Si p no figura en A, entonces A[p := B] = A. • Si p 6= q y p no figura en C, entonces   A[p := B][q := C] = A[q := C] p := B[q := C] . 196 Inducción y recursión • Si p 6= q y p no figura en B, entonces A[q, p := B, C] = A[q := B][p := C]. 4.5.10.- Sea A una fórmula de la lógica proposicional cuyos únicos conectivos son ∧, ∨, ¬. Construimos la fórmula dual de A, denotada AD , intercambiando ∧ con ∨, y reemplazando cada variable p por su negación ¬p. Por ejemplo, si A = (r ∨ p) ∧ ¬q, entonces AD = (¬r ∧ ¬p) ∨ ¬¬q. • Define recursivamente una función dual tal que dual(A) = AD . • Muestra que ¬A ≡ AD mediante inducción sobre las fórmulas. 4.5.11.- Define recursivamente al conjunto de términos de la lógica de predicados y enuncia el principio de inducción estructural correspondiente. 4.5.12.- Define recursivamente al conjunto de fórmulas de la lógica de predicados y enuncia el principio de inducción estructural correspondiente. Observa que este principio debe incluir al dado en la sección 4.5.2 para la lógica de proposiciones. 4.5.13.- Define recursivamente las siguientes funciones para términos de la lógica de predicados: a) ctes(t) que devuelva el conjunto de constantes que figuran en t. Por ejemplo, ctes(f (a, g(x, b)) = {a, b} b) vars(t) que devuelva el conjunto de variables que figuran en t. Por ejemplo, var(g(x, f (y), h(b))) = {x, y}. c) f unc(t) que devuelva el conjunto de sı́mbolos de función que figuran en t. Por ejemplo, f unc(f (a, g(x, b)) = {f, g}. 4.5.14.- La operación de sustitución textual puede extenderse a los términos de la lógica de predicados. Si t y r son términos y x es una variable entonces t[x := r] denota a la sustitución textual de x por r en t. Por ejemplo f (a, x, g(y, x))[x := h(w)] = f (a, h(w), g(y, h(w))). Realiza lo siguiente: a) Formula una definición recursiva de t[x := r]. b) Muestra que si x ∈ / vars(t), entonces t[x := r] = t. c) Muestra que: vars(t[x := r]) = (vars(t) \ {x}) ∪ vars(r). 4.5.15.- Define recursivamente las siguientes funciones para fórmulas de la lógica de predicados: a) f v(A) que devuelva el conjunto de variables libres de A. Por ejemplo, f v(∀xP (x, y) ∧ ∃wQ(z, w)) = {y, z} 197 4.5 Inducción estructural b) bv(A) que devuelva el conjunto de variables ligadas de A. Por ejemplo, bv(∀xP (x, y) ∧ ∃wQ(z, w)) = {x, w} c) nq(A) que devuelva el número de cuantificadores que figuran en A. Por ejemplo, bv(∀x∃yP (x, y) ∧ ∃w∀zQ(z, w)) = 4 4.5.16.- Demuestra que el mı́nimo número de nodos en un árbol de altura n es n. 4.5.17.- Demuestra que el número máximo de hojas en un árbol de altura n es 2n−1 y que el máximo número de nodos internos es 2n−1 − 1 4.5.18.- Demuestra que el siguiente recorrido en un árbol binario reporta a todos los nodos del árbol y siempre termina. Reglas para reportar un árbol binario. a) Si el árbol es un árbol vacı́o, reporta void y regresa. b) Si el árbol es tree(A, c, B), donde A y B son árboles binarios, entonces: i. Reporta c. ii. Reporta A. iii. Reporta B. iv. Termina. 4.5.19.- Define recursivamente una función aplana que tome un árbol binario y devuelva la lista de sus nodos empezando por la raı́z y siguiendo con los nodos del subárbol izquierdo y derecho recursivamente. Por ejemplo, si T = tree(tree(hoja(1), 6, hoja(2)), 5, tree(hoja(4), 9, void)), donde hoja(n) = tree(void, n, void), entonces aplana(T ) = [5, 6, 1, 2, 9, 4]. Muestra que para cualquier árbol t, se cumple nn(t) = long (aplana(t)). 4.5.20.- Queremos representar árboles binarios cuyas únicos nodos etiquetados son las hojas. Para eso tenemos la siguiente definición: • Si a ∈ A, entonces hoja(a) es un árbol. • Si t1 , t2 son árboles, entonces mk(t1 , t2 ) es un árbol. • Son todos. Observa que en esta definición no existe el árbol vacı́o. a) Define funciones recursivas nh, nni que calculen el número de hojas y el número de nodos internos de un árbol (es decir los nodos que no son hojas). b) Enuncia el principio de inducción estructural correspondiente y utilı́zalo para mostrar que: nh(t) = nni(t) + 1. Parte III Teorı́a de Gráficas Conceptos de teorı́a de gráficas 5 5.1. Motivación Una de las actividades más importantes de todo cientı́fico, y en particular de los dedicados a Computación es la del modelado. Modelar un problema quiere decir traducirlo del lenguaje natural a un lenguaje matemático en el que podamos expresar de manera más precisa las caracterı́sticas de lo que estamos modelando, y poder manipularlo también de manera precisa y válida. Hemos estado manejando ya modelos cuando trabajamos con Cálculo Proposicional y con Cálculo de Predicados, tratando de modelar estados de la vida real. Pasaremos ahora a modelar otro tipo de problemas. Una vez que tenemos un modelo apropiado, podemos usar la computadora para manipularlo. En general, estamos preocupados con tres problemas: i. ¿Existe una solución para el problema? Nos interesa una solución que pueda ser calculada (o encontrada) por una computadora en un tiempo razonable. ii. ¿Existe una solución óptima para el problema? Esto es, podemos calcular una solución que sea mejor que cualquier otra solución dada para ese problema. iii. Por último, ¿Cuántas soluciones distintas existen para el problema dado? Veamos algunos ejemplos. 202 Conceptos de teorı́a de gráficas Existencia de solución: Cuatro parejas casadas juegan tenis de dobles mixtos en dos canchas cada domingo en la noche. Juegan durante dos horas, pero intercambian parejas y oponentes al final de cada perı́odo de media hora. ¿Existe una programación de tal manera que cada hombre juegue con y contra cada mujer exactamente una vez, y juega contra cada hombre al menos una vez? Contar el número de soluciones: Un grupo de inversionistas decide rotar los puestos de presidente y tesorero cada año. ¿Cuántos años van a transcurrir antes de que tenga que repetir alguno de los socios en alguna de las dos posiciones? Optimización: Un empresario tiene tres empleados, Patty, Enrique y Roque, a quienes les paga $60, $70 y $80 pesos la hora respectivamente. El empresario tiene tres trabajos por asignar. La siguiente tabla muestra cuánto tiempo requiere cada trabajador para hacer cada uno de los trabajos. ¿Cuál es la manera de asignar el trabajo para que salga tan barato como sea posible? Patty Trabajo 1 Trabajo 2 Trabajo 3 Enrique 7.5 hr. 6 hr. 8 hr. 8.5 hr. 5 hr. 6.5 hr. Roque 6.5 hr 7 hr. 5.5 hr. Estos tres problemas, de alguna manera, tienen que ver con combinatoria, las distintas maneras que se tienen de resolver el problema y cómo elegir la mejor de ellas. La solución para muchos de estos problemas está dada por algoritmos. Un algoritmo es un método de solución que cumple con: Entradas: El algoritmo trabaja a partir de cero o más datos. Cuando son cero datos, es porque trabaja a partir de constantes. Por ejemplo, tenemos un algoritmo que elabora una tabla de senos, y empieza a producir valores empezando con un valor constante. Salidas: El algoritmo produce un resultado. Finitud: El número de pasos del algoritmo es finito. Definición: Cada paso está bien definido y susceptible de ser ejecutado por un hombre con papel y lápiz. Terminación: El algoritmo siempre debe terminar. No para todos los problemas hay algoritmos que los resuelvan. Más adelante, en su contacto con las ciencias de la computación estudiarán que hay más problemas que algoritmos, por lo que algunos problemas se tendrán que quedar sin solución algorı́tmica. En este capı́tulo nos haremos las tres preguntas que acabamos de plantear, revisando aquellos problemas que se pueden modelar con gráficas, donde una gráfica es un modelo matemático. 203 5.1 Motivación 5.1.1. Tiempo para completar un proyecto El problema: La Sociedad Mexicana de Ciencias de la Computación está organizando un Encuentro para llevarse a cabo a principios del mes de marzo, y tiene que mandar propaganda (un folleto de 8 páginas) para avisar del evento. Esta propaganda debe ser enviada al menos 10 dı́as antes de la fecha del evento para que sea efectivo, pero se deben hacer varias tareas y tomar algunas decisiones antes de elaborar el folleto. El comité organizador del evento debe decidir que temas se van a tratar en el encuentro, y el comité académico debe decidir a quienes invitar para que sean árbitros de los trabajos. Entonces un comité local debe decidir a quién invitar para conferencias magistrales sobre los temas decididos. El comité organizador debe preparar dibujos alusivos a los temas a tratar, y alguien tiene que redactar las descripciones cortas de las conferencias magistrales. Finalmente se junta toda la información y se elabora la propaganda requerida, para que se envı́e por correo. El comité de propaganda elabora una lista de correo de a quienes enviar la propaganda. Una vez hecho esto se elaboran las etiquetas para los sobres a enviar. Una vez que se termina de imprimir el folleto, se le pega a cada uno una etiqueta, se organizan por código postal y se llevan a la oficina de correos. Todas estas actividades toman un cierto tiempo; algunas de ellas se pueden llevar a cabo de manera simultánea, pero otras tienen que esperar a que actividades previas se terminen. La SMCC quiere saber cuál es el tiempo que requiere para preparar el encuentro, para saber cuál es la fecha más tarde en la que pueden empezar las distintas tareas. Para calcular el tiempo total del proyecto necesitamos dos tipos de información: el tiempo, en dı́as, que se toma cada actividad, y las actividades que tienen que estar terminadas para que ésta se pueda llevar a cabo. En la tabla 5.1 se encuentra esa información. Este problema se presta para modelarlo con una gráfica dirigida (o digráfica). Una digráfica es un conjunto de vértices o nodos y una relación entre ellos, que llamamos los arcos de la digráfica. Si u y v son nodos de la digráfica, decimos que (u, v) (u → v) es un arco que sale del nodo u y llega al nodo v y que se representa de alguna de las siguientes formas: u v u • v • u v En nuestro problema particular, el arco (u, v) significa que la actividad u se tiene que terminar antes de que inicie la actividad v. En cada vértice colocaremos el tiempo requerido para que la actividad se lleve a cabo, además del identificador de la actividad. El resultado se puede observar en la figura 5.1. 204 Conceptos de teorı́a de gráficas Tabla 5.1 Tiempos requeridos y predecesores por actividad Id. Tarea Tiempo Tareas precedentes A. B. C. D. E. F. G. H. I. J K Elegir temas. Elegir árbitros Elegir conferencias magistrales Dibujos alusivos Redacción de resúmenes Elaborar el folleto Elaborar la lista de correo Imprimir las etiquetas Imprimir el folleto Pegar las etiquetas Repartir la propaganda 3 2 2 4 3 2 3 1 5 2 10 ninguna ninguna AyB C C D, E C G F H, I J Figura 5.1 Digráfica que corresponde a la organización del encuentro A 3 G 3 C 2 D 4 H 1 F 2 I 2 J 2 K 10 B 2 E 3 Tratemos de calcular cuál es el mı́nimo tiempo requerido para ejecutar todas las tareas y terminar lo antes posible. Si simplemente tomamos la suma de los tiempos que se requieren para terminar todas las tareas, obtendremos un tiempo total de 47 dı́as. Sin embargo, muchas de esas tareas se pueden hacer de manera simultánea. ¿Cómo determinar, entonces, cuál es el menor tiempo en el que todas las tareas pueden ser completadas? 205 5.1 Motivación En 1958 se desarrolló una técnica, llamada PERT (Program Evaluation and Review Technique), que calcula, entre otras cosas, lo que se conoce como ruta crı́tica. Una ruta crı́tica consiste de ordenar en el tiempo los eventos que se tienen que llevar a cabo y encontrar una “programación” de dichos eventos, de tal manera que se desarrollen todos ellos en el menor tiempo posible, respetando las precedencias especificadas. El algoritmo para ruta crı́tica es muy sencillo y consiste de lo siguiente. 1. Programar a todas las tareas que no tienen ninguna tarea que las preceda. Esto quiere decir asignarles como tiempo de programación (o terminación) igual al tiempo que se lleva la tarea. 2. Mientras queden tareas por programar: a) La tarea t se programa si todas las tareas que preceden a t ya están programadas. b) Su tiempo de programación se calcula como la suma del tiempo que se lleva la tarea t más el máximo tiempo de programación de entre las tareas que la preceden. 3. El tiempo total mı́nimo que se lleva el proceso es el máximo asignado a cualquiera de los nodos. Si trabajamos sobre la digráfica de la figura 5.1, podemos ver la ejecución de cada uno de los pasos. Colocamos encima del nodo el valor asignado para la programación. El Paso 1 nos indica que localicemos a las tareas que no tienen predecesores, y que son la tarea A y la B. Procedemos a asignarles como tiempo de programación el que corresponde a su tiempo de ejecución. Figura 5.2 Programación de los eventos A y B de la digráfica 5.1 3 G 3 A 3 C 2 D 4 H 1 F 2 I 2 J 2 K 10 2 B 2 E 3 Al entrar a la iteración del algoritmo, el único nodo que cumple con las condiciones dadas es el nodo etiquetado con C, al que le corresponde el valor de 5, que es el máximo para programación de sus predecesores (3) sumado al tiempo que toma C (2). 206 Conceptos de teorı́a de gráficas Figura 5.3 Programación del evento C de la digráfica 3 A 3 G 3 H 1 5 C 2 D 4 F 2 I 2 J 2 K 10 2 E 3 B 2 Como C es el único predecesor de G, D y H, estamos en condiciones de resolver el tiempo requerido, desde el inicio del proyecto, para estas tres tareas: Figura 5.4 Programación de los eventos D, G y E de la digráfica 3 8 A 3 G 3 5 9 C 2 D 4 2 8 B 2 E 3 H 1 F 2 I 2 J 2 K 10 La siguiente “capa” es la que corresponde a las tareas H y F , cuyos antecesores ya están resueltos: 207 5.1 Motivación Figura 5.5 Programación de los eventos F y H de la digráfica 3 8 9 A 3 G 3 H 1 5 9 11 C 2 D 4 F 2 2 8 B 2 E 3 I 2 J 2 K 10 A continuación resolvemos el evento I, al que le asignamos un valor de 15, y con este evento, y con el evento H podemos resolver el evento J y a continuación el evento K. Los tiempos quedan asignados como se muestra en la figura 5.6. Figura 5.6 Programación del resto de los eventos de la digráfica 3 8 9 A 3 G 3 H 1 5 9 11 13 15 25 C 2 D 4 F 2 I 2 J 2 K 10 2 8 B 2 E 3 De manera similar podemos obtener el tiempo de inicio de cada proyecto mediante el siguiente algoritmo: 1. Marcar con 1 a todas las tareas que no tienen otra tarea que las preceda. 2. Se asigna tiempo de inicio a la tarea t si todas las tareas que la preceden tienen ya tiempo de inicio asignado, usando la siguiente fórmula: Inicio(t) = máx{Inicio(p) + T iempo(p)} con p predecesor de t 3. Termina cuando no haya tareas sin tiempo inicial asignado. 208 Conceptos de teorı́a de gráficas Colocaremos el tiempo inicial antes del tiempo final, separándolos con una diagonal, en la figura 5.7. Figura 5.7 Tiempos de inicio/fin de cada tarea 1/3 6/8 9/9 A 3 G 3 H 1 4/5 6/9 10/11 12/13 14/15 16/25 C 2 D 4 F 2 I 2 J 2 K 10 1/2 6/8 B 2 E 3 A continuación queremos obtener aquellas tareas que son crı́ticas para el proyecto, esto es, que deben iniciar exactamente en cuanto sus predecesores terminan – de acá viene el nombre de ruta crı́tica para este problema. Para ello, procedemos de la última tarea, la que le da el tiempo total al proyecto, y regresamos marcando a las tareas que aportaron el máximo. Conforme vamos regresando, marcamos los arcos de la digráfica con lı́nea doble, para identificar la ruta, y los nodos también con lı́nea doble. El resultado se puede ver en la figura 5.8. Figura 5.8 Una de las rutas crı́ticas del proyecto 1/3 6/8 9/9 A 3 G 3 H 1 4/5 6/9 10/11 12/13 14/15 16/25 C 2 D 4 F 2 I 2 J 2 K 10 1/2 6/8 B 2 E 3 209 5.1 Motivación Otra información que podemos sacar de esta digráfica es aquellas actividades que tienen tiempo “de sobra” para empezar sus actividades. Es claro que las actividades que están sobre la ruta crı́tica no pueden perder tiempo y deben empezar exactamente cuando se les tiene programadas, pues son las que más tiempo se llevan. Pero aquellas actividades que no están en la ruta crı́tica pudiesen tener alguna holgura en su tiempo de inicio. Por ejemplo, la actividad B podrı́a no empezar el primer dı́a, sino hacerlo hasta el segundo sin retrasar el tiempo final del proyecto. La actividad H, asimismo, pudiera empezar el noveno dı́a o bien esperarse hasta el dı́a 13, y con eso estar lista en el dı́a 14, que es cuando la actividad J necesita que la actividad H esté terminada. Este tiempo de holgura lo podemos calcular como el menor tiempo de inicio de sus sucesores. El cálculo empieza en las tareas que no tienen sucesores y va hacia atrás. En la figura 5.9 se muestra a continuación del tiempo de inicio, mediante el siguiente algoritmo: 1. Calcula el máximo tiempo de inicio de las tareas que no tienen sucesores como el tiempo de inicio qee tienen ya marcado. 2. El máximo tiempo de inicio de una tarea que tiene sucesores se calcula como: mInicio(t) = mín{Inicio(s) − T iempo(t)} con s tarea sucesora de p Figura 5.9 Tiempos de inicio/último-inicio/fin de cada tarea 1/1/2 6/10/8 9/13/9 A 3 G 3 H 1 4/4/5 6/6/9 10/10/11 12/12/13 14/14/15 16/16/25 C 2 D 4 F 2 I 2 J 2 K 10 1/2/3 6/7/8 B 2 E 3 En la tabla 5.2 en la siguiente página ponemos el último dı́a en que cada actividad puede empezar. 210 Conceptos de teorı́a de gráficas Tabla 5.2 Margen de tiempos para el inicio de las actividades 5.1.2. Id. Tarea A. B. C. D. E. F. G. H. I. J K Elegir temas. Elegir árbitros Elegir conferencias magistrales Dibujos alusivos Redacción de resúmenes Elaborar el folleto Elaborar la lista de correo Imprimir las etiquetas Imprimir el folleto Pegar las etiquetas Repartir la propaganda Tiempo Tareas precedentes Dı́a 1 Dı́a últ. 3 2 2 4 3 2 3 1 2 2 10 ninguna ninguna AyB C C DyE C G F H, I J 1 1 4 6 6 10 6 9 12 14 16 1 2 4 6 7 10 10 13 12 14 16 Asignación óptima de recursos Supongamos que tenemos una aerolı́nea que vuela a 7 distintas ciudades y cuenta con 7 pilotos. Cada piloto tiene sus preferencias respecto a dónde quiere volar. ¿Cuál es la manera de asignar a cada piloto a un vuelo, de tal manera que todos los pilotos vuelen a alguna ciudad de su preferencia? A este problema se le conoce con el nombre de apareamiento perfecto o acoplamiento perfecto (perfect matching en inglés) y se representa también con una gráfica que se conoce como bipartita. Veamos las preferencias de los pilotos respecto a las ciudades a las que quieren volar en la tabla 5.3. Tabla 5.3 Relación entre ciudades y pilotos Ciudad Pilotos: Monterrey Torres, Juárez, Guadalajara Albarrán, Torres, Londres Torres, Tamariz, Manzanillo Albarrán, Tamariz, Cancún Juárez, Zepeda, Huatulco Juárez, Ramı́rez Acapulco Torres, Robles, Robles Tamariz, Zepeda Robles, Robles Ramı́rez Zepeda Ramı́rez 211 5.1 Motivación Una gráfica bipartita es aquélla en la que los vértices están partidos en dos conjuntos ajenos y las aristas van siempre de vértices en un conjunto a vértices en el otro. En el caso de acoplamiento, es natural que un conjunto sea, por ejemplo, el de los pilotos, mientras que el otro conjunto es el de las ciudades a las que deben volar. La gráfica que corresponde a la tabla 5.3 se encuentra en la figura 5.10 Figura 5.10 Gráfica bipartita que corresponde a la tabla 5.3 To Ju Ro Al Ta Ze Ra Mo Gu Lo Ma Ca Hu Ac No todos los problemas de asignación óptima de recursos tienen solución. Por ejemplo, si se limita a que cada elemento de una de las partes quede relacionado únicamente con sólo uno de la otra parte, empezamos por pedir que el número de vértices en una partición sea el mismo que en la otra. Aun ası́ podrı́a no tener solución. Un algoritmo nos dice que tratemos de encontrar un camino que toque a cada vértice exactamente una vez y da otras pistas de dónde iniciar y cuáles son las caracterı́sticas que debe tener la gráfica bipartita para intentar armar el camino. Habiendo dado ya una idea de por qué las gráficas son un mecanismo de modelado útil, pasamos a explorar este concepto. Ejercicios 5.1.1.- Encuentra la ruta crı́tica en la siguiente digráfica. Para ello, elabora la tabla de las dependencias dadas por la digráfica y anota en dicha tabla el tiempo de inicio, el tiempo final y el tiempo disponible de holgura (slack en inglés) para cada una de las actividades del proyecto. Indica también cuál es el evento que se puede llevar a cabo el primero y cuál es el último evento en llevarse a cabo. 212 Conceptos de teorı́a de gráficas B 3 D 8 A 6 F 4 C 1 E 2 5.1.2.- Encuentra la ruta crı́tica en la siguiente digráfica. Para ello, elabora la tabla de las dependencias dadas por la digráfica y anota en dicha tabla el tiempo de inicio, el tiempo final y el tiempo disponible de holgura para cada una de las actividades del proyectos. Indica también cuál es el evento que se puede llevar a cabo el primero y cuál es el último evento en llevarse a cabo? B 3 D 4 A 2 F 1 C 2 E 3 5.1.3.- Encuentra la ruta crı́tica en la siguiente digráfica. Para ello, elabora la tabla de las dependencias dadas por la digráfica y anota en dicha tabla el tiempo de inicio, el tiempo final y el tiempo disponible de holgura para cada una de las actividades del proyectos. Indica también cuál es el evento que se puede llevar a cabo el primero y cuál es el último evento en llevarse a cabo? B 3 G 3 A 2 D 4 E 2 C 1 F 1 H 2 213 5.1 Motivación 5.1.4.- Encuentra la ruta crı́tica en la siguiente digráfica. Para ello, elabora la tabla de las dependencias dadas por la digráfica y anota en dicha tabla el tiempo de inicio, el tiempo final y el tiempo disponible de holgura para cada una de las actividades del proyectos. Indica también cuál es el evento que se puede llevar a cabo el primero y cuál es el último evento en llevarse a cabo? A 3 S 2 B 4 E 4 F 2 C 3 H 3 T 3 D 7 G 5 J 5 I 17 5.1.5.- Encuentra la ruta crı́tica en la siguiente digráfica. Para ello, elabora la tabla de las dependencias dadas por la digráfica y anota en dicha tabla el tiempo de inicio, el tiempo final y el tiempo disponible de holgura para cada una de las actividades del proyectos. Indica también cuál es el evento que se puede llevar a cabo el primero y cuál es el último evento en llevarse a cabo? S 3 C 2 B 4 D 3 E 3 F 3 G 1 I 2 J 2 K 5 H 3 L 5 M 2 N 12 T 3 5.1.6.- En un taller de herrerı́a se cuenta con dos máquinas de tipo A, una máquina de tipo B y tres máquinas de tipo C. El taller cuenta con 7 empleados con distinto manejo de cada una de las máquinas, como se muestra en la tabla siguiente: 214 Conceptos de teorı́a de gráficas Empleado Num. Sabe usar máquina(s): 1 2 3 4 5 6 7 A A,C C A,B A,B,C B B,C Construye la gráfica bipartita correspondiente a la tabla anterior. 5.1.7.- Da una asignación posible para el problema anterior que ocupe el mayor número de máquinas, un trabajador por máquina. ¿Cuántos turnos tendrı́an que cubrirse para que todos los trabajadores trabajen el mismo número de turnos en las máquinas? Da la organización necesaria para que esto último suceda. 5.1.8.- La siguiente gráfica es bipartita, aunque no se note. Dibújala de tal manera que se vea a simple vista que es bipartita. A B C E D F G H 5.1.9.- Dada la siguiente gráfica, argumenta por qué NO es bipartita. 215 5.2 Conceptos y formalización A B C D E F G 5.1.10.- Dada la siguiente gráfica, decide si es bipartita o no. Si es bipartita, da la partición de los vértices y si no lo es, explica por qué esa partición no se puede dar. E B D A C F G 5.2. Conceptos y formalización Como ya vimos, las gráficas nos sirven para modelar un sinfı́n de problemas de la vida real, como lo son la programación de eventos, el si se puede llegar de una ciudad a otra, los mapas, las relaciones presentes entre personas de un cierto grupo, la asignación de tareas, y muchos más. En este capı́tulo revisaremos con más cuidado el concepto matemático de gráfica y algunos de sus usos. Definición 5.1 Una gráfica G = (V, E) es una pareja que consiste de un conjunto no vacı́o de puntos V, llamados los vértices o nodos de la gráfica, y un segundo conjunto E de aristas, que corresponden a una relación de parejas entre los vértices, subconjunto de V × V . Los elementos de E reciben nombres, dependiendo de la forma que toma la pareja: Definición 5.2 Una arista es una pareja no ordenada de vértices e = uv. Los vértices u y v son los extremos de la arista e y la representamos como uv = vu. 216 Conceptos de teorı́a de gráficas Definición 5.3 Un lazo es una arista cuyos extremos son el mismo vértice (uu). → o, simplemente, Definición 5.4 Un arco es una pareja ordenada, que representamos como u → v, − uv (u, v). En el caso que estemos trabajando con arcos, al subconjunto del producto cartesiano lo identificamos con A. Definición 5.5 Decimos que una gráfica tiene aristas múltiples si es que hay más de dos aristas con los mismos extremos. Podemos asignar nombres a las aristas o arcos. Dependiendo de las restricciones que pudiese tener E (o A), las gráficas se clasifican de la siguiente manera: Definición 5.6 Una gráfica simple es aquella que no tiene aristas múltiples ni lazos. Definición 5.7 Una multigráfica es aquella que permite aristas múltiples y lazos. Definición 5.8 Una gráfica dirigida o digráfica es aquella que se define como G = (V, A), donde el subconjunto del producto cartesiano V × V corresponde a arcos; en este caso es claro que (u, v) 6= (v, u). Los términos gráfica simple o multigráfica se pueden aplicar a digráficas, sustituyendo simplemente a las aristas por arcos. Utilizaremos el término genérico de gráfica cuando no distingamos entre gráficas simples o multigráficas; en el mismo sentido utilizaremos digráficas cuando hablemos de los distintos tipos de gráficas dirigidas. Solemos representar a las gráficas pintando un punto o cı́rculo pequeño por cada vértice y una lı́nea que une a dos de éstos para las aristas. Podemos ver distintas representaciones de gráficas en la figura 5.11. En ella se muestran tres de las posibles variaciones que podemos darle a la representación, que incluyen nombrar o no a las aristas o vértices de la gráfica y la manera como elegimos representar a los vértices. Figura 5.11 Algunas representaciones con figuras (visuales) de gráficas (b) (a) v1 A v3 v5 v2 (1/2) C E v4 V = { v1 , v2 , v3 , v4 , v5 },  E = v1 v3 , v1 v5 , v1 v2 , v2 v4 , v2 v5 , v4 v5 , v3 v5 B D V = { A, B, C, D, E},  E = AC, AB, AE, BD, BE, CE, DE 217 5.2 Conceptos y formalización Figura 5.11 Algunas representaciones con figuras (visuales) de gráficas (2/2) (c) A e2 C e6 e3 e5 e1 B e4 E D e7 V = {A, B, C, D, E}, E = {e1 , e2 , e3 , e4 , e5 , e6 , e7 } El que la pareja sea no ordenada quiere decir que las parejas uv y vu representan a la misma arista, pues aparecen los mismos vértices, no importa en qué orden. En la figura 5.11, tenemos a las aristas sin nombre en las gráficas de las figuras 5.11(a) y 5.11(b), mientras que las aristas en la subfigura 5.11(c) sı́ tienen nombre (en los tres casos están listadas abajo de la gráfica). Definición 5.9 Dos vértices u y v son adyacentes si la arista e = uv ∈ E; dicho de otra manera, si existe una arista en E cuyos extremos son u y v. En las gráficas de la figura 5.11 los vértices A y B, por ejemplo, son adyacentes, lo mismo que los vértices A y C; y A y E. Los vértices B y C, en cambio, no son adyacentes ya que no hay ninguna arista que los conecte. Definición 5.10 Una arista e es incidente en un vértice v si v es uno de los extremos de la arista. En la gráfica de la figura 5.11(c) la arista e4 es incidente en los vértices B y D. En la figura 5.12 presentamos distintas maneras de dibujar una digráfica. En el caso de las digráficas los arcos se representan en los dibujos como flechas con la dirección deseada. La relación entre aristas y vértices está dada por el grado de un vértice: Definición 5.11 El grado de un vértice, denotado por grado(v), es el número de aristas incidentes en el vértice. En la gráfica de la figura 5.11(c) el grado del vértice A es 3, que corresponde a las aristas e1 , e2 y e3 , mientras que el grado del vértice D es 2 que corresponde a las aristas e4 y e7 . En digráficas hablamos del exgrado(v) e ingrado(v) que corresponde, respectivamente, al número de arcos que salen de v y al número de arcos que entran a v. 218 Conceptos de teorı́a de gráficas Figura 5.12 Representación de gráficas dirigidas (b) (a) A • v1 C • v3 v2 v4 • B v5 • D V = { A, B, C, D, E}, E = { AD, DE, BA, DC, CB, CE } V = { v1 , v2 , v3 , v4 , v5 }, E = { v1 → v4 , v4 → v5 , v2 → v1 , v4 → v3 , v3 → v2 , v3 → v5 } •E (c) A a1 B a2 C a4 a5 a3 D a6 E V = {A, B, C, D, E}, A = {a1 , a2 , a3 , a4 , a5 , a6 } El número de aristas de una gráfica está ı́ntimamente relacionado con el grado de los vértices. Esta relación se presenta en el teorema 5.1. Teorema 5.1 En una gráfica, la suma de los grados de los vértices es igual a dos veces el número de aristas: X grado(v) = 2 · |E| v∈V donde |E| denota al número de elementos de E, la cardinalidad de E. 219 5.2 Conceptos y formalización Cada arista incide en dos vértices, por lo que si se cuentan los vértices en los que inciden Demostración.  P las aristas grados , cada arista será contada dos veces. Otra demostración de este teorema, y que utiliza la inducción estructural que ya vimos y que es muy común en teorı́a de gráficas, se plantea como sigue: (a) Demostramos primero el caso para una gráfica con 1 vértice y 0 aristas (ver en la figura 5.13 el caso G = ({v}, ∅)). El grado de este vértice es 0; el número de aristas también es 0, por lo que se cumple X 0 = 2 · |E| = grado(v) = 0 v∈V Figura 5.13 G = ({v}, ∅) v (b) Observemos una gráfica con n ≥ 2 vértices. Quitémosle un vértice (con todas las aristas que inciden en él) – ver figura 5.14 –. Figura 5.14 Inducción estructural en gráficas La gráfica resultante (encuadrada con lı́nea punteada) cumple con la hipótesis de inducción de que la suma de los grados de los vértices es dos veces el número de aristas. Repongamos el vértice que quitamos, junto con sus aristas. Por cada arista que agregamos, dos vértices ven incrementado sus grados en una unidad – el que estamos reinsertando y aquel al que llega la arista –. Supongamos que el grado del vértice reinsertado es k. Entonces tenemos ! n n−1 X X grado(vi ) = grado(vi ) + 2 · k = 2 (|E| − k) + 2 · k = 2 · |E| i=1 i=1 220 Conceptos de teorı́a de gráficas Teorema 5.2 En una gráfica cualquiera, existe un número par de vértices de grado impar. P Demostración. Por el teorema anterior sabemos que v∈V grado(v) = 2|E|. Separemos esta suma entre los vértices de grado par y los de grado impar: Sea y Entonces X Vp = {v ∈ V |grado(v) es par} Vi = {v ∈ V |grado(v) es impar} grado(v) = v∈V X grado(v) + v∈Vp X grado(v) = 2|E| v∈Vi La suma total es par; la suma de pares es par (de la primera parte) y, para que el resultado sea par, la segunda parte también tiene que ser par. Si el número de vértices de grado impar fuera impar, el resultado serı́a impar, por lo que el número de vértices de grado impar tiene que ser par. Tenemos ciertos tipos de gráficas que tienen una determinada relación entre sus vértices y sus aristas. Definición 5.12 Una gráfica completa con n vértices, denotada por Kn , es aquélla donde cada vértice es adyacente a cualquier otro vértice de la misma gráfica. En la figura 5.15 vemos algunos ejemplos de gráficas completas. Figura 5.15 Ejemplos de gráficas completas (b) K6 (a) K4 v6 v3 v4 v1 v2 v3 v4 v1 v2 v5 221 5.2 Conceptos y formalización Otro tipo de gráficas distinguidas son aquellas que forman una especie de anillo, donde cada vértice tiene grado 2 y se puede llegar de cualquier vértice a cualquier otro simplemente recorriendo el anillo. A estas gráficas se les conoce como Cn , donde la C está por “ciclo” y la n denota el número de vértices. En la figura 5.16 se muestran varias de estas gráficas. Figura 5.16 Ejemplos de ciclos (b) C6 (a) C3 v3 v5 (c) C4 v4 v6 v1 v4 v3 v1 v2 v3 v2 v1 v2 Las gráficas Cn presentan también algunas propiedades, como son que el grado de todos sus vértices es 2 y que el número de aristas en una gráfica Cn es n. Cuando definamos lo que es un camino entre dos vértices regresaremos brevemente a las gráficas Cn . Otro tipo de gráfica que ya vimos y que resulta muy importante para toda una clase de problemas, la optimización de asignación de recursos, son las gráficas bipartitas. Definición 5.13 (Gráfica bipartirta) Una gráfica bipartita es aquella en la que podemos partir al conjunto de los vértices en dos subconjuntos ajenos, de tal manera que todas las aristas van de vértices de un conjunto a vértices del otro subconjunto (esto es, no hay aristas entre los vértices de un mismo subconjunto). De esta definición queda claro que no importa cómo se dibuje la gráfica, siempre se puede redibujar de tal manera que tengamos dos hileras de vértices, una por cada subconjunto. En la figura 5.17 se muestran varias gráficas bipartitas. Figura 5.17 Gráficas bipartitas (1/2) (a) c a a b f g c d e h f d h g b e 222 Conceptos de teorı́a de gráficas Figura 5.17 Gráficas bipartitas (2/2) (b) b a e a c c b e d d (c) a c b a c d e f h e d g f h g b También entre las gráficas bipartitas podemos tener gráficas completas y se representan como Km,n , donde la m y la n nos denotan el número de vértices en cada subconjunto. En el caso de gráficas bipartitas, lo completo se refiere a que cada vértice de un subconjunto es adyacente a todos los vértices del otro subconjunto. En la figura 5.18 podemos ver algunas gráficas bipartitas completas. Figura 5.18 Gráficas bipartitas completas (1/2) (a) K3,2 a (b) K4,4 c b d e a b c d e f g h 223 5.2 Conceptos y formalización Figura 5.18 Gráficas bipartitas completas (2/2) (d) K2,2 (c) K6,2 a c b a b a d b c e d c g f d h Definimos también lo que es una subgráfica, concepto que utilizaremos ampliamente en el resto de este capı́tulo. Definición 5.14 (Subgráfica) Sea G = (V, E) una gráfica. Una subgráfica G′ = (V ′ , E ′ ) de G es una gráfica tal que V ⊆ V ′ y E ⊆ E ′ . En otras palabras, se eliminan cero o más vértices y cero o más aristas de la gráfica original. Entre las aristas que se eliminan tienen que estar aquellas aristas incidentes en los vértices eliminados. Esto es, una subgráfica G′ de una gráfica G es aquella que resulta de quitar de la gráfica original algunos vértices, junto con todas las aristas que inciden en estos vértices, y algunas aristas más. Ya utilizamos el concepto de subgráfica en la demostración por inducción estructural del teorema 5.1. En la figura 5.19 presentamos varias gráficas y a su derecha algunas de sus subgráficas. Figura 5.19 Gráficas con algunas de sus subgráficas (1/2) (a) a e d f c b g a b c a b c f g h e h g 224 Conceptos de teorı́a de gráficas Figura 5.19 Gráficas con algunas de sus subgráficas (2/2) (a) v1 v3 v5 v1 v2 v4 v6 v2 v3 v5 v1 v5 v6 v2 v6 Nos van a interesar ciertos tipos de subgráficas, que definimos a continuación: Definición 5.15 Una subgráfica de una gráfica G inducida por un subconjunto de vértices A es aquella que resulta de eliminar algunos vértices de la gráfica y, junto con esos vértices, eliminar exclusivamente las aristas incidentes en los vértices eliminados; se denota como G[A] (o más raramente GhAi). Similarmente, una subgráfica inducida por un subconjunto de aristas es aquella que resulta de eliminar algunas aristas y, junto con esas aristas, aquellos vértices que resultan no ser adyacentes a ningún otro vértice de la gráfica una vez eliminadas las aristas seleccionadas. En la figura 5.20 presentamos varias gráficas y a su derecha algunas de sus subgráficas inducidas. En la subfigura 5.20(a) vemos subgráficas generadas por un subconjunto de los vértices originales. Se eliminan exclusivamente las aristas incidentes en los vértices eliminados. En la subfigura 5.20(a) vemos subgráficas inducidas por un subconjunto de aristas, donde se eliminan aquellos vértices que quedan sin ninguna arista incidente en ellos. Figura 5.20 Gráficas con algunas de sus subgráficas inducidas (1/2) (a) Subgráficas inducidas por subconjuntos de vértices a e d f c b g b b c f g h e d h a g 225 5.2 Conceptos y formalización Figura 5.20 Gráficas con algunas de sus subgráficas inducidas (2/2) (a) Subgráficas inducidas por subconjuntos de aristas e10 e2 v1 e1 e3 v2 e5 v3 e6 e4 v4 v5 e7 e8 v1 v3 v5 v1 v5 v2 v4 v6 v2 v6 e9 v6 e11 En la segunda gráfica de la subfigura 5.20(a), al eliminar a las aristas e3 , e6 , e10 y e11 , ningún vértice queda aislado, por lo que no se elimina ninguno de la subgráfica. En cambio, en la tercera gráfica de esta misma subfigura, al eliminar a todas las aristas incidentes en v3 y v4 , se eliminan también estos dos vértices. Otro concepto importante relacionado con el de subgráficas es el de subgráfica generador que se define como sigue: 1 Definición 5.16 (Subgráfica generadora) Sea G = (V, E) una gráfica no dirigida. Una subgráfica generadora es una subgráfica G′ = (V, E ′ ) de G tal que contiene a todos los vértices de G y E ′ ⊆ E. La idea con una subgráfica generadora es que estén presentes todos los vértices de la gráfica original. En la figura 5.21 podemos ver a una gráfica con dos de sus gráficas generadoras. Figura 5.21 Gráfica con subgráficas generadoras (a) (b) v2 v1 v4 v3 1 v5 v2 v1 v6 En inglés spanning subgraph. (c) v5 v4 v3 v2 v1 v6 v5 v4 v3 v6 226 Conceptos de teorı́a de gráficas Ejercicios 5.2.1.- Dada la siguiente gráfica, especifica cuáles son sus conjuntos V y E. d a g e c f b 5.2.2.- Dada la siguiente gráfica, especifica cuáles son sus conjuntos V y E. v1 v3 v5 v2 v4 v6 5.2.3.- Dada la siguiente gráfica dirigida, especifica cuáles son sus conjuntos V y A. F C B H I E G A D 227 5.2 Conceptos y formalización 5.2.4.- Dados los siguientes conjuntos, dibuja la gráfica a la que corresponden.  V = v1 , v2 , v3 , v4 , v5 , v6  E = v1 v2 , v2 v4 , v2 v5 , v2 v3 , v2 v6 , v 4 v 3 , v6 v 3 } 5.2.5.- Dibuja una gráfica tal que |V | = 5 y |E| = 6. 5.2.6.- Dibuja una gráfica dirigida tal que |V | = 6 y |A| = 9. 5.2.7.- Determina el grado de cada vértice en las siguientes gráficas: (b) (a) v1 v1 v2 v3 v4 v5 v5 v3 v6 v2 v6 v4 5.2.8.- Determina el exgrado e ingrado de cada vértice en las siguientes gráficas dirigidas: (b) (a) v2 v1 v3 v6 v4 v5 v1 v2 v4 v3 v5 228 Conceptos de teorı́a de gráficas 5.2.9.- Explica por qué no puede haber una gráfica con un número impar de vértices, cada uno de ellos con grado impar. 5.2.10.- Dibuja las gráfica que corresponden a K2 , K3 y K5 . 5.2.11.- Usando la propiedad de que los vértices en las gráficas Cn , n > 2, tienen todos grado 2, demuestra que el número de aristas en una gráfica Cn es n. 5.2.12.- Dada la siguiente gráfica, dibuja dos subgráficas generadoras distintas. a b e c f d g h 5.3. Representación de gráficas para su manipulación En esta sección trabajaremos únicamente con gráficas simples y nos referiremos a ellas simplemente como gráficas. Para poder manipular las gráficas desde alguna aplicación en una computadora tenemos que contar con alguna representación más descriptiva que la de los dibujos. Si bien los dibujos funcionan muy bien para el ojo humano, las computadoras no trabajan bien con imágenes “de conjunto”. La definición matemática de lo que es una gráfica resulta ser mucho más manejable. En esta sección presentaremos varias opciones de representación que se prestan bien para la manipulación de gráficas a través de algoritmos. 5.3.1. Matriz de adyacencias La matriz de adyacencias para una gráfica con n vértices es una matriz cuadrada de n×n, tal que el elemento mi,j de la matriz, que denota al renglón i, columna j, está definido 229 5.3 Representación de gráficas para su manipulación de la siguiente manera: ( 1 si e = vi vj ∈ E = 0 si e = vi vj ∈ /E mi,j Veamos en la figura 5.22 una gráfica con su correspondiente matriz de adyacencias. Figura 5.22 Representación de gráficas con matriz de adyacencias (b) (a) v1 0 1 1 1 0 0 0 v2 1 0 1 0 0 0 0 v3 1 1 0 0 1 1 0 v4 1 0 0 0 1 0 0 v5 0 0 1 1 0 0 1 v6 0 0 1 0 0 0 1 v7 0 0 0 0 1 1 0 1 ( ) v1 v2 v3 v4 v5 v6 v7 2 7 3 4 6 5 Esta representación particular presenta propiedades que pudiesen contestar rápidamente a preguntas que quisiésemos hacernos respecto a una gráfica particular. Teorema 5.3 La suma de las entradas en el renglón i de una matriz de adyacencias corresponde al grado del vértice vi . Observemos el renglón de cualquier vértice, digamos vi . Cada 1 que aparece es porque el Demostración. vértice de la columna j, vj , es adyacente a él. Por lo tanto, el número de 1’s en el renglón i indica el número de vértices distintos de vi que son adyacentes a él. Como cada entrada vale 1, la suma de estas entradas es precisamente el número de vértices adyacentes a él, o sea grado(vi ). La matriz de adyacencias de una gráfica presenta las siguientes propiedades: Definición 5.17 Decimos que una matriz es cuadrada si tiene el mismo número de renglones que de columnas. Las matrices de adyacencias son cuadradas porque tienen un renglón para cada vértice y una columna para cada vértice, por lo que el número de renglones es el mismo que el n umero de columnas. 230 Conceptos de teorı́a de gráficas Definición 5.18 Decimos que una matriz es simétrica si ∀i, j, 0 ≤ i, j < |V |, mi,j = mj,i . Para que una matriz sea simétrica debe ser cuadrada. Definición 5.19 La diagonal principal de una matriz (cuadrada) es el vector que corresponde a los elementos mi,i de la matriz. Como estamos trabajando con gráficas simples, la diagonal principal de una matriz de adyacencias es de ceros, ya que no tenemos ningún lazo en la gráfica. También es importante notar que las matrices de adyacencias son siempre simétricas: si tenemos una arista que va del vértice i al vértice j (mi,j = 1), también tendremos a esa misma arista (recordemos que estamos trabajando con gráficas simples) que va del vértice j al vértice i (por lo que mi,j = mj,i = 1). Es conveniente mencionar que, dada esta simetrı́a en las matrices de adyacencias, el teorema 5.3 se cumple también si sustituimos “columna” donde dice “renglón”. 5.3.2. Matriz de incidencias En esta representación tenemos también una matriz, pero ahora es de n = |V | renglones por m = |E| columnas, donde en cada posición (i, j) se anota si la arista j es incidente en el vértice i. Las ventajas que tiene esta representación es que podemos tener más de una arista entre dos vértices (multigráfica). Las entradas de la matriz quedan de la siguiente forma: ( 0 si ej no incide en vi mi,j = 1 si ej incide en vi Si le ponemos nombres a las aristas de la gráfica anterior, la matriz de incidencias quedarı́a como se ve en la figura 5.23. Figura 5.23 Representación de gráficas con matriz de incidencias (a) ( v1 v2 v3 v4 v5 v6 v7 a 1 1 0 0 0 0 0 b 1 0 1 0 0 0 0 c 1 0 0 1 0 0 0 d 0 1 1 0 0 0 0 e 0 0 1 0 1 0 0 f 0 0 0 1 1 0 0 (b) g 0 0 1 0 0 1 0 h 0 0 0 0 1 0 1 i 0 0 0 0 0 1 1 ) a v1 b c v2 d i g v3 v7 e v4 v6 f v5 h 5.3 Representación de gráficas para su manipulación 231 En esta representación es un poco más complicado conocer cuáles son los vértices adyacentes a un vértice dado. Si queremos saber, por ejemplo, cuáles son los vértices adyacentes al vértice v3 , observamos cada columna del renglón correspondiente a v3 en la que haya un 1, indicando que la arista ej es incidente en ese vértice. Las columnas correspondientes son la b, d, e y g. A continuación revisamos cada una de estas columnas y aquel renglón distinto del correspondiente a v3 en el que haya un 1, corresponde a un vértice adyacente al vértice v3 ; en la columna b es v1 ; en la columna d es v2 ; en la columna e es v5 y en la columna g es v8 . Sin embargo, a la pregunta de si una arista es o no incidente en un vértice la respuesta se obtiene simplemente revisando la entrada correspondiente de la matriz. De esta representación obtenemos rápidamente la información respecto al grado de un vértice, ya que corresponde al número de aristas incidentes en él. Lema 5.1 En una gráfica representada por una matriz de incidencias, el grado del vértice vi está dado por la suma de las entradas del renglón i en la matriz. La demostración de este lema se deja como ejercicio. El número de aristas en la gráfica también se obtiene de manera inmediata de esta representación, ya que corresponde al número de columnas de la matriz. 5.3.3. Listas de adyacencias Cuando representamos a una gráfica a través de una matriz, sea ésta de adyacencias o incidencias, se tiene la sensación de que se desperdicia mucho lugar en la matriz. Por ejemplo, si los vértices, en general, tienen un grado menor a la mitad del número de vértices (∀v ∈ V, grado(v) < |V |), la matriz va a tener más ceros que unos. Si estamos hablando de una matriz de incidencias, cada columna tiene a lo más dos entradas con 1 y el resto con 0. Las entradas que realmente tienen información son las que tienen 1, por lo que decimos que la densidad de la matriz es baja (a matrices con esta distribución de información se les conoce como matrices ralas y a las gráficas correspondientes también se les llama gráficas ralas porque tienen pocas aristas). Si en lugar de una posición para cada combinación posible, listamos únicamente aquellas entradas que sean distintas de 0, y si la matriz es rala, podemos ahorrar muchı́simo espacio. Por ejemplo, si la gráfica tiene 1,000 vértices que representan, digamos, a todos los pueblos por los que pasan todas las carreteras del paı́s, pero cada pueblo está conectado a, digamos, un máximo de 6 pueblos distintos a él, con las listas de adyacencias ocuparı́amos algo ası́ como 12,000 lugares2 , mientras que con la matriz de adyacencias ocuparı́amos 1,000,000 de lugares. 2 En una lista se ocupan dos espacios por cada elemento, uno para el elemento mismo y otro como referencia al que sigue en la lista. 232 Conceptos de teorı́a de gráficas La representación con listas de adyacencias es como sigue: se usan n = |V | listas, una para cada vértice. Estas listas pueden estar en un vector, de tal manera que la lista correspondiente al i-ésimo vértice se encuentre a partir de la posición i del vector. A partir de ahı́, vamos colocando en la lista del vértice i a cada uno de los vértices adyacentes a él. Para que el tamaño de cada lista pueda ser variable, cada elemento de la lista tiene una referencia (apuntador, liga) al siguiente vértice adyacente, o bien una referencia nula si éste es el último vértice de la lista. Figura 5.24 Representación de gráficas con listas de adyacencias (b) (a) a 1 v1 v2 v3 v4 v5 v6 v7 v2 v1 v1 v1 v3 v3 v5 v3 v3 v2 v5 v4 v7 v6 v4 v5 b v6 c 2 d 6 i g 7 3 v7 e 4 f h 5 En el caso de la gráfica que nos ocupa, para cada vértice vi , armamos una sucesión (una lista) con todos los vértices que son adyacentes a él. Nuevamente utilizamos a la gráfica de la figura 5.23 para construir la lista de adyacencias en la figura 5.24. Esta representación resulta apropiada para recorrer gráficas, pues se pueden ir eliminando de las listas para cada vértice a aquellos vértices que se van alcanzando. Asimismo, es fácil recorrer aristas pues se va de vértice en vértice de manera prácticamente directa. Las respuestas a las preguntas relacionadas con los grados de los vértices se obtienen de manera muy eficiente, pues se cuentan los elementos presentes en cada una de las listas. Averiguar si dos vértices son o no adyacentes puede ser un poco más costoso, pues hay que recorrer toda la lista de uno de los vértices antes de decidir que el otro vértice no aparece en esa lista, mientras que en la representación de matriz de adyacencias la respuesta se obtiene simplemente viendo la entrada correspondiente de la matriz. Esta representación es la preferida para la mayorı́a de los algoritmos que pretenden explorar una gráfica. 233 5.3 Representación de gráficas para su manipulación 5.3.4. Listas de incidencias En la representación de gráficas mediante listas de incidencias seguimos una lógica parecida a la que usamos para las listas de adyacencias: únicamente vamos a listar, para cada vértice, aquellas aristas que son incidentes a ese vértice. La diferencia principal es que en lugar de que aparezcan los vértices adyacentes aparecen las aristas incidentes. En la figura 5.25 mostramos la codificación de la gráfica que hemos estado manejando. Figura 5.25 Representación de gráficas con listas de incidencias (a) (b) a 1 v1 v2 v3 v4 v5 v6 v7 a a b c e g h b d d f f i i b c e c g 2 d i g 7 3 e h 4 6 f h 5 Nuevamente en esta representación obtenemos información de manera eficiente respecto a los grados de los vértices de la gráfica. Para saber cuáles son los vértices adyacentes a un vértice dado deberemos contar con otra estructura de datos que nos indique cuáles son los extremos de las aristas listadas. Si bien esto requiere de más espacio, el tiempo requerido para responder a esta pregunta también es constante, por lo que se considera una operación eficiente. Cada una de estas representaciones tiene ventajas y desventajas. Es claro que la elección de representación va a depender del tamaño de la gráfica (podemos pensar en gráficas con un número muy grande de vértices), de qué tan conectados estén los vértices entre sı́ (si hay una gran cantidad de conexiones entre los vértices o la gráfica es completa, la matriz resultará densa y por lo tanto con poco desperdicio), de cuáles sean las preguntas que nos hagamos respecto a ella y, finalmente, de cuáles son los algoritmos que queramos ejecutar sobre la gráfica. 234 Conceptos de teorı́a de gráficas Ejercicios 5.3.1.- Demuestra el lema 5.1. 5.3.2.- Cuenta el número de observaciones que se tienen que hacer en una gráfica representada por una matriz de adyacencias para determinar el grado de cada uno de los vértices de la gráfica. 5.3.3.- Explica cómo se obtienen los extremos de una arista dada en cada una de las representaciones que dimos. 5.3.4.- Para la siguiente gráfica, da su representación como matriz de adyacencias, matriz de incidencias, listas de adyacencias y listas de incidencias. h v1 a c v2 d e v3 b f g v4 v5 5.3.5.- Explica por qué las listas de adyacencias y las listas de incidencias tienen exactamente el mismo número de elementos renglón por renglón. 5.3.6.- ¿Con cuál de las codificaciones se pueden representar lazos, o sea aristas que salen y llegan al mismo vértice? 5.3.7.- Dada las siguientes listas de adyacencias, dibuja una gráfica que corresponda a estas listas. Listas de adyacencias: v1 v2 v5 v6 v2 v1 v3 v6 v3 v2 v4 v6 v4 v3 v5 v6 v5 v1 v4 v6 v6 v1 v2 v3 v4 v5 5.3 Representación de gráficas para su manipulación 235 5.3.8.- Dada la siguiente matriz de adyacencias, dibuja una gráfica que tenga a esa matriz como representación.           1 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 1 0 0 0 1 1 1           5.3.9.- Dibuja una gráfica que corresponda a la siguiente matriz de adyacencias:         0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0         5.3.10.- ¿Cómo identificas en una matriz de adyacencias a una gráfica Cn ? 5.3.11.- ¿Cómo identificas en una matriz de adyacencias a una gráfica Kn ? 5.3.12.- En una gráfica no dirigida bastarı́a con registrar la mitad de la matriz de adyacencias, ya que la matriz es simétrica: lo que está bajo la diagonal se repite arriba de la diagonal. Justifica esta aseveración. 5.3.13.- ¿Cómo identificas en una matriz de adyacencias una gráfica que tiene al menos un lazo? 5.3.14.- En las listas de incidencias que corresponde a una gráfica no dirigida, ¿cuántas veces aparece cada arista? 5.3.15.- ¿Qué cambios hay que hacer a una matriz de adyacencias para poder representar a una gráfica dirigida? 5.3.16.- Dada la siguiente matriz de adyacencias que corresponde a una gráfica dirigida, dibuja una gráfica que corresponda a esta matriz. 236 Conceptos de teorı́a de gráficas           0 1 0 1 0 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 0 0 1 0 1 0           5.3.17.- Dadas las siguientes listas de incidencias, dibuja una gráfica dirigida que corresponda a estas listas. arco a b c d e f g h i j vértice origen vértice destino v1 v2 v1 v4 v1 v3 v2 v5 v3 v6 v2 v4 v4 v7 v3 v1 v5 v4 v6 v4 v1 a c v2 b g v3 f i v4 d v5 h v6 j e v7 5.3.18.- Revisa cada una de las representaciones posibles y discute la manera en que se logra invertir la dirección de todos los arcos en la gráfica dirigida del ejercicio 17. 5.4. Isomorfismo entre gráficas Como pudimos observar en los ejercicios de la sección anterior, hay más de una manera de dibujar una misma gráfica – recordemos que el término gráfica corresponde al ente matemático –. ¿Cómo podemos determinar que dos dibujos corresponden a la misma gráfica? ¿Por qué el interés de determinar esto? Muchas veces tenemos dos problemas aparentemente distintos, pero que denotan a gráficas similares (o a la misma gráfica). En estos casos, la solución a uno de los problemas 237 5.4 Isomorfismo entre gráficas de manera automática nos proporciona la solución a todos los problemas que tengan a la misma gráfica, aunque sus gráficas respectivas estén dibujadas o especificadas de manera distinta. Revisemos un caso donde esto sucede. Por ejemplo, supongamos que tenemos cinco materias en la carrera de Ciencias de la Computación; de cada materia se reciben cuatro solicitudes cada semestre y existen colisiones entre los profesores que desean impartir estas materias, como se muestra en la tabla 5.4: Tabla 5.4 Grupos para las materias de CC Materia Profesores: Matemáticas Discretas Macı́as Teorı́a de la Computación Viso Lenguajes de Programación Solsona ICC1 Solsona Bases de datos Garcı́a Hernández Guerrero Reyes Reyes Macı́as Hernández Ramı́rez Viso Oktaba Peláez Hernández López López Ramı́rez Sugawara Podemos pensar en una gráfica donde cada vértice es una de las materias o uno de los profesores; la materia a es adyacente al profesor B si es que el profesor B solicita la materia a. La gráfica queda como se muestra en la figura 5.26. Figura 5.26 G1 para las materias de CC Guerr MD Reyes Macı́a TC Herná Oktab Viso ICC1 Peláe LP Solso Sugaw Ramı́r BD López Garcı́ Es conveniente notar que no hay aristas entre profesores, ya que, como está dibujado, las materias y los profesores corresponden a categorı́as distintas. 238 Conceptos de teorı́a de gráficas También en matemáticas se consideran cinco materias y las solicitudes para ellas. La relación está dada por la tabla 5.5 y la gráfica correspondiente se encuentra en la figura 5.27. La gráfica que corresponde a esta tabla se encuentra en la figura 5.27. Tabla 5.5 Materias en Matemáticas Materia Álgebra Superior I Álgebra Superior II Geometrı́a Analı́tica I Geometrı́a Analı́tica II Cálculo Dif e Int I Profesores: Gómez Lascuráin Guerrero Barrera Abrı́n Magidin Miranda Tomé Sáenz Rosas Tomé Hernández Torres Lascuráin Guerrero Lascuráin Torres Gómez Hernández Rosas Figura 5.27 Gráfica correspondiente a las materias de matemáticas Sáenz Magidin ASI Miranda Tomé Rosas Gómez Hernández CDI-I Abrı́n Torres Barrera AS II Geometrı́a I Guerrero Geometrı́a II Lascuráin Aunque estas dos gráficas, a simple vista, no se parecen, podemos encontrar, por ejemplo, que las podrı́amos dibujar igual. En general, podemos encontrar que el número de vértices y aristas es el mismo, y que por cada vértice con grado k en una de las gráficas existe un vértice con el mismo grado en la otra. Si verificamos otra condición más, que consiste en que las relaciones de adyacencia se mantengan, decimos entonces que podemos definir un isomorfismo entre ambas gráficas. Definición 5.20 Una gráfica G1 = (V1 , E1 ) es isomorfa a una gráfica G2 = (V2 , E2 ) si es que podemos hacer una correspondencia 1 a 1 entre los vértices (una función biyectiva de los vértices de G1 a los vértices de G2 ), f : V1 7→ V2 de tal manera que uv ∈ E1 ⇐⇒ f (u)f (v) ∈ E2 239 5.4 Isomorfismo entre gráficas Es fácil corroborar que existen el mismo número de vértices y de aristas en las dos gráficas de las figuras 5.26 y 5.27; asimismo, también se preserva el número de vértices con grado 1, 2 y ası́ sucesivamente, como se puede ver en la tabla 5.6. Tabla 5.6 Condiciones necesarias para que haya isomorfismo entre gráficas Gráfica G1 G2 Número de vértices: 17 17 Gráfica G1 G2 grado=1 5 5 grado=2 6 6 Número de aristas: 20 20 grado=3 1 1 grado=4 5 5 Total de vértices 17 17 Dado que se cumplen las condiciones básicas, no podemos descartar que haya un isomorfismo entre estas dos gráficas. Deberemos verificar, sin embargo, que las relaciones de adyacencia se mantengan. Para ello definimos un isomorfismo para este caso en la tabla 5.7. Tabla 5.7 Isomorfismo entre las gráficas de las figuras 5.26 y 5.27 f(MD) f(TC) f(ICC1) f(LP) f(BD) f(Sugawara) f(Garcı́a) f(Peláez) f(López) f(Solsona) f(Ramı́rez) f(Viso) f(Oktaba) f(Reyes) f(Guerrero) f(Macı́as) f(Hernández) = = = = = = = = = = = = = = = = = Geometrı́a II Geometrı́a I Álgebra Superior II Cálculo I Álgebra Superior I Magidin Miranda Sáenz Tomé Rosas Gómez Hernández Abrı́n Torres Barrera Guerrero Lascuráin 240 Conceptos de teorı́a de gráficas Podemos verificar que esta función preserva la adyacencia entre vértices en una gráfica y la imagen de esos vértices en la otra. Por ejemplo, en la primera gráfica tenemos las siguientes aristas: (MD,Guerrero), (LP,Ramı́rez), (ICC1,Peláez) que en la segunda gráfica, bajo el isomorfismo, tenemos: (f(MD),f(Guerrero)) (Geometrı́a II, Barrera) (f(LP),f(Ramı́rez)) (Cálculo I, Gómez) (f(ICC1),f(Peláez)) (Álgebra Superior II, Sáenz) que como podemos verificar con la gráfica, están todas presentes en la segunda gráfica. El lector puede verificar que la relación de adyacencia se preserva dada esta asociación. Sin embargo, no es la única asociación posible. Ejercicios 5.4.1.- Determina si las dos gráficas que se encuentran a continuación son isomorfas. Si lo son, da el isomorfismo que mantiene las relaciones de adyacencia. Si no son isomorfas, explica qué es lo que hace que no lo sean. (a) (b) 241 5.4 Isomorfismo entre gráficas 5.4.2.- Determina si las dos gráficas que se encuentran a continuación son isomorfas. Si lo son, da el isomorfismo que mantiene las relaciones de adyacencia. Si no son isomorfas, explica qué es lo que hace que no lo sean. (b) (a) 5.4.3.- Determina si las dos gráficas que se encuentran a continuación son isomorfas. Si lo son, da el isomorfismo que mantiene las relaciones de adyacencia. Si no son isomorfas, explica qué es lo que hace que no lo sean. (b) (a) 6 A 3 B C 5 D 4 E 1 F 2 5.4.4.- Determina si las dos gráficas que se encuentran a continuación son isomorfas. Si lo son, da el isomorfismo que mantiene las relaciones de adyacencia. Si no son isomorfas, explica qué es lo que hace que no lo sean. 242 Conceptos de teorı́a de gráficas (b) (a) 6 G A 3 B C 5 7 D 4 1 E 2 F 5.4.5.- Di si es posible un isomorfismo entre las siguientes dos gráficas. Si es posible, propón uno; si no es posible definir un isomorfismo, explica por qué. (b) (a) A 1 B 2 3 C D 4 E 5 5.4.6.- Di si es posible un isomorfismo entre las siguientes dos gráficas. Si es posible, propón uno; si no, explica por qué. (a) A (b) B 1 2 3 C D E 4 5 Exploración en gráficas 6 6.1. Circuitos eulerianos Una exploración en una gráfica implica recorrerla de alguna manera para descubrir propiedades de la misma. Para explorar una gráfica debemos visitar los vértices de la misma usando las aristas para pasar de un vértice a otro; en otras palabras, definimos caminos en ellas. Visitaremos primero la exploración en gráficas no dirigidas (o simplemente gráficas). Definición 6.1 (camino) Un camino en una gráfica es una sucesión de vértices intercalados con aristas, donde el primero y último elemento de la sucesión son vértices. Si el primer vértice de la sucesión es u y el ultimo vértice es v, decimos que tenemos un camino de u a v. Podemos denotar a ese camino con una letra mayúscula (usualmente P ) y damos los vértices u P y v en sus extremos, u P v (o u v); o si no le ponemos nombre al camino, simplemente lo denotamos con u v. Por ejemplo, observemos la gráfica de la figura 6.1. En esta gráfica tenemos los siguientes caminos entre el vértice v y el vértice t: P1 =v−a−w−b−u−g−t P2 =v−d−s−c−u−b−w−a−v−k−u−g−t−f −x−j −u−g−t P3 =v−a−w−b−u−j −x−f −t−h−y−i−t 244 Exploración en gráficas y muchos más. Noten que los nombres de los vértices corresponden a letras cerca del final del alfabeto mientras que los nombres de las aristas corresponden a letras cerca del principio del alfabeto. En ambos casos usaremos letras minúsculas. Figura 6.1 Gráfica no dirigida con caminos definidos v w a k d b c s h y j u g x f t i Si es que no hay confusión (que la gráfica no tenga más de una arista entre cualesquiera dos vértices) el camino puede representarse únicamente por la sucesión de vértices. En cualquier caso un camino está totalmente representado por la sucesión de aristas. Los primeros dos caminos que dimos pueden ser representados por sus vértices o aristas. El tercero no puede ser representado por la sucesión de vértices, pues no quedarı́a claro cuál arista fue la utilizada entre los vértices y y t. P1 = v, w, u, t = a, b, g P2 = v, s, u, w, v, u, t, u, t = d, c, b, a, k, g, f, j, g P3 = v, w, u, x, t, y, t = a, b, j.f, h, i Podemos observar en estos tres caminos que algunas veces regresamos a un vértice ya visitado o a una arista ya recorrida. Nos interesa el camino más sencillo que podamos encontrar, donde sencillo lo interpretamos como con el menor número de vértices o aristas que llevan del vértice inicial al final. Definición 6.2 Una trayectoria entre u y v (u − v) es aquella en el que no se repiten vértices – y por lo tanto tampoco se repiten aristas –. 245 6.1 Circuitos eulerianos La única trayectoria que dimos en la gráfica de la figura 6.1 es P1 . Otras trayectorias en esa misma gráfica son v, u, t y v, s, u, x, t. Íntimamente relacionado con el concepto de trayectoria es el de una trayectoria cerrada. Definición 6.3 (Trayectoria cerrada) Una trayectoria cerrada es una sucesión de vértices y aristas intercalados, donde el primer y último vértice son el mismo vértice. Definición 6.4 (Ciclo) Un ciclo es una trayectoria cerrada. Al igual que con caminos, podemos tener un ciclo dentro de otro ciclo. Por ejemplo, en la figura 6.2 tenemos los siguientes ciclos, con ciclos dentro de ellos: C1 =a, b, i, k, d, c, a C3 =a, b, d, g, f, d, c, a C2 =d, f, e, h, f, g, d P =g, d, f, g, n, o, q, n, o, p En el caso de C1 tenemos un ciclo que empieza y termina en el vértice a. En C2 podemos identificar el ciclo “externo” que empieza y termina en el vértice d. Dentro de ese ciclo podemos identificar otro ciclo, el que corresponde a f, e, h, f . En C3 también tenemos al ciclo d, g, f, d contenido en el ciclo exterior que empieza y termina en el vértice a. Por último, en P , que no es un ciclo, podemos encontrar el ciclo n, o, q, n contenido en el camino; también podemos encontrar el ciclo o, q, n, o que se intersecta con el ciclo n, o, q, n. Figura 6.2 Ciclos en una gráfica a b i j c d k m e f h g n o p q Regresando a caminos en general, nos interesa, por supuesto, comparar qué tan grande es un camino con respecto a otro: Definición 6.5 La longitud de un camino P , denotada por |P |, es el número de aristas en el camino (uno menos que el número de vértices). 246 Exploración en gráficas En la gráfica de la figura 6.1, el camino P1 tiene longitud 3; el camino P2 tiene longitud 9; y el camino P3 tiene longitud 6: |P1 | = 3; |P2 | = 9; |P3 | = 6. Por definición, todo vértice tiene un camino a sı́ mismo de longitud 0. Teorema 6.1 Todo camino entre u y v (camino u−v) contiene a una trayectoria. Demostración. Si el camino u−v es una trayectoria, se contiene a sı́ misma y queda demostrado el teorema. Supongamos que el camino u−v no es una trayectoria y veamos la sucesión de vértices que lo denotan (anotando la posición que ocupa cada uno de ellos): v 1 , v2 , . . . , v n Como no es trayectoria existe algún vértice en esta sucesión que se repite. Si u = v (se sale y llega al mismo vértice), eliminamos toda la sucesión y dejamos únicamente el primer vértice, que tiene una trayectoria de tamaño cero a sı́ mismo. Supongamos que u 6= v. Entonces tenemos dos vértices en la sucesión, digamos en las posiciones i y j, que son el mismo vértice (vi = x = vj ). Por lo tanto, tenemos un camino de la siguiente forma: u − v2 − . . . − vi (x) − vi+1 − . . . − vj (x) − vj+1 . . . − v u v1 v2 ... x vj−1 vj+1 ... v vi+1 Si procedemos a quitar del camino el subcamino x = vi − vi+1 − . . . − vj−1 − vj = x, nos quedaremos con el camino más corto dado por u − v2 − . . . − vi − vj+1 . . . − v. Si este camino todavı́a no es trayectoria, volvemos a hacer lo mismo hasta que ya no queden vértices repetidos en la sucesión. 247 6.1 Circuitos eulerianos Queremos explorar cuál es la relación entre los vértices de una gráfica, como por ejemplo si hay algún camino entre ellos. Esto nos lleva a la siguiente definición: Definición 6.6 Una gráfica G = (V, E) es conexa si para cualesquiera dos vértices u y v ∈ V existe un camino entre ellos. Definición 6.7 Una gráfica que no es conexa está compuesta por dos o más componentes conexas, donde en cada componente hay un camino entre cualesquiera dos vértices. En la figura 6.3 mostramos una gráfica conexa y una que no lo es. Si bien hasta el momento hemos trabajado casi exclusivamente con gráficas conexas, es importante notar que la gráfica en 6.3(b) cumple perfectamente con la definición que dimos para una gráfica: conjunto de vértices y conjunto de aristas denotadas por la relación entre los vértices. En la figura 6.3(a) tenemos una gráfica donde no importa qué pareja de vértices tomemos, siempre hay una trayectoria entre ellos. En cambio, en la figura 6.3(b) tenemos dos componentes conexas, pero no hay trayectoria entre algún vértice en una de las componentes y un vértice en la otra componente. Figura 6.3 Conexidad en gráficas (a) Gráfica conexa (b) Gráfica no conexa Otro tipo de gráfica que no hemos introducido en este capı́tulo, y que será importante en el futuro, son los árboles . Definición 6.8 (Árbol) Un árbol es una gráfica acı́clica y conexa. Daremos más adelante varias definiciones equivalentes de lo que es un árbol y demostraremos propiedades que nos serán muy útiles. Por lo pronto nos conformamos con esta definición, que se ilustra en las gráficas de la figura 6.4. 248 Exploración en gráficas Figura 6.4 Gráficas que son árboles (b) (a) a b g (c) a b c a f c d c b d e e f e d g f Circuitos eulerianos Los problemas relacionados con caminos en gráficas se aplican a muchas situaciones en la vida real. El primero de ellos (considerado como el problema fundador de la teorı́a de gráficas) fue planteado por Leonhard Euler en 1736 y surge como la solución a un problema sencillo, conocido hoy en dı́a como circuito euleriano . Figura 6.5 Problema de los Puentes de Königsberg c C d B g e A a C c f b d D A e b a g D f B Euler nació el 15 de abril de 1707 en Basilea, Suiza. En la década de 1730 a sus manos llegó un problema relativo a la ciudad de Königsberg en Prusia (actualmente la ciudad se llama Kaliningrado y se encuentra en Rusia); esta ciudad bordeaba al rı́o Pregel e incluı́a dos grandes islas que estaban conectadas entre sı́ y a tierra firme por siete puentes1 . El acertijo consistı́a en definir un paseo por esa parte del rı́o de tal manera de recorrer cada puente exactamente una vez y regresar al punto desde el que se inició el paseo. Euler modeló este problema con lo que conocemos hoy en dı́a como una multigráfica, donde las aristas eran los puentes y habı́a un vértice por cada posición de tierra. No se deberı́a 6.1 Circuitos eulerianos 249 llegar a una isla más que recorriendo alguno de los puentes y todos los puentes deberı́an ser recorridos de extremo a extremo. El problema consistı́a en encontrar si la gráfica tenı́a un paseo de este tipo. La gráfica resultante fue la que se muestra en la figura 6.5. Definición 6.9 (Circuito euleriano) Un circuito euleriano sobre una gráfica (o multigráfica) es aquel ciclo en la gráfica donde cada arista aparece exactamente una vez. Similar a este problema se definió el de encontrar si una gráfica tiene un paseo euleriano, que se define como sigue: Definición 6.10 (Paseo euleriano) Un paseo euleriano en una gráfica (o multigráfica) es una trayectoria que incluye a cada arista de la gráfica exactamente una vez, empezando y terminando en vértices distintos. No sólo pudo Euler dar respuesta a esta pregunta, sino que caracterizó a aquellas gráficas que sı́ tienen un circuito euleriano de la siguiente forma: Teorema 6.2 Una gráfica conexa G = (V, E) tiene un circuito euleriano si y sólo si todos los vértices tienen grado par. G tiene un paseo euleriano si y sólo si todos los vértices de G tienen grado par, excepto exactamente dos vértices que tienen grado impar. Demostración. Supongamos que la gráfica tiene un circuito euleriano y supongamos que iniciamos el circuito en un cierto vértice v0 recorriendo una arista. v0 tiene al menos grado 1 porque la gráfica es conexa. A cada vértice que llegamos por una arista volvemos a salir por otra, por lo que cada vértice tiene un número par de artistas incidentes: aquella por la que se llega y aquella por la que se sale. Cuando ya terminamos de recorrer todas las aristas regresamos a v0 , por lo que le sumamos 1 al grado (impar hasta ahora) de v0 . De donde todos los vértices tienen grado par. Supongamos ahora que en G = (V, E) todos los vértices tienen grado par. Elegimos a un vértice v como origen del circuito y vamos recorriendo aristas. A cada vértice que llegamos podemos salir, pues el grado es par. Como únicamente hemos utilizado un número impar de aristas incidentes en v (por la que salimos más dos por cada vez que pasemos por v), tenemos que usar una última arista que regrese a v y ya no podremos salir de él. Tomamos entonces cualquier arista que no ha sido recorrida y cualquiera de los vértices en uno de sus extremos, digamos u. Volvemos a repetir el ejercicio hasta que tengamos un circuito que empiece y termine en u. Como la gráfica es conexa, existe un camino entre cualquier arista no usada todavı́a y algún vértice en el circuito construido hasta el momento, por lo que el último circuito se conecta al anterior en un vértice. Esto es, toda arista es finalmente incluida en el circuito. Para el caso de paseos eulerianos, se sigue el mismo razonamiento, excepto que el vértice del que se sale y al que se llega finalmente no son el mismo. 1 Desgraciadamente los puentes fueron destruidos durante la Segunda Guerra Mundial. 250 Exploración en gráficas En el algoritmo 6.1 se formalizan las ideas dadas en la demostración, en cuanto a que si el grado de cada vértice es par, tenemos un circuito euleriano. Este algoritmo construye el circuito euleriano correctamente, si es que la gráfica cumple con las condiciones necesarias para ello (grado par en todos sus vértices). Veamos un ejemplo: Listado 6.1 Algoritmo para obtener un circuito euleriano 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Sea C = [ x ] , x ∈ V ; Sea E = E ; M i e n t r a s ( haya a r i s t a s s i n usar en E ) Sea v un v é r t i c e a r b i t r a r i o en C que t i e n e alguna arista disponible . Sea P = [ v ] Sea u = v ; M i e n t r a s ( ∃ e = ux d i s p o n i b l e ) E = E − e; P = P + e + x; u = x; / * C i c l o : M i e n t r a s ( ∃ e = ux d i s p o n i b l e ) * / S u s t i t u i r a v por P en C ; / * C i c l o : M i e n t r a s ( haya a r i s t a s s i n u s a r en E ) * / C es e l c i r c u i t o e u l e r i a n o ; Ejemplo 6.1. Tenemos la siguiente gráfica que cumple con las condiciones necesarias y suficientes para tener un circuito euleriano. Representamos a la gráfica con listas de adyacencia. A la derecha de la lista de adyacencias se encuentra la lista de aristas, identificadas en orden alfabético, esto es, el primer vértice es el nombre menor. Cada arista aparece en esta lista únicamente una vez. b a g f c e d Listas de adyacencias g a ∅ f g c ∅ b g c ∅ b e f ∅ d g e ∅ d a f ∅ d g a c b e ∅ Aristas a f g a c b g b g c e d f d g e Procedemos a construir un circuito euleriano siguiendo el algoritmo dado. Elegimos al 251 6.1 Circuitos eulerianos azar cualquiera de los vértices. El vértice natural a elegir es el primero, a. Inicialización 1 C = [a]; 2 E = {a−f , a−g, b−c, b−g, c−g, d−e, d−f , e−g}; Entramos al ciclo de la lı́nea 3 porque E tiene todavı́a aristas sin usar. Tomamos al vértice a en las lı́neas 4 y 5. 4 v = a; 6 P = [a]; 7 u = a; Entramos al ciclo de la lı́nea 8, ya que la lista de adyacencias del vértice a no está vacı́a, y elegimos al primer vértice adyacente al que se alcanza con la arista e = a−f , por lo que eliminamos a esta arista de E y agregamos a la arista y al vértice en el otro extremo al camino que estamos construyendo. 9 E = {a−g, b−c, b−g, c−g, d−e, d−f , e−g}; 10 P = [ a, a−f , f ]; 11 u = f ; Como usamos la arista e = a−f = f −a, eliminamos a f de la lista de adyacencias de a y a a de la lista de adyacencias de f : Listas de adyacencias a g a ∅ g c ∅ b g c ∅ b f e f ∅ d g e ∅ d f ∅ d g a c e ∅ b Seguimos en el ciclo de la lı́nea 8 tomando a la siguiente arista disponible desde f que es f −d = d−f , ya que d es el primer vértice en la lista de adyacencias de f . 8 9 10 11 e = f −d; E = {a−g, b−c, b−g, c−g, d−e, e−g}; P = [ a, a−f , f, f −d, d ]; u = d; Como usamos la arista e = f −d = d−f , eliminamos a d de la lista de adyacencias de f y a f de la lista de adyacencias de d: 252 Exploración en gráficas a f d Listas de adyacencias g a ∅ g c ∅ b g c ∅ b e ∅ d g e ∅ d f ∅ g c a b e ∅ Seguimos en el ciclo de la lı́nea 8 pues d tiene todavı́a vértices en su lista de adyacencias, el primero de los cuales es e; ası́ que tomamos la arista d−e = e−d. 8 9 10 11 e = d−e; E = {a−g, b−c, b−g, c−g, e−g}; P = [ a, a−f , f, f −d, d, d−e, e ]; u = e; Como usamos la arista e = d−e = e−d, eliminamos a d de la lista de adyacencias de e y a e de la lista de adyacencias de d: a f e d Listas de adyacencias g a ∅ g c ∅ b g c ∅ b ∅ d g e ∅ f ∅ g c a b e ∅ Seguimos en el ciclo de la lı́nea 8 pues e tiene todavı́a vértices en su lista de adyacencias, el primero de los cuales es g, ası́ que tomamos la arista e−g = g−e. 8 9 10 11 e = e−g; E = {a−g, b−c, b−g, c−g}; P = [ a, a−f , f, f −d, d, d−e, e, e−g, g ]; u = g; Eliminamos a e de la lista de adyacencias de g y a g de la lista de e: 253 6.1 Circuitos eulerianos a g f e d Listas de adyacencias g a ∅ g c ∅ b g c ∅ b ∅ d e ∅ f ∅ g c a b ∅ Seguimos en el ciclo de la lı́nea 8 pues g tiene todavı́a vértices en su lista de adyacencias, el primero de los cuales es a, por lo que tomamos la arista g−a = a−g. 8 9 10 11 e = g−a; E = {b−c, b−g, c−g}; P = [ a, a−f , f, f −d, d, d−e, e, e−g, g.g−a, a ]; u = a; Eliminamos a a de la lista de adyacencias de g y a g de la lista de a: a g f e d Listas de adyacencias a ∅ g c ∅ b g c ∅ b ∅ d e ∅ f ∅ g c ∅ b Como el vértice a ya no tiene a ningún vértice en su lista de adyacencias, no volvemos a entrar en el ciclo de la lı́nea 8 y pasamos a ejecutar la lı́nea 13. En esa lı́nea tenemos que v es a, por lo que sustituimos a a en C por todo el camino P que se construyó: C = [a] C = [ a, a−f , f, f −d, d, d−e, e, e−g, g, g−a, a ] antes después y regresamos a la iteración de la lı́nea 3. Como E todavı́a tiene aristas, elegimos un vértice en C que tenga aristas disponibles; este es el caso del vértice g, por lo que la ejecución se da como sigue: 4 v = g; 6 P = [g]; 7 u = g; 254 Exploración en gráficas Llegamos nuevamente a la lı́nea 8 del algoritmo, donde el primer vértice en la lista de adyacencias de g es b, por lo que elegimos a la arista e = g−b = b−g y procedemos a ejecutar la iteración: 8 9 10 11 e = g−b; E = {b−c, c−g}; P = [ g, g−b, b ]; u = b; Eliminamos a g de la lista de adyacencias de b y a b de la de g: Listas de adyacencias a ∅ c ∅ b g c ∅ b ∅ d e ∅ f ∅ g c ∅ b a g f e d Regresamos a la lı́nea 8 y como tenemos a c en la lista de adyacencias de b, entramos nuevamente a la iteración: 8 9 10 11 e = b−c; E = {c−g}; P = [ g, g−b, b, b−c, c ]; u = c; Eliminamos a b de la lista de adyacencias de c y a c de la de b: b a g f c e d Listas de adyacencias a ∅ ∅ b g c ∅ ∅ d e ∅ f ∅ g c ∅ 255 6.1 Circuitos eulerianos Regresamos a verificar la condición en la lı́nea 8 y vemos que en la lista de adyacencias de c está el vértice g, por lo que tomamos la arista e = c−g = g−e y entramos al ciclo nuevamente. 8 e = c−g; 9 E = { }; 10 P = [ g, g−b, b, b−c, c, c−g, g ]; 11 u = g; Eliminamos a g de la lista de adyacencias de c y a c de la de g: b a g f c e Listas de adyacencias a ∅ ∅ b c ∅ ∅ d e ∅ f ∅ g ∅ d Al regresar a la lı́nea 8 vemos que ya no hay ningún vértice en la lista de adyacencias de g, por lo que pasamos a ejecutar la lı́nea 13 del algoritmo. En esa lı́nea tenemos que v es g, por lo que sustituimos a g en C por todo el camino P que se construyó: antes C = [ a, a−f , f, f −d, d, d−e, e, e−g, g , g−a, a ] C = [ a, a−f , f, f −d, d, d−e, e, e−g, g, g−b, b, b−c, c, c−g, g , g−a, a ] después y regresamos a la iteración de la lı́nea 3. Como E ya está vacı́a, salimos de la iteración en la lı́nea 15 y damos el circuito euleriano. b a g f c e d Listas de adyacencias a ∅ ∅ b c ∅ ∅ d e ∅ f ∅ g ∅ 256 Exploración en gráficas Si deseamos que el algoritmo construya un paseo euleriano, suponiendo que la gráfica tiene grado par en todos sus vértices excepto en exactamente dos, tenemos que modificar ligeramente el algoritmo para que el primer vértice seleccionado en las lı́neas 4 y 5 sea uno de los de grado impar. De otra manera va a tratar de construir un circuito que no existe. Veamos un ejemplo. Ejemplo 6.2. Obtener el paseo euleriano de la siguiente gráfica. a b d e c Verificamos primero que la gráfica cumpla con la condición necesaria y suficiente para que tenga un paseo euleriano y ası́ es. En esta ocasión únicamente iremos dibujando el paseo que se va formando. Lo mostraremos en la figura 6.6. Tenemos que empezar con el vértice b o con el e porque son los que tienen grado impar. Empezaremos en el vértice b. Suponemos que las listas de adyacencias están ordenadas lexicográficamente, por lo que la primera arista que vamos a agregar al paseo es b−c. Figura 6.6 Construcción de un paseo euleriano (b) (a) b c b (d) a b d e c (c) c a b e e (e) (f) a b d e c a b d e c c Exactamente hay dos vértices, b y e que tienen grado impar; el resto de los vértices tiene grado par. El camino empieza en el vértice b, que es uno de los que tiene grado impar; 257 6.1 Circuitos eulerianos recorre todas las aristas exactamente una vez; termina en el vértice e, que es el otro vértice con grado impar. Podemos notar que el algoritmo que construye el circuito euleriano (paseo euleriano) le asigna una orientación a las aristas por el orden en que las va usando. La eficiencia del algoritmo va a depender de la representación interna de la gráfica y de cómo determinemos que una arista ya fue usada: quitarla de ambas listas de adyacencias no es muy eficiente y tal vez convendrı́a más tener una lista de aristas en la que marcáramos aquellas que ya fueron usadas y no se pueden volver a usar. El algoritmo del listado 6.1 obtiene un circuito euleriano. Si se le da una gráfica que no cumpla con los requisitos de tener grado par en todos sus vértices el algoritmo de todos modos va a trabajar, pero no va a encontrar un circuito euleriano. Veamos el siguiente ejemplo para ilustrar este aspecto. Ejemplo 6.3. Tomemos la siguiente gráfica, que no cumple con tener grado par en todos sus vértices, por lo que no tiene un circuito euleriano; tampoco tiene exactamente dos vértices con grado impar, por lo que tampoco tiene un paseo euleriano. a d f g b c e h Veremos el progreso del paseo en la figura 6.7. Tomamos como primer vértice a uno de los que tienen grado impar, por ejemplo a, y de ahı́ continuamos eligiendo aristas disponibles. Figura 6.7 Construcción incorrecta de un paseo euleriano (b) (a) a a b b 1/2 (c) c (d) a d a d b c b c 258 Exploración en gráficas Figura 6.7 Construcción incorrecta de un paseo euleriano 2/2 En este momento ya no podemos seguir con el mismo paseo, ası́ que la “guardamos” y tomamos al vértice c que es el único en el camino actual que tiene aristas disponibles. (e) a d b c (f) e a d f b c e (g) (h) a d f b c e g a d f g b c e h (i) (j) a d f g a d f g b c e h b c e h En este punto ya no tenemos aristas disponibles en g por lo que debemos intentar juntar esta trayectoria a la primera; tenemos lo siguiente: C = {a, a−b, b, b−c, c , c−d, d, d−b} P = {c, c−e, e, e−f , f, f −g, g, g−h, h, h−e, e, e−g, g} Sin embargo, si tratamos de sustituir al vértice c en C por la trayectoria P, nos vamos a 259 6.1 Circuitos eulerianos encontrar que lo que resulta no es un camino: . . . b−c, c, c−e, . . . , e, e−g, g, c−d . . . ; esto se debe a que el primer paseo euleriano que construimos termina en un vértice de grado impar (b), pero entonces requerimos que lo que se construya para ocupar el lugar de c sea un circuito euleriano que empiece y termine en c, lo que no sucede, pues en esa subgráfica tenemos tres vértices de grado impar. Si bien se recorrieron todas las aristas exactamente una vez, lo que construimos fueron dos caminos ajenos, no un paseo euleriano. Ejercicios 6.1.1.- En las gráficas que siguen, di cuántas trayectorias distintas hay entre los vértices a y d. (a) a (b) c b b a e d d c f e g f 6.1.2.- Para las siguientes gráficas, determina si son gráficas conexas. (b) (a) (c) c b a c e b g e d a f e a d b d f h c 260 Exploración en gráficas 6.1.3.- ¿Cuáles de las siguientes gráficas tienen circuito/paseo euleriano? Si es que tienen alguno de los dos, aplicar el algoritmo 6.1 para encontrarlo, dando cómo se va armando el circuito/paseo durante la aplicación del algoritmo. (b) (a) c (c) e a a c b e b g a h f d c e d f d (d) b (e) (f) a a c b d e c e b d d c e f a f b 6.1.4.- Para cada una de las siguientes gráficas, que no tienen circuito euleriano ni paseo euleriano, di cuántas aristas tendrı́as que agregar y dónde para que la gráfica tuviera un circuito euleriano, si es que esto es posible. Di cuántas aristas tendrı́as que agregar y dónde para que la gráfica tuviera un paseo euleriano, si es que esto es posible. (a) b (b) a g a d c e d f f c e b h 261 6.2 Trayectorias hamiltonianas (d) (c) g a c b d e a f f d b c h e (e) (f) d e b g b a g d a e c c f i h f 6.2. Trayectorias hamiltonianas Veamos ahora un problema muy parecido, el de explorar una gráfica con la restricción de que cada vértice sea visitado exactamente una vez. Bajo visitado queremos decir llegar y salir de él. Tenemos la restricción adicional de empezar y terminar el ciclo en el mismo vértice en el que empezamos. A este tipo de recorrido es a lo que se conoce como ciclo hamiltoniano. El problema es, entonces, dada una gráfica conexa determinar si existe o no un ciclo hamiltoniano en la gráfica. A pesar del gran parecido entre éste y el problema de los ciclos (o paseos) eulerianos, mientras que las condiciones necesarias y suficientes para que exista un ciclo euleriano están perfectamente definidas, éste no es el caso de los ciclos hamiltonianos. Inclusive, mientras que para construir el ciclo euleriano existe un algoritmo muy eficiente, para el ciclo hamiltoniano la única manera conocida de obtenerlo es calculando todos los posibles ciclos y ver cuál de ellos es hamiltoniano. Sin embargo sı́ existen algunos resultados que nos pueden ayudar a determinar si una gráfica pudiese tener un ciclo o trayectoria hamiltoniana. Una condición suficiente para ello 262 Exploración en gráficas se enuncia en el teorema 6.3, que se debe a Dirac. Teorema 6.3 (Teorema de Dirac) Sea G = (V, E) una gráfica conexa tal que |V | = n, n > 2. Si grado(v) ≥ n2 , ∀v ∈ V , entonces G tiene un ciclo hamiltoniano. Demostración. Si n = 3, como estamos pidiendo grado(v) ≥ n2 = 2, G tiene que ser K3 y tiene un ciclo hamiltoniano que empieza en cualquiera de los vértices y prosigue al siguiente. Veamos que pasa con n ≥ 4. Construyamos una trayectoria P tan larga como sea posible. vk+1 v1 v2 vk Observemos lo siguiente: • • Tenemos como hipótesis que grado(v1 ) ≥ n2 . No puede haber otro vértice fuera de P adyacente a v1 , porque harı́a una trayectoria P ′ mayor que P , y lo mismo sucede con vk+1 , y supusimos que P era la más larga (o que no hay en G una trayectoria más larga). vk+1 v1 w v2 vk w′ Quiere decir que todos los vértices a los que es adyacente v1 están en P (lo mismo para vk+1 ). • Por lo que en P debe haber al menos n2 + 1 vértices, donde al menos n2 son los vértices adyacentes a v1 distintos de v1 . • 263 6.2 Trayectorias hamiltonianas Si todos los vértices de V están en P , ya terminamos, pues P los toca a todos exactamente una vez. Si no es ası́, procedemos de la siguiente manera. Supongamos ahora que en P existe un vértice vi , 2 ≤ i ≤ k + 1, tal que vi es adyacente a v1 y vi−1 es adyacente a vk+1 . Si esto es ası́, tenemos el siguiente ciclo: vk+1 v1 vi−1 v2 vi vk Demostraremos por contradicción que vi y vi−1 deben existir con estas caracterı́sticas. • Supongamos que para toda i ≥ 2 tal que vi es adyacente a v1 , tenemos que vi−1 no es adyacente a vk+1 . • Como grado(v1 ) ≥ n2 y ya demostramos que no puede haber ningún vértice adyacente a v1 que no esté en P , hay al menos n2 vértices adyacentes a v1 en P ; para cada uno de estos vértice adyacentes a v1 hay un vértice que lo precede; como estamos demostrando por contradicción, estamos suponiendo que ninguno de estos vértices vi−1 es adyacente a vk+1 . Por lo tanto en P hay n2 + 1 vértices no adyacentes a vk+1 (los inmediatos anteriores a vi junto con vk+1 ). • También demostramos que todos los vértices adyacentes a vk+1 tienen que estar en P . • Como la gráfica tiene n vértices, de los cuales n − 1 no son vk+1 , si contamos los vértices que quedan en P y que pueden ser adyacentes a vk+1 nos vamos a encontrar con que son n − ( n2 + 1) = n2 − 1 < n2 . Por lo que tenemos: grado(vk+1 ) ≤ n − 1. 2 Pero esto es una contradicción respecto a que grado(v) ≥ n2 . Por lo que sı́ existen vi y vi−1 . Dada esta situación, podemos construir un ciclo C = v1 , v2 , . . . , vi−1 , vk+1 , vk , . . . , vi , v1 , que contiene a todos los vértices de P . Si P contiene a todos los vértices de V , este ciclo nos da el ciclo hamiltoniano. Y debe ser ası́. 264 Exploración en gráficas Supongamos que no y que existe un vértice w ∈ / P . A lo más hay n2 − 1 vértices de G n fuera de P . Como grado(w) ≥ 2 , w tiene que ser adyacente a algún vértice de P . Sea ese vértice vj . vk+1 v1 vi−1 v2 vi vj−1 vj vk w Pero entonces, la trayectoria P ′ = w, vj , vj+1 , . . . , vk , vk+1 , vi−1 , . . . , v2 , v1 , vi , . . . , vj−1 es una trayectoria de longitud mayor que P (tiene una arista más, ya que sustituimos la arista vi−1 vi por las dos aristas vi−1 vk+1 y v1 vi ; también sustituimos a la arista vj−1 vj por la arista wvj ), a quien supusimos de longitud máxima. Por lo que no puede haber vértices de V fuera de P . Veamos un ejemplo sencillo de gráficas que cumplen con la condición del teorema 6.3 y que, por lo tanto, tiene un ciclo hamiltoniano, en la figura 6.8. Figura 6.8 Algunas gráficas con ciclos hamiltonianos que cumplen la condición de Dirac (b) (a) a (c) a d a b c e c d b b e f e f d c Si bien el teorema 6.3 garantiza la existencia de un ciclo hamiltoniano si el grado de cada vértice es mayor o igual a la mitad del número de vértices, el teorema no nos dice cómo encontrar ese camino. Esto fue evidente al construir los ciclos hamiltonianos de las primeras dos gráficas de la figura 6.8. En cambio, en el caso de los ciclos eulerianos, al demostrar el teorema dimos un método de construcción del ciclo. Es claro que todas las 265 6.2 Trayectorias hamiltonianas gráficas completas tienen un ciclo hamiltoniano pues cumplen con la condición dada por el teorema. Esta es una condición suficiente; esto es, podemos tener gráficas que no cumplan esta condición y que sin embargo sı́ tengan ciclos hamiltonianos, como las que se muestran en la figura 6.9. Figura 6.9 Gráficas con ciclo hamiltoniano que no cumplen con la condición de Dirac (b) (a) a (c) e a a b c e b c d b f g d e f d c En estas tres gráficas hay vértices con grado menor a n2 y sin embargo sı́ tienen un ciclo hamiltoniano. Las dos primeras, de hecho, tienen más de uno. Otro teorema que da condiciones suficientes para que una gráfica tenga un ciclo hamiltoniano, pero que no demostraremos acá, es el Teorema de Ore: Teorema 6.4 (Teorema de Ore) Si G es una gráfica con n vértices, n ≥ 3, tal que para todo par de vértices no adyacentes u y v en G, grado(u) + grado(v) ≥ n, entonces G tiene un ciclo hamiltoniano. Nuevamente este teorema nos da una condición suficiente. Ninguna de las gráficas de la figura 6.9 cumple con la condición de Ore y sin embargo todas tienen un ciclo hamiltoniano. De manera similar a como definimos un paseo euleriano podemos definir una trayectoria hamiltoniana como aquella que recorre a cada vértice exactamente una vez, pero a diferencia de un ciclo hamiltoniano, empieza y termina en distintos vértices. Es claro que toda gráfica que tiene un ciclo hamiltoniano tiene, asimismo, una trayectoria hamiltoniana: simplemente no usamos la última arista recorrida para el ciclo hamiltoniano. Pero podrı́amos tener una trayectoria hamiltoniana y que no hubiera arista entre el primer vértice de la trayectoria y el último. En la figura 6.10 tenemos varias gráficas que tienen una trayectoria hamiltoniana. 266 Exploración en gráficas Figura 6.10 Gráficas con trayectorias hamiltonianas (b) (a) a e c a (c) a b b c d f b c e d f e d Ejercicios 6.2.1.- El matemático irlandés, Sir William R. Hamilton, a quien se debe la introducción del concepto de ciclo hamiltoniano, trató de comercializar un juego que consistı́a de un dodecaedro hecho de madera, donde cada esquina representaba a una ciudad famosa. El juego consistı́a en encontrar una ruta que visitara todas las ciudades exactamente una vez y regresara a la ciudad de origen o, lo que es lo mismo, encontrar un ciclo hamiltoniano en el dodecaedro. En el plano, el juego se pinta como sigue: 2 7 6 1 8 16 15 17 20 9 3 18 14 10 19 13 5 12 11 4 Encontrar un ciclo hamiltoniano (o todos) en el dodecaedro. 6.2.2.- De las siguientes gráficas di cuáles tienen un ciclo hamiltoniano o una trayectoria hamiltoniana. Si tiene alguno de estos dos, dibújalo. 267 6.2 Trayectorias hamiltonianas (b) (a) c b (c) a f a a b c d e f g h i b d d e e c (d) (e) g e h a c b a b c f e d c a (f) f d d g b i h e f 6.2.3.- La siguiente gráfica, conocida como la gráfica de Petersen, no tiene un ciclo hamiltoniano, pero si se le quita cualquiera de sus vértices y las aristas incidentes en él, la subgráfica ası́ obtenida sı́ tiene un ciclo hamiltoniano. Muestra que estas dos aseveraciones son verdaderas. a f e i d b g j h c 6.2.4.- Un caballo es una pieza de ajedrez que se puede mover dos cuadros horizontales y uno vertical, o un cuadro horizontal y dos verticales. Esto es, un caballo en el 268 Exploración en gráficas cuadro (x, y) puede moverse a cualquiera de las siguientes posiciones (x ± 2, y ± 1), (x ± 1, y ± 2), si estos cuadrados se encuentran en el tablero. Veamos un ejemplo en un tablero de 6 × 6. La posición del caballo la mostraremos con ⊠ y las posibles posiciones a las que se puede mover con •. • • • • ⊠ • • • • Un paseo equino es una secuencia de movimientos legales de un caballo que empieza en alguna posición y visita cada cuadro del tablero exactamente una vez. Un paseo equino es reentrante si hay un movimiento legal que lleva al caballo desde el último cuadro del paseo a donde inició el mismo. Podemos modelar paseos equinos usando una gráfica que tiene un vértice para cada cuadro en el tablero, con una arista entre dos vértices si el caballo se puede mover legalmente entre los cuadrados representados por estos vértices. (a) Dibuja la gráfica que representa los movimientos válidos de un caballo en un tablero de 3 × 3. (b) Dibuja la gráfica que representa los movimientos válidos de un caballo en un tablero de 3 × 4. (c) Muestra que encontrar un paseo equino en un tablero de m × n es equivalente a encontrar una trayectoria hamiltoniana en la gráfica que representa los movimientos legales del caballo en el tablero. (d) Muestra que encontrar un paseo equino reentrante en un tablero de m × n es equivalente a encontrar un ciclo hamiltoniano en la gráfica que representa los movimientos legales del caballo en el tablero. 6.2.5.- Se dice que una gráfica es euleriana (hamiltoniana) si tiene un ciclo euleriano (hamiltoniano, respectivamente). Da un ejemplo de gráfica que exactamente sea (a) euleriana y hamiltoniana, (b) euleriana y no hamiltoniana, 6.3 Distancias en una gráfica 269 (c) no euleriana y hamiltoniana, (d) no euleriana y no hamiltoniana. 6.3. Distancias en una gráfica En esta sección exploraremos una gráfica para obtener caminos entre vértices y ver cuál es su longitud. Primero veremos gráficas no dirigidas sencillas, donde suponemos que todas las aristas tienen un costo (o peso) uniforme de una unidad. En la siguiente sección exploraremos el concepto de una gráfica con pesos, que es aquella donde cada arista tiene un costo asociado. A continuación definimos el concepto de distancia, que es el que nos ocupará por lo pronto. Definición 6.11 (distancia) Sea G = (V, E) una gráfica no dirigida. La distancia entre dos vértices u y v en V , denotada por δ(u, v), es la longitud de la trayectoria más corta entre u y v. Definimos δ(u, v) = ∞ si no existe trayectoria entre u y v. Hay tres modalidades bajo las cuáles podemos querer obtener distancias en una gráfica: i. Trayectoria más corta entre dos vértices s y t. ii. Trayectoria más corta desde un vértice origen a todos y cada uno de los vértices en la gráfica. iii. Trayectorias más cortas entre todas las posibles parejas de vértices u y v en una gráfica. El algoritmo que presentaremos a continuación ejecuta una exploración en amplitud (Breadth First Search) y por esta caracterı́stica se le conoce como BF S. El algoritmo elige a un vértice como origen de la exploración, y “cuelga” la gráfica de ese vértice, obteniendo la distancia desde él a todos y cada uno de los vértices a los que se puede llegar desde s. Una vez elegido (o determinado) el vértice origen s, procede a avanzar de un vértice a otro por capas de adyacencia: primero a los vértices adyacentes a s – que están a una arista de s – definiendo una primera capa de vértices a distancia 1; después a los que están adyacentes a los vértices de la primera capa y que no se encuentran ya en ella y que están a distancia 2; y ası́ sucesivamente. Al ir calculando las distancias registra también la trayectoria más corta que lleva a ese vértice mediante un atributo π que se refiere al vértice desde el cual se le visitó por primera vez. Al construir estas capas de adyacencia, la distancia desde s a un vértice está dada por la capa que le corresponde la primera vez que se le alcanza (cuando se le descubre). 270 Exploración en gráficas Esta exploración calcula naturalmente la distancia del vértice seleccionado como origen a cada uno de los vértices de la gráfica, por lo que resuelve la primera y segunda modalidad. Para resolver la tercera modalidad deberı́amos ejecutar BF S desde cada uno de los vértices de la gráfica. En los algoritmos que siguen usaremos notación orientada a objetos para referirnos a los distintos atributos (campos) que queremos tenga cada arista o vértice de la gráfica. Ası́, para referirnos a la distancia δ del vértice v al origen, lo denotaremos con v.δ. Definición 6.12 (Vértice alcanzable) Un vértice v ∈ V es alcanzable desde u si es que existe alguna trayectoria entre u y v. En una componente conexa todos los vértices son alcanzables desde cualquier otro vértice, mientras que si tenemos más de una componente conexa en una gráfica, ningún vértice de una de las componentes es alcanzable desde cualquier vértice en una componente conexa distinta. Algoritmo BFS Objetivo: Dada una gráfica G = (V, E) y un vértice s ∈ V , encontrar v.δ, que corresponde a la distancia del vértice s a v. Dejar marcada en la gráfica la trayectoria que corresponde a cómo se obtuvo esa distancia. Datos: La gráfica G = (V, E) y s ∈ V . Salida: ∀v ∈ V , tal que haya una trayectoria s v, reportar v.δ y s v. Estructuras de datos: i. La gráfica estará representada por listas de adyacencias. ii. Cada vértice tendrá un atributo v.π que indica cuál es el vértice predecesor y un atributo v.δ que indica cuál es la distancia a s. Método: Se encuentra en el listado 6.2. Listado 6.2 Algoritmo BFS (δ(s, v), ∀v ∈ V alcanzable desde s) firstnumber 1 / * ( I n i c i a l i z a c i ón : ) * / 2 ∀v ∈ V : {v.π ← nulo ; v.δ ← ∞ } 3 s.δ ← 0; s.π ← nulo 4 C ← hsi (1/2) 6.3 Distancias en una gráfica Listado 6.2 Algoritmo BFS (δ(s, v), ∀v ∈ V alcanzable desde s) 271 (2/2) 5 / * ( P r o c e s a r a l que e s t é a l f r e n t e de l a c o l a . ) * / 6 M i e n t r a s C 6= ∅ , 7 u = frente(C) 8 ∀v ∈ u.adyacencias : 9 v ← s i g u i e n t e v é r t i c e en l a l i s t a de adyacencias de u 10 S i v.δ == ∞ / * P r i m e r a v e z que s e l l e g a a é l * / 11 v.δ ← u.δ + 1 12 v.π ← u 13 C←C+v 14 / * F i n : v.δ == ∞ * / 15 / * C i c l o : ∀v ∈ u.adyacencias * / 16 C←C−u / * Se s a c a a u de l a c o l a * / 17 / * C i c l o : M i e n t r a s C 6= ∅ * / 18 / * Se r e p o r t a n l o s r e s u l t a d o s * / 19 ∀v ∈ V 20 /* ( Reporta d i s t a n c i a : ) */ 21 E s c r i b e : "La distancia a v es " + v.δ 22 / * ( R e p o r t a camino ) * / 23 Repite : 24 Reporta v 25 v ← v.π 26 hasta que v == nulo 27 / * C i c l o : ∀v ∈ V * / Ejemplo 6.4. Si seguimos el algoritmo BFS en la gráfica de la figura 6.11, veremos que los vértices de la gráfica van llegando a la cola C en el orden en que se muestra en esa misma figura. Este orden es el que define la exploración. Podemos observar en esta figura cómo se van definiendo las distancias de los vértices. – En la subfigura 6.11(a) se calculan las distancias de p, el origen de la exploración, a r y w y se determina que su distancia es 1. – En ese momento al frente de la cola se encuentra r, que es adyacente a u y v. Se calcula la distancia para estos dos vértices (2) y se quita de la cola a r. – En ese momento se encuentra w al frente de la cola, con sus dos aristas sin usar que van a u y v; pero como estos dos vértices ya fueron alcanzados antes (su atributo δ es distinto de ∞), estas aristas no se incluyen en la subgráfica que estamos armando. – Quitamos a w del frente de la cola y surge u al frente de la misma. Las aristas de u que no han sido usadas son las que van a t y a q. A ambos vértices se les anota la distancia, se meten a la cola y se saca a u. – Queda v al frente de la cola, pero como ya fueron exploradas sus aristas a u y a w, simplemente se saca de la cola a v. 272 Exploración en gráficas – A continuación queda t al frente de la cola y tiene dos aristas sin usar, la que va a s y la que va a q. La que va a q se desecha porque a q se le asignó ya su distancia; se registra la distancia a s, que es 4, y se mete a s a la cola. – Se saca a t de la cola, quedando q al frente de la cola. La única arista que tiene q sin usar es la que va a s, que ya fue procesado, por lo que simplemente se quita a q de la cola. Llega s al frente de la cola y como ya no tiene aristas incidentes sin usar, se le saca de la cola y la cola queda vacı́a. Figura 6.11 Exploración BFS de una gráfica conexa desde el vértice p (a) C = hp, r, wi en lı́neas 6, 15(2) (b) C = hr, w, u, vi en lı́nea 25, 15 (2) 1 r u s t 1 2 r u t w 1 q s 2 v v 0 p q w 1 0 p (c) C = hu, v, t, qi en lı́nea 25 (2),15 (2) 1 2 3 r u t 0 p s (d) C = ht, q, si en lı́nea 25 (2),15, 25(3) 1 2 3 4 r u t s w 1 q 3 2 2 v v w 1 q 3 0 p Una caracterı́stica de la exploración BFS en gráficas no dirigidas es que determina si la gráfica tiene o no ciclos. Si durante el recorrido alguna arista que se está explorando termina en un vértice que ya fue visitado, quiere decir que la gráfica contiene un ciclo. Esto se puede ver claramente porque hay dos trayectorias distintas que llevan desde el vértice origen hasta el vértice de que se trata. Por ejemplo, en la gráfica de la figura 6.11, cuando 273 6.3 Distancias en una gráfica se tiene en la cabeza de la cola al vértice w, al tratar de explorar la arista hacia u, encuentra este vértice ya marcado – se descubrió desde el vértice r –. Podemos ver que la trayectoria u–r–p–w formarı́a una trayectoria que se cerrarı́a formando un ciclo si se agregara la arista wu. Podemos observar que la subgráfica generadora de la gráfica (incluye a todos los vértices) que se construye durante la ejecución de BFS es un árbol, pues es una subgráfica conexa y no tiene ciclos. Cada recorrido BFS genera una subgráfica generadora G′ = (V ′ , E ′ ), que contiene a todos los vértices de la gráfica original, si es que ésta es conexa (V ′ corresponde a todos los vértices alcanzables desde el vértice origen). En el caso del recorrido BFS nunca se tiene que deshacer una trayectoria encontrada, pues éste queda determinado por la primera arista que descubra a un vértice. Veamos algunos ejemplos más en la figura 6.12. En las gráficas de esta figura damos dirección a las aristas para mostrar el sentido de la exploración. Figura 6.12 Ejemplos de recorridos BFS (a) Orden: u, v, y, z, w, x, t (b) Orden: a, b, c, d, e (c) Orden: a, b, e, c, d 0 1 2 0 0 u v w a a 2 x y 1 z 1 t 2 1 1 1 1 e b e b d c d c 1 1 2 2 Ejercicios 6.3.1.- Demostrar que la distancia definida para gráficas cumple con las tres propiedades que debe cumplir una medida de distancia y que son, a saber: No negatividad: δ(x, y) ≥ 0; δ(x, y) = 0 si y sólo si x = y. simetrı́a: δ(x, y) = δ(y, x) Desigualdad del triángulo: δ(x, z) ≤ δ(x, y) + δ(y, z). 274 Exploración en gráficas 6.3.2.- Tenemos la siguiente gráfica, con su codificación en listas de adyacencias a su derecha. Da el recorrido BFS de la gráfica que se produce usando el algoritmo del listado 6.2 y la representación dada para la gráfica en listas de adyacencias. e b a a b c d e f g h i h g d c f i b a a a b c e e h c e d b d d f g f d d f c g g h i g e h i i g f d 6.3.3.- Dado el recorrido BFS marcado con aristas sólidas (el resto de las aristas son punteadas), determinar las listas de adyacencias que hicieron posible este recorrido. 1 2 c e 0 2 a g b h 3 2 d f 2 2 6.3.4.- Da las distancias de cada uno de los vértices al vértice a, en las gráficas que siguen. (a) (b) g a (c) e b e b d f b h a j a d g d e c i c f c f 275 6.4 Trayectorias más cortas (e) (d) b e (f) a e a c f h a c f c h d d i d g f b e b g 6.3.5.- La siguiente gráfica representa una ciudad en la que existen dos depósitos de gas, marcados con los sı́mbolos X e Y . El dueño de los depósitos desea saber desde cuál depósito puede alcanzar a todos los clientes, representados por vértices, al menor costo posible. Las aristas representan caminos entre los tanques de gas que se deben llenar. Proporciona al dueño del depósito la respuesta. a e Y b X f d c 6.4. Trayectorias más cortas Muchas veces las aristas de una gráfica tienen costos asociados, como pudiera ser la distancia entre dos ciudades, el tiempo que se lleva recorrerla o el precio que hay que pagar por acceder a ella. En este caso tenemos lo que se conoce como una gráfica con pesos (en inglés, weighted graph) G = (V, E; w), donde w es una función que asigna a cada arista (o arco) un valor. Este valor puede ser entero, real, o cualquier otro tipo que se pueda agregar. Cuando este es el caso, la distancia entre el vértice u y el vértice v se define como la menor suma posible de los pesos de las aristas de las trayectorias entre u y v. Sin embargo, como w puede ser cualquier valor, podrı́amos encontrarnos con un caso como el que se muestra en la Figura 6.13. 276 Exploración en gráficas Figura 6.13 Ciclos negativos en una gráfica con pesos x -5 s 1 u v 2 y 6 r 1 En el caso de esta gráfica con pesos, la distancia de u a r, por el camino u, x, v, r es 2; por el camino u, y, v, r es 9. Sin embargo, si tomamos el camino u, x, v, y, u, x, v, r la distancia es 1. Si recorremos el ciclo n veces la distancia se va acortando, y no hay una cota inferior para ello. Decimos entonces que no podemos calcular la distancia de u a r y le asignamos el valor ∞. Tenemos algoritmos que logran detectar si existe algún ciclo negativo en la gráfica y entonces no calculan las distancias. En el caso del algoritmo de Dijkstra para trayectorias más cortas, el algoritmo supone que la gráfica no tiene ningún ciclo negativo; más aún, que todas las aristas tienen pesos positivos o cero. Si se presentan pesos negativos en las aristas, aunque no excluyen por sı́ solos que la distancia entre los vértices esté definida, no es posible demostrar la correctud del algoritmo de Dijkstra, demostración que no enfrentaremos en este texto. Algoritmo de Dijkstra para trayectorias más cortas El algoritmo de Dijkstra para trayectorias más cortas encuentra la distancia entre un vértice origen s y todos aquellos vértices alcanzables desde s. Como acabamos de mencionar, este algoritmo trabaja únicamente con gráficas cuyas aristas tengan pesos no negativos. Es un algoritmos bastante eficiente, conocido como glotón o ávido (greedy), ya que en cada momento toma la decisión local más conveniente. Para ello mantiene lo que se conoce como una cola de prioridades, manteniendo a la cabeza de la cola aquel vértice ya descubierto cuya distancia al origen sea la menor de entre los que se encuentran en la cola. De cierta manera trabaja muy parecido al algoritmo BFS, pues va estableciendo capas de vértices a una cierta distancia del vértice origen. La diferencia principal es que mientras que en BFS el número de aristas determina la distancia, en el algoritmo de distancias de Dijkstra lo que determina las distancias es la suma de los pesos de las aristas. De esta manera, un vértice que pudiese estar adyacente al origen, este camino bien pudiera pesar más que uno que estuviese a dos aristas del origen. A continuación se encuentra el algoritmo para trayectorias más cortas de Dijkstra. Objetivo: Dada una gráfica G = (V, E; w) tal que todos los pesos en las aristas son no negativos, y un vértice origen s, determinar v.δ, la distancia del vértice origen a cada uno de los vértices alcanzables desde s. 277 6.4 Trayectorias más cortas Datos: La gráfica G = (V, E; w) y s ∈ V . Salida: El valor de v.δ, ∀v ∈ V tal que ∃s v.. Estructuras de datos: Las mismas que para BFS, excepto que cada arista tiene asociado un peso. La cola ahora es una cola de prioridades (CP ), donde podemos elegir al que tenga la mayor prioridad (la menor distancia anotada). Método: Se encuentra en el listado 6.3. Listado 6.3 Algoritmo de Dijkstra para distancias 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 / * I n i c i a l i z a c i ón : * / ∀v ∈ V : v.δ ← ∞ v.π ← nulo / * C i c l o : ∀v ∈ V : s.δ ← 0 CP ← hsi / * P r o c e s a r a l que e s t é a l f r e n t e de l a c o l a . * / M i e n t r a s C 6= ∅ u ← v t a l que v.δ ≤ x.δ , para toda x ∈ C ∀v ∈ l i s t a de adyacencias de u : v ← u.primero; w ← (u, v).peso S i v.δ == ∞ v.δ ← u.δ + w v.π ← u CP ← CP + v / * F i n : v.δ == ∞ * / S i v.δ > u.δ + w v.δ ← u.δ + w v.π ←= u / * F i n : v.δ > u.δ + w * / / * C i c l o : ∀v ∈ l i s t a de a d y a c e n c i a s de u * / CP = CP − u / * C i c l o : M i e n t r a s C 6= ∅ * / /* Reporta Resultados : */ ∀v ∈ V /* ( Reporta d i s t a n c i a ) */ E s c r i b e "Distancia de "+ s+" a " +v+" es "+v.δ / * ( R e p o r t a camino ) * / Repite : Reporta v u ← u.π hasta que u == nulo / * C i c l o : ∀v ∈ V * / 278 Exploración en gráficas Ejemplo 6.5. Apliquemos el algoritmo a la gráfica de la figura 6.14 cuya representación con listas de adyacencias se encuentra en la tabla 6.1. Figura 6.14 Algoritmo de Dijkstra para trayectorias más cortas 3 o 1 3 1 s 2 3 q 1 3 5 2 u t 2 p v 1 1 4 2 w 3 r Tabla 6.1 Listas de adyacencias para la gráfica en la figura 6.14 vértice → vértices adyacentes: (peso(u, v), v) s o t q u p v r w → (3, o) → (1, t) → (2, q) → ∅ → (3, s) → (1, t) → (2, u) → (3, p) → ∅ → (1, o) → (1, s) → (3, q) → ∅ → (2, s) → (3, t) → (3, u) → (4, r) → ∅ → (2, o) → (3, q) → (1, p) → (1, r) → ∅ → (3, o) → (2, v) → (5, w) → ∅ → (2, p) → (1, r) → (2, w) → ∅ → (4, q) → (1, u) → (1, v) → (3, w) → ∅ → (5, p) → (2, v) → (3, r) → ∅ En la figura 6.15 mostramos a la derecha de la gráfica, arriba, el significado del tipo de lı́nea que une a dos vértices y, abajo, en una tabla, la distancia con la que quedó cada vértice, medida desde el vértice s, y el orden en que fue llegando cada vértice al frente de la cola de prioridades. Este orden depende del orden de los vértices (o aristas) en las listas de adyacencias (incidencias) de cada vértice. 279 6.4 Trayectorias más cortas Figura 6.15 Distancias con el algoritmo de Dijkstra 2 o 1 3 0 s 1 2 3 4 q 1 3 6 v 1 4 5 2 4 u t 1 2 5 p 3 1 2 w 8 aristas usadas no incluidas aristas incluidas y quitadas aristas que dan la distancia 3 r 5 vi s o t q u p r w v δ 0 3, 2 1 2 4 5 6, 5 10, 8 7, 6 orden 1 3 2 4 5 6 7 9 8 Las aristas se van tomando en el orden en que están en la lista de adyacencias de cada vértice cuando éste llega al frente de la cola de prioridades. La gráfica resultante es producto de este orden y el peso especı́fico de las aristas. En ocasiones podemos tener otra gráfica como resultado y esta situación se da cuando se puede llegar a un vértice desde dos vértices distintos pero con la misma distancia. Si las aristas se toman en orden distinto o cambiamos el orden de selección entre vértices que tienen la misma distancia y ésta los coloca al frente de la cola, podemos terminar con trayectorias del mismo tamaño pero que visitan diferentes vértices. Esto sucede, por ejemplo, si al elegir entre o y q, ambos con distancia 2, se elige al vértice que no se eligió en una ejecución anterior. También sucede entre los vértices p y r. Veamos algunos ejemplos más del uso del algoritmos de distancias de Dijkstra. La cola de prioridades aparecerá en orden de prioridad, no en el orden en que ingresaron los vértices a la misma. Las listas de adyacencias se van a considerar ordenadas alfabéticamente. Ejemplo 6.6. En la figura 6.16 de la siguiente página vemos nuevamente la ejecución del algoritmo de Dijkstra para trayectorias más cortas. 280 Exploración en gráficas Figura 6.16 Trayectorias más cortas (b) (a) C = h(a, 0)i 0 a C = h(a, 0); (c, 4); (e, 9)i 0 a 4 b 3 4 c 9 6 15 4 10 d e 9 10 d e 3 6 15 4 f b 3 4 c f 3 9 (c) (d) C = h(c, 4); (e, 9); (b, 7); (f, 19); (d, 8)i 0 a 4 9 6 15 4 10 8 d e 0 a 7 b 3 4 c C = h(b, 7); (d, 8); (e, 9); (f, 13)i 4 9 e 3 f 13 9 (f) C = h(d, 8); (e, 9); (f, 13)i 0 a 4 15 4 10 3 C = h(e, 9); (f, 12)i 0 a 7 b 3 4 c 8 d e 10 3 (e) 9 6 15 8 d 9 9 3 4 c 4 f 19 7 b 6 9 4 3 4 c 15 4 10 8 d f 13 e 9 7 b 3 6 f 12 281 6.4 Trayectorias más cortas Figura 6.16 Trayectorias más cortas (continúa. . . ) (g) (h) C = h(f, 12)i 0 a 9 4 C=∅ 3 4 c 15 4 10 8 d e 9 3 0 a 7 b 6 9 4 3 4 c 15 4 10 8 d f 12 e 7 b 6 f 12 3 9 En la figura 6.16 mostramos el progreso del algoritmo de Dijkstra para trayectorias más cortas. (a) En la subfigura 6.16(a) se encuentra el estado de la gráfica y la cola de prioridades al iniciarse el ciclo, después de la inicialización. El vértice a, que es el origen, se encuentra como único elemento de la cola y su distancia es 0. (b) Los vértices c y e entran a la cola de prioridades ya que son descubiertos desde a. Entran a la cola con su distancia a a. Esto se muestra en la subfigura 6.16(b). (c) Se elimina a a de la cola y queda c al frente de la cola, ya que es el vértice con la distancia menor registrada que se encuentra en la cola. Desde c se descubre a b, d y f , que entran a la cola con sus distancias al vértice a, pero pasando por el vértice c. Este estado se muestra en la subfigura 6.16(c). (d) En la subfigura 6.16(d) se muestra la salida del vértice c de la cola porque ya fue procesado; el vértice al frente de la cola es b, porque es el que presenta la menor distancia al vértice a de entre los que se encuentran en la cola; como el camino desde a a f que pasa por b es más corto que el que pasa por c, se corrige la distancia a f y la trayectoria más corta hasta el momento de a a f . (e) Se elimina a b de la cola y queda como primero en la misma el vértice d. No se descubre a ningún vértice que no está ya en la cola, ni cambia ninguna de las trayectorias. (f) Se elimina a d de la cola, quedando al frente de la misma el vértice e. La trayectoria de a a f que pasa por d es más corta que la que pasa por b, por lo que se corrige la distancia a f y la trayectoria, obligando a que ahora pase por e. (g) Sale e de la cola, quedando f al frente de la misma y como único elemento. Desde f no hay ninguna trayectoria que corregir y no queda ya ningún vértice por descubrir que sea adyacente a f , por lo que en esta iteración no se hace nada. 282 Exploración en gráficas (h) Se saca a f de la cola, quedando ésta vacı́a, por lo que ya no se vuelve a entrar al ciclo. A diferencia del algoritmo BFS, el algoritmo de Dijkstra para trayectorias más cortas sı́ debe deshacer trabajo ya hecho. Sin embargo, este trabajo no es significativo, pues el peor caso se va a presentar si cada arista que se explora obliga a cambiar las distancias y la trayectoria. Pero tanto la distancia como la trayectoria representan un cambio en los campos δ y π de cada vértice, por lo que la construcción de la trayectoria y la definición de la distancia únicamente involucra, en el peor caso, dos pasos por cada arista en la gráfica. Pero notarán que en cada ciclo se tiene que salir del mismo con la cola de prioridades actualizada, esto es, con el vértice de menor distancia al frente. Podemos pensar en mantener la lista ordenada, pero esto es muy costoso, por lo que nos vamos a conformar con mover al vértice con la menor distancia al frente de la cola. Hay algoritmos eficientes que logran esto y depende de la estructura de datos que se elija para almacenar a la cola de prioridades. De cualquier forma, al costo de procesar los caminos y las distancias le debemos agregar el costo de mantener la cola de prioridades, que puede ser tan bajo como n log n. Por lo que el costo de encontrar el camino con pesos en las aristas es más costoso que el problema similar con pesos homogéneos en las aristas. Es importante notar también que una vez que un vértice llega al frente de la cola es porque ya alcanzó su trayectoria más corta. Por lo tanto, ninguna iteración va a modificar su distancia. Esto se demuestra en un curso de análisis de algoritmos (y es la razón por la que los pesos en las aristas deben ser no negativos). Ejercicios 6.4.1.- Si alguna de las aristas tuviese peso negativo, ¿en qué punto falları́a el algoritmo de Dijkstra para trayectorias más cortas? 6.4.2.- En las siguientes gráficas, encuentra las trayectorias más cortas dadas por el algoritmo de Dijkstra para distancias. (b) (a) c 5 a 2 6 2 1 2 e b a 4 f 2 c e 2 1 4 3 4 3 1 d 3 2 7 b 2 d 1 f 283 6.4 Trayectorias más cortas (d) (c) 9 a 8 b c a 3 3 5 3 3 9 e 4 d 2 1 f 2 i 4 g 5 4 6 d 5 6 3 c b 2 e f 3 4 h 1 1 j 6.4.3.- Modifica el algoritmo de distancias de Dijkstra para que produzca la distancia entre dos vértices dados en una gráfica con pesos en las aristas. 6.4.4.- Dado el siguiente árbol de distancias de Dijkstra que corresponde a una gráfica con pesos en las aristas, reconstruye las listas de adyacencias que fueron usadas al ejecutarse el algoritmo. b 3 c 2 2 a f 3 2 1 d 3 e 6.4.5.- Supongamos que queremos movernos en el sistema de transporte público de la ciudad. Describe a la gráfica con pesos en las aristas que modelan a los siguientes problemas: (a) ¿Cuál es el menor tiempo requerido para viajar entre dos puntos? (b) ¿Cuál es la menor distancia que se tiene que recorrer para viajar de un punto a otro? (c) Suponiendo que cada uno de los tipos de transporte tiene un costo distinto, ¿cuál es la manera más económica de llegar de un punto a otro de la ciudad? 6.4.6.- ¿Se podrı́a modificar el algoritmo de Dijkstra para que encuentre la trayectoria más larga entre cualesquiera dos puntos? Justifica tu respuesta. 284 Exploración en gráficas 6.4.7.- Si tenemos aristas con pesos negativos en una gráfica con pesos en las aristas, pero de tal manera que no haya ciclos negativos, ¿podemos modificar la gráfica de alguna manera para poder usar el algoritmo de Dijkstra para distancias? Justifica tu respuesta. 6.5. Número de caminos Queremos saber el número de caminos de una cierta longitud que hay entre cualesquiera dos vértices o, simplemente, si existen caminos de una cierta longitud entre dos vértices. Esta información es importante cuando queremos operar sobre una red y deseamos saber qué tan conectados están unos vértices con otros. 6.5.1. Matrices de adyacencias El siguiente teorema nos dice cómo obtener el número de caminos de una cierta longitud entre dos vértices cualesquiera. Teorema 6.5 Sea G = (V, E) con |V | = n y los vértices etiquetados v1 , v2 , . . . , vn . Sea A la matriz de adyacencias de G, con ai,j la entrada que corresponde a los vértices i y j. Entonces, el número de caminos de longitud m entre los vértices vi y vj está dado por ai,j en Am , donde Am corresponde a la multiplicación de la matriz A por sı́ misma m veces. Demostración. Demostraremos el teorema por inducción sobre m. Base: Para m = 1, el número de caminos entre el vértice vi y el vértice vj de tamaño uno es 0 o 1, dependiendo de si hay una arista entre vi y vj . Esta es precisamente la definición de matriz de adyacencias. Hipótesis de inducción: Supongamos que la matriz Am−1 contiene para cada pareja i, j el número de caminos distintos entre vi y vj de tamaño m − 1. Paso inductivo: Veamos qué y cómo se calcula Am , representándola como am i,j . am i,j = n X k=1 m−1 ai,k · ak,j m−1 nos dice cuántos caminos ai,k nos dice si hay un camino de longitud 1 de vi a vk , y ak,j hay de vk a vj de longitud m − 1. Para calcular el número de caminos de longitud m tratamos de extender los caminos de longitud m − 1, de la siguiente manera: 6.5 Número de caminos 285 Para ir de vi a vj con un camino de longitud m, vemos cuáles vértices vk tienen caminos de longitud m − 1 hacia vj , y aumentamos el camino con todos los vértices vk que tienen caminos de longitud 1 desde vi . Si no hay arista de vi a vk el camino no puede ser extendido. Si hay, vamos a sumar todos los posibles caminos que cumplan con esto. ∴ En Am queda el número de caminos de longitud m entre cualesquiera dos vértices. Ejemplo 6.7. Fijémonos en la figura 6.17, donde la matriz A1 corresponde simplemente a la matriz de adyacencias de la gráfica. Debemos notar que esta forma de calcular el número de caminos entre cualesquiera dos vértices de una gráfica también nos puede llevar a decidir fácilmente si existe un camino entre cualesquiera dos vértices. Para este último punto, podemos observar que si una gráfica tiene n vértices, lo más alejados que pueden estar dos vértices entre sı́ es por n − 1 aristas; por lo tanto, si tenemos una gráfica G = (V, E) con n vértices y la matriz de adyacencias A para esa gráfica, la pregunta de si la gráfica es o no conexa se puede resolver obteniendo sucesivamente Ak , para k = 1, 2, . . . n − 1, lo que nos darı́a, para cada k, si existen o no caminos de longitud k entre dos vértices. Como a lo más tenemos que calcular la potencia n − 1, si alguna entrada de la matriz se mantiene en 0 en todas estas matrices, quiere decir que esos vértices no están conectados. Ejemplo 6.8. Si bien la matriz Ak (la matriz de adyacencias multiplicada por sı́ misma k veces) nos da el número de caminos de longitud k, pudiera ser que para una pareja particular de vértices no existiera ningún camino de longitud 2, por ejemplo, pero que sı́ existieran caminos de longitud 1 y 3. Tal es el caso de los vértices v1 y v2 en la gráfica de la figura 6.18. Para obtener si hay una trayectoria cualquiera entre dos vértices hay que obtener, de alguna manera, la suma de todas estas matrices. Por ejemplo, A nos dice si están conectados por un camino de longitud 1, A + A2 nos indica si hay caminos de longitud 2 o menores entre cualesquiera dos vértices; A + A2 + A3 si hay algún camino de longitud menor o igual a 3; y ası́ sucesivamente. Podrı́amos definir a estas matrices de la siguiente forma: A1 =A; An =An−1 + An ; donde An tiene el significado que le dimos en los párrafos anteriores. De esta manera, la entrada (i, j) de la matriz An (mnij ) nos indicarı́a el número de caminos de longitud menor o igual a n entre los vértices vi y vj de la gráfica. 286 Exploración en gráficas Figura 6.17 Número de caminos de longitud 3 v1 v4 A2 :  A3 :  A1 : v2 v1 v2 v3 v4 v3 0 1 1 1          1 0 1 1  •     1 1 0 0    1 1 0 0 3 2 1 1      2 3 1 1   •    1 1 2 2    1 1 2 2 0 1 1 1 v1 v2 v3 v4 0 1 1 1 1 0 1 1 1 1 0 0 1 1 0 0 (          1 0 1 1       1 1 0 0    1 1 0 0 0 1 1 1      1 0 1 1       1 1 0 0    1 1 0 0 ) 3 2 1 1       2 3 1 1       1 1 2 2    1 1 2 2 4 5 5 5       5 4 5 5       5 5 2 2    5 5 2 2 Las matrices para este caso (corroborar si se desea) serı́an las que se encuentran en la figura 6.19. Figura 6.18 No existe camino de longitud 2 entre 1 y 2 1 2 3 4 287 6.5 Número de caminos Figura 6.19 Resultado de multiplicar matrices de adyacencias por sı́ mismas A1 : ( ) ( ) ( ) 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 2 0 0 2 A2 : 0 2 2 0 0 2 2 0 2 0 0 2 0 4 4 0 A3 : 4 0 0 4 4 0 0 4 0 4 4 0 Ejemplo 6.9. Veamos la gráfica de la figura 6.20. Vamos a tratar de determinar si la gráfica es conexa, aplicando la suma y multiplicación de las matrices de adyacencias. Figura 6.20 Conexidad en gráficas mediante número de caminos b f d a h c g e a b c d e f g h a  b c 0   1   1   0    0   0    0 0 d 1 0 1 1 0 0 0 0 e 1 1 0 1 1 0 0 0 f 0 1 1 0 1 1 0 0 g 0 0 1 1 0 0 1 0 h 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0                El número de caminos de longitud 2 entre cualesquiera dos vértices está dado por la matriz de adyacencias multiplicada por sı́ misma, mientras que el número de caminos de longitud 3 entre cualesquiera dos vértices está dado por A3 :         A2 =        2 1 1 2 1 0 0 0 1 3 2 1 2 1 0 0 1 2 4 2 1 1 1 0 2 1 2 4 1 0 2 1 1 2 1 1 3 2 0 1 0 1 1 0 2 3 1 1 0 0 1 2 0 1 3 1 0 0 0 1 1 1 1 2                        A3 =        2 5 6 3 3 2 1 0 5 4 7 8 3 1 3 1 6 7 6 8 7 3 2 2 3 8 8 4 8 7 2 2 3 3 7 8 2 2 6 2 2 1 3 7 2 2 6 4 1 3 2 2 6 6 2 4 0 1 2 2 2 4 4 2                288 Exploración en gráficas Revisemos algunas parejas de vértices para ver que, en efecto, el número de caminos dado por las potencias de la matriz es correcto. Por ejemplo, el número de caminos de longitud 2 que salen de a y regresan a a está dado por la entrada m2aa = 2, y corresponden a a−b−a y a−c−a. Sólo hay un camino de longitud 2 entre d y e, que corresponde a d−c−e. Cualquier otro camino entre d y e es de longitud distinto a 2. Para los caminos de longitud 3, especificados en la matriz A3 , podemos observar que hay 3 caminos de longitud 3 entre c y f , a saber, c−b−d−f , c−e−d−f y c−e−g−f . Cualquier otro camino tiene longitud distinta a 3. Mostramos a continuación las matrices obtenidas de las distintas potencias. Lo único realmente interesante es que en A3 todavı́a no hay camino entre a y h (m3ha = m3ah = 0), aunque en A4 deberemos poder ya alcanzar todos los vértices desde cualquier otro vértice, pues el camino simple más largo entre dos vértices tiene longitud 4.     11 11 13 16 10 4 5 3 24 40 48 38 34 24 17 9      11 20 20 15 18 12 5 4   40 46 64 70 40 24 34 17       13 20 28 23 16 12 12 5   48 64 72 76 63 40 33 24       16 15 23 31 14 8 17 9   38 70 76 60 71 57 31 25    5   A4 =   A =   10 18 16 14 21 16 6 8   34 40 63 71 36 28 45 22       4 12 12 8 16 17 8 8   24 24 40 57 28 24 41 25           5 5 12 17 6 8 16 8   17 34 33 31 45 41 22 24  3 4 5 9 8 8 8 8 9 17 24 25 22 25 24 16 A4 dice que hay 3 caminos de longitud 4 entre a y h. Ellos son: a−b−d−f−h, a−c−e−g−h y a−c−d−f−h. Como vemos en A3 , A2 y A, no hay caminos de longitud menor a 4; como vemos de A5 hay 9 caminos de longitud 5. Estos 9 caminos se obtienen cuando, para cada uno de los caminos de longitud 4 (que son 3) en lugar de seguir hacia h pasamos al vértice “de enfrente”. Tomemos el camino a−c−e−g−h por ejemplo. De este camino obtenemos 3 de longitud 5, si desde c subimos a b y seguimos hacia h (a−c−b−d−f−h), desde e subimos a d (a−c−e−d−f−h) o desde g subimos a h ((a−c−e−g−f−h). En resumen, si nos interesa saber si hay alguna trayectoria entre dos vértices tenemos que observar si para alguna de las potencias de la matriz hay una entrada distinta de cero en esa posición de la matriz. No obtenemos esta información simplemente de observar Ak , pues pudiese haber caminos de longitudes distintas a k, pero ninguno exactamente de longitud k. Para obtener la información de si hay o no camino, o de cuántos caminos hay de cualquier longitud (menores a n) hay que sumar las entradas de las potencias de las matrices. Por ejemplo, para saber si dos vértices están conectados por algún camino de longitud menor a 3, basta sumar A, A2 y A3 . Podemos denotar con S3 al resultado de sumar A+A2 +A3 289 6.5 Número de caminos y con s3ij al elemento en el renglón i columna j de S k . Cada skij , i = 1, . . . , n, j = 1, . . . , n se calcula como sigue:  r−1 Pn r−1 sij + k=1 mik ∗ mkj si r > 1     srij = mij + m2ij + . . . + mrij =     mij si r = 1 Ejemplo 6.10. Apliquemos esta operación a la gráfica de la figura 6.20.         A + A2 + A3 =        4 6 7 5 4 2 1 0 6 7 5 4 2 1 0 7 9 9 5 2 3 1 9 10 10 8 4 3 2 9 10 8 9 7 4 3 5 8 9 5 4 6 3 2 4 7 4 5 7 5 3 3 4 6 7 5 5 1 2 3 3 5 5 4                En esta matriz podemos observar que no hay camino, de longitud menor o igual que 3, entre a y h. Por ejemplo, entre los vértices d y f no hay caminos de longitud 2, pero sı́ de longitud 1 y 3. Al observar la matriz de las sumas vemos que en la matriz que representa a las sumas, la posición Mdf es distinta de cero. Si únicamente queremos saber si hay algún camino entre dos vértices, podemos modificar ligeramente el algoritmo y hacer una operación lógica de disyunción en lugar de la suma. Llamemos a esta matriz C r y a cada elemento de la misma crij . La fórmula para el cálculo de esta matriz queda como sigue:  r−1 Wn r−1 ∧ mkj si r > 1 cij ⊕ k=1 mik     crij = mij ⊕ m2ij ⊕ . . . ⊕ mrij =     mij si r = 1 La interpretación de ⊕ corresponde al resultado de hacer una disyunción lógica, interpretando a 0 como falso y a 1 como verdadero. El significado de la fórmula es que va a haber un camino entre el vértice vi y el vértice vj , si es que para alguna k existe un camino entre 290 Exploración en gráficas el vértice vi y el vértice vk y hay una arista entre el vértice vk y el vértice vj . En este tipo de cálculo sólo se verifica si hay o no camino. Para saber si tenemos una gráfica conexa obtenemos Ak , donde A es la matriz de adyacencias y k = 1, . . . , n − 1. Como ya vimos, si es que hay algún camino entre dos vértices, vi y vj , este camino tiene que ser de longitud menor o igual a n − 1. Como C r nos indica si hay algún camino de longitud menor o igual a r, este algoritmo, que se debe a Warshall de quien toma su nombre, nos indicará en Cn−1 si hay algún camino entre cualesquiera dos vértices de la gráfica. Ejemplo 6.11. Veamos la matriz de adyacencias de la gráfica en la figura 6.20 y trabajemos con el algoritmo de Warshall para saber en cuál iteración se determina que la gráfica es conexa. 1 1 1 1 1 0 0 0  1 0 1 1 0 0 0 0    1 1 0 1 1 0 0 0    0 1 1 0 1 1 0 0    0 0 1 1 0 0 1 0   0 0 0 1 0 0 1 1    0 0 0 0 1 1 0 1   0 0 0 0 0 1 1 0          2 C =           1 1 1 1 1 1 1 1  0 1 1 0 0 0 0 0  1 1 1 1 1 1 1 0         1 C =A=                 3 C =           1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   0 1 1 1 1 1 1 1         4 C =           1 1 1 1 1 1 0 0    1 1 1 1 1 1 1 0    1 1 1 1 1 0 1 1    1 1 1 1 1 1 0 1   0 1 1 0 1 1 1 1    0 0 1 1 0 1 1 1   0 0 0 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1 291 6.5 Número de caminos          5 C =         1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1          6 C =         1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1    1 1 1 1 1 1 1 1   1 1 1 1 1 1 1 1 De los productos obtenidos del algoritmo de Warshall podemos observar lo siguiente: i. En C 3 la entrada para cah = cha es 0, lo que quiere decir que no hay ningún camino de longitud menor o igual a 3 entre los vértices a y h, lo que podemos observar directamente en la gráfica. ii. En C 4 podemos observar que todas las entradas en la matriz son 1, lo que quiere decir que hay algún camino de longitud menor o igual a 4 entre cualesquiera dos vértices. iii. A partir de C 4 el contenido de la matriz ya no cambia, pues ya se encontró un camino entre cualesquiera dos vértices. No mostramos ya C 7 para ahorrar espacio, aunque es claro que va a ser igual a las tres matrices anteriores. 6.5.2. Colofón El algoritmo de Warshall es lo que se conoce como un algoritmo de punto fijo, esto es, a partir de una determinada iteración el resultado de la ejecución ya no cambia. En el caso de este algoritmo, la iteración corresponde, a más tardar, a una menos que el número de vértices, aunque como ya vimos, esto puede suceder antes. Nos vamos a encontrar con muchos algoritmos de punto fijo en ciencias de la computación. Este atributo es importante porque nos garantiza que el algoritmo va a terminar. Es claro que la representación más conveniente de una gráfica va a depender de los procesos que queramos aplicarle o de las preguntas que deseamos hacer respecto a la gráfica. Si la pregunta se refiere a la conexidad de una gráfica, podemos aplicar cualquiera de los algoritmos de exploración que vimos (BFS o ciclos eulerianos) y en un número relativamente bajo de operaciones (proporcional a la suma del número de vértices con el número 292 Exploración en gráficas de aristas) determinar si existe un camino desde alguno de los vértices a cualquier otro. Al final del algoritmo simplemente tenemos que observar si todos los vértices quedaron con una distancia definida, y si es ası́ la gráfica es conexa. Si algún vértice quedó con distancia indefinida (∞), entonces no hay camino a él desde el vértice origen. Si usamos el algoritmo BFS podemos averiguar la distancia entre el vértice origen y cualquiera de los otros vértices en la gráfica, pero para saber la distancia entre cualesquiera dos vértices tendrı́amos que ejecutar el algoritmo tomando como origen a cada uno de los vértices de la gráfica, lo que nos llevarı́a un número de operaciones proporcional a n2 , donde n es el número de vértices en la gráfica. El algoritmo de Warshall ejecuta n2 operaciones para obtener cada matriz de caminos, por lo que ejecuta un número de operaciones proporcional a n3 para obtener la conexidad de la gráfica. Sin embargo, como estamos hablando de matrices simétricas, se pueden usar representaciones especı́ficas para matrices triangulares y disminuir el número de operaciones a ejecutar. Encontrar el número de caminos de determinada longitud en una gráfica representada por listas, ya sea de adyacencias o incidencias, se ve bastante más complicado. Habrı́a que seguir todos los posibles caminos para ver si alguno llega al vértice deseado, lo que supondrı́a muchos caminos fallidos. También es difı́cil responder eficientemente en esta representación a la pregunta de si existe algún camino entre dos vértices cualesquiera. Esto se deberá repetir para cualquier pareja de vértices y no sirve el trabajo hecho para otra pareja cualquiera. En cambio, con la matriz de adyacencias, todos los caminos se calculan simultáneamente. En contrapartida, ejecutar un algoritmo como BFS o DFS sobre una gráfica representada en una matriz involucra revisar todo el renglón o la columna correspondiente para encontrar el siguiente vértice a explorar, o para determinar si quedan aristas sin usar. Esto agregarı́a muchas operaciones, por cada operación que se realiza en una lista de adyacencias. Si representamos una relación de equivalencia con una gráfica no dirigida, el algoritmo de Warshall encuentra lo que se conoce como la cerradura transitiva de la relación, esto es, cuáles vértices están relacionados, usando transitividad y simetrı́a. Para terminar con este tema deseamos remarcar que cuando se va a procesar una gráfica usando una computadora es importante tener claro el tipo de preguntas que se desean hacer, ya que de ello depende la representación interna que se le dé a la gráfica y que va a llevar a procesos más eficientes si esta representación es la adecuada. Ejercicios 6.5.1.- Supongamos que tenemos una gráfica con pesos en las aristas sin ciclos negativos. El algoritmo de Floyd trabaja de manera similar a como lo hace el algoritmo de Warshall; lo presentamos a continuación: 293 6.5 Número de caminos Algoritmo de Floyd para distancias Objetivo: Encontrar la distancia entre cualesquiera dos vértices para una gráfica con pesos en las aristas. Datos: La gráfica representada con una matriz de pesos, esto es, en cada entrada de la matriz se encuentra el peso de la arista que conecta a esos vértices. Para el caso de que no haya arista, se registra como distancia ∞. Salida: Una matriz D donde en la entrada dij = dji se encuentra la distancia entre los vértices vi y vj . Método: Se multiplica la matriz por sı́ misma; en cada operación se selecciona la trayectoria más corta hasta el momento. El algoritmo se encuentra en el listado 6.4. Listado 6.4 Algoritmo para distancias de Floyd 1 / * I n i c i a l i z a c i on * / 2 ∀i = 1, . . . , n 3 ∀j = 1, . . . , n 4 dij = matrizij 5 ∀i = 1, . . . , n 6 ∀j = 1, . . . , n 7 ∀k = 1, . . . , n 8 dist = dik + dkj 9 i f dist < dij 10 dij = dist Supongamos que la gráfica de la figura 6.20 tenga pesos homogéneos en sus aristas (pensemos que es 1). (a) ¿Cuál es la matriz inicial de distancias? (b) ¿Cuál es el resultado de aplicar el algoritmo de Floyd a esta gráfica? 6.5.2.- Calcula el número de caminos de longitud menor o igual a 3 en cada una de las siguientes gráficas: (b) (a) v1 v4 (c) v3 v1 v7 v1 v5 v3 v5 v2 v6 v4 v6 v3 v2 v5 v4 v2 v8 294 Exploración en gráficas 6.5.3.- Para cada una de las gráficas del ejercicio anterior determina las distancias entre todas las parejas de vértices. 6.5.4.- Encuentra las distancias entre cualquier pareja de vértices en la siguiente gráfica: a 3 b 5 2 6 4 d c 7 6.5.5.- Determina cuál es la trayectoria más corta que hace que todos los vértices de la siguiente gráfica queden conectados, usando para ello la versión adecuada del algoritmo de Warshall. a b e c d 6.5.6.- Prueba que el elemento aii de la matriz A2 , donde A es la matriz de adyacencias de una gráfica, contiene el grado del vértice i. Modelado con gráficas 7 7.1. Coloración Supongamos que tenemos que organizar el calendario de exámenes finales para los estudiantes de primer semestre. Tenemos el problema que mientras que los cursos únicamente se llevan una hora al dı́a (dos para Cálculo), los exámenes finales tienen que durar dos horas. Se desea que el examen inicie a la hora que le corresponde al curso. Deseamos también, de preferencia, que a los alumnos de un semestre dado no les toque en un mismo dı́a dos exámenes del mismo semestre. Por lo tanto, debemos evitar que cursos llevados por el mismo estudiante tengan como fecha de examen final perı́odos o salones que se intersecten. Podemos modelar este problema con gráficas: cada curso corresponde a un vértice de la gráfica; existe una arista entre dos vértices si y sólo si esas materias se intersectan en horario. El máximo número de materias para las tres carreras del departamento de matemáticas es cinco, por lo que si repartimos las materias en los cinco dı́as no deberı́a haber problemas. La restricción debiera ser que dos materias que están relacionadas entre sı́ por el horario no les toque el mismo dı́a. Veamos el primer semestre para la carrera de Ciencias de la Computación. La lista de materias que se llevan en primer semestre, con los horarios, se encuentra en la tabla 7.1. La gráfica que corresponde a estas incompatibilidades se encuentra en la figura 7.1. Lo que debemos hacer es asignar dı́as distintos a vértices adyacentes; a cada dı́a lo 296 Modelado con gráficas podemos pensar como un color distinto y pintar (colorear) los vértices de la gráfica de tal manera que no haya dos vértices adyacentes con el mismo color. En general, si contamos con un número infinito de colores podrı́amos dar a cada vértice su propio color, pero esto no es ası́: contamos con un número finito de colores, muchas veces acotado – como es este caso en que los exámenes se deben realizar todos en 5 dı́as – por lo que el problema en realidad se puede describir como la coloración de una gráfica con el menor número posible de colores. Tabla 7.1 Incompatibilidades en exámenes finales Vértice A1 A2 A3 A4 C1 C2 G1 G2 M1 M2 Materia Álgebra Superior I Álgebra Superior I Álgebra Superior I Álgebra Superior I Cálculo Diferencial e Integral I Cálculo Diferencial e Integral I Geometrı́a Analı́tica I Geometrı́a Analı́tica I Matemáticas Discretas Matemáticas Discretas Grupos 4000 4001 4002 a 4007 4008 a 4012 4018 4019 a 4029 4037 a 4042 4043 a 4048 7000 7001 Horario 7-9 8-10 9-11 12-14 8-10 10-12 9-11 12-14 9-11 13-15 Figura 7.1 Gráfica de incompatibilidades para exámenes C1 A2 C2 M1 A3 G2 M2 A1 G1 A4 Tratemos de asignar colores de izquierda a derecha. A A1 le podemos asignar cualquiera de los colores, digamos rojo. A continuación, a C1 y A2 no les podemos asignar rojo, 297 7.1 Coloración porque son adyacentes a A1, ni tampoco el mismo color a ambos porque son adyacentes entre sı́; por lo tanto, asignémosles amarillo y verde respectivamente. En el siguiente nivel, podemos volver a asignar a M 1 el rojo, pero como tenemos disponibles todavı́a 2 colores sin usar, asignemos el negro; podemos usar el rojo para G1 o A3, y como A1 es la misma materia que A3, se lo asignamos a A3. A G1 le podemos asignar el quinto color que tenemos todavı́a disponible, el azul. A C2 no le podemos asignar ninguno de negro, rojo o azul; de igual manera en que lo hicimos con A1 y A3 le asignamos amarillo, que es el color asignado a C1 que corresponde a la misma materia. Para los tres vértices del componente del lado derecho, bajo el razonamiento que hemos dado hasta ahora, asignamos rojo a A4, azul a G2 y negro a M 2. Con esto terminamos de colorear la gráfica y queda como se muestra en le figura 7.2. Figura 7.2 Coloración de la gráfica de incompatibilidades para exámenes Muestra de colores (tonos de gris) a utilizar martes: amarillo miércoles: verde lunes: rojo jueves: negro viernes: azul C1 A2 C2 M1 A3 G2 M2 A1 G1 A4 Prevalece la pregunta de si 5 es el menor número de colores con el que se puede colorear esta gráfica. Si revisamos con cuidado esta gráfica veremos que no se puede colorear con menos de 5 colores, ya que M 1, por ejemplo, es adyacente a 4 vértices, que son adyacentes dos a dos entre sı́, por lo que no se puede repetir ningún color entre ellos ni con M 1. Veamos otro ejemplo. Supongamos que estamos tratando de programar presentaciones de libros en la Feria Internacional del Libro. Cada compañı́a editora tiene un determinado número de libros que presentar, y los autores de los libros deben estar presentes, ası́ como el representante de la editorial. Aunque no es común, podrı́amos tener más de un libro por autor, por lo que un mismo autor no puede estar en dos presentaciones a la vez. Para modelar este problema tendremos un vértice por cada libro a presentar, y habrá una arista entre dos vértices si es que son de la misma editorial, del mismo autor o tienen 298 Modelado con gráficas presentadores en común. La lista de libros a presentar se encuentra en la tabla 7.2. Tabla 7.2 Presentaciones de libros en la Feria del libro Vértice v1 v2 v3 v4 v5 v6 v3 v7 v2 v7 Autor Magidin Dehesa Viso Miranda Galaviz López Viso Kuri Dehesa Kuri Editorial Trillas Siglo XXI Trillas Fondo de Cultura Fondo de Cultura Trillas Fondo de Cultura Siglo XXI Fondo de Cultura Trillas La gráfica que corresponde a este problema se encuentra en la figura 7.3. Figura 7.3 Relación entre autores y editoriales v3 v6 v1 v5 v2 v7 v4 Veamos cuál es el menor número de colores que requerimos para colorear esta gráfica. Si asignamos a v3 un color, tenemos que asignar a v4 y v5 colores distintos entre sı́ y distintos del primero. Para v2 requerimos también un cuarto color, ya que v2 es adyacente a los tres vértices anteriores. Por otro lado, v1 o v6 pueden ser coloreados con el mismo color que v2 , pero no el mismo para ambos. Como v6 no es adyacente a v5 podrı́a recibir el mismo color, lo mismo que v7 . Con esto, la gráfica quedarı́a coloreada como se muestra en la figura 7.4. En este caso si hubiésemos usado un color por vértice (un horario distinto para cada presentación) hubiésemos requerido de 7 horarios. De esta manera, sólo requerimos 4 horarios distintos. 299 7.1 Coloración Figura 7.4 Coloración de la gráfica correspondiente a la Feria del Libro v3 v6 v1 v5 v2 v7 v4 Como se habrá notado el problema de coloración de gráficas es importante y se presenta suficientemente seguido como para que se trate de encontrar un algoritmo para que asigne los colores de manera eficiente. Tal algoritmo no existe, pero tenemos algunos resultados que nos pueden ayudar en esta asignación. Precisemos primero algunos conceptos: Definición 7.1 (número cromático) El número cromático de una gráfica es el número mı́nimo de colores que se requieren para colorearla, de forma tal que cualquier par de vértices adyacentes reciban distinto color; el número cromático de una gráfica G se denota con χ(G). Supongamos que tenemos un subconjunto de vértices Vi ⊆ V pintados todos del mismo color. Entonces, la subgráfica inducida por este subconjunto (G[Vi ]) no contiene ninguna arista, pues no puede haber aristas entre vértices pintados del mismo color. El problema es, entonces, determinar el número cromático de distintas gráficas. A continuación mencionamos algunas propiedades que conocemos acerca del número cromático de una gráfica. Lema 7.1 χ(G) = 1 si y sólo si G no tiene aristas, esto es G = (V, ∅). Demostración. ⇒: Por contrapositivo, supongamos que G = (V, E), con E 6= ∅. Entonces existe e = uv ∈ E tal que el vértice u es adyacente al vértice v (y viceversa). Si esto es ası́, u y v tienen que estar coloreados con distinto color, por lo que χ(G) es al menos 2  ¬(χ(G) = 1) ≡ (χ(G) 6= 1) . ⇐: Supongamos ahora que G = (V, ∅). En este caso no hay ningún par de vértices que sean adyacentes, por lo que todos los vértices pueden estar coloreados con el mismo color; esto es, χ(G) = 1. 300 Modelado con gráficas Lema 7.2 (χ(Cn )) El número cromático de un ciclo con n vértices y n par es 2; si n es impar entonces χ(Cn ) = 3: ( 2 si n es par χ(Cn ) = 3 si n es impar Demostración. Caso n par: Tomemos un vértice cualquiera del ciclo y lo coloreamos con color 1; el siguiente vértice (en cualquier dirección) lo coloreamos con color 2; el siguiente con 1 y ası́ sucesivamente. A los vértices pares se les asigna 1 y a los vértices impares 2. El último vértice es impar y el primero par, por lo que no se asigna el mismo color a vértices adyacentes – ver figura 7.5. Figura 7.5 Coloración de cı́rculo con un número par de vértices Caso n impar: En cambio, si el número de vértices en el ciclo es impar, necesitaremos al menos 3 colores. Si asignamos los colores de la misma forma que lo hicimos en el ciclo de longitud par, al llegar al último vértice por colorear va a resultar que es par, lo mismo que el primero; si le asignamos el color 1 estará coloreado igual que el primero, que es adyacente a él; si le asignamos el color 2 estará coloreado igual que el último que coloreamos, que también es adyacente a él. Por lo tanto, debemos colorearlo con un nuevo color. Ejemplo 7.1. Veamos la siguiente gráfica, que consiste de un ciclo con 6 vértices: v1 v2 v3 v5 v1 v3 v4 v4 v5 v6 v6 v2 301 7.1 Coloración Nótese que la gráfica está pintada como si fuera una gráfica bipartita. De hecho, cualquier gráfica que se puede colorear con exactamente dos colores corresponde a una gráfica bipartita. También tenemos resultados referentes a las gráficas completas, Kn : Lema 7.3 El número cromático de Kn es n. Demostración. Como todas y cada uno de los vértices de Kn tiene n − 1 vecinos, y cada uno de ellos es vecino de todos y cada uno de los otros vértices, no se puede asignar el mismo color a ningún par de vértices vecinos del primero, ya que son vecinos entre sı́. Por lo tanto necesitamos que cada vértice tenga su propio color. Ejemplo 7.2. Veamos la coloración de la gráfica K6 . Como cada vértice es adyacente a todos los otros vértices de la gráfica, ninguna pareja de vértices puede estar pintado del mismo color. De esto, el número cromático es precisamente n, usando un color distinto para cada vértice. 3 2 4 1 5 6 Si tenemos una gráfica que no tiene ciclos, entonces su número cromático será 2, como lo enuncia el lema 7.4. Lema 7.4 El número cromático de una gráfica sin ciclos es 2. Demostración. Ejecutamos en la gráfica BFS y asignamos los colores de la siguiente manera: a los vértices que están a distancia impar de s les asignamos el color 1, y a los que están a distancia par les asignamos el color 2. Como no hay ciclos en la gráfica, ningún vértice a distancia impar es adyacente a otro vértice a distancia impar, por lo que la coloración es correcta. 302 Modelado con gráficas Veamos un ejemplo en la gráfica de la figura 7.6, donde la distancia al vértice origen se encuentra dentro del vértice. Figura 7.6 Coloración de gráfica sin ciclos usando BFS 4 2 4 2 3 2 0 1 3 3 2 1 4 Podemos decir algo respecto al número cromático que tiene que ver con los distintos grados de los vértices de la gráfica. Podemos notar que si un vértice tiene grado k, a lo más requerimos de k + 1 colores distintos. Esto es una cota superior para el número cromático, ya que si los vértices vecinos no son adyacentes entre sı́ bastarı́a con dos colores. Teorema 7.1 El número cromático de una gráfica no excede el máximo grado de sus vértices más 1. Demostración. Supongamos que tenemos una gráfica cualquiera cuyo grado máximo es k. Por lo tanto contamos con los colores C0 , C1 , . . . , Ck . Tomemos al primer vértice v y lo coloreamos con cualquiera de los colores. Tomamos cualquier vértice u que no ha sido coloreado; como grado(u) ≤ k, hay al menos 1 color que no ha sido usado en ninguno de sus vecinos (pudieran ser más o que los vecinos no estén coloreados todavı́a); usamos ese color para colorear a u. Continuamos de esa manera hasta que no quede ningún vértice sin colorear. En ningún momento requerimos de más de k + 1 colores. Ejemplo 7.3. Veamos la gráfica en la figura 7.7. La manera sencilla de colorear la gráfica es empezando con un color arbitrario para el vértice de mayor grado, que en este caso es v6 , al que coloreamos de rojo. Después usamos el resto de los colores para colorear a cada uno de los vértices adyacentes a v6 . En este punto hemos coloreado a todos los vértices menos a v3 , que no es adyacente a v6 , por lo que lo podemos colorear con el mismo color que a v6 , o sea rojo. 303 7.1 Coloración Figura 7.7 Coloración siguiendo el grado mayor v1 v2 v3 v4 v7 v6 v5 Sin embargo, podemos colorear esta gráfica con menos colores, de la siguiente manera: • Empezamos con el vértice v6 , que es el de mayor grado. • Observamos que los vértices adyacentes a v6 no son todos adyacentes entre sı́, ası́ que aprovechamos esta situación para asignar colores alternados, siguiendo el ciclo v6 –v7 –v1 –v2 –v6 . Como es un ciclo de longitud par, bastarı́a con dos colores para colorearlo. Sin embargo, tenemos la arista v1 –v6 que cierra dos ciclos impares, por lo que requerimos tres colores distintos para v6 , v7 y v1 , digamos rojo, verde y azul respectivamente. v2 también forma parte de un ciclo impar, pero no es adyacente a v7 , por lo que lo podemos colorear también con verde. • Pasamos a ver el ciclo formado por v2 , v3 y v4 , que también es de longitud impar, por lo que hay que colorear los vértices en el ciclo con tres colores distintos; v4 no puede ser verde ni rojo, pues es adyacente a vértices con estos colores, por lo que le asignamos azul. v3 no puede ser verde ni azul, por lo que le asignamos rojo. • Por último sólo nos falta v5 , que también conforma un ciclo impar con v6 y v4 , por lo que tiene que pintarse de verde. v1 v2 v3 v4 v7 v6 v5 Si bien la primera coloración es correcta – no hay dos vértices adyacentes con el mismo color – el número cromático de la gráfica es menor, como lo pudimos constatar con la segunda coloración que dimos. Esta segunda coloración corresponde al número cromático de la gráfica. 304 Modelado con gráficas Ejemplo 7.4. Observemos, sin embargo, una gráfica muy similar a la anterior, con el mismo grado máximo: v1 v2 v3 v8 v4 v7 v6 v5 En este caso, colorando de manera simple, al terminar de pintar los vértices adyacentes a v6 nos quedan dos vértices sin colorear, v3 y v8 , a los que no podemos colorear con el mismo color, pues son adyacentes entre sı́. Conviene en este caso simplemente asignar colores siguiendo la estrategia dada para el vértice de mayor grado, parándose en los vértices adyacentes a los que quedaron sin asignar color, trabajando uno por uno. Una coloración más eficiente se logra siguiendo el critero de los ciclos impares que dimos en el ejemplo anterior, cuidando a los vértices adyacentes en ciclos distintos. Otro tipo de gráficas muy fáciles de colorear son las gráficas bipartitas. Al respecto enunciamos un resultado en el teorema 7.2. Teorema 7.2 Sea G = (V, E) una gráfica. Entonces χ(G) = 2 si y sólo si G es bipartita. Demostración. Supongamos que G = (V, E) es bipartita. Por la definición de gráfica bipartita, sabemos que V = V1 ∪ V2 con V1 ∩ V2 = ∅. También sabemos que no hay ninguna arista entre cualesquiera dos vértices de V1 (y lo mismo para cualquier pareja de vértices en V2 ). Por lo tanto, si asignamos un color a los vértices de V1 y otro color a los de V2 , no tendremos ninguna pareja de vértices adyacentes pintados con el mismo color y sólo requerimos de 2 colores, por lo que χ(G) = 2 (una gráfica con al menos una arista tiene número cromático al menos 2). Ahora supongamos que χ(G) = 2. Sea V1 el conjunto de vértices pintados con uno de los colores y V2 el de los vértices pintados con el otro color. Ningún vértice en V1 es adyacente a otro en el mismo subconjunto, porque si ası́ fuera no tendrı́amos una coloración correcta. Lo mismo sucede para cualesquiera dos vértices en V2 . De esto, tenemos que V = V1 ∪ V2 ; V1 ∩ V2 = ∅, pues ningún vértice puede estar pintado con los dos colores; ningún vértice es adyacente a otro vértice en el mismo subconjunto: por la 305 7.1 Coloración definición de número cromático, cada una de las subgráficas inducidas G[Vi ](i = 1, 2) no contiene aristas. Por lo tanto, todas las aristas en G tienen un vértice en V1 y otro vértice en V2 . De donde G es bipartita. Teorema 7.3 Sea G = (V, E) una gráfica conexa tal que |V | ≥ 3. Entonces G es bipartita si y sólo si G no contiene ciclos de longitud impar. Demostración. Sea G = (V1 , V2 , E) una gráfica bipartita. Si G contiene un ciclo C, los vértices de C alternan entre los conjuntos V1 y V2 , por lo que el número de vértices es par y por lo tanto también el número de aristas; de donde C es de longitud par. En sentido inverso, supongamos que G no contiene ciclos de longitud impar. Demostraremos que podemos partir a V en dos conjuntos ajenos, tales que toda arista vaya de un vértice en uno de los conjuntos a un vértice en el otro. Elegimos un vértice arbitrario u en V y ejecutamos el algoritmo BFS con u como origen. A los vértices que están a distancia impar los asignamos a un conjunto V1 , mientras que a los vértices que están a distancia par (incluyendo a u que está a distancia 0) los asignamos a un conjunto V2 . Es claro que V1 ∩ V2 = ∅ y que, si G es conexa, V = V1 ∪ V2 , pues todos los vértices serán alcanzados. Debemos demostrar ahora que no hay aristas entre vértices del mismo conjunto. Consideremos los siguientes cuatro casos: Caso 1. Sea x ∈ V2 tal que x 6= u. Como x está a distancia par de u, existe una trayectoria P de longitud par de u a x. Sea 2n la longitud de P . Si la arista ux ∈ E, tenemos un ciclo P xu de longitud impar – la longitud de u x—u es 2n + 1 – lo que contradice la hipótesis de que G no contiene ningún ciclo de longitud impar. Por lo que ux no puede estar en E. P u x Caso 2. Sean y, w ∈ V1 , con y 6= u y w 6= u. Supongamos que yw ∈ E. Sea P la trayectoria entre u e y, y Q la trayectoria entre u y w, y supongamos que P y Q no tienen ningún vértice en común: y P u Q w 306 Modelado con gráficas Como BFS encuentra las distancias entre el vértice u y cualquier otro vértice en G, sabemos que P y Q son trayectorias lo más cortas posibles, con P de longitud 2m y Q de longitud 2n. Si yw ∈ E, el ciclo u P y yw w Q u tiene longitud impar (2m + 2n + 1 = 2(m + n) + 1), lo que contradice la hipótesis de que G no contiene ciclos de longitud impar, por lo que yw 6∈ E. Supongamos ahora que las trayectorias se intersectan en un vértice x, con P′ = x y y Q′ = x w. Además, P ′ y Q′ no tienen ningún otro vértice en común además de x: y P −P P′ ′ u x Q − Q′ Q′ w Como tanto P como Q son trayectorias más cortas, P − P ′ y Q − Q′ tienen la misma longitud: si por ejemplo P −P ′ tuviera menor longitud que Q−Q′ , entonces la trayectoria P −P ′ Q′ u x w serı́a una trayectoria más corta que Q, contradiciendo el hecho de que BFS encuentra trayectorias más cortas. Por lo tanto, si suponemos que la longitud de P − P ′ (Q−Q′ ) es r, la longitud de P ′ es 2m−r y la longitud de Q′ es 2n−r. Por lo tanto, el ciclo que se forma, si es que yw ∈ E , es de longitud 2m−r +2n−r +1 = 2m+2n−2r +1 = 2(m + n − r) + 1 que es impar, otra vez contradiciendo la hipótesis de que no existe ningún ciclo de longitud impar en G, por lo que yw 6∈ E. Caso 3. Tanto y como w están a distancia impar, con y, w ∈ V1 , y 6= u y w 6= u. Nuevamente sean P y Q trayectorias de longitud más corta entre u e y y entre u y w respectivamente (tenemos un diagrama como el del caso 2). En este caso, las longitudes de P y Q son ambas impares, por lo que podemos expresarlas como 2m − 1 y 2n − 1 Q P yw y w u tiene longitud respectivamente. Si yw ∈ E, el ciclo formado por u 2m − 1 + 2n − 1 + 1 = 2m + 2n − 2 + 1 = 2(m + n − 1) + 1 que es un número impar, nuevamente contradiciendo la hipótesis de que G no contiene ciclos de longitud impar, por lo que yw 6∈ E. El caso de que P y Q se intersecten en algún vértice distinto de u sigue el mismo razonamiento que en el caso 2, por lo que ya no lo presentamos. Caso 4. No hay ningún vértice distinto de u en V1 . Si este es el caso, todos los vértices en V2 son adyacentes a u y están a distancia 1 – como no hay ningún vértice a distancia par de u, en particular a distancia 2, ningún camino que empiece en u puede tener longitud mayor que 1 –. 307 7.1 Coloración w x u y Si hubiese alguna arista entre dos vértices de V2 , por ejemplo xw ∈ E, tendrı́amos el ciclo u–x–w–u, que serı́a un ciclo impar, contradiciendo la hipótesis de que G no tiene ciclos de longitud impar, por lo que xw 6∈ E. Si bien una de las hipótesis de estos dos teoremas es que G es conexa, se puede aplicar el mismo razonamiento para cada componente conexa de una grafica, lo que resulta en el siguiente corolario: Corolario 7.4 Sea G una gráfica. Entonces χ(G) = 2 si y sólo si G no contiene ciclos de longitud impar. Se deja la demostración como ejercicio. Con lo anterior hemos dado algunas pistas de cómo proceder a colorear una gráfica, identificando qué tipo de gráfica es y asignando el menor número de colores posibles. Hay que aclarar, sin embargo, que fuera de las gráficas que están plenamente identificadas, no hay receta (algoritmo) para colorear una gráfica. Para terminar esta sección enunciaremos un teorema muy famoso, conocido como el Teorema de los cuatro colores, que hasta 1976 seguı́a como una conjetura. Para enunciarlo requerimos del concepto de una gráfica plana: Definición 7.2 Una gráfica plana es aquella que se puede pintar en el plano sin que se crucen aristas. Tomemos un mapa donde todos los paı́ses están totalmente contenidos en una sola región; cada paı́s está representado por un vértice y hay una arista entre un paı́s y otro si y sólo si los paı́ses tienen una frontera en común que corresponda a algún segmento de recta (si la frontera es únicamente en un punto, no se consideran adyacentes). Este tipo de gráficas son planas pues nunca hay fronteras en común que “brinquen” por encima de otras fronteras. Las aristas siempre aparecen como radios que salen de un paı́s a los paı́ses con frontera común y se pueden ir dibujando de izquierda a derecha y de norte a sur. La especificación original del Teorema de los cuatro colores, planteado como conjetura a mitad 308 Modelado con gráficas del siglo XIX; fue demostrado por Appel y Haken en 1976, haciendo un estudio caso por caso, usando para ello una computadora1 . Pasamos a enunciar el teorema: Teorema 7.5 (Teorema de los cuatro colores) El número cromático de una gráfica plana no excede a 4. Ejercicios 7.1.1.- Demuestra el corolario 7.4. 7.1.2.- Colorea las siguientes gráficas de acuerdo a su número cromático. Justifica el número cromático determinado. (a) (b) e b e b a g d a c c f (c) a g d f (d) c b a b e d e f g c d 7.1.3.- Programa los exámenes finales para Cálculo I, Cálculo II, Cálculo III, Cálculo IV, Discretas, ICC1, ICC2 y Probabilidad y Estadı́stica, usando el mı́nimo número de horarios y considerando que no hay estudiantes cursando al mismo tiempo2 : 1 Por el hecho de que el teorema fue demostrado con la ayuda de una computadora, para listar los casos posibles, muchos matemáticos sostienen que ésta no es una demostración matemática elegante. Inclusive, hay matemáticos que sostienen que ni siquiera es una demostración. 2 A este tipo de consideraciones se les llama incompatibilidades. 309 7.1 Coloración – – – – – – Cálculo I y Probabilidad y Estadı́stica; Cálculo II y Probabilidad y Estadı́stica; Cálculo IV y Discretas; Cálculo IV e ICC1; Cálculo I y Cálculo II; Cálculo III y Cálculo IV; pero hay estudiantes comunes en cualquier otra combinación de cursos. 7.1.4.- ¿Cuál es el menor número de policı́as que debemos apostar en las escuelas de una colonia para cubrir a todas las escuelas de la zona, si no podemos poner policı́as que estén a menos de 15 cuadras de distancia, porque entonces se juntan y se ponen a platicar, descuidando la vigilancia? E1 E2 E3 E4 E5 E6 – 8 17 20 5 10 8 – 12 17 10 16 17 12 – 10 20 25 20 17 10 – 21 22 5 10 20 21 – 10 10 16 25 22 10 – E1 E2 E3 E4 E5 E6 7.1.5.- Podemos observar que K3,3 y K5 no son gráficas planas, pues no hay manera de dibujarlas sin cruzar aristas. El Teorema de Kuratowski nos dice que si una gráfica contiene alguna subgráfica isomorfa a K3,3 o a K5 entonces la gráfica no es plana – el Teorema de Kuratowski es más fuerte e incluye el concepto de homeomorfismo que no es parte de este texto, por lo que sólo veremos esta versión de este teorema –. En las siguientes gráficas, usando este teorema, determina si las gráficas son planas o no. Si lo son, dibújalas como gráficas planas. (b) (a) a b (c) c d c f g e b c h a a b d f e e d 310 Modelado con gráficas 7.1.6.- Usando todos los resultados presentados en esta sección, determina el número cromático de las siguientes gráficas y colorea las gráficas de acuerdo al número cromático determinado. (b) (a) c a i a b b d e h c g g f h d f e (c) (d) b a b c c d a e f g h d f e Árboles 8 8.1. Caracterización Los árboles son gráficas que modelan adecuadamente diversos problemas. En particular son muy útiles cuando queremos cubrir a un conjunto de nodos de la manera más eficientemente posible, con el menor número posible de conexiones. Por ejemplo, si queremos poner un conjunto de teléfonos que comuniquen a un cierto número de comunidades pero queremos tener la menor cantidad de lı́neas posibles; y estamos dispuestos a canalizar llamadas aunque no sea directamente, la manera más económica de hacerlo es mediante un árbol. Supongamos que tenemos cinco pueblos y queremos que todos estén comunicados con cualquier otro. La gráfica que deseamos tener es una gráfica completa (K5 ), pero sin que tengamos que tener a todas las aristas presentes. Figura 8.1 Gráfica completa K5 U a b j e V c X k W g f h d Y 312 Árboles Podemos encontrar varios conjuntos de aristas tales que cubramos con ellas a todas las ciudades, como se muestra en las gráficas de la figura 8.2. Lo que podemos notar en estas tres gráficas es que todas son conexas y no tienen ciclos. Definición 8.1 (árbol) Un árbol es una gráfica conexa y acı́clica. Figura 8.2 Maneras de cubrir a todos los vértices de K5 (a) U V a b j k (b) (c) U U a a W V W c X Y X d h Y e V W c h X Y Las gráficas de la figura 8.3 son todas ellas árboles, mientras que las de la figura 8.4 no lo son. Figura 8.3 Gráficas que son árboles (a) (b) 313 8.1 Caracterización Figura 8.4 Gráficas que no son árboles (b) Tiene ciclos (a) No es conexa Teorema 8.1 Sean u y v vértices en un árbol T con al menos dos vértices. Entonces hay exactamente una trayectoria de u a v. Demostración. Como un árbol es una gráfica conexa, existe al menos un camino entre u y v en T ; por el teorema 6.1 éste contiene a una trayectoria entre u y v. Ahora mostraremos que no puede haber más de una. Supongamos que hay más de una trayectoria entre u y v – al menos dos –; si el árbol tiene sólo dos vértices, la única trayectoria entre ellos es la arista que los une, y como no permitimos aristas múltiples, ésa es la única trayectoria entre los dos vértices. Supongamos entonces |V | ≥ 3 y hay más de una trayectoria entre dos de esos vértices, u y v; tenemos la situación que se muestra en la figura 8.5. Figura 8.5 Existencia de más de una trayectoria entre dos vértices en un árbol P1 u w x P2 v 314 Árboles Supongamos que las dos trayectorias comparten una porción inicial y final, u w y x v (w pudiera ser u y x pudiera ser v). Sean esas dos trayectorias P1 y P2 . Pero entonces, la trayectoria w P1 x P2 w forma un ciclo, lo que contradice que T es un árbol (conexo y acı́clico). De donde no puede haber dos trayectorias entre dos vértices. Teorema 8.2 En un árbol T con más de un vértice hay al menos dos vértices de grado 1. Demostración. Como T es conexa con más de un vértice, hay al menos una trayectoria con dos vértices distintos. Tomemos una pareja de vértices u y v cuyo camino entre ellos sea tan grande como cualquier otra trayectoria entre dos vértices en T (de tamaño máximo). Esta trayectoria tiene un número máximo de aristas respecto a cualquier trayectoria en T . Aseveramos que tanto u como v tienen grado uno. Si u tiene grado mayor que uno, como T no tiene ciclos, existirı́a una trayectoria más larga en T ; lo mismo para v. De donde u y v tienen grado uno. Teorema 8.3 Un árbol con n vértices tiene exactamente n − 1 aristas. Demostración. Haremos la demostración por inducción en n, el número de vértices en T . Para n = 1, el único árbol con un solo vértice no puede tener ninguna arista, pues como no hay ciclos no podemos tener lazos. Por lo que se cumple que el árbol con un vértice tiene cero aristas. Nuestra hipótesis de inducción es que todo árbol con k < n vértices tiene k − 1 aristas. Supongamos ahora un árbol con n vértices. Como tenemos al menos dos de ellos con grado 1, quitemos uno de ellos y su correspondiente arista. Esta gráfica también es un árbol (sigue siendo conexa y acı́clica). Nos queda una gráfica con n − 1 vértices que, por la hipótesis de inducción, tiene n − 2 aristas. Por lo que al agregarle el vértice que quitamos con su arista correspondiente, tendremos n vértices con n − 1 aristas. Teorema 8.4 a. Cuando se elimina una arista de un árbol, la gráfica se desconecta y deja de ser árbol. b. Cuando se agrega una arista a un árbol (sin agregar vértices) la gráfica resultante tiene exactamente un ciclo y por lo tanto deja de ser árbol. Demostración. a. Sea T un árbol con n vértices. Por el teorema 8.3, T tiene n − 1 aristas y existe exactamente una trayectoria entre cualesquiera dos vértices. Supongamos que quitamos la arista u–v. Esta arista era la única trayectoria entre u y v, por lo que al quitar la arista ya no hay trayectoria entre u y v y la gráfica queda desconectada. 315 8.1 Caracterización b. Nuevamente, como T es un árbol, existe exactamente una trayectoria entre cualesquiera dos vértices. Si la gráfica únicamente tiene dos vértices y una arista, la única arista que podemos agregar es un lazo, lo que hace un ciclo, o una arista múltiple, lo que también formarı́a un ciclo. De esto, T dejarı́a de ser acı́clica y por lo tanto árbol. Supongamos que |V | > 2 y tomemos dos vértices u y v que no son adyacentes en T . Como T es árbol, existe una trayectoria entre u y v. Al agregarle la arista u–v se forma exactamente un ciclo, por lo que T deja de ser árbol. Teorema 8.5 Los siguientes enunciados respecto a una gráfica T son equivalentes: (a) T es un árbol. (b) T es conexa y el número de vértices es uno más que el número de aristas. (c) T es acı́clica y el número de vértices es uno más que el número de aristas. (d) Existe una única trayectoria entre cualesquiera dos vértices de T . (e) T es conexa y al quitar cualquier arista T se desconecta. (f) T es acı́clica y al agregar cualquier arista se forma un ciclo. Demostración. Para demostrar estas equivalencias, tenemos que seguir el siguiente orden en las demostraciones: a→b→c→d→e→f a → b Sea T un árbol (gráfica acı́clica y conexa). Por definición, es conexa, por lo que la primera parte del inciso (b) ya está. También demostramos en el teorema 8.3 que un árbol con n vértices tiene n − 1 aristas, que corresponde a la segunda parte del inciso (b). b → c Que el número de vértices es uno más que el número de aristas está en el antecedente, por lo que está en el consecuente. Nos falta demostrar que es acı́clica. Como es conexa, existe una trayectoria entre cualesquiera dos vértices. Por contradicción, supongamos que existe un ciclo con k vértices en la gráfica. Como es un ciclo, hay el mismo número de vértices que de aristas en él. Fuera del ciclo se encuentran n − k vértices y, como la gráfica es conexa, debemos poderlos alcanzar desde cualquier vértice del ciclo. Pero necesitamos al menos n − k aristas para alcanzar a esos vértices, lo que nos da un total de al menos n aristas; y por el antecedente sabemos que la gráfica tiene exactamente n − 1 aristas; de donde la suposición de que existe al menos un ciclo no se cumple, por lo que la gráfica es acı́clica. 316 Árboles c → d Sabemos que T es acı́clica y con n vértices y n − 1 aristas. Debemos demostrar que es conexa. Como no hay ciclos no hay más de una trayectoria entre cualesquiera dos vértices. Ahora tenemos que demostrar que al menos hay una. Haremos la demostración por inducción en el número de vértices. Si el número de vértices es uno, T es conexa y acı́clica y tiene cero aristas. Por vacuidad se cumple que hay una trayectoria entre cualesquiera dos vértices distintos. Supongamos que se cumple para gráficas con 2 ≤ k < n vértices y veamos para n vértices. Tomemos la gráfica con n vértices. Como es acı́clica, tiene al menos dos vértices de grado 1. Quitemos a uno de ellos y a la arista que lo conecta con la gráfica. En la subgráfica que nos queda tenemos un vértice menos, una arista menos y no hay ciclos. Por la hipótesis de inducción, en esta gráfica existe una única trayectoria entre cualesquiera dos vértices. Ahora le agregamos el vértice que le quitamos, junto con su arista. La única trayectoria a este vértice es pasando por la arista que lo une al resto de la gráfica, por lo que se cumple para toda la gráfica que exista una única trayectoria entre cualesquiera dos vértices. d → e Sabemos que existe exactamente una trayectoria entre cualesquiera dos vértices, que es la definición de que T es conexa. Como esa trayectoria es única, al quitar cualquier arista deja de haber trayectoria entre los extremos de esa arista. e → f Como T es conexa, quiere decir que hay una trayectoria entre cualesquiera dos vértices. Si hubiese algún ciclo, podrı́amos quitar una arista de ese ciclo sin que la gráfica se desconectara, pero no es ası́, ya que en el antecedente decimos que si se quita una arista se desconecta. De donde es acı́clica. Si agregamos una arista entre cualesquiera dos vértices, como ya habı́a una trayectoria entre ellos, se forma una nueva trayectoria, y por lo tanto un ciclo. f → a Debemos demostrar que T es acı́clica y conexa, suponiendo que es acı́clica y que al agregarle cualquier arista se forma un ciclo. Que es acı́clica ya está. Si al agregar una arista x–y, para x e y cualesquiera, se forma un ciclo, quiere decir que ya habı́a una trayectoria entre x e y. Y la definición de que es conexa es que para cualesquiera dos vértices haya siempre una trayectoria enrtre ellos. Con este teorema dejamos ya varias caracterizaciones de árboles con las que podemos jugar para encontrar otros resultados. Ejercicios 8.1.1.- Demuestra directamente que d → c. 8.1.2.- ¿Cuántas aristas hay en un árbol con 15 vértices? 8.1.3.- ¿Cuántos vértices hay en un árbol con 20 aristas? 317 8.1 Caracterización 8.1.4.- Determina si las siguientes gráficas son o no árboles. Justifica tu respuesta. (c) (b) (a) a a b c d e f g h b a c d e (d) a (e) c b a e d e d g f c b f g h 8.1.5.- La Secretarı́a de comunicaciones quiere construir una red ferroviaria que una a varias comunidades madereras en el estado de Oaxaca para que puedan transportar la madera a la Ciudad de Oaxaca. Los puntos de acopio van a estar situados equidistantes y se pueden ver en el siguiente mapa. Diseña las lı́neas del ferrocarril para que se construya lo más económico posible. ¿Hay una única solución? 1 3 2 Oaxaca O 4 5 6 7 318 Árboles 8.1.6.- Dibuja una gráfica que no sea un árbol para la cual el número de vértices es uno más que el número de aristas. 8.1.7.- Dibuja una gráfica que no sea un árbol que tenga exactamente dos vértices de grado 1. 8.1.8.- ¿Cuál es el máximo número de vértices en una gráfica conexa con n aristas? 8.1.9.- ¿Cuál es el mı́nimo número de vértices en una gráfica conexa con n aristas? 8.2. Árboles generadores Recordemos la definición 5.14 de la página 223, que repetimos acá: Definición 8.2 (subgráfica) Una gráfica G′ = (V ′ , E ′ ) es subgráfica de una gráfica G = (V, E) si es que V ′ ⊆ V y E ′ ⊆ E. Es claro que toda gráfica es subgráfica de sı́ misma. Muchas veces queremos conectar un conjunto de puntos entre sı́ de la manera más económica posible. Es decir, queremos encontrar una subgráfica de la gráfica original cuyas aristas toquen todos los vértices y que no tenga ciclos. Los ciclos, de cierta manera, son un gasto redundante porque tenemos más de una manera de alcanzar a los vértices en el ciclo. Definición 8.3 (árbol generador) Un árbol generador de una gráfica G = (V, E) es una subgráfica conexa y acı́clica de G, T = (V ′ , E ′ ), tal que V ′ = V , E ′ ⊆ E. Veamos las gráficas en las figuras 8.6 y 8.7. En la gráfica de la figura 8.6, la subgráfica 8.6(b) corresponde a un árbol generador de la gráfica en 8.6(a), ya que es conexa, acı́clica y cubre todos los vértices de 8.6(a). Las dos gráficas de la figura 8.7, en cambio, no corresponden a árboles generadores de la gráfica 8.6(a) en la figura 8.6. La gráfica 8.7(a) no es acı́clica y por lo tanto no es árbol. La gráfica 8.7(b), aunque es acı́clica, no es conexa, por lo que tampoco corresponde a un árbol generador. Hay varias maneras de construir un árbol generador. Si la gráfica no tiene pesos, por ejemplo, podemos usar el algoritmo que dimos para BFS para determinar un árbol generador de la gráfica. Recuerden que en la subgráfica de distancias resultante, cada vértice tiene únicamente un predecesor, que es el padre en el árbol generador. No tiene ciclos, pues cuando se llega a un vértice y no es la primera vez, esta arista nos define una trayectoria al vértice en cuestión, distinta de la que se habı́a determinado antes; pero esta arista no se 319 8.2 Árboles generadores Figura 8.6 Árbol generador en una gráfica G (a) G = (V, E) (b) T = (V, E ′ ) Figura 8.7 Subgráficas que no son árboles generadores de G (a) Tiene ciclos (b) No es conexa incluye en el árbol, por lo que no se cierra el ciclo. Este árbol incluye a todos los vértices de la gráfica, si la gráfica originalmente es conexa, pues llega a los vértices adyacentes al inicio, a los adyacentes a éstos, y ası́ sucesivamente. Y es conexa ya que siempre estamos recorriendo caminos desde el origen. En la figura 8.8 en la siguiente página mostramos un recorrido BFS en una gráfica y el árbol generador que produce. Las aristas están etiquetadas con el ordinal en que fueron usadas. Si la gráfica tiene pesos, lo mismo podemos decir del algoritmo de Dijkstra, que construye un árbol generador de trayectorias más cortas. Hay otros algoritmos que también son muy famosos, como el algoritmo de exploración en profundidad (Depth First Search, DFS) 320 Árboles que también determinan árboles generadores de las gráficas sobre las cuales se ejecutan. Lo veremos en la siguiente sección. Figura 8.8 Árbol generador determinado por BFS, con origen en el vértice A (a) Gráfica original conexa B C (b) Árbol generador con vértice origen A D E 6 B C 5 15 D E 17 8 F G 16 11 F 1 7 9 G 2 H I A H 12 I 3 A 10 18 4 J K 13 J 21 K 14 L M N 26 L 27 O Q P R M 29 O 30 P 22 28 24 (c) Gráfica mostrada como un árbol A0 C1 B2 F1 D2 E3 G2 K2 Q3 P4 R3 I1 J1 H2 N2 M3 19 N 20 23 Q 25 R 321 8.3 Búsqueda en profundidad (DFS) Ejercicios 8.2.1.- ¿Cuántas aristas se tienen que eliminar de una gráfica conexa con n vértices y m aristas para producir un árbol generador? 8.2.2.- Para las siguientes gráficas, dibuja un árbol generador para cada una de ellas. (a) (b) a b c a b c d e f g h i j e d (c) a d (d) e g c b e f h i a b c f g h i j k d l 8.2.3.- Supongamos que tenemos dos árboles generadores para una misma gráfica. ¿Estos árboles tienen algún vértice en común? Si sı́, justifica. Si no, da un contraejemplo. 8.2.4.- ¿Cuántos árboles generadores distintos hay para un ciclo con n vértices, n ≥ 3? ¿Cuántos hay si consideramos árboles isomorfos entre sı́? 8.2.5.- Muestra que una arista que al removerla desconecta a una gráfica conexa forma parte de todo árbol generador de la gráfica. 8.2.6.- Dibuja el árbol generador que se forma aplicando el algoritmo BFS a Kn . 322 Árboles 8.3. Búsqueda en profundidad (DFS) Supongamos que tenemos un laberinto del que queremos salir y este laberinto está representado en una gráfica de la siguiente manera: i. Habrá un vértice para la entrada del laberinto y uno para la salida. ii. Cada esquina donde se pueda optar por más de un camino la representamos con un vértice. iii. Cada punto en el que ya no se pueda continuar corresponde también a un vértice. iv. Las aristas corresponden a los senderos dentro del laberinto. Tenemos que tener una disciplina de cómo recorrer el laberinto para salir lo antes posible. Si siguiéramos la estrategia BFS no ganarı́amos mucho, pues si la salida está a la máxima distancia posible desde la entrada, habrı́amos revisado todos los vértices en capas anteriores antes de llegar a ella. Otra estrategia, que es la que sigue DFS, es bajar por un camino hasta que ya no se pueda seguir por él; marcamos cada vértice por el que vamos pasando y si vamos hacia adelante, nunca vamos a un vértice que ya ha sido marcado (visitado). Cuando llegamos a un punto ciego – todos los vértices adyacentes ya están marcados – regresamos al vértice desde el que se exploró esta arista y tratamos de tomar otro camino. Si no podemos, porque ya no haya aristas sin usar o porque todas las aristas llevan a vértices ya visitados, regresamos otro nivel. La exploración termina cuando, habiendo regresado a la raı́z, ya no quedan aristas sin usar, o alcanzamos la salida del laberinto. En la figura 8.10 mostraremos la ejecución de DFS sobre la gráfica en la figura 8.9. Cada subfigura nos irá mostrando el recorrido hasta que se encuentre un punto ciego. Figura 8.9 Árbol generador determinado por DFS, con origen en el vértice A B H C I D E F G A J L M N O P Q K R 323 8.3 Búsqueda en profundidad (DFS) Figura 8.10 Árbol generador determinado por DFS, con origen en el vértice A (a) 2 B3 3 26 C2 7 6 (b) D F 1 29 E B3 G 3 2 C2 26 7 6 D H 4 I 5 G 29 24 A 5 F 1 24 4 E 1 30 H 4 4 I 5 A1 5 12 30 12 J K J9 8 13 K 10 11 L M 20 18 O Q P I L6 20 16 15 P: ACBH 22 N 9 R M7 18 O13 19 2 C2 N8 P 12 14 22 16 15 Q11 17 R P : A C B H LMN J K Q P O punto ciego punto ciego (c) B3 10 (d) 26 D 2 B3 E C2 26 D16 27 E 17 28 25 3 7 6 F 1 G 29 3 7 6 1 24 H 4 4 I 5 A 30 H 4 4 I 5 5 12 J9 8 L6 20 M7 18 O13 19 P 12 10 15 17 K 10 14 22 16 J9 8 L6 9 20 21 P : A C B H LMN J K Q R punto ciego 30 23 13 K 10 11 N8 Q11 A1 12 13 11 9 G18 29 24 1 5 F 15 R14 M7 18 O13 19 P 12 10 15 17 N8 14 22 16 Q11 21 R14 P : A C B H LMN J K F D E G punto ciego 324 Árboles Como ya mencionamos, en la figura 8.10 mostramos la ejecución del algoritmo DFS. Cada subfigura corresponde al avance de la exploración hasta que se encuentra un vértice por el que ya no se puede continuar – marcado al final de la lista –. En este punto, retrocede – marcado con flecha punteadas en gris claro – hasta un vértice desde el que pueda volver a salir. Durante el recorrido iremos colocando a los vértices una etiqueta que corresponderá al orden en que el vértice fue descubierto. También anotaremos en las aristas el orden en el que fueron consideradas. Asimismo, mantendremos un conjunto con aquellos vértices que ya han sido visitados y otro con las aristas que se van eligiendo para el árbol generador. Para decidir el orden en que se van visitando los vértices usaremos lo que se conoce como una pila: es una estructura en la que el último que entra es el primero que sale (Last In First Out, LIFO), que llamaremos P. Las operaciones válidas en una pila son pop, que elimina al último vértice que se agregó, push(v) que ingresa al vértice v en la pila y top que informa cuál es el elemento que se encuentra en el tope, el último que fue agregado. Si al buscar vértices adyacentes sin marcar hay varios vértices que se pueden seleccionar, se elegirá al que tenga la etiqueta menor en orden alfabético. El árbol generado por este recorrido se encuentra en la figura 8.11. Procederemos a explicar cada una de las subfiguras que representan al recorrido. Figura 8.11 Árbol generado por DFS en la gráfica de la figura 8.11 F 15 L6 A1 C2 B3 M7 N8 J9 K 10 D16 E 17 G18 R14 Q11 H4 I5 P 12 O13 En la gráfica de la subfigura 8.10(a), se recorre desde A hasta llegar al vértice I; para este vértice, todas las aristas tienen como destino a un vértice ya visitado, por lo que es un punto ciego. Se retrocede hasta el vértice H que tiene todavı́a aristas disponibles. En la gráfica de la subfigura 8.10(b), se recorre desde H hasta el vértice O, siguiendo siempre el orden dado por el alfabeto. En este punto, la única arista disponible de O va hacia L, que ya fue visitado, por lo que O es un punto ciego y se procede a regresar. En P 8.3 Búsqueda en profundidad (DFS) 325 sucede lo mismo, esto es, que la única arista disponible es a un vértice ya visitado, por lo que se continúa el retroceso. En Q, si bien dos de sus aristas disponibles son a vértices ya visitados (M y N ), la artista hacia R aún no ha sido usada y R no ha sido descubierto, por lo que la exploración se continúa desde Q. En la gráfica de la subfigura 8.10(c), se recorre la arista que va de Q a R, pero como la única arista disponible de R es hacia K que ya fue descubierto, R corresponde a un punto ciego, por lo que hay que retroceder para encontrar algún vértice que tenga aristas disponibles a vértices aún no descubiertos. Este retroceso se hace sobre la pila, en orden inverso a como fueron ingresando los vértices, y nos deja en el vértice K que aún tiene aristas disponibles a vértices que todavı́a no han sido visitados. En la gráfica de la subfigura 8.10(d) se encuentra la pila, antes de retroceder. Como ya todas las aristas fueron usadas y los vértices visitados, el retroceso se lleva a cabo hasta que se llega al vértice origen, que es el vértice A, que ya no tiene aristas disponibles. Veamos a continuación más detenidamente el algoritmo. Algoritmo de búsqueda a profundidad (DFS) Objetivo: Dada una gráfica G = (V, E) conexa y un vértice de salida s, construir un árbol generador para G, que realice la exploración a profundidad. Datos: La gráfica G = (V, E) – representada por su lista de adyacencias – y un vértice s que pertenezca a G, que será el vértice inicial en la exploración. Salida: Una gráfica G′ = (V, E ′ ) que corresponda a un árbol generador de G. Esta gráfica deberá tener anotado lo siguiente: (a) El orden en que los vértices son alcanzados (v.etiq). (b) Una referencia al vertice desde el que se les alcanzó por primer vez (v.π). (c) La marca de que ya fueron alcanzados (v.visitado). Estructuras de datos: 1. La gráfica representada con listas de incidencia. 2. Una pila P para dar el orden en que se usan los vértices. 3. Cada vértice quedará apuntando a su predecesor y de esta forma se va armando el árbol. 4. La lista de aristas donde se marcará a cada una cuando ya haya sido usada. Método: Se encuentra en el listado 8.1. Listado 8.1 Algoritmo de búsqueda a profundidad (DFS) 1 /* Inicio : */ 2 ∀v ∈ V : 3 v.visitado ← no 4 v.π ← ∅ 5 v.etiq ← 0 6 ∀e ∈ E 7 e.usada ← no 1/2 326 Árboles Listado 8.1 Algoritmo de búsqueda a profundidad(DFS) 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 2/2 / * Marcar a l v é r t i c e i n i c i a l * / s.etiq ← 1 s.visitado ← ya k ← 2 / / i n i c i a r el contador P.push(s) / * E t i q u e t a r e l r e s t o de l o s v é r t i c e s * / M i e n t r a s que P = 6 ∅: x ← P.tope M i e n t r a s haya a l g ún v é r t i c e v adyacente a x s i n marcar : v.visitado ← ya P.push(v) e = xv e.usada ← ya v.π ← x v.etiq ← k + + x ← P.tope / * F i n c i c l o M i e n t r a s haya v é r t i c e s . \ . \ . * / / * Ya no hay v é r t i c e s a d y a c e n t e s a x s i n v i s i t a r * / P.pop / / Ya s e p r o c e s a r o n t o d o s l o s v é r t i c e s a l c a n z a b l e s d e s d e s Todos l o s v é r t i c e s e s t án marcados : E l á r b o l generador e s t á dado por l a s r e f e r e n c i a s a v.π y tenemos un á r b o l generador de G No todos l o s v é r t i c e s e s t án marcados : G no es conexa y no t i e n e á r b o l generador Es interesante observar (en la figura 8.11) la forma que toma el árbol generador construido por DFS. Notemos que las ramas son mucho más profundas que en BFS; por eso este algoritmo recibe el nombre de búsqueda en profundidad. Ejercicios 8.3.1.- Para las siguientes gráficas, siguiendo los algoritmos respectivos, construye los árboles generadores dados por BFS y DFS. 327 8.3 Búsqueda en profundidad (DFS) (a) C (b) F A B D B G (c) D A B F E C A E D E C G F 8.3.2.- Encuentra el árbol generador DFS de las siguientes gráficas: (a) (b) B A F G C E B D H A C D F E H G 8.3.3.- Explica por qué en el ejercicio anterior, a pesar de que son gráficas isomorfas entre sı́, el árbol generado por DFS no es el mismo. 8.3.4.- Usando el algoritmo DFS en los dos ejercicios anteriores, para cada una de las gráficas lista las aristas hacia atrás que se van generando. 8.3.5.- El Jefe de Gobierno de la Ciudad de México tiene identificada una colonia en la que las calles son muy angostas, pero tienen tráfico en ambos sentidos. Quiere hacer las calles de un solo sentido pero no sabe cómo asignar los sentidos de tal manera que se pueda llegar de cualquier lugar a cualquier otro siguiendo el sentido de las calles. A continuación se encuentra un mapa de las calles de la colonia. 328 Árboles A C B D E F G H I J K L M N O Un estudiante de ciencias de la computación le comentó al Jefe de Gobierno que se podı́a asignar dirección a las calles usando DFS. Determina la dirección de las calles usando este algoritmo y ve si es posible llegar de cualquier punto a cualquier otro usando esta dirección. Nota: se tiene que asignar dirección también a las aristas que cierran ciclos, aunque se lleve a cabo el regreso al vértice desde el que se explora una arista que lleva a un vértice ya descubierto. 8.3.6.- ¿Cómo caracterizarı́as a la gráfica que produce DFS para poder determinar que se puede llegar de cualquier vértice a cualquier otro? 8.3.7.- Para una misma gráfica, ¿pueden coincidir los árboles generadores creados por DFS y BFS? ¿Cuáles son las condiciones en las que esto sucede? 8.4. Árboles generadores de peso mı́nimo Al ver exploración en gráficas, en particular los algoritmos BFS y de Warshall, revisamos también el caso de gráficas con peso en las aristas y vimos varios algoritmos para resolver este caso. Tanto BFS como DFS construyen un árbol generador de la gráfica. Pasamos ahora a observar árboles generadores sobre gráficas con peso en las aristas. Cabe aclarar que el árbol de distancias que construye el algoritmo de Dijkstra es también un árbol generador. La diferencia con los árboles generadores de peso mı́nimo es que en este último caso lo que buscamos minimizar es la suma total de pesos de las aristas que conforman el árbol y no el peso de la única trayectyoria a cada uno de los vértices. Este algoritmo 329 8.4 Árboles generadores de peso mı́nimo es muy útil, por ejemplo, si tratamos de conectar una red de computadoras buscando que el costo total de la red sea mı́nimo. En el caso de BFS por ejemplo, donde todas las aristas tienen peso uniforme, el árbol construido por BFS (o para el caso, también por DFS) es un árbol de peso mı́nimo, ya que el peso total es n − 1. Sin embargo, en el caso del algoritmo de Dijkstra el árbol de trayectorias más cortas construidas puede no ser un árbol de pesos mı́nimos, como se puede observar en la gráfica de la figura 8.12, que se encuentra abajo. Cabe notar que el árbol de peso mı́nimo tiene un peso mayor que la trayectoria del origen al destino. Esto se debe a que en la trayectoria más corta pueden no incluirse todos los vértices, mientras que en el árbol generador de peso mı́nimo sı́ tienen que aparecer todos los vértices. Adicionalmente, en el árbol de peso mı́nimo no importa cuál es el origen de la exploración. En la gráfica de la figura 8.12 se contrastan un árbol de trayectorias más cortas con uno de peso mı́nimo. El peso del árbol en la gráfica 8.12(a) es 18, mientras que el árbol de peso mı́nimo tiene peso total 11. En cambio, la longitud de la trayectoria de t a s en la gráfica 8.12(a) es 5, mientras que en la gráfica 8.12(b) es 10. Se puede ver que cada árbol generador cumple su cometido, aunque pudiera darse el caso de que coincidieran. Figura 8.12 Árbol generador de trayectorias más cortas vs. de peso mı́nimo (a) δ(t, s) = 5; peso(T ) = 18 s 6 1 x 7 2 s 1 w 4 3 2 4 3 z 4 x 4 w 3 2 u 4 v 2 1 y 6 1 t 4 3 3 u 1 4 4 v 4 2 8.4.1. 1 t 0 (b) δ(t, s) = 10; peso(T ) = 11 3 1 y 2 z Algoritmo de Prim para árboles de peso mı́nimo El algoritmo de Prim para árboles de peso mı́nimo es un algoritmo ávido (greedy) que toma decisiones localmente. Inicia con un vértice cualquiera de la gráfica y mete a una cola de prioridades a las aristas incidentes en ese vértice que conecten con un vértice que todavı́a no esté en la cola, con el orden dado por el peso de la arista. En todo momento se encuentra al frente de la cola aquel vértice – con la arista con la que se llegó a él – que tenga el menor peso asociado a la arista. Toma al vértice al frente de la cola e inserta a la cola de prioridades todos aquellos vértices en el extremo opuesto de cada arista incidente al vértice elegido de la cola. Una vez incluidos los nuevos vértices, saca al que acaba de ser 330 Árboles el centro de acción. Prosigue con este proceso hasta que no haya ya vértices sin incluir en la cola. Conforme se revisan los vértices adyacentes, se sustituyen aristas si es que se encuentra alguna de menor peso que incida en algún vértice que todavı́a está en la cola. Se puede demostrar, aunque no es materia de este material, que este algoritmo construye un árbol generador (incluye a todos los vértices en la lista) y que éste es de peso mı́nimo. El algoritmo formal se encuentra a continuación. Objetivo: Dada una gráfica G = (V, E; w), encontrar un árbol generador de peso mı́nimo T = (V, E ′ ⊆ E; w), esto es, si T ′ = (V, E ′′ ⊆ E; w) es cualquier otro árbol generador de G, tenemos X e∈E′ w(e) ≤ X w(e) e∈E′′ Datos: La gráfica G = (V, E; w). Salida: El árbol generador de peso mı́nimo. Estructuras de datos: 1. La gráfica, representada con listas de adyacencia. 2. Una tabla donde apuntaremos, para cada vértice, quién es su predecesor y cuál es la arista que lo incluyó. 3. Una lista donde iremos colocando las aristas que van conformando el árbol. 4. Una cola de prioridades donde iremos colocando los vértices conforme los vamos alcanzando. Ingresa a la cola un vértice con el peso de la arista que lo hizo ingresar. La cola es una cola de prioridades, donde podemos elegir al que tenga la mayor prioridad (el menor peso para la arista). Conforme se van examinando aristas, si se encuentra una de peso menor para un vértice en la cola, se modifica este peso. Se elige al vértice que tiene el menor peso anotado. Método: El algoritmo como se describió al inicio de esta sección se encuentra en el listado 8.2 de la siguiente página. 8.4 Árboles generadores de peso mı́nimo 331 Listado 8.2 Algoritmo de Prim para árbol generador de peso mı́nimo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 / * I n i c i a l i z a c i ón : * / ∀v ∈ V : v.π ← nulo v.peso ← ∞ v.arista ← nulo; s.peso ← 0; s.π ← nulo Cp ← hsi / * P r o c e s a r a l que e s t é a l f r e n t e de l a c o l a de p r i o r i d a d e s * / M i e n t r a s Cp 6= ∅ u ← Cp .f rente S i u.arista 6= nulo T ← T ∪ u.arista M i e n t r a s u.listaAdy 6= ∅ v ← u.listaAdy.siguiente e = uv w ← e.peso u.listaAdy ← u.listaAdy − {v} S i v.peso = ∞ Cp ← Cp + v S i v.peso > w v.peso ← w v.π ← u v.arista ← e / * F i n u.listaAdy == ∅ * / 27 28 29 30 31 32 Cp ← Cp − {u} / * Cp == ∅ * / S i |T | = |V | − 1 : entonces T es e l á r b o l generador de G de peso mı́nimo S i no : l a g r á f i c a no es conexa . Éste es un algoritmo sencillo de implementar y corresponde, como ya dijimos, a un algoritmo glotón. Veamos la ejecución del algoritmo sobre la misma gráfica que hemos utilizado hasta ahora para ver árboles generadores, pero con pesos asignados a las aristas. 332 Árboles Figura 8.13 Árbol generador de peso mı́nimo (algoritmo de Prim) (a) Gráfica original conexa 5 B 3 C (b) Árbol de peso mı́nimo 2 D E 3 7 F 5 4 5 3 C D 4 1 2 B G I 7 2 3 1 4 H I 7 1 M K 6 5 2 O P 7 8 J 3 6 L 3 Q R 3 1 M 5 4 4 1 4 K 6 3 N 2 A 6 3 3 G 4 J L F 5 4 4 3 4 7 2 A 6 E 1 2 H 2 2 O P 7 2 4 8 N 6 4 Q 3 R Veamos paso a paso la ejecución del algoritmo. Para no extendernos demasiado mostraremos la cola a intervalos regulares. Empezamos con la cola de prioridades con el vértice D y agregamos a ella todos los vértices adyacentes a D con el peso de la arista anotado: Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (1/8) (a) Centro de acción: D B 5 3 C D 2 E 4 1 2 3 5 4 F 7 G 2 H 7 I 6 A 4 1 4 J 3 K 6 3 L 3 M 5 O 2 7 P 1 2 4 8 N 6 4 Q 3 Cola de prioridades R desde:peso v :0 D:1 D:2 D:3 D F E C orden/salida 1 2 3 4 333 8.4 Árboles generadores de peso mı́nimo Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (2/8) (b) Centro de acción: F 5 B 3 C D 2 E 2 3 F 5 4 Cola de prioridades 4 1 7 G 2 H 7 I A 6 desde:peso D:1 D:2 v F E 1 4 4 orden/salida J 3 3 2 F:2 D:3 F:4 F:7 A C K G 4 5 6 7 K 6 3 3 L M 5 2 O 7 P 1 8 N 2 6 4 Q 4 R 3 (c) Centro de acción: E B 5 3 C D 2 E 2 3 F 5 4 7 G 2 H 7 I 6 A 4 1 4 K 6 3 L M 5 O 2 7 P 1 2 4 desde:peso D:2 v E orden/salida J 3 3 Cola de prioridades 4 1 8 N 6 4 Q 3 R 3 F:2 D:3 F:4 E:4 A C K G 4 5 6 7 334 Árboles Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (3/8) (d) Centro de acción: A B 5 3 C D 2 E 2 3 F 5 4 7 G 2 H I 7 A 6 Cola de prioridades 4 1 1 4 4 desde:peso F:2 v A orden/salida J 3 4 D:3 F:4 E:4 A:4 A:6 C K G J I 5 6 7 8 9 K 6 3 L 3 M 5 2 O P 7 1 8 N 2 6 4 Q 4 R 3 (e) Centro de acción: C B 5 3 C D 2 E 2 3 F 5 4 7 G 2 H 7 I A 6 4 1 4 J K 6 3 3 M 5 O 2 7 P 1 2 4 desde:peso D:3 v C orden/salida 3 L Cola de prioridades 4 1 8 N 6 4 Q 3 R 5 F:4 E:4 A:4 C:4 C:5 K G J I B 6 7 8 9 10 335 8.4 Árboles generadores de peso mı́nimo Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (4/8) (f) Centro de acción: K B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G orden/salida 2 H I 7 A 6 desde:peso F:4 v K 1 4 6 C:4 C:5 K:6 G J I B R 7 8 9 10 11 K:1 A:4 K:8 4 Q J 3 K 6 12 3 L 3 M 5 2 O P 7 1 8 N 2 6 4 Q 4 R 3 El siguiente centro de acción es G, pero como no tiene aristas sin usar incidentes en él, simplemente se le saca de la cola, ası́ que el siguiente centro de acción es el vértice J. (g) Centro de acción: J B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H 7 I A 6 1 4 4 orden/salida J 3 K 6 3 L 3 M 5 O 2 7 P 1 2 4 desde:peso A:4 v J 8 N 6 4 Q 3 R 8 J:3 C:4 C:5 K:6 K:8 N I B R Q 9 10 11 12 13 336 Árboles Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (5/8) (h) Centro de acción: N B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H I 7 A 6 1 4 4 N:1 C:4 N:4 C:5 K:6 M I Q B R 10 11 12 13 14 desde:peso N:1 M:2 M:2 M:3 C:4 v M Q P L I C:5 orden/salida 10 15 orden/salida J 3 desde:peso J:3 v N 9 K 6 3 L 3 M 5 2 O P 7 1 8 N 2 6 4 Q 4 R 3 (i) Centro de acción: M B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H 7 I A 6 1 4 4 R J 3 K 6 16 3 L 3 M 5 O 2 7 P 1 2 4 K:6 8 N 6 4 Q 3 R 11 12 13 14 B 337 8.4 Árboles generadores de peso mı́nimo Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (6/8) (j) Centro de acción: Q B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G orden/salida 11 2 H I 7 A 6 desde:peso M:2 M:2 M:3 Q:3 v Q P L R 12 13 C:4 C:5 I B 15 16 C:4 C:5 P:7 I B O 15 16 17 14 1 4 4 J 3 K 6 3 L 3 M 5 2 O P 7 1 8 N 2 6 4 Q 4 R 3 (k) Centro de acción: P B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G orden/salida 12 2 H 7 I A 6 1 4 4 J 3 K 6 3 L 3 M 5 O 2 7 P 1 2 4 desde:peso M:2 M:3 Q:3 v P L R 8 N 6 4 Q 3 R 13 14 338 Árboles Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (7/8) (l) Centro de acción: L B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H I 7 A 6 desde:peso M:3 Q:3 v L R L:3 C:4 C:5 L:5 H I B O orden/salida 13 15 16 17 18 14 1 4 4 J 3 K 6 3 L 3 M 5 2 O P 7 1 8 N 2 6 4 Q 4 R 3 El siguiente centro de acción es R, pero como ya no tiene aristas disponibles, simplemente se le saca de la cola y queda H al frente de la cola. (m) Centro de acción: H B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H 7 I A 6 1 4 4 J 3 K 6 3 L 3 M 5 2 O 7 P 1 2 4 8 N 6 4 Q 3 R desde:peso L:3 v H H:2 C:4 L:5 B I O orden/salida 15 16 17 18 339 8.4 Árboles generadores de peso mı́nimo Figura 8.14 Árbol generador de peso mı́nimo (algoritmo de Prim) (8/8) (n) Centro de acción: B B 5 3 C D 2 4 1 2 3 F 5 4 Cola de prioridades E 7 G 2 H 7 I A 6 desde:peso v H:2 B:3 L:5 B I O orden/salida 16 17 18 1 4 4 J 3 K 6 3 L 3 M 5 2 O 7 P 1 2 4 8 N 6 4 Q 3 R El siguiente centro de acción es I, pero como ya no hay aristas disponibles no modifica ya nada en el árbol; lo mismo sucede cuando O es centro de acción. En este momento se vacı́a la cola de prioridades y el algoritmo de Prim termina. En todas las subgráficas se presentó sombreado el centro de acción, que es aquel vértice que se encuentra al frente de la cola de prioridades y desde el que se van a explorar aquellas aristas que no hayan sido ya exploradas. La simbologı́a que se utilizó es la siguiente: Arista aún no considerada. Arista del árbol generador de peso mı́nimo. Arista incluida y después eliminada. Arista no incluida en el árbol generador de peso mı́nimo. La gráfica, presentada como árbol y únicamente con las aristas que quedaron en el mismo, queda como se ve en la figura 8.15 (en la siguiente página) y tiene un peso total de 44 unidades. Es importante mencionar que éste no es el único árbol posible de peso mı́nimo, ya que existen otras combinaciones posibles para árboles en los cuales la suma de los pesos de las 340 Árboles Figura 8.15 Árbol generador de peso mı́nimo (Prim) C Peso total del árbol = 44 3 D 2 E 1 4 F K 1 Q G 3 R 2 2 A 4 j 3 N 1 M 2 P 3 3 L H 2 B 3 I 5 O aristas también dé el mı́nimo de 44 unidades. Esto depende en gran medida del algoritmo que se utilice para mantener la cola de prioridades. Cuando en la cola de prioridades se encuentran dos vértices con el mismo peso, el algoritmo puede respetar el orden en que entraron a la cola; puede optar por el vértice con el nombre lexicográficamente menor; o simplemente elegir aleatoriamente cuál de los vértices con peso igual colocar al frente de la cola. En el ejemplo que vimos se eligió el criterio de respetar el orden de llegada a la cola, además de que cuando se modificó el peso de un vértice para moverlo hacia el frente de la cola, se le colocaba después de cualquier otro vértice que ya tuviera ese mismo peso. Un ejercicio interesante es observar cómo se comparan un árbol generador de peso mı́nimo y uno de distancias, generado por el algoritmo de Dijkstra. Para hacer esta comparación mostramos en la figura 8.16 el árbol generador de distancias de Dijkstra aplicando el algoritmo a la misma gráfica. Como se puede ver, los árboles son muy distintos, aun teniendo el mismo vértice como origen. Inmediatamente se puede observar que el árbol de distancias es más bajo y ancho, porque, precisamente, el algoritmo de Dijkstra busca minimizar la distancia desde la raı́z a cualquiera de los vértices de la gráfica: busca que todas las trayectorias sean lo más cortas posibles. Por ejemplo, la distancia del vértice D al vértice I es de 7, mientras que si seguimos la trayectoria dada por el árbol generador de peso mı́nimo, la longitud de la trayectoria del vértice D al vértice I es de 22 unidades. Otro comentario interesante es el hecho de que aunque consideremos otro vértice origen para el árbol generador de peso mı́nimo, existirá un árbol generador de peso mı́nimo con origen en D que contenga a las mismas aristas. Esto es, si le quitamos la dirección a las aristas del árbol generador de peso mı́nimo, podemos usar a cualquier otro vértice y “colgar” de ahı́ el árbol. Eso, en cambio, no sucede con el árbol de distancias, pues éstas están determinadas para un origen particular. 341 8.4 Árboles generadores de peso mı́nimo Figura 8.16 Árbol generador de trayectorias más cortas (algoritmo de Dijkstra) (a) Gráfica original conexa B 5 3 C D (b) Árbol de distancias de Dijkstra 2 E 3 5 4 3 C D 4 1 2 5 B F 7 I 7 6 G 2 3 5 4 1 4 H I 7 6 4 5 O 1 M 2 P 7 2 4 A K 3 6 J 3 3 F 4 3 8 N 6 3 L 5 4 Q R 3 1 M 2 O P 7 2 4 8 N Q 3 1 E2 K5 6 R11 8 4 Q13 F1 2 1 D0 A3 4 J7 3 N 10 1 M 11 3 4 I7 5 B8 2 H 10 3 L13 5 O18 6 4 G6 C3 1 K 6 (c) Árbol generador de Dijkstra 2 G 4 J L 4 7 2 A 3 E 1 2 H 2 2 P 13 R 342 Árboles Como ya mencionamos, el árbol de trayectorias más cortas tiene menor profundidad que el de peso mı́nimo, mientras que éste tiene mayor amplitud que aquél. Es importante notar que el peso total del árbol es de 56 unidades, bastante más que el árbol de peso mı́nimo. Sin embargo, el vértice más lejano del origen, está a una distancia de 18 unidades (O), mientras que ese mismo vértice está a distancia de 19 unidades del origen en el árbol generador de peso mı́nimo. El algoritmo de Prim para árboles generadores de peso mı́nimo es bastante eficiente. El único costo es, realmente, el de mantener la cola de prioridades, ya que siempre debe tener al frente al vértice al que se llega con la arista de menor peso. Veamos paso a paso la ejecución del algoritmo de Prim con una gráfica más sencilla que las que hemos visto en esta sección. Ejemplo 8.1. Apliquemos el algoritmo de Prim para árboles generadores de peso mı́nimo en la gráfica de la figura 8.17. Usaremos como vértice origen al vértice u. Figura 8.17 Otro ejemplo para el algoritmo de Prim e1 u e4 e3 e2 v e5 z e8 e6 w e7 x Pasos 2 a 7: v u v w x z v.π v.peso v.arista lista de adyacencias nulo 0 nulo →v→z→w nulo ∞ nulo →u→z→x nulo ∞ nulo →u→z→x nulo ∞ nulo →v→z→w nulo ∞ nulo →u→v→w→x Cp = h(u, 0, ∅)i U so ei e1 e2 e3 e4 e5 e6 e7 e8 u v e.peso u v 1 u w 4 u z 2 v z 3 v x 3 w z 3 w x 1 x z 2 343 8.4 Árboles generadores de peso mı́nimo Pasos 12 a 14 e1 u e4 e3 e2 v e5 z e8 e6 w x e7 Pasos 16 a 27 para v, z y w v v.π v.peso v.arista lista de adyacencias u nulo 0 nulo ∅ v u 1 e1 →u→z→x w u 4 e2 →u→z→x x nulo ∞ nulo →v→z→w z u 2 e3 →u→v→w→x U so ei √ e1 √ e2 √ e3 e4 e5 e6 e7 e8 Cp = h(u, 0, ∅), (v, 1, u), (z, 2, u), (w, 4, u)i Paso 28 Cp = h(v, 1, u), (z, 2, u), (w, 4, u)i Pasos 12 a 14 (v, 1) está al frente de la cola, por lo que tenemos: e1 u e4 e3 e2 v e5 z e8 e6 w e7 x u v e.peso u v 1 u w 4 u z 2 v z 3 v x 3 w z 3 w x 1 x z 2 344 Árboles Pasos 15 a 27 2 veces Tomamos los dos vértices adyacentes a v con aristas que no han sido usadas, y las estructuras de datos quedan como sigue: v v.π v.peso v.arista lista de adyacencias u nulo 0 nulo ∅ v u 1 e1 ∅ w u 4 e2 →u→z→x x v 3 e5 →v→z→w z u 2 e3 →u→v→w→x U so √ √ √ √ √ Cp = h(v, 1, u), (z, 2, u), (x, 3, v), (w, 4, u)i ei e1 e2 e3 e4 e5 e6 e7 e8 u v e.peso u v 1 u w 4 u z 2 v z 3 v x 3 w z 3 w x 1 x z 2 Terminamos la lista de adyacencias de v, lo quitamos de la cola y queda z al frente de la cola. Pasos 12 a 14 Quitamos a v de la cola y queda z al frente de la misma. Cp = h(z, 2, v), (x, 3, v), (w, 4, u)i Pasos 15 a 27 para las aristas e8 y e6 Con z como centro de acción verificamos a la arista a w (e6 ) y a x (e8 ). Como la arista e8 pesa menos que e5 , cambia los atributos de x y la sustituye en el árbol; lo mismo que pasa con la arista e6 a w, que pesa menos que e2 , por lo que también corrige los atributos de w. v v.π v.peso v.arista lista de adyacencias u nulo 0 nulo ∅ v u 1 e1 ∅ w z 3 e6 →u→z→x x z 2 e8 →v→z→w z u 2 e3 ∅ √ Cp = h(z, 2, u), (x, 2, z), (w, 3, z)i e1 u v e4 e3 e2 U so √ √ √ √ √ √ e5 z e8 e6 w e7 x ei e1 e2 e3 e4 e5 e6 e7 e8 u v e.peso u v 1 u w 4 u z 2 v z 3 v x 3 w z 3 w x 1 x z 2 345 8.4 Árboles generadores de peso mı́nimo Pasos 12 a 14 con x al frente de la cola: La única arista que queda por explorar es e7 , que lleva a w con peso 1; como este peso es menor que el que tenı́a w, se sustituye a la arista e6 por e7 y se ajusta a w para que sea alcanzado por esta arista. Las estructuras de datos quedan como sigue: v v.π v.peso v.arista lista de adyacencias u nulo 0 nulo ∅ v u 1 e1 ∅ w x 1 e7 ∅ x z 2 e8 ∅ z u 2 e3 ∅ U so √ √ √ √ √ √ √ √ Cp = h(x, 2, z), (w, 1, x)i e1 u u v e.peso u v 1 u w 4 u z 2 v z 3 v x 3 w z 3 w x 1 x z 2 v e4 e3 e2 ei e1 e2 e3 e4 e5 e6 e7 e8 e5 z e8 e6 w x e7 Paso 28 Se quita a x de la cola, quedando ya únicamente w. C = h(w, 1, x)i Pasos 15 a 28 Como w ya no tiene ninguna arista sin usar, no entra al ciclo y en la lı́nea 28 saca a w de la cola y deja la cola vacı́a. Esto hace que ya no vuelva a entrar al ciclo en la lı́nea 11 y salta hasta la lı́nea 30. Pasos 30 a 32 Como T = he1 , e3 , e8 , e7 i, que consiste de 4 aristas, una menos que el número de vértices, la gráfica original es conexa y T es un árbol generador de peso mı́nimo. e1 u e4 e3 e2 v e5 z e8 e6 w e7 x 346 Árboles El algoritmo de Prim para árboles generadores de peso mı́nimo es un algoritmo eficiente donde el único problema es mantener la cola de prioridades de tal manera que siempre se pueda elegir fácilmente al siguiente vértice que va a ser el centro de acción – desde el que se van a explorar aristas que no han sido usadas. Como los valores que dan la prioridad pueden cambiar en cada paso, la cola debe actualizarse constantemente. Si esto no se hace de manera adecuada, el costo de elegir el vértice con mayor prioridad en la lı́nea 12 puede subir el costo del algoritmo de manera notoria. 8.4.2. Algoritmo de Kruskal para árboles de peso mı́nimo Otro algoritmo que también obtiene un árbol generador de peso mı́nimo es el algoritmo de Kruskal. En él, las aristas se ordenan por peso y se van tomando en orden (de menor a mayor para peso mı́nimo). A los vértices se les coloca a cada uno en un conjunto que contiene únicamente a ese vértice. Para cada arista que se va tomando (en orden) se verifica si sus extremos están o no en el mismo conjunto. Si es ası́, al agregar la arista se estarı́a cerrando un ciclo, por lo que la arista se desecha. Si los vértices no están en el mismo conjunto, entonces se agrega la arista al árbol que se está construyendo. De esta manera, los vértices en un conjunto forman una subgráfica conexa y acı́clica. Al terminar, si todos los vértices quedaron en el mismo subconjunto, esas aristas conforman el árbol generador de peso mı́nimo. Supongamos que la arista e = uv es la siguiente sin usar en la lista con menor peso de entre las que quedan en ella. Si u y v están en el mismo conjunto, quiere decir que hay un camino entre ellos, y la arista se descarta, pues al agregarla se formarı́a un ciclo. Si u y v están en distintos conjuntos, entonces se agrega la arista y se construye un nuevo conjunto que es la unión del conjunto que contiene a u y el que contiene a v. En el caso en que la gráfica sea conexa, el algoritmo termina cuando todos los vértices están en un único conjunto, pues al agregar cualquier otra arista se formarı́a un ciclo. Si la gráfica no es conexa, el algoritmo alcanzará un punt6o fijo en el que ya no será posible agregar aristas y quedarán tantos subconjuntos como componentes conexas tenga la gráfica. En el listado 8.3 se encuentra a detalle el algoritmo de Kruskal. Algoritmo de Kruskal Objetivo: Encontrar el árbol generador de peso mı́nimo de una gráfica usando el algoritmo de Kruskal. Datos: Una gráfica representada por la lista de sus aristas. Cada arista tiene los siguientes atributos: vértices en los extremos y peso. Salida: El árbol generador de peso mı́nimo de la gráfica, si es que la gráfica original es conexa. 8.4 Árboles generadores de peso mı́nimo 347 Estructuras de datos: i. Una lista de las aristas ordenadas por peso. ii. Subconjuntos de vértices, donde inicialmente cada vértice pertenece a un subconjunto que sólo lo contiene a él. Método: El algoritmo va tomando arista por arista en el orden en que vienen por peso. Si los extremos de la arista se encuentran en conjuntos ajenos, se incluye la arista en el árbol generador y se hace la unión de los subconjuntos que contienen a los vértices. Si ambos vértices se encuentran en el mismo conjunto, entonces la arista se desecha. Dos vértices se encuentran en el mismo subconjunto si hay un camino en el árbol generador de uno al otro. Si en ese momento se agrega la arista que se está inspeccionando, se formarı́a un ciclo. Los pasos precisos se encuentran en el listado 8.3. Listado 8.3 Algoritmo de Kruskal para árbol generador de peso mı́nimo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 / * I n i c i o : o r d e n a r l i s t a de a r i s t a s * / C = h l i s t a ordenada de a r i s t a s i / * C o n s t r u i r l o s s u b c o n j u n t o s p a r a cada v é r t i c e * / ∀v ∈ V c o n s t r u i r Sv / * I n i c i a r e l á r b o l g e n e r a d o r * / T =∅ / * P r o c e s a r l a s a r i s t a s en o r d e n * / M i e n t r a s C 6= ∅ y |T | < |V | − 1 e ← a r i s t a a l f r e n t e de l a c o l a C ← C − {e} Sean e = uv S i Su 6= Sv / / S i e s t án en d i s t i n t o s u b c o n j u n t o Suv ← Su ∪ Sv T ← T ∪ {e} /* . . . Mientras */ S i |T | = |V | − 1 T es e l á r b o l generador de peso mı́nimo S i no G no es conexa . 348 Árboles Ejemplo 8.2. Veamos el árbol generador que se forma con el algoritmo de Kruskal en la gráfica con la que hemos estado trabajando. Mostraremos también cómo se van formando los conjuntos. Figura 8.18 Lista ordenada de aristas al empezar D J A 1 3 6 F, G N, L I, J 1 3 6 K, M M, H K, K 1 3 6 N, B L, C R, F 2 4 7 H, M I,E G, H 2 4 7 P, A K, P I,O 2 4 7 F,M Q, A P, K 2 4 8 Q, D J,N 2 4 E, C Q, B 3 5 D, B C, L 3 5 I,Q O, A 3 5 R, C, Q, Formemos cada vértice en su propio conjunto y veamos el resultado de incluir al árbol todas las aristas con peso 1. como se muestra en la figura 8.19: Figura 8.19 Inclusión de aristas con peso 1 B C D E 1 F H I A J L M O P G 1 1 K N Q R Ahora agreguemos las aristas de peso 2 que no cierren ciclos, como se muestra en la figura 8.20 de la siguiente página. 349 8.4 Árboles generadores de peso mı́nimo Figura 8.20 Inclusión de aristas con peso 2 B C D 2 E 1 F 2 G 2 H I A 1 J L M 2 O 1 K N 2 Q P R Agregamos ahora las aristas de peso 3 que no cierren ningún ciclo, como se muestra en la figura 8.21. Los subconjuntos están formados por cada una de las componentes conexas. Figura 8.21 Inclusión de aristas con peso 3 B 3 C D 2 E 1 2 F 3 G 2 H I A 1 J 3 K 3 L 3 M 2 O P 1 N 2 Q 3 R Agregamos ahora aquellas aristas de peso 4 que no cierren ciclos. Marcaremos con lı́nea 350 Árboles punteada las que no pueden ser agregadas porque cierren un ciclo. El resultado se puede ver en la figura 8.22. Figura 8.22 Inclusión de aristas con peso 4 B 3 C D 2 E 4 1 2 3 F 4 G 2 H I A 1 4 4 J 3 K 3 L 3 M 2 O P 1 2 N 4 Q 4 R 3 Agreguemos ahora las aristas de peso 5, sin incluir aquellas que cierran ciclos, como se muestra en la figura 8.23. Figura 8.23 Inclusión de aristas con peso 5 B 5 3 C D 2 E 4 1 2 3 F 4 G 2 H I A 1 4 4 J 3 K 3 L 3 M 5 2 O P 1 2 4 N 4 Q 3 R 351 8.4 Árboles generadores de peso mı́nimo La última arista que incluimos es OL, pues al agregarla se completa el número de aristas necesarias para el árbol. El resto de las aristas ni siquiera se revisan. El peso total del árbol es de 44 unidades, exactamente el mismo peso que el obtenido con el algoritmo de Prim. Aunque pudiera suponerse que el árbol generador producido por el algoritmo de Kruskal fuese, si no idéntico, casi idéntico al obtenido por el algoritmo de Prim, esto no es forzosamente cierto, sobre todo si existen más de un árbol generador de peso mı́nimo para una gráfica. Si no son el mismo será porque se sustituyen aristas por otras de exactamente el mismo peso. Por ejemplo, mientras que con el algoritmo de Prim tenı́amos el subcamino F − K − G con peso total de 5 unidades, en el árbol construido por el algoritmo de Kruskal tenemos a G colgando de E y a K colgando de G, lo que da un costo también de 5 unidades para incluir a G y K al árbol. Deseamos insistir en que hemos utilizado hasta ahora aristas con pesos positivos. En especial el algoritmo de Dijkstra no puede utilizarse si hay pesos negativos, porque no podrı́amos garantizar que una vez que un vértice está al frente de la cola de prioridades es porque ya se le alcanzó por el camino más corto. Las aristas con peso negativo pudiesen encontrar un camino más corto aun después de haberse terminado de procesar al vértice. Los algoritmos de Prim y Kruskal no se ven afectados por esta situación. Ejercicios 8.4.1.- ¿Puede el algoritmo de Kruskal producir más de un árbol generador distinto para una misma gráfica? Si es ası́, ¿cuándo se podrı́a dar esta situación? 8.4.2.- Para las gráficas que siguen construye los árboles generadores bajo el algoritmo de Prim y después bajo el algoritmo de Kruskal. En el caso del algoritmo de Prim, cada vez que haya más de una opción para elegir al siguiente vértice que será el centro de acción, deberás elegir en orden lexicográfico. (b) (a) a 2 3 b 3 1 e 4 4 3 1 f 3 g 3 j 3 k 1 1 3 3 1 l b 3 2 e h 3 4 a d 5 2 2 i c 4 2 2 f 5 1 i c 4 g 4 1 j 2 d h 4 k 3 l 352 Árboles (d) (c) 2 4 a a 1 3 2 e 3 1 f 4 3 m 5 g j 2 4 2 3 k 6 4 5 1 d h c 3 e 7 3 4 g 2 3 5 2 4 3 n d 4 1 4 2 c 2 2 1 i 2 b 3 b 3 f 8 h 4 6 i l 2 o 3 p 2 8.4.3.- Construye una gráfica simple con pesos en las aristas con el menor número posible de aristas que tenga al menos dos árboles generadores de peso mı́nimo distintos. 8.4.4.- Un bosque generador de peso mı́nimo es un conjunto de árboles, donde cada árbol es un árbol generador de peso mı́nimo para la componente conexa de la gráfica. Habrá tantas componentes conexas como árboles generadores de peso mı́nimo. Explica cómo modificarı́as los algoritmos de Prim y Kruskal para que pudieran calcular el bosque generador de peso mı́nimo de una gráfica cualquiera, con posiblemente más de una componente conexa. 8.4.5.- Argumenta por qué una arista que tiene el peso mı́nimo de entre los pesos presentes en la gráfica debe estar presente en el árbol generador de peso mı́nimo. 8.4.6.- Supongamos que deseamos un árbol generador de peso mı́nimo para una gráfica, pero hay ciertas aristas que, independientemente de su peso, tienen que estar presentes en el árbol. ¿Cómo sugieres que esto se pueda hacer? Multigráficas y gráficas dirigidas 9 Hasta ahora hemos trabajado exclusivamente con gráficas donde entre dos vértices a lo más hay una arista – excepto cuando revisamos la formalización dada por Euler para el problema de los Puentes de Königsberg – y no hemos admitido aristas de la forma uu, conocidas como lazos1 . Tampoco hemos trabajado con gráficas dirigidas (llamadas digráficas). En esta sección abordaremos ambos temas. 9.1. Multigráficas Una multigráfica es, como ya mencionamos, una gráfica que admite varias aristas entre dos vértices – llamadas aristas paralelas – y lazos. En realidad una gráfica es un caso particular de una multigráfica, por lo que todos los conceptos que vimos en las gráficas se aplican a multigráficas. La diferencia fundamental es que los extremos de una arista ya no determinan unı́vocamente a la arista. Por ello se usa identificar a las aristas de una multigráfica asociando nombres para cada arista. Veamos una multigráfica en la figura 9.1. En el caso de multigráficas las trayectorias especificar usando los nombres de las aristas, no las parejas de vértices, ya que esto último lleva a confundir de cuál arista se trata. Podemos observar, por ejemplo, que la gráfica del problema de los Puentes de Königsberg es una multigráfica. Por lo tanto encontrar un ciclo euleriano o un paseo euleriano se aplica también a multigráficas. o de componente conexa de una gráfica, que se interpreta de 1 En inglés loop. 354 Multigráficas y gráficas dirigidas manera directa para una jultigráfica. Figura 9.1 Ejemplo de multigráfica k c V W a b n m U d ℓ X e g Y f R i h Z j La representación de multigráficas en matrices de adyacencias no es posible, pues no tendrı́amos la noción de cuál de las aristas es la que está en juego. Lo mismo podemos decir de las listas de adyacencias. En cambio, las matrices o listas de incidencias son una representación adecuada que preserva la distinción entre las aristas múltiples. Ejemplo 9.1. Veamos la matriz de incidencias y las listas de incidencias para la gráfica en la figura 9.1. Matriz de incidencias Listas de incidencias  a R 0   U 1   V  1   W 0   X 0   Y  0  Z 0 b c d e f g h i j k ℓ m n 0 0 0 0 0 1 1 0 0 0 0 0 0   1 0 0 0 0 0 0 0 0 0 1 0 0    1 1 0 0 0 0 0 0 0 0 0 0 0    0 1 1 0 0 0 0 0 0 1 0 1 1    0 0 0 1 1 0 0 0 0 0 1 1 1    0 0 1 1 0 0 0 1 1 0 0 0 0   0 0 0 0 1 0 1 1 1 0 0 0 0 R g h U a b l V a b c W c d k m n X e f l m n Y d e i j Z f h i j 355 9.2 Gráficas dirigidas Ejercicios 9.1.1.- Demuestra que una multigráfica siempre tiene una subgráfica simple que preserva adyacencias. 9.1.2.- En las siguientes gráficas determina si la gráfica es o no una multigráfica. Justifica tu respuesta. (b) (a) (c) b a a b b a c c f e d e d 9.1.3.- Lista los lazos y las aristas múltiples en las siguientes multigráficas. (a) (b) u d v a b v c a c b b v w f c f d g w j i h y x u t e u (c) a m e x k z n 9.1.4.- Dibuja ejemplos de multigráficas que satisfagan cada una de las siguientes condiciones: (a) Hay exactamente dos ciclos. (b) Hay un ciclo de tamaño 1. (c) Hay un ciclo de tamaño 2. 356 Multigráficas y gráficas dirigidas 9.2. Gráficas dirigidas Como mencionamos al principio de este capı́tulo, una gráfica dirigida o digráfica D = (V, A) es una pareja compuesta por un conjunto de vértices, como en el caso de las gráficas, y un conjunto de arcos que consisten de parejas ordenadas de vértices. Recordamos que a las parejas ordenadas de vértices se les conoce como arcos para subrayar el hecho de que el orden de los vértices en la pareja importan: (u, v) 6= (v, u). En el caso de las digráficas, podemos tener también multigráficas dirigidas, aunque el concepto de arco múltiple entre dos vértices se aplica únicamente a la presencia más de una vez de la misma pareja de vértices ordenados. Es frecuente la presencia de lazos en el caso de gráficas dirigidas. Ejemplo 9.2. En la figura 9.2 vemos la ilustración de algunas digráficas. Figura 9.2 Ejemplos de digráficas (a) (b) (c) a b a a b b c c c d d e d En la digráfica de la figura 9.2(a) podemos observar que aunque hay dos arcos entre a y c, uno corresponde a la pareja ordenada (a, c) mientras que el otro corresponde a (c, a), por lo que no hay posibilidad de confundirlos. En la figura 9.2(b) podemos observar que no hay manera de llegar del vértice a al vértice c, siguiendo la dirección de los arcos. En cambio, en la 9.2(c) se puede llegar desde cualquier vértice a cualquier otro siguiendo la dirección de los arcos. En el caso de digráficas, al definir uns trayectoria deberemos exigir que la dirección de los arcos sea la correcta: Definición 9.1 (trayectoria dirigida) Una trayectoria dirigida en una digráfica es una sucesión de arcos a1 , a2 , . . . , ak tal que ai = (u, v), ai−1 = (x, u) y ai+1 = (v, y), 2 ≤ i ≤ k − 1. 357 9.2 Gráficas dirigidas Ejemplo 9.3. En la digráfica de la figura 9.2(a) la sucesión (a, c), (c, d), (d, a), (a, b), (b, c), (c, a) forman una trayectoria dirigida; pero la sucesión (c, a), (c, d), (d, a), (a, b), (b, c), (c, a) no corresponde a una trayectoria dirigida, pues no coinciden el segundo elemento de la primera pareja con el primer elemento de la segunda pareja. En ocasiones es conveniente observar una digráfica sin tomar en cuenta la dirección de sus arcos. Tenemos entonces el concepto de gráfica subyacente: Definición 9.2 (gráfica subyacente) La gráfica subyacente de una digráfica D es la que resulta de quitar la dirección a los arcos de la digráfica; esto es, considerar a las parejas de vértices que representan a los arcos como parejas no ordenadas. Si consideramos a las subgráficas subyacentes, tenemos la siguiente definición: Definición 9.3 (trayectoria no dirigida) Uns trayectoria no dirigida en una digráfica D es aquella que es una trayectoria en la gráfica subyacente. Otro tipo de caminos que podemos identificar son los caminos antidirigidos: Definición 9.4 (trayectorias antidirigidas) Una trayectoria antidirigida es una sucesión de arcos o flechas que alternan direcciones. Veamos dos definiciones más relacionadas con digráficas: Definición 9.5 (exgrado) El exgrado de un vértice v ∈ V – denotado por d+ (v) – corresponde al número de arcos que salen de v, aquéllos en los que el primer componente es v. Definición 9.6 (ingrado) El ingrado de un vértice v ∈ V – denotado por d− (v) – corresponde al número de arcos que llegan o entran a v, aquéllos cuya segunda componente es v. Ejemplo 9.4. Veamos los ingrados y exgrados de las gráficas de la figurea 9.2. gráfica 9.2(a) v d+ d− a 3 3 b 1 1 c 3 3 d 1 1 gráfica 9.2(b) v d+ d− a 2 1 b 1 1 c 2 0 d 0 3 gráfica 9.2(c) v d+ d− a 1 1 b 2 2 c 1 1 d 1 2 e 2 1 358 Multigráficas y gráficas dirigidas En cuanto a la representación de las gráficas dirigidas lo haremos de la misma manera que lo hicimos con gráficas en general, siempre y cuando no se repita ninguna pareja ordenada de vértices. Cabe mencionar que en este caso las matrices de adyacencias no van a ser simétricas, ya que el arco (u, v) se registra únicamente en el renglón u, columna v. Por otro lado, las matrices de incidencias no nos van a dar información respecto al ingrado o exgrado de los vértices, ya que si, para un vértice dado, registramos si es extremo de un arco, de la matriz, y sin ver a la pareja que conforma al arco, no sabemos si el arco sale o llega al vértice. Tampoco tenemos realmente forma de representar a un lazo en las matrices de incidencias. Una opción es la de anotar con 1 los vértices a los que llega esa arista y con −1 los vértices de los que sale, pero esta representación tampoco nos va a dar oportunidad de representar lazos. Para el caso de las listas de adyacencias seguiremos la regla de colocar en la lista de un vértice dado sólo aquellos vértices a los que se puede llegar desde ese vértice recorriendo un único arco; similarmente, para las listas de incidencias únicamente registraremos en la lista de un vértice a aquellos arcos que salen de ese vértice. Ejemplo 9.5. Veamos las distintas representaciones para la digráfica de la figura 9.2(a), a la que le agregamos nombres a los arcos: b a1 a7 a5 a2 a c a4 a6 a3 d Matriz de adyacencias a b c d   a 1 1 1 0 a8    b  0 0 1 0   c 1 0 1 1   d 1 0 0 0 Matriz de incidencias  a  b  c  d a1 a2 a3 a4 a5 a6 a7 a8  1 0 0 1 1 1 1 0  1 1 0 0 0 0 0 0   0 1 1 0 1 1 0 1   0 0 1 1 0 0 0 0 Listas de adyacencias a a b c c c d a b d a d Listas de incidencias a1 a5 a7 a b a2 c a3 d a4 a6 a8 El concepto de conexidad en gráficas se traslada a digráficas de manera un poco distinta. Por un lado tenemos el concepto de digráfica fuertemente conexa , donde se exige que haya 359 9.2 Gráficas dirigidas un camino dirigido entre cualesquiera dos vértices. Aunque en ocasiones esta exigencia resulta demasiado fuerte, es común que se desee una digráfica con estas caracterı́sticas para garantizar el acceso de cualquier vértice desde cualquier otro. El concepto de digráfica (débilmente) conexa es un poco más relajado e involucra a la gráfica subyacente. Entonces, decimos que una digráfica es conexa si su gráfica subyacente es conexa. Ejemplo 9.6. Si bien en la digráfica de la figure 9.2(b) no hay trayectorias dirigidas entre cualesquiera dos vértices de la digráfica – por ejemplo, no se puede llegar desde el vértice d al vértice a – la gráfica subyacente es conexa, como se puede observar en la figura. a b c d Pasemos a ver algunas de las propiedades que vimos en gráficas simples y que, de alguna manera, se adaptan a gráficas dirigidas. Lema 9.1 En una gráfica dirigida D = (V, A), las siguientes cantidades son iguales: X X d+ (v) = d− (v) = |A| v∈V v∈V Demostración. Claramente por cada unidad en el ingrado de un vértice que corresponde a un arco que llega al vértice, este arco proviene de algún (otro) vértice, donde corresponde, a su vez, a una unidad en el exgrado de ese vértice. Por lo que por cada unidad en el ingrado, existe una unidad en el exgrado y la primera igualdad se cumple. Ahora, el número de arcos los podemos contar ya sea cuando salen de un vértice (el exgrado) o cuando llegan a un vértice, que corresponde al ingrado. Por lo tanto, el número total de arcos corresponde a la suma de los ingrados o bien a la suma de los exgrados. Ejercicios 9.2.1.- Para las siguientes matrices de adyacencias, dibuja las gráficas dirigidas correspondientes. 360 Multigráficas y gráficas dirigidas (d)         0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 (e) 0 0 0 0 1 0 0 1 0 0 0 1  0 0 1 0 0 0                0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 (f) 1 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0                 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1         9.2.2.- Para las siguientes gráficas dirigidas, construye las matrices de adyacencias y las listas de adyacencias e incidencias correspondientes. (b) (a) a b c b a c d e f g f g (c) a e d h (d) b c a b c d e d e f 9.2.3.- ¿Hay alguna caracterı́stica que determine, a priori, que una gráfica dirigida no tenga caminos desde un vértice origen a cualquiera de los vértices de la gráfica? 9.2.4.- Da un algoritmo para determinar si desde cualquier vértice se puede llegar a un vértice dado en una gráfica dirigida. 361 9.3 Circuitos eulerianos 9.2.5.- Escribe una definición de lo que es un isomorfismo entre gráficas dirigidas. 9.2.6.- Determina si las gráficas dirigidas a continuación son o no isomorfas. a b u v c d w x 9.3. Circuitos eulerianos Para el caso de digráficas, se definen condiciones un poco distintas para que haya un circuito euleriano dirigido (en adelante abreviamos a circuito euleriano simplemente); básicamente, se exige que a cada vértice al que se llega mediante un arco dirigido hacia él, haya un arco que salga de él para poder abandonarlo. Esta condición queda clara en el teorema 9.1. Teorema 9.1 Una digráfica D = (V, A) cuya gráfica subyacente es conexa, tiene un circuito euleriano dirigido si y sólo si para cada v ∈ V , d+ (v) = d− (v). Demostración. =⇒ Supongamos que D = (V, A) tiene un circuito euleriano. Mantengamos la cuenta de d+ (v) y d− (v), ∀v ∈ V . Sea v0 el vértice en el que iniciamos; sumamos 1 a d+ (v0 ). A partir de ese momento, a cada vértice al que llegamos, salimos de él, de donde por cada arco que llega tenemos un arco que sale del vértice, por lo que incrementamos en 1 tanto a d+ (v) como a d− (v). Pero para el último vértice en el circuito únicamente tenemos el arco que llega. Pero ese vértice es v0 , el mismo desde el cual iniciamos, por lo que ese último arco se aparea con el que se usó para empezar e incrementa a d− (v) en 1. ∴ ∀v ∈ V, d+ (v) = d− (v) ⇐= Supongamos ahora que ∀v ∈ V, d+ (v) = d− (v). Seguimos el algoritmo dado para gráficas no dirigidas, pero en cada vértice elegimos algún que y que no haya P arco Psalga + − d (v)= d (v) , cada uno de sido todavı́a utilizado; como en el caso de digráficas v∈V v∈V − estos arcos, llega a otro vértice. Como tenemos para cada vértice que d (v) = d+ (v), cada vez que llegamos a un vértice, tenemos uno libre por el cual salir. Por lo que si seguimos el algoritmo 6.1, pero eligiendo para salir un arco que tenga como primer 362 Multigráficas y gráficas dirigidas componente al vértice del que deseo salir, construiremos un circuito euleriano. En cuanto a los paseos eulerianos dirigidos (en adelante, paseos eulerianos simplemente), también podemos pensar en condiciones similares. Mientras que en gráficas no dirigidas se exigı́a que hubiese exactamente dos vértices de grado impar y el resto de grado par, en el caso de digráficas debemos pedir que exactamente un vértice tenga un arco más de salida que los que tiene de entrada, mientras que exactamente un vértice tenga un arco más de entrada que los que tiene de salida. El resto de los vértices tendrá que cumplir la condición de que su exgrado sea igual a su ingrado. El paseo euleriano debe iniciar en el vértice de exgrado mayor al ingrado y debe terminar en el vértice con ingrado mayor a su exgrado. Ejemplo 9.7. Dada la gráfica dirigida de la figura 9.3, decidir si la digráfica tiene o no un paseo euleriano, y si lo tiene, encontrarlo. Figura 9.3 Digráfica para paseo dirigido euleriano w s v u z x t y Respuesta: La digráfica tiene una trayectoria dirigida euleriana porque d+ (v) = d− (v), ∀v ∈ V , excepto para s que tiene d− (s) = 1 mientras que d+ (s) = 2, lo que indica que se debe empezar en ese vértice. Para el vértice donde se debe terminar tenemos d− (v) = 2 y d+ (v) = 1; de donde los vértices cubren las condiciones necesarias y suficientes para que la gráfica tenga un paseo euleriano euleriana. En la gráfica de la figura 9.4 anotamos los arcos con el orden en que pueden recorrerse para obtener un paseo euleriano. 363 9.3 Circuitos eulerianos Figura 9.4 Digráfica con el paseo euleriano 9 w 8 1 s 14 7 13 3 2 v z x 12 4 t 10 5 11 y u 6 Ejemplo 9.8. Examinemos las digráficas que presentamos en la figura 9.2 para ver si tienen o no circuito o paseo euleriano. (a) En la digráfica de esta figura, la gráfica subyacente es conexa y nos encontramos con que para todos los vértices se cumple que su ingrado sea igual a su exgrado, por lo que tiene un circuito euleriano. A continuación mostramos la digráfica con las aristas anotadas con el orden en que son tomadas para el circuito euleriano. b 5 1 2 6 a c 4 8 7 3 d Hay muchos otros posibles circuitos eulerianos en esta digráfica. Invitamos al lector a encontrarlos. (b) En esta digráfica tres de los cuatro vértices tienen distintos su ingrado y su exgrado, por lo que no hay posibilidad ni de circuito euleriano ni de paseo euleriano. (c) En esta digráfica vemos que se cumplen las condiciones para un paseo euleriano, empezando en el vértice e que es el que tiene el exgrado mayor a su ingrado, y terminando en el vértice d que es el que tiene el ingrado mayor que el exgrado. Un paseo euleriano posible se muestra a continuación. 364 Multigráficas y gráficas dirigidas 6 a b 3 5 c 7 4 2 e 1 d Hay al menos otro paseo euleriano sobre esta misma digráfica. Invitamos al lector a encontrarlo. Como se puede observar, la única diferencia entre los algoritmos que se aplican a gráficas no dirigidas o a digráficas, en el caso de paseos eulerianos, es que hay que cuidar de cuál de los dos vértices se sale; la representación más útil para manipular digráficas va a ser la de listas de adyacencias porque esta representación es la que nos va a dar más información. Sin embargo, si queremos saber, por ejemplo, el ingrado de un vértice, tendremos que contar las veces que ese vértice aparece en las distintas listas, lo que tiene un costo proporcional al número de arcos. Ejercicios 9.3.1.- Para las digráficas del ejercicio 9.3.2, determina si tienen circuito euleriano, paseo euleriano o ninguno de los dos. Si es alguno de los primeros dos casos, encuentra un circuito euleriano o un paseo euleriano, según corresponda. 9.3.2.- Queremos modelar con una digráfica las preferencias de un profesor para impartir cursos en la carrera de Ciencias de la Computación. El profesor ha establecido su preferencia entre cada dos materias de cinco – Matemáticas discretas (MD), Análisis lógico (AL), Teorı́a de la computación (TC), Complejidad computacional (CC), Lenguajes de programación (LP) – que él puede impartir. Las preferencias son las siguientes: Su materia favorita es TC. Prefiere dar AL que cualquier otra materia excepto TC. Prefiere dar CC que LP. Prefiere dar MD que CC o LP. Dibuja la gráfica dirigida que corresponde a estas preferencias. ¿Existe algún orden en estas materias que refleje estas preferencias? ¿Cuántos posibles ordenamientos 365 9.4 Distancias en una gráfica dirigida existen? (Este problema se asemeja un poco al de trayectorias hamiltonianas, pues nos pide un camino que visite a todos los vértices exactamente una vez, siguiendo la dirección de los arcos, donde hay un arco del vértice u al vértice v si es que u debe ir antes que v en la lista ordenada.) 9.3.3.- Un torneo es una digráfica que se obtiene asignando dirección a cada arista de una gráfica completa no dirigida. Es decir, un torneo es una digráfica en la que cada pareja de vértices está conectado por un solo arco. En un torneo, el exgrado de un vértice nos indica el marcador (número de juegos que ganó). El rey del torneo es aquel vértice con marcador mayor. En los siguientes torneos encuentra al rey del torneo y muestra que hay una trayectoria dirigida de longitud 1 o 2 desde ese vértice a cualquier otro: (b) (a) a b a (c) a b c c b c f d e d e d 9.3.4.- ¿Puede un torneo tener dos equipos que siempre pierdan? 9.3.5.- En un torneo con 4 equipos, América, Pumas, Chivas y Cruz Azul, cada uno de los equipos juega contra el resto exactamente una vez. El resultado de los juegos es el siguiente: i. Los Pumas les ganaron al resto de los equipos. ii. Las Chivas perdieron contra el resto de los equipos. iii. El América les ganó a todos menos a los Pumas. ¿Puedes asignar lugares a cada uno de los equipos? ¿Cuántos posibles órdenes hay? 9.3.6.- Escribe el algoritmo para encontrar un circuito euleriano en una digráfica. 366 Multigráficas y gráficas dirigidas 9.4. Distancias en una gráfica dirigida Adaptamos el concepto de distancia entre dos vértices u y v – δ(u, v) – en una digráfica a que sea la longitud de la trayectoria dirigida simple más corta que va de u a v, o bien δ(u, v) = ∞ si tal trayectoria dirigida no existe. Nuevamente, el orden de los vértices es importante, pues en una digráfica puede haber una trayectoria dirigida de u a v y que no haya una de v a u. 9.4.1. BFS Para encontrar δ(u, v) para todo vértice v en V , usamos el algoritmo BFS, excepto que las listas de adyacencias respetan la dirección de los arcos – ver el algoritmo BFS en la página 270. Similarmente, si deseamos encontrar la distancia entre cualquier pareja de vértices o entre dos vértices (u, v), usamos el algoritmo BFS con las listas de adyacencias respetando la dirección de los arcos. Debemos tener claro que aunque la gráfica subyacente sea conexa, pudiese suceder que no haya trayectoria entre dos vértices dados, ya que ésta depende del vértice origen y que los arcos se encuentren en la dirección correcta para seguir una trayectoria. Veamos, por ejemplo, la misma gráfica que se usó para ejemplificar BFS en la figura 9.5, pero con dirección definida para los arcos. Figura 9.5 Exploración BFS de una gráfica dirigida desde el vértice p 1 2 r u 3 5 t s 2 v 0 p C = hp, r, u, v, t, w, q, si w 3 q 4 Si la distancia se mide desde el vértice p, entonces todos los vértices quedan con la distancia definida (< ∞). En cambio, si intentamos medir la distancia desde el vértice u nos vamos a encontrar que únicamente la parte derecha de la gráfica es alcanzable, mientras que la parte izquierda no; esto sucede a pesar de que la gráfica subyacente es conexa – ver figura 9.6. 367 9.4 Distancias en una gráfica dirigida Figura 9.6 Exploración BFS de una gráfica dirigida desde el vértice u ∞ 0 r 1 3 u t s w ∞ q 2 ∞ v ∞ p 9.4.2. arcos usados no incluidos arcos no explorados arcos que dan la distancia C = hu, t, q, si Algoritmo de Dijkstra para trayectorias dirigidas más cortas También en el caso del algoritmo de Dijkstra para trayectorias dirigidas más cortas, todo sucede igual que en el caso de gráficas no dirigidas, excepto que los arcos se toman con la dirección adecuada – ver página 276 – donde en cada vértice se pregunta por los arcos no usados que salen de ese vértice. En el caso de este algoritmo, cuando se utilizan arcos en lugar de aristas las cosas pueden cambiar mucho, pues aunque la gráfica subyacente sea conexa, en ocasiones no habrá trayectoria dirigida entre dos vértices. Veamos la misma gráfica de la figura 6.14 pero con dirección en las aristas, para ver cómo se definen las distancias, en la gráfica de la figura 9.7. Figura 9.7 Algoritmo de Dijkstra para trayectorias dirigidas más cortas con origen en s 2 o 1 3 1 0 s 2 2 3 1 4 u t 1 3 arcos usados no incluidos arcos incluidos y quitados arcos que dan la distancia 16 p 3 5 2 6 v 1 1 8w 3 q r 4 5 vi s o t q u r v w p δ 0 3, 2 1 4 7 8 9 11 16 orden 1 3 2 4 5 6 7 8 9 368 Multigráficas y gráficas dirigidas Sin embargo, si el vértice origen es, por ejemplo, u, no todos los vértices van a tener una distancia definida, como se puede ver en la figura 9.8. Figura 9.8 Algoritmo de Dijkstra para trayectorias dirigidas más cortas con origen en u 2 1 ∞ t 2 9.4.3. arcos usados no incluidos arcos no explorados arcos que dan la distancia p 5 2 0 1 ∞ s 2 1 3 9 3 o u 3 3 v 1 w 2 1 4 vi u o r v w p δ 0 2 1 2 4 9 orden 1 3 2 4 5 6 3 q r ∞ 1 Número de caminos Nuevamente utilizamos el método de multiplicar las matrices de adyacencias, excepto que estas matrices deben reflejar la dirección de los arcos. En Ak encontraremos el número de caminos dirigidos del vértice u al vértice v de tamaño k. Veamos lo que pasa con la matriz de adyacencias de la gráfica en la figura 9.8 sin pesos en las aristas. Obtendremos únicamente los caminos de longitud 2, sólo para ilustrar. A o p q r s t u v w o p q r s t u v w                 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 A2 A 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 o p q r s t u v w o p q r s t u v w               •                  0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0                                 0 1 2 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0                 369 9.4 Distancias en una gráfica dirigida En la matriz correspondiente a A2 , tenemos que hay dos caminos del vértice q al vértice o. En efecto, en la gráfica de la figura 9.8 podemos observar que esos dos caminos son q → u → o y q → s → o. El camino de longitud 2 que va del vértice t al vértice s es t → q → s. El resto de los caminos los puede verificar el lector de ası́ desearlo. 9.4.4. Árboles En el caso de árboles dirigidos los cambios que se presentan son más significativos que para el resto de los algoritmos que vimos. Por falta de espacio y tiempo hemos decidido no revisarlo en esta ocasión. Ejercicios 9.4.1.- Escribe la versión del algoritmo BFS para encontrar las distancias en una gráfica dirigida. 9.4.2.- Usa el algoritmo BFS para encontrar el árbol de distancias de las siguientes digráficas. (a) (b) s a b c d e f g h i j k l m t s l a b c d e f g h i j k m n o p q r t u 9.4.3.- Encuentra los árboles de distancias para las gráficas dirigidas con pesos en los arcos que se encuentran a continuación. 370 Multigráficas y gráficas dirigidas (b) (a) 2 a 3 2 2 s a 4 2 j 3 4 k 2 2 h 3 3 3 l m s d 2 g f 1 c 5 2 e 3 b 2 1 1 i c b 2 e 3 4 1 1 f 4 j 3 t 2 4 m l 2 o 4 q 1 4 1 k 3 p 2 r h 1 n 3 2 2 3 4 d 4 g i 3 3 t 2 1 3 u 9.4.4.- Encuentra la trayectoria dirigida más corta del vértice s al vértice a en las siguientes digráficas utilizando el algoritmo de Dijkstra. (b) (a) 2 c a 1 c (c) 8 d 3 s 4 2 7 e d 1 3 5 b 2 s 2 3 f 4 1 g 1 4 3 f 6 9 1 3 1 2 s e 1 2 a 1 a 3 1 1 1 3 1 h 1 2 f g g 1 b 3 2 d e 4 1 5 2 c 2 h 2 b 2 i 1 1 i 9.4.5.- Explica por qué para una digráfica D donde V = {v1 , v2 , . . . , vn } con su matriz de adyacencias A, el número de caminos dirigidos de tamaño m desde vi hasta vj está dado por la entrada [i, j] de Am . 9.4.6.- Da una definición de digráficas isomorfas con pesos en sus arcos. Da un ejemplo de 371 9.4 Distancias en una gráfica dirigida dos digráficas con pesos en sus arcos que no sean isomorfas, aun cuando sus gráficas subyacentes sı́ lo son. 9.4.7.- Muestra que todo torneo tiene una trayectoria dirigida hamiltoniana. 9.4.8.- Para la siguiente gráfica determina el número de caminos de tamaño 1, 2, 3 y 4 desde a hasta d y desde d hasta a. a b c d Bibliografı́a [1] K. Doets and J. van Eijck. The Haskell Road to Logic, Maths and Programming. King’s Coll. Pub., London, 2004. [2] John A. Dossey, Albert D. Otto, Lawrence E. Spence, and Charles Vanden Eynden. Discrete Mathematics. Pearson/Addison-Wesley, 5-th edition, 2006. [3] Judith L. Gersting. Mathematical Structures for Computer Science. Computer Science Press, W.H. Freeman and Company, third edition, 1993. [4] Winifried Karl Grassman and Jean-Paul Tremblay. LOGIC AND DISCRETE MATHEMATICS, A Computer Science Perspective. Prentice-Hall Inc., 1996. [5] David Gries and Fred B. Schneider. A Logical Approach to Discrete Mathematics. Springer-Verlag, 1994. [6] Jerold W. Grossman. DISCRETE MATHEMATICS, an introduction to concepts, methods and applications. Macmillan Publishing Company, 1990. [7] Thomas Koshy. Discrete Mathematics with Applications. Elsevier Academoc Press, 2004. [8] K.H. Rossen. Discrete Mathematics and its Applications. McGraw Hill, 6-th edition, 2006. Índice ::=, 10 acoplamiento perfecto, 210 adyacencia en vértices, 217 preservación, 240 alcance, 54, 122 alcanzable vertice, 270 algoritmo, 202 BFS, 269 circuito euleriano, 250 de Dijkstra, 276 en digráficas, 367 de Floyd, 292 de Prim, 329 de Warshall, 290 DFS, 322 glotón o ávido, 276 para clasificar fórmulas, 109 para consecuencia lógica, 110 para ruta crı́tica, 205 para satisfacibilidad, 109 para tautologı́as, 108 análisis sintáctico, 50 apareamiento perfecto, 210 árbol, 12, 247, 312, 315 binario, 180, 197 de distancias, 340, 369 de peso mı́nimo, 339 generador, 318 de peso mı́nimo, 328 por BFS, 320 por DFS, 322, 326 por Dijkstra, 328 por Prim, 330 resultado, 12 archivo directorio, 158 arco, 203, 216, 356 argumento correcto, 37, 77, 155 deductivo, 37 inductivo, 37 lógico, 19, 37 aridad, 119 arista, 215, 216 dirección, 257 múltiple, 216 aristas hacia atrás, 327 paralelas, 353 asociatividad, 34, 44 autómatas finitos, 175 ávido algoritmo de Prim, 329 axioma, 91 de inducción, 166 de Peano, 165 BFS algoritmo, 269 en digráficas, 366 exploración en digráfica, 366 gráficas dirigidas, 369 bicondicional, 32, 61 busqueda en profundidad, 322 búsqueda en profundidad, 322 376 ÍNDICE cadenas, 10 cálculos deductivos, 91 camino, 243 longitud o tamaño, 245 casación de patrones, 181 cerradura transitiva, 292 χ(G), 299 ciclo, 245 BFS, 272 hamiltoniano, 261, 266 circuito euleriano, 248, 249, 362–364 algoritmo, 250 dirigido, 361 Cn , 221 ciclo, 221 cola de prioridades, 276, 329 estructura de datos, 276 coloración, 295, 296 BFS, 302 ciclos, 299, 301 gráfica bipartita, 304 completa, 301 colorear, 296 completo, 96 componente conexa, 270 conclusión, 19, 37 condicional, 29 conectivo, 24 principal, 54 conexidad digráficas, 358 conjunción, 28 conjuntos infinitos numerables, 163 conmutatividad, 33, 63 consecuencia lógica, 77, 82, 88 constante, 4 contingencia, 35 contradicción, 35, 36, 76 contraejemplo, 86, 88 contrapositiva, 31 contrarrecı́proca, 31 correcto, 20 cuantificación alcance, 121 existencial, 121 universal, 121 vacua, 150 variable de la, 121 cuantificador, 117 cuatro colores teorema de los, 307 deducción formal, 91 definición recursiva, 178 de funciones, 181 general, 178 δ(u, v) distancia en digráficas, 366 derivable, 92 derivación, 12, 91 descendiente relación, 178 DFS algoritmo, 325 ejecución, 323 diagonal principal, 230 digráfica, 203, 216, 353, 356 conexa, 359 débilmente conexa, 359 fuertemente conexa, 358 listas de adyacencias, 358 matriz de adyacencias, 358 matriz de incidencias, 358 Dijkstra algoritmo de, 276 dilema constructivo simple, 85, 89 Dirac teorema de, 262 ÍNDICE 377 dirección asignar, DFS, 327 distancia, 269 en digráficas, 366 distributividad en lógica de predicados, 149 disyunción, 29 d+ (v) exgrado, 357 − d (v) ingrado, 357 dominante, 34 dominio bien fundado, 164 de interpretación, 139 x E R, 46 E[x := R], 46 elemento identidad, 34 elemento neutro, 34 eliminación de ↔, 93 de ∧, 92 emparejamiento de patrones, 181 enunciado, 124 equivalencia, 32, 61 lógica, 61, 147 álgebra de, 72 esquema, 51 básico, 55 instanciar un, 52 estado, 22, 42, 75 evaluación en un, 43 evaluación de una expresión, 42, 49 exgrado, 217, 227, 357, 362, 363 exploración, 243 expresión aritmética, 6, 179 lógica, 50 extremo de una arista, 215 f (n) , 119 factorial, 181 falacia, 96 Floyd algoritmo de, 292 fórmula, 50 atómica, 21 bien construida, 179 cerrada, 124 cuantificada, 121 insatisfacible, 76 no satisfacible, 76 razonable, 98 válida, 76 fórmula atómica con predicados, 119 fuertemente tipificado, 157 función sucesor, 164 G[Vi ], 299 generalización existencial, 156 universal, 155 grado, 217 gráfica, 202, 215 acı́clica, 247, 315, 318 bipartita, 210, 221 completa, 222 completa, 220 coloración, 301 componente de una, 247 con pesos, 275, 319 conexa, 247, 313, 315, 318 digráfica, 203 dirigida, 203 exploración, 243 generadora BFS, 273 isomorfismo, 236 multigráfica, 216 378 ÍNDICE número de caminos, 284 plana, 307 rala, 231 simple, 216 subyacente, 357, 359 gramática, 10 de la lógica de predicados, 121, 122 proposicional, 24 de los términos, 118 formal, 10 hojas, 12 holgura, 209, 211 slack, 211 homeomorfismo, 309 I, 75 idempotencia, 35 identificador, 51 implicación, 29 contrapositiva, 31 contrarrecı́proca, 31 recı́proca, 31 incidencia en vértices, 217 incógnitas, 44 ı́ndice, 119 inducción, 163 cambio de base, 170 completa, 172 en fórmulas, 190 en listas, 187 en árboles, 192 estructural, 186 fuerte, 172 matemática, 163 inferencia regla de, 59 ingrado, 217, 227, 357, 362, 363 instanciación existencial, 156 universal, 155 instanciar un esquema, 52 interpretación, 75, 82, 88 función de, 75 introducción de ∨, 92 de ∧, 92 inversa, 31 isomorfismo de digráficas, 361 de digráficas con pesos, 371 de gráficas, 238 juicio afirmativo, 157 aristotélico, 130 existencial afirmativo, 130, 156 negativo, 130 universal afirmativo, 130, 156 negativo, 130 K5 , 309 Km,n bipartita completa, 222 Kn , 220 Kruskal algoritmo de, 346 árbol de peso mı́nimo, 346 subgráfica conexa acı́clica, 346 K3,3 , 309 Kuratowski teorema de, 309 L, 91 laberinto DFS, 322 lazo, 216, 230, 353 Leibniz regla de, 63, 72 ÍNDICE 379 lenguaje de la lógica de predicados, 118 de la lógica proposicional, 19 formal, 3 fuertemente tipificado, 157 natural, 3 LIFO pila, 324 lista concatenación, 183 de adyacencias, 231 de incidencias, 233 en multigráficas, 354 finita, 179 longitud, 182 reversa, 183 tipo, 158 literal, 98, 103 complementaria, 103 lógica de predicados de primer orden, 118 proposicional, 21 mapa, 307 matriz cuadrada, 229 de adyacencias, 228 de distancias, 293 de incidencias, 230 en multigráficas, 354 de pesos, 293 rala, 231 simétrica, 230 triangular, 235 metaexpresión, 36 metalenguaje, 36 método analı́tico, 55 generador, 55 micromundo, 133 de cubos, 133 de figuras geométricas, 134 modelo, 4, 75, 98 matemático, 4 |=, 36 modus ponens, 59, 82 tollens, 84 multiarco, 356 multigráfica, 230, 248, 249, 353 ciclo euleriano en, 353 componente conexa, 354 paseo euleriano en, 353 trayectoria en, 353 nand, 42 naturales definición recursiva, 164 exponenciación, 181 producto, 165 suma, 165 negación, 27 en lógica de predicados, 131 notación infija, 5 prefija, 5 sufija o polaca, 5 numerable, 163 número cromático, 299 en gráfica plana, 308 de caminos, 368 números naturales, 163 operador, 4 binario, 5 de cuantificación, 117 n-ario, 5 unario, 5 Ore teorema de, 265 380 ÍNDICE P, 324 palabras, 10 palı́ndroma, 195 paseo equino, 268 reentrante, 268 euleriano, 249, 256, 362–364 dirigido, 362 patrón, 181 Peano axioma de inducción, 166 axiomas de, 165 PERT, 205 pesos homogéneos, 293 Petersen gráfica de, 267 pila, 324 tipo, 159 poliominó, 176 pop, 324 precedencia, 44 predicado, 114 calificador, 156 tablas para, 142 premisa, 19, 37 prenexación, 150 producciones, 10 propiedades, 116 proposición, 4, 22, 50 atómica, 21, 23 compuesta, 23, 55 definición, 23 lógica, 4 prueba, 91 punto ciego, 322 en DFS, 324 punto fijo en algoritmos, 291 push, 324 rama de un tableau, 103 rango, 54 razonamiento ecuacional, 63, 72 recı́proca, 31 recursión, 163 reflexividad, 63 regla de reescritura, 10 recursiva, 178 sintáctica, 10 regla de inferencia, 59 α, 105 β, 105 casos simple, 93 de Leibniz, 64 eliminación de ↔, 93 de ∧, 92 generalización existencial, 156 universal, 155 inconsistencia, 93 instanciación existencial, 156 universal, 155 introducción de ∨, 92 de ∧, 92 introducción de ↔, 93 modus ponens, 92 tollens, 92 para tableaux, 105 σ, 105 silogismo disyuntivo, 93 hipotético, 92 ruta crı́tica, 205 raı́z, 12 satisface, 75 ÍNDICE 381 satisfacible, 75 semántica, 5, 26, 74, 165 silogismo disyuntivo, 93 hipotético, 81, 89, 92 sı́mbolo no terminal, 10 terminal, 10, 13 sintaxis, 5, 165 sólido, 20 subconjuntos de aristas, 346 subexpresión, 11 subgráfica, 223, 318 generadora, 225 inducida, 224 sustitución por la izquierda, 11 propiedad de, 58 textual, 46, 63 variables escondidas en, 48 tablas de verdad, 27 tableaux, 98 algoritmos con, 108 contradicción, 104 fórmula contingente, 105 semánticos, 98 tautologı́a, 105, 108 tautologı́a, 35, 57, 61, 76 teorema de la deducción, 95 de los cuatro colores, 307 teorı́a de la demostración, 91 de modelos, 91 tercero excluido, 36 término, 118 tipado, 157 tipo, 156 abreviado, 157 top, 324 torneo digráficas, 365 transitividad, 63 trayectoria, 244 antidirigida, 357 cerrada, 245 dirigida, 356 más corta, 367 en multigráficas, 353 hamiltoniana en digráficas, 365 más corta, 293 no dirigida, 357 universo de discurso, 114, 139 valor, 22 forzar un, 86 variable, 4, 10 acotada, 124 libre, 123 ligada, 123 proposicional, 24 verdad noción de, 143 vértice, 203, 215 alcanzable, 270 Warshall algoritmo de, 290