// Compile:
//    gcc -Wall -std=c++11 -o a a.cpp -lgecodedriver -lgecodegist -lgecodeint
//    -lgecodekernel -lgecodesearch -lgecodeset -lgecodesupport -lstdc++
#include <gecode/set.hh>
#include <gecode/driver.hh>
 
using namespace Gecode;
using namespace Gecode::Driver;
 
class SceneAlloc: public Script {
private:
        IntSetArgs x;
        SetVar y;
        SetVar z;
 
public:
        SceneAlloc(const SizeOptions &opt): Script(opt) {
                int a[] = {0};
                int b[] = {0, 1};
                IntSet glb(a, sizeof(a)/sizeof(int));
                IntSet lub(b, sizeof(b)/sizeof(int));
                y = SetVar(*this, glb, lub, 1, 2);
 
                int c0[] = {0, 4};
                int c1[] = {1, 7, 8};
                IntSet s0(c0, sizeof(c0)/sizeof(int));
                IntSet s1(c1, sizeof(c1)/sizeof(int));
                if (opt.size() == 0) {
                        x << s0;
                        x << s1;
                } else {
                        x << s1;
                        x << s0;
                }
                std::cout << "x: " << x << std::endl;
 
                z = SetVar(*this, IntSet::empty, IntSet(0, 10));
 
                element(*this, SOT_UNION, x, y, z);
 
                branch(*this, y, SET_VAL_MIN_INC());
        }
 
        SceneAlloc(bool share, SceneAlloc &s): Script(share, s) {
                y.update(*this, share, s.y);
                z.update(*this, share, s.z);
        }
 
        virtual Space * copy(bool share) {
                return new SceneAlloc(share, *this);
        }
 
        virtual void print(std::ostream &os) const {
                os << "y: " << y << std::endl;
                os << "z: " << z << std::endl;
        }
};
 
int main(int argc, char **argv) {
        SizeOptions opt("element union");
        opt.parse(argc, argv);
        Script::run<SceneAlloc, DFS, SizeOptions>(opt);
        return 0;