Prepare for the Deprecation of Compound Sets
Summary
AIMMS deprecated compound sets in January 1, 2020. The functionality of compound sets can be achieved with a set mapping.
This document provides a process to replace the compound sets with a set mapping.
For an overview of the rationale and timeline for deprecating compound sets, read Overview: Deprecation of Compound Sets.
Identifying Compound Sets in your Application
A compound set is defined as one of these:
It is a subset of a Cartesian product with an index or element parameter declared in its attribute form.
It is a subset of another compound set.
We provide a library with tools to identify compound sets based on these characteristics.
To identify compound sets in your application,
Download the attached
AIMMS project download
and run it using AIMMS 4.54 or more recent but not more recent than AIMMS 4.72.Copy the
DeprecateCompoundSetUtilities
library to your AIMMS project.Run the procedure
dcsu::prIdentifyCompoundSets
. This tests for compound sets, according to the following rules:A set whose string in the
subset of
attribute has a comma, and has defined the attributeindex
or the attributeparameter
. (These are compound root sets.)A set with a compound set as its domain set. (These are not compound root sets.)
The procedure fills the sets
dcsu::sCompoundRootSets
,dcsu::sCompoundSets
, anddcsu::sCompoundSetsThatAreNotRootSets
. Using these results, you may continue to the conversion procedure below.
Replacing Compound Sets with Set Mapping
This conversion procedure explains how to convert compound sets to set mappings in your application. This ensures that your model will function in the same way but without compound sets.
Note
The conversion procedure contains a multitude of steps, and you may wonder whether this is necessary?
To determine the scope that this conversion procedure needs to handle, note that compound data is present in AIMMS Cases and compound data identifiers are present in both WinUI and WebUI pages of that AIMMS application. AIMMS cases cannot be edited manually. The format of both WinUI and WebUI pages are designed for fast serialization instead of for human editing. Obviously, this conversion procedure should not overlook the need to adapt the model itself.
The multitude of steps are too gradually transform the information in cases, pages, and model.
Overview of the conversion procedure
Step 1: Create backups of your application and cases.
Step 2:
Add DeprecateCompoundSetUtilities
library to your application.
Step 3: Create Set Mapping with data of compound sets.
Step 4: Create Set Mapping declarations and copy them to your main model.
Step 5: Create a shadow case for each case with shadow data for the compound data identifiers.
Step 6: Adapt the model to remove compound sets.
Step 7 Move compound indexes to the corresponding set mapping sets.
Step 8: Copy each shadow case back to its corresponding original case.
Step 9:
Remove DeprecateCompoundSetUtilities
library from your application.
Step 1: Create Backups of your Data
The importance of creating backups before starting maintenance on your projects cannot be overemphasized.
Simply create a physical copy of the project and cases and store this in a safe place.
Consider putting the project in a Source Code Management system, if you haven’t done so already.
Step 2: Add Library DeprecateCompoundSetUtilities
The AIMMS project download
provides an example app and utility library DeprecateCompoundSetUtilities
.
Copy the library from that example and add it to your application.
Step 3: Create Set Mapping
There are two things to watch out for:
The definition of a compound set should be suitable for a relation as well.
Use the data from compound sets in your project to create corresponding relations. The definition (if any) of a compound set must be suitable for a relation as well.
Consider the following example:
Set C { SubsetOf: (S, T, U); Tags: (TS, TT, TU); Index: h ; Definition: { { (i,j,k) | pAllowedElementsC(i,j,k) = 1 } } } Set D { SubsetOf: C; Index: g ; definition: { { h | pAllowedElementsD(h.TS, h.TT, h.TU) = 1 } } }
In the example above, the definition of
C
can also be used for a relation, \(R\), that is a subset of the Cartesian product \(S \times T \times U\). The definition ofD
cannot be used for a relation, so it must be rewritten:Set D { SubsetOf: C; Index: g ; definition: { { (i,j,k) | pAllowedElementsC(i,j,k) = 1 and pAllowedElementsD(i, j, k) = 1 } } }
The new definition of
D
is now based on tuples instead of individual elements and can be used for a relation.The predeclared set Integers cannot be used as a component in the domain of a compound set for conversion.
As an example consider the set
Set E { SubsetOf: (S, Integers); Tags: (TS, Int); Index: i_e ; }
The language construct
ie.Int
will be converted to the use of an element parameter. To fill this element parameter with the appropriate contents, a slicing is formulated and this slicing involves an index of each component. For instance as follows:ElementParameter epTag_E_int { IndexDomain: iSMI_E; Range: Integers; Definition: first( IndexIntegers | exists( i | ( i, IndexIntegers, iSMI_E ) in sSetMappingRelation_E ) ); }
When the set
Integers
is used as a component, thenIndexIntegers
is an index that varies over 2G elements. An attempt to do so would trigger the error messageThe set Integers is too big to be used as the range of running index "IndexIntegers"
.Therefore we should introduce a new set, say
s_SomeIntegers
and fill it using the integer elements actually used. Then we should replace the componentIntegers
in the compound set, for instance as follows:Set E { SubsetOf: (S, s_SomeIntegers); Tags: (TS, Int); Index: i_e ; }
The set
s_SomeIntegers
should not be declared to be a subset of the setIntegers
. Once the compound set conversion is complete, we can makes_SomeIntegers
a subset of the setIntegers
.
Step 4: Create Set Mapping Declarations
Now let’s create a set mapping for each compound set in your model. Group set mappings according to namespace (main model, library or module).
Open the WinUI page: Deprecate Compound Set Control Page
of the library DeprecateCompoundSetUtilities
, and press the button Create Set Mapping Declarations
. A section named set mapping declarations
appears in the main model.
Sections named <prefix> set mapping declarations
appear in each library/module where compound sets are defined. These sections are created in the runtime library CompoundSetMappingRuntimeLibrary
as runtime libraries are the only place where a library or main model may create new AIMMS code.
The model explorer should now look something like this:
Perform the following sequence for each set mapping declarations
section.
Go to Edit > Export to save a file (e.g.,
smd.ams
).Select focus on the main model, library or module and create a section named
Set Mapping Declarations
.Select that newly created section and go to Edit > Import to select the file you saved (e.g.,
smd.ams
).
Caution
Do not Copy/Paste the section Set Mapping Declarations
of the runtime library! When you Copy/Paste, the copied section still contains references to the runtime indexes. This causes compilation errors upon restart.
Now is a good time to save the project, exit AIMMS, and create another backup copy of your project.
Step 5: Create Shadow Cases
Shadow cases are cases where the compound data is replaced by atomic shadow data.
You can convert cases with compound data to shadow cases using a tool in the DeprecateCompoundSetUtilities
library.
You can convert multiple cases contained in one folder using the Folder option, or convert each case separately using the File option.
Go to
Deprecate Compound Set Control Page
of theDeprecateCompoundSetUtilities
library.In the section labeled Forward - creating shadow cases:
Specify the input file/folder (to pull original cases containing compound data).
Specify the output file/folder (to push converted cases containing atomic data).
Then click the Copy button to convert.
Step 6: Adapt Model to Remove Compound Sets
This section shows how to convert models using compound sets to use the set mappings created in step 3 above.
Example Case
In this conversion step we will use a running example that contains:
One dimensional sets \(S, T, U\), with indexes respectively \(i, j, k\).
A relation \(R\) that is subset of the Cartesian product \(S \times T \times U\).
A compound set \(C\) with index \(h\) defined as \(\{ (i, j, k) | (i, j, k) \in R \}\). The tags of this compound set are \((TS,TT,TU)\)
A compound subset \(D \subset C\) with index \(g\). Note that \(D\) inherits its tags from \(C\).
A parameter \(P\) declared over the index for the compound set: \(P_h\)
A parameter \(P1\) declared over the index for the compound subset: \(P1_g\)
A parameter \(Q\) declared over the indexes for the one dimensional sets: \(Q_{i,j,k}\)
A parameter \(Q1\) declared over the index \(i\): \(Q1_i\)
Replace Atomic Indexes with Set Mapping Index
Consider the declaration of compound data parameter P
:
Parameter P {
IndexDomain: h;
}
Then using P
is not allowed in an expression such as:
Parameter PS {
IndexDomain: (i,j,k);
Definition: p(i,j,k);
}
It is not allowed, as the automatic mapping between h
and (i,j,k)
is no longer supported.
AIMMS displays a compilation error The number of arguments in the parameter "P" is not correct.
You can replace this definition by:
Parameter PS {
IndexDomain: (i,j,k);
Definition: sum(h|(i,j,k,h) in sMappingSet_C_Relation,p(h));
}
Replace the Function Tuple
The function `Tuple
is a predeclared function to create an element in a compound set from elements in the atomic sets that together form the domain of that compound set.
Consider the function:
epC := Tuple( epS, epT, epU );
Here epS
, epT
, and epU
contain the elements, and Tuple will create a corresponding element in the compound set C
, where C
is the range of the element parameter epC
.
With the deprecation of compound sets, Tuple
is no longer supported , and this should be replaced by:
epC := first( iSMI_C | ( epS, epT, epU, iSMI_C ) in sSetMappingRelation_C );
Step 7: Move Compound Indexes to Set Mapping Sets
To ensure screen definitions are not broken, you must move indexes from the declarations of compound sets to the declaration of the corresponding set mapping set.
To move an index that is declared as part of a set declaration:
Delete it using the wizard at the index attribute.
Re-create it in the destination set.
Step 8: Move Shadow Cases Back to Original Cases
You can convert shadow cases created in step 5 back to the original case locations using the same tool in the DeprecateCompoundSetUtilities
library.
You can convert multiple cases contained in one folder using the Folder option, or convert each case separately using the File option.
Go to
Deprecate Compound Set Control Page
of theDeprecateCompoundSetUtilities
library.In the section labeled Backward - creating cases with original identifiers without compound data:
Specify the input file/folder (to pull cases containing converted data).
Specify the output file/folder (to push to the original case folder location).
Then click the Copy button to convert.
Step 9: Remove the Library DeprecateCompoundSetUtilities
Now that you have removed compound sets from your project, you can remove the library DeprecateCompoundSetUtililities
.
Glossary of Terms Used
- Atomic sets
One-dimensional sets that are not compound sets are called atomic sets. Examples of atomic sets are sets containing names, calendars and subsets of the set Integers. To declare a relation, AIMMS only allows atomic sets in the
subset of
attribute of that relation.- Atomic index
An atomic index is an index in an atomic set. A compound index is an index in a compound set.
- Set mapping
A set mapping is a collection of identifiers that together provide an alternative for the functionality of a single compound set.
A set mapping consists of:
A set mapping set is an atomic set with elements that look like elements from a compound set.
A set mapping index is an index in a set mapping set. Note that a set mapping index is an atomic index.
A set mapping relation is a relation that contains the same set of tuples as a compound set.
A set mapping parameter is an element parameter that contains the data to handle the “tags” functionality of a compound set.
- Compound data
A compound data identifier is a parameter, variable, or constraint with at least one compound index in its index domain. Thus, compound data is the data of a compound data identifier.
- Screen definition
A screen definition is a serialized representation of a screen. The point and click types of UI provided by AIMMS, both WinUI and WebUI, store these screen definitions as text files within an AIMMS project.
- Shadow case
A case containing the same data references to its corresponding namesake but replacing compound data with atomic set mapping data to allow for the removal of compound sets.
- Shadow parameter
Consider a parameter
A
, then a shadow parameter, sayA_Shadow
, is a parameter with the same element values.