Clase 06
Clase 6: Introducción a la Instrucción de Asignación y Selección
Resumen de la Clase Anterior
- Se inicia la clase número seis, revisando conceptos de la clase pasada.
- Se discuten dos casos importantes sobre cómo calcular un vector ortogonal a un segmento: uno para segmentos diagonales y otro para segmentos horizontales.
- Se destaca que la instrucción de asignación no es suficiente en todos los casos; se necesita una selección basada en condiciones.
Instrucciones de Selección e Iteración
- La clase se enfocará en definir mejor las instrucciones de selección e introducir las instrucciones de iteración.
- Se menciona un ejemplo anterior donde todas las variables eran reales, aclarando su interpretación.
Definición del Dominio y Funciones Auxiliares
- Se explica cómo extender el dominio a todos los estados posibles, incluyendo el cero, y el costo asociado con ello.
- La función auxiliar R prima se define inicialmente en un dominio restringido antes de extenderse al espacio completo, manejando abortos cuando sea necesario.
Predicados Fuertes y Débiles
- Se introduce el concepto de predicados fuertes y débiles mediante ejemplos gráficos que ilustran restricciones lógicas.
- Un predicado más restrictivo (fuerte) tiene menos elementos válidos que uno menos restrictivo (débil), lo cual se relaciona con implicaciones lógicas entre ellos.
Comparación de Conjuntos y Variables
Restricciones en Comparaciones
- Se establece que hay diferentes niveles de restricción entre conjuntos, donde uno puede ser más fuerte o más débil que el otro.
- Se introduce la comparación entre un conjunto con dos variables y otro con una sola variable, destacando la importancia de entender sus extensiones.
Análisis de Conjuntos
- Se menciona que el conjunto donde se cumple una condición es un conjunto de pares ordenados.
- La representación gráfica de la ecuación y = -x + 3 se discute, enfatizando cómo las condiciones afectan su interpretación.
Comparaciones Lógicas
- Al comparar conjuntos, se asume que el conjunto considerado incluye todos los pares ordenados donde x > 5, mientras que y es libre.
- No hay un conjunto contenido puramente dentro del otro; ambos son comparables sin ser más débiles entre sí.
Ejercicios y Especificaciones
- Se mencionan ejercicios sobre especificación, donde se definen problemas con precondiciones y postcondiciones sin necesidad de incluir algoritmos.
- Los estudiantes deben definir constantes y variables adecuadamente para cumplir con las especificaciones requeridas en los ejercicios.
Demostraciones Matemáticas
- Un ejercicio específico requiere demostrar la validez de una tripleta (precondición, postcondición e instrucción).
- Se enfatiza la importancia de definir dominio y rango al trabajar con funciones matemáticas en contextos específicos.
Aplicación Práctica
- Los estudiantes deben sustituir valores específicos para calcular conjuntos y verificar si caen dentro del rango definido por las condiciones iniciales.
- En la parte B del ejercicio, se pide realizar demostraciones similares utilizando valores fijos para validar afirmaciones matemáticas.
¿Cómo generalizar en pruebas matemáticas?
Conceptos de Generalización
- Se discute la importancia de generalizar al final de una prueba, utilizando variables A y B para establecer una relación que se cumple para todos los casos.
- La noción de variables ligadas permite nombrar libremente las variables, lo que facilita la comprensión y aplicación de definiciones matemáticas.
- Se explica el valor de verdad de una tripleta (precondición, código, postcondición), diferenciando entre definiciones con y sin variables de especificación.
Proceso de Prueba
- La práctica repetida con definiciones es crucial para entender conceptos más complejos que se abordarán posteriormente.
- Se menciona que realizar un ejercicio inicial "rudo" proporciona valor a métodos más sencillos que se aprenderán después.
Desarrollo del Algoritmo del Triángulo
Etapas del Algoritmo
- El algoritmo consta de cinco etapas clave, comenzando por calcular la altura H del triángulo mediante coordenadas específicas.
- La segunda etapa implica calcular un vector ortogonal al segmento definido por las coordenadas dadas.
Cálculos Específicos
- Una vez obtenido el vector ortogonal, este debe ser estirado para alcanzar la altura H deseada.
- Se calcula el punto medio entre dos puntos antes de trasladarlo según la magnitud y dirección del vector ortogonal calculado.
Ejemplo Práctico: Corrida en Frío
Implementación del Algoritmo
- Se presenta un caso práctico donde se ejecuta el algoritmo sin condiciones adicionales (sin elif), aplicable solo a triángulos inclinados.
- El cálculo del punto medio se realiza con instrucciones simples, destacando la eficiencia en la implementación analítica como suma de vectores.
Resultados y Validaciones
- Al final, se revisan los pasos finales del algoritmo asegurando que cada instrucción cumpla su función correctamente durante la corrida en frío.
- Se establece un registro claro sobre cómo se construye el triángulo mediante coordenadas específicas y ajustes necesarios en cada instante.
¿Cómo se realizan cálculos y cambios en coordenadas?
Proceso de Cálculo Inicial
- Se plantea un cálculo inicial: ¿Cuánto es 3 * 29? Se decide no usar decimales para simplificar el proceso.
- Se realiza una resta entre las variables x1 y x2, obteniendo -2 como resultado. También se calcula la diferencia entre y1 y y2, resultando en 5.
Cambios en Variables
- Las variables x3 e y3 son las únicas que cambian. Se establece que x3 toma el valor anterior dividido por el estado anterior de y3, con un signo negativo.
- La división de los valores anteriores da como resultado positivo 2/5. Este cambio afecta a la variable H.
Simplificación de Resultados
- Se simplifica la expresión a raíz de (x3² + y3²), utilizando los valores anteriores para calcular correctamente.
- La expresión se reduce a 4/25, lo que permite realizar operaciones más simples al combinar raíces.
Ejecución del Programa
- Al ejecutar el programa, se actualizan las coordenadas x1, x2 y x3. El nuevo valor de x1 es 2 tras sumar las coordenadas correspondientes.
- Para obtener nuevas coordenadas (x3, y3), se suman los valores actuales de x1, x2 y el anterior valor de x3.
Verificación Final
- Se verifica si las distancias entre puntos forman un triángulo equilátero mediante cálculos específicos sin necesidad de extraer raíces.
- Los resultados indican que todas las distancias calculadas son correctas al dar raíz de 29.
Importancia de la Sintaxis en Programación
- Se discute cómo cada instrucción debe ejecutarse secuencialmente; el uso del punto y coma indica esta secuenciación en programación.
- La sintaxis es crucial para entender cómo funcionan las instrucciones dentro del código.
¿Cómo se utilizan los operadores en programación?
Uso del punto y coma en lenguajes de programación
- El operador binario se menciona como un símbolo que se coloca entre dos instrucciones. En algunos lenguajes, el punto y coma actúa como terminador de una instrucción.
- En GCL, el punto y coma es considerado un operador binario, lo que significa que la última instrucción de un bloque no lleva este símbolo.
- Python no requiere el uso del punto y coma para identificar bloques de código; utiliza la indentación para reconocer la estructura.
- La secuenciación de instrucciones implica colocar cada instrucción en líneas separadas, especialmente en Python donde esto es obligatorio.
- Aunque otros lenguajes permiten omitir saltos de línea, escribir todo en una sola línea puede hacer que el código sea ilegible.
Composición de funciones e interpretación
- Se discute cómo la secuenciación puede interpretarse como composición de funciones, donde se determina el orden de ejecución.
- Los estados se representan con pares ordenados (x,y), mostrando cómo las instrucciones cambian el estado a través del tiempo.
- La ejecución de instrucciones lleva a un cambio de estado, ilustrando la relación entre las funciones ejecutadas.
- Al dar semántica a las instrucciones, se elimina la noción del tiempo; solo se considera el estado inicial y final sin información intermedia.
- La función compuesta no refleja los pasos intermedios; solo muestra puntos iniciales y finales sin detallar lo ocurrido entre ellos.
Definición de Pares Ordenados y Estructuras de Control
Concepto de Pares Ordenados
- Se introduce la definición de pares ordenados, donde se establece que un par está compuesto por dos elementos, uno en cada posición.
- Se menciona que para definir un par ordenado, debe existir un punto intermedio que conecte ambos elementos del par.
- La idea principal es visualizar el conjunto de instrucciones como una única gran instrucción que abarca desde el inicio hasta el final sin información intermedia.
Instrucción Skip
- Se presenta la instrucción "skip", considerada como una función identidad en programación, ya que no altera el estado actual del sistema.
- Al ejecutar "skip", se mantiene el mismo estado sin cambios, lo cual puede parecer irrelevante pero tiene sus utilidades.
Instrucciones de Selección en Programación
Importancia de las Instrucciones Condicionales
- Se discute la necesidad de instrucciones condicionales para dirigir el flujo del programa según ciertas condiciones.
- Ejemplos previos muestran cómo ciertos fragmentos de código son útiles solo bajo condiciones específicas; esto resalta la importancia de seleccionar adecuadamente qué código ejecutar.
Sintaxis y Funcionamiento del If
- La sintaxis general para una instrucción condicional en GSL comienza con "if" seguido por una expresión lógica que determina el camino a seguir.
- El programa evalúa esta expresión antes de continuar con la ejecución, decidiendo así qué bloque de código ejecutar basado en su valor booleano.
Estructura y Bloques de Código
- Dentro del contexto GCL, las instrucciones dentro del bloque condicional no llevan punto y coma al final; esto indica el cierre del bloque.
- Se enfatiza que los bloques pueden contener múltiples instrucciones y deben ser considerados como unidades atómicas dentro del flujo general del programa.
¿Cómo funciona la ejecución condicional en GCL?
Ejecución de código y saltos
- Si una guardia es verdadera, el programa ejecuta solo ese bloque de código y omite el resto, saltando a la siguiente línea después de la última instrucción.
- En GCL, si ninguna guardia es verdadera, el programa no continúa; simplemente se aborta. Esto contrasta con otros lenguajes donde se sigue ejecutando.
Diferencias con otros lenguajes
- En otros lenguajes como los utilizados en laboratorios, si todas las guardias son falsas, el programa actúa como un "skip" y continúa sin abortar.
- En GCL, si una guardia es falsa, se produce un aborto del programa. Esta diferencia es crucial para entender cómo funcionan las instrucciones condicionales.
Complemento lógico en GSL
- Para replicar el comportamiento de GCL en Python o GSL, sería necesario incluir una expresión lógica que determine el complemento de la condición original.
- El uso del "skip" permite complementar las guardias sin que esto cause un aborto del programa.
No determinismo en ejecuciones
- Cuando hay múltiples guardias verdaderas, cualquiera puede ejecutarse de forma no determinística. Este aspecto introduce la posibilidad de crear programas no deterministas.
- La capacidad de tener múltiples caminos posibles durante la ejecución es fundamental para entender cómo funcionan ciertos algoritmos.
¿Cómo calcular el máximo entre dos números?
Declaración y precondiciones
- Se declara una constante A y B para representar los números entre los cuales se desea encontrar el máximo. La precondición no tiene restricciones específicas.
Especificaciones lógicas
- La poscondición establece que la variable m debe contener el valor máximo entre A y B. Esto puede expresarse usando implicaciones lógicas.
Casos a considerar
- Se identifican dos casos: cuando A es mayor o igual a B (m = A), y cuando A es menor que B (m = B). Ambos casos aseguran que m contenga correctamente el máximo.
Implementación del algoritmo
- Para programar esta lógica se utiliza una instrucción condicional que evalúa ambas condiciones antes mencionadas.
- Se sugiere demostrar lógicamente que las condiciones son equivalentes para asegurar la validez del enfoque utilizado en este algoritmo.
Evaluación de Condiciones en Programación
Conceptos Básicos sobre Evaluaciones Lógicas
- Se discute la evaluación de condiciones lógicas, donde si una condición es verdadera, se anula otra parte del código. Esto es fundamental para entender cómo funcionan las estructuras condicionales.
- La asignación de valores en programación se menciona como crucial; el valor final debe ser igual a B, lo que implica el uso de instrucciones adecuadas sin necesidad de punto y coma al final.
Estructuras Condicionales
- Se explica la importancia del uso correcto de los tokens de terminación en bloques condicionales para evitar ambigüedades en la interpretación del código.
- El uso de identación y terminadores permite que el intérprete comprenda correctamente qué instrucciones pertenecen a cada bloque, especialmente cuando se escriben en una sola línea.
Uso de Else y Guardias
- En GSL (Guardia Selección Lógica), no existe un "else" convencional; se utiliza "els", lo que requiere siempre una condición para su funcionamiento.
- La negación lógica es esencial al trabajar con múltiples condiciones; se debe definir claramente el complemento para asegurar que todas las posibilidades sean consideradas.
Ejecución y Evaluación Práctica
- Se presenta un ejemplo práctico donde se evalúa si 3 es menor o igual a 4, mostrando cómo fluye la ejecución del programa dependiendo del resultado.
- Un segundo escenario plantea invertir los valores (4 y 3), demostrando cómo cambia el flujo según las condiciones evaluadas.
Cálculo del Máximo entre Tres Números
- Se introduce un ejercicio donde se busca determinar el máximo entre tres números distintos A, B y C, almacenándolo en D.
- Para calcular el máximo, se propone usar funciones auxiliares que simplifiquen la lógica al comparar pares antes de llegar a un resultado final.
Asserciones Cortas y Funciones Auxiliares
- Al utilizar funciones auxiliares que devuelven verdadero o falso, se pueden crear asserciones más cortas y efectivas dentro del código.
- La declaración adecuada de funciones permite construir predicados más simples y eficientes, facilitando así la escritura del código.
Casos Distintos en Ejecuciones
- Cada caso tiene instrucciones específicas diseñadas para resolver problemas particulares; esto incluye representar gráficamente diferentes escenarios con los valores A, B y C.
Análisis de Permutaciones y Lógica en Programación
Conceptos Básicos de Permutaciones
- Se discute la cantidad de permutaciones discretas posibles, que es una: 3 factorial (6). Esto establece un fundamento para entender cómo se pueden organizar elementos.
- El proceso mental detrás de llegar a seis formas distintas se apoya en conocimientos previos del curso anterior sobre combinatoria discreta.
Estrategias para Comparar Valores
- Se busca el valor máximo entre tres variables (A, B y C), sugiriendo que es más fácil trabajar con un orden específico.
- Se propone simplificar las comparaciones agrupando casos donde A es mayor que B y C, lo cual optimiza el código.
Evaluación de Condiciones Lógicas
- La lógica detrás de las condiciones se explica mediante predicados que son verdaderos solo en situaciones específicas. Esto ayuda a evitar complicaciones innecesarias.
- Se aclara que no tiene sentido hablar de "mayor o igual" ya que los valores son distintos, enfocándose en establecer comparaciones claras entre A, B y C.
Comportamiento del Programa ante Condiciones
- Se analiza si hay estados donde dos guardias pueden ser verdaderas simultáneamente; se concluye que esto no es posible debido a la naturaleza disjunta de las condiciones.
- La discusión incluye la posibilidad de encontrar un estado donde ninguna condición sea verdadera, lo cual lleva a reflexionar sobre el flujo del programa.
Uso de Aserciones en Programación
- Se introduce el concepto de aserciones como herramientas para validar condiciones dentro del código. Estas pueden colocarse como precondiciones o postcondiciones.
- Las aserciones permiten identificar errores durante la ejecución del programa al evaluar expresiones matemáticas y lógicas antes o después de ciertas operaciones.
Importancia de las Postcondiciones
- En el contexto educativo actual, se enfatiza la necesidad de incluir postcondiciones para asegurar que los resultados deseados sean alcanzados correctamente.
- La técnica propuesta sugiere calcular aserciones desde postcondiciones hasta precondiciones para garantizar la validez del programa.
Contrato y Programación
Concepto de Contrato en Programación
- Se establece un "contrato" entre el programador y el cliente, donde se especifican precondiciones, postcondiciones y variables necesarias para el desarrollo del programa.
- El enfoque del curso enfatiza la importancia de formalizar este acuerdo antes de comenzar a programar, asegurando que el resultado final sea correcto según lo pactado.
Instrucción de Iteración
- Se introduce la instrucción de iteración, comparándola con un ejercicio previo sobre "caraotas", donde se ejecuta un bloque de instrucciones mientras una condición sea verdadera.
- La ejecución continúa hasta que la condición evaluada resulta falsa; en ese momento, se salta a otra parte del código.
Composición Semántica
- Se discute cómo las instrucciones pueden entenderse como composición de funciones repetidas n veces, permitiendo construir relaciones semánticas complejas.
- La próxima clase abordará más detalles sobre esta estructura y su aplicación práctica.
Problema Propuesto: Identificación de Vocales
Estructura del Programa
- Se plantea un problema donde se debe devolver verdadero si una letra es vocal y falso si es consonante.
- La solución implica definir claramente las condiciones bajo las cuales una letra pertenece al conjunto de vocales (A, E, I, O, U), considerando también mayúsculas.
Condición Compacta
- Se propone una forma compacta para expresar la postcondición sin necesidad de enumerar todas las consonantes; esto simplifica el código manteniendo su funcionalidad.