Skip to content

A wall check, step by step

Picture tour: page 3 of 3

This example turns one written requirement into three clear checks. You can read the whole page without opening any code. Each source example is folded away until you choose to see it.

An object marked 331 is checked to be a wall, load bearing, and external

A learning example

This page is not legal or standards advice. It uses a checked learning fixture based on DIN 276 cost group 331. Use the licensed standard and your project's own classification rules for production work.

The goal

For every object marked with system DIN 276:2018-12 and code 331, ask three questions:

Question Expected answer
Is it a wall? Yes, including supported wall subtypes
Is it load bearing? Yes, in the named wall property set
Is it external? Yes, wherever the supported model stores that fact

The public IFC documentation confirms that Pset_WallCommon defines LoadBearing and IsExternal as yes or no properties for walls.

Step 1: Name the important things

Dictionary

First, give the ideas stable names. This example names a wall and the facts “Load bearing” and “Is external.” It also records the matching IFC names.

The shared names are used by the checks. If another model format uses different names, a tool can connect those names to the same ideas.

Show the Pkl source
objectTypes {
  ["axioval:example.ifc.wall"] = new Definitions.ObjectTypeDefinition {
    id = "axioval:example.ifc.wall"
    name = new Types.LocalizedText { default = "Wall" }
    externalNames {
      new Definitions.ExternalName {
        typeSystem = "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3"
        name = "IfcWall"
      }
    }
  }
}

properties {
  ["axioval:example.ifc.load-bearing"] = new Definitions.PropertyDefinition {
    id = "axioval:example.ifc.load-bearing"
    name = new Types.LocalizedText { default = "Load bearing" }
    valueKind = "boolean"
    externalNames {
      new Definitions.ExternalName {
        typeSystem = "https://identifier.buildingsmart.org/uri/buildingsmart/ifc/4.3"
        name = "LoadBearing"
      }
    }
  }
}

Step 2: Describe reusable kinds of checks

Recipe

The example needs two recipes:

  1. compare an object's type with an expected type;
  2. compare a yes or no fact with an expected answer.

A tool must already understand a recipe before it can use it. A shared bundle describes checks. It does not add new checking behavior to a tool.

Show the Pkl source
["axioval:example.boolean-property-equals"] = new Definitions.RuleDefinition {
  id = "axioval:example.boolean-property-equals"
  capability = "axioval:capability.property-value-equals"
  name = new Types.LocalizedText { default = "Boolean property equals" }
  parameters {
    ["property"] = new Definitions.ParameterDefinition {
      id = "property"
      kind = "propertyReference"
      referencedValueKind = "boolean"
    }
    ["expected"] = new Definitions.ParameterDefinition {
      id = "expected"
      kind = "boolean"
    }
  }
}

Step 3: Choose what to inspect

Scope

Select every object marked with code 331. Do not select walls only.

Why? If a slab was wrongly marked as 331, selecting walls would hide that slab before the wall check could report it.

Show the Pkl source
local kg331Objects = new Selectors.ClassificationSelector {
  system = "DIN 276:2018-12"
  code = "331"
  includeDescendants = false
}

Step 4: Fill in the wall check

Filled card

Now connect the “object type equals” recipe to the shared Wall name. Apply it to every object chosen in step 3.

Show the Pkl source
new RuleSets.RuleInstance {
  id = "kg331-is-wall"
  definitionId = "axioval:example.entity-type-equals"
  name = new Types.LocalizedText { default = "KG 331 objects are walls" }
  parameters {
    ["objectType"] = new Values.ObjectTypeReferenceValue {
      objectType = "axioval:example.ifc.wall"
      includeSubtypes = true
    }
  }
  applicability = kg331Objects
}

Step 5: Say when location matters

Two choices

The two property checks make different choices on purpose.

Load bearing: the named place matters

The project expects LoadBearing in Pset_WallCommon. The check names both the fact and that exact place. The same fact found somewhere else is not enough.

Show the Pkl source
["property"] = new Values.PropertyReferenceValue {
  property = "axioval:example.ifc.load-bearing"
  propertySet = "axioval:example.ifc.pset-wall-common"
}
["expected"] = new Values.BooleanValue { value = true }

External: any supported place is fine

This check cares about the answer, not the name of the place that holds it. A tool searches its supported locations. If it finds conflicting answers, it must report a conflict instead of choosing one silently.

Show the Pkl source
["property"] = new Values.PropertyReferenceValue {
  property = "axioval:example.ifc.is-external"
}
["expected"] = new Values.BooleanValue { value = true }

Step 6: Check the complete bundle

Ready to share

The final check reads the bundle label, opens only the listed files, resolves every shared name, confirms every value, and compares the result with checked examples.

Missing, unknown, conflicting, or wrongly typed parts stop the process.

Show the validation command
PATH="$HOME/.local/bin:$PATH" ./scripts/check.sh

The example is complete

One group of objects is selected. Three separate questions are asked. Each failure can explain exactly what was wrong.

Where to go next

Practical guide

When does location matter?

Explore the two ways to refer to a property.

Open the guide
Technical detail

How does a tool accept a bundle?

Read the ordered safety and checking contract.

Open the deep dive
Implementation responsibilities for tool builders

A checking tool resolves external names in the active model format, reads classifications and property relationships, distinguishes missing, conflicting, invalid, and resolved facts, implements each declared capability, and reports each failed rule with a stable message.

The complete checked source lives in examples/din-276-331.