$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 c0 $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 c0 $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%