pyfcstm.diagnostics.inspect
Structured model inspection for pyfcstm.
This module provides inspect_model(), a single entry point that
walks a pyfcstm.model.StateMachine and produces a stable,
serialization-friendly view of its structure plus five derived
relational graphs (reachability, event emission, variable data flow,
aspect impact, action reference). The output is the foundation that
Layer 2 design-health warnings (W_* / I_* codes) and downstream
LLM / evaluation tooling consume.
The view shape is the single source of truth for the pyfcstm /
jsfcstm contract. Adding or renaming a field here must be mirrored on
the jsfcstm side (editors/jsfcstm/src/diagnostics/inspect.ts) and
in pyfcstm/diagnostics/schema.json.
The module exposes the following dataclasses:
StateInfo— per-state structural summaryTransitionInfo— per-transition structural summaryComboOriginInfo— original combo trigger provenanceVariableInfo— per-variable structural summary plus guard-affect flags used byW_UNREFERENCED_VAREventInfo— per-event structural summaryModelMetrics— aggregate counts and ratiosModelInspect— top-level container including diagnostics
Examples:
>>> from pyfcstm.dsl import parse_with_grammar_entry
>>> from pyfcstm.model import parse_dsl_node_to_state_machine
>>> from pyfcstm.diagnostics import inspect_model
>>> source = '''
... def int counter = 0;
... state Root {
... state Idle;
... state Active;
... [*] -> Idle;
... Idle -> Active : if [counter > 0];
... }
... '''
>>> ast = parse_with_grammar_entry(source, 'state_machine_dsl')
>>> machine = parse_dsl_node_to_state_machine(ast)
>>> report = inspect_model(machine)
>>> report.metrics.n_states_leaf
2
DEFAULT_DEEP_HIERARCHY_THRESHOLD
- pyfcstm.diagnostics.inspect.DEFAULT_DEEP_HIERARCHY_THRESHOLD = 6
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
DEFAULT_LARGE_COMPOSITE_THRESHOLD
- pyfcstm.diagnostics.inspect.DEFAULT_LARGE_COMPOSITE_THRESHOLD = 12
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
DEFAULT_VAR_TO_LEAF_RATIO_THRESHOLD
- pyfcstm.diagnostics.inspect.DEFAULT_VAR_TO_LEAF_RATIO_THRESHOLD = 2.0
Convert a string or number to a floating point number, if possible.
DEFAULT_STRUCTURE_MAX_TRANSITIONS_PER_STATE
- pyfcstm.diagnostics.inspect.DEFAULT_STRUCTURE_MAX_TRANSITIONS_PER_STATE = 6.0
Convert a string or number to a floating point number, if possible.
DEFAULT_STRUCTURE_MAX_UNREACHABLE_LEAF_STATE_RATE
- pyfcstm.diagnostics.inspect.DEFAULT_STRUCTURE_MAX_UNREACHABLE_LEAF_STATE_RATE = 0.1
Convert a string or number to a floating point number, if possible.
DEFAULT_STRUCTURE_MAX_UNREACHABLE_TRANSITION_RATE
- pyfcstm.diagnostics.inspect.DEFAULT_STRUCTURE_MAX_UNREACHABLE_TRANSITION_RATE = 0.1
Convert a string or number to a floating point number, if possible.
KNOWN_SPANLESS_CODES
- pyfcstm.diagnostics.inspect.KNOWN_SPANLESS_CODES = frozenset({})
frozenset() -> empty frozenset object frozenset(iterable) -> frozenset object
Build an immutable unordered collection of unique elements.
COMBO_GUARD_VERIFY_REPLACEMENT_CODES
- pyfcstm.diagnostics.inspect.COMBO_GUARD_VERIFY_REPLACEMENT_CODES = {'W_DEAD_GUARD': 'W_COMBO_GUARD_CONST_FALSE', 'W_GUARD_TAUTOLOGY': 'W_COMBO_GUARD_CONST_TRUE'}
Mapping from generic guard diagnostics to combo-specific diagnostics when optional verify analysis runs against an expanded combo pseudo transition.
DEFAULT_STRUCTURE_STATISTICS_POLICY
- pyfcstm.diagnostics.inspect.DEFAULT_STRUCTURE_STATISTICS_POLICY = StructureStatisticsPolicy(max_transitions_per_state=6.0, max_unreachable_leaf_state_rate=0.1, max_unreachable_transition_rate=0.1)
Advisory thresholds for the structure-statistics section.
The defaults are deliberately limited to size-normalized topology signals: a PSMBench-style pooled transition/state ratio of 2.75 remains below the broad review trigger, while 10% unreachable populations provide a useful review trigger without pretending to be a semantic proof.
Nonedisables one advisory threshold. Exceeding a threshold only records metadata; it never creates a diagnostic.- Parameters:
max_transitions_per_state – Maximum advisory
T / Sratio.max_unreachable_leaf_state_rate – Maximum advisory unreachable leaf state fraction.
max_unreachable_transition_rate – Maximum advisory unreachable authored transition fraction.
StateInfo
- class pyfcstm.diagnostics.inspect.StateInfo(path: str, name: str, parent_path: str | None, is_leaf: bool, is_pseudo: bool, is_composite: bool, substates: Tuple[str, ...], initial_targets: Tuple[Dict[str, Any], ...], entry_actions: Tuple[str, ...], during_actions: Tuple[str, ...], exit_actions: Tuple[str, ...], aspect_before: Tuple[str, ...], aspect_after: Tuple[str, ...], has_abstract_action: bool, span: Span | None = None)[source]
Structural summary of a single state.
- Parameters:
path (str) – Dotted hierarchical path, e.g.
'Root.SubSystem.Active'.name (str) – Short name of the state (last component of
path).parent_path (Optional[str]) – Dotted path of the parent state, or
Nonefor the root state.is_leaf (bool) –
Truewhen this state has no substates.is_pseudo (bool) –
Truewhen the state was declared withpseudo state.is_composite (bool) –
Truewhen this state has substates.substates (Tuple[str, ...]) – Direct-child state paths, in source order.
initial_targets (Tuple[Mapping[str, Any], ...]) – Each item describes one
[*] -> Xinitial transition declared inside this composite.targetis the target child path,guardis the source text of the guard orNone,eventis the qualified event name orNone,is_unconditionalisTrueonly when both guard and event are absent.entry_actions (Tuple[str, ...]) – Action labels (function name or
'<inline>') forenteractions on this state, in source order.during_actions (Tuple[str, ...]) – Action labels for
duringactions.exit_actions (Tuple[str, ...]) – Action labels for
exitactions.aspect_before (Tuple[str, ...]) – Aspect-action labels for
>> during before.aspect_after (Tuple[str, ...]) – Aspect-action labels for
>> during after.has_abstract_action (bool) –
Trueif any of the actions above is abstract. Used byVariableInfoconfidence judgements.
TransitionInfo
- class pyfcstm.diagnostics.inspect.TransitionInfo(from_path: str, to_path: str, event: str | None, event_scope: str | None, guard: str | None, effect: str | None, effect_self_assigns: ~typing.Tuple[str, ...], is_forced: bool, forced_origin: str | None, transition_index: int | None, span: ~pyfcstm.utils.validate.Span | None = None, effect_spans: ~typing.Tuple[~pyfcstm.utils.validate.Span, ...] = <factory>, effect_self_assign_spans: ~typing.Tuple[~pyfcstm.utils.validate.Span | None, ...] = <factory>, combo_origin_refs: ~typing.Tuple[~pyfcstm.diagnostics.inspect.ComboOriginRefInfo, ...] = <factory>, combo_projection_key: ~typing.Tuple[object, ...] | None = None, combo_projection_order_key: ~typing.Tuple[object, ...] | None = None, combo_reuse_group_id: str | None = None, combo_priority_run_identity: ~typing.Tuple[str, int | None] | None = None, combo_priority_run_index: int | None = None, source_path: str | None = None, target_history: str | None = None)[source]
Structural summary of a single transition.
- Parameters:
from_path (str) – Dotted path of the source state, or the literal
'[*]'for an initial transition declared at the root.to_path (str) – Dotted path of the target state, or
'[*]'for an exit transition.event (Optional[str]) – Qualified event name (e.g.
'Root.SubA.E') orNoneif the transition has no event.event_scope (Optional[str]) –
'local','chain','absolute', orNonewhen there is no event.guard (Optional[str]) – Normalized guard expression text, or
None. Pyfcstm and jsfcstm share this inspect expression format so downstream range resolution can treatguard_textas a stable disambiguation hint.effect (Optional[str]) – Source text of the effect block, or
None.effect_self_assigns (Tuple[str, ...]) – Variable names assigned to themselves anywhere inside the transition effect block, including nested
ifbranches. Duplicate names are preserved so quick-fix emitters can detect ambiguous occurrences.effect_self_assign_spans (Tuple[Optional[pyfcstm.utils.validate.Span], ...]) – Source spans for the self-assign statements listed in
effect_self_assigns. The order matcheseffect_self_assignsand usesNonewhen a statement has no source span, preventing later spans from shifting to earlier names.is_forced (bool) –
Truewhen the transition was expanded from a!-prefixed forced transition.forced_origin (Optional[str]) – Raw source text of the original
!X -> Ydeclaration whenis_forcedisTrue, otherwiseNone.transition_index (Optional[int]) – Zero-based index in parent-first model transition order, including expanded forced transitions at their declaring state before ordinary transitions and descendant-state transitions. Downstream tooling may use this as a best-effort source-range disambiguation hint when spans are not available.
source_path (Optional[str]) – Source file that authored this transition, when the model carries source metadata. This is distinct from the state paths in the transition endpoints.
combo_origin_refs (Tuple[ComboOriginRefInfo, ...]) – Provenance references from a generated combo edge back to the original combo trigger terms. Empty for ordinary transitions.
combo_projection_key (Optional[Tuple[object, ...]]) – Logical combo chooser key used to project generated continuation edges back to their original transition chooser.
combo_projection_order_key (Optional[Tuple[object, ...]]) – Stable ordering key inside the combo ordered-trie projection.
combo_reuse_group_id (Optional[str]) – Stable identifier explaining the local prefix-sharing group for generated combo edges.
combo_priority_run_identity (Optional[Tuple[str, Optional[int]]]) – Stable ordered-trie run identity, typically
(run_anchor_origin_id, duplicate_discriminator).combo_priority_run_index (Optional[int]) – Preorder index of the generated combo edge inside the projection.
target_history (Optional[str]) –
'shallow'or'deep'when the transition entersTarget.[H]orTarget.[H*], otherwiseNone;to_paththen names the history owner.
ComboOriginRefInfo
- class pyfcstm.diagnostics.inspect.ComboOriginRefInfo(origin_id: str, term_index: int, role: str, consumes_term: bool, term_text: str, transition_span: Span | None = None, trigger_span: Span | None = None, term_span: Span | None = None, value_span: Span | None = None, removal_span: Span | None = None, source_kind: str = 'state', source_path: str | None = None, selection_owner_path: str | None = None, target_kind: str = 'state', target_path: str | None = None)[source]
Structured provenance reference for one generated combo edge.
- Parameters:
origin_id (str) – Stable identifier of the original combo transition.
term_index (int) – Zero-based trigger term index consumed by this edge.
role (str) – Projection role, such as
'prefix'or'terminal'.consumes_term (bool) – Whether this edge consumes the referenced term.
term_text (str) – Canonical text of the referenced combo term.
transition_span (pyfcstm.utils.validate.Span, optional) – Source span of the original combo transition.
trigger_span (pyfcstm.utils.validate.Span, optional) – Source span of the full combo trigger suffix.
term_span (pyfcstm.utils.validate.Span, optional) – Source span of the referenced term.
value_span (pyfcstm.utils.validate.Span, optional) – Source span inside the term when available.
removal_span (pyfcstm.utils.validate.Span, optional) – Source span suitable for removing the term.
source_kind (str) – Authored source kind,
'state'or'init'.source_path (Optional[str]) – Authored source state path, or
Nonefor init.selection_owner_path (Optional[str]) – Composite owner path for an init transition, or
Nonefor a normal transition.target_kind (str) – Authored target kind,
'state'or'exit'.target_path (Optional[str]) – Authored target path, or
'[*]'for exit.
Example:
>>> ref = ComboOriginRefInfo('Root:A->B::: E1 + E2', 0, 'prefix', True, 'E1') >>> ref.term_text 'E1'
ComboOriginTermInfo
- class pyfcstm.diagnostics.inspect.ComboOriginTermInfo(term_index: int, role: str, consumes_term: bool, term_text: str, transition_span: Span | None = None, trigger_span: Span | None = None, term_span: Span | None = None, value_span: Span | None = None, removal_span: Span | None = None)[source]
Term-level inspect record for one original combo trigger term.
- Parameters:
term_index (int) – Zero-based trigger term index.
role (str) – Role of the generated edge first exposing this term.
consumes_term (bool) – Whether the term is consumed by that edge.
term_text (str) – Canonical term text.
transition_span (pyfcstm.utils.validate.Span, optional) – Source span of the original combo transition.
trigger_span (pyfcstm.utils.validate.Span, optional) – Source span of the combo trigger suffix.
term_span (pyfcstm.utils.validate.Span, optional) – Source span of the full term.
value_span (pyfcstm.utils.validate.Span, optional) – Source span inside the term when available.
removal_span (pyfcstm.utils.validate.Span, optional) – Source span suitable for removing the term.
Example:
>>> term = ComboOriginTermInfo(1, 'terminal', True, 'E2') >>> term.term_index 1
ComboOriginInfo
- class pyfcstm.diagnostics.inspect.ComboOriginInfo(origin_id: str, transition_span: Span | None, trigger_span: Span | None, terms: Tuple[ComboOriginTermInfo, ...])[source]
Inspect projection for one user-authored combo transition.
- Parameters:
origin_id (str) – Stable identifier of the original combo transition.
transition_span (pyfcstm.utils.validate.Span, optional) – Source span of the original combo transition.
trigger_span (pyfcstm.utils.validate.Span, optional) – Source span of the combo trigger suffix.
terms (Tuple[ComboOriginTermInfo, ...]) – Ordered term-level provenance records.
Example:
>>> origin = ComboOriginInfo('Root:A->B::: E1 + E2', None, None, ()) >>> origin.terms ()
VariableAccessSite
- class pyfcstm.diagnostics.inspect.VariableAccessSite(kind: str, state_path: str, action: str | None, action_index: int | None, transition_index: int | None, statement_path: Tuple[int, ...], source_path: str | None, span: Span | None)[source]
A static variable access in an expanded model.
statement_pathcontains zero-based statement and branch indices within the owning action or effect; an empty path identifies a transition guard.spancovers the authored statement, branch block, or transition, rather than claiming a token-level variable position. Missing source metadata remainsNonefor programmatically constructed models.
VariableInfo
- class pyfcstm.diagnostics.inspect.VariableInfo(name: str, type: str, init_value: str, read_in_states: ~typing.Tuple[str, ...], written_in_states: ~typing.Tuple[str, ...], read_in_guards: ~typing.Tuple[~typing.Tuple[str, str], ...], written_in_effects: ~typing.Tuple[~typing.Tuple[str, str], ...], affects_guard_directly: bool, affects_guard_indirectly: bool, abstract_actions_in_scope: ~typing.Tuple[str, ...], float_literal_assignments: ~typing.Tuple[str, ...] = <factory>, span: ~pyfcstm.utils.validate.Span | None = None, float_literal_assignment_spans: ~typing.Tuple[~pyfcstm.utils.validate.Span | None, ...] = <factory>, role: str = 'control', external_supply: str = 'none', diagnostic_policy: ~typing.Dict[str, bool] = <factory>, read_sites: ~typing.Tuple[~pyfcstm.diagnostics.inspect.VariableAccessSite, ...] = <factory>, write_sites: ~typing.Tuple[~pyfcstm.diagnostics.inspect.VariableAccessSite, ...] = <factory>)[source]
Structural summary of a variable definition plus guard-affect flags.
The
affects_guard_directlyandaffects_guard_indirectlyflags are precomputed here so that unreferenced-variable diagnostics can be expressed as a one-line filter against this object.- Parameters:
name (str) – Variable identifier.
type (str) – Declared type, currently
'int'or'float'.init_value (str) – Source text of the initializer expression.
read_in_states (Tuple[str, ...]) – State paths where the variable is read inside any action (
enter/during/exit/ aspect).written_in_states (Tuple[str, ...]) – State paths where the variable is written inside any action.
read_in_guards (Tuple[Tuple[str, str], ...]) – Tuples
(from_path, to_path)of transitions whose guard reads this variable.written_in_effects (Tuple[Tuple[str, str], ...]) – Tuples
(from_path, to_path)of transitions whose effect block writes this variable.affects_guard_directly (bool) –
Truewhen the variable is read by at least one transition guard.affects_guard_indirectly (bool) –
Truewhen the variable reaches a transition guard through the conservative use-def graph.abstract_actions_in_scope (Tuple[str, ...]) – Function names of abstract actions that may access this variable. FCSTM variables are global, so any abstract action in the machine is conservatively visible here. Downstream diagnostics can use this to distinguish high-confidence unused variables from variables that may be touched by abstract behavior.
float_literal_assignments (Tuple[str, ...]) – Source text of float literal assignments to this variable from lifecycle actions or transition effects.
external_supply (str) –
cyclefor inputs,constructionfor parameters, ornonefor model-owned control/output variables.diagnostic_policy (Dict[str, bool]) – Fixed applicability of control-variable unused, unwritten-read, write-only and guard-variable-change diagnostics. These flags do not suppress other validation or expression analysis.
read_sites (Tuple[VariableAccessSite, ...]) – Static reads in expanded model traversal order. Repeated occurrences within one expression share a site.
write_sites (Tuple[VariableAccessSite, ...]) – Static assignment destinations, including unreachable statements but excluding declaration initializers.
EventInfo
- class pyfcstm.diagnostics.inspect.EventInfo(qualified_name: str, scope: str, used_by: Tuple[Tuple[str, str], ...], is_declared: bool, is_used: bool, span: Span | None = None)[source]
Structural summary of an event declaration.
- Parameters:
qualified_name (str) – Dotted fully qualified event name (e.g.
'Root.SubA.E').scope (str) –
'local','chain', or'absolute'.used_by (Tuple[Tuple[str, str], ...]) –
(from_path, to_path)tuples for every transition that references this event.is_declared (bool) –
Truewhen the event came from an expliciteventdeclaration.is_used (bool) –
Truewhen at least one transition references the event.
ActionInfo
ForcedTransitionInfo
ModelMetrics
- class pyfcstm.diagnostics.inspect.ModelMetrics(n_states_leaf: int, n_states_composite: int, n_states_pseudo: int, max_hierarchy_depth: int, n_transitions_normal: int, n_transitions_forced: int, n_events: int, n_variables: int, var_to_leaf_ratio: float, aspect_coverage: Dict[str, int], abstract_action_inventory: Tuple[str, ...])[source]
Aggregate model metrics.
- Parameters:
n_states_leaf (int) – Number of leaf states excluding pseudo states.
n_states_composite (int) – Number of composite states.
n_states_pseudo (int) – Number of pseudo states.
max_hierarchy_depth (int) – Maximum depth of state nesting, counted from the root (depth 0 = root).
n_transitions_normal (int) – Number of transitions that did not originate from a
!-forced declaration.n_transitions_forced (int) – Number of transitions expanded from
!-forced declarations.n_events (int) – Number of distinct qualified events exposed by the inspect surface, including explicitly declared events that no transition uses.
n_variables (int) – Number of variable definitions.
var_to_leaf_ratio (float) –
n_variables / max(n_states_leaf, 1).aspect_coverage (Dict[str, int]) – Mapping
composite_path -> n_descendant_leavesfor composite states that declare>> duringaspects.abstract_action_inventory (Tuple[str, ...]) – Function names of every abstract action across the model, sorted for stable output.
StructureStatisticsPolicy
- class pyfcstm.diagnostics.inspect.StructureStatisticsPolicy(max_transitions_per_state: float | None = 6.0, max_unreachable_leaf_state_rate: float | None = 0.1, max_unreachable_transition_rate: float | None = 0.1)[source]
Advisory thresholds for the structure-statistics section.
The defaults are deliberately limited to size-normalized topology signals: a PSMBench-style pooled transition/state ratio of 2.75 remains below the broad review trigger, while 10% unreachable populations provide a useful review trigger without pretending to be a semantic proof.
Nonedisables one advisory threshold. Exceeding a threshold only records metadata; it never creates a diagnostic.- Parameters:
max_transitions_per_state – Maximum advisory
T / Sratio.max_unreachable_leaf_state_rate – Maximum advisory unreachable leaf state fraction.
max_unreachable_transition_rate – Maximum advisory unreachable authored transition fraction.
StructureStatistics
- class pyfcstm.diagnostics.inspect.StructureStatistics(state_count: int, leaf_state_count: int, composite_state_count: int, authored_transition_count: int, transitions_per_state: float | None, states_per_transition: float | None, unreachable_leaf_states: int, unreachable_leaf_state_rate: float | None, unreachable_transitions: int, unreachable_transition_rate: float | None, unreachable_transition_reasons: Dict[str, int], thresholds: StructureStatisticsPolicy, exceeded_thresholds: Tuple[str, ...], unguarded_transitions: int, guard_eligible_transitions: int, unguarded_rate: float | None, missing_effect_transitions: int, effect_eligible_transitions: int, missing_effect_rate: float | None, eventless_unconditional_transitions: int, behavior_transitions: int, eventless_unconditional_rate: float | None)[source]
Descriptive structure statistics for LLM and human review.
These values are intentionally observations, not health thresholds. The transition population is authored behavior: initial edges are excluded, generated combo edges are folded to their origin, and forced expansions are counted once per declaration.
- Parameters:
state_count – Non-pseudo state count, including composite states.
leaf_state_count – Non-pseudo leaf-state count.
composite_state_count – Non-pseudo composite-state count.
authored_transition_count – Authored behavior transitions after initial-edge, combo-expansion, and forced-expansion normalization.
transitions_per_state –
authored_transition_count / state_count;Nonewhen there are no states.states_per_transition – Inverse ratio;
Nonewhen there are no authored transitions.unreachable_leaf_states – Leaf states reported as unreachable.
unreachable_leaf_state_rate – Unreachable leaf states divided by the leaf-state population, or
Nonewhen there are no leaves.unreachable_transitions – Distinct authored transitions covered by the existing unreachable/dead/shadowed diagnostics.
unreachable_transition_rate – Unreachable authored transitions divided by authored transitions, or
Nonewhen there are none.unreachable_transition_reasons – Reason buckets for that count.
thresholds – Advisory thresholds applied to the rates. These are metadata only and do not emit diagnostics.
exceeded_thresholds – Names of advisory thresholds exceeded by this report.
unguarded_transitions – Authored transitions without an AST guard.
guard_eligible_transitions – Authored transition denominator for
unguarded_rate.unguarded_rate –
unguarded_transitions / guard_eligible_transitionsorNonefor an empty denominator.missing_effect_transitions – Effect-eligible transitions without an AST effect block.
effect_eligible_transitions – Authored non-forced transition denominator for
missing_effect_rate.missing_effect_rate – Missing-effect fraction or
Nonewhen the denominator is empty.eventless_unconditional_transitions – Authored transitions with no event and no guard.
behavior_transitions – Denominator for the eventless-unconditional rate; currently equal to
authored_transition_count.eventless_unconditional_rate – Eventless-unconditional fraction or
Nonewhen the denominator is empty.
InspectVerificationPolicy
InspectVerificationSummary
InspectVerificationAlgorithm
- class pyfcstm.diagnostics.inspect.InspectVerificationAlgorithm(algorithm_name: str, complexity_tier: str, call_count_scaling: str, verification_scope: str | None, declared_diagnostic_codes: Tuple[str, ...], result_kind: str, reason_code: str | None, reason: str | None, partial_diagnostic_count: int)[source]
Public execution projection for one registered verify algorithm.
InspectVerificationReport
- class pyfcstm.diagnostics.inspect.InspectVerificationReport(supported: bool, enabled: bool, provider: str | None, reason_code: str | None, requested_policy: InspectVerificationPolicy, summary: InspectVerificationSummary, algorithms: Tuple[InspectVerificationAlgorithm, ...])[source]
Optional verification status attached to
ModelInspect.
ModelInspect
- class pyfcstm.diagnostics.inspect.ModelInspect(root_state_path: str, states: ~typing.Tuple[~pyfcstm.diagnostics.inspect.StateInfo, ...], transitions: ~typing.Tuple[~pyfcstm.diagnostics.inspect.TransitionInfo, ...], variables: ~typing.Tuple[~pyfcstm.diagnostics.inspect.VariableInfo, ...], events: ~typing.Tuple[~pyfcstm.diagnostics.inspect.EventInfo, ...], actions: ~typing.Tuple[~pyfcstm.diagnostics.inspect.ActionInfo, ...], forced_transitions: ~typing.Tuple[~pyfcstm.diagnostics.inspect.ForcedTransitionInfo, ...], combo_transitions: ~typing.Tuple[~pyfcstm.diagnostics.inspect.TransitionInfo, ...], combo_origins: ~typing.Tuple[~pyfcstm.diagnostics.inspect.ComboOriginInfo, ...], metrics: ~pyfcstm.diagnostics.inspect.ModelMetrics, reachability_graph: ~typing.Dict[str, ~typing.Tuple[str, ...]], event_emission_map: ~typing.Dict[str, ~typing.Tuple[str, ...]], var_dataflow: ~typing.Dict[str, ~typing.Dict[str, ~typing.Tuple[str, ...]]], aspect_impact_map: ~typing.Dict[str, ~typing.Tuple[str, ...]], action_ref_graph: ~typing.Dict[str, ~typing.Tuple[str, ...]], diagnostics: ~typing.Tuple[~pyfcstm.utils.validate.ModelDiagnostic, ...] = <factory>, verification: ~pyfcstm.diagnostics.inspect.InspectVerificationReport = <factory>, structure_statistics: ~pyfcstm.diagnostics.inspect.StructureStatistics = <factory>)[source]
Top-level structured view of a state machine model.
- Parameters:
root_state_path (str) – Dotted path of the root state.
states (Tuple[StateInfo, ...]) – All states walked from the root in pre-order.
transitions (Tuple[TransitionInfo, ...]) – All transitions, including expanded forced transitions, in source order.
variables (Tuple[VariableInfo, ...]) – All
defvariables, in declaration order.events (Tuple[EventInfo, ...]) – All qualified events exposed by the inspect surface, including explicitly declared events that no transition uses, sorted by qualified name.
actions (Tuple[ActionInfo, ...]) – Lifecycle and aspect actions attached to states.
forced_transitions (Tuple[ForcedTransitionInfo, ...]) – Source forced-transition declarations and their expansion summary.
combo_transitions (Tuple[TransitionInfo, ...]) – Generated combo transitions copied out of
transitionsfor machine consumers that need direct access to combo projection metadata.combo_origins (Tuple[ComboOriginInfo, ...]) – Original combo transition provenance grouped by
origin_idand ordered by trigger term index.metrics (ModelMetrics) – Aggregate model metrics.
structure_statistics (StructureStatistics) – Descriptive authored-structure counts and rates for human and LLM consumers. These are not health thresholds.
reachability_graph (Dict[str, Tuple[str, ...]]) – Mapping from every state path to state paths reachable through normal transitions and composite initial edges. Guards are ignored;
[*]entry/exit markers are not exposed. A transition into a history also reaches the states of its default path and what a restore can re-enter.event_emission_map (Dict[str, Tuple[str, ...]]) – Mapping event qualified name → list of source state paths that can emit it.
var_dataflow (Dict[str, Dict[str, Tuple[str, ...]]]) – Mapping variable name →
{'reads': [...], 'writes': [...]}of state paths.aspect_impact_map (Dict[str, Tuple[str, ...]]) – Mapping composite path → descendant leaf paths actually reached by its aspect actions.
action_ref_graph (Dict[str, Tuple[str, ...]]) – Mapping named-action function path → list of
refedges out of it.diagnostics (Tuple[ModelDiagnostic, ...]) – Layer 1
E_*plus design-healthW_*/I_*diagnostics derived from the inspect payload.verification (InspectVerificationReport) – Verify-provider policy and execution projection. The disabled report is populated without importing
pyfcstm.verify.
- to_json() Dict[str, Any][source]
Serialize this inspection report to a plain JSON-friendly dict.
Tuples are converted to lists; frozen dataclasses to dicts.
ModelDiagnosticinstances are serialized via their public attributes (code,severity,message,span,refs).- Returns:
A dict that round-trips through
json.dumps()without loss.- Return type:
Dict[str, Any]
Examples:
>>> from pyfcstm.dsl import parse_with_grammar_entry >>> from pyfcstm.model import parse_dsl_node_to_state_machine >>> ast = parse_with_grammar_entry('state Root;', 'state_machine_dsl') >>> machine = parse_dsl_node_to_state_machine(ast) >>> report = inspect_model(machine) >>> report.to_json()['root_state_path'] 'Root'
inspect_model
- pyfcstm.diagnostics.inspect.inspect_model(machine: StateMachine, *, deep_hierarchy_threshold: int = 6, large_composite_threshold: int = 12, var_to_leaf_ratio_threshold: float = 2.0, structure_statistics_policy: object | None = None, enable_verify: bool = False, max_complexity_tier: str = 'structural', max_call_count_scaling: str = 'linear_in_transitions', smt_timeout_ms: int | None = None, model_diagnostics: Sequence[ModelDiagnostic] | None = None) ModelInspect[source]
Build a structured inspection report for a state machine model.
The report combines the structural payload, the five derived view graphs, and design-health diagnostics that can be computed from the inspect surface.
A machine that uses
[H]/[H*]history is reported as written: model conversion can also build the model before history lowering, and the report, its findings and the optional verify run describe that model, with each history entry an ordinary transition marked bytarget_history. The lowered variables, gate states and route initials therefore appear nowhere in the report. For reachability, a history entry also reaches every state on the default path of the kind it names.- Parameters:
machine (pyfcstm.model.StateMachine) – The state machine model to inspect.
deep_hierarchy_threshold (int) – Maximum accepted hierarchy depth.
large_composite_threshold (int) – Maximum accepted number of direct child states in one composite.
var_to_leaf_ratio_threshold (float) – Maximum accepted variable to non-pseudo leaf-state ratio.
structure_statistics_policy (Optional[object]) – Optional advisory structure-statistics thresholds. A mapping may override selected fields;
Noneuses the general-purpose defaults. Thresholds only appear in report metadata and never emit diagnostics.enable_verify (bool, optional) – Whether to run inspect-eligible
pyfcstm.verifyalgorithms and append their diagnostics. The defaultFalsepreserves the Layer 2 inspect contract.max_complexity_tier (str, optional) – Maximum verify complexity tier accepted by the inspect adapter when
enable_verifyis true."structural"keeps the default to graph-only verification.max_call_count_scaling (str, optional) – Maximum verify call-count scaling accepted by the inspect adapter when
enable_verifyis true.smt_timeout_ms (Optional[int], optional) – Optional solver timeout forwarded to SMT-local verify algorithms.
Nonepreserves the raw verify default of no configured timeout; an integer value must be non-negative.model_diagnostics (Optional[Sequence[pyfcstm.utils.validate.ModelDiagnostic]], optional) – Diagnostics produced while building
machine, prepended to the analyzer output. Callers that built the model withpyfcstm.model.parse_dsl_node_to_state_machine()in collect mode pass the returned diagnostic list here so the report carries the model errors alongside the design-health warnings. Defaults toNone, which uses the warnings a strict build ofmachineemitted while converting the model, such asW_HISTORY_UNUSED, so a strictly loaded model gets the same report aspyfcstm inspect.
- Returns:
Structured view of the model.
- Return type:
Examples:
>>> from pyfcstm.dsl import parse_with_grammar_entry >>> from pyfcstm.model import parse_dsl_node_to_state_machine >>> source = ''' ... state Root { ... state A; ... state B; ... [*] -> A; ... A -> B; ... } ... ''' >>> ast = parse_with_grammar_entry(source, 'state_machine_dsl') >>> machine = parse_dsl_node_to_state_machine(ast) >>> report = inspect_model(machine) >>> report.reachability_graph['Root.A'] ('Root.B',) >>> verify_report = inspect_model(machine, enable_verify=True) >>> len(verify_report.diagnostics) >= len(report.diagnostics) True