Hi Allan,
There is currently no setting for doing this in NORMA.
There are certainly some things that could be applied in this area, but the fundamental problem is that it is not always clear how a 'default value' on all types of conceptual fact types actually means. When you're talking about a default value in a relation--such as a column in a relational table--then you already have already dealt with the question of existence: the row must exists for the default to be applied. Translating back to the conceptual world, this means that another fact (such as the identifying fact type that populates the primary key) must be true before the default value can be applied.
A default value would definitely not apply to a ValueType, but it could apply to a fact type with a value role, meaning a role that is not under a uniqueness constraint. This is reasonably well defined for binary fact types with a value role connected to a value type, but becomes much trickier as soon as you hit a multi-role non-spanning uniqueness constraint.
[I'm not proposing a solution here, just trying to introduce some of the potential issues.]
The conceptual binary case translates most directly to the relational default value. However, it isn't all theoretical smooth sailing. The first question arises with the mandatory/optional setting on the functional role (the role under the uniqueness). Conceptually, automatically populating the fact type if the functional object exists means that this role is always mandatory. However, I think this would be counterintuitive to most modelers, who would expect default values to apply only to optional fact types. There is a similar issue with the implied mandatory on the non-unique role. For example, if the PersonName value type is used only in the Person has PersonName fact type, then there is an implied mandatory constraint on PersonName that means no PersonName instance exists that is not associated with a Person instance. However, if the default value is '<Unknown>', we have to ask if this is a theoretical violation of the implied mandatory constraint. After all, we now have a PersonName instance that was not asserted.
Basically, what you now have is a semi-derived fact type with the derived portion dependent upon the asserted portion. As with other derivations, the choice of storage needs to be made when this is mapped to a relational model. For a binary, the theoretically cleanest way to do this is with two columns, one asserted and the other calculated. The calculation would provide the default value, and the user would read the derived column and write to the asserted column. Unfortunately, this is somewhat impractical from the relational perspective, although it does allow a more flexible model than the 'default value' approach because the default is stored once (in the derivation rule) instead of being injected into each row of the table.
The bigger issue with default values comes with the n-ary case. Consider Person(.id) speaks Language(.code) with Proficiency() with a uniqueness on the first two roles and a default value on the Proficiency role. Unlike the binary case, where you clearly apply the default only when the functional role player is populated, the population in this case is actually a cross product of all Person and Language instances that are not formally paired in this fact type. This makes sense for a query or as part of a derivation rule, but is definitely not something you would want to populate. Also note that in this case there is an implied objectification with a co-referenced binarized form behind the scenes (but visible if needed) in NORMA. In the binarized form, the Proficiency role here is mandatory, so is probably not a good default value candidate anyway.
Given these theoretical concerns, if we add this, I would suggest the following:
-
Limit it to non-spanning binary cases only.
-
Allow value types or simply-identified entity types only on the value role.
Even in these cases I have reservations about the conceptual nature of this feature, but I agree that it can be very useful and that some architects much prefer a default value to a null, so I think we should consider it. At the very least we should allow adding it at the relational column level (where the existence question is not an issue and all identifiers are resolved).
-Matt