fix(understand): a line number is not an equipment tag

parse_tag started a token at the first letter, so '100-P-001', a line
number that begins with its size, read as the pump tag P-001. The review of
the network engine found this. On a P&ID the phantom tag can capture a
valve beside the line as equipment, or collide with the real pump P-001.

A token that is the tail of a word beginning with a digit is no longer a
tag. The same text still yields T101 in 'LINE 100-P-001 TO T101', and
P-001 alone is still a tag. The new test failed before this change; the
label, network, describe, scale, cable and plant-pair suites all pass
(160 tests).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-24 12:48:56 +03:00
co-authored by Claude Opus 5.5
parent 27d44e909e
commit fb2953c324
2 changed files with 18 additions and 2 deletions
+8 -2
View File
@@ -229,9 +229,15 @@ def parse_tag(text: str | None) -> str | None:
``"Т4100"`` (Cyrillic Т) -> ``"T4100"``; ``"pump M41A"`` -> ``"M41A"``;
``"CP-M82"`` stays ``"CP-M82"``. A size label (``DN20``, ``SMS51``), a
pressure rating (``PN16``) or an IP code (``IP65``) is not a tag; a token
that keeps a Cyrillic letter without a Latin twin is not one either.
that keeps a Cyrillic letter without a Latin twin is not one either, and
neither is the tail of a word that begins with a digit - a line number
such as ``100-P-001`` names a pipe, not the pump ``P-001``.
"""
for match in _TAG_TOKEN.finditer(plain(text)):
source = plain(text)
for match in _TAG_TOKEN.finditer(source):
word_start = max(source.rfind(" ", 0, match.start()), source.rfind("\n", 0, match.start()))
if source[word_start + 1 : match.start()][:1].isdigit():
continue
token = fold_lookalikes(match.group(0)).rstrip(".-")
if not _TAG_RE.fullmatch(token):
continue
+10
View File
@@ -163,6 +163,16 @@ def test_text_without_a_tag():
assert parse_tag(None) is None
def test_a_line_number_is_not_an_equipment_tag():
# A line number starts with its size: read as a tag, '100-P-001' would give
# 'P-001', which can capture a valve beside the line or collide with a real
# pump P-001. A word that begins with a digit holds no tag.
assert parse_tag("100-P-001") is None
assert parse_tag('2"-P-1001-A1') is None
assert parse_tag("LINE 100-P-001 TO T101") == "T101"
assert parse_tag("P-001") == "P-001" # the pump itself is still a tag
# -- panels and wiring callouts ----------------------------------------------------