Ex4pm.Runtime.PowlExecutor (ex4pm v26.9.9)

Copy Markdown View Source

A real GenStateMachine implementing a Petri-net-style token game for a POWL process model.

The machine's state is a marking: a map of place -> non_neg_integer token counts. The single state-machine state is :marking (this executor is deliberately single-mode — the "state" that matters is the data, not the state-function name), and the machine data carries both the current marking and the transition graph it was started with.

A transition is identified by any term (usually an atom or string) and is described by its input places (consumed on fire) and output places (produced on fire). Firing a transition whose input places do not all hold at least one token is refused: the marking is left unchanged and the caller receives {:error, :insufficient_tokens}.

This module is intentionally self-contained: it has no dependency on BRCE or receipts. Wiring a receipted :fire call is a later capability's job.

Summary

Functions

Returns a specification to start this module under a supervisor.

Attempt to fire transition_id. Returns {:ok, marking} with the new marking on success, or {:error, :insufficient_tokens} / {:error, :unknown_transition} on refusal, in which case the marking is left unchanged.

Return the current marking.

Types

marking()

@type marking() :: %{optional(place()) => non_neg_integer()}

place()

@type place() :: term()

transition()

@type transition() :: %{inputs: [place()], outputs: [place()]}

transition_id()

@type transition_id() :: term()

transitions()

@type transitions() :: %{optional(transition_id()) => transition()}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

fire(server, transition_id)

@spec fire(GenServer.server(), transition_id()) ::
  {:ok, marking()} | {:error, :insufficient_tokens | :unknown_transition}

Attempt to fire transition_id. Returns {:ok, marking} with the new marking on success, or {:error, :insufficient_tokens} / {:error, :unknown_transition} on refusal, in which case the marking is left unchanged.

marking(server)

@spec marking(GenServer.server()) :: marking()

Return the current marking.

marking(arg1, arg2, data)

start_link(initial_marking, transitions, opts \\ [])

@spec start_link(marking(), transitions(), GenServer.options()) ::
  GenServer.on_start()

Start the executor.

initial_marking is a map of place => token count. transitions is a map of transition_id => %{inputs: [place], outputs: [place]}.