La respuesta de DW es excelente , pero me gustaría ampliar un punto. Una especificación no es solo una referencia contra la cual se verifica el código. Una de las razones para tener una especificación formal es validarla probando algunas propiedades fundamentales. Por supuesto, la especificación no se puede validar por completo: la validación sería tan compleja como la especificación en sí misma, por lo que sería un proceso interminable. Pero la validación nos permite obtener una garantía más sólida en algunas propiedades críticas.
Por ejemplo, supongamos que está diseñando un piloto automático para automóvil. Esta es una cosa bastante compleja que involucra muchos parámetros. Las propiedades de corrección del piloto automático incluyen cosas como "el automóvil no chocará contra una pared" y "el automóvil conducirá donde se le indique que vaya". Una propiedad como "el automóvil no chocará contra una pared" es realmente muy importante, por lo que nos gustaría demostrarlo. Como el sistema funciona en el mundo físico, deberá agregar algunas restricciones físicas; La propiedad real del sistema computacional será algo así como "bajo estos supuestos con respecto a la ciencia de los materiales, y estos supuestos con respecto a la percepción de obstáculos por los sensores del automóvil, el automóvil no chocará contra una pared". Pero aun así, el resultado es una propiedad relativamente simple que es claramente deseable.
¿Podría probar esta propiedad del código? En última instancia, eso es lo que está sucediendo, si está siguiendo un enfoque totalmente formal¹. Pero el código tiene muchas partes diferentes; Los frenos, las cámaras, el motor, etc. se controlan de forma autónoma. Una propiedad de corrección de los frenos sería algo así como "si la señal de" aplicar frenos "está activada, entonces se aplican los frenos". Una propiedad de corrección del motor sería "si la señal del embrague está apagada, entonces el motor no conduce las ruedas". Se necesita una vista de muy alto nivel para ponerlos todos juntos. Una especificación crea capas intermedias donde los diferentes componentes del sistema se pueden articular juntos.
De hecho, un sistema tan complejo como el piloto automático de un automóvil tendría varios niveles de especificaciones con diferentes cantidades de mejoras. A menudo se usa un enfoque de refinamiento en el diseño: comience con algunas propiedades de alto nivel como "el automóvil no chocará contra una pared", luego descubra que esto requiere sensores y frenos y calcule algunos requisitos básicos para los sensores, los frenos y el software piloto, luego refina nuevamente esos requisitos básicos en un diseño del componente (para el sensor, voy a necesitar un radar, un DSP, una biblioteca de procesamiento de imágenes, ...), etc. En un proceso de desarrollo formal, cada nivel de especificación cumple con los requisitos establecidos por el nivel superior, desde las propiedades de más alto nivel hasta el código.
Es imposible estar seguro de que la especificación es correcta. Por ejemplo, si te equivocaste en la física, los frenos podrían no ser efectivos a pesar de que la matemática que relaciona el código de freno con los requisitos formales es correcta. No es bueno demostrar que los descansos son efectivos con 500 kg de carga si realmente tienes 5000 kg. Pero es más fácil ver que 500 kg están mal que ver dentro del código de frenos que no serán lo suficientemente buenos para los parámetros físicos del automóvil.
¹ Lo opuesto a un enfoque totalmente formal es "Supongo que esto funciona, pero no puedo estar seguro". Cuando estás apostando tu vida, eso no parece tan bueno.