Saltar al contenido principal

Visión general

Las Constantes (Constants) y las Tablas de búsqueda (Lookup Tables) son la forma en que separas los parámetros de un modelo de su lógica. En lugar de codificar valores dentro de las expresiones, los nombras, los almacenas en un solo lugar y los referencias desde cualquier parte. Cambia el valor nombrado una vez, y cada expresión que lo referencia se actualiza automáticamente. Esto importa por tres razones:
  1. Ajuste — modifica parámetros del modelo sin cazar a través de expresiones. Cambia BASE_PROCESSING_TIME de 60 a 75 y cada componente relevante sigue.
  2. LegibilidadSHIFT_EFFICIENCY_FACTOR es más fácil de entender que 0.87 esparcido por las expresiones.
  3. Acceso no técnico — los operadores y analistas que no deberían modificar Expresiones (Expression) aún pueden afinar el modelo cambiando los valores de las constantes.
Tanto las Constantes como las Tablas de búsqueda están limitadas a la fábrica (factory) — viven a nivel de fábrica y pueden reutilizarse entre modelos. Pero cada modelo tiene que optar por participar listando el slug de la constante o tabla de búsqueda en los arreglos constants[] / lookup_tables[] de su metadata.json. Una constante que existe en la fábrica pero no está en la lista de opt-in del modelo es invisible para ese modelo.

Constantes

Una Constante es un valor nombrado con un tipo específico: number, text o boolean. Cada constante tiene:
  • Name — cómo las expresiones la referencian. Los nombres usan SCREAMING_SNAKE_CASE (por ejemplo, BASE_CYCLE_TIME)
  • Description — qué representa y qué unidades
  • Typenumber, text o boolean
  • Value — los datos reales
El tipo es text, no string. El enum del esquema es ["boolean", "text", "number"]. Escribir "type": "string" en una definición de constante falla la validación. El desplegable Type de la UI etiqueta la opción Text.
Los nombres se convierten automáticamente a mayúsculas mientras escribes. La entrada del nombre de constante transforma la entrada en el lado del cliente a SCREAMING_SNAKE_CASE: escribir lowercase_name se guarda como LOWERCASE_NAME. Los guiones bajos que escribes se preservan; los espacios no se añaden por ti. Referencia el nombre tal como queda después de la transformación.
Referencia una constante por su nombre en cualquier expresión:
BASE_CYCLE_TIME * SHIFT_EFFICIENCY_FACTOR

Constantes vs. variables de estado

Las Constantes son estáticas durante la duración de una ejecución (Run) — no pueden ser reasignadas. Para mutar un valor durante la simulación, usa una Variable de estado en su lugar. Las variables de estado exponen una acción assign en tiempo de ejecución que las constantes no tienen. Una constante es la herramienta correcta para un parámetro que afinas entre ejecuciones. Una variable de estado es la herramienta correcta para un valor que la simulación misma cambia: turno actual, contador móvil de WIP, señal de demanda.

Cuándo usar una constante

  • Cualquier valor que aparezca en múltiples lugares. Si te encuentras escribiendo 0.87 en varias expresiones, extráelo a una constante.
  • Cualquier valor que podrías querer cambiar entre ejecuciones. Edita la constante, captura una nueva Instantánea (Snapshot), y la instantánea congela ese valor para comparación downstream.
  • Cualquier valor que un interesado no técnico pueda necesitar ajustar. Los analistas pueden afinar una constante sin conocer el lenguaje de expresiones.
Los Experimentos no barren constantes automáticamente. Un Experimento compara Instantáneas, no valores de parámetros directamente. Para barrer una constante a través de un experimento, cambia su valor, captura una instantánea, cámbiala de nuevo, captura otra instantánea, luego añade ambas instantáneas al experimento.

Gestión de constantes

Las constantes viven en el modal Lookups en el panel Library del Modelador (Modeler) — haz clic en el botón Lookups en la parte inferior de la Library y abre la pestaña Constants. El mismo modal también aloja Lookup Tables, State Variables y Topics, cada uno en su propia pestaña. Añade, edita o elimina constantes allí: los cambios se propagan a cada modelo en la fábrica que tenga la constante en su lista de opt-in. Cada constante se almacena en factory/constants/{slug}.json.

Tablas de búsqueda

Una Tabla de búsqueda (Lookup Table) es una tabla nombrada con claves tipadas consultable en expresiones. Cada tabla tiene un tipo de valor (number, text o boolean) y una o más claves (llamadas “Attributes” en la UI). Las claves mismas están tipadas — cada una puede ser boolean, text o number — por lo que una búsqueda multidimensional puede mezclar tipos de clave. Consulta una tabla con LOOKUP:
LOOKUP(cycle_times, ENTITY_TYPE)

Proporcionar un valor de respaldo

LOOKUP acepta un argumento de palabra clave opcional default:= que devuelve el valor proporcionado cuando ninguna fila coincide:
LOOKUP(yield_rates, ENTITY_TYPE, default:=0.95)
Esta es la forma canónica de darle un valor de respaldo a una búsqueda. Siempre prefiere default:= sobre envolver en IF() — es una sola expresión sin doble evaluación de la misma búsqueda.
Sin default:=, las filas faltantes devuelven el cero específico del tipo0 para una tabla numérica, "" (cadena vacía) para una tabla de texto, FALSE para una tabla booleana. Ese cero es silencioso y fácilmente confundido con un resultado real. Usa default:= siempre que la diferencia entre “ninguna fila coincidió” y “el valor es exactamente cero” importe.
La sintaxis de argumento de palabra clave usa := (estilo morsa) — no = (que significa igualdad). El mismo := se usa para los argumentos de palabra clave filter:= y type:= en funciones de agregación.

Búsquedas multidimensionales

Una Tabla de búsqueda puede configurarse con más de una columna clave, por lo que una sola tabla puede capturar datos que varían a través de dos o más ejes a la vez — como “tiempo de procesamiento por (tipo de producto, estación)” o “tasa de rendimiento por (turno, clase de material)”. Consulta con un argumento posicional por columna clave, en el orden que la tabla los define:
LOOKUP(cycle_times_by_station, ENTITY_TYPE, station_name)
LOOKUP(cycle_times_by_station, ENTITY_TYPE, station_name, default:=180)
Cada columna clave tiene su propio tipo y una lista de permitidos possible_keys opcional (un arreglo de valores contra los que validar). Las llamadas a LOOKUP con múltiples claves coinciden con filas donde todas las columnas clave igualan los valores que pasas. Un argumento por columna clave. No hay sintaxis comodín ni de coincidencia parcial: siempre pasa exactamente tantas claves como define la tabla.

Gestión de tablas de búsqueda

Las Tablas de búsqueda se gestionan en el mismo modal Lookups que las Constantes — ábrelo desde el panel Library y cambia a la pestaña Lookup Tables. Cada tabla se almacena en factory/lookup_tables/{slug}.json con un value_type de nivel superior, un arreglo de keys tipadas (la UI las etiqueta como Attributes) y filas.

Cuándo usar una tabla de búsqueda

  • Valores que varían según un atributo categórico. Tiempo de procesamiento por tipo de producto, tasa de rendimiento por material, peso de prioridad por nivel de cliente — todas búsquedas naturales.
  • Enrutamiento y divisiones proporcionales. Diferentes entidades se enrutan de manera diferente; almacena las reglas de enrutamiento en una tabla en lugar de expresiones IF profundamente anidadas.
  • Configuración basada en datos. Cuando la “configuración” de un modelo es realmente un conjunto de números ligados a categorías, una tabla de búsqueda es más clara que codificar la misma información a través de muchos campos.

Constantes vs. tablas de búsqueda — ¿cuál usar?

  • Valor único usado en muchos lugares → Constante
  • Valor que depende de un atributo categórico → Tabla de búsqueda
  • Necesita ser barrido a través de instantáneas en un experimento → Constante (un valor por instantánea)
  • Conjunto de datos de referencia grande → Tabla de búsqueda
Es común usar ambos: una constante para un factor global, una búsqueda para tasas por tipo, combinadas en una expresión.

Patrones

Tiempo de procesamiento por producto:
LOOKUP(cycle_times, ENTITY_TYPE) * BASE_PROCESSING_FACTOR
Costo o recargo condicional con respaldo seguro:
IF(priority == "rush",
   LOOKUP(rush_surcharges, ENTITY_TYPE, default:=0),
   LOOKUP(standard_rates, ENTITY_TYPE, default:=0))
Dinámicas de turno ajustables:
IF(SIM_TIME < SHIFT_1_END,
   BASE_RATE * SHIFT_1_EFFICIENCY,
   BASE_RATE * SHIFT_2_EFFICIENCY)

Consejos

  • La aritmética del DSL es estricta en tipos. Los números se suman a números; el texto no se coerce silenciosamente. Captura desajustes de tipo en validación en lugar de depender de conversiones silenciosas.
  • Usa default:= defensivamente. Si una fila de búsqueda faltante debería ser cualquier cosa diferente del cero del tipo, default:= es más corto y claro que un envoltorio IF() alrededor de dos llamadas a LOOKUP.
  • Cada modelo opta por participar. Añadir una constante o búsqueda a nivel de fábrica es el primer paso. Los arreglos constants[] / lookup_tables[] del metadata.json del modelo deciden si ese modelo la ve.