has_nc_channel
one row when the design can express intentional no-connect
What it is ¶
has_nc_channel(present) yields exactly one row, with the value true, when the design’s source
format can express an intentional no-connect, and zero rows otherwise. It is a design-capability
flag, not a per-entity relation: there is never more than one row, and its presence or absence is
the whole signal. A KiCad no-connect flag (a pin typed NO_CONNECT, or a net named
unconnected/no_connect/nc_) makes the row appear; a bare netlist that cannot state “this pin
is deliberately open” produces no row.
For hardware engineers ¶
Some formats let you mark a pin as intentionally left open, so the tool can tell “this pin is supposed to be unconnected” from “someone forgot to wire it.” Others carry no such marker at all. This flag says which world you are in. It matters because a rule that flags floating or single-pin conditions would fire on every deliberately-open pin in a format that cannot express intent, drowning the real problems. Querying it confirms whether the design even carries the no-connect vocabulary a per-pin absence check depends on.
For software engineers ¶
This is a capability probe over the whole design, closer to a feature flag than to a row set.
Because a rule reads it as has_nc_channel(?_), an absent row makes the enclosing conjunction
yield nothing, so the guard fails closed: on a format that cannot express intentional no-connect,
the gated rule produces no findings by construction. That is the point. Per-pin absence rules
must not fire where the format cannot distinguish an intentional open from a mistake (the naive
unconnected-pin check fired over 1800 times on a real netlist that had no no-connect channel; the
gate took it to zero). Absent means “the format cannot say,” which is treated as “do not fire,”
never as “everything is connected.”
Go projector ¶
ncChannelFacts in check/facts.go calls Model.HasNoConnectChannel(). When it is true the
projector returns a single row (subject true); when it is false it returns nil, so the relation
is one row or none, never more. The underlying flag is set during the model build (check/query.go)
whenever a pin carries the NO_CONNECT electrical type or a net uses the no-connect naming
vocabulary. Zero rows is the meaningful state, and it is what a gated rule fails closed on.
Datalog ¶
Probe the flag directly (one row true, or empty):
has_nc_channel(?present) => ?present
Use it as a guard so a per-pin absence check runs only where intentional no-connect is expressible (unconnected pins reported only when the format can say a pin is deliberately open):
pin(?r, ?p), not pin.net(?r, ?p, ?_), has_nc_channel(?present) => ?r, ?p