Subcircuit Recognizer

Layer 1 — Subcircuit Recognizer (SR).

Matches the pattern library (config/primitives.yaml + config/structural_patterns.yaml + config/opamp_patterns.yaml, loaded by load_patterns()) against a ParsedNetlist’s devices, producing a SubcircuitRecognitionResult.

The recognition algorithm runs in multiple ordered passes determined by a topological sort of pattern children references:

Pass 0 — exclusive per-device primitives. For each device, the highest-priority exclusive pattern that matches it is assigned. Each device is claimed by exactly one exclusive pattern. Exclusive patterns live in config/primitives.yaml.

Passes 1+ — multi-level composites. Patterns whose computed level ≥ 1 (i.e. they declare children) are tried in level order. A match is only accepted when all declared children are present as structures from the previous level’s pass. Multiple parent structures may share the same child (DAG sharing).

Non-exclusive level-0 pass. Patterns with no children and exclusive=False run in a single pass using the original algorithm — every assignment is accepted regardless of exclusive device claims. This preserves backward compatibility with the 34 MVP composite patterns.

See PatternDef for field semantics.

circuitgenome.recognizer.subcircuit_recognizer.load_patterns(path=None)[source]

Load the SR pattern library.

With no arguments, loads all three built-in files in dependency order:

  1. config/primitives.yaml — level-0 exclusive single-device patterns

  2. config/structural_patterns.yaml — circuit-type-agnostic composites (current mirrors, cascode pairs, etc.) shared across opamps, LDOs, etc.

  3. config/opamp_patterns.yaml — opamp-specific functional patterns (FBR categories: input_pair, load, tail_current, etc.)

Pass an explicit path to load a single custom file instead (the file must have a top-level "patterns" key).

Parameters:

path (Path | None) – If given, load only this file. Defaults to all three built-in files.

Returns:

PatternDef instances in load order (primitives → structural → opamp when using the default).

Return type:

list[PatternDef]

circuitgenome.recognizer.subcircuit_recognizer.recognize(netlist, patterns=None)[source]

Match every pattern in patterns against netlist.devices.

Runs the multi-level recognition algorithm:

  1. Pass 0 (exclusive) — assign each device to the highest-priority exclusive (level-0 primitive) pattern that matches it.

  2. Passes 1+ (multi-level) — for each level in topological order, find all assignments that satisfy both the template constraints and the children constraint (all declared children must be present from the previous level’s results).

  3. Non-exclusive level-0 pass — run all non-exclusive, children-less patterns in a single pass (the original MVP algorithm, backward- compatible with the 34 existing composite patterns).

Parameters:
Returns:

A SubcircuitRecognitionResult with one RecognizedStructure per accepted candidate (level-0 primitives, level-1+ composites, and MVP composites) and unrecognized_devices = every netlist device that is not part of any accepted candidate’s device set.

Return type:

SubcircuitRecognitionResult