22. Funciones como relaciones especiales

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.

22.1 Introducción

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.

22.2 La función como subconjunto del producto cartesiano

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:

f ⊆ A × B tal que: 1. Para todo a ∈ A existe al menos un b con (a, b) ∈ f [existencia] 2. Si (a, b) ∈ f y (a, c) ∈ f entonces b = c [unicidad]

Juntas, estas condiciones dicen que cada a aparece como primera componente en exactamente un par de f.

22.3 Condición de unicidad en pares

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

22.4 Grafo dirigido de una función

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.

Función válida: 1 ──→ x 2 ──→ y 3 ──→ x No es función (unicidad violada): 1 ──→ x 1 ──→ z ← dos flechas desde 1 2 ──→ y No es función (existencia violada): 1 ──→ x 2 ──→ y (3 sin flecha)

22.5 Matriz de una función

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.

f = {(1,x), (2,y), (3,x)} con A={1,2,3}, B={x,y,z} x y z 1 [ 1 0 0 ] 2 [ 0 1 0 ] 3 [ 1 0 0 ]
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.

22.6 Qué hereda la función de las relaciones

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 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 Limitar el dominio conserva la condición de función

22.7 Composición de funciones es 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}.

22.8 La inversa de una función no siempre es función

Si f no es inyectiva, su inversa f⁻¹ asigna más de una preimagen a algún elemento del codominio, violando la unicidad.

f = {(1, x), (2, x), (3, y)} f⁻¹ = {(x, 1), (x, 2), (y, 3)} ↑ x tiene dos preimágenes → f⁻¹ no es función
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

22.9 Restricción de una función

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.

22.10 Función identidad

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

22.11 Comparación: relación general vs. función

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

22.12 Errores comunes

  • Creer que toda relación es una función: una relación solo es función si cumple existencia y unicidad.
  • Confundir la inversa de una función con la función inversa: la inversa como relación siempre existe, pero como función solo si f es biyectiva.
  • Suponer que la unión de dos funciones es siempre una función: puede violar la unicidad.
  • Olvidar verificar la existencia: que todos los elementos del dominio tengan imagen.
  • Confundir restricción con composición: restringir reduce el dominio, componer encadena dos funciones.

22.13 Qué debes recordar de este tema

  • Una función es un subconjunto de A × B con existencia y unicidad en la primera componente.
  • En la matriz de una función, cada fila tiene exactamente un 1.
  • En el grafo de una función, cada nodo del dominio tiene exactamente una flecha saliente.
  • La composición de dos funciones siempre produce una función.
  • La inversa de una función es una función solo si la original es biyectiva.
  • La restricción de una función a un subdominio siempre produce una función.
  • La función identidad es el elemento neutro de la composición de funciones.

22.14 Conclusión

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.