Una función booleana recibe valores verdaderos o falsos y produce un único resultado booleano. Describe decisiones, validaciones y el comportamiento de las puertas lógicas que forman los circuitos digitales.
El tema anterior estudió las operaciones del álgebra de Boole. Ahora las usamos para definir funciones: reglas que reciben una combinación de entradas binarias y devuelven un valor binario.
Una condición de un if, una regla de permisos, un filtro de datos y una puerta digital pueden verse como funciones booleanas. La tabla de verdad es su especificación más directa.
Una función booleana de n variables es una función cuyo dominio es {0, 1}n y cuyo codominio es {0, 1}:
El dominio contiene todas las combinaciones posibles de n entradas. Como cada entrada tiene dos valores, hay 2n combinaciones que la función debe definir.
Una tabla de verdad enumera cada combinación de entradas y el resultado de la función. Para dos variables hay cuatro filas.
| p | q | f(p, q) = p ∧ q |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
La tabla no deja casos implícitos: indica exactamente qué resultado produce la función para cualquier entrada permitida.
Una función de n variables tiene 2n filas en su tabla. Cada fila puede asignarse independientemente a 0 o 1, por lo que el número de funciones booleanas distintas es:
El crecimiento es muy rápido. Con cuatro variables ya hay 65 536 funciones posibles, aunque muchas no tienen un nombre especial ni una expresión sencilla.
Las cuatro funciones booleanas posibles de una variable son la constante falsa, la identidad, la negación y la constante verdadera.
| p | 0 | p | ¬p | 1 |
|---|---|---|---|---|
| 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 1 | 0 | 1 |
Una función constante ignora su entrada. La identidad la conserva y la negación la invierte. Estas operaciones simples se combinan para construir funciones más complejas.
| p | q | AND | OR | XOR | NAND | NOR |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 |
XOR es verdadero cuando exactamente una entrada es verdadera. NAND y NOR son las negaciones de AND y OR, respectivamente; más adelante veremos que cada una de ellas puede construir cualquier función booleana.
const and = (p, q) => p && q;
const or = (p, q) => p || q;
const not = p => !p;
const xor = (p, q) => p !== q;
const nand = (p, q) => !(p && q);
const nor = (p, q) => !(p || q);
console.log(xor(true, false)); // true
console.log(nand(true, true)); // false
console.log(nor(false, false)); // trueLa desigualdad estricta entre booleanos implementa XOR porque true !== false y false !== true, mientras que entradas iguales producen false.
La función mayoría de tres entradas vale 1 cuando al menos dos de las tres entradas valen 1. Se usa como modelo de votación y como componente de ciertos circuitos.
La expresión muestra una forma natural de describir la regla: cada término cubre uno de los pares que basta para obtener mayoría.
function mayoria(p, q, r) {
return (p && q) || (p && r) || (q && r);
}
console.log(mayoria(false, true, true)); // true
console.log(mayoria(false, true, false)); // falseUna alternativa es contar valores verdaderos, pero la expresión booleana comunica directamente la estructura lógica y se traduce de manera inmediata a puertas digitales.
Dos funciones booleanas son iguales si devuelven el mismo valor para cada combinación de entradas. No importa que sus expresiones tengan formas distintas.
La equivalencia puede demostrarse con una tabla de verdad o aplicando leyes del álgebra de Boole, como la absorción.
Para un número pequeño de variables, un programa puede enumerar todas las combinaciones binarias y evaluar una función.
function tablaDeVerdad(cantidadVariables, funcion) {
const filas = [];
const total = 2 ** cantidadVariables;
for (let numero = 0; numero < total; numero++) {
const entradas = Array.from({ length: cantidadVariables }, (_, indice) => {
const desplazamiento = cantidadVariables - indice - 1;
return Boolean((numero >> desplazamiento) & 1);
});
filas.push({ entradas, salida: funcion(...entradas) });
}
return filas;
}
console.log(tablaDeVerdad(2, xor));El código interpreta cada número entre 0 y 2n - 1 como una combinación de bits. Es adecuado para tablas pequeñas; para muchas variables, 2n filas crecen demasiado rápido.
Un mintermino es una conjunción que contiene todas las variables, negando las que valen 0 y dejando sin negar las que valen 1. Cada mintermino vale 1 en exactamente una fila de la tabla.
La suma lógica, es decir OR, de los minterminos correspondientes a las filas donde una función vale 1 produce una representación canónica de la función.
La forma normal disyuntiva o suma de productos expresa una función como OR de minterminos. Es una forma canónica cuando se incluyen todos los minterminos de las filas con salida 1.
Esta representación siempre existe porque una tabla de verdad enumera todas las entradas. No siempre es la expresión más corta; la simplificación busca reducir términos y variables.
Un maxtermino es una disyunción que vale 0 en exactamente una fila. La forma normal conjuntiva o producto de sumas usa AND de los maxterminos de las filas donde la función vale 0.
Las formas disyuntiva y conjuntiva describen la misma función desde perspectivas complementarias. La primera enumera las entradas aceptadas; la segunda enumera las combinaciones que se deben evitar.
Una forma canónica puede tener muchos términos. Las leyes booleanas permiten obtener una expresión equivalente más pequeña.
Para pocas variables, las tablas de Karnaugh ayudan a visualizar agrupamientos de filas adyacentes. Para expresiones grandes se usan algoritmos de minimización y herramientas de síntesis lógica.
Un conjunto de conectivos es funcionalmente completo si permite expresar cualquier función booleana. AND, OR y NOT forman un conjunto completo, pero NAND por sí sola también lo es, al igual que NOR por sí sola.
Esta propiedad es importante para la electrónica digital: un circuito puede fabricarse usando una sola familia de puertas universales.
Podemos usar la salida de una función booleana como entrada de otra. Así se construyen expresiones y circuitos de mayor complejidad a partir de componentes pequeños.
En programación, dividir una condición compleja en funciones con nombres claros facilita probarla y reduce el riesgo de confundir la prioridad de los operadores.
Una validación es una función booleana: recibe datos, evalúa condiciones y responde si son aceptables según una regla. Por ejemplo, una cuenta puede requerir correo válido, contraseña suficiente y aceptación de términos.
function registroValido(correoValido, contrasenaSegura, aceptaTerminos) {
return correoValido && contrasenaSegura && aceptaTerminos;
}
console.log(registroValido(true, true, true)); // true
console.log(registroValido(true, false, true)); // falseSeparar cada predicado permite explicar por qué una entrada no es válida y probar todos los casos relevantes sin repetir la lógica de la regla principal.
Los filtros de colecciones son predicados: funciones que devuelven un booleano para cada elemento. Combinarlos con AND, OR y NOT construye búsquedas complejas.
const productos = [
{ nombre: "Teclado", enStock: true, precio: 40 },
{ nombre: "Monitor", enStock: false, precio: 180 },
{ nombre: "Mouse", enStock: true, precio: 25 }
];
const visibles = productos.filter(producto =>
producto.enStock && producto.precio <= 50
);
console.log(visibles); // Teclado y MouseLa función pasada a filter define formalmente qué elementos pertenecen al resultado. Ajustar un filtro equivale a modificar una función booleana.
Las tablas de verdad son exhaustivas, pero su tamaño es exponencial. Con 10 variables hay 1 024 filas; con 20 hay más de un millón.
La explosión combinatoria explica por qué el diseño de funciones lógicas complejas requiere abstraer, simplificar y verificar propiedades sin enumerar siempre todos los casos.
Las funciones booleanas convierten reglas lógicas en objetos que se pueden especificar, simplificar, probar y componer. En el próximo tema veremos cómo estas funciones se implementan físicamente mediante circuitos combinacionales.