Debilitamiento (Weakening): Podemos añadir una premisa.
Contracción (Contraction): Podemos cancelar una premisa redundante.
Demostración por Contradicción: Asumes que A es falsa y llegas a una contradicción, por lo tanto, concluyes A.
| Lógica | Debilitamiento | Contracción | por Contradicción |
|---|---|---|---|
| Clásica | ✓ | ✓ | ✓ |
| Intuicionista | ✓ | ✓ | X |
| Afín | ✓ | X | * |
| Lineal | X | X | * |
*: Podemos tener lógica lineal clásica y lineal intuicionista, dependiendo de si aceptamos o no, como axioma, el principio del tercio excluso; igual para la lógica afín. Recordemos que un axioma es aquello que aceptamos como verdad sin una demostración o, bajo la correspondencia Curry-Howard, sin un algoritmo.
Tanto en lógica lineal como en la afín, las proposiciones ahora se tratan como recursos.
- Lógica Afín: Un recurso se usa como máximo una vez (0 o 1). No puedes duplicarlo, pero sí puedes ignorarlo o descartarlo (esto es el debilitamiento).
- Lógica Lineal: Un recurso se usa exactamente una vez (1 y solo 1).
- No puedes duplicarlo (porque no hay contracción).
- No puedes ignorarlo ni descartarlo (porque no hay debilitamiento).
¿Cuál es la regla #1 de Rust? Que un valor tiene un único dueño y se usa, como máximo, una vez.
En Rust, el sistema de ownership asegura que los recursos tengan un único dueño.
fn main() {
let s1 = String::from("hola mundo");
// El recurso se mueve de s1 a s2.
// s2 es el nuevo dueño.
let s2 = s1;
// Si intentas hacer esto, el compilador lanzará un error:
println!("{}", s1); // ¡Error! s1 ya fue consumido.
}Por lo tanto, Rust, en el fondo, trabaja con un sistema de tipos afín intuicionista.
En lógica lineal introducimos una nueva implicación, la implicación lineal (que se lee como ” se consume para producir ”), y una nueva conjunción, (tener ambos recursos simultáneamente).
Veamos ejemplos de tautologías clásicas que fallan en lógica lineal:
1. Falla por falta de Contracción:
- Clásicamente: Si asumo , es cierto que tengo .
ej1 :: a -> (a, a)
ej1 x = (x, x)Linealmente: Esto es inválido. Un solo recurso no puede producir dos recursos .
{-# LANGUAGE LinearTypes #-}
ej1 :: a %1 -> (a, a)
ej1 x = (x, x) -- ERROR: x se usa dos veces2. Falla por falta de Debilitamiento:
- Clásicamente: (Eliminación de la conjunción).
ej2 :: (a, b) -> a
ej2 (x, _) = xLinealmente: Es inválido. Si tienes los recursos A y B, y produces solo A, ¿qué le pasó a B? La lógica lineal exige que B sea consumido de alguna manera.
ej2 :: (a, b) %1 -> a
ej2 (x, y) = x -- ERROR: y no se ha consumidoAhora veamos teoremas que sí son válidos en lógica lineal: (La identidad lineal)
ej3 :: a %1 -> a
ej3 x = x(El modus ponens lineal)
ej4 :: (a %1 -> b, a) %1 -> b
ej4 (f, x) = f x