| name | ifc-syntax-express |
| description | Use when reading or reasoning about an IFC EXPRESS schema declaration : an ENTITY, TYPE, ENUMERATION, SELECT, a WHERE or UNIQUE rule, or an attribute, and when deciding what a serialized IFC instance must contain. Prevents serializing DERIVE or INVERSE attributes, miscounting positional attributes, instantiating an ABSTRACT supertype, treating SELECT as inheritance, and confusing the three EXPRESS equality operators. Covers the EXPRESS language (ISO 10303-11) used for IFC2x3, IFC4 and IFC4.3 : defined types, enumerations, selects, entities and inheritance, the explicit / DERIVE / INVERSE attribute kinds, WHERE / UNIQUE / global RULE constraints, the four aggregations, the SELF backslash path syntax, and the built-in functions. Keywords: EXPRESS, ISO 10303-11, IFC schema, ENTITY, SUBTYPE OF, SUPERTYPE OF, ABSTRACT SUPERTYPE, ONEOF, ANDOR, TYPE, ENUMERATION OF, SELECT, DERIVE, INVERSE, OPTIONAL, WHERE rule, UNIQUE rule, global RULE, LIST SET ARRAY BAG, SELF backslash supertype, EXISTS SIZEOF TYPEOF QUERY HIINDEX, instance equality, how to read an IFC schema, what does DERIVE mean, why is there an asterisk in my IFC file, attribute count mismatch, wrong number of attributes, dollar sign in IFC file.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires IFC IFC2x3, IFC4, IFC4.3. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
IFC Syntax : The EXPRESS Schema Language
Every IFC schema (IFC2x3, IFC4, IFC4.3) is written entirely in EXPRESS, the data
modeling language standardized as ISO 10303-11:2004. EXPRESS is declarative : it
describes what a valid population of data looks like, never behaviour or algorithms.
This skill teaches how to read an EXPRESS declaration and how it maps to a serialized
IFC instance. The EXPRESS schema is the single source of truth : the STEP physical
file, ifcXML, and ifcJSON are all derived encodings of the same EXPRESS model.
Quick Reference
The three attribute kinds : the most important table
| Kind | Stored? | Serialized in the STEP file? | What it is |
|---|
| Explicit | Yes | Yes : a positional value | An independently stored value, supplied in the file |
| DERIVE | No | No : slot holds * | A value computed by an expression (:=) |
| INVERSE | No | No : occupies no slot at all | A navigable back-reference, reconstructed by the reader |
ALWAYS count only explicit attributes (across the full inheritance chain) when
reading or writing a STEP instance. NEVER give a DERIVE or INVERSE attribute a value.
EXPRESS construct cheat-sheet
| Construct | Declares | Example |
|---|
TYPE name = base; END_TYPE; | A defined type (a named, optionally constrained base type) | TYPE IfcLengthMeasure = REAL; END_TYPE; |
TYPE name = ENUMERATION OF (...); END_TYPE; | A fixed list of named values | IfcWallTypeEnum |
TYPE name = SELECT (...); END_TYPE; | A type union (one-of alternatives) | IfcUnit |
ENTITY name ... END_ENTITY; | An entity type with attributes and inheritance | IfcWall |
RULE name FOR (...); ... END_RULE; | A schema-level population constraint | global rules |
FUNCTION name(...) : T; ... END_FUNCTION; | A computation used by DERIVE / WHERE | IfcBaseAxis |
STEP physical file markers (the EXPRESS-to-file mapping)
| Marker in the file | EXPRESS meaning |
|---|
#42=IFCWALL(...) | An instance ; keyword upper-case, #id file-local |
$ | An unset OPTIONAL explicit attribute |
* | A DERIVE (or re-declared) attribute slot ; computed, not stored |
| (absent) | An INVERSE attribute : no slot exists in the parentheses |
.STANDARD. .T. .F. .U. | An enumeration, BOOLEAN, or LOGICAL value (dotted) |
IFCLENGTHMEASURE(2.5) | A SELECT-of-defined-type value (wrapped in the type name) |
#84 | A SELECT-of-entity value (a bare reference, no wrapper) |
(0.,0.,0.) | Any aggregate (LIST / SET / ARRAY / BAG : the wire syntax is the same) |
The four aggregations
| Aggregation | Ordered | Duplicates | Bounds | Notes |
|---|
LIST [lo:hi] OF T | Yes | Allowed (unless OF UNIQUE) | Optional, default [0:?] | Indexable |
SET [lo:hi] OF T | No | Never | Optional | Set semantics |
ARRAY [lo:hi] OF T | Yes | Allowed (unless UNIQUE) | Mandatory | Only one that allows OPTIONAL holes |
BAG [lo:hi] OF T | No | Allowed | Optional | Unordered multiset |
? as the high bound means unbounded. LIST OF UNIQUE differs from SET only in that
it is ordered.
The three equality tokens (NEVER confuse these)
= : value equality (deep, structural comparison).
:=: : instance equality (identity : same #id).
:= : assignment ; used ONLY to give a DERIVE attribute its expression. It is not
a comparison operator.
Decision Trees
Which attribute kind is this, and does it go in the file?
Where is the attribute declared in the ENTITY body?
|
+-- In the main attribute block (before DERIVE/INVERSE/WHERE)
| --> EXPLICIT attribute. Serialized as a positional value.
| If marked OPTIONAL and unset --> written as $
|
+-- Under the DERIVE keyword (has := and an expression)
| --> DERIVE attribute. NEVER serialized as a value ; slot is *
|
+-- Under the INVERSE keyword (has a FOR clause)
--> INVERSE attribute. NEVER serialized ; no slot exists at all.
Which TYPE construct is this?
TYPE name = ... END_TYPE; what follows the "=" ?
|
+-- A base type / another defined type (REAL, INTEGER, IfcLengthMeasure, ...)
| --> Defined type. A named alias, optionally narrowed by a WHERE rule.
|
+-- ENUMERATION OF (V1, V2, ..., USERDEFINED, NOTDEFINED)
| --> Enumeration. A fixed list of dotted values.
|
+-- SELECT (A, B, C)
--> Select (type union). An attribute typed by it holds ONE of A, B, C.
This is NOT inheritance : the alternatives need not share a supertype.
ONEOF vs ANDOR (subtype constraint)
SUPERTYPE OF (...) contains which operator?
|
+-- ONEOF (A, B, C) --> a concrete instance is EXACTLY ONE of A, B, or C.
| Mutually exclusive. The overwhelmingly common IFC case.
|
+-- A ANDOR B --> an instance may be A alone, B alone, OR A and B together.
Multiple inheritance. IFC uses ANDOR rarely.
Can I instantiate this entity?
Does the ENTITY declaration say ABSTRACT SUPERTYPE?
|
+-- YES --> NEVER instantiate it. IfcRoot, IfcProduct, IfcElement,
| IfcObjectDefinition exist only as supertypes. No #id=IFCELEMENT(...).
|
+-- NO --> It is concrete and instantiable (IfcWall, IfcDoor, IfcCartesianPoint).
A concrete entity may still be a SUPERTYPE OF other entities.
Patterns
Pattern : Read an ENTITY declaration top to bottom
An ENTITY ... END_ENTITY; block has a fixed order of sections :
ENTITY IfcRoot
ABSTRACT SUPERTYPE OF (ONEOF
(IfcObjectDefinition, IfcPropertyDefinition, IfcRelationship));
GlobalId : IfcGloballyUniqueId;
OwnerHistory : OPTIONAL IfcOwnerHistory;
Name : OPTIONAL IfcLabel;
Description : OPTIONAL IfcText;
UNIQUE
UR1 : GlobalId;
END_ENTITY;
ALWAYS read in this order :
ABSTRACT (if present) : the entity cannot be instantiated.
SUPERTYPE OF (...) : its direct subtypes, with ONEOF or ANDOR.
SUBTYPE OF (...) : its direct supertype(s). Absent on a root entity.
- The explicit attribute block : independently stored values, in declared order.
DERIVE (if present) : computed attributes.
INVERSE (if present) : back-references.
WHERE (if present) : per-instance rules.
UNIQUE (if present) : per-population uniqueness rules.
A subtype inherits every attribute of every supertype. A serialized IfcWall (chain
IfcRoot to IfcObjectDefinition to IfcObject to IfcProduct to IfcElement to
IfcBuiltElement to IfcWall) carries every explicit attribute of all seven levels, in
supertype-first order.
IfcBuiltElement is the IFC4.3 name. In IFC2x3 and IFC4 the equivalent supertype is
IfcBuildingElement ; IFC4.3 renamed IfcBuildingElement to IfcBuiltElement. See
ifc-core-entity-hierarchy.
Pattern : Treat the three attribute kinds correctly
ALWAYS check which keyword block an attribute sits under before reasoning about a file.
- Explicit attributes are the only ones that appear as positional values. The number
of values inside the parentheses MUST equal the count of explicit attributes across
the full inheritance chain.
- DERIVE attributes (introduced with
:= and an expression, for example
IfcDirection.Dim := HIINDEX(DirectionRatios);) are recomputed by every reader. Their
positional slot holds *, never a value.
- INVERSE attributes (which always have a
FOR clause, for example
IfcProduct.ReferencedBy : SET [0:?] OF IfcRelAssignsToProduct FOR RelatingProduct)
occupy no slot at all. The reader rebuilds them by indexing forward #id
references. This is the foundation of the IFC objectified-relationship pattern.
Pattern : Read the INVERSE FOR clause
ReferencedBy : SET [0:?] OF IfcRelAssignsToProduct FOR RelatingProduct reads :
"the set of every IfcRelAssignsToProduct instance whose RelatingProduct explicit
attribute points at this instance." The FOR names the explicit attribute on the other
entity that this INVERSE mirrors. The cardinality (SET [0:?], SET [0:1], ...)
constrains how many back-links may exist. See ifc-core-relationships.
Pattern : Apply the WHERE / UNIQUE / RULE scope correctly
The three constraint mechanisms differ in scope :
- A WHERE rule constrains one instance. A named boolean expression that MUST
evaluate TRUE for every instance. On a defined type,
SELF is the value
(IfcPositiveLengthMeasure.WR1 : SELF > 0.;) ; on an entity, SELF is the instance.
- A UNIQUE rule constrains across the whole population of one entity type.
IfcRoot.UR1 : GlobalId; forbids two IfcRoot instances from sharing a GlobalId. A
UNIQUE rule may list several attributes for a compound key.
- A global RULE constrains populations across entity types. It is declared at
schema level, not on any entity, and can range over an entire population. An entity
WHERE rule cannot see other instances ; a global RULE can.
NEVER read a WHERE rule, RULE, or function as application behaviour. They are
constraints and computations, never algorithms with side effects.
Pattern : Read the SELF backslash supertype path
Inside a WHERE rule or DERIVE expression, SELF\Supertype.Attribute names an attribute
inherited from a supertype. The backslash \ is the supertype-cast operator : it
narrows the view of SELF to a named supertype.
DimIs3D : SELF\IfcCartesianTransformationOperator.Dim = 3; reads "this instance,
viewed as its supertype IfcCartesianTransformationOperator, its Dim attribute." The
qualifier is required because EXPRESS allows an attribute name to be re-declared in a
subtype. ALWAYS expect SELF\... whenever a rule reaches up the inheritance chain.
Pattern : Read the built-in functions in WHERE rules
The functions that actually appear in IFC WHERE rules :
EXISTS(v) : TRUE if v is set. The standard guard for OPTIONAL attributes.
SIZEOF(agg) : element count of an aggregate.
TYPEOF(v) : the set of type-name strings of v ; used with IN, for example
'IFC4X3.IFCWALL' IN TYPEOF(x). The type-name string is schema-qualified, upper-case.
HIINDEX(agg) / LOINDEX(agg) : the actual high / low index of a populated aggregate.
Distinct from HIBOUND / LOBOUND, which return the declared bounds.
QUERY(x <* agg | condition) : iterate-and-filter. <* binds x to each element ;
returns the elements where the filter is TRUE. Almost always wrapped in SIZEOF(...).
NVL(v, default) : returns v if set, otherwise default.
USEDIN(v, 'Schema.Entity.Attribute') : the instances referencing v through that
role. The functional counterpart of an INVERSE attribute.
See references/methods.md for the full ISO 10303-11 function library.
Pattern : Honour the USERDEFINED / NOTDEFINED enumeration convention
Every IFC predefined-type enumeration ends with USERDEFINED and NOTDEFINED. When an
instance's PredefinedType is .USERDEFINED., the paired free-text attribute (usually
ObjectType, inherited from IfcObject) MUST carry the actual type name. This pairing
is enforced by a WHERE rule on the entity. ALWAYS set the paired attribute when
using USERDEFINED. See ifc-syntax-data-types.
Reference Links
references/methods.md : the full EXPRESS construct reference : TYPE / ENUMERATION /
SELECT / ENTITY grammar, the three attribute kinds, WHERE / UNIQUE / RULE, the four
aggregations with BNF, the built-in function library, operators, and the complete
EXPRESS-to-STEP mapping rules.
references/examples.md : verbatim, source-verified EXPRESS snippets from IFC4.3 and
IFC4 entity pages, each explained, plus the matching STEP serialization.
references/anti-patterns.md : the twelve common EXPRESS misreadings, each with the
reason it corrupts a file or a reading.
Official sources
Related skills
ifc-syntax-data-types : the IFC resource-layer value-type system built on EXPRESS
defined types, selects, and enumerations.
ifc-core-data-model : the four-layer schema architecture written in EXPRESS.
ifc-syntax-step-physical-file : the STEP physical file (ISO 10303-21) encoding.
ifc-core-entity-hierarchy : the IFC inheritance lattice and the
IfcBuildingElement to IfcBuiltElement rename.
ifc-core-relationships : the objectified-relationship pattern built on INVERSE.