Replaced By Proposal
In another breakout session at COMBINE 2011, we discussed the ‘identical’ flag on ReplacedElements. From the current specification:
[We] want to acknowledge that in a given model, the ‘canonical’ form of a particular element may lie in a submodel and not in the containing model, and that the only reason a parent model may contain a replacement element is to be able to refer to it. This is the purpose of the optional ‘identical’ attribute of the ReplacedElement class. Setting this Boolean value to ‘true’ indicates that the two linked elements are intended to be the same in every respect, so if the two differ in any attribute or subobject, a validation error is produced. This means that even if the subelement sets the optional ‘name’ property to one value and the replacing element sets it to a different value, the resulting SBML would not be considered valid. Semantic equivalence is required here, not literal equivalence. Numerical values of any attributes such as ‘initialValue’ must be equivalent to each other as dictated by any relevant conversion factors (see ‘Conversion Factors’, section 3.5). Similarly, SIds (such as the ‘compartment’ attribute of a Species) should point to the same element, but should that element have been replaced in the containing model, the literal SId will be different. Finally, the ‘id’ and ‘metaid’ attributes, which each exist in different namespaces (and may be required to be different, in the metaid case), may change without breaking identity. If the ‘identical’ attribute is not set, the validator will warn if an attribute of the replaced element was defined that is not defined at all on the replacement element. If the ‘identical’ attribute is set ‘false’, no validation errors or warnings will be produced from any comparison of the two elements.
What we discussed at COMBINE was whether there could be a way to take this a step further: instead of stating modeler intent, as it currently does, what if there was a way to make it rule-based: to make it actually declare ‘use the submodel bit here and not the containing model element’? Initially I considered a rule stating that you must copy attributes and children objects from the object in the submodel to the object in the containing model. But this started to get complicated: what do you do about attributes that are SIdRefs? UnitSIdRefs? Children objects containing those? What do you do with Ids of child objects?
Finally, I realized that by default, we already had a way to have elements of submodels remain in the containing model: simply do not replace them. So all we need is a way to obtain a ‘local handle’ for those submodel objects we do not wish to change, but instead merely add to.
The rules here could be exactly the same as they are now for replacing elements in submodels, but applied to the containing model. The existing rules for replacing elements in submodels are:
- Delete the referenced element in the submodel.
- Take any references to it, and point them instead to the replacement element in the containing model.
The rules for this new reverse concept replacement would be similar:
- Delete the element in the containing model.
- Take any references to it, and point them instead to the replacement element in the submodel.
Note that ‘any references’ could now include elements in other submodels! If we agree that this concept would be useful to have, the next step is to decide how to encode the rule in XML. The most straightforward is to simply replace the ‘identical’ attribute with a different attribute like ‘isReference’. The only problem with this is that the name ‘Replaced Element’ is now something of a misnomer: it is no longer a replaced element, but a replacement element.
So, an alternative proposal is to create an entirely new construct for ‘pointing the other way’, and call it something like ‘ReplacedBy’. We would change the extended SBase class to be:
This has the advantage of clearly being something different, so a casual reading of the specification or of a model would make it clear that something had fundamentally changed. By not appearing in a list, it is clear that there can only be one of it per SBase object.
What do you think? Is this a useful concept to add to comp, and if so, is this the way to do it?