feat: Phase 2 complete — 13 Phases of COBOL type classification and test benchmark

P0.6: gcov infrastructure
P1: extract_structure output expansion (11 new feature fields)
P2: Confusion group rule engine (8 pairs + contradiction + backtrack)
P3: 4-factor confidence calculation + quality gate update
P4: 33+2 COBOL program type test samples (22 files, 7 categories)
P5: parametrized/ test data generation engine
P6: japanese_data.py lookup tables
P7-10: Type-specific test suites (~159 parametrized tests)
P11: Full classification pipeline (classify_program) + orchestrator integration
P12: Documentation (module-interfaces, test-plan v3.0, coverage-matrix)

Architecture decisions:
- classification_pipeline/ merged to hina/pipeline/
- parametrized/ as independent module
- japanese_data.py as root-level file
- hina/__all__ only exports classify_program()

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
hangshuo652
2026-06-19 23:51:55 +08:00
parent 63b5284715
commit bc1d56d1a4
129 changed files with 19378 additions and 261 deletions
@@ -0,0 +1,31 @@
* ==== TYPE: CI01 CICS ====
*> FEATURE: DFHCOMMAREA + MAP simulation
*> NOTE: CICS keywords marked with *> not for compilation
IDENTIFICATION DIVISION.
PROGRAM-ID. CI01.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COMMAREA.
05 WS-CA-LENGTH PIC S9(4) COMP.
05 WS-CA-DATA PIC X(100).
01 WS-MAP-RECV.
05 WS-MAP-INPUT PIC X(50).
01 WS-MAP-SEND.
05 WS-MAP-OUTPUT PIC X(50).
01 WS-RESPONSE PIC S9(8) COMP.
PROCEDURE DIVISION.
*> EXEC CICS RECEIVE MAP('MAP01')
*> INTO(WS-MAP-RECV)
*> RESP(WS-RESPONSE)
*> END-EXEC.
DISPLAY 'RECEIVED MAP'.
*> EXEC CICS SEND MAP('MAP01')
*> FROM(WS-MAP-SEND)
*> RESP(WS-RESPONSE)
*> END-EXEC.
DISPLAY 'SENT MAP'.
*> EXEC CICS RETURN
*> COMMAREA(WS-COMMAREA)
*> END-EXEC.
STOP RUN.
@@ -0,0 +1,24 @@
* ==== TYPE: CV01 CSV(NO NEWLINE) ====
* FEATURE: STRING concatenation without newline
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. CV01.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-FIELD1 PIC X(10) VALUE 'ALPHA'.
01 WS-FIELD2 PIC X(10) VALUE 'BETA'.
01 WS-FIELD3 PIC X(10) VALUE 'GAMMA'.
01 WS-CSV-LINE PIC X(100).
01 WS-PTR PIC 9(3) VALUE 1.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
MOVE 1 TO WS-PTR.
STRING WS-FIELD1 DELIMITED BY SPACES
',' DELIMITED BY SIZE
WS-FIELD2 DELIMITED BY SPACES
',' DELIMITED BY SIZE
WS-FIELD3 DELIMITED BY SPACES
INTO WS-CSV-LINE
WITH POINTER WS-PTR.
DISPLAY 'CSV: ' WS-CSV-LINE.
STOP RUN.
@@ -0,0 +1,25 @@
* ==== TYPE: CV02 CSV(WITH NEWLINE) ====
* FEATURE: INSPECT REPLACING for newline handling
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. CV02.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-LINE PIC X(100) VALUE
'FIELD1,FIELD2,FIELD3'.
01 WS-PTR PIC 9(3) VALUE 1.
01 WS-COM-COUNT PIC 9(3) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
INSPECT WS-LINE TALLYING WS-COM-COUNT
FOR ALL ','.
DISPLAY 'COMMA COUNT: ' WS-COM-COUNT.
INSPECT WS-LINE REPLACING ALL ',' BY '|'.
DISPLAY 'PIPE LINE: ' WS-LINE.
MOVE 1 TO WS-PTR.
STRING WS-LINE DELIMITED BY SPACES
';' DELIMITED BY SIZE
INTO WS-LINE
WITH POINTER WS-PTR.
DISPLAY 'CSV+TERM: ' WS-LINE.
STOP RUN.
@@ -0,0 +1,27 @@
* ==== TYPE: CV03 ASCII-EBCDIC ====
* FEATURE: ASCII to EBCDIC conversion simulation
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. CV03.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ASCII-DATA PIC X(10) VALUE 'ABCDEF0123'.
01 WS-EBCDIC-DATA PIC X(10).
01 WS-I PIC 9(2) VALUE 1.
01 WS-CHAR PIC X(1).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
MOVE SPACES TO WS-EBCDIC-DATA.
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
MOVE WS-ASCII-DATA(WS-I:1) TO WS-CHAR
IF WS-CHAR >= 'A' AND <= 'Z'
DISPLAY 'ALPHA AT ' WS-I
ELSE IF WS-CHAR >= '0' AND <= '9'
DISPLAY 'DIGIT AT ' WS-I
ELSE
DISPLAY 'OTHER AT ' WS-I
END-IF
END-PERFORM.
MOVE WS-ASCII-DATA TO WS-EBCDIC-DATA.
DISPLAY 'EBCDIC: ' WS-EBCDIC-DATA.
STOP RUN.
@@ -0,0 +1,34 @@
* ==== TYPE: DB01 SELECT-UPDATE ====
*> FEATURE: EXEC SQL + INSERT/UPDATE simulation
*> NOTE: SQL keywords marked with *> not for compilation
IDENTIFICATION DIVISION.
PROGRAM-ID. DB01.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EMP-ID PIC X(10).
01 WS-EMP-NAME PIC X(30).
01 WS-EMP-SALARY PIC 9(7)V99.
01 WS-SQLCODE PIC S9(4) COMP.
01 WS-SQLMSG PIC X(50).
PROCEDURE DIVISION.
*> EXEC SQL
*> SELECT EMP_NAME, EMP_SALARY
*> INTO :WS-EMP-NAME, :WS-EMP-SALARY
*> FROM EMPLOYEE
*> WHERE EMP_ID = :WS-EMP-ID
*> END-EXEC.
DISPLAY 'SELECTED: ' WS-EMP-NAME.
*> EXEC SQL
*> UPDATE EMPLOYEE
*> SET EMP_SALARY = :WS-EMP-SALARY
*> WHERE EMP_ID = :WS-EMP-ID
*> END-EXEC.
DISPLAY 'UPDATED: ' WS-EMP-ID.
*> EXEC SQL
*> INSERT INTO EMPLOYEE
*> (EMP_ID, EMP_NAME, EMP_SALARY)
*> VALUES (:WS-EMP-ID, :WS-EMP-NAME,
*> :WS-EMP-SALARY)
*> END-EXEC.
DISPLAY 'INSERTED: ' WS-EMP-ID.
STOP RUN.
@@ -0,0 +1,22 @@
* ==== TYPE: DV01 DIVIDE(50) ====
* FEATURE: DIVIDE 50 INTO
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. DV01.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VALUE PIC 9(5) VALUE 10000.
01 WS-RESULT PIC 9(5) VALUE 0.
01 WS-REMAIND PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DIVIDE 50 INTO WS-VALUE GIVING WS-RESULT
REMAINDER WS-REMAIND.
DISPLAY 'VALUE: ' WS-VALUE ' RESULT: ' WS-RESULT
' REM: ' WS-REMAIND.
IF WS-REMAIND = 0
DISPLAY 'DIVISIBLE BY 50'
ELSE
DISPLAY 'NOT DIVISIBLE BY 50'
END-IF.
STOP RUN.
@@ -0,0 +1,22 @@
* ==== TYPE: DV02 DIVIDE(25) ====
* FEATURE: DIVIDE 25 INTO
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. DV02.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VALUE PIC 9(5) VALUE 5000.
01 WS-RESULT PIC 9(5) VALUE 0.
01 WS-REMAIND PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DIVIDE 25 INTO WS-VALUE GIVING WS-RESULT
REMAINDER WS-REMAIND.
DISPLAY 'VALUE: ' WS-VALUE ' RESULT: ' WS-RESULT
' REM: ' WS-REMAIND.
IF WS-REMAIND = 0
DISPLAY 'DIVISIBLE BY 25'
ELSE
DISPLAY 'NOT DIVISIBLE BY 25'
END-IF.
STOP RUN.
@@ -0,0 +1,22 @@
* ==== TYPE: DV03 DIVIDE(100) ====
* FEATURE: DIVIDE 100 INTO
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. DV03.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VALUE PIC 9(5) VALUE 20000.
01 WS-RESULT PIC 9(5) VALUE 0.
01 WS-REMAIND PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DIVIDE 100 INTO WS-VALUE GIVING WS-RESULT
REMAINDER WS-REMAIND.
DISPLAY 'VALUE: ' WS-VALUE ' RESULT: ' WS-RESULT
' REM: ' WS-REMAIND.
IF WS-REMAIND = 0
DISPLAY 'DIVISIBLE BY 100'
ELSE
DISPLAY 'NOT DIVISIBLE BY 100'
END-IF.
STOP RUN.
@@ -0,0 +1,43 @@
* ==== TYPE: MT01 MATCHING(1:1) ====
* FEATURE: 2 input files, IF KEY = compare, 3-way IF
* BRANCHES: 4, DECISIONS: 2
IDENTIFICATION DIVISION.
PROGRAM-ID. MT01.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-A ASSIGN TO 'FILEA.DAT'.
SELECT FILE-B ASSIGN TO 'FILEB.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-A.
01 REC-A PIC X(80).
FD FILE-B.
01 REC-B PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-A PIC X(10).
01 WS-KEY-B PIC X(10).
01 WS-EOF-A PIC X VALUE 'N'.
01 WS-EOF-B PIC X VALUE 'N'.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-A FILE-B.
READ FILE-A INTO REC-A
AT END MOVE 'Y' TO WS-EOF-A.
READ FILE-B INTO REC-B
AT END MOVE 'Y' TO WS-EOF-B.
PERFORM UNTIL WS-EOF-A = 'Y' OR WS-EOF-B = 'Y'
IF WS-KEY-A = WS-KEY-B
DISPLAY 'MATCH: ' REC-A(1:50)
READ FILE-A AT END MOVE 'Y' TO WS-EOF-A
READ FILE-B AT END MOVE 'Y' TO WS-EOF-B
ELSE IF WS-KEY-A < WS-KEY-B
DISPLAY 'UNMATCH-A: ' REC-A(1:50)
READ FILE-A AT END MOVE 'Y' TO WS-EOF-A
ELSE
DISPLAY 'UNMATCH-B: ' REC-B(1:50)
READ FILE-B AT END MOVE 'Y' TO WS-EOF-B
END-IF
END-PERFORM.
CLOSE FILE-A FILE-B.
STOP RUN.
@@ -0,0 +1,44 @@
* ==== TYPE: MT02 MATCHING(1:N) ====
* FEATURE: 1 master file, N transaction files
* BRANCHES: 6, DECISIONS: 3
IDENTIFICATION DIVISION.
PROGRAM-ID. MT02.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT MASTER-FILE ASSIGN TO 'MASTER.DAT'.
SELECT TRANS-FILE ASSIGN TO 'TRANS.DAT'.
DATA DIVISION.
FILE SECTION.
FD MASTER-FILE.
01 MASTER-REC PIC X(80).
FD TRANS-FILE.
01 TRANS-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-MAST-KEY PIC X(10).
01 WS-TRAN-KEY PIC X(10).
01 WS-MAST-EOF PIC X VALUE 'N'.
01 WS-TRAN-EOF PIC X VALUE 'N'.
01 WS-MATCH-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT MASTER-FILE TRANS-FILE.
READ MASTER-FILE INTO MASTER-REC
AT END MOVE 'Y' TO WS-MAST-EOF.
READ TRANS-FILE INTO TRANS-REC
AT END MOVE 'Y' TO WS-TRAN-EOF.
PERFORM UNTIL WS-MAST-EOF = 'Y' OR WS-TRAN-EOF = 'Y'
IF WS-MAST-KEY = WS-TRAN-KEY
ADD 1 TO WS-MATCH-COUNT
DISPLAY 'MATCH: ' TRANS-REC(1:50)
READ TRANS-FILE AT END MOVE 'Y' TO WS-TRAN-EOF
ELSE IF WS-MAST-KEY < WS-TRAN-KEY
DISPLAY 'MASTER UNMATCHED: ' MASTER-REC(1:40)
READ MASTER-FILE AT END MOVE 'Y' TO WS-MAST-EOF
ELSE
DISPLAY 'TRAN UNMATCHED: ' TRANS-REC(1:40)
READ TRANS-FILE AT END MOVE 'Y' TO WS-TRAN-EOF
END-IF
END-PERFORM.
CLOSE MASTER-FILE TRANS-FILE.
STOP RUN.
@@ -0,0 +1,44 @@
* ==== TYPE: MT03 MATCHING(N:1) ====
* FEATURE: N master files, 1 transaction file
* BRANCHES: 6, DECISIONS: 3
IDENTIFICATION DIVISION.
PROGRAM-ID. MT03.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-M ASSIGN TO 'FILEM.DAT'.
SELECT FILE-T ASSIGN TO 'FILET.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-M.
01 REC-M PIC X(80).
FD FILE-T.
01 REC-T PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-M PIC X(10).
01 WS-KEY-T PIC X(10).
01 WS-M-EOF PIC X VALUE 'N'.
01 WS-T-EOF PIC X VALUE 'N'.
01 WS-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-M FILE-T.
READ FILE-M INTO REC-M
AT END MOVE 'Y' TO WS-M-EOF.
READ FILE-T INTO REC-T
AT END MOVE 'Y' TO WS-T-EOF.
PERFORM UNTIL WS-M-EOF = 'Y' OR WS-T-EOF = 'Y'
IF WS-KEY-M = WS-KEY-T
ADD 1 TO WS-COUNT
DISPLAY 'MATCHED: ' REC-M(1:50)
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
ELSE IF WS-KEY-M < WS-KEY-T
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
ELSE
DISPLAY 'TRAN ONLY: ' REC-T(1:50)
READ FILE-T AT END MOVE 'Y' TO WS-T-EOF
END-IF
END-PERFORM.
DISPLAY 'TOTAL MATCHED: ' WS-COUNT.
CLOSE FILE-M FILE-T.
STOP RUN.
@@ -0,0 +1,64 @@
* ==== TYPE: MT16 TWO-STAGE MATCHING(1:1) ====
* FEATURE: 1:1 -> intermediate file -> re-match
* BRANCHES: 8, DECISIONS: 4
IDENTIFICATION DIVISION.
PROGRAM-ID. MT16.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-A ASSIGN TO 'FILEA.DAT'.
SELECT FILE-B ASSIGN TO 'FILEB.DAT'.
SELECT FILE-C ASSIGN TO 'FILEC.DAT'.
SELECT INT-FILE ASSIGN TO 'INTERM.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-A.
01 REC-A PIC X(80).
FD FILE-B.
01 REC-B PIC X(80).
FD FILE-C.
01 REC-C PIC X(80).
FD INT-FILE.
01 INT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-A PIC X(10).
01 WS-KEY-B PIC X(10).
01 WS-KEY-C PIC X(10).
01 WS-EOF-A PIC X VALUE 'N'.
01 WS-EOF-B PIC X VALUE 'N'.
01 WS-EOF-I PIC X VALUE 'N'.
PROCEDURE DIVISION.
STAGE-1.
OPEN INPUT FILE-A FILE-B.
OPEN OUTPUT INT-FILE.
READ FILE-A AT END MOVE 'Y' TO WS-EOF-A.
READ FILE-B AT END MOVE 'Y' TO WS-EOF-B.
PERFORM UNTIL WS-EOF-A = 'Y' OR WS-EOF-B = 'Y'
IF WS-KEY-A = WS-KEY-B
WRITE INT-REC FROM REC-A
READ FILE-A AT END MOVE 'Y' TO WS-EOF-A
READ FILE-B AT END MOVE 'Y' TO WS-EOF-B
ELSE IF WS-KEY-A < WS-KEY-B
READ FILE-A AT END MOVE 'Y' TO WS-EOF-A
ELSE
READ FILE-B AT END MOVE 'Y' TO WS-EOF-B
END-IF
END-PERFORM.
CLOSE FILE-A FILE-B INT-FILE.
STAGE-2.
OPEN INPUT INT-FILE FILE-C.
READ INT-FILE AT END MOVE 'Y' TO WS-EOF-I.
READ FILE-C AT END MOVE 'Y' TO WS-EOF-A.
PERFORM UNTIL WS-EOF-I = 'Y' OR WS-EOF-A = 'Y'
IF WS-KEY-C = WS-KEY-A
DISPLAY 'FINAL MATCH'
READ INT-FILE AT END MOVE 'Y' TO WS-EOF-I
READ FILE-C AT END MOVE 'Y' TO WS-EOF-A
ELSE IF WS-KEY-C < WS-KEY-A
READ FILE-C AT END MOVE 'Y' TO WS-EOF-A
ELSE
READ INT-FILE AT END MOVE 'Y' TO WS-EOF-I
END-IF
END-PERFORM.
CLOSE INT-FILE FILE-C.
STOP RUN.
@@ -0,0 +1,55 @@
* ==== TYPE: MT17 TWO-STAGE MATCHING(N:1) ====
* FEATURE: N:1 -> intermediate file -> re-match
* BRANCHES: 8, DECISIONS: 4
IDENTIFICATION DIVISION.
PROGRAM-ID. MT17.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-X ASSIGN TO 'FILEX.DAT'.
SELECT FILE-Y ASSIGN TO 'FILEY.DAT'.
SELECT INT-FILE ASSIGN TO 'INTERM.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-X.
01 REC-X PIC X(80).
FD FILE-Y.
01 REC-Y PIC X(80).
FD INT-FILE.
01 INT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-X PIC X(10).
01 WS-KEY-Y PIC X(10).
01 WS-EOF-X PIC X VALUE 'N'.
01 WS-EOF-Y PIC X VALUE 'N'.
01 WS-EOF-I PIC X VALUE 'N'.
01 WS-INT-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
STAGE-1.
OPEN INPUT FILE-X FILE-Y.
OPEN OUTPUT INT-FILE.
READ FILE-X AT END MOVE 'Y' TO WS-EOF-X.
READ FILE-Y AT END MOVE 'Y' TO WS-EOF-Y.
PERFORM UNTIL WS-EOF-X = 'Y' OR WS-EOF-Y = 'Y'
IF WS-KEY-X = WS-KEY-Y
WRITE INT-REC FROM REC-Y
READ FILE-Y AT END MOVE 'Y' TO WS-EOF-Y
ELSE IF WS-KEY-X < WS-KEY-Y
READ FILE-X AT END MOVE 'Y' TO WS-EOF-X
ELSE
READ FILE-Y AT END MOVE 'Y' TO WS-EOF-Y
END-IF
END-PERFORM.
CLOSE FILE-X FILE-Y INT-FILE.
STAGE-2.
OPEN INPUT INT-FILE.
OPEN OUTPUT FILE-X.
READ INT-FILE AT END MOVE 'Y' TO WS-EOF-I.
PERFORM UNTIL WS-EOF-I = 'Y'
ADD 1 TO WS-INT-COUNT
WRITE REC-X FROM INT-REC
READ INT-FILE AT END MOVE 'Y' TO WS-EOF-I
END-PERFORM.
DISPLAY 'INT RECORDS: ' WS-INT-COUNT.
CLOSE INT-FILE FILE-X.
STOP RUN.
@@ -0,0 +1,42 @@
* ==== TYPE: MT18 MATCHING(M:N -> M) ====
* FEATURE: M:N combination, output M records
* BRANCHES: 6, DECISIONS: 3
IDENTIFICATION DIVISION.
PROGRAM-ID. MT18.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-M ASSIGN TO 'FILEM.DAT'.
SELECT FILE-N ASSIGN TO 'FILEN.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-M.
01 REC-M PIC X(80).
FD FILE-N.
01 REC-N PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-M PIC X(10).
01 WS-KEY-N PIC X(10).
01 WS-M-EOF PIC X VALUE 'N'.
01 WS-N-EOF PIC X VALUE 'N'.
01 WS-M-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-M FILE-N.
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF.
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF.
PERFORM UNTIL WS-M-EOF = 'Y' OR WS-N-EOF = 'Y'
IF WS-KEY-M = WS-KEY-N
ADD 1 TO WS-M-COUNT
DISPLAY 'M-OUT: ' REC-M(1:50)
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
ELSE IF WS-KEY-M < WS-KEY-N
DISPLAY 'M-ONLY: ' REC-M(1:50)
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
ELSE
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF
END-IF
END-PERFORM.
DISPLAY 'M RECORDS OUT: ' WS-M-COUNT.
CLOSE FILE-M FILE-N.
STOP RUN.
@@ -0,0 +1,42 @@
* ==== TYPE: MT19 MATCHING(M:N -> N) ====
* FEATURE: M:N combination, output N records
* BRANCHES: 6, DECISIONS: 3
IDENTIFICATION DIVISION.
PROGRAM-ID. MT19.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-M ASSIGN TO 'FILEM.DAT'.
SELECT FILE-N ASSIGN TO 'FILEN.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-M.
01 REC-M PIC X(80).
FD FILE-N.
01 REC-N PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-M PIC X(10).
01 WS-KEY-N PIC X(10).
01 WS-M-EOF PIC X VALUE 'N'.
01 WS-N-EOF PIC X VALUE 'N'.
01 WS-N-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-M FILE-N.
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF.
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF.
PERFORM UNTIL WS-M-EOF = 'Y' OR WS-N-EOF = 'Y'
IF WS-KEY-M = WS-KEY-N
ADD 1 TO WS-N-COUNT
DISPLAY 'N-OUT: ' REC-N(1:50)
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF
ELSE IF WS-KEY-M < WS-KEY-N
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
ELSE
DISPLAY 'N-ONLY: ' REC-N(1:50)
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF
END-IF
END-PERFORM.
DISPLAY 'N RECORDS OUT: ' WS-N-COUNT.
CLOSE FILE-M FILE-N.
STOP RUN.
@@ -0,0 +1,48 @@
* ==== TYPE: MT20 MATCHING(M:N -> MxN) ====
* FEATURE: M:N Cartesian product
* BRANCHES: 8, DECISIONS: 4
IDENTIFICATION DIVISION.
PROGRAM-ID. MT20.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-M ASSIGN TO 'FILEM.DAT'.
SELECT FILE-N ASSIGN TO 'FILEN.DAT'.
SELECT FILE-O ASSIGN TO 'FILEO.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-M.
01 REC-M PIC X(80).
FD FILE-N.
01 REC-N PIC X(80).
FD FILE-O.
01 REC-O PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-M PIC X(10).
01 WS-KEY-N PIC X(10).
01 WS-M-EOF PIC X VALUE 'N'.
01 WS-N-EOF PIC X VALUE 'N'.
01 WS-PROD-COUNT PIC 9(6) VALUE 0.
01 WS-SAVE-KEY PIC X(10).
01 WS-SAVE-REC PIC X(80).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-M FILE-N.
OPEN OUTPUT FILE-O.
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF.
PERFORM UNTIL WS-M-EOF = 'Y'
MOVE WS-KEY-M TO WS-SAVE-KEY
MOVE REC-M TO WS-SAVE-REC
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF
PERFORM UNTIL WS-N-EOF = 'Y'
IF WS-KEY-N = WS-SAVE-KEY
ADD 1 TO WS-PROD-COUNT
WRITE REC-O FROM WS-SAVE-REC
END-IF
READ FILE-N AT END MOVE 'Y' TO WS-N-EOF
END-PERFORM
READ FILE-M AT END MOVE 'Y' TO WS-M-EOF
END-PERFORM.
DISPLAY 'CARTESIAN PRODUCT COUNT: ' WS-PROD-COUNT.
CLOSE FILE-M FILE-N FILE-O.
STOP RUN.
@@ -0,0 +1,47 @@
* ==== TYPE: MT32 MIXED MATCHING(SAME KEY) ====
* FEATURE: 1:N + same key mixed
* BRANCHES: 8, DECISIONS: 4
IDENTIFICATION DIVISION.
PROGRAM-ID. MT32.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-P ASSIGN TO 'FILEP.DAT'.
SELECT FILE-Q ASSIGN TO 'FILEQ.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-P.
01 REC-P PIC X(80).
FD FILE-Q.
01 REC-Q PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-P PIC X(10).
01 WS-KEY-Q PIC X(10).
01 WS-P-EOF PIC X VALUE 'N'.
01 WS-Q-EOF PIC X VALUE 'N'.
01 WS-PREV-KEY PIC X(10) VALUE SPACES.
01 WS-MIXED-FLAG PIC X VALUE 'N'.
01 WS-GROUP-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-P FILE-Q.
READ FILE-P AT END MOVE 'Y' TO WS-P-EOF.
READ FILE-Q AT END MOVE 'Y' TO WS-Q-EOF.
PERFORM UNTIL WS-P-EOF = 'Y' OR WS-Q-EOF = 'Y'
IF WS-KEY-P = WS-KEY-Q
IF WS-PREV-KEY NOT = WS-KEY-P
MOVE 'Y' TO WS-MIXED-FLAG
MOVE WS-KEY-P TO WS-PREV-KEY
END-IF
ADD 1 TO WS-GROUP-COUNT
READ FILE-P AT END MOVE 'Y' TO WS-P-EOF
READ FILE-Q AT END MOVE 'Y' TO WS-Q-EOF
ELSE IF WS-KEY-P < WS-KEY-Q
READ FILE-P AT END MOVE 'Y' TO WS-P-EOF
ELSE
READ FILE-Q AT END MOVE 'Y' TO WS-Q-EOF
END-IF
END-PERFORM.
DISPLAY 'MIXED GROUPS: ' WS-GROUP-COUNT.
CLOSE FILE-P FILE-Q.
STOP RUN.
@@ -0,0 +1,45 @@
* ==== TYPE: MT33 MIXED MATCHING(DIFF KEY) ====
* FEATURE: 1:N + different key mixed
* BRANCHES: 8, DECISIONS: 4
IDENTIFICATION DIVISION.
PROGRAM-ID. MT33.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-R ASSIGN TO 'FILER.DAT'.
SELECT FILE-S ASSIGN TO 'FILES.DAT'.
DATA DIVISION.
FILE SECTION.
FD FILE-R.
01 REC-R PIC X(80).
FD FILE-S.
01 REC-S PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY-R PIC X(10).
01 WS-KEY-S PIC X(10).
01 WS-ALT-KEY PIC X(10).
01 WS-R-EOF PIC X VALUE 'N'.
01 WS-S-EOF PIC X VALUE 'N'.
01 WS-DIFF-FLAG PIC X VALUE 'N'.
01 WS-CROSS-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT FILE-R FILE-S.
READ FILE-R AT END MOVE 'Y' TO WS-R-EOF.
READ FILE-S AT END MOVE 'Y' TO WS-S-EOF.
PERFORM UNTIL WS-R-EOF = 'Y' OR WS-S-EOF = 'Y'
MOVE WS-KEY-R TO WS-ALT-KEY
IF WS-KEY-R = WS-KEY-S
ADD 1 TO WS-CROSS-COUNT
MOVE 'Y' TO WS-DIFF-FLAG
READ FILE-R AT END MOVE 'Y' TO WS-R-EOF
READ FILE-S AT END MOVE 'Y' TO WS-S-EOF
ELSE IF WS-ALT-KEY < WS-KEY-S
READ FILE-R AT END MOVE 'Y' TO WS-R-EOF
ELSE
READ FILE-S AT END MOVE 'Y' TO WS-S-EOF
END-IF
END-PERFORM.
DISPLAY 'CROSS MATCHES: ' WS-CROSS-COUNT.
CLOSE FILE-R FILE-S.
STOP RUN.
@@ -0,0 +1,38 @@
* ==== TYPE: ST01 SORT ====
* FEATURE: SORT USING/GIVING ascending + INPUT PROCEDURE
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. ST01.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO 'INDATA.DAT'.
SELECT OUT-FILE ASSIGN TO 'OUTDATA.DAT'.
SELECT SORT-FILE ASSIGN TO 'SORTWORK'.
DATA DIVISION.
FILE SECTION.
FD IN-FILE.
01 IN-REC PIC X(80).
FD OUT-FILE.
01 OUT-REC PIC X(80).
SD SORT-FILE.
01 SORT-REC.
05 SORT-KEY PIC X(10).
05 SORT-DATA PIC X(70).
WORKING-STORAGE SECTION.
01 WS-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
SORT SORT-FILE
ON ASCENDING KEY SORT-KEY
USING IN-FILE
INPUT PROCEDURE IS INPUT-FILTER
GIVING OUT-FILE.
DISPLAY 'SORT COMPLETE'.
STOP RUN.
INPUT-FILTER SECTION.
INPUT-FILTER-PROC.
RETURN SORT-FILE INTO SORT-REC
AT END DISPLAY 'END OF INPUT'.
ADD 1 TO WS-COUNT.
DISPLAY 'SORTED REC: ' SORT-REC(1:30).
@@ -0,0 +1,32 @@
* ==== TYPE: ST02 MERGE ====
* FEATURE: MERGE 2 files into 1
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. ST02.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FILE-1 ASSIGN TO 'FILE1.DAT'.
SELECT FILE-2 ASSIGN TO 'FILE2.DAT'.
SELECT FILE-O ASSIGN TO 'FILEO.DAT'.
SELECT MERGE-FILE ASSIGN TO 'MERGWORK'.
DATA DIVISION.
FILE SECTION.
FD FILE-1.
01 REC-1 PIC X(80).
FD FILE-2.
01 REC-2 PIC X(80).
FD FILE-O.
01 REC-O PIC X(80).
SD MERGE-FILE.
01 MERGE-REC.
05 MERGE-KEY PIC X(10).
05 MERGE-DATA PIC X(70).
PROCEDURE DIVISION.
MAIN-PROCEDURE.
MERGE MERGE-FILE
ON ASCENDING KEY MERGE-KEY
USING FILE-1 FILE-2
GIVING FILE-O.
DISPLAY 'MERGE COMPLETE'.
STOP RUN.
@@ -0,0 +1,39 @@
* ==== TYPE: VL01 VALIDATION(WITH DUP) ====
* FEATURE: Duplicate detection with WS-PREV-KEY
* BRANCHES: 4, DECISIONS: 2
IDENTIFICATION DIVISION.
PROGRAM-ID. VL01.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO 'INDATA.DAT'.
DATA DIVISION.
FILE SECTION.
FD IN-FILE.
01 IN-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-KEY PIC X(10).
01 WS-PREV-KEY PIC X(10) VALUE SPACES.
01 WS-EOF PIC X VALUE 'N'.
01 WS-DUP-FLAG PIC X VALUE 'N'.
01 WS-REC-COUNT PIC 9(4) VALUE 0.
01 WS-DUP-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT IN-FILE.
READ IN-FILE AT END MOVE 'Y' TO WS-EOF.
PERFORM UNTIL WS-EOF = 'Y'
ADD 1 TO WS-REC-COUNT
IF WS-KEY = WS-PREV-KEY
ADD 1 TO WS-DUP-COUNT
MOVE 'Y' TO WS-DUP-FLAG
DISPLAY 'DUP: ' IN-REC(1:50)
ELSE
MOVE WS-KEY TO WS-PREV-KEY
DISPLAY 'NEW: ' IN-REC(1:50)
END-IF
READ IN-FILE AT END MOVE 'Y' TO WS-EOF
END-PERFORM.
DISPLAY 'TOTAL: ' WS-REC-COUNT ' DUPS: ' WS-DUP-COUNT.
CLOSE IN-FILE.
STOP RUN.
@@ -0,0 +1,28 @@
* ==== TYPE: VL02 VALIDATION(NO DUP) ====
* FEATURE: No duplicate detection
* BRANCHES: 2, DECISIONS: 1
IDENTIFICATION DIVISION.
PROGRAM-ID. VL02.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO 'INDATA.DAT'.
DATA DIVISION.
FILE SECTION.
FD IN-FILE.
01 IN-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-EOF PIC X VALUE 'N'.
01 WS-COUNT PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT IN-FILE.
READ IN-FILE AT END MOVE 'Y' TO WS-EOF.
PERFORM UNTIL WS-EOF = 'Y'
ADD 1 TO WS-COUNT
DISPLAY 'VALID: ' IN-REC(1:50)
READ IN-FILE AT END MOVE 'Y' TO WS-EOF
END-PERFORM.
DISPLAY 'VALID RECORDS: ' WS-COUNT.
CLOSE IN-FILE.
STOP RUN.