Semantic properties not updated when creating new elements

Hello everyone,

Consider the following model:

package Package {
    part def PartDef {
        attribute attr;
    }
    metadata def partMeta :> Metaobjects::SemanticMetadata {
        :>> baseType = PartDef meta SysML::PartDefinition;
    }

    #partMeta part myPart;
}

I can confirm that myPart.inherited_features indeed contains PartDef::attr. However, when I create a new element with the same annotation, the inherited_features list is not updated:

import syside

model, _ = syside.load_model(['model.sysml'])
with model.documents[-1].lock() as doc:
    root_node = doc.root_node
    package: syside.Package = root_node.children.elements[0]

    part_def = package.children.elements[0]
    assert isinstance(part_def, syside.PartDefinition)

    part_def_attr = part_def.children.elements[0]
    assert part_def_attr.name == 'attr'

    meta_def = package.children.elements[1]
    assert isinstance(meta_def, syside.MetadataDefinition)

    # Confirm that attr is an inherited feature of myPart
    part_usage = package.children.elements[2]
    assert isinstance(part_usage, syside.PartUsage)

    assert part_def_attr in part_usage.inherited_features

    # Create a new part with the same annotation
    new_part_usage: syside.PartUsage
    _, new_part_usage = package.children.append(syside.OwningMembership, syside.PartUsage)
    new_part_usage.declared_name = 'newPart'

    metadata_usage: syside.MetadataUsage
    _, metadata_usage = new_part_usage.prefixes.append(syside.OwningMembership, syside.MetadataUsage)
    metadata_usage.heritage.insert(0, syside.FeatureTyping, meta_def)

    printer_config = syside.PrinterConfig(line_width=80, tab_width=2)
    printer = syside.ModelPrinter.sysml()
    output = syside.pprint(root_node, printer, printer_config)
    print(output)

    # Check the inherited features --> this assertion fails
    assert part_def_attr in new_part_usage.inherited_features

I didn’t check if this is also the case for other semantic/derived properties, but the user would expected these to be kept updated in my opinion.

Greetings,
Jasper

Hi Jasper,

This is intended because semantic resolution is

  1. incredibly expensive compared to most other languages
  2. and depends on arbitrarily deep and wide hierarchies

So automatic semantic resolution would have to reset and resolve a potentially large chunk of the model either on each modification or lazily by depending on some mutable global state. This is terrible UX, as modifications would no longer be (amortized) constant time and have predictable memory usage, and could even take multiple if not hundreds of milliseconds to resolve compared to the current time of nanoseconds-to-microseconds without semantic resolution. In addition, our preference is to keep the model as a data structure (attributes are typically just graph traversals) and have systems operate on it as needed, i.e. composition over inheritance.

Instead there is an explicit semantic resolution using Sema.resolve and sema_reset.