De la redacción
El Buen Tono
La indexación inversa de dependencias es una técnica de programación que permite identificar qué elementos deben actualizarse cuando cambia un dato, sin recorrer todo un sistema para descubrir cuáles dependen de él.
La propuesta, desarrollada en el marco del proyecto .me, utiliza un índice inverso que registra qué cálculos dependen de cada dato. De esta manera, el sistema puede localizar los elementos afectados y actualizar únicamente esos resultados.
1. Ejemplo de código: registrar dependencias automáticamente
El siguiente fragmento muestra cómo una fórmula puede calcularse a partir de otros datos y cómo el sistema puede registrar las relaciones necesarias para mantenerla actualizada.
me.districts[42].loadPercent = () =>
city.sensors[42].vehicles * 0.8;
En este ejemplo, el resultado loadPercent depende del valor de vehicles en el sensor 42. El motor registra esa relación cuando detecta que la fórmula lee dicho dato.
La dependencia queda representada conceptualmente de esta manera:
sensors[42] → district 42
Cuando cambia el valor del sensor, el sistema consulta el índice inverso y localiza directamente el distrito que depende de él, en lugar de examinar todos los nodos del grafo.
2. Ejemplo de código: dividir gastos entre varias personas
El proyecto también muestra cómo utilizar las dependencias para calcular cuánto debe pagar cada integrante de un grupo y determinar el saldo individual.
me.wallets.vancouver.total(0);
me.wallets.vancouver["="](
"per_person",
"total / members.count"
);
me.wallets.vancouver.paid.jabellae(0);
me.wallets.vancouver["="](
"balance_jabellae",
"paid.jabellae - per_person"
);
En este caso, el sistema define cuatro elementos:
total: el importe total que se debe repartir.per_person: la cantidad correspondiente a cada integrante.paid.jabellae: el importe pagado por una persona.balance_jabellae: la diferencia entre lo que pagó y lo que le corresponde.
Cuando se modifica el total o la cantidad de integrantes, el cálculo por persona puede actualizarse. Si cambia el importe pagado por Jabellae, el sistema puede recalcular su saldo sin modificar los resultados de las demás personas que no dependen de ese dato.
3. Ejemplo de código: actualizar únicamente los cálculos afectados
Una de las características principales de esta arquitectura es la propagación selectiva de los cambios.
me.wallets.vancouver.paid.jabellae(300);
me.wallets.vancouver.total(300);
El primer comando registra un pago de 300 unidades monetarias. El segundo establece el total de la cuenta en 300.
Cuando se modifica paid.jabellae, el motor consulta su índice de dependencias y localiza los cálculos relacionados con ese pago.
En este ejemplo, el saldo de Jabellae depende de paid.jabellae, por lo que debe actualizarse. Otros cálculos que no utilizan ese dato no necesitan volver a ejecutarse por ese cambio.
4. Ejemplo de código: explicar cómo se obtuvo un resultado
El proyecto incorpora la función explain(), que permite inspeccionar la fórmula asociada a un resultado y conocer los valores de entrada que intervienen en su cálculo.
console.log(
me.explain("wallets.vancouver.balance_jabellae")
);
La función permite examinar información como:
- La expresión utilizada para calcular el resultado.
- Los valores de entrada que intervienen en la fórmula.
- La cantidad de nodos recalculados durante una actualización.
- La lista ordenada de rutas que fueron recalculadas.
Esto permite rastrear el origen de un resultado y conocer qué operaciones se ejecutaron para actualizarlo.
5. Ejemplo de código: medir cuántos nodos se recalcularon
El siguiente fragmento demuestra cómo comprobar el número de dependencias afectadas por un cambio.
me.units[1].seed(1);
me.units[1]["="]("mid", "seed + 1");
me.units[1]["="]("out", "mid * 2");
me.units[1].seed(2);
const trace = me.explain("units.1.out");
assert.equal(trace.meta.k, 2);
assert.deepEqual(
trace.meta.recomputed,
["units.1.mid", "units.1.out"]
);
La secuencia establece tres elementos relacionados:
seedcontiene el dato inicial.midcalcula el valor inicial más uno.outmultiplica el resultado intermedio por dos.
Cuando seed cambia de 1 a 2, el motor actualiza mid y posteriormente out.
La prueba verifica que se recalcularon exactamente dos nodos. En este caso, k representa la cantidad de elementos que tuvieron que actualizarse.
6. Comparación entre indexación tradicional e inversa
Índice tradicional
Guarda de qué datos depende cada nodo.
O(n)
Puede requerir recorrer todos los nodos para localizar los afectados.
Índice inverso
Guarda qué nodos dependen de cada dato.
O(k)
Recorre los elementos afectados, sin buscar dependencias por todo el grafo.
En estas expresiones, n representa el tamaño total del grafo y k la cantidad de elementos afectados por una modificación. El costo real también depende del trabajo necesario para recalcular cada resultado.

7. Ejemplo a gran escala: un millón de sensores
El proyecto presenta una demostración con un millón de nodos organizados en una cuadrícula de 1,000 por 1,000. En el escenario mostrado, una modificación afecta únicamente a seis nodos dependientes.
La relación se resume así:
Nodos totales: 1,000,000
Nodos afectados: 6
Complejidad: O(k)
La demostración también presenta un escenario de alta concentración de dependencias: una sola modificación puede afectar a 100,000 nodos. En ese caso, el índice inverso evita buscar cuáles son los afectados, pero sigue siendo necesario procesar los 100,000 resultados que realmente dependen del dato modificado.
8. ¿Cómo se aplica a ciudades inteligentes y robots?
La arquitectura puede utilizarse para representar sistemas donde múltiples componentes dependen de información compartida.
En una ciudad inteligente, una variación en un sensor de tráfico puede provocar la actualización de los cruces que utilizan esa información para calcular sus decisiones.
En una flota de robots, un cambio de contexto puede requerir actualizar las decisiones de los equipos que dependen de ese contexto, sin recalcular las de toda la flota.
El principio es el mismo en ambos casos: registrar quién depende de cada dato para identificar directamente los resultados que deben actualizarse.
Conclusión
La indexación inversa de dependencias propone que la eficiencia de un sistema reactivo dependa del número de elementos que realmente necesitan actualizarse y no solamente del tamaño total de su estructura.
Mediante relaciones registradas automáticamente, fórmulas derivadas y herramientas de inspección como explain(), el proyecto .me busca reducir operaciones innecesarias y facilitar el seguimiento de los cambios dentro de grafos semánticos complejos.
Los fragmentos anteriores corresponden a los ejemplos documentados del proyecto y a sus demostraciones técnicas; no constituyen el código fuente completo de su motor de ejecución.
Es gratis. Solo escribe tu correo y presiona Sign Up para suscribirte.
