Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/acdeveloper-sci/forti4d/llms.txt

Use this file to discover all available pages before exploring further.

The E4 ScopeManager is the symbol-level analysis layer of Forti4D, corresponding to Axis Z of the MI4D model. While the earlier pipeline tiers answer “what units exist and how they relate,” E4 answers “what is declared inside each unit.” The three scripts in this tier — symbols.py, derived_types.py, and equivalences.py — all read the audit/*_DEBUG.csv files produced by profiler.py and the inventory for scope resolution. Their outputs feed back into cross_analysis.py (E4 ICM penalty) and consolidate.py (E4 summary columns), and they are the basis for the Scope Health section of PROJECT_SUMMARY.md.
All three E4 scripts require profiler.py (audit CSVs) and inventory.py to have run first. They are steps 10, 11, and 12 of the pipeline.

symbols.py — Variable Declarations and IMPLICIT Rules

symbols.py is step 10 of the pipeline.

Inputs

  • <FORT_OUT>/audit/<filename>_DEBUG.csv for each source file — reads lines classified as VAR_DECLARATION, PARAMETER_STMT, IMPLICIT_STMT, COMMON_STMT, SUBROUTINE_UNIT, or FUNCTION_UNIT
  • <FORT_OUT>/inventory_report.csv

Output Files

symbol_variables.csv — one row per declared variable or PARAMETER constant.
ColumnDescription
FileSource file name
UnitContaining unit name
Unit_TypeUnit type (SUBROUTINE, FUNCTION, PROGRAM, etc.)
LineLine number of the declaration
Var_NameVariable name (uppercase)
Fortran_TypeBase type: INTEGER, REAL, CHARACTER, TYPE, etc.
Kind_ParamKIND or byte-size modifier, e.g. 8, *4, *8
DimensionArray dimension spec, e.g. 100 or N,M or 0:10; empty if scalar
AttributesPipe-separated attribute list, e.g. INTENT(IN)|DIMENSION(10)
IntentIN, OUT, or INOUT if declared; empty otherwise
Initial_ValueCompile-time value for PARAMETER constants; empty for regular vars
Is_ParameterYES if the variable is a PARAMETER constant, NO otherwise
In_CommonCOMMON block name if the variable appears in a COMMON statement; empty otherwise
TruncatedYES if the source line was near the 120-character audit truncation limit
symbol_signatures.csv — one row per formal argument of each SUBROUTINE or FUNCTION. Units with no arguments produce no rows.
ColumnDescription
FileSource file name
UnitSubroutine or function name
Unit_TypeSUBROUTINE or FUNCTION
Signature_LineLine number of the unit header
PositionArgument position (1-based)
Arg_NameFormal argument name (uppercase)
Return_TypeDeclared return type for FUNCTION units (e.g. REAL, REAL*8); empty for SUBROUTINE
symbol_implicit.csv — one row per IMPLICIT statement found in each unit. This is the key input for measuring IMPLICIT NONE coverage across the corpus.
ColumnDescription
FileSource file name
UnitUnit name
Unit_TypeUnit type
LineLine number of the IMPLICIT statement
RuleNONE for IMPLICIT NONE; otherwise the rule as written in source
Is_NoneYES if the statement is IMPLICIT NONE, NO otherwise

COMMON Cross-Reference

Variables that appear in a COMMON statement within the same unit have their In_Common field populated post-processing — after all lines of all files have been scanned. The blank (unnamed) COMMON is represented as (BLANK), consistent with common_blocks.py.

derived_types.py — Derived TYPE Definitions

derived_types.py is step 11 of the pipeline.

Inputs

  • <FORT_OUT>/audit/<filename>_DEBUG.csv for each source file — reads lines classified as TYPE_DEFINITION, VAR_DECLARATION, or END_BLOCK_STMT
  • <FORT_OUT>/inventory_report.csv

Output Files

type_definitions.csv — one row per derived TYPE definition found.
ColumnDescription
FileSource file name
UnitName of the host unit (MODULE, SUBROUTINE, etc.) containing the TYPE
Unit_TypeHost unit type (e.g. MODULE)
Start_LineLine number of the TYPE name statement
End_LineLine number of the matching END TYPE statement
Type_NameTYPE name (uppercase)
N_ComponentsNumber of component fields declared inside the TYPE
type_components.csv — one row per component field of each derived TYPE.
ColumnDescription
FileSource file name
Type_NameParent TYPE name (uppercase)
LineLine number of the component declaration
PositionComponent position within the TYPE (1-based)
Comp_NameComponent field name (uppercase)
Fortran_TypeBase type: INTEGER, REAL, LOGICAL, CHARACTER, etc.
Kind_ParamKIND or byte-size modifier, e.g. *4, *8
DimensionArray dimension spec if the component is an array; empty if scalar
AttributesPipe-separated attribute list (e.g. ALLOCATABLE, POINTER)

State Machine

derived_types.py uses a per-file state machine to extract TYPE bodies:
1

Enter TYPE body

A TYPE_DEFINITION line is detected. The type name and host unit are recorded via scope resolution.
2

Parse components

While inside the TYPE body, every VAR_DECLARATION line is parsed as a component field using the same F77/F90 hybrid rules as symbols.py.
3

Close and emit

An END_BLOCK_STMT matching END TYPE closes the TYPE body. All collected component rows are emitted.

equivalences.py — EQUIVALENCE Aliasing Groups

equivalences.py is step 12 of the pipeline.
EQUIVALENCE statements cause two or more variables to share the same memory location — a legacy F77 construct that complicates static analysis, type inference, and safe refactoring. equivalences.py resolves transitive aliasing across multiple EQUIVALENCE statements using a union-find algorithm.

Inputs

  • <FORT_OUT>/audit/<filename>_DEBUG.csv for each source file — reads lines classified as EQUIVALENCE_STMT
  • <FORT_OUT>/inventory_report.csv

Output: equivalences.csv

One row per variable per aliasing group.
ColumnDescription
FileSource file name
UnitContaining unit name
Unit_TypeUnit type
Group_IDSequential group identifier within the unit (1-based)
PositionPosition of this variable within the group (1-based, sorted alphabetically)
Var_NameVariable name (uppercase); array subscripts are stripped
N_MembersTotal number of variables in this aliasing group
Stmt_LinesSemicolon-separated line numbers of the EQUIVALENCE statements that define this group

Union-Find Algorithm

EQUIVALENCE aliasing is transitive: if A aliases B and B aliases C (across separate statements), then A, B, and C form a single group. The algorithm handles this correctly:
EQUIVALENCE (A, B)   ! Group: {A, B}
EQUIVALENCE (B, C)   ! Merges into: {A, B, C}
1

Parse statements

Each EQUIVALENCE_STMT line within a unit is parsed to extract its parenthesized variable lists.
2

Union variables

All variables within each list are unioned into the same component.
3

Extract components

After processing all statements in the unit, connected components are extracted.
4

Assign Group_IDs

Sequential Group_ID values are assigned (sorted by first member name).
Array subscripts in EQUIVALENCE references (e.g. A(1)) are stripped — only the variable name is recorded. Offset-based partial aliasing is not analyzed. Units with no EQUIVALENCE statements produce no rows.

E4 Data Flow

E4 outputs feed back into two downstream scripts:
  • cross_analysis.py — when symbol_implicit.csv and/or equivalences.csv are present, adds up to 7 ICM penalty points for units without IMPLICIT NONE and/or with EQUIVALENCE aliasing groups.
  • consolidate.py — aggregates E4 data into summary columns (N_Local_Vars, N_Params, N_Formal_Args, Implicit_None, N_Derived_Types, Has_Equiv, N_Equiv_Groups) in report_consolidated.csv.
  • executive_summary.py — generates the optional Scope Health section of PROJECT_SUMMARY.md when at least one E4 source is present.

Build docs developers (and LLMs) love