Remove Elements from a Set
The empty statement in AIMMS is used to clear the contents of a set or reset values of identifiers within a subset of predefined sets.
Its behavior depends on the type of set being emptied:
The set is not a subset of
AllIdentifiers: the empty statement will remove all elements from the given set.The set is a subset of
AllIdentifiers: the empty statement will empty all the identifiers that are in the given subset.
Clearing a Regular Set vs. a Subset of AllVariables
Let’s assume the following two identifiers:
Set NormalSet;
Set ActiveVariables {
SubsetOf: AllVariables;
}
As you can see, it holds that ActiveVariables \(\subseteq\) AllVariables \(\subseteq\) AllIdentifiers because the predefined
set AllVariables is defined in AIMMS to be a subset of AllVariablesConstraints, which in turn is a subset of AllIdentifiers.
You can verify this by opening the attribute window of these predefined sets.
This means that the empty statement behaves differently for NormalSet and ActiveVariables, as explained below:
1!This will remove all elements from the set NormalSet
2empty NormalSet ;
3
4!This will clear the values of all variables in the subset ActiveVariables
5!After the empty statement, the set itself will still contain elements!
6empty ActiveVariables ;
7
8!This will actually remove all elements from the set ActiveVariables
9ActiveVariables := {} ;
empty vs. := {} on a Regular Set
For a set that is not a subset of AllIdentifiers, both empty s_A and s_A := {} leave
the set without elements, but they do not treat the data defined over it the same way.
Assume the following declarations, where p_B has data:
Set s_A {
Index : i_a;
}
Parameter p_B {
IndexDomain : i_a;
}
After empty, the data of p_B is gone:
1empty s_A ; ! s_A has no elements, and all data of p_B is removed
After assigning the empty set, p_B only looks empty:
1s_A := {} ; ! s_A has no elements, and the data of p_B becomes inactive
The values of p_B are still stored, but they are inactive: no element of s_A refers to them, so
they do not show up in displays, pages or expressions. Restoring s_A to its previous contents makes
the data of p_B visible again.
Choose the form that matches your intent:
Use
empty s_Awhen you want the set and everything defined over it cleared, for instance before reading a new data instance.Use
s_A := {}when you want to hide the data temporarily and bring it back by restoring the elements later. Keep in mind that inactive data still occupies memory until it is removed.
If you decide later that the inactive data is no longer needed, remove it explicitly. Cleanup p_B ;
drops the inactive values from p_B alone, and CleanDependents s_A ; does the same across every
identifier defined over s_A. After either statement, restoring the elements of s_A no longer brings
the old values back. See Reclaim Memory Between Data Instances for how these
statements compare and what they do to memory.
A Defined Set Cannot Be Emptied At All
There is a third case. If a set was declared with a Definition attribute, its contents are computed from
that definition rather than stored as data the model owns, and neither form above applies:
1empty MySet ;
fails with
The defined domain set "MySet" cannot be emptied
This is not a defect. A defined set is recomputed automatically whenever the identifiers its definition depends on change, so there is no independently stored content for a procedural statement to clear.
If what you need is a set that can be reset and repopulated between runs - to keep elements from a previous
execution out of the next one, for instance - declare it without a Definition attribute and populate
it explicitly, with SetElementAdd or an assignment. A set’s contents can only be assigned or reset
procedurally when it is not a defined set.
Empty Every Set Except a Named Few
Clearing every set you declared, except one or two, is a subset construction rather than a list. The
second case above is what makes it work: empty applied to a subset of AllIdentifiers
empties the identifiers that the subset contains.
First capture the scope:
Set s_declaredSets {
SubsetOf : AllIdentifiers;
Index : i_sds;
}
Then:
1s_declaredSets := MySection * AllSets;
AllSets is the predeclared subset of AllIdentifiers holding every declared set
in the project. The name of a Section node is also available as an implicit subset of
AllIdentifiers, containing every identifier declared beneath that node, so intersecting the
two restricts the result to the sets declared in that section.
Use a section rather than the whole model. That is what keeps the statement from reaching sets that belong to a library you did not write.
Then filter out the exceptions:
Set s_setsToEmpty {
SubsetOf : s_declaredSets;
}
Then:
1s_setsToEmpty := s_declaredSets - { 's_keepThisOne' };
The elements of AllIdentifiers are the identifier names themselves, so a set difference
against an element literal is enough. Add further exceptions inside the braces. The literal has to name
an identifier that exists, otherwise AIMMS rejects it at compile time.
And clear them in one statement:
1empty s_setsToEmpty ;
Naming the exceptions, rather than the sets to clear, is almost always the intent: a set added next month is then cleared automatically. Listing the sets to clear does the opposite, and the omission surfaces later as data surviving a reset that should have removed it.
Key Takeaways
The
emptystatement removes elements from general sets but only clears values for subsets of predefined sets.To fully remove elements from a subset of
AllIdentifiers, assign an empty set{}to it explicitly.On a regular set,
empty s_Aalso removes the data of identifiers defined overs_A, whiles_A := {}only makes that data inactive; restoring the elements makes it visible again.A set with a
Definitionattribute cannot be emptied by any means; drop the definition if the set has to be procedurally editable.To clear many sets at once, intersect a
Sectionname withAllSetsand subtract the exceptions, then pass the result toempty. Naming the exceptions keeps new sets covered automatically.Use
emptycarefully when dealing with predefined sets to avoid unintended behavior.