Arquitectura y evidencia
Cinco capas alrededor de una frontera: dónde termina la palabra y empieza el tipo
Metamatemático es una herramienta que toma una pregunta de matemáticas escrita en castellano o en inglés, la traduce a un enunciado formal de Lean 4 y deja que el kernel decida si es cierta. No responde: verifica. Y cuando no puede verificar, dice exactamente qué falló — el veredicto tiene ocho estados, no dos.
Lo que la organiza es una sola distinción, y no se postuló: se descubrió midiendo. Antes de que exista un enunciado formal, el sistema trabaja con palabras humanas —ahí gana, y por mucho—. Después, el objeto ya es un tipo, y quien busca bien sobre tipos es Lean, no un grafo de palabras. Esa es la frontera de formalización, y de ella salen las cinco capas: tres antes (lengua, concepto, territorio), dos después (evidencia, emergencia).
Sirve a quien estudia —un veredicto sobre lo que uno mismo escribió, no sobre lo que dice el libro—, a quien enseña —comprobar que un enunciado dice lo que uno cree que dice— y a quien investiga —vocabulario de Mathlib verificado en un área que no domina—. Esta página describe cada pieza y la evidencia que la sostiene, incluida la que no la sostiene.
Leonardo Jiménez Martínez · BIOMAT, Centro de Biomatemáticas · Licencia MIT
El planteamiento
Qué es. Un traductor con verificador: convierte una pregunta en lenguaje natural en un enunciado de Lean 4 y somete ese enunciado al kernel. Lo que devuelve no es una respuesta sino un veredicto, y el código que lo sostiene.
Por qué hace falta. Un modelo de lenguaje que responde matemáticas produce texto plausible. La plausibilidad no es una demostración, y el modelo no distingue entre las dos: escribe con la misma seguridad un lema que existe y uno que ha inventado. De 28 identificadores que propuso de memoria, 21 no existían —y los 21 eran lemas, con la convención de nombres de Mathlib seguida al dedillo—. Por eso la decisión sobre qué es cierto se saca del modelo y se entrega al kernel de Lean 4, que sólo acepta lo que puede comprobar.
Eso reparte el trabajo en tres papeles que no se solapan:
El modelo de lenguaje
Traduce del castellano a Lean 4 y de vuelta. Escribe el enunciado formal y la explicación. No emite ningún juicio de verdad que llegue al alumno sin pasar por Lean.
nucleo/llm/El núcleo, en cinco capas
Antes de la frontera lee la pregunta y ofrece
vocabulario de Mathlib comprobado con #check.
Después ordena las tácticas por la forma del objetivo
y explica el resultado. No decide qué es cierto en ningún
punto.
Lean y Mathlib
Comprueba. Su veredicto es inapelable y va delante del texto de la respuesta, para que el alumno lea primero qué se ha comprobado y sólo después la prosa.
lake build · MathlibNinguna afirmación llega al alumno con sello de verificada si Lean no la ha comprobado, y el sello dice exactamente qué se comprobó. Compilar sin errores no es lo mismo que demostrar lo que se preguntó: por eso el veredicto tiene ocho estados y no dos, y tres de ellos existen justamente para nombrar los casos en que Lean acepta un archivo que no demuestra lo pedido.
Y una segunda regla, sobre la evidencia
Cada componente del núcleo lleva una medición con su modelo nulo al lado. Un porcentaje solo no dice nada: un clasificador que acierta el 61 % parece bueno hasta que se comprueba que responder siempre lo mismo acierta el 89 %. Comparar dos versiones de la propia idea tampoco es medir — es preferir.
La consecuencia es que este documento contiene componentes que no baten a su nulo, y lo dice. Tres de ellos están apagados en producción por esa razón, mediante una regla explícita (§12), no por criterio de nadie.
El flujo, de la entrada a la salida
Todo pasa por Nucleo.process(texto). Son seis pasos entre
dos fronteras de idioma. El núcleo interviene en tres de los seis; en
ninguno decide si algo es cierto.
| paso | quién | qué hace | evidencia |
|---|---|---|---|
| 1 | grafo | inyecta nombres de Mathlib verificados en el prompt_find_relevant_context | aporta · 15,7× |
| 2 | modelo | escribe Lean 4 — no juzga si es correctoLEAN_SYSTEM_PROMPT | — |
| 3 | grafo | elige qué módulos importa Lean_modulos_mathlib | inerte |
| 4 | Lean | verifica · veredicto inapelablelean/client.py | — |
| 5 | L3 | ordena las 12 tácticas ante un sorrysolver_cascade.py::TacticRanker | aporta · 3,7× |
| 6 | modelo | traduce el código que Lean aceptóEXPLICACION_SYSTEM_PROMPT | — |
La última columna es el resultado de medir cada punto por separado. No hay un veredicto único sobre «el núcleo»: aporta en el paso 1 y en el paso 5 —y por razones distintas, a un lado y a otro de la frontera de formalización (§5)— y es inerte en el 3. Resumirlo en una sola cifra sería mentir por agregación.
Conviene separar dos cosas que el paso 5 mezcló mucho tiempo: la regla por área que proponía el grafo de conceptos no batía a su nulo (1,26 frente a 1,09) y está apagada por el decisor; lo que ordena la cascada hoy es un clasificador sobre la forma del objetivo, que es otra cosa y se mide aparte.
La frontera del idioma
El alumno pregunta en castellano y todo el aparato del sistema es inglés: las palabras clave del grafo, los 183 433 hechos de Mathlib, los ejemplos few-shot de miniF2F y el propio Lean. Quien escribe «¿Es 17 un número primo?» no toca ninguna de esas palabras.
La consulta se traduce una sola vez, al entrar, con un
modelo local de 74 M de parámetros
(Helsinki-NLP/opus-mt-es-en): sin API y sin coste por consulta.
El inglés pasa directo.
Un traductor general no distingue notación de prosa. Medido sobre el modelo desnudo:
$x^2 - 5x + 6$ → $x^2 - 5x + $6
\mathbb{R}$ → \mathbb{R$
\int_0^\infty ... dx$ → int_0=infty ... dx$ (destruido)
\sin x → \without x
El último lo explica todo: \sin es el seno, y «sin» en
castellano es una preposición. Así que la notación se extrae, se sustituye
por marcas que sobreviven al tokenizador y se restituye en su sitio.
Medido sobre 200 enunciados con notación: 15 014 caracteres
de notación protegidos y 653 expuestos, con hueco en 21 de los
200.
Traducir no basta, porque el emparejador comparaba dos alfabetos. La
puntuación —primo? no es primo—
y los acentos, porque las palabras clave se escribieron
sin acentuar y el alumno escribe con ellos. Normalizar sólo la consulta
empeoraría las cosas: una palabra clave acentuada dejaría de casar.
La ñ se conserva: es una letra del alfabeto, no una
n con tilde — año → ano cambia la
palabra. Sobre 3 000 consultas etiquetadas, el grafo guarda silencio
total en el 7,7 % de los casos y activa
7,00 conceptos por consulta de media.
Y la frontera se cruza de vuelta. Si preguntó en castellano, la respuesta sale en castellano, y eso hay que fijarlo explícitamente en el prompt: el enunciado que el modelo tiene delante ya está en inglés, así que una instrucción como «responde en el idioma del usuario» le haría contestar en inglés. Lo que se le enseña como «pregunta original» es la del alumno, no la traducción, y el historial guarda lo que él escribió.
La sintaxis de la consulta
Una expresión matemática es un árbol, no una cadena. El
módulo nucleo/sintaxis/ la analiza por precedencia
—lexer, parser tipo Pratt, extractor de rasgos y revisor— y produce dos
cosas que conviene no mezclar: rasgos estructurales que
alimentan al emparejador, y un aviso para el alumno que
sólo se emite cuando merece la pena.
Los rasgos predicen qué hechos harán falta
La relación entre sintaxis y semántica se puede medir aquí sin metáforas, porque están las dos mitades: el enunciado en Lean es un objeto puramente simbólico, y los lemas que su prueba usó son lo que hizo falta en el universo matemático. Sobre 22 117 pares y los 100 lemas con suficientes ejemplos:
| representación | rasgos | cobertura | acierta alguno |
|---|---|---|---|
| modelo nulo los 6 lemas más citados | — | 56,6 % | 80,3 % |
| n-gramas de caracteres | 40 000 | 76,8 % | 94,7 % |
| estructura sintáctica | 68 | 76,3 % | 94,9 % |
| las dos juntas | 40 068 | 80,9 % | 96,8 % |
Sesenta y ocho rasgos igualan a cuarenta mil, y juntos suman cuatro puntos: no son la misma información. Y lo que aprende la estructura se puede leer, que es lo que una bolsa de n-gramas no da nunca:
| lema | el rasgo que lo predice | qué significa |
|---|---|---|
| sq_nonneg | relación principal ≤ (+2,92)en contra: = (−2,54) | los cuadrados sirven para desigualdades, no para igualdades |
| mul_pos | < o > en las hipótesis (+2,90) | hace falta cuando el signo viene supuesto |
| Real.sqrt_nonneg | √ en la conclusión (+1,67)en contra: tipo ℤ (−1,92) | no hay raíces sobre los enteros |
| mul_comm | tipo ℂ y relación =en contra: ¬ y % | no es lo que se usa en aritmética modular |
El corpus es lean_workbook y está dominado por
desigualdades: sq_nonneg aparece en el 72 % de las
pruebas, y por eso el modelo nulo ya llega al 56,6 %. Mide
recuperar premisas, no cerrar pruebas, y son 100 lemas
de los 809 que aparecen — los que tienen al menos 30 ejemplos. Los rasgos
corren sobre enunciados de Lean, que sólo existen después del paso 2.
La arquitectura: cinco capas y una frontera
El sistema y Lean hacen búsquedas distintas, y durante mucho tiempo compitieron sin saberlo. La diferencia no es de calidad: es de tipo de entrada. Eso parte el trabajo en dos mitades con dueños distintos, y la frontera es el momento en que existe un enunciado formal.
| quién busca | indexa por | necesita |
|---|---|---|
| el grafo | palabras humanas, ES/EN | prosa |
| Lean exact? · apply? · aesop | estructura del tipo, sobre ~200 000 declaraciones | un objetivo formal |
La evidencia del reparto
Antes de formalizar, con la consulta todavía en prosa, buscar sobre el índice completo no supera al azar; el vocabulario curado lo bate trece veces:
| antes de la frontera | precisión | veredicto |
|---|---|---|
| grafo curado 352 nodos | 22,8 % | 15,7× · aporta |
| índice completo de Mathlib 217 419 nombres | 1,53 % | empata con el azar |
| modelo nulo | 1,45 % | — |
Después de formalizar, con un objetivo formal delante, la búsqueda del grafo pierde por dos órdenes de magnitud:
| después de la frontera | cobertura | veredicto |
|---|---|---|
| recuperación de lemas, método léxico | 0,64 % | muy por debajo |
| recuperación de lemas, método semántico | 0,37 % | muy por debajo |
| modelo nulo los lemas más citados | 77,05 % | — |
El decisor (§12) había separado estas capacidades una a una, cada cual contra su propio nulo, antes de que nadie nombrara la frontera. Al ponerlas en fila apareció la regla: toda capacidad del grafo que actúa antes de formalizar gana, y toda la que actúa después pierde o empata. No es una tesis previa con datos buscados a posteriori; es lo que quedó cuando se apagó lo que no batía a su nulo.
Las cinco capas
consulta (ES/EN)
│
L0 LENGUA palabras clave ES/EN → concepto ANTES
L1 CONCEPTO 158 curados · vocabulario #check DE
L2 TERRITORIO 147 generados · dónde vive FORMALIZAR
│
ENUNCIADO FORMAL ←── la frontera
│
LEAN VERIFICA
│
L3 EVIDENCIA forma del objetivo → qué cierra DESPUÉS
L4 EMERGENCIA colímites sobre teoremas aceptados
│
LA RESPUESTA veredicto delante del texto
Hasta el 10 de septiembre de 2026 L3 y L4 estaban descritas y
medidas, y no estaban enchufadas. El rankeador estaba entrenado,
guardado en disco y con su cifra publicada, y
set_tactic_ranker no lo llamaba nadie: el
getattr de la cascada devolvía None en todas
las consultas y se ordenaba solo con la heurística. L4 igual —
cargar_coocurrencia_verificada existía en CR_org y en la
fachada, y el paisaje se seguía sembrando con lo que el emparejador
léxico adivinaba.
Ninguna de las dos cosas daba error. Los tests pasaban, las mediciones
eran ciertas, y el sistema que corría no era el que este documento
describía. Es la misma familia de fallo que la §16 persigue: afirmar con
más autoridad de la que se tiene. Ahora las dos corren, y hay un
guardián —tests/test_capas_cableadas.py— que falla si
alguna vuelve a quedarse desconectada.
Qué está cableado hoy
| capa | en el camino | quién la gobierna | evidencia |
|---|---|---|---|
| L0 lengua | sí | clasificacion_por_palabras_clave | 58,7 % vs 33,3 % |
| L1 concepto | sí | nombres_de_mathlib_en_el_prompt | 22,8 % vs 1,45 % |
| L2 territorio | alcance, sin nombres | — por diseño | no transfiere |
| Lean | sí | verificacion_con_leanla excepción declarada: no pasa por la regla | el veredicto |
| L3 evidencia | sí · desde hoy | modelo_de_orden_de_cascada | 0,621 vs 0,318 1,57 vs 2,44 posiciones |
| L4 emergencia | sí · desde hoy | siembra al arrancar28 pares con exceso ≥ 1,5 | exceso hasta +6,74 |
| bloque estructuralla explicabilidad en el prompt | no | contexto_estructural_en_el_prompt | sin evidencia — el decisor lo deja fuera |
El bloque estructural —prerrequisitos, tácticas sugeridas, competencia emergente y skills que suelen acompañar, que es lo que el grafo sabe por sus aristas— está escrito y apagado. Su efecto sólo se ve en lo que el modelo escribe, y eso cuesta una llamada. Este repositorio ya ha medido dos veces que añadir contenido correcto al prompt puede empeorar el resultado, así que encenderlo sin medirlo sería justo el error contra el que existe el decisor.
L0 — Lengua
Por qué. Es lo único que Lean no puede hacer: leer una
frase. Un índice de 217 419 nombres formales no contiene la correspondencia
«grupo → Group, Subgroup, MonoidHom»; ésa la escribió una
persona.
Qué muestra. 58,7 % de acierto de área equilibrado, frente
al 33,3 % de responder siempre la clase mayoritaria.
L1 — Concepto
Por qué. El modelo inventa 21 de cada 28
identificadores cuando tira de memoria.
Qué muestra. 180 de 186 nombres existen; los seis restantes
son espacios de nombres y están filtrados antes del prompt, así que la
etiqueta «verificado» es cierta para todo lo que se ofrece.
Lo que NO muestra: que eso haga verificar más a Lean. Se
midió — rescata 3, rompe 2, p = 1,0. Es puntería, no
resultado.
L2 — Territorio
Por qué. El curado nombra 190 conceptos; la taxonomía de
Mathlib tiene 1 139. Los generados dan alcance para reconocer temas.
Qué muestra. Que su vocabulario no transfiere, por
tres vías medidas: sin criba 17,45 %, criba por uso 20,77 % y cuota separada
20,18 %, frente al 21,64 % de la base. El módulo de un objeto generado es un
rincón de su área, no su centro.
L3 — Evidencia
Por qué. Pasada la frontera la pregunta ya no es «de qué
trata» sino «qué cierra esto», y eso lo decide la forma del objetivo. Cada
intento fallido cuesta una compilación de 12 a 30 segundos.
Qué hace. Un clasificador ordena la cascada combinando
n-gramas —que ven los símbolos— con 74 rasgos estructurales, que ven la
forma. No son redundantes: 60,53 % y 61,14 % por separado,
67,11 % juntos, sobre un nulo de 23,77 % —responder
siempre nlinarith—.
Qué muestra. Medido con el modelo de producción contra el
orden fijo real, sobre 1 530 casos que no vio:
| orden | posición media | 1er intento | en los 3 |
|---|---|---|---|
fijo SOLVER_CASCADE | 5,79 | 0,0 % | 36,0 % |
| modelo nulo por frecuencia | 2,44 | 42,5 % | 78,5 % |
| el rankeador | 1,57 | 71,0 % | 93,5 % |
3,7 veces menos invocaciones de Lean que el orden fijo, y bate al nulo fuerte por 0,87 posiciones. Es la pieza que más mejora la búsqueda de todo el sistema.
L4 — Emergencia
Por qué. El paisaje de CR_org, de donde salen los
patrones que se ligan en colímites, se alimentaba de lo que el emparejador
léxico adivinaba: el grafo llevaba la cuenta de sus propias
conjeturas.
Qué hace. Dos conceptos coocurren si un teorema que Lean
aceptó habla de los dos — 40 025 teoremas de Mathlib, corregido por
frecuencia.
Qué muestra. Que los pares que emergen son relaciones
genuinas, medidas por el exceso sobre lo esperado:
| exceso | par de conceptos | juntas | esperadas |
|---|---|---|---|
| +6,74 | derived-category + homological-algebra | 6 | 0,1 |
| +6,23 | measure-theory + random-variables | 9 | 0,1 |
| +5,03 | hilbert-spaces + inner-product-spaces | 22 | 0,7 |
| +4,95 | ideals-quotient-rings + ring-theory | 49 | 1,6 |
| +4,61 | commutative-algebra + ideals-quotient-rings | 49 | 2,0 |
En crudo, el cuarto par más frecuente es cic + linear-algebra
con 134 coocurrencias, y su exceso es +0,11: azar puro,
porque cic declara Type y eso sale en todos los
enunciados. Contar coocurrencias sin corregir mide qué palabras son
comunes, no qué conceptos se relacionan.
Qué parte busca y qué parte explica
Las capas no hacen todas lo mismo, y confundirlo lleva a pedirle a una lo que sólo puede dar otra.
| pieza | busca | explica | evidencia |
|---|---|---|---|
| L0 lengua | sí | poco | 58,7 % vs 33,3 % |
| L1 vocabulario | sí, y no llega al final | mucho | 22,8 % vs 1,45 %p = 1,0 en verificación |
| L2 territorio | reconoce temas | poco | no transfiere |
| L3 rankeador | la más efectiva | poco | 3,7× menos compilaciones |
| L4 coocurrencia | no | mucho | exceso hasta +6,74 |
| la reparación | sí | no | rescata 4, rompe 0 |
| 387 teoremas Lean | no | el fundamento | 62 de 63 operaciones |
La pieza que más mejora la búsqueda no es el grafo de
conceptos: es L3, el rankeador del estado de prueba, que trabaja
del lado formal de la frontera. L1 busca bien y no llega al
resultado. Y L4 no busca nada y es de lo más valioso para
explicar: no entra en el prompt ni ordena tácticas; lo que aporta es
poder decirle a un alumno que group-theory y
subgroups-cosets aparecen juntos en 206 teoremas que
Lean aceptó, veinte veces más de lo que cabría esperar por azar
(exceso +4,32).
Las dos capas de conocimiento
Hay dos almacenes con trabajos distintos, y se miden distinto. Uno dice de qué habla algo; el otro dice qué es cierto.
Por qué hacen falta las dos
De los 169 nombres que el grafo inyecta hoy, 3 son teoremas o
lemas y 166 son tipos, estructuras y clases: el grafo aporta los
sustantivos. Y ahí no es donde el modelo falla. De 28 nombres que el modelo
propuso de memoria, los 21 inexistentes eran todos lemas —
tsum_geometric_two, Subgroup.isCyclic,
isOpen_union: siguen la convención de nombres al dedillo y no
existen.
El modelo acierta razonablemente los sustantivos e inventa los hechos. La lista existe para cubrir esa mitad, y el índice de nombres (§9) para desmentir la otra.
El grafo: anatomía
Una categoría finita: 321 objetos y 1 349 morfismos, con identidad
en cada objeto y composición por transitividad. Cada nodo lleva un
sort que dice qué clase de objeto es, y ese tipado lo
hace cumplir el constructor: una dependencia mal tipada se rechaza.
Un dibujo estático no puede mostrar 352 nodos con sus nombres ni 1 578 flechas a la vez. El explorador interactivo sí: lleva el grafo completo dentro, con filtro por sort y por área, búsqueda por identificador, nombre o palabra clave, y la ficha de cada nodo — qué vocabulario lo alcanza desde una consulta, qué identificadores de Mathlib aporta al prompt, de qué depende y qué le apunta.
Se regenera desde el grafo del runtime con
scripts/exportar_grafo_web.py y
scripts/incrustar_grafo_web.py, así que no puede quedarse
desfasado en silencio.
CONCEPTO aportan nombres de Mathlib al prompt: los
MODULO y los AREA aportan estructura, y por eso
la política de ranking los sitúa detrás — un acierto de área es más grueso
que uno de concepto.Un solo grafo, cosido por el anidamiento de módulos
Los nodos generados (125) y los curados (173) están cosidos por la jerarquía
que Mathlib ya tiene escrita en el anidamiento de sus
módulos, que va de lo general a lo especial — la misma dirección
que el grafo curado sigue con group-theory → ring-theory →
field-theory. Un cuerpo es un anillo con más axiomas: la teoría
general se inyecta en la especializada.
aristas que cruzan curado ↔ generado 125 generados con ancestro curado común 109 de 125 nodos que alcanza la lógica 278 de 320
fol-deduction → zfc-axioms. ZFC es una teoría de
primer orden: sus axiomas son fórmulas de primer orden con
igualdad, el ejemplo canónico. Sin esa arista la lógica alcanzaba 158 de
352 nodos, o sea media matemática del grafo sin la lógica detrás.
Es curada, no derivada: Mathlib no construye ZFC sobre
Logic.Basic, así que el DAG de imports no la contiene. Sale
de un juicio matemático y va marcada como tal.
Lo que el esqueleto de módulos no da: los generados y
los curados son hermanos bajo un área, no descendientes, porque la
profundidad del módulo no ordena la generalidad —
LinearAlgebra.Basis está a profundidad 2 y
LinearAlgebra.Matrix.Defs a 3, y sin embargo el álgebra lineal
es más general que la noción de base. Eso requiere un juicio que Mathlib no
contiene.
Los ciclos son de la agregación, no de la matemática
Hay 134 ciclos, todos entre nodos generados; entre los 173 curados hay cero. El DAG oficial de imports es acíclico —Lean prohíbe imports circulares— pero al colapsar 7 747 módulos en conceptos de dos niveles aparecen:
Topology.Instances → Analysis.Asymptotics → Analysis.Complex → Topology.Instances
Son tres desarrollos distintos: los espacios vectoriales topológicos
necesitan la topología de ℝ≥0∞, el análisis asintótico complejo
necesita la notación Θ, y la topología de ℂ necesita su estructura normada.
Nadie dio la vuelta. El ciclo marca dónde la división en ramas deja
de funcionar, no un recorrido.
Se intentó definir las áreas por componentes fuertemente conexas, para que el corte lo dictara la estructura y no una elección de profundidad. Da una mega-área con 918 de los 1 358 conceptos — Algebra, Data, Order, Topology y Analysis en el mismo saco— más dos residuos.
A nivel de fichero Mathlib es un DAG limpio; en cuanto se agrupa por ramas, casi todo queda entrelazado. El orden en que se construye la matemática formalizada no respeta la frontera entre álgebra, topología y análisis. Las ramas son una capa humana, útil y no derivable.
La base y las fibras
El grafo tiene dos preguntas distintas sobre cada nodo, y separarlas es
lo que le da estructura: area dice de qué rama habla
—y es la base— y sort dice qué clase de
objeto es —y determina la fibra—.
sorry
(CategoryFoundations/Fibracion.lean); lo que no se cumple es
la hipótesis sobre el grafo real. No falta formalización: faltan
morfismos que crucen de área.ColimitVerifier.lean y JoinColimit.lean
exigen que la alcanzabilidad sea un preorden. Con un solo conjunto plano
eso hay que pedirlo sobre los 352 nodos. En una
estructura fibrada la delgadez se pide por fibra, y la base es un
poset por construcción: la obligación de prueba se hace más pequeña y más
honesta.
Y interpretado=False deja de ser un booleano que hay que
acordarse de respetar: como sort, una arista de dependencia
CONCEPTO → MODULO es sencillamente mal tipada, y el
constructor la rechaza.
El claim que el sistema sostiene, y con esa precisión: I es el
colímite de P en la subcategoría delgada finita Gn — no
en una categoría arbitraria. La propiedad universal, la unicidad del
mediador y el puente con CategoryTheory.Limits.IsColimit de
Mathlib están demostrados, y el Python que los implementa está auditado
contra ellos (§13).
Dos cosas distintas que Lean comprueba aquí
Los archivos de CategoryFoundations/ demuestran los
teoremas generales: que ser colímite equivale a ser join
en un preorden delgado, que el mediador es único, que la construcción
encaja con IsColimit de Mathlib. Son enunciados sobre
cualquier grafo, y se prueban una vez.
Lo que no dicen es si este nodo concreto es
colímite de este patrón en el grafo de hoy. Eso es una
afirmación sobre una instancia finita, y es decidible:
hay 321 objetos, así que el ∀ del enunciado se recorre entero.
build_colimit(…, con_lean=True) genera ese enunciado en Lean
—sin import Mathlib, para que compile en segundos— y lo
cierra con decide, que lo comprueba el kernel
y no el compilador. El veredicto queda en Colimit.lean_verified.
Tres valores, no dos. True es «el kernel
lo comprobó»; False es «el kernel lo refutó, hay un
co-cono sin mediador»; y None es «no se sabe» — no había
Lean, o no pudo terminar. Distinguir el tercero del segundo es lo único
que impide que un fallo del verificador se lea como un resultado sobre
el grafo, y no es hipotético: a escala real el kernel agotaba la
profundidad de recursión y eso salía indistinguible de una refutación.
Va apagado por defecto, porque cuesta un compilado. Y cuesta asimétrico:
refutar es barato —decide se para en el primer
contraejemplo— mientras que confirmar obliga a reducir la
conjunción entera. Medido sobre tres colímites reales del grafo: 2,6 s,
3,4 s y 15,3 s.
Al enunciado sólo viajan los morfismos que consulta —los que salen del diagrama y los que salen del ápice—, que no es una poda sino el conjunto exacto que la propiedad mira; el universo del cuantificador sigue siendo los 352 nodos. Sin ese recorte, los casos verdaderos agotaban el presupuesto del kernel a los 25 segundos.
La lista y los índices
Tres estructuras derivadas del fuente de Mathlib, con trabajos distintos: una dice qué es cierto, otra qué nombres existen, y la tercera qué herramienta puede usar cada lema.
La lista de hechos
Nombre, enunciado, módulo y concepto por cada teorema, lema e instancia. Alimenta el índice de premisas.
183 433 entradas · 54 MB121 756 theorem · 50 835 lemma
10 842 instance · 1 102 conceptos
El índice de nombres
Unifica lemas y sustantivos. Se consulta para saber si un nombre existe, para cualificarlo antes de compilar y para desmentir a la respuesta cuando afirma que un nombre real no existe.
217 419 nombres183 351 lemas + 34 084 sustantivos
El DAG oficial de imports
No hubo que reconstruirlo: Mathlib trae la herramienta hecha en
.lake/packages/importGraph.
Mathlib no etiqueta por rama — etiqueta por táctica
Se buscó una anotación de área y no existe. Lo que sí hay, en 83 111 líneas y 162 atributos distintos, es qué herramienta puede usar cada lema:
@[simp] 40 736 @[gcongr] 575 @[continuity] 255 @[norm_cast] 2 257 @[grind] 547 @[mono] 244 @[fun_prop] 1 796 @[aesop] 286 @[measurability]
Es un índice herramienta → lemas curado por los mantenedores, y
sirve para algo concreto: el 42,1 % de las premisas
que citan las pruebas ya llevan @[simp], y simp
las conoce sin que nadie se las pase. Filtrarlas movió la selección de
premisas de empatar con un prior de frecuencia (9,4 % contra
9,2 %) a superarlo: 14,0 % contra 11,7 %.
El índice de 217 419 nombres se consulta en la ruta de
formalización con tres reglas deliberadamente conservadoras: un nombre con
punto desconocido que tenga exactamente una terminación válida se
cualifica; un nombre capitalizado suelto se resuelve por los espacios de
nombres que la primera regla descubrió; y se añade el import
del módulo que lo define.
Comprobado sobre las 241 pruebas de miniF2F que ya compilaban: el reparador no modifica ninguna. Sólo actúa donde hay algo roto.
Cobertura de la taxonomía
Los conceptos de nivel 2 que el grafo cubre alcanzan
137 476 de los 173 636 teoremas de Mathlib
(79,2 %) con 211 conceptos de 1 139. La cobertura es muy desigual
por rama —Álgebra 25 410 de 27 560, Análisis 20 178 de
21 240, Geometría algebraica 1 643 de 2 906, y Condensed
0 de 75—, y esa desigualdad es informativa: marca dónde el grafo
curado tiene huecos reales.
Lean: cuatro caminos, ocho veredictos
Hay dos cosas que conviene no mezclar. Lo que Lean dice abre cuatro caminos, y tres de ellos siguen trabajando. El veredicto viene después, y no coincide con «compiló».
| lo que dice Lean | qué pasa después |
|---|---|
| falta un módulo | se repara el encabezado y se reintenta una vez |
| error semántico | el error estructurado vuelve al modelo, máximo 2 rondas |
queda un sorry | entra la cascada de 12 tácticas |
| acepta el archivo | pasa directo al árbol de veredicto |
Nunca se sustituye un resultado por otro peor. Sin esa condición, un reintento que rompe lo que ya compilaba sería indistinguible de uno que arregla, y el sistema iría hacia atrás sin avisar.
La distinción entre error mecánico y error semántico se toma del campo
kind del JSON que Lean emite —por ejemplo
lean.unknownIdentifier— y sólo en segundo lugar de buscar
subcadenas en el texto del error.
El árbol de veredicto, en el orden exacto en que se decide
core.py. Los tres filtros de la izquierda se
aplican antes de conceder el sello, y existen porque los tres
casos se dan en la práctica: un archivo que compila no es lo mismo que una
demostración de lo que se preguntó.| veredicto | qué significa exactamente |
|---|---|
| verificado | hay teorema, Lean lo prueba, no es vacuo y no es la negación de lo pedido |
| parcial | la estructura compila y queda un sorry; la cascada intentó cerrarlo |
| refutado | Lean verificó la negación del enunciado — el enunciado pedido es falso |
| sin_teorema | Lean aceptó el archivo, pero no contiene ningún teorema |
| vacuo | hay teorema y compila, pero su conclusión es exactamente True: no afirma nada |
| no_verificado | Lean rechazó y los reintentos no lo arreglaron |
| timeout | Lean no terminó dentro del límite |
| sin_entorno | no hay lake instalado — no es un fallo de lógica |
El normalizador retira import Mathlib antes de compilar,
porque cargarlo entero tarda 742 s — más que el tiempo límite. El
resultado guarda el código que realmente se compiló, y es ése el
que se muestra y el que se le pasa al modelo para que lo explique. Así, el
bloque de código de la respuesta y el veredicto hablan del mismo
archivo.
La detección de vacuo es deliberadamente estrecha: sólo
dispara cuando la conclusión es exactamente True tras el
último : de profundidad cero, de manera que
∃ (n : Nat), True —que sí afirma algo— no se marca.
La cascada de tácticas
Cuando Lean acepta la estructura pero queda un sorry, entran
doce tácticas con su tiempo límite. El orden lo propone el grafo a partir de
la forma del objetivo.
rfl 1s simp 2s norm_num 2s ring 2s ring_nf 3s field_simp 3s linarith 3s nlinarith 4s omega 3s exact? 5s apply? 5s aesop 8s
done, que falla si quedan objetivos abiertos, y un
trace con una marca distintiva para que Lean diga qué táctica
ganó — sin eso, la ganancia costaría saber cuál fue, que es justo lo que
la cascada tiene que devolver.Sobre 1 600 pruebas de una línea de Mathlib, con una partición de prueba del 20 %:
orden posición media 1er intento en los 3 regla de hoy 1,26 88,4 % 94,4 % MODELO NULO 1,09 94,4 % 99,4 % clasificador entrenado 1,06 95,9 % 99,4 %
El modelo nulo es «probar simp primero y no mirar nada
más», y sale de mirar la distribución: simp cierra el
95,8 % de los 1 600 casos. La regla pierde contra el
nulo en 24 casos y gana en 2, con diferencia media +0,172 posiciones e
intervalo de confianza bootstrap del 95 % en
[+0,094, +0,253] — entero por encima de cero, o sea real.
El mecanismo se ve en los casos: los patrones del objetivo
desplazan a simp justo en objetivos que
simp cierra.
La conclusión honesta no es «el orden de tácticas es malo», sino que
este banco no puede decidirlo: con el 95,8 % en una
sola clase, casi cualquier cosa que ponga simp primero da lo
mismo. Por eso tampoco se cablea el clasificador entrenado: 1,06 frente a
1,09 no es nada sobre 320 casos.
El decisor
Una tabla de mediciones con filas que dicen «no bate al nulo» no sirve de
nada si esas capacidades siguen ejecutándose. nucleo/decisor.py
convierte la evidencia en control de flujo.
El catálogo tiene doce capacidades. Ocho tienen evidencia y guarda, tres están apagadas por medición, una —el emparejador semántico— nunca llegó a producción y se conserva en el catálogo a propósito: un candidato evaluado y descartado es información, y borrarlo invita a reinventarlo.
El respaldo formal en Lean
Las construcciones categóricas del núcleo no se implementan primero en
Python y se justifican después: se demuestran en Lean, y el Python
se audita contra los teoremas. El corpus son 387 teoremas y lemas
en 22 archivos, sin un solo sorry — y eso se
comprueba preguntándole al compilador con #print axioms, no con
grep: ninguna constante depende de sorryAx.
lake build, se verifica que el grafo real satisface las
hipótesis del teorema, y sólo entonces se escribe el Python — que queda
registrado en el mapeo de la auditoría.Fibracion.lean define proyección monótona, levantamiento
cartesiano y fibración, y prueba la unicidad del levantamiento, la
monotonía del reindexado y su composición — sin depender de ningún
axioma, ni siquiera de los tres estándar. También incluye un
contraejemplo finito: hay monótonas que no son fibraciones, sin el cual la
condición no distinguiría nada.
JoinColimit.lean prueba que ser colímite equivale a ser
co-cono con propiedad universal en un preorden delgado, con unicidad
automática. IsColimitBridge.lean conecta ese resultado con
CategoryTheory.Limits.IsColimit de Mathlib, que es lo que
convierte una construcción propia en una instancia de la noción
estándar.
El método de medición
Todo lo que se afirma de este sistema se afirma con una medición detrás, y toda medición cumple cuatro condiciones. No son formalidades: cada una corresponde a una forma concreta de producir una cifra creíble y falsa.
1 · Modelo nulo obligatorio
Cada cifra se compara contra la cosa más tonta que haría el mismo trabajo: responder siempre la clase mayoritaria, ofrecer los elementos más frecuentes, barajar las etiquetas.
Sin él, un 61 % de acierto parece bueno hasta que se sabe que una constante acierta el 89 %.
2 · Volumen igualado
La precisión y la cobertura no se comparan entre configuraciones que ofrecen distinto número de candidatos. Un mando de volumen disfrazado de mando de calidad produce una tabla creíble y una conclusión falsa: basta ofrecer un tercio de los nombres para que suba la precisión sin acertar más.
3 · La medida adecuada al banco
En un banco desequilibrado, la exactitud cruda mide el desequilibrio. La exactitud equilibrada —media de los aciertos dentro de cada clase— es inmune a él, y su nulo baja a 1/k clases.
4 · La alarma dentro del instrumento
Cada script de medición lleva escrita la condición que revelaría que el instrumento está roto y no el sistema: un cero perfecto que incluye al azar, una tasa de exclusión imposible, un resultado demasiado cómodo.
Los bancos que llaman al modelo distinguen explícitamente entre un caso que falló y uno que no se midió porque se agotó el saldo o la API devolvió un error. Un caso sin medir no cuenta ni a favor ni en contra, y mientras queden casos sin medir no hay nota: una cifra parcial presentada como total sería una medición deshonesta.
El bucle que no cuesta dinero
La formalización es el único paso que necesita el modelo. Con
METAMAT_GRABAR=1 se graba el código del modelo
antes de que Lean lo vea, y todo lo que el sistema hace
después —reparación de imports, cascada, premisas, veredicto— se reejecuta
con Lean de juez y coste cero.
La frontera está donde tiene que estar, y hay un test que lo impide mover: si el gancho de grabación se colocara detrás de la normalización, la reejecución mediría el sistema contra su propia salida y daría siempre lo mismo.
Lo que está medido
El resultado que ordena a los demás: ¿aporta el sistema?
Durante mucho tiempo la comparación fue «el sistema con el grafo» contra «el sistema sin el grafo». Esa pareja contesta si aporta el grafo, no si aporta el sistema: la rama sin grafo sigue llevando reparación, premisas, cascada y ejemplos. Faltaba el suelo — el mismo modelo, una llamada, sin nada.
| configuración | verifica | qué es |
|---|---|---|
| modelo solo | 4 de 20 · 20 % | una llamada, sin sistema |
| sin reparación | 6 de 15 · 40 % | el sistema menos el bucle de reparación |
| sin vocabulario | 11 de 20 · 55 % | el sistema menos el grafo |
| sistema completo | 12 de 20 · 60 % | la configuración que se sirve |
| comparación pareada | rescata | rompe | p · McNemar exacto |
|---|---|---|---|
| el sistema frente al modelo solo | 8 | 0 | 0,0078 |
| la reparación completo frente a sin reparación | 4 | 0 | 0,1250 |
| el vocabulario con frente a sin | 3 | 2 | 1,0000 |
El aparato triplica al modelo aislado y es significativo. El grafo, dentro de él, no se distingue del ruido. El vocabulario cambió lo que el modelo escribió en 19 de los 20 casos, pero no movió el veredicto en una dirección consistente.
Y hay una tercera pieza medida contra el mismo suelo: la reparación —devolverle al modelo el error de Lean— rescata cuatro casos y no rompe ninguno. Con 15 pares no llega a significancia, pero es, junto al aparato entero, la única pieza que nunca estropea un caso; el vocabulario rescata tres y rompe dos.
La afirmación sostenible es, por tanto: el grafo ofrece los identificadores correctos —catorce veces mejor que su nulo— y eso es puntería, no resultado. Que haga verificar más a Lean se midió y no se ve a n=20.
Catorce mediciones, cada una con su modelo nulo. La figura las pone todas en la misma escala —cuántas veces bate a su nulo— para que se puedan comparar componentes que miden cosas distintas.
| qué se mide | resultado | modelo nulo | veredicto |
|---|---|---|---|
| Vocabulario contra ProofNet371 ejercicios con formalización de oro · k=2, el valor de producción | 22,8 % precisión 18,0 % cobertura | 1,45 % 3,3 % | 15,7× · aporta |
Dependencias curadas contra el DAG real154 aristas skill→skill medibles · nulo emparejado | 112 confirmadas 72,7 % | 31,9 % | 2,28× · aporta |
Costura de cobertura contra el DAG9 aristas skill→módulo medibles | 9 confirmadas 100 % | 100 % | 1,00× · no dice nada |
| Revisión de sintaxis de la consulta23 243 enunciados de LeanWorkbook, todos correctos | 3,6 % falsos pos. 60,8 % de caza | 3,6 % (moneda) | +57,2 puntos |
| Rasgos del árbol → premisas22 117 pares, bootstrap emparejado, 68 rasgos | 80,9 % cobertura | 56,6 % | +24,3 · aporta |
| Reconocedor de área por la forma5 750 de test sobre 7 temas de MATH · medido, no cableado: por el camino real contra ProofNet no paga | 75,4 % techo 84,1 % | 23,8 % | 3,2× · aporta fuera de la cadena |
| Área de la consulta3 000 consultas etiquetadas · banco 88,6 % algebra | 58,7 % equilibrada 61,2 % cruda | 33,3 % 88,6 % cruda | +25,4 equilibrada |
Selección de premisassin los @[simp], que simp ya conoce | 14,0 % cobertura | 11,7 % | mejora pequeña |
| Elección de imports20 enunciados, Lean como juez · azar 14/20 | 18/20 elabora | 18/20 fijo | inerte |
Orden de tácticas1 600 pruebas de Mathlib · simp cierra el 95,8 % | 1,26 posiciones | 1,09 | no bate al nulo |
| Poda por área antes de elegircon localización perfecta — es el techo, no lo real | 6,8 % | 9,8 % | no llega al nulo |
| Fibración π : Skills → Áreas860 pares (objeto, área por debajo) | 3 se levantan 0,3 % | 6,1 % (áreas al azar) | peor que el azar |
Nombres de los nodos generados447 identificadores, uno a uno con #check | 346 existen | — | 95 no existen |
| Respaldo formal Python ↔ Leanauditoría del mapeo operación → teorema | 62/63 · 98 % | — | 0 mapeos rotos |
El banco de fidelidad
Es el instrumento que responde a la pregunta central: ¿el teorema que Lean verifica es el que se preguntó? Verificar fielmente algo falso es tan malo como verificar infielmente algo cierto, así que un caso sólo cuenta como bueno si salen bien las tres cosas:
- Verificación — qué dijo Lean.
- Fidelidad — un juez independiente decide si el enunciado formalizado es el de la pregunta, sin ver el veredicto de Lean, para que el sello no lo contamine.
- Honestidad — para los enunciados falsos a propósito, el sistema debe rechazarlos o probar su negación, y la respuesta debe abrir diciéndolo.
El banco tiene 24 casos en tres grupos: 16 ciertos y formalizables, 4 falsos a propósito y 4 controles que no son matemáticas y no deberían tocar Lean. La corrida rápida es una muestra estratificada de ocho —4/2/2— para que la parte que discrimina siga estando representada.
La corrida registrada en data/banco_fidelidad.json es la
muestra rápida: 8 casos medidos, 8 correctos, 0 infieles.
La corrida completa de los 24 es la medición pendiente del proyecto, y es
la única que necesita presupuesto de API y de Lean. Hasta que exista, la
cifra que este documento sostiene es la de ocho casos.
Los resultados negativos
Costaron el mismo trabajo que los positivos y valen igual. Están aquí para que nadie los repita, y porque un sistema que sólo publica lo que funciona no se puede evaluar.
La elección de imports no aporta, y el banco casi no puede detectarlo
Un conjunto fijo de tres módulos hace elaborar 18 de 20 enunciados. Añadirle lo que el grafo propone: los mismos 18, el mismo tiempo. Contra el azar sí gana —18 frente a 14—, o sea que hace trabajo real, pero redundante con una constante.
De los 2 fallos, ninguno es de imports: uno necesita open Real y otro usa sintaxis vieja de Mathlib.
El «conjunto fijo» no es pequeño: Mathlib.Tactic arrastra 2 972 módulos por transitividad, y los tres juntos cubren el 38,4 % de Mathlib. La medición es aditiva —añadir imports nunca rompe una elaboración— así que la única forma de ganar era rescatar un fallo. En 14 de 20 casos el grafo no añade ni un módulo: las dos ramas son la misma ejecución.
El test discriminante tiene n ≈ 0. «Inerte» está sostenido como no se midió beneficio, no como se demostró que no lo hay.
Las premisas no cierran pruebas, y la aritmética lo explica
Añadir tácticas con premisas costó 231 invocaciones extra de Lean y cerró cero sobre 21 teoremas que la cascada desnuda no cerraba.
La cobertura de premisas es del 14 %, o sea una de cada siete, y una prueba las necesita todas — 2,1 de media. Esperado 0,14² × 21 ≈ 0,4 cierres; observado, 0.
Una métrica de recuperación no se traduce en cierres. El listón real está muy por encima del 14 % que la mejora celebraba.
Tres emparejadores fallaron, y la causa no era el emparejador
Búsqueda plana 43,9 %, descenso anclado en pilares 11,8 %, embeddings 11,9 % — los tres por debajo del 79,4 % de decir siempre «álgebra».
Para (a+b)² = a²+2ab+b² no existía el nodo: las 35 skills de álgebra eran todas álgebra abstracta. Ningún emparejador recupera lo que no está.
MATH es 79 % álgebra escolar contra una ontología de investigación. La conclusión útil no es sobre el emparejador, es sobre qué conceptos faltan en el grafo.
Podar por área no sirve, ni siquiera acertando el área
Localizar primero el área y elegir las premisas sólo dentro de ella. El orden es correcto: buscar sobre los 183 433 hechos de golpe confundiría el fallo de la búsqueda con la ausencia de poda.
Con localización perfecta —el oráculo— la cobertura sube de 6,0 % a 6,8 %. El modelo nulo da 9,8 %. Aunque se acertara el área siempre, se perdería contra ofrecer las premisas más citadas.
empeora
De 27 áreas a 1 095 sub-áreas: el espacio se divide por cuarenta y el techo sube 0,3 puntos, pero acertar la sub-área es la mitad de fácil, así que en la práctica cae de 4,6 % a 4,0 %.
descartada
Se pensó que la poda fallaba porque las premisas venían de otras áreas. No: el 77,1 % está en la misma área que el teorema. La localización sí informa; lo que falla es elegir cuáles dentro.
Los sustantivos del módulo: la lista sirve, la vía no
es real
Mathlib tiene 34 084 sustantivos —29 883 def, 2 949 abbrev, 1 845 class, 1 490 structure, 300 inductive— y el grafo inyecta 169: el 0,50 %. Y es justo la mitad del trabajo que el reparto le asigna, porque el modelo acierta los sustantivos e inventa los lemas.
es buena
Los nombres se leen de la declaración en vez de deducirse de la ruta. #check sobre una muestra: 200 de 200 existen, frente al 77,4 % de los deducidos.
pierde
Ofrecer los sustantivos del módulo de cada nodo generado, a volumen igualado contra ProofNet: en ~1 800–2 000 nombres, 14,0 % / 17,8 % sin ellos contra 11,5 % / 16,5 % con ellos. Pierde precisión en los dos puntos de la curva: no es dilución, son peores nombres.
sin estadística
El módulo de un nodo generado es un rincón de su área. mathlib-analysis-real ofrecía Hyperreal.Infinite y Real.ofDigits, mientras Real y Real.sqrt viven en Data/Real/Basic. La clave «módulo del nodo» no lleva a los sustantivos que hacen falta.
Buscar en los 217 419 nombres no bate al vocabulario curado
El índice de nombres se usa para comprobar y cualificar, nunca para buscar. ¿Y si se usara como buscador, con índice invertido e idf?
Contra ProofNet, mismo K y mismo nulo: el índice completo da 0,0 % de precisión y el de sólo sustantivos 1,5 %, frente al 22,8 % del vocabulario curado y al 1,45 % del nulo. El mejor índice empata con el azar.
Más candidatos no es más información. Las colisiones de palabra dominan: «Banach» lleva a los espacios de Banach, no al teorema del punto fijo.
La recuperación de lemas por contenido pierde contra la moda
Sobre 23 243 pruebas reales: por contenido, 0,6 % de cobertura; ofrecer siempre los 20 lemas más citados, 77 %.
sq_nonneg no aparece en el enunciado ni tiene por qué: es una herramienta que el problema necesita, no un concepto del que hable. No hay parecido que encontrar.
En Mathlib general el nulo sólo vale 9,2 % y el contenido 4,6 %: lo que cambia por dominio es la fuerza del nulo, no la del método.
95 de los 447 nombres generados no existen en Mathlib
De los 447 identificadores que proponen los 125 nodos generados, comprobados uno a uno con #check: 346 existen, 95 no existen en absoluto y 6 son espacios de nombres — agrupan, pero no son un término.
Estaban deducidos de la ruta del módulo. El filtro pedía CamelCase sin guion bajo, y eso deja pasar Basic —un nombre de fichero— igual que Polynomial —un tipo—. La forma no distingue; sólo Lean lo hace.
Cuatro nodos se quedan sin ningún nombre válido, así que aunque se activara la inyección no podrían aportar nada. Por eso los nodos generados no inyectan vocabulario.
Tests y guardianes
1 085 tests en 53 suites, verdes en los dos intérpretes con los que se trabaja. Los que más valen no comprueban que el código funcione: comprueban que el sistema no pueda volver a afirmar más de lo que sabe.
| guardián | qué impide |
|---|---|
| test_cobertura_consultas | que el grafo deje de engancharse con las consultas reales sin que nadie se entere |
| test_auditoria_veredicto | que un archivo sin teorema, vacuo o refutado reciba el sello de verificado |
| test_interpretacion | que un nodo generado se cuele como si estuviera interpretado categóricamente |
| test_decisor | que una capacidad se apague en silencio porque su ruta de evidencia dejó de resolver |
| test_idioma_de_los_prompts | que las instrucciones a Lean y a Mathlib dejen de estar en inglés |
| test_nombres_mathlib | que el reparador de nombres modifique código que ya compilaba |
| test_fibracion | que cambie la proporción de morfismos que cruzan de área sin volver a medir la fibración |
| rutas absolutas en el runtime | que un except mudo degrade el sistema en silencio al mover el proyecto |
| cifras declaradas | que la documentación anuncie números que ya no son ciertos |
| valores por defecto de los medidores | que un banco mida una configuración que el sistema no sirve |
Los tres últimos no comprueban comportamiento: comprueban que lo que se publica siga siendo verdad. Una cifra desactualizada en la portada y un banco que mide otra configuración producen exactamente el mismo daño que un fallo de lógica, y ningún test normal los ve.
Límites y trabajo abierto
Lo que el sistema no hace
- No demuestra teoremas por sí solo. Formaliza y verifica. La prueba la escribe el modelo o la cierra la cascada de tácticas.
- El grafo no decide qué es cierto en ningún punto. Eso es Lean, siempre.
- Sin API no hay formalización, ni chat, ni banco de fidelidad. Lo que sigue vivo sin ella es todo el trabajo de validar y mejorar el núcleo, que es la mayor parte de este documento.
Preguntas abiertas
- El banco de fidelidad completo, los 24 casos con juez ciego. Es la única medida de si la respuesta responde a la pregunta, y la única que sigue necesitando presupuesto de modelo.
- Un banco en español con premisas de oro. Sin él, todo lo que se construye para el alumno hispanohablante se mide en inglés y por analogía.
- Subir el n de la campaña. Los tres contrastes pareados corren sobre 20 casos (15 en la rama sin reparación). Con ese tamaño, «rescata 4 y rompe 0» no llega a significancia aunque el efecto sea real.
Identificado, con el camino claro
- Las tácticas deberían ser flechas, no nodos. Hoy son
9 sumideros que reciben 453 aristas. Sus objetos deben ser estados de
prueba y sus morfismos las tácticas. Hay 25 214
transiciones
state_before → tactic → state_afteren disco para construir esa categoría y medirla sin API, y la cascada en un compilado hace que explorarlo ya no cueste tres minutos por consulta. - Faltan morfismos que crucen de área. Es lo único que
puede convertir el funtor verificado en una fibración: hoy sólo 29 de 230
morfismos de orden cruzan. No falta formalización — la definición y sus
propiedades están demostradas sin
sorry—, faltan datos. - La fibra de hechos.
data/banco_lemas.jsonlson 23 243 pares (enunciado, lemas que la prueba usó): un grafo bipartito esperando a ser construido, que hoy sólo alimenta un índice plano. - Un índice de sustantivos consultado por la consulta,
como
premisas.pyhace con los lemas. La lista está construida y verificada; lo que no funciona es la clave «módulo del nodo». - No hay lematización en el emparejador, así que
primosno casa conprimo. Añadirla mueve la precisión y necesita su propia medición. - Seis dependencias del grafo siguen bajo sospecha de ir en sentido contrario, según la comparación con el DAG oficial.