Una función no es más que una relación binaria que cumple dos condiciones sobre sus pares. Al entenderlas así, todas las herramientas del álgebra de relaciones quedan disponibles para estudiarlas.
En el tema anterior introdujimos el concepto de función. En este tema profundizamos en su naturaleza como relación binaria: veremos exactamente qué condiciones sobre los pares ordenados hacen que una relación sea una función, y cómo esto nos permite aprovechar todo lo que ya sabemos sobre relaciones.
Esta perspectiva unifica dos ramas del curso y permite razonar sobre funciones usando matrices, grafos dirigidos y las operaciones algebraicas que ya conocemos.
Una función f : A → B es, ante todo, un subconjunto del producto cartesiano A × B. Lo que la distingue de una relación general es que ese subconjunto debe satisfacer dos condiciones sobre la primera componente de sus pares:
Juntas, estas condiciones dicen que cada a aparece como primera componente en exactamente un par de f.
La condición de unicidad puede reformularse: si en la relación hay dos pares con la misma primera componente, sus segundas componentes deben coincidir.
// Verifica existencia y unicidad sobre el dominio dado
function esFuncion(dominio, relacion) {
for (const a of dominio) {
const imagenes = relacion
.filter(([x]) => x === a)
.map(([, y]) => y);
if (imagenes.length === 0) {
console.log(`Falta imagen para ${a}: viola existencia`);
return false;
}
if (new Set(imagenes).size > 1) {
console.log(`${a} tiene varias imágenes distintas: viola unicidad`);
return false;
}
}
return true;
}
const A = [1, 2, 3];
const f = [[1, 'x'], [2, 'y'], [3, 'x']]; // función válida
const g = [[1, 'x'], [1, 'z'], [2, 'y'], [3, 'x']]; // viola unicidad
const h = [[1, 'x'], [2, 'y']]; // viola existencia (falta 3)
console.log(esFuncion(A, f)); // true
console.log(esFuncion(A, g)); // false
console.log(esFuncion(A, h)); // false
Al representar una función como grafo dirigido, su condición se hace visual: de cada nodo del dominio sale exactamente una flecha. Nunca cero, nunca dos o más.
En la matriz booleana de una función, cada fila tiene exactamente un 1. Esa es la traducción matricial de la condición de unicidad y existencia.
function matrizDeFuncion(dominio, codominio, f) {
return dominio.map(a => {
const par = f.find(([x]) => x === a);
return codominio.map(b => par && par[1] === b ? 1 : 0);
});
}
const A = [1, 2, 3];
const B = ['x', 'y', 'z'];
const f = [[1, 'x'], [2, 'y'], [3, 'x']];
const M = matrizDeFuncion(A, B, f);
M.forEach(fila => console.log(fila));
// [1, 0, 0]
// [0, 1, 0]
// [1, 0, 0]
Cada fila suma exactamente 1. Si alguna fila sumara 0 o más de 1, la relación no sería una función.
Al ser una relación, una función hereda todas las operaciones que ya conocemos. Sin embargo, no todas ellas producen otra función:
| Operación | ¿El resultado es siempre función? | Observación |
|---|---|---|
| Inversa f⁻¹ | No siempre | Solo si f es biyectiva |
| Composición g ∘ f | Sí | La composición de funciones es función |
| Unión f ∪ g | No siempre | Puede violarse la unicidad si f y g difieren en algún punto |
| Intersección f ∩ g | No siempre | Puede violarse la existencia si f y g difieren en algún punto |
| Restricción al dominio A'⊆A | Sí | Limitar el dominio conserva la condición de función |
Si f : A → B y g : B → C son funciones, su composición g ∘ f : A → C también es una función. La unicidad se conserva porque cada paso aplica exactamente una imagen.
function componer(f, g) {
// f: pares (a, b), g: pares (b, c)
// resultado: pares (a, c)
const resultado = [];
for (const [a, b] of f) {
const parG = g.find(([x]) => x === b);
if (parG) resultado.push([a, parG[1]]);
}
return resultado;
}
const f = [[1, 'p'], [2, 'q'], [3, 'p']]; // f: {1,2,3} → {p,q}
const g = [['p', 10], ['q', 20]]; // g: {p,q} → {10,20}
const gof = componer(f, g);
console.log(gof);
// [[1, 10], [2, 20], [3, 10]]
El resultado es una función válida: cada elemento de {1, 2, 3} tiene exactamente una imagen en {10, 20}.
Si f no es inyectiva, su inversa f⁻¹ asigna más de una preimagen a algún elemento del codominio, violando la unicidad.
function esFuncion(dominio, relacion) {
return dominio.every(a => {
const imagenes = relacion.filter(([x]) => x === a);
return imagenes.length === 1;
});
}
function inversa(relacion) {
return relacion.map(([a, b]) => [b, a]);
}
const f = [[1, 'x'], [2, 'x'], [3, 'y']];
const fInv = inversa(f);
const codominioF = ['x', 'y'];
console.log(fInv); // [['x',1],['x',2],['y',3]]
console.log(esFuncion(codominioF, fInv)); // false
Dada una función f : A → B y un subconjunto A' ⊆ A, la restricción de f a A' es la función f|_{A'} : A' → B formada por los pares de f cuya primera componente está en A'.
function restringir(f, subdominio) {
return f.filter(([a]) => subdominio.includes(a));
}
const f = [[1, 'x'], [2, 'y'], [3, 'x'], [4, 'z']];
const subA = [1, 3];
console.log(restringir(f, subA));
// [[1, 'x'], [3, 'x']]
La restricción siempre produce una función válida sobre el subdominio elegido.
La función identidad sobre A, escrita id_A, es la relación {(a, a) | a ∈ A}. Asigna a cada elemento sí mismo. Es una función porque cada a tiene exactamente una imagen: a.
function identidad(conjunto) {
return conjunto.map(a => [a, a]);
}
function componer(f, g) {
const resultado = [];
for (const [a, b] of f) {
const parG = g.find(([x]) => x === b);
if (parG) resultado.push([a, parG[1]]);
}
return resultado;
}
const A = [1, 2, 3];
const f = [[1, 'x'], [2, 'y'], [3, 'x']];
const idA = identidad(A);
// f ∘ id_A debe ser igual a f
console.log(JSON.stringify(componer(idA, f)) === JSON.stringify(f)); // true
| Característica | Relación general | Función |
|---|---|---|
| Pares por elemento del dominio | Cero, uno o varios | Exactamente uno |
| Notación de imagen | No aplica directamente | f(a) = b |
| Filas en la matriz | Cualquier combinación de 0s y 1s | Exactamente un 1 por fila |
| Flechas en el grafo | Cualquier cantidad por nodo | Exactamente una por nodo del dominio |
| Composición | Siempre posible | Siempre posible y produce función |
| Inversa | Siempre existe como relación | Solo es función si f es biyectiva |
Ver las funciones como relaciones especiales permite aplicarles todo el aparato del álgebra de relaciones: matrices, grafos, composición e inversa. La condición de que cada elemento del dominio tenga exactamente una imagen es la clave que diferencia a las funciones de las relaciones generales, y la que les da su poder computacional.
En el próximo tema estudiaremos en detalle el dominio, el codominio y la imagen de una función, y las diferencias prácticas entre estos tres conceptos.