InitialData Silently Leaves a Parameter Empty
Two parameters, the same InitialData, and only one of them has values at startup.
Example
Take two sets. s_Periods gets its elements from its own definition, while s_Products is filled by a
procedure called from MainInitialization:
1Set s_Periods {
2 Index : i_t;
3 Definition : data { t1, t2, t3 };
4}
5
6Set s_Products {
7 Index : i_p;
8}
9
10Procedure MainInitialization {
11 Body : {
12 s_Products := data { productA, productB, productC };
13 }
14}
Now declare one parameter over each set, both with the same InitialData:
1Parameter p_PeriodFactor {
2 IndexDomain : i_t;
3 InitialData : 1; ! 1 for t1, t2 and t3
4}
5
6Parameter p_ProductFactor {
7 IndexDomain : i_p;
8 InitialData : 1; ! empty at startup
9}
After the project opens, p_PeriodFactor holds the value 1 for every period, but p_ProductFactor has no
data at all, even though s_Products now contains three elements.
Nothing distinguishes the two declarations. What differs is when each index set gets its contents.
The Order of Initialization
Definitions and
InitialDataattributes are worked first, in declaration order, before any procedure runs.MainInitializationandPostMainInitializationrun afterwards.
So when p_ProductFactor is initialized in step 1, s_Products is still empty, because it is only filled
inside MainInitialization. There is nothing for the InitialData value to be assigned to. The parameter is
not initialized and then cleared; it is initialized over an empty domain, which produces no data at all.
s_Periods works because it has its elements before step 1. Here they come from its own definition, but a
literal or data read at load time would work the same way.
No error is reported, because nothing went wrong. The assignment covered every tuple in the domain, and there were none.
What To Do Instead
Assign it in a procedure, after the set is filled. If the set is populated in MainInitialization, the
assignment belongs after that point, and PostMainInitialization is the natural home:
1Procedure PostMainInitialization {
2 Body : {
3 p_ProductFactor(i_p) := 1;
4 }
5}
Or give the parameter a definition rather than initial data, if the value is genuinely constant. A definition is re-evaluated when its domain changes, so it follows the set instead of predating it:
1Parameter p_ProductFactor {
2 IndexDomain : i_p;
3 Definition : 1;
4}
The one thing not to do is move the declaration, hoping declaration order will fix it. Declaration order decides
the sequence within step 1; it cannot move an InitialData attribute after a procedure.