One Rung or Five? How to Count Networks in Ladder Logic
A network is one output, not one condition. The reset-latch example shows why the same behaviour can be one rung or two, and how timers and math count.
When our compiler finishes a program it says something like "✓ compiled · 53 networks". People sometimes expect that number to match the count of conditions they wrote, or the count of lines, and it matches neither. The rule it follows is the one ladder logic has always used, and once it clicks it changes how you write structured text for a PLC.
A network is an output
In ladder logic a network, also called a rung, is everything that drives one coil: the contacts, the branches, the timer in the middle, and the coil at the right rail. A rung with five contacts in series is one network. A rung with a three-branch OR is one network. What makes a new network is a new thing being written, not a new thing being tested.
So this is one network, however long the condition gets:
Stage1 := GridFreq < 49.5 AND BusVoltage > 0.8 AND NOT Blocked AND NOT Maint;
Four contacts in series, one coil. Our ladder view draws it as one card, and the FBD view draws a single AND gate with four inputs feeding one assignment.
The reset-latch example
Now take a latch. There are two idiomatic ways to write the same behaviour in structured text.
The seal-in form is a single assignment:
Motor := (Start OR Motor) AND NOT Stop;
One output, one network. The ladder shows the classic pattern: Start in parallel with a Motor contact, then a normally-closed Stop, then the Motor coil. It is the rung every apprentice learns, and it is one rung because it writes one coil once.
The set/reset form uses two conditionals:
IF Start THEN Motor := TRUE; END_IF;
IF Stop THEN Motor := FALSE; END_IF;
Same variable, same behaviour in most situations, but this is two networks: a SET coil driven by Start and a RESET coil driven by Stop. Ladder needs two rungs because there are two distinct writes, and each has its own condition. Our compiler lowers each IF … THEN X := TRUE/FALSE to exactly one such rung, which is also how the standard's set and reset coils are meant to be used.
The two forms differ in one corner: what happens when Start and Stop are both true on the same scan. The seal-in form has NOT Stop in series, so Stop wins. With separate set and reset coils, the answer depends on rung order on a real controller, the later rung winning. We made our simulator set-dominant for a SET/RESET pair regardless of order, and we say so in the docs, because "depends on rung order" is not a property you want to discover on site. If you need stop-dominant behaviour, write the seal-in.
IF/ELSE counts as two
IF c THEN X := TRUE; ELSE X := FALSE; END_IF; looks like one statement and is also two networks: a SET on c and a RESET on NOT c. It is behaviourally the same as X := c;, which is one network, and the drafter will prefer the single assignment when the intent is simply "X follows c". Use the IF form when you genuinely mean a latch.
Timers are their own network
Stage1Delay(IN := Stage1, PT := T#2s);
Trip1 := Stage1Delay.Q;
The timer call is a network. In ladder it is a rung whose element after the contacts is the TON box, with no coil of its own; the timer's Q is consumed by the next rung's contact. That is two networks, and the second one is what the technician forces to test the breaker. If you fold the timer call into a longer expression you cannot avoid it: the timer still gets its own rung, because a timer holds state and the ladder has to show where that state lives.
Math is one network per target
FreqDev := GridFreq - 50.0;
AbsDev := ABS(FreqDev);
Two numeric assignments, two networks. In the ladder view each is a single compute box (CPT FreqDev := GridFreq - 50.0); in FBD each becomes a chain of blocks ending in one assignment. A conditional numeric assignment, IF c THEN X := expr; END_IF;, is one network too: the contacts for c followed by a MOVE box, and X keeps its previous value when the condition is false.
A library block call such as SYM_COMP(...) expands to several math networks internally, but we render the call as one glyph and one rung, and count it as its expansion. The number in the status chip is the number of things the simulator evaluates per scan, which is what you want to know when you ask "how big is this program".
Why the count matters
Two reasons. First, review effort: a 53-network program is 53 rungs a reviewer has to read and a tester has to exercise, and no amount of clever expression nesting reduces that. Second, drift between languages: if your structured text has 30 assignments and the ladder printout has 41 rungs, the difference is timers and IF/ELSE pairs, and knowing that in advance is what lets the two views agree. Our two views are drawn from the same compiled model precisely so they never disagree about the count.
Try it: describe your logic in plain English at PLC-Ladder, and watch the network count as the drafter writes.