Description
With GAMS 25.2 we introduced the new feature called "Implicit Set Definition (or: Domain Defining Symbol Declarations)". Here we test for the expected behavior. Contributor: Lutz Westermann, October 2018
Small Model of Type : GAMS
Category : GAMS Test library
Main file : implset1.gms
$title 'Test for Implicit Set Definition' (IMPLSET1,SEQ=788)
$onText
With GAMS 25.2 we introduced the new feature called "Implicit Set Definition
(or: Domain Defining Symbol Declarations)".
Here we test for the expected behavior.
Contributor: Lutz Westermann, October 2018
$offText
* Start with simple example from documentation
$onEcho > test.gms
Set
i(*) 'canning plants'
j(*) 'markets';
Table d(i<,j<) 'distance in thousands of miles'
new-york chicago topeka
seattle 2.5 1.7 1.8
san-diego 2.5 1.8 1.4;
Alias(u,*);
Set iWant / seattle, san-diego /
jWant / new-york, chicago, topeka /
iTest(u)
jTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
jTest(u) = jWant(u) xor j(u);
abort$card(jTest) jTest;
$offEcho
$call gams test.gms lo=%GAMS.lo% gdx d
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Another example from documentation using multiple symbols defining one set
$onEcho > test.gms
Set
food(*)
fruits(food<) / apple, orange /
$onMulti
vegetable(food<) / carrot, cauliflower /
meat(food<) / beef, pork /;
Alias(u,*);
Set foodWant / apple, orange, carrot, cauliflower, beef, pork /
foodTest(u);
foodTest(u) = foodWant(u) xor food(u);
abort$card(foodTest) foodTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Similar to the previous example, but with $onMultiR we just keep the last definition
$onEcho > test.gms
Set
food(*)
fruits(food<) / apple, orange /
$onMultiR
vegetable(food<) / carrot, cauliflower /
meat(food<) / beef, pork /;
Alias(u,*);
Set foodWant / beef, pork /
foodTest(u);
foodTest(u) = foodWant(u) xor food(u);
abort$card(foodTest) foodTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* With onMulti, the implicitly defined set can also be prefilled
$onEcho > test.gms
Set
food(*) / apple, orange /
$onMulti
vegetable(food<) / carrot, cauliflower /
meat(food<) / beef, pork /;
Alias(u,*);
Set foodWant / apple, orange, carrot, cauliflower, beef, pork /
foodTest(u);
foodTest(u) = foodWant(u) xor food(u);
abort$card(foodTest) foodTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* A set could also be empty after being implicitly defined, but it should still be assigned in this case
$onEcho > test.gms
Set
i;
Parameter
p(i<) / i1 0 /;
Display i;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Simple example with $load
$onEcho > test.gms
Set
i(*) 'canning plants'
j(*) 'markets';
Parameter d(i<,j<) 'distance in thousands of miles';
$gdxIn d.gdx
$load d
Alias(u,*);
Set iWant / seattle, san-diego /
jWant / new-york, chicago, topeka /
iTest(u)
jTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
jTest(u) = jWant(u) xor j(u);
abort$card(jTest) jTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Example with $load exercising filtered loading
$onEcho > test.gms
Set ab / a1.b1
a2.b1
a3.b2 /;
$gdxOut ab.gdx
$unLoad ab
$gdxOut
Set a /a1,a2/, b(*), c(*),
xx(a,b<);
$gdxIn ab.gdx
$load xx=ab c<ab.dim2
Alias(u,*);
Set bWant / b1 /
cWant / b1, b2 /
bTest(u)
cTest(u);
bTest(u) = bWant(u) xor b(u);
abort$card(bTest) bTest;
cTest(u) = cWant(u) xor c(u);
abort$card(cTest) cTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Also works with variables
$onEcho > test.gms
Set
i(*) 'canning plants'
j(*) 'markets';
Variable Table d(i<,j<)
l
seattle.new-york 300
seattle.chicago 400
seattle.topeka 500
san-diego.chicago 600 ;
Alias(u,*);
Set iWant / seattle, san-diego /
jWant / new-york, chicago, topeka /
iTest(u)
jTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
jTest(u) = jWant(u) xor j(u);
abort$card(jTest) jTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
$log --- Using Python library %sysEnv.GMSPYTHONLIB%
* Simple example with embeddedCode
$onEcho > test.gms
Set
i(*) 'canning plants'
j(*) 'markets';
Parameter d(i<,j<) 'distance in thousands of miles';
$onEmbeddedCode python:
gams.set('d',[('seattle', 'new-york',2.5),('seattle', 'chicago',1.7),('seattle', 'topeka',1.8),
('san-diego','new-york',2.5),('san-diego','chicago',1.8),('san-diego','topeka',1.4)])
$offEmbeddedCode d
Alias(u,*);
Set iWant / seattle, san-diego /
jWant / new-york, chicago, topeka /
iTest(u)
jTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
jTest(u) = jWant(u) xor j(u);
abort$card(jTest) jTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Example with embedded Code exercising filtered loading
$onEcho > test.gms
Set a /a1,a2/, b(*), c(*);
Set xx(a,b<);
$onEmbeddedCode Python:
gams.set('xx',[('a1','b1'),('a2','b1'),('a3','b2')])
$offEmbeddedCode xx c<xx.dim2
Alias(u,*);
Set bWant / b1 /
cWant / b1, b2 /
bTest(u)
cTest(u);
bTest(u) = bWant(u) xor b(u);
abort$card(bTest) bTest;
cTest(u) = cWant(u) xor c(u);
abort$card(cTest) cTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Simple example with embeddedCode - at execution time, this is expected to fail
$onEcho > test.gms
Set
i(*) 'canning plants'
j(*) 'markets';
Parameter d(i<,j<) 'distance in thousands of miles';
Embeddedcode python:
gams.set('d',[('seattle', 'new-york',2.5),('seattle', 'chicago',1.7),('seattle', 'topeka',1.8),
('san-diego','new-york',2.5),('san-diego','chicago',1.8),('san-diego','topeka',1.4)])
endEmbeddedcode d
Alias(u,*);
Set iWant / seattle, san-diego /
jWant / new-york, chicago, topeka /
iTest(u)
jTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
jTest(u) = jWant(u) xor j(u);
abort$card(jTest) jTest;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Problem in line %system.line%
$label noEmbeddedPython
* Temporary problem reported by Michael
$onEcho > test.gms
Set p, xs, ys;
Table tab(p<,xs<,ys<)
y1 y2 y3 y4 y5
p1.x1 1 1 1 1 1
;
parameter pend(p) /p1 2/;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Merging to start of existing data should not lead to out-of-order data (which would lead to an error when unloading to GDX), see #4340
$onEcho > test.gms
Alias(u,*);
Set t1 / 2021*2024/;
Set t2 / 2022 /;
$onMulti
Set t(t2<) / 2021 /
t2Want / 2021, 2022 /
t2Test(u);
t2Test(u) = t2Want(u) xor t2(u);
abort$card(t2Test) t2Test;
execute_unload 'all.gdx';
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Merging first UEL to start of existing data with first UEL should not lead to duplicate UEL (which would lead to an error when unloading to GDX), see #3657
$onEcho > test.gms
Set
i 'canning plants' / seattle, kk /;
$onMulti
Alias(u,*);
Parameter
a(i<) 'capacity of plant i in cases'
/ seattle 350/;
Set iWant / seattle, kk /
iTest(u);
iTest(u) = iWant(u) xor i(u);
abort$card(iTest) iTest;
execute_unload 'all.gdx';
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Multiple implicit set definition with multiple usage as domain need to make sure, that domain list gets updated in the middle, see #5014
$onEcho > test.gms
Set sSuper;
Set x_set(sSuper<) /1*2/;
Parameter x(sSuper) /1 1
2 2/;
$onMulti
Set y_set(sSuper<) /1*3/;
parameter y(sSuper) /1 1
2 2
3 3/;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel<>0 $abort Problem in line %system.line%
* Element text should be copied as well if the source is a 1-dim set - last one wins for duplicates
$onEcho > test.gms
Set
f
fruit(f<) / apple red
orange orange /
$onMulti
fruit(f<) / carrot orange
apple green /;
file fx / 'fruit.txt' /
fy / 'f.txt' /;
loop(f,
put fx f.te(f) /;
put fy fruit.te(f) /;
)
$offEcho
$call.checkErrorLevel gams test.gms lo=%GAMS.lo%
$call.checkErrorLevel diff f.txt fruit.txt
* The following tests expect an error
* Redefinition should be wrong by default
$onEcho > test.gms
Set
food(*) / apple, orange /
vegetable(food<) / carrot, cauliflower /
meat(food<) / beef, pork /;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Expected problem in line %system.line%
* Implicit definition of domain set cannot be applied to the universe
$onEcho > test.gms
Alias (food,*);
Set
meat(food<) / beef, pork /;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Expected problem in line %system.line%
* Implicit definition of domain set cannot be applied, if domain is identical to the symbol
$onEcho > test.gms
Set
meat(meat<) / beef, pork /;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Expected problem in line %system.line%
* Implicit definition of domain set cannot be applied, if domain is a subset
$onEcho > test.gms
Set
u
food(u)
meat(food<) / beef, pork /;
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Expected problem in line %system.line%
* Do not allow two mismatching declaration
$onEcho > test.gms
Set
food
meat(food )
meat(food<);
$offEcho
$call gams test.gms lo=%GAMS.lo%
$ifE errorLevel=0 $abort Expected problem in line %system.line%