Skip to content

det: P-scaled PICTUREs as cobc stores them, the rest refused by name (#4669, #4670) - #4685

Merged
squid-protocol merged 3 commits into
mainfrom
fix/4669-4670-p-scaling
Oct 8, 2026
Merged

squid-protocol merged 3 commits into
mainfrom
fix/4669-4670-p-scaling

Conversation

@squid-protocol

@squid-protocol squid-protocol commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Fixes #4669, Fixes #4670

Part of #4270. P-scaled PICTUREs in the det translator / runtime, measured against the oracle (cobc 3.1.2 -std=ibm) item by item.

Modelled

A P is a scaling position, never stored. Item.digits now counts a numeric item's 9s and Item.scale counts the Ps: 99PP / 99PPV are 2 digits at scale -2, VPP99 / PP99 are 2 digits at scale 4. Nothing else in the runtime needed to change for these: BigDecimal.setScale(-2) already truncates the way cobc does.

Refused by name (the oracle has no usable answer)

  • P-scaled COMP-3: cobc 3.1.2 puts digits into the sign nibble (MOVE 5600 TO PIC S99PP COMP-3 reads back as <600).
  • Right-P or COMP-5 binary: cobc loops forever on MOVE 0 into PIC 99PP COMP.
  • DISPLAY of a P-scaled item: cobc writes 99PP VALUE 1200 as 0012 and S99PP -3400 as 0034-.
  • A P-scaled operand in a condition's arithmetic expression: cobc says IF PR / 7 > 171 and IF PR * 2 > 2399 are false for 1200.
  • A right-P operand in a COMPUTE with a division or more than two operands: cobc computes (PR / 7) * PR with truncated quotient digits, and I5 + PR * 0.5 and B0 * .03 * PS as if the product were 0.

The #4668 refusal (a P-scaled operand in a numeric-edited comparison) is not touched.

Shared functions touched (for the det/cobolrt train: #4654, #4677, #4663, #4666, #4668)

  • layout.py: Item.digits, Item.scale, new Item.p_scaled, Item.elementary_size (one line)
  • gen.py: new module function p_unmodelled, Gen.resolve (3 lines at its end), Gen._init_one (3 lines at its top), Gen.display_operand (3 lines), Gen.rel (numeric branch, 2 lines), new method Gen.p_scaled_expr, the COMPUTE branch of the statement translator (1 line)
  • cobolrt/Cobol.java: sourceText (its two returns), new helper pZeros

Evidence

  • Tests (tests/cobol_mainframe/test_det_programs.py), all 12 fail on origin/main and pass here:
    • PSCALE: an end-to-end program run in bytes, typed and groups modes. It has about 140 output lines over 8 P-scaled items and is equal to GnuCOBOL.
    • 8 refusal cases.
    • A layout unit test for digits / scale / size and the packed bytes.
  • Random differential fuzz: the det-4655 generator plus 6 P-scaled operands and 3 P-scaled receivers, 40 programs of 100 statements, bytes and typed modes. The generator leaves out the refused forms.
  • det_port.py check vs origin/main: all 68 ports change, but only in the runtime's Cobol.java (17 lines). No service changed.
  • proof_sweep.py --det-only: 65 PROVED, and 3 NOT PROVEN that are already in the baseline (carddemo-cardupdate, carddemo-intcalc-generated, mortgage-mpmt). Result "sweep: as expected".
  • evidence_report.py --check rc 0. test_evidence.py and test_evidence_report.py: 71 passed.
  • pr_gates.py --fast: 5/5 pass. pr_gates.py --ratchets: 7 pass, 0 fail, 0 skipped.

Follow-ups filed

🤖 Generated with Claude Code

…ed by name (#4669, #4670)

A P is a scaling position, never stored: Item.digits counts a numeric item's 9s and Item.scale counts the Ps
(99PP: 2 digits, scale -2; VPP99 / PP99: 2 digits, scale 4). PIC SVPP99 COMP-3 no longer crashes the layout
(ValueError) and MOVE 1200 TO a 99PP item no longer throws in Cobol.store. A right-P item MOVEd to an
alphanumeric gets a zero per P (Cobol.sourceText), as GnuCOBOL does.

Refused by name where GnuCOBOL 3.1.2 gives no usable oracle: P-scaled COMP-3 (mis-stored), right-P / COMP-5
binary (loops on MOVE 0), DISPLAY of a P-scaled item (cobc shows 99PP VALUE 1200 as 0012), a P-scaled
operand in a condition's arithmetic expression, and a right-P operand in a COMPUTE with a division or three
operands (cobc's intermediate precision for it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

squid-protocol and others added 2 commits October 8, 2026 11:23
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
@squid-protocol
squid-protocol marked this pull request as ready for review October 8, 2026 17:09
@squid-protocol
squid-protocol merged commit 321f9fe into main Oct 8, 2026
37 checks passed
@squid-protocol
squid-protocol deleted the fix/4669-4670-p-scaling branch October 8, 2026 17:09
squid-protocol added a commit that referenced this pull request Oct 8, 2026
Conflict in Gen's COMPUTE: keep #4685's p_scaled_expr refusal (first)
and this PR's ARITHMETIC-OSVS plan around the expression.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
squid-protocol added a commit that referenced this pull request Oct 8, 2026
squid-protocol added a commit that referenced this pull request Oct 8, 2026
…e-error

gen.py COMPUTE: this PR's float_statement(targets) kept with main's
p_scaled_expr refusal (#4685). test_det_size_error.py: both branches
already use the one `import test_det_programs as T` form (CodeQL).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQNoe4wPJgr7dbUvs3DG6D
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant