No estoy en condiciones de decir cuánto se debe hacer más investigación sobre el tema, pero puedo decirle que se está haciendo investigación, por ejemplo, el programa Verisoft XT financiado por el gobierno alemán.
Los conceptos que creo que está buscando se llaman verificación formal y programación basada en contratos , donde este último es una forma fácil de programar para hacer lo primero. En la programación basada en contratos, primero debe escribir su código de manera normal y luego insertar los llamados contratos en el código. Un lenguaje fácil de usar que se basa en este paradigma es Spec # de Microsoft Research, y la extensión de contratos de código funcionalmente similar pero un poco menos bonita para C # que ambos pueden probar en línea (también tienen herramientas similares para otros idiomas, consulte rise4fun ) El "int con tipo de rango" que mencionó se reflejaría en dos contratos en una función:
Contract.Requires(-3 <= a && a <= 24);
Contract.Requires( 3 <= b && b <= 10);
Si desea llamar a esa función, debe usar parámetros que se aseguren de cumplir con estos criterios, u obtendrá un error de tiempo de compilación. Los anteriores son contratos muy simples, puede insertar casi cualquier suposición o requisito sobre variables o excepciones y su relación que pueda pensar y el compilador verificará si cada requisito está cubierto por una suposición o algo que pueda garantizarse, es decir, derivado de los supuestos Es por eso de donde proviene el nombre: la persona que llama establece requisitos , la persona que llama se asegura de que se cumplan, como en un contrato comercial.
Bajo el capó, los contratos de código generalmente se combinan con el conocimiento sobre el funcionamiento interno (semántica operativa) del lenguaje de programación en una lista de condiciones de verificación . Esta lista representa básicamente una gran proposición lógica con variables libres: las entradas de su programa. Si la proposición es verdadera para todas las asignaciones de variables posibles, entonces el programa se considera correcto. Para verificar si este es o no el caso, un Probador SMTn PP(x1,x2,...,xn)nPes usado Desde el lado de la CS, esas dos son las partes críticas del proceso: la generación de condiciones de verificación es complicada y SMT es un problema NP-completo o indecidible, dependiendo de las teorías consideradas. Incluso hay una competencia para los solucionadores SMT, por lo que ciertamente se investiga un poco al respecto. Además, existen enfoques alternativos para usar SMT para la verificación formal, como la enumeración del espacio de estado, la verificación de modelos simbólicos, la verificación de modelos acotados y muchos más que también se están investigando, aunque SMT es, afaik, actualmente el enfoque más "moderno".
En cuanto a los límites de la idea general:
- Como se indicó anteriormente, demostrar que el programa es correcto es un problema computacionalmente difícil, por lo que es posible que la verificación del tiempo de compilación de un programa con contratos (u otra forma de especificación) tome mucho tiempo o incluso sea imposible. Aplicar la heurística que funciona bien la mayor parte del tiempo es lo mejor que se puede hacer al respecto.
- Cuanto más especifique sobre su programa, mayor será la probabilidad de tener errores en la propia especificación . Esto puede conducir a falsos positivos (la comprobación del tiempo de compilación falla aunque todo esté libre de errores) o la falsa impresión de estar seguro, aunque su programa todavía tenga errores.
- Escribir contratos o especificaciones es realmente un trabajo tedioso y la mayoría de los programadores son demasiado vagos para hacerlo. Intente escribir un programa C # con contratos de código en todas partes, después de un tiempo pensará "vamos, ¿es realmente necesario?". Es por eso que la verificación formal generalmente solo se usa para el diseño de hardware y los sistemas críticos de seguridad, como el software que controla aviones o automóviles.
Una última cosa que vale la pena mencionar que no se ajusta del todo a la explicación anterior es un campo llamado "Teoría de la complejidad implícita", por ejemplo, este artículo . Su objetivo es caracterizar los lenguajes de programación en los que cada programa que puede escribir se encuadra en una clase de complejidad específica, por ejemplo P. En dicho lenguaje, cada programa que escribe se "asegura" automáticamente para que tenga un tiempo de ejecución polinómico, que se puede "verificar" en tiempo de compilación simplemente compilando el programa. Sin embargo, no conozco ningún resultado prácticamente utilizable de esta investigación, pero también estoy lejos de ser un experto.