Skip to content

ReasonMachine: Status and Gating ​

The ReasonMachine (RM, src/ADSIDAC/ReasonMachine/) is the knowledge-based reasoning model of the Decision Maker. Its reasoning cycle does not run in the current engine. This page states what of the RM still executes, how the --enable-rm-cycle flag gates the rest, and what has to be dealt with before the cycle is called again.

Status ​

The cycle entry point ReasonMachine::OneStepOfReasonMachine() has no caller. What still executes:

SurfaceWhereWhy it matters
Construction and knowledge-base load at start-upOperator::initiationForSimulation calls InitiationOfReasonMachineFromInputFile(), for the Decision Maker onlyRandomlyGenerateKnowledgeBug() draws one rand() value per knowledge unit from the global random stream that all later stochastic sampling uses. Removing or reordering this call changes the sampled values of a run
WhetherItIsNormalOperating()called from the Decision Maker cycle (OperatorDM.cpp)It reads a list that only the reasoning cycle fills, so its result is constant
AddDeltaToCognitiveLoad()called when an operator actively fetches information (Operator.cpp)The accumulated value has no reader: the call that would pass it to the human-failure-event network (hfe_bbn.setCognitiveTaskLoad) is commented out

Start-up also writes RMI.txt, AuxInfo.txt and Semantic_Base.txt into the working directory.

The gate ​

The runtime flag g_sim.config.rm_cycle_enabled (command line --enable-rm-cycle, default off) gates the copy and serialization machinery and leaves the live RM untouched.

With the flag off:

  • Operator::copyOperatorToRestartInfo does not clone the RM into the restart snapshot, so the snapshot's m_RM is null.
  • Operator::serialize writes a has_rm flag followed by the RM data only when m_RM is not null. A snapshot without an RM therefore adds no RM data to MPI transfers and checkpoints. An archive that does contain RM data still loads.
  • On restore (copyOperatorFromRestartInfo and the MPI restore path) the live RM persists across sequences, and ReasonMachine::ClearTBIListsForRestart() resets the input queues of the cycle.
  • The five m_tbi_*_list producers in OperatorDM::infoChunking do not push. Those lists are consumed only by the reasoning cycle.

With the flag on, the snapshot holds a clone of the RM (CopyReasonMachineFromAnotherRM() followed by BuildTheConnectionsWithinRM()) at every branch point, a restore replaces the live RM by a clone of the snapshot's, the RM data travels in every transfer and checkpoint, and the m_tbi_*_list producers push. The cycle itself still does not run, because nothing calls OneStepOfReasonMachine().

Never gated: the start-up construction (and with it the rand() draws; the only rand() call in ReasonMachine.cpp is in RandomlyGenerateKnowledgeBug()), WhetherItIsNormalOperating() and AddDeltaToCognitiveLoad().

Before calling the cycle again ​

The following are properties of the dormant code. They have no effect while the cycle does not run.

  1. Archive round trip of dynamic state. RMSerialization.h serializes string ids and skips raw pointers. It also skips m_other_evidence_list, the investigator case lists and several pointer members, with the expectation that execution rebuilds them. Confirm that for every skipped member before relying on MPI transfers or checkpoints with the cycle enabled, and include the m_position_tbi_*_list vectors.
  2. ReasonMachine::FindRecentStatementBySentence() never advances its iterator and reads state_pt before assigning it. It does not terminate when the statement list is not empty.
  3. SentenceUnit, sentence type 5. In the activation-ratio switch, case 5 has its break before the statement that does the work, so the attribute's activation ratio is never applied.
  4. Model-specific debug residue inside the cycle. ReasonMachine.cpp contains a statement conditioned on timesno >= 1809, a block conditioned on 848 < timesno < 850, and checks against literal ids ("statement_2472", and "Investigator_278" in SymptomInvestigator.cpp and EventSchemaBase.cpp). They belong to one plant model and one debugging session and have to be removed for any other model.
  5. OperatorCT::OperatorCT() dereferences m_RM, which is null until initiationForSimulation creates it.

Design guidance for enabling it ​

  • Split static from dynamic state. Most of what CopyReasonMachineFromAnotherRM() copies (concepts, sentences, knowledge elements, nodes and units, mental-representation templates, the instantiation base) does not change after start-up. Hold it behind a shared_ptr<const ...> shared by the live RM and every snapshot, and copy and serialize only the dynamic part (activations, statements, investigators, histories).
  • Index the lookups. The Find*ByID(std::string) functions are linear scans with by-value string parameters. They dominate BuildTheConnectionsWithinRM() and sit on the per-tick path once the cycle runs. Use const std::string& and unordered_map<string, T*> indexes maintained on insertion.
  • Keep diagnostics out of snapshots. The history vectors (performance shaping factors, loads, m_data_array, token histories) grow with every cycle step and would be cloned and shipped at every branch point. Write them out per sequence, as KeyParameterHistory does, or bound them.
  • Buffer the cycle's output. PrintMessage() and WriteAuxInfo() open, append to and close RMI.txt and AuxInfo.txt for every message. Buffer in memory and flush per sequence, and write under Output/ and not into the working directory.
  • Use a deque or a cursor for the m_tbi_* queues. The cycle erases from the front of growing vectors.
  • Expect different trees. The cycle generates goals (MaintainGlobalSafetyMargin, through WhetherItIsNormalOperating()), so the reference tree sizes change when it runs. Plan a new set of reference counts.
  • Mind the random stream. Any change to the start-up knowledge-base load that adds or removes rand() draws shifts the global stream. A seeded generator with deterministic reseeding per sequence is best introduced together with the new reference counts, since both change sampled values.

ADS-IDAC Engine Documentation