# `Monty.Frameworks.Models.Mixins.NoResetEvidence.TheoreticalLimitLMLoggingMixin`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/frameworks/models/mixins/no_reset_evidence/theoretical_limit_lm_logging_mixin.ex#L1)

What a learning module's hypotheses were worth, in the terms a paper uses.

Mirrors `frameworks/models/mixins/no_reset_evidence.py::TheoreticalLimitLMLoggingMixin`,
the mixin Monty's unsupervised-inference learning module is built from. It
adds four things to a step's log, none of which the module needs in order to
recognise anything — they exist so an episode can be judged as well as read:

  * `"max_evidence"` — the strongest hypothesis of every object;
  * `"target_object_theoretical_limit"` — the pose error of the *best*
    hypothesis of the target object, i.e. how right Monty could have been if
    it had picked the best one instead of the most likely one;
  * `"target_object_pose_error"` — the pose error of the most likely
    hypothesis, which is the error the episode is actually charged with;
  * `"hypotheses_updater_telemetry"` — per object, the whole hypothesis space
    (`Monty.Frameworks.Models.Mixins.NoResetEvidence.HypothesesUpdaterGraphTelemetry`).

## The gap between the two pose errors is the finding

The theoretical limit is an oracle's score and the MLH's error is Monty's.
When they diverge, the hypotheses are fine and the choice among them is not —
which is a different repair from "the model never had a good explanation".
That is why the mixin computes both rather than one.

## Differences from Monty, on purpose

  * **No inheritance, so no `__init_subclass__` guard.** Monty refuses at class
    definition time to mix this into anything but an `EvidenceGraphLM`; here
    the guard is the argument's type, and `add_detailed_stats/2` has no clause
    for anything else.
  * **Monty's mixin replaces the learning module's own detailed statistics**
    rather than adding to them: its `_add_detailed_stats` does not call
    `super()`, so `possible_locations`, `evidences`, `possible_rotations` and
    `symmetry_evidence` are absent from the log of the learning module that
    mixes it in. That is Monty's behaviour, kept.

# `add_detailed_stats`

```elixir
@spec add_detailed_stats(
  Monty.Frameworks.Models.EvidenceMatching.LearningModule.EvidenceGraphLM.t(),
  map()
) :: map()
```

`_add_detailed_stats`: the step's statistics, with this mixin's four added.

Takes the statistics the learning module would have written and returns them
with the mixin's fields in place — replacing that module's own detailed
fields, which is what Monty's mixin does.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
