This document compares two versions of the AP242 schema to demonstrate the difference between STEPcode's non-standard flow-sensitive narrowing extension and the ISO 10303-11 compliant TREAT expression.
- Status: Uses implicit flow-sensitive narrowing (non-standard extension)
- Location:
data/ap242/242_mim_lf.exp - Size: 54,756 lines
- Problematic code: Line 34149 in
styled_itementity, WR3 WHERE rule
- Status: Standards-compliant using TREAT expression
- Location:
data/ap242/242_mim_lf_treat.exp - Size: 54,756 lines
- Fix applied: Line 34149 - explicit TREAT expression
In the styled_item entity at line ~34148, the WHERE rule WR3 contains:
WR3: ('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(item)) OR
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN TYPEOF(item)) OR
(('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
(SIZEOF(QUERY(it <* item | ...)) = 0));
itemis of typestyled_item_target, which is a SELECT type- The SELECT contains
set_representation_item(which is an aggregate type) - The code checks
'SET_REPRESENTATION_ITEM' IN TYPEOF(item)(a TYPEOF guard) - Then tries to iterate over
itemin a QUERY:QUERY(it <* item | ...)
According to strict ISO 10303-11 standards, you cannot iterate over a SELECT type directly in a QUERY expression, even if there's a preceding TYPEOF guard. The guard and the QUERY are separate expressions in an AND clause.
STEPcode implements a flow-sensitive type narrowing extension that:
- Recognizes the pattern
'TypeName' IN TYPEOF(var)in AND expressions - Automatically narrows the type of
vartoTypeNamefor subsequent expressions in the AND - Allows
QUERY(it <* item | ...)to work becauseitemis implicitly narrowed toset_representation_item
Code (original, line 34149):
QUERY(it <* item | ...)
How it works:
- The AND expression LHS has the guard:
'SET_REPRESENTATION_ITEM' IN TYPEOF(item) - The RHS has the QUERY:
SIZEOF(QUERY(it <* item | ...)) = 0 - STEPcode's narrowing recognizes the pattern and narrows
itemtoset_representation_item - The QUERY can now iterate over the narrowed type
The ISO 10303-11 standard provides the TREAT expression for explicit type narrowing:
Code (TREAT version, line 34149):
QUERY(it <* TREAT(item AS set_representation_item) | ...)
How it works:
TREAT(item AS set_representation_item)explicitly narrows the SELECT type to the member type- The QUERY can iterate over the result of TREAT, which is guaranteed to be
set_representation_item - No implicit narrowing needed - the intent is explicit in the code
--- data/ap242/242_mim_lf.exp
+++ data/ap242/242_mim_lf_treat.exp
@@ -34146,7 +34146,7 @@
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN TYPEOF(item)) OR
(('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.SET_REPRESENTATION_ITEM' IN TYPEOF(item)) AND
(SIZEOF(QUERY(it
- <* item
+ <* TREAT(item AS set_representation_item)
| NOT (('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.MAPPED_ITEM' IN TYPEOF(it)) OR
('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.GEOMETRIC_REPRESENTATION_ITEM' IN
TYPEOF(it))))) =Change: Single line change from <* item to <* TREAT(item AS set_representation_item)
./build/bin/exp2cxx data/ap242/242_mim_lf.exp /tmp/ap242_original_testResult: ✅ Parses successfully, generates 5,626 C++ files
./build/bin/exp2cxx data/ap242/242_mim_lf_treat.exp /tmp/ap242_treat_testResult: ✅ Parses successfully, generates 5,626 C++ files
Both versions generate identical output:
- Same number of entities
- Same entity relationships
- Same multiple inheritance warnings
- Identical "Finished writing files" status
To verify both versions produce consistent output:
# Parse original version
mkdir -p /tmp/ap242_original
./build/bin/exp2cxx data/ap242/242_mim_lf.exp /tmp/ap242_original
# Parse TREAT version
mkdir -p /tmp/ap242_treat
./build/bin/exp2cxx data/ap242/242_mim_lf_treat.exp /tmp/ap242_treat
# Compare generated headers (should be identical except for file references)
diff /tmp/ap242_original/SdaiAP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.h \
/tmp/ap242_treat/SdaiAP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF.h- Current: Both versions work due to flow-sensitive narrowing extension
- Future: TREAT version is more portable if other EXPRESS parsers are used
- Recommended: Use TREAT for new schemas to ensure standards compliance
- Flow-sensitive narrowing is a valuable usability extension
- TREAT expression provides standards-compliant alternative
- Both should continue to be supported for compatibility
- Original AP242 schema uses pattern that requires extension
- TREAT version is fully ISO 10303-11 compliant
- TREAT makes intent explicit and improves code clarity
doc/express-type-unwrapping.md- Full documentation of TREAT and narrowing featuressrc/express/test/README_AP242_BASELINE.md- Historical PE056 error documentation- Test schemas:
test/unitary_schemas/flow_narrowing_test.exp- Flow-sensitive narrowing examplestest/unitary_schemas/minimal_treat_test.exp- TREAT expression examples
This comparison demonstrates:
- ✅ STEPcode's flow-sensitive narrowing successfully handles the original AP242 schema
- ✅ TREAT expression provides the standards-compliant alternative
- ✅ Both approaches produce identical, correct output
- ✅ The single-line change makes the code more explicit and portable
The availability of both approaches gives users flexibility while maintaining standards compliance when needed.