1function domain_check(varargin)
3 % check workspace info from arguments
5 wsInfo = gams.control.WorkspaceInfo();
6 wsInfo.systemDirectory = varargin{1};
7 ws = gams.control.Workspace(wsInfo);
9 ws = gams.control.Workspace();
13 plants = {
'Seattle',
'San-Diego'};
14 markets = {
'New-York',
'Chicago',
'Topeka'};
15 capacity = [350, 600];
16 demand = [325, 300, 275];
17 distance = [2.5, 1.7, 1.8; 2.5, 1.8, 1.4];
19 % prepare a Database with the data above
20 db = ws.addDatabase();
22 % add two sets to the Database
23 i = db.addSet(
'i', 1,
'canning plants');
24 for k = 1:numel(plants)
25 i.addRecord(plants{k});
27 j = db.addSet(
'j', 1,
'markets');
28 for k = 1:numel(markets)
29 j.addRecord(markets{k});
32 % add a parameter with domain information
33 a = db.addParameter(
'a',
'capacity of plant i in cases', i);
34 for k = 1:numel(plants)
35 rec = a.addRecord(plants{k});
36 rec.value = capacity(k);
38 %
if we see a domain violation something went wrong
40 error(
'Unexpected domain violation in a');
43 % add a parameter with relaxed domain information
44 b = db.addParameter(
'b',
'demand at market j in cases',
'j');
45 for k = 1:numel(markets)
46 rec = b.addRecord(markets{k});
47 rec.value = demand(k);
50 error(
'Unexpected domain violation in b');
53 % add a 2-dim parameter with domain information
55 d = db.addParameter(
'd',
'distance in thousands of miles', domains);
56 for k1 = 1:numel(plants)
57 for k2 = 1:numel(markets)
58 keys = {plants{k1}, markets{k2}};
59 rec = d.addRecord(keys);
60 rec.value = distance(k1,k2);
64 error(
'Unexpected domain violation in d');
68 error(
'Unexpected domain violation in db');
71 % create some
'wrong' entries
72 rec = d.addRecord({
'Seattle',
'aa'});
74 rec = d.addRecord({
'bb',
'Seattle'});
77 rec = a.addRecord(
'aa');
79 rec = a.addRecord(
'bb');
81 rec = b.addRecord(
'aa');
83 rec = b.addRecord(
'bb');
86 % now the database as well as the symbols a and d should have domain violations
88 error(
'Domain violation for db not recognized');
91 error(
'Domain violation for a not recognized');
94 error(
'Domain violation for d not recognized');
97 % b in contrast was defined with relaxed domain info only, therefore we should never see a domain violation
99 error(
'Unexpected domain violation in b');
102 %
for a, we should see 2 domain violations (
'aa' and
'bb')
103 fprintf(
'Symbol Domain Violations of a:\n');
104 dvCnt = list_domain_violations(
'', a.getSymbolDomainViolations(0), 0);
106 error(
'Expected 2 domain violation records of a, but found [%d]', dvCnt);
109 %
for d, we should see 3 domain violations (
'Seattle', *
'aa'*; *
'bb'*, *
'Seattle'*)
110 fprintf(
'Symbol Domain Violations of d:\n');
111 dvCnt = list_domain_violations(
'', d.getSymbolDomainViolations(0), 0);
113 error(
'Expected 3 domain violation records of d, but found [%d]', dvCnt);
116 %
for db, we should see 5 domain violations (all the ones from a and d)
118 fprintf(
'Database Domain Violations of db without maximum limit of record numbers:\n');
119 dbDomViolations = db.getDatabaseDomainViolations(0,0);
120 for i = 1:numel(dbDomViolations)
121 name = dbDomViolations{i}.symbol.name;
122 dvCnt = list_domain_violations(name, dbDomViolations{i}.symbolDomainViolations, dvCnt);
125 error(
'Expected 5 domain violation records of db, but found [%d]', dvCnt);
128 % now we limit the amount of violated records reported to a total of 3
130 fprintf(
'Database Domain Violations of db with no more than 3 violation records:\n');
131 dbDomViolations = db.getDatabaseDomainViolations(3,0);
132 for i = 1:numel(dbDomViolations)
133 name = dbDomViolations{i}.symbol.name;
134 dvCnt = list_domain_violations(name, dbDomViolations{i}.symbolDomainViolations, dvCnt);
137 error(
'Expected 3 domain violation records of db, but found [%d]', dvCnt);
140 % now we limit the amount of violated records reported to 1 per symbol
142 fprintf(
'Database Domain Violations of db with no more than 1 violation record per 1 symbol:\n');
143 dbDomViolations = db.getDatabaseDomainViolations(0,1);
144 for i = 1:numel(dbDomViolations)
145 name = dbDomViolations{i}.symbol.name;
146 dvCnt = list_domain_violations(name, dbDomViolations{i}.symbolDomainViolations, dvCnt);
149 error(
'Expected 2 domain violation records of db, but found [%d]', dvCnt);
152 % by
default we should
get an exception when exporting a Database with domain violations
153 sawException =
false;
155 db.export(
'test.gdx');
158 db.suppressAutoDomainChecking =
true;
159 db.export(
'test.gdx');
162 error(
'It should not be possible to export a Database containing domain violations by default');
165 % read a parameter with domain info from gdx
166 db2 = ws.addDatabaseFromGDX(
'test.gdx');
167 d2 = db2.getParameter(
'd');
169 % the domain of the parameter should be Set i and Set j
170 domains = d2.domains;
171 for i = 1:numel(domains)
172 if ~isa(domains{i},
'gams.control.Set')
173 error(
'Expected Set as domain but found relaxed domain %s', item);
175 if strcmp(domains{i}.name,
'i')
176 if ~check_uel(domains{i}, plants)
177 error(
'Unexpected uel found in domain i');
179 elseif strcmp(domains{i}.name,
'j')
180 if ~check_uel(domains{i}, markets)
181 error(
'Unexpected uel found in domain j');
184 error(
'Expected Set i and j but found %s', domains{i}.name);
188 % *************************************************************** %
189 % This next section is acutally not about domain checking, but we %
190 % make sure that certain things are working as expected. %
191 % *************************************************************** %
195 ' i canning plants / seattle, san-diego /; '
198 aliasData = sprintf(
'%s\n', aliasData{:});
200 % Try reading an Alias as Set
201 aliasJob = ws.addJobFromString(aliasData);
203 ii = aliasJob.outDB.getSet(
'ii');
204 fprintf(
'Elements of aliased Set:');
206 fprintf(
' > %s\n', rec{1}.key(1));
209 testDB = ws.addDatabase();
210 testSet = testDB.addSet(
'test', 1);
212 % Try adding empty UEL
213 testSet.addRecord(
'');
214 fprintf(
'Elements of test Set after adding empty UEL:\n');
215 fprintf(
' > %d\n', testSet.numberOfRecords);
217 % GAMS strips pending blanks
while leading blanks are relevant
218 rec = testSet.addRecord(
' a ');
220 fprintf(
'Record '' a '' should be the same as '' a'':\n');
221 fprintf(
' > %s\n', testSet.findRecord(
' a').text);
223 % GAMS cannot handle UELs with more than 63 characters
224 % This should be OK ...
225 rec = testSet.addRecord(
'123456789012345678901234567890123456789012345678901234567890123 ');
230 rec = testSet.addRecord(
'1234567890123456789012345678901234567890123456789012345678901234');
232 error_thrown =
false;
236 error(
'It should not be possible to add a record with more than 63 characters');
239 % GAMS cannot handle explanatory texts with more than 255 characters
240 testDB.addSet(
'textOK',
'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345');
243 testDB.addSet(
'textNotOK',
'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456');
244 error_thrown =
false;
248 error(
'It should not be possible to add an explanatory text with more than 255 characters');
251 rec = testSet.addRecord(
'OK');
252 rec.text =
'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345';
255 rec = testSet.addRecord(
'notOK');
256 rec.text =
'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456';
257 error_thrown =
false;
261 error(
'It should not be possible to add an explanatory text with more than 255 characters');
264 % GAMS can handle UELs containing single and
double quotes but not at the same time
265 testSet.addRecord(
'quote''');
266 testSet.addRecord(
'quote"');
269 testSet.addRecord(
'quote''"');
270 error_thrown =
false;
274 error(
'It should not be possible to add a record single AND double quote');
277 testDB.export(
'test.gdx');
279 fprintf(
'successfully terminated!\n');
283function dvCnt = list_domain_violations(symbolName, domViolations, dvCnt)
284 for j = 1:numel(domViolations)
285 fprintf(
' > %s [', symbolName);
286 item1 = domViolations{j}.violationArray;
287 for k = 1:numel(item1)
296 item2 = domViolations{j}.record.keys;
297 for k = 1:numel(item2)
298 fprintf(
'%s ', item2{k});
304function ret = check_uel(symbol, uels)
306 for rec = symbol.records
308 is_contained =
false;
309 for i = 1:numel(uels)
310 if strcmp(key, uels{i})