(Knowledge Augmented) Decision Process -> (KA)DP

Decision Process Cycle

The key to orchestrating sequential decision-making – builds upon…

  • state: you design what (mutable) data is needed to represent progress

    • Upon initialization the DP, you provide a function to supply its initial state

  • IOContainer: process access to non-state data/channels

    • (i)nput: read-only structured data (typically from external sensors)

    • (o)utput: channels for execution (typically a function to interact with external actuators)

    • (e)lab: key/computed value pairs (typically combining aspects of state + input + arguments)

    • (a)rgs: read-only key/value pairs to parameterize the process

  • phase: the DP continually executes a cycle (see figure above)

    1. Elaboration (implemented via Elaborator): compute value(s) based upon state and IO

    2. Termination (implemented via TerminationCheck): detect state-based ending conditions

    3. Propose (implemented via ActionFactory): indicate valid Action(s)

    4. Rank (implemented via ActionEvaluator, which produces ActionRank): use knowledge to evaluate candidate actions

    5. Apply (commonly performed via operators): execute the single selected action, typically to modify state and/or externally actuate

Tip

The string value (e.g., str(my_dp) of a DP tells you a LOT about this info).

A DP can run individual phase/cycle(s), but commonly until a termination condition is detected.

Once a DP has terminated, it must be reinitialized before future runs – this restarts the cycle, and also sets DP state to an initial value (via the supplied function).

Tip

It is not uncommon for the state initialization function to return a reference to a (mutable) object…

my_state = CustomStateClass()
my_dp = DecisionProcess(lambda: my_state)

The effect of this pattern is that DP state persists across DP reinit.

Typical DP Usage (e.g., isolated testing)

  1. Design DP state (e.g., a custom class)

  2. Instantiate a DP (with a function that supplies an initial state value)

  3. Add components to the DP (e.g., operators, termination check)

  4. Run (e.g., via my_dp())

  5. Access DP state, possibly reinit + re-run