// arch-tag: DB2FEBED-DE12-4185-B2F1-225EC7A49C12

// Copyright (c) 2006, Kilian Sprotte. All rights reserved.
// Mauricio Toro-Bermudez 2008. Extending gecol to work with gecode 2.0.x

// Thanks to Christian Schulte and Guido Tack (Gecode developers) and 
// Gustavo Gutierrez (GeOz developer) for their help.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:

//   * Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.

//   * Redistributions in binary form must reproduce the above
//     copyright notice, this list of conditions and the following
//     disclaimer in the documentation and/or other materials
//     provided with the distribution.

// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gecode/int.hh"
#include "gecode/set.hh"
#include "gecode/search.hh"
#include "gecode/minimodel.hh"

using namespace Gecode;

class GecolSpace : public Space {
protected:
  IntVarArray  ints;
  BoolVarArray bools;
  SetVarArray  sets;
  int bab_intvar_ind;
  IntRelType bab_intreltype;
public:
  GecolSpace(int intnum, int intmin, int intmax,
             int boolnum,
             int setnum,
             int arg_bab_intvar_ind, IntRelType arg_bab_intreltype)
    : ints(this, intnum, intmin, intmax),
      bools(this, boolnum, 0, 1),
      sets(this,setnum),
      bab_intvar_ind(arg_bab_intvar_ind),
      bab_intreltype(arg_bab_intreltype)
  {
  }
  // Constructor for cloning a s
  GecolSpace(bool share, GecolSpace &s) : Space(share,s) {
    ints.update(this, share, s.ints);
    bools.update(this, share, s.bools);
    sets.update(this, share, s.sets);
    // FIXME maybe specialize GecolBABSpace
    // so we dont always copy these
    bab_intvar_ind = s.bab_intvar_ind;
    bab_intreltype = s.bab_intreltype;
  }
  // Copy during cloning
  virtual Space*
  copy(bool share) {
    return new GecolSpace(share,*this);
  }
  IntVarArray getInts () {
    return ints;
  }
  BoolVarArray getBools () {
    return bools;
  }
  SetVarArray getSets () {
    return sets;
  }
  // FIXME use here the 'more complicated' version
  // like in gecode examples?
  void constrain(GecolSpace* latest) {
    rel(this, this->getInts()[bab_intvar_ind], bab_intreltype, latest->getInts()[bab_intvar_ind]);
  }
};

struct lisp_SetVarArgs
{
  int size;
  SetVar** array[];
};

struct lisp_IntVarArgs
{
  int size;
  IntVar** array[];
};

struct lisp_BoolVarArgs
{
  int size;
  BoolVar** array[];
};

struct lisp_IntArgs
{
  int size;
  int* array[];
};

extern "C" {
  // IntSet
  IntSet *make_IntSet_int_int(int n, int m);
  IntSet *make_IntSet_intarray_int(const int r[], int n);
  IntSet *make_IntSet_intarray2_int(const int r[][2], int n);
  int IntSet_size(IntSet *intset);
  int IntSet_min_int(IntSet *intset, int i);
  int IntSet_max_int(IntSet *intset, int i);
  unsigned int IntSet_width_int(IntSet *intset, int i);
  int IntSet_min(IntSet *intset);
  int IntSet_max(IntSet *intset);
  void delete_IntSet(IntSet *intset);
  // IntVar
  IntVar *make_IntVar_Space_int_int(Space* home, int min, int max);
  int IntVar_min(IntVar* intvar);
  int IntVar_max(IntVar* intvar);
  int IntVar_med(IntVar* intvar);
  int IntVar_val(IntVar* intvar);
  unsigned int IntVar_size(IntVar* intvar);
  unsigned int IntVar_width(IntVar* intvar);
  unsigned int IntVar_degree(IntVar* intvar);  
  bool IntVar_range(IntVar* intvar);
  bool IntVar_assigned(IntVar* intvar);
  bool IntVar_in_int(IntVar* intvar, const int n);
  void delete_IntVar(IntVar *v);
  // GecolSpace
  GecolSpace* make_GecolSpace(int intnum, int intmin, int intmax, int boolnum, int setnum,
                              int bab_intvar_ind, IntRelType bab_intreltype);
  void delete_GecolSpace(GecolSpace* space);
  IntVar* GecolSpace_getInt_int(GecolSpace* space, int ind);
  BoolVar* GecolSpace_getBool_int(GecolSpace* space, int ind);
  SetVar* GecolSpace_getSet_int(GecolSpace* space, int ind);
 
  void GecolSpace_putSet_int_SetVar(GecolSpace* space, int ind, SetVar* set);
  SpaceStatus GecolSpace_status(GecolSpace* space);
  const BranchingDesc* GecolSpace_description(GecolSpace* space);
  Space* GecolSpace_clone(GecolSpace* space, bool share);
  void GecolSpace_commit(GecolSpace* space, const BranchingDesc *d, unsigned int a);
  void GecolSpace_fail(GecolSpace* space);
  bool GecolSpace_failed(GecolSpace* space);
  unsigned int GecolSpace_propagators(GecolSpace* space);
  unsigned int GecolSpace_branchings(GecolSpace* space);

  // DFS
  DFS<GecolSpace>* make_DFS_Space_int_int_Stop(GecolSpace* space, int c_d, int a_d, Search::Stop* st);
  void delete_DFS(DFS<GecolSpace>* dfs);
  GecolSpace* DFS_next(DFS<GecolSpace>* dfs);
  // BAB
  BAB<GecolSpace>* make_BAB_Space_int_int_Stop(GecolSpace* space, int c_d, int a_d, Search::Stop* st);
  void delete_BAB(BAB<GecolSpace>* bab);
  GecolSpace* BAB_next(BAB<GecolSpace>* bab);

  ////////////
  //reg exp
  REG * make_REG_void();
  REG * make_REG_int(int a);
 // REG * requal(REG * a, REG * b);
  REG * rplus(REG * a, REG * b);
  REG * ror(REG * a, REG * b);
  REG * rklene(REG * a);
  void extensional_IntVarArgs_DFA_intcontlevel(Space * home, const lisp_IntVarArgs * x, DFA * d, IntConLevel icl);
  //branching
  void branch_intvarargs_bvarsel_bvalsel(Space *home, const lisp_IntVarArgs *x, IntVarBranch vars, IntValBranch vals);
  // new branching functions
  void branch_setvarargs_setvarbranch_setvalbranch(Space *home, const lisp_SetVarArgs *x, SetVarBranch vars, SetValBranch vals); 
  void branch_bvarsel_bvalsel(Space *home, IntVarBranch vars, IntValBranch vals);
  void branch_setvarbranch_setvalbranch(Space *home, SetVarBranch vars, SetValBranch vals); 
  //
  void linear_intvarargs_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, int c, IntConLevel icl);
  void linear_intvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl);
  void linear_intvarargs_intreltype_int_boolvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, int c, BoolVar *b, IntConLevel icl);
  void linear_intvarargs_intreltype_intvar_boolvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, BoolVar *b, IntConLevel icl);
  void linear_intargs_intvarargs_intreltype_int_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, int c, IntConLevel icl);
  void linear_intargs_intvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl);
  void linear_intargs_intvarargs_intreltype_int_boolvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, int c, BoolVar *b, IntConLevel icl);
  void linear_intargs_intvarargs_intreltype_intvar_boolvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, BoolVar *b, IntConLevel icl);
  void linear_boolvarargs_intreltype_int_intconlevel(Space *home, const lisp_BoolVarArgs *x, IntRelType r, int c, IntConLevel icl);
  void linear_boolvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_BoolVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl);
  void cumulatives_intvarargs_intvarargs_intvarargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intargs_intvarargs_intvarargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intvarargs_intvarargs_intargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intargs_intvarargs_intargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intvarargs_intvarargs_intvarargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intargs_intvarargs_intvarargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intvarargs_intvarargs_intargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void cumulatives_intargs_intvarargs_intargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl);
  void eq_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntConLevel icl);
  void eq_intvar_int_intconlevel(Space *home, IntVar *x, int n, IntConLevel icl);
  void eq_intvar_intvar_boolvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, BoolVar *b, IntConLevel icl);
  void eq_intvar_int_boolvar_intconlevel(Space *home, IntVar *x, int n, BoolVar *b, IntConLevel icl);
  void eq_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntConLevel icl);
  void count_intvarargs_int_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int n, IntRelType r, int m, IntConLevel icl, PropKind pk);
  void count_intvarargs_intvar_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntRelType r, int m, IntConLevel icl, PropKind pk);
  void count_intvarargs_int_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, int n, IntRelType r, IntVar *z, IntConLevel icl, PropKind pk);
  void count_intvarargs_intvar_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntRelType r, IntVar *z, IntConLevel icl, PropKind pk);
  // --------Old gcc interface
//   void gcc_intvarargs_intargs_int_int_int_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *c, int m, int unspec_low, int unspec_up, int min, int max, IntConLevel icl);
//   void gcc_intvarargs_intargs_int_int_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *c, int m, int unspec, int min, int max, IntConLevel icl);
//   void gcc_intvarargs_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int lb, int ub, IntConLevel icl);
//   void gcc_intvarargs_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int ub, IntConLevel icl);
//   void gcc_intvarargs_intvarargs_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *c, int min, int max, IntConLevel icl);
//   void gcc_intvarargs_intargs_intvarargs_int_int_int_bool_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *v, const lisp_IntVarArgs *c, int m, int unspec_low, int unspec_up, bool all, int min, int max, IntConLevel icl);
//   void gcc_intvarargs_intargs_intvarargs_int_int_bool_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *v, const lisp_IntVarArgs *c, int m, int unspec, bool all, int min, int max, IntConLevel icl);
  // ----------New gcc interface
  void count_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *c,  IntConLevel icl, PropKind pk);

  void channel_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, IntConLevel icl);
  void dom_intvar_int_int_intconlevel(Space *home, IntVar *x, int l, int m, IntConLevel icl);
  void dom_intvarargs_int_int_intconlevel(Space *home, lisp_IntVarArgs *x, int l, int m, IntConLevel icl);
  void dom_intvar_intset_intconlevel(Space *home, IntVar *x, const IntSet *s, IntConLevel icl);
  void dom_intvarargs_intset_intconlevel(Space *home, lisp_IntVarArgs *x, const IntSet *s, IntConLevel icl);
  void dom_intvar_int_int_boolvar_intconlevel(Space *home, IntVar *x, int l, int m, BoolVar *b, IntConLevel icl);
  void dom_intvar_intset_boolvar_intconlevel(Space *home, IntVar *x, const IntSet *s, BoolVar *b, IntConLevel icl);
  void bool_not_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, IntConLevel icl);
  void bool_eq_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, IntConLevel icl);
  void bool_and_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl);
  void bool_and_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl);
  void bool_and_boolvarargs_boolvar_intconlevel(Space *home, const lisp_BoolVarArgs *b, BoolVar *c, IntConLevel icl);
  void bool_and_boolvarargs_bool_intconlevel(Space *home, const lisp_BoolVarArgs *b, bool c, IntConLevel icl);
  void bool_or_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl);
  void bool_or_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl);
  void bool_or_boolvarargs_boolvar_intconlevel(Space *home, const lisp_BoolVarArgs *b, BoolVar *c, IntConLevel icl);
  void bool_or_boolvarargs_bool_intconlevel(Space *home, const lisp_BoolVarArgs *b, bool c, IntConLevel icl);
  void bool_imp_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl);
  void bool_imp_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl);
  void bool_eqv_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl);
  void bool_eqv_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl);
  void bool_xor_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl);
  void bool_xor_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl);
  void sortedness_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, IntConLevel icl);
  void sortedness_intvarargs_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, const lisp_IntVarArgs *z, IntConLevel icl);
  void distinct_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntConLevel icl);
  void distinct_intargs_intvarargs_intconlevel(Space *home, const lisp_IntArgs *n, const lisp_IntVarArgs *x, IntConLevel icl);
  void element_intargs_intvar_intvar_intconlevel(Space *home, const lisp_IntArgs *n, IntVar *x0, IntVar *x1, IntConLevel icl);
  void element_intvarargs_intvar_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y0, IntVar *y1, IntConLevel icl);
  void rel_intvar_intreltype_intvar_intconlevel(Space *home, IntVar *x0, IntRelType r, IntVar *x1, IntConLevel icl);
  void rel_intvar_intreltype_int_intconlevel(Space *home, IntVar *x, IntRelType r, int c, IntConLevel icl);
  void rel_intvar_intreltype_intvar_boolvar_intconlevel(Space *home, IntVar *x0, IntRelType r, IntVar *x1, BoolVar *b, IntConLevel icl);
  void rel_intvar_intreltype_int_boolvar_intconlevel(Space *home, IntVar *x, IntRelType r, int c, BoolVar *b, IntConLevel icl);
  void rel_intvarargs_intreltype_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, const lisp_IntVarArgs *y, IntConLevel icl);
  void min_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl);
  void min_intvarargs_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntConLevel icl);
  void max_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl);
  void max_intvarargs_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntConLevel icl);
  void abs_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntConLevel icl);
  void mult_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl);



  // Sets
  SetVar* gec_fs_make(GecolSpace* space);
  SetVar* gec_fs_make_const(GecolSpace* space, IntSet d);
  SetVar* gec_fs_make_bounds(GecolSpace* space, IntSet ld, IntSet ud);
  SetVar* gec_fs_make_lower_bound(GecolSpace* space, IntSet ld);
  SetVar* gec_fs_make_upper_bound(GecolSpace* space, IntSet ud);
  unsigned int gec_fs_glb_size(SetVar* set);
  unsigned int gec_fs_lub_size(SetVar* set);
  unsigned int gec_fs_unknown_size(SetVar* set);
  unsigned int gec_fs_card_min(SetVar* set);
  unsigned int gec_fs_card_max(SetVar* set);
  int gec_fs_lub_min(SetVar* set);
  int gec_fs_lub_max(SetVar* set);
  int gec_fs_glb_min(SetVar* set);
  int gec_fs_glb_max(SetVar* set);
  bool gec_fs_contains(SetVar* set, int x);
  bool gec_fs_not_contains(SetVar* set, int x);
  bool gec_fs_assigned(SetVar* set);
  Set::SetVarImp* gec_fs_variable(SetVar* set);
  // SetView
  // Set::SetView* make_SetView(SetVar* set);
  // void delete_SetView(Set::SetView* v);
  // LubRanges
  Gecode::Set::LubRanges<Set::SetVarImp*>* make_LubRanges(Set::SetVarImp* v);
  int LubRanges_min(Set::LubRanges<Set::SetVarImp*>* r);
  int LubRanges_max(Set::LubRanges<Set::SetVarImp*>* r);
  unsigned int LubRanges_width(Set::LubRanges<Set::SetVarImp*>* r);
  bool LubRanges_valid(Set::LubRanges<Set::SetVarImp*>* r);
  void LubRanges_next(Set::LubRanges<Set::SetVarImp*>* r);
  void delete_LubRanges(Set::LubRanges<Set::SetVarImp*>* r);
  // GlbRanges
  Gecode::Set::GlbRanges<Set::SetVarImp*>* make_GlbRanges(Set::SetVarImp* v);
  int GlbRanges_min(Set::GlbRanges<Set::SetVarImp*>* r);
  int GlbRanges_max(Set::GlbRanges<Set::SetVarImp*>* r);
  unsigned int GlbRanges_width(Set::GlbRanges<Set::SetVarImp*>* r);
  bool GlbRanges_valid(Set::GlbRanges<Set::SetVarImp*>* r);
  void GlbRanges_next(Set::GlbRanges<Set::SetVarImp*>* r);
  void delete_GlbRanges(Set::GlbRanges<Set::SetVarImp*>* r);
  
  void atmostOne_setvarargs_unsigned_int(Space *home, const lisp_SetVarArgs *x, unsigned int c);
  void distinct_setvarargs_unsigned_int(Space *home, const lisp_SetVarArgs *x, unsigned int c);
  void min_setvar_intvar(Space *home, SetVar *s, IntVar *x);
  void max_setvar_intvar(Space *home, SetVar *s, IntVar *x);
  void match_setvar_intvarargs(Space *home, SetVar *s, const lisp_IntVarArgs *x);
  void channel_intvarargs_setvarargs(Space *home, const lisp_IntVarArgs *x, const lisp_SetVarArgs *y);
  void cardinality_setvar_intvar(Space *home, SetVar *s, IntVar *x);
  void weights_intargs_intargs_setvar_intvar(Space *home, const lisp_IntArgs *elements, const lisp_IntArgs *weights, SetVar *x, IntVar *y);
  void convex_setvar(Space *home, SetVar *x);
  void convexHull_setvar_setvar(Space *home, SetVar *x, SetVar *y);
  void selectUnion_setvarargs_setvar_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z);
  void selectInter_setvarargs_setvar_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z);
  void selectInterIn_setvarargs_setvar_setvar_intset(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z, const IntSet *universe);
  void selectDisjoint_setvarargs_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y);
  void selectSet_setvarargs_intvar_setvar(Space *home, const lisp_SetVarArgs *x, IntVar *y, SetVar *z);
  void rel_setvar_setreltype_setvar(Space *home, SetVar *x, SetRelType r, SetVar *y);
  void rel_setvar_setreltype_setvar_boolvar(Space *home, SetVar *x, SetRelType r, SetVar *y, BoolVar *b);
  void rel_setvar_setreltype_intvar(Space *home, SetVar *s, SetRelType r, IntVar *x);
  void rel_intvar_setreltype_setvar(Space *home, IntVar *x, SetRelType r, SetVar *s);
  void rel_setvar_setreltype_intvar_boolvar(Space *home, SetVar *s, SetRelType r, IntVar *x, BoolVar *b);
  void rel_intvar_setreltype_setvar_boolvar(Space *home, IntVar *x, SetRelType r, SetVar *s, BoolVar *b);
  void rel_setvar_intreltype_intvar(Space *home, SetVar *s, IntRelType r, IntVar *x);
  void rel_intvar_intreltype_setvar(Space *home, IntVar *x, IntRelType r, SetVar *s);
  void rel_setvar_setoptype_setvar_setreltype_setvar(Space *home, SetVar *x, SetOpType op, SetVar *y, SetRelType r, SetVar *z);
  void rel_setoptype_setvarargs_setvar(Space *home, SetOpType op, const lisp_SetVarArgs *x, SetVar *y);
  void rel_setoptype_intvarargs_setvar(Space *home, SetOpType op, const lisp_IntVarArgs *x, SetVar *y);
  void rel_intset_setoptype_setvar_setreltype_setvar(Space *home, const IntSet *x, SetOpType op, SetVar *y, SetRelType r, SetVar *z);
  void rel_setvar_setoptype_intset_setreltype_setvar(Space *home, SetVar *x, SetOpType op, const IntSet *y, SetRelType r, SetVar *z);
  void rel_setvar_setoptype_setvar_setreltype_intset(Space *home, SetVar *x, SetOpType op, SetVar *y, SetRelType r, const IntSet *z);
  void rel_intset_setoptype_intset_setreltype_setvar(Space *home, const IntSet *x, SetOpType op, const IntSet *y, SetRelType r, SetVar *z);
  void rel_intset_setoptype_setvar_setreltype_intset(Space *home, const IntSet *x, SetOpType op, SetVar *y, SetRelType r, const IntSet *z);
  void rel_setvar_setoptype_intset_setreltype_intset(Space *home, SetVar *x, SetOpType op, const IntSet *y, SetRelType r, const IntSet *z);
  void sequence_setvarargs(Space *home, const lisp_SetVarArgs *x);
  void sequentialUnion_setvarargs_setvar(Space *home, const lisp_SetVarArgs *y, SetVar *x);
  void dom_setvar_setreltype_int(Space *home, SetVar *x, SetRelType r, int i);
  void dom_setvar_setreltype_int_int(Space *home, SetVar *x, SetRelType r, int i, int j);
  void dom_setvar_setreltype_intset(Space *home, SetVar *x, SetRelType r, const IntSet *s);
  void dom_setvar_setreltype_int_boolvar(Space *home, SetVar *x, SetRelType r, int i, BoolVar *b);
  void dom_setvar_setreltype_int_int_boolvar(Space *home, SetVar *x, SetRelType r, int i, int j, BoolVar *b);
  void dom_setvar_setreltype_intset_boolvar(Space *home, SetVar *x, SetRelType r, const IntSet *s, BoolVar *b);
  void cardinality_setvar_unsigned_int_unsigned_int(Space *home, SetVar *x, unsigned int i, unsigned int j);


}

//regexp
  REG * make_REG_void()
  {
	return new REG();
  }
  
  REG * make_REG_int(int a)
  {
	return new REG(a);
  }
  
 /* REG * requal(REG * a, REG * b)
  {
		REG aa = *a;
		REG bb = *b;
		return new REG(aa.operator=(bb));
  }*/
  
  REG * rplus(REG * a, REG * b)
    {
		REG aa = *a;
		REG bb = *b;
		return new REG(aa.operator+(bb));
  }
  
  REG * ror(REG * a, REG * b)
    {
		REG aa = *a;
		REG bb = *b;
		return new REG(aa.operator|(bb));
  }
  
  REG * rklene(REG * a)
    {
		REG aa = *a;
		return new REG(aa.operator*());
  }
  
  void extensional_IntVarArgs_DFA_intcontlevel(Space * home, const lisp_IntVarArgs * x, DFA * d, IntConLevel icl)
{
 IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::extensional(home, x_IntVarArgs, *d, icl);
}

// IntSet

IntSet *make_IntSet_int_int(int n, int m)
{
  return new IntSet(n,m);
}

IntSet *make_IntSet_intarray_int(const int r[], int n)
{
  return new IntSet(r,n);
}

IntSet *make_IntSet_intarray2_int(const int r[][2], int n)
{
  return new IntSet(r,n);
}

int IntSet_size(IntSet *intset)
{
  return intset->size();
}

int IntSet_min_int(IntSet *intset, int i)
{
  return intset->min(i);
}

int IntSet_max_int(IntSet *intset, int i)
{
  return intset->max(i);
}

unsigned int IntSet_width_int(IntSet *intset, int i)
{
  return intset->width(i);
}

int IntSet_min(IntSet *intset)
{
  return intset->min();
}

int IntSet_max(IntSet *intset)
{
  return intset->max();
}

void delete_IntSet(IntSet *intset)
{
  delete intset;
}

// IntVar
IntVar *make_IntVar_Space_int_int(Space* home, int min, int max)
{
  return new IntVar(home, min, max);
}

int IntVar_min(IntVar* intvar)
{
  return intvar->min();
}

int IntVar_max(IntVar* intvar)
{
  return intvar->max();
}

int IntVar_med(IntVar* intvar)
{
  return intvar->med();
}

int IntVar_val(IntVar* intvar)
{
  return intvar->val();
}

unsigned int IntVar_size(IntVar* intvar)
{
  return intvar->size();
}

unsigned int IntVar_width(IntVar* intvar)
{
  return intvar->width();
}

unsigned int IntVar_degree(IntVar* intvar)
{
  return intvar->degree();
}

bool IntVar_range(IntVar* intvar)
{
  return intvar->range();
}

bool IntVar_assigned(IntVar* intvar)
{
  return intvar->assigned();
}

bool IntVar_in_int(IntVar* intvar, const int n)
{
  return intvar->in(n);
}

void delete_IntVar(IntVar *v)
{
  delete v;
}

// GecolSpace
GecolSpace* make_GecolSpace(int intnum, int intmin, int intmax, int boolnum, int setnum,
                            int bab_intvar_ind, IntRelType bab_intreltype)
{
  return new GecolSpace(intnum, intmin, intmax, boolnum, setnum,
                        bab_intvar_ind, bab_intreltype);
}

void delete_GecolSpace(GecolSpace* space)
{
  delete space;
}

// Providing these as if they were GecolSpace methods
IntVar* GecolSpace_getInt_int(GecolSpace* space, int ind)
{
  IntVarArray ints = space->getInts();
  return &(ints[ind]);
}

BoolVar* GecolSpace_getBool_int(GecolSpace* space, int ind)
{
  BoolVarArray bools = space->getBools();
  return &(bools[ind]);
}

SetVar* GecolSpace_getSet_int(GecolSpace* space, int ind)
{
  SetVarArray sets = space->getSets();
  return &(sets[ind]);
}

void GecolSpace_putSet_int_SetVar(GecolSpace* space, int ind, SetVar* set)
{
  SetVarArray sets = space->getSets();
  sets[ind] = *set;
}

SpaceStatus GecolSpace_status(GecolSpace* space)
{
  return space->Gecode::Space::status();
}

const BranchingDesc* GecolSpace_description(GecolSpace* space)
{
  return space->Gecode::Space::description();
}

Space* GecolSpace_clone(GecolSpace* space, bool share)
{
  return space->Gecode::Space::clone(share);
}

void GecolSpace_commit(GecolSpace* space, const BranchingDesc *d, unsigned int a)
{
  space->Gecode::Space::commit(d, a);
}

void GecolSpace_fail(GecolSpace* space)
{
  space->Gecode::Space::fail();
}

bool GecolSpace_failed(GecolSpace* space)
{
  return space->Gecode::Space::failed();
}

unsigned int GecolSpace_propagators(GecolSpace* space)
{
  return space->Gecode::Space::propagators();
}

unsigned int GecolSpace_branchings(GecolSpace* space)
{
  return space->Gecode::Space::branchings();
}


// DFS
DFS<GecolSpace>* make_DFS_Space_int_int_Stop(GecolSpace* space, int c_d, int a_d, Search::Stop* st)
{
  Search::Options *opt = new Search::Options();
  opt->c_d = c_d;
  opt->a_d = a_d;
  opt->stop = st;
  return new DFS<GecolSpace>(space, *opt);
}

void delete_DFS(DFS<GecolSpace>* dfs)
{
  // WB: delete opt?
  delete dfs;
}

GecolSpace* DFS_next(DFS<GecolSpace>* dfs)
{
  return dfs->next();
}

// BAB
BAB<GecolSpace>* make_BAB_Space_int_int_Stop(GecolSpace* space, int c_d, int a_d, Search::Stop* st)
{
  Search::Options *opt = new Search::Options();
  opt->c_d = c_d;
  opt->a_d = a_d;
  opt->stop = st;
  return new BAB<GecolSpace>(space, *opt); 
}

void delete_BAB(BAB<GecolSpace>* bab)
{
  // WB: delete opt?
  delete bab;
}

GecolSpace* BAB_next(BAB<GecolSpace>* bab)
{
  return bab->next();
}

////////

void branch_intvarargs_bvarsel_bvalsel(Space *home, const lisp_IntVarArgs *x, IntVarBranch vars, IntValBranch vals)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::branch(home, x_IntVarArgs, vars, vals);
}

// new functions
void branch_setvarargs_setvarbranch_setvalbranch(Space *home, const lisp_SetVarArgs *x, SetVarBranch vars, SetValBranch vals)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::branch(home, x_SetVarArgs, vars, vals);
}

void branch_setvarbranch_setvalbranch(Space *home,  SetVarBranch vars, SetValBranch vals)
{
 
  Gecode::branch(home, ((GecolSpace *)home)->getSets(), vars, vals);
}

void branch_bvarsel_bvalsel(Space *home,  IntVarBranch vars, IntValBranch vals)
{

  Gecode::branch(home, ((GecolSpace *)home)->getInts(), vars, vals);
}

// end

void linear_intvarargs_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, int c, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_IntVarArgs, r, c, icl);
}

void linear_intvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_IntVarArgs, r, *y, icl);
}

void linear_intvarargs_intreltype_int_boolvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, int c, BoolVar *b, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_IntVarArgs, r, c, *b, icl);
}

void linear_intvarargs_intreltype_intvar_boolvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, BoolVar *b, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_IntVarArgs, r, *y, *b, icl);
}

void linear_intargs_intvarargs_intreltype_int_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, int c, IntConLevel icl)
{
  IntArgs a_IntArgs(a->size);
  for(int i=0;i<a->size;i++)
    a_IntArgs[i] = (*(a->array))[i];
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, a_IntArgs, x_IntVarArgs, r, c, icl);
}

void linear_intargs_intvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl)
{
  IntArgs a_IntArgs(a->size);
  for(int i=0;i<a->size;i++)
    a_IntArgs[i] = (*(a->array))[i];
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, a_IntArgs, x_IntVarArgs, r, *y, icl);
}

void linear_intargs_intvarargs_intreltype_int_boolvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, int c, BoolVar *b, IntConLevel icl)
{
  IntArgs a_IntArgs(a->size);
  for(int i=0;i<a->size;i++)
    a_IntArgs[i] = (*(a->array))[i];
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, a_IntArgs, x_IntVarArgs, r, c, *b, icl);
}

void linear_intargs_intvarargs_intreltype_intvar_boolvar_intconlevel(Space *home, const lisp_IntArgs *a, const lisp_IntVarArgs *x, IntRelType r, IntVar *y, BoolVar *b, IntConLevel icl)
{
  IntArgs a_IntArgs(a->size);
  for(int i=0;i<a->size;i++)
    a_IntArgs[i] = (*(a->array))[i];
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, a_IntArgs, x_IntVarArgs, r, *y, *b, icl);
}

void linear_boolvarargs_intreltype_int_intconlevel(Space *home, const lisp_BoolVarArgs *x, IntRelType r, int c, IntConLevel icl)
{
  BoolVarArgs x_BoolVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_BoolVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_BoolVarArgs, r, c, icl);
}

void linear_boolvarargs_intreltype_intvar_intconlevel(Space *home, const lisp_BoolVarArgs *x, IntRelType r, IntVar *y, IntConLevel icl)
{
  BoolVarArgs x_BoolVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_BoolVarArgs[i] = *((*(x->array))[i]);
  Gecode::linear(home, x_BoolVarArgs, r, *y, icl);
}

void cumulatives_intvarargs_intvarargs_intvarargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntVarArgs machine_IntVarArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntVarArgs[i] = *((*(machine->array))[i]);
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntVarArgs duration_IntVarArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntVarArgs[i] = *((*(duration->array))[i]);
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntVarArgs height_IntVarArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntVarArgs[i] = *((*(height->array))[i]);
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntVarArgs, start_IntVarArgs, duration_IntVarArgs, end_IntVarArgs, height_IntVarArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intargs_intvarargs_intvarargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntArgs machine_IntArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntArgs[i] = (*(machine->array))[i];
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntVarArgs duration_IntVarArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntVarArgs[i] = *((*(duration->array))[i]);
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntVarArgs height_IntVarArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntVarArgs[i] = *((*(height->array))[i]);
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntArgs, start_IntVarArgs, duration_IntVarArgs, end_IntVarArgs, height_IntVarArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intvarargs_intvarargs_intargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntVarArgs machine_IntVarArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntVarArgs[i] = *((*(machine->array))[i]);
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntArgs duration_IntArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntArgs[i] = (*(duration->array))[i];
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntVarArgs height_IntVarArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntVarArgs[i] = *((*(height->array))[i]);
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntVarArgs, start_IntVarArgs, duration_IntArgs, end_IntVarArgs, height_IntVarArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intargs_intvarargs_intargs_intvarargs_intvarargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntVarArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntArgs machine_IntArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntArgs[i] = (*(machine->array))[i];
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntArgs duration_IntArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntArgs[i] = (*(duration->array))[i];
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntVarArgs height_IntVarArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntVarArgs[i] = *((*(height->array))[i]);
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntArgs, start_IntVarArgs, duration_IntArgs, end_IntVarArgs, height_IntVarArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intvarargs_intvarargs_intvarargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntVarArgs machine_IntVarArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntVarArgs[i] = *((*(machine->array))[i]);
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntVarArgs duration_IntVarArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntVarArgs[i] = *((*(duration->array))[i]);
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntArgs height_IntArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntArgs[i] = (*(height->array))[i];
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntVarArgs, start_IntVarArgs, duration_IntVarArgs, end_IntVarArgs, height_IntArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intargs_intvarargs_intvarargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntVarArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntArgs machine_IntArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntArgs[i] = (*(machine->array))[i];
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntVarArgs duration_IntVarArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntVarArgs[i] = *((*(duration->array))[i]);
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntArgs height_IntArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntArgs[i] = (*(height->array))[i];
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntArgs, start_IntVarArgs, duration_IntVarArgs, end_IntVarArgs, height_IntArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intvarargs_intvarargs_intargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntVarArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntVarArgs machine_IntVarArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntVarArgs[i] = *((*(machine->array))[i]);
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntArgs duration_IntArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntArgs[i] = (*(duration->array))[i];
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntArgs height_IntArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntArgs[i] = (*(height->array))[i];
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntVarArgs, start_IntVarArgs, duration_IntArgs, end_IntVarArgs, height_IntArgs, limit_IntArgs, at_most, icl);
}

void cumulatives_intargs_intvarargs_intargs_intvarargs_intargs_intargs_bool_intconlevel(Space *home, const lisp_IntArgs *machine, const lisp_IntVarArgs *start, const lisp_IntArgs *duration, const lisp_IntVarArgs *end, const lisp_IntArgs *height, const lisp_IntArgs *limit, bool at_most, IntConLevel icl)
{
  IntArgs machine_IntArgs(machine->size);
  for(int i=0;i<machine->size;i++)
    machine_IntArgs[i] = (*(machine->array))[i];
  IntVarArgs start_IntVarArgs(start->size);
  for(int i=0;i<start->size;i++)
    start_IntVarArgs[i] = *((*(start->array))[i]);
  IntArgs duration_IntArgs(duration->size);
  for(int i=0;i<duration->size;i++)
    duration_IntArgs[i] = (*(duration->array))[i];
  IntVarArgs end_IntVarArgs(end->size);
  for(int i=0;i<end->size;i++)
    end_IntVarArgs[i] = *((*(end->array))[i]);
  IntArgs height_IntArgs(height->size);
  for(int i=0;i<height->size;i++)
    height_IntArgs[i] = (*(height->array))[i];
  IntArgs limit_IntArgs(limit->size);
  for(int i=0;i<limit->size;i++)
    limit_IntArgs[i] = (*(limit->array))[i];
  Gecode::cumulatives(home, machine_IntArgs, start_IntVarArgs, duration_IntArgs, end_IntVarArgs, height_IntArgs, limit_IntArgs, at_most, icl);
}

//Gecode::rel (Space *home, IntVar x0, IntRelType r, IntVar x1, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)

void eq_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::eq(home, *x0, *x1, icl);
  Gecode::rel(home, *x0, IRT_EQ, *x1, icl, pk);
}

//Gecode::rel (Space *home, IntVar x, IntRelType r, int c, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void eq_intvar_int_intconlevel(Space *home, IntVar *x, int n, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::eq(home, *x, n, icl); ???
  Gecode::rel(home, *x, IRT_EQ, n, icl, pk);
}

//Gecode::rel (Space *home, IntVar x0, IntRelType r, IntVar x1, BoolVar b, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void eq_intvar_intvar_boolvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, BoolVar *b, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::eq(home, *x0, *x1, *b, icl); ???
  Gecode::rel(home, *x0,IRT_EQ, *x1, *b, icl, pk);
}

//Gecode::rel (Space *home, IntVar x, IntRelType r, int c, BoolVar b, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void eq_intvar_int_boolvar_intconlevel(Space *home, IntVar *x, int n, BoolVar *b, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::eq(home, *x, n, *b, icl); ???
 Gecode:rel(home, *x, IRT_EQ,n, *b, icl,pk);
}

//Gecode::rel (Space *home, const IntVarArgs &x, IntRelType r, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void eq_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  //Gecode::eq(home, x_IntVarArgs, icl); ???
  Gecode::rel(home, x_IntVarArgs, IRT_EQ, icl, pk);
}

void count_intvarargs_int_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int n, IntRelType r, int m, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::count(home, x_IntVarArgs, n, r, m, icl,pk);
}

void count_intvarargs_intvar_intreltype_int_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntRelType r, int m, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::count(home, x_IntVarArgs, *y, r, m, icl,pk);
}

void count_intvarargs_int_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, int n, IntRelType r, IntVar *z, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::count(home, x_IntVarArgs, n, r, *z, icl,pk);
}

void count_intvarargs_intvar_intreltype_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntRelType r, IntVar *z, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::count(home, x_IntVarArgs, *y, r, *z, icl,pk);
}

//Gecode::count (Space *home, const IntVarArgs &x, const IntArgs &y, IntRelType r, int //m, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
/*
void gcc_intvarargs_intargs_int_int_int_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *c, int m, int unspec_low, int unspec_up, int min, int max, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntArgs c_IntArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntArgs[i] = (*(c->array))[i];
  //Gecode::gcc(home, x_IntVarArgs, c_IntArgs, m, unspec_low, unspec_up, min, max, icl); ???
}

void gcc_intvarargs_intargs_int_int_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgIntVarBranchs *c, int m, int unspec, int min, int max, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntArgs c_IntArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntArgs[i] = (*(c->array))[i];
  //Gecode::gcc(home, x_IntVarArgs, c_IntArgs, m, unspec, min, max, icl); ???
}

void gcc_intvarargs_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int lb, int ub, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  //Gecode::gcc(home, x_IntVarArgs, lb, ub, icl); ???

}

void gcc_intvarargs_int_intconlevel(Space *home, const lisp_IntVarArgs *x, int ub, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  //Gecode::gcc(home, x_IntVarArgs, ub, icl); ???
}

void gcc_intvarargs_intvarargs_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *c, int min, int max, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntVarArgs c_IntVarArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntVarArgs[i] = *((*(c->array))[i]);
  //Gecode::gcc(home, x_IntVarArgs, c_IntVarArgs, min, max, icl); ???
}

void gcc_intvarargs_intargs_intvarargs_int_int_int_bool_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *v, const lisp_IntVarArgs *c, int m, int unspec_low, int unspec_up, bool all, int min, int max, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntArgs v_IntArgs(v->size);
  for(int i=0;i<v->size;i++)
    v_IntArgs[i] = (*(v->array))[i];
  IntVarArgs c_IntVarArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntVarArgs[i] = *((*(c->array))[i]);
  //Gecode::gcc(home, x_IntVarArgs, v_IntArgs, c_IntVarArgs, m, unspec_low, unspec_up, all, min, max, icl); ???
}

void gcc_intvarargs_intargs_intvarargs_int_int_bool_int_int_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntArgs *v, const lisp_IntVarArgs *c, int m, int unspec, bool all, int min, int max, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntArgs v_IntArgs(v->size);
  for(int i=0;i<v->size;i++)
    v_IntArgs[i] = (*(v->array))[i];
  IntVarArgs c_IntVarArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntVarArgs[i] = *((*(c->array))[i]);
  //Gecode::gcc(home, x_IntVarArgs, v_IntArgs, c_IntVarArgs, m, unspec, all, min, max, icl); ???
}
*/

// ------New interface for gcc (global cardinality count), now called Count !

//void 	Gecode::count (Space *home, const IntVarArgs &x, const IntVarArgs &c, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void count_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *c,  IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);

  IntVarArgs c_IntVarArgs(c->size);
  for(int i=0;i<c->size;i++)
    c_IntVarArgs[i] = *((*(c->array))[i]);

  Gecode::count (home, x_IntVarArgs, c_IntVarArgs, icl, pk);
}

// End ------New interface for gcc (global cardinality count), now called Count !
void channel_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntVarArgs y_IntVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_IntVarArgs[i] = *((*(y->array))[i]);
  Gecode::channel(home, x_IntVarArgs, y_IntVarArgs, icl);
}

void dom_intvar_int_int_intconlevel(Space *home, IntVar *x, int l, int m, IntConLevel icl)
{
  Gecode::dom(home, *x, l, m, icl);
}

void dom_intvarargs_int_int_intconlevel(Space *home, lisp_IntVarArgs *x, int l, int m, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::dom(home, x_IntVarArgs, l, m, icl);
}

void dom_intvar_intset_intconlevel(Space *home, IntVar *x, const IntSet *s, IntConLevel icl)
{
  Gecode::dom(home, *x, *s, icl);
}

void dom_intvarargs_intset_intconlevel(Space *home, lisp_IntVarArgs *x, const IntSet *s, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::dom(home, x_IntVarArgs, *s, icl);
}

void dom_intvar_int_int_boolvar_intconlevel(Space *home, IntVar *x, int l, int m, BoolVar *b, IntConLevel icl)
{
  Gecode::dom(home, *x, l, m, *b, icl);
}

void dom_intvar_intset_boolvar_intconlevel(Space *home, IntVar *x, const IntSet *s, BoolVar *b, IntConLevel icl)
{
  Gecode::dom(home, *x, *s, *b, icl);
}

// Rel constraints

// bool_and(home, x, y, z); 
//you have to write
// rel(home, x, BOT_AND, y, z); 

//kewise, for arrays you have to write

// rel(home, BOT_AND, x, y); 

//instead of

 //bool_and(home, x, y); 

//Gecode::rel (Space *home, BoolVar x0, IntRelType r, BoolVar x1, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)

void bool_not_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_not(home, *b0, *b1, icl); --> it was used this way on gecode 1.3.1
  //Gecode::rel(home, BOT_NOT, *b0, *b1, icl); ???
  Gecode::rel(home, *b0, IRT_NQ, *b1, icl,pk);
}

void bool_eq_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_eq(home, *b0, *b1, icl); --> it was used this way on gecode 1.3.1
  //Gecode::rel(home,*b0, BOT_EQV, *b1, icl,pk); ???
  Gecode::rel(home, *b0, BOT_EQV, *b1, 1,icl,pk);
}

void bool_and_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl,PropKind pk=PK_DEF)
{
  //Gecode::bool_and(home, *b0, *b1, *b2, icl); --> it was used this way on gecode 1.3.1
  Gecode::rel(home,*b0, BOT_AND, *b1, *b2, icl,pk);
}

//Gecode::rel (Space *home, BoolVar x0, BoolOpType o, BoolVar x1, int n, IntConLevel icl=ICL_DEF,PropKind pk=PK_DEF)
void bool_and_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl,PropKind pk=PK_DEF)
{
  //Gecode::bool_and(home, *b0, *b1, b2, icl);  --> it was used this way on gecode 1.3.1
  Gecode::rel(home, *b0, BOT_AND, *b1, b2, icl, pk);
}

void bool_and_boolvarargs_boolvar_intconlevel(Space *home, const lisp_BoolVarArgs *b, BoolVar *c, IntConLevel icl,PropKind pk=PK_DEF)
{
  BoolVarArgs b_BoolVarArgs(b->size);
  for(int i=0;i<b->size;i++)
    b_BoolVarArgs[i] = *((*(b->array))[i]);
  //Gecode::bool_and(home, b_BoolVarArgs, *c, icl);  --> it used this way on gecode 1.3.1
  Gecode::rel(home, BOT_AND, b_BoolVarArgs, *c,icl,pk);

//Gecode::rel (Space *home, BoolOpType o, const BoolVarArgs &x, BoolVar y, IntConLevel //icl=ICL_DEF, PropKind pk=PK_DEF)
}

//Gecode::rel (Space *home, BoolOpType o, const BoolVarArgs &x, int n, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF)
void bool_and_boolvarargs_bool_intconlevel(Space *home, const lisp_BoolVarArgs *b, bool c, IntConLevel icl, PropKind pk=PK_DEF)
{
  BoolVarArgs b_BoolVarArgs(b->size);
  for(int i=0;i<b->size;i++)
    b_BoolVarArgs[i] = *((*(b->array))[i]);
  //Gecode::bool_and(home, b_BoolVarArgs, c, icl); ???
  Gecode::rel (home,BOT_AND, b_BoolVarArgs, c, icl, pk);
}

void bool_or_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_or(home, *b0, *b1, *b2, icl); --> it used this way on gecode 1.3.1
  Gecode::rel(home,*b0, BOT_AND, *b1, *b2, icl,pk);
}

void bool_or_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_or(home, *b0, *b1, b2, icl); ???
Gecode::rel(home, *b0, BOT_OR, *b1, b2, icl, pk);
}

void bool_or_boolvarargs_boolvar_intconlevel(Space *home, const lisp_BoolVarArgs *b, BoolVar *c, IntConLevel icl, PropKind pk=PK_DEF)
{
  BoolVarArgs b_BoolVarArgs(b->size);
  for(int i=0;i<b->size;i++)
    b_BoolVarArgs[i] = *((*(b->array))[i]);
  //Gecode::bool_or(home, b_BoolVarArgs, *c, icl);--> it used this way on gecode 1.3.1
    Gecode::rel(home, BOT_OR, b_BoolVarArgs, *c,icl,pk);
}

void bool_or_boolvarargs_bool_intconlevel(Space *home, const lisp_BoolVarArgs *b, bool c, IntConLevel icl, PropKind pk=PK_DEF)
{
  BoolVarArgs b_BoolVarArgs(b->size);
  for(int i=0;i<b->size;i++)
    b_BoolVarArgs[i] = *((*(b->array))[i]);
  //Gecode::bool_or(home, b_BoolVarArgs, c, icl); ???
 Gecode::rel (home,BOT_OR, b_BoolVarArgs, c, icl, pk);
}

void bool_imp_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_imp(home, *b0, *b1, *b2, icl);
    Gecode::rel(home,*b0, BOT_IMP, *b1, *b2, icl,pk);
}

void bool_imp_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_imp(home, *b0, *b1, b2, icl);
  Gecode::rel (home,*b0,BOT_IMP, *b1, b2, icl, pk);
}

void bool_eqv_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_eqv(home, *b0, *b1, *b2, icl);--> it used this way on gecode 1.3.1
    Gecode::rel(home,*b0, BOT_EQV, *b1, *b2, icl,pk);

}

void bool_eqv_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_eqv(home, *b0, *b1, b2, icl);
Gecode::rel(home, *b0, BOT_EQV, *b1, b2, icl, pk);
}

void bool_xor_boolvar_boolvar_boolvar_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, BoolVar *b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_xor(home, *b0, *b1, *b2, icl);
    Gecode::rel(home,*b0, BOT_XOR, *b1, *b2, icl,pk);
}

void bool_xor_boolvar_boolvar_bool_intconlevel(Space *home, BoolVar *b0, BoolVar *b1, bool b2, IntConLevel icl, PropKind pk=PK_DEF)
{
  //Gecode::bool_xor(home, *b0, *b1, b2, icl);
Gecode::rel(home, *b0, BOT_XOR, *b1, b2, icl, pk);
}

// Post propagator that y is x sorted in increasing order. 
void sortedness_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntVarArgs y_IntVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_IntVarArgs[i] = *((*(y->array))[i]);
  Gecode::sorted(home, x_IntVarArgs, y_IntVarArgs, icl,pk); 
 //in version 1.3.1 it was called sortedness, now sorted.
}

// Post propagator that y is x sorted in increasing order. 
// The values in z describe the sorting permutation
void sortedness_intvarargs_intvarargs_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, const lisp_IntVarArgs *y, const lisp_IntVarArgs *z, IntConLevel icl, PropKind pk=PK_DEF)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntVarArgs y_IntVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_IntVarArgs[i] = *((*(y->array))[i]);
  IntVarArgs z_IntVarArgs(z->size);
  for(int i=0;i<z->size;i++)
    z_IntVarArgs[i] = *((*(z->array))[i]);
  Gecode::sorted(home, x_IntVarArgs, y_IntVarArgs, z_IntVarArgs, icl,pk);
 //in version 1.3.1 it was called sortedness, now sorted.
}

void distinct_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::distinct(home, x_IntVarArgs, icl);
}

void distinct_intargs_intvarargs_intconlevel(Space *home, const lisp_IntArgs *n, const lisp_IntVarArgs *x, IntConLevel icl)
{
  IntArgs n_IntArgs(n->size);
  for(int i=0;i<n->size;i++)
    n_IntArgs[i] = (*(n->array))[i];
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::distinct(home, n_IntArgs, x_IntVarArgs, icl);
}

void element_intargs_intvar_intvar_intconlevel(Space *home, const lisp_IntArgs *n, IntVar *x0, IntVar *x1, IntConLevel icl)
{
  IntArgs n_IntArgs(n->size);
  for(int i=0;i<n->size;i++)
    n_IntArgs[i] = (*(n->array))[i];
  Gecode::element(home, n_IntArgs, *x0, *x1, icl);
}

void element_intvarargs_intvar_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y0, IntVar *y1, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::element(home, x_IntVarArgs, *y0, *y1, icl);
}

void rel_intvar_intreltype_intvar_intconlevel(Space *home, IntVar *x0, IntRelType r, IntVar *x1, IntConLevel icl)
{
  Gecode::rel(home, *x0, r, *x1, icl);
}

void rel_intvar_intreltype_int_intconlevel(Space *home, IntVar *x, IntRelType r, int c, IntConLevel icl)
{
  Gecode::rel(home, *x, r, c, icl);
}

void rel_intvar_intreltype_intvar_boolvar_intconlevel(Space *home, IntVar *x0, IntRelType r, IntVar *x1, BoolVar *b, IntConLevel icl)
{
  Gecode::rel(home, *x0, r, *x1, *b, icl);
}

void rel_intvar_intreltype_int_boolvar_intconlevel(Space *home, IntVar *x, IntRelType r, int c, BoolVar *b, IntConLevel icl)
{
  Gecode::rel(home, *x, r, c, *b, icl);
}

void rel_intvarargs_intreltype_intvarargs_intconlevel(Space *home, const lisp_IntVarArgs *x, IntRelType r, const lisp_IntVarArgs *y, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  IntVarArgs y_IntVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_IntVarArgs[i] = *((*(y->array))[i]);
  Gecode::rel(home, x_IntVarArgs, r, y_IntVarArgs, icl);
}

void min_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl)
{
  Gecode::min(home, *x0, *x1, *x2, icl);
}

void min_intvarargs_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::min(home, x_IntVarArgs, *y, icl);
}

void max_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl)
{
  Gecode::max(home, *x0, *x1, *x2, icl);
}

void max_intvarargs_intvar_intconlevel(Space *home, const lisp_IntVarArgs *x, IntVar *y, IntConLevel icl)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::max(home, x_IntVarArgs, *y, icl);
}

void abs_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntConLevel icl)
{
  Gecode::abs(home, *x0, *x1, icl);
}

void mult_intvar_intvar_intvar_intconlevel(Space *home, IntVar *x0, IntVar *x1, IntVar *x2, IntConLevel icl)
{
  Gecode::mult(home, *x0, *x1, *x2, icl);
}


// Sets
SetVar* gec_fs_make(GecolSpace* space)
{
  return new SetVar(space);
}

SetVar* gec_fs_make_const(GecolSpace* space, IntSet d)
{
  return new SetVar(space, d, d);
}

SetVar* gec_fs_make_bounds(GecolSpace* space, IntSet ld, IntSet ud)
{
  return new SetVar(space, ld, ud);
}

SetVar* gec_fs_make_lower_bound(GecolSpace* space, IntSet ld)
{
  return new SetVar(space, ld, IntSet::empty);
}

SetVar* gec_fs_make_upper_bound(GecolSpace* space, IntSet ud)
{
  return new SetVar(space, IntSet::empty, ud);
}

unsigned int gec_fs_glb_size(SetVar* set)
{
  return set->glbSize();
}

unsigned int gec_fs_lub_size(SetVar* set)
{
  return set->lubSize();
}

unsigned int gec_fs_unknown_size(SetVar* set)
{
  return set->unknownSize();
}

unsigned int gec_fs_card_min(SetVar* set)
{
  return set->cardMin();
}

unsigned int gec_fs_card_max(SetVar* set)
{
  return set->cardMax();
}

int gec_fs_lub_min(SetVar* set)
{
  return set->lubMin();
}

int gec_fs_lub_max(SetVar* set)
{
  return set->lubMax();
}

int gec_fs_glb_min(SetVar* set)
{
  return set->glbMin();
}

int gec_fs_glb_max(SetVar* set)
{
  return set->glbMax();
}

bool gec_fs_contains(SetVar* set, int x)
{
  return set->contains(x);
}

bool gec_fs_not_contains(SetVar* set, int x)
{
  return set->notContains(x);
}

bool gec_fs_assigned(SetVar* set)
{
  return set->assigned();
}

Set::SetVarImp* gec_fs_variable(SetVar* set)
{
  // WB: was: return set->variable(); (this works in Gecode < 2.1.1)
  return set->var();
}

// SetView
// Set::SetView* make_SetView(SetVar* set)
// {
//   return new Set::SetView(*set);
// }
// 
// void delete_SetView(Set::SetView* v)
// {
//   delete v;
// }

// LubRanges
Set::LubRanges<Set::SetVarImp*>* make_LubRanges(Set::SetVarImp* v)
{
  return new Set::LubRanges<Set::SetVarImp*>(v);
}

int LubRanges_min(Set::LubRanges<Set::SetVarImp*>* r)
{
  return r->min();
}

int LubRanges_max(Set::LubRanges<Set::SetVarImp*>* r)
{
  return r->max();
}

unsigned int LubRanges_width(Set::LubRanges<Set::SetVarImp*>* r)
{
  return r->width();
}

bool LubRanges_valid(Set::LubRanges<Set::SetVarImp*>* r)
{
  return r->operator ()();
}

void LubRanges_next(Set::LubRanges<Set::SetVarImp*>* r)
{
  r->operator ++();
}

void delete_LubRanges(Set::LubRanges<Set::SetVarImp*>* r)
{
  delete r;
}

// GlbRanges
Set::GlbRanges<Set::SetVarImp*>* make_GlbRanges(Set::SetVarImp* v)
{
  return new Set::GlbRanges<Set::SetVarImp*>(v);
}

int GlbRanges_min(Set::GlbRanges<Set::SetVarImp*>* r)
{
  return r->min();
}

int GlbRanges_max(Set::GlbRanges<Set::SetVarImp*>* r)
{
  return r->max();
}

unsigned int GlbRanges_width(Set::GlbRanges<Set::SetVarImp*>* r)
{
  return r->width();
}

bool GlbRanges_valid(Set::GlbRanges<Set::SetVarImp*>* r)
{
  return r->operator ()();
}

void GlbRanges_next(Set::GlbRanges<Set::SetVarImp*>* r)
{
  r->operator ++();
}

void delete_GlbRanges(Set::GlbRanges<Set::SetVarImp*>* r)
{
  delete r;
}

//////

void atmostOne_setvarargs_unsigned_int(Space *home, const lisp_SetVarArgs *x, unsigned int c)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::atmostOne(home, x_SetVarArgs, c);
}

void distinct_setvarargs_unsigned_int(Space *home, const lisp_SetVarArgs *x, unsigned int c)
{
  //SetVarArgs x_SetVarArgs(x->size);
     //for(int i=0;i<x->size;i++)
     //  x_SetVarArgs[i] = *((*(x->array))[i]);
  //Gecode::distinct(home, x_SetVarArgs, c); ???

  //Just post rel(home, x1, SRT_NQ, x2) for each pair x1,x2 of variables in the original SetVarArgs.

  for(int i=0; i<x->size; i++)
   {
    Gecode::cardinality(home, *((*(x->array))[i]), c, c);
    for(int j=0; j<x->size;j++)
       Gecode::rel(home, *((*(x->array))[i]), SRT_NQ, *((*(x->array))[j]));
   }
}

void min_setvar_intvar(Space *home, SetVar *s, IntVar *x)
{
  Gecode::min(home, *s, *x);
}

void max_setvar_intvar(Space *home, SetVar *s, IntVar *x)
{
  Gecode::max(home, *s, *x);
}

void match_setvar_intvarargs(Space *home, SetVar *s, const lisp_IntVarArgs *x)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::match(home, *s, x_IntVarArgs);
}

void channel_intvarargs_setvarargs(Space *home, const lisp_IntVarArgs *x, const lisp_SetVarArgs *y)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  SetVarArgs y_SetVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_SetVarArgs[i] = *((*(y->array))[i]);
  Gecode::channel(home, x_IntVarArgs, y_SetVarArgs);
}

void cardinality_setvar_intvar(Space *home, SetVar *s, IntVar *x)
{
  Gecode::cardinality(home, *s, *x);
}

void weights_intargs_intargs_setvar_intvar(Space *home, const lisp_IntArgs *elements, const lisp_IntArgs *weights, SetVar *x, IntVar *y)
{
  IntArgs elements_IntArgs(elements->size);
  for(int i=0;i<elements->size;i++)
    elements_IntArgs[i] = (*(elements->array))[i];
  IntArgs weights_IntArgs(weights->size);
  for(int i=0;i<weights->size;i++)
    weights_IntArgs[i] = (*(weights->array))[i];
  Gecode::weights(home, elements_IntArgs, weights_IntArgs, *x, *y);
}

void convex_setvar(Space *home, SetVar *x)
{
  Gecode::convex(home, *x);
}

void convexHull_setvar_setvar(Space *home, SetVar *x, SetVar *y)
{
  Gecode::convexHull(home, *x, *y);
}

void selectUnion_setvarargs_setvar_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::selectUnion(home, x_SetVarArgs, *y, *z);
}

void selectInter_setvarargs_setvar_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::selectInter(home, x_SetVarArgs, *y, *z);
}

void selectInterIn_setvarargs_setvar_setvar_intset(Space *home, const lisp_SetVarArgs *x, SetVar *y, SetVar *z, const IntSet *universe)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::selectInterIn(home, x_SetVarArgs, *y, *z, *universe);
}

void selectDisjoint_setvarargs_setvar(Space *home, const lisp_SetVarArgs *x, SetVar *y)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::selectDisjoint(home, x_SetVarArgs, *y);
}

void selectSet_setvarargs_intvar_setvar(Space *home, const lisp_SetVarArgs *x, IntVar *y, SetVar *z)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::selectSet(home, x_SetVarArgs, *y, *z);
}

void rel_setvar_setreltype_setvar(Space *home, SetVar *x, SetRelType r, SetVar *y)
{
  Gecode::rel(home, *x, r, *y);
}

void rel_setvar_setreltype_setvar_boolvar(Space *home, SetVar *x, SetRelType r, SetVar *y, BoolVar *b)
{
  Gecode::rel(home, *x, r, *y, *b);
}

void rel_setvar_setreltype_intvar(Space *home, SetVar *s, SetRelType r, IntVar *x)
{
  Gecode::rel(home, *s, r, *x);
}

void rel_intvar_setreltype_setvar(Space *home, IntVar *x, SetRelType r, SetVar *s)
{
  Gecode::rel(home, *x, r, *s);
}

void rel_setvar_setreltype_intvar_boolvar(Space *home, SetVar *s, SetRelType r, IntVar *x, BoolVar *b)
{
  Gecode::rel(home, *s, r, *x, *b);
}

void rel_intvar_setreltype_setvar_boolvar(Space *home, IntVar *x, SetRelType r, SetVar *s, BoolVar *b)
{
  Gecode::rel(home, *x, r, *s, *b);
}

void rel_setvar_intreltype_intvar(Space *home, SetVar *s, IntRelType r, IntVar *x)
{
  Gecode::rel(home, *s, r, *x);
}

void rel_intvar_intreltype_setvar(Space *home, IntVar *x, IntRelType r, SetVar *s)
{
  Gecode::rel(home, *x, r, *s);
}

void rel_setvar_setoptype_setvar_setreltype_setvar(Space *home, SetVar *x, SetOpType op, SetVar *y, SetRelType r, SetVar *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void rel_setoptype_setvarargs_setvar(Space *home, SetOpType op, const lisp_SetVarArgs *x, SetVar *y)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::rel(home, op, x_SetVarArgs, *y);
}

void rel_setoptype_intvarargs_setvar(Space *home, SetOpType op, const lisp_IntVarArgs *x, SetVar *y)
{
  IntVarArgs x_IntVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_IntVarArgs[i] = *((*(x->array))[i]);
  Gecode::rel(home, op, x_IntVarArgs, *y);
}

void rel_intset_setoptype_setvar_setreltype_setvar(Space *home, const IntSet *x, SetOpType op, SetVar *y, SetRelType r, SetVar *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void rel_setvar_setoptype_intset_setreltype_setvar(Space *home, SetVar *x, SetOpType op, const IntSet *y, SetRelType r, SetVar *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void rel_setvar_setoptype_setvar_setreltype_intset(Space *home, SetVar *x, SetOpType op, SetVar *y, SetRelType r, const IntSet *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void rel_intset_setoptype_intset_setreltype_setvar(Space *home, const IntSet *x, SetOpType op, const IntSet *y, SetRelType r, SetVar *z)
{
// You have to emulate it like this:

// void rel_intset_setoptype_intset_setreltype_setvar(Space *home, const
// IntSet *x, SetOpType op, const IntSet *y, SetRelType r, SetVar *z)
// {
//   Gecode::IntSetRanges xr(*x);
//   Gecode::IntSetRanges yr(*y);
//   switch (op) {
//   case SOT_INTER:
//     {
//         Gecode::Iter::Ranges::Inter< Gecode::IntSetRanges,
// Gecode::IntSetRanges > ir(xr,yr);
//         Gecode::IntSet result(ir);
//         Gecode::dom(home, *z, inverse(r), ir);
//     }
//     break;
//   case SOT_UNION:
//     ...
//   }
//   case ...
//   }
// }

// Where inverse(r) is pseudo-code for inverting the relation (SRT_SUB <-
//  > SRT_SUP).


  //Gecode::rel(home, *x, op, *y, r, *z); ???
}

void rel_intset_setoptype_setvar_setreltype_intset(Space *home, const IntSet *x, SetOpType op, SetVar *y, SetRelType r, const IntSet *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void rel_setvar_setoptype_intset_setreltype_intset(Space *home, SetVar *x, SetOpType op, const IntSet *y, SetRelType r, const IntSet *z)
{
  Gecode::rel(home, *x, op, *y, r, *z);
}

void sequence_setvarargs(Space *home, const lisp_SetVarArgs *x)
{
  SetVarArgs x_SetVarArgs(x->size);
  for(int i=0;i<x->size;i++)
    x_SetVarArgs[i] = *((*(x->array))[i]);
  Gecode::sequence(home, x_SetVarArgs);
}

void sequentialUnion_setvarargs_setvar(Space *home, const lisp_SetVarArgs *y, SetVar *x)
{
  SetVarArgs y_SetVarArgs(y->size);
  for(int i=0;i<y->size;i++)
    y_SetVarArgs[i] = *((*(y->array))[i]);
  Gecode::sequentialUnion(home, y_SetVarArgs, *x);
}

void dom_setvar_setreltype_int(Space *home, SetVar *x, SetRelType r, int i)
{
  Gecode::dom(home, *x, r, i);
}

void dom_setvar_setreltype_int_int(Space *home, SetVar *x, SetRelType r, int i, int j)
{
  Gecode::dom(home, *x, r, i, j);
}

void dom_setvar_setreltype_intset(Space *home, SetVar *x, SetRelType r, const IntSet *s)
{
  Gecode::dom(home, *x, r, *s);
}

void dom_setvar_setreltype_int_boolvar(Space *home, SetVar *x, SetRelType r, int i, BoolVar *b)
{
  Gecode::dom(home, *x, r, i, *b);
}

void dom_setvar_setreltype_int_int_boolvar(Space *home, SetVar *x, SetRelType r, int i, int j, BoolVar *b)
{
  Gecode::dom(home, *x, r, i, j, *b);
}

void dom_setvar_setreltype_intset_boolvar(Space *home, SetVar *x, SetRelType r, const IntSet *s, BoolVar *b)
{
  Gecode::dom(home, *x, r, *s, *b);
}

void cardinality_setvar_unsigned_int_unsigned_int(Space *home, SetVar *x, unsigned int i, unsigned int j)
{
  Gecode::cardinality(home, *x, i, j);
}
