Skip to content

Commit

Permalink
Merge branch 'feature/enums' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
guidotack committed Aug 30, 2016
2 parents a44ef3c + 5f11965 commit db9c794
Show file tree
Hide file tree
Showing 20 changed files with 804 additions and 146 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ endif()
# The version number.
set (libminizinc_VERSION_MAJOR 2)
set (libminizinc_VERSION_MINOR 0)
set (libminizinc_VERSION_PATCH 13)
set (libminizinc_VERSION_PATCH 13_enum2)

if (ADDITIONAL_DATE_STRING)
set (libminizinc_VERSION_PATCH "${libminizinc_VERSION_PATCH}.${ADDITIONAL_DATE_STRING}")
Expand Down Expand Up @@ -247,6 +247,7 @@ lib/prettyprinter.cpp
lib/solver.cpp
lib/solver_instance.cpp
lib/solver_instance_base.cpp
lib/type.cpp
lib/typecheck.cpp
lib/flatten.cpp
lib/flattener.cpp
Expand Down
6 changes: 6 additions & 0 deletions include/minizinc/ast.hh
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ namespace MiniZinc {
ASTString v(void) const { return _v; }
/// Set identifier
void v(const ASTString& val) { _v = val; }
/// Check whether it is an enum identifier (starting with two $ signs)
bool isEnum(void) const { return _v.c_str()[0]=='$'; }
/// Recompute hash value
void rehash(void);
};
Expand Down Expand Up @@ -917,6 +919,10 @@ namespace MiniZinc {
bool computedDomain(void) const { return _flag_1; }
/// Set if domain is computed from right hand side of variable
void setComputedDomain(bool b) { _flag_1=b; }
/// Check if this TypeInst represents an enum
bool isEnum(void) const { return _flag_2; }
/// Set if this TypeInst represents an enum
void setIsEnum(bool b) { _flag_2=b; }
};

/**
Expand Down
2 changes: 2 additions & 0 deletions include/minizinc/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ namespace MiniZinc {
Expression* domain)
: Expression(loc,E_TI,type), _ranges(ranges), _domain(domain) {
_flag_1 = false;
_flag_2 = false;
rehash();
}

Expand All @@ -484,6 +485,7 @@ namespace MiniZinc {
Expression* domain)
: Expression(loc,E_TI,type), _domain(domain) {
_flag_1 = false;
_flag_2 = false;
rehash();
}

Expand Down
11 changes: 11 additions & 0 deletions include/minizinc/flatten_internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ namespace MiniZinc {
bool _failed;
unsigned int ids;
ASTStringMap<ASTString>::t reifyMap;
typedef UNORDERED_NAMESPACE::unordered_map<VarDeclI*,unsigned int> EnumMap;
EnumMap enumMap;
std::vector<VarDeclI*> enumVarDecls;
typedef UNORDERED_NAMESPACE::unordered_map<std::string,unsigned int> ArrayEnumMap;
ArrayEnumMap arrayEnumMap;
std::vector<std::vector<unsigned int> > arrayEnumDecls;
public:
EnvI(Model* orig0);
~EnvI(void);
Expand All @@ -103,6 +109,11 @@ namespace MiniZinc {
Map::iterator map_end(void);
void dump(void);

unsigned int registerEnum(VarDeclI* vdi);
VarDeclI* getEnum(unsigned int i) const;
unsigned int registerArrayEnum(const std::vector<unsigned int>& arrayEnum);
const std::vector<unsigned int>& getArrayEnum(unsigned int i) const;

void flat_addItem(Item* i);
void flat_removeItem(int i);
void flat_removeItem(Item* i);
Expand Down
124 changes: 64 additions & 60 deletions include/minizinc/type.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@

#include <string>
#include <sstream>
#include <cassert>

namespace MiniZinc {

class EnvI;

/// Type of a MiniZinc expression
class Type {
public:
Expand All @@ -37,12 +40,19 @@ namespace MiniZinc {
unsigned int _st : 1;
unsigned int _ot : 1;
unsigned int _cv : 1;
/** \brief Enumerated type identifier
* This is an index into a table in the Env. It is currently limited to
* 4095 different enumerated type identifiers.
* For a non-array type, this maps directly to the identity of the enum.
* For an array type, it maps to a tuple of enum identities.
*/
unsigned int _enumId : 12;
/// Number of array dimensions
int _dim : 19;
int _dim : 7;
public:
/// Default constructor
Type(void) : _ti(TI_PAR), _bt(BT_UNKNOWN), _st(ST_PLAIN),
_ot(OT_PRESENT), _cv(CV_NO), _dim(0) {}
_ot(OT_PRESENT), _cv(CV_NO), _enumId(0), _dim(0) {}

/// Access type-inst
TypeInst ti(void) const { return static_cast<TypeInst>(_ti); }
Expand Down Expand Up @@ -73,70 +83,85 @@ namespace MiniZinc {
/// Set var-in-par type
void cv(bool b) { _cv = b ? CV_YES : CV_NO; }

/// Access enum identifier
unsigned int enumId(void) const { return _enumId; }
/// Set enum identifier
void enumId(unsigned int eid) { _enumId = eid; }

/// Access dimensions
int dim(void) const { return _dim; }
/// Set dimensions
void dim(int d) { _dim = d; }
void dim(int d) { _dim = d; assert(_dim==d); }

protected:
/// Constructor
Type(const TypeInst& ti, const BaseType& bt, const SetType& st,
int dim)
: _ti(ti), _bt(bt), _st(st), _ot(OT_PRESENT), _cv(ti==TI_VAR ? CV_YES : CV_NO), _dim(dim) {}
unsigned int enumId, int dim)
: _ti(ti), _bt(bt), _st(st), _ot(OT_PRESENT), _cv(ti==TI_VAR ? CV_YES : CV_NO)
, _enumId(enumId), _dim(dim) {}
public:
static Type parint(int dim=0) {
return Type(TI_PAR,BT_INT,ST_PLAIN,dim);
return Type(TI_PAR,BT_INT,ST_PLAIN,0,dim);
}
static Type parenum(unsigned int enumId, int dim=0) {
return Type(TI_PAR,BT_INT,ST_PLAIN,enumId,dim);
}
static Type parbool(int dim=0) {
return Type(TI_PAR,BT_BOOL,ST_PLAIN,dim);
return Type(TI_PAR,BT_BOOL,ST_PLAIN,0,dim);
}
static Type parfloat(int dim=0) {
return Type(TI_PAR,BT_FLOAT,ST_PLAIN,dim);
return Type(TI_PAR,BT_FLOAT,ST_PLAIN,0,dim);
}
static Type parstring(int dim=0) {
return Type(TI_PAR,BT_STRING,ST_PLAIN,dim);
return Type(TI_PAR,BT_STRING,ST_PLAIN,0,dim);
}
static Type ann(int dim=0) {
return Type(TI_PAR,BT_ANN,ST_PLAIN,dim);
return Type(TI_PAR,BT_ANN,ST_PLAIN,0,dim);
}
static Type parsetint(int dim=0) {
return Type(TI_PAR,BT_INT,ST_SET,dim);
return Type(TI_PAR,BT_INT,ST_SET,0,dim);
}
static Type parsetenum(unsigned int enumId, int dim=0) {
return Type(TI_PAR,BT_INT,ST_SET,enumId,dim);
}
static Type parsetbool(int dim=0) {
return Type(TI_PAR,BT_BOOL,ST_SET,dim);
return Type(TI_PAR,BT_BOOL,ST_SET,0,dim);
}
static Type parsetfloat(int dim=0) {
return Type(TI_PAR,BT_FLOAT,ST_SET,dim);
return Type(TI_PAR,BT_FLOAT,ST_SET,0,dim);
}
static Type parsetstring(int dim=0) {
return Type(TI_PAR,BT_STRING,ST_SET,dim);
return Type(TI_PAR,BT_STRING,ST_SET,0,dim);
}
static Type varint(int dim=0) {
return Type(TI_VAR,BT_INT,ST_PLAIN,dim);
return Type(TI_VAR,BT_INT,ST_PLAIN,0,dim);
}
static Type varenumint(unsigned int enumId, int dim=0) {
return Type(TI_VAR,BT_INT,ST_PLAIN,enumId,dim);
}
static Type varbool(int dim=0) {
return Type(TI_VAR,BT_BOOL,ST_PLAIN,dim);
return Type(TI_VAR,BT_BOOL,ST_PLAIN,0,dim);
}
static Type varfloat(int dim=0) {
return Type(TI_VAR,BT_FLOAT,ST_PLAIN,dim);
return Type(TI_VAR,BT_FLOAT,ST_PLAIN,0,dim);
}
static Type varsetint(int dim=0) {
return Type(TI_VAR,BT_INT,ST_SET,dim);
return Type(TI_VAR,BT_INT,ST_SET,0,dim);
}
static Type varbot(int dim=0) {
return Type(TI_VAR,BT_BOT,ST_PLAIN,dim);
return Type(TI_VAR,BT_BOT,ST_PLAIN,0,dim);
}
static Type bot(int dim=0) {
return Type(TI_PAR,BT_BOT,ST_PLAIN,dim);
return Type(TI_PAR,BT_BOT,ST_PLAIN,0,dim);
}
static Type top(int dim=0) {
return Type(TI_PAR,BT_TOP,ST_PLAIN,dim);
return Type(TI_PAR,BT_TOP,ST_PLAIN,0,dim);
}
static Type vartop(int dim=0) {
return Type(TI_VAR,BT_TOP,ST_PLAIN,dim);
return Type(TI_VAR,BT_TOP,ST_PLAIN,0,dim);
}
static Type optvartop(int dim=0) {
Type t(TI_VAR,BT_TOP,ST_PLAIN,dim);
Type t(TI_VAR,BT_TOP,ST_PLAIN,0,dim);
t._ot = OT_OPTIONAL;
return t;
}
Expand Down Expand Up @@ -192,6 +217,7 @@ namespace MiniZinc {
+ (static_cast<int>(_bt)<<24)
+ (static_cast<int>(_ti)<<21)
+ (static_cast<int>(_ot)<<20)
+ (static_cast<int>(_enumId)<<8)
+ (_dim == -1 ? 1 : (_dim == 0 ? 0 : _dim+1));
}
static Type fromInt(int i) {
Expand All @@ -200,64 +226,42 @@ namespace MiniZinc {
t._bt = static_cast<BaseType>((i >> 24) & 0xF);
t._ti = static_cast<TypeInst>((i >> 21) & 0x7);
t._ot = static_cast<OptType>((i >> 20) & 0x1);
int dim = (i & 0xFFFFF);
t._enumId = static_cast<unsigned int>((i >> 8) & 0xFFF);
int dim = (i & 0x7F);
t._dim = (dim == 0 ? 0 : (dim==1 ? -1 : dim-1));
return t;
}
std::string toString(void) const {
std::ostringstream oss;
if (_dim>0) {
oss<<"array[int";
for (int i=1; i<_dim; i++)
oss << ",int";
oss<<"] of ";
}
if (_dim<0)
oss<<"array[$_] of ";
switch (_ti) {
case TI_PAR: break;
case TI_VAR: oss<<"var "; break;
}
if (_ot==OT_OPTIONAL) oss<<"opt ";
if (_st==ST_SET) oss<<"set of ";
switch (_bt) {
case BT_INT: oss<<"int"; break;
case BT_BOOL: oss<<"bool"; break;
case BT_FLOAT: oss<<"float"; break;
case BT_STRING: oss<<"string"; break;
case BT_ANN: oss<<"ann"; break;
case BT_BOT: oss<<"bot"; break;
case BT_TOP: oss<<"top"; break;
case BT_UNKNOWN: oss<<"??? "; break;
}
return oss.str();
}
std::string toString(EnvI& env) const;
std::string nonEnumToString(void) const;
public:
/// Check if \a bt0 is a subtype of \a bt1
static bool bt_subtype(const BaseType& bt0, const BaseType& bt1) {
if (bt0==bt1)
static bool bt_subtype(const Type& t0, const Type& t1) {
// TODO: this should be
// if (t0.bt() == t1.bt() && (t0.enumId() == t1.enumId() || t1.enumId()==0))
// But currently subtyping on enums does not work yet
if (t0.bt() == t1.bt())
return true;
switch (bt0) {
case BT_BOOL: return (bt1==BT_INT || bt1==BT_FLOAT);
case BT_INT: return bt1==BT_FLOAT;
switch (t0.bt()) {
case BT_BOOL: return (t1.bt()==BT_INT || t1.bt()==BT_FLOAT);
case BT_INT: return t1.bt()==BT_FLOAT;
default: return false;
}
}

/// Check if this type is a subtype of \a t
bool isSubtypeOf(const Type& t) const {
if (_dim==0 && t._dim!=0 && _st==ST_SET && t._st==ST_PLAIN &&
( bt()==BT_BOT || bt_subtype(bt(), t.bt()) || t.bt()==BT_TOP) && _ti==TI_PAR &&
( bt()==BT_BOT || bt_subtype(*this, t) || t.bt()==BT_TOP) && _ti==TI_PAR &&
(_ot==OT_PRESENT || _ot==t._ot) )
return true;
// either same dimension or t has variable dimension
if (_dim!=t._dim && (_dim==0 || t._dim!=-1))
return false;
// same type, this is present or both optional
if (_ti==t._ti && bt_subtype(bt(),t.bt()) && _st==t._st)
if (_ti==t._ti && bt_subtype(*this,t) && _st==t._st)
return _ot==OT_PRESENT || _ot==t._ot;
// this is par other than that same type as t
if (_ti==TI_PAR && bt_subtype(bt(),t.bt()) && _st==t._st)
if (_ti==TI_PAR && bt_subtype(*this,t) && _st==t._st)
return _ot==OT_PRESENT || _ot==t._ot;
if ( _ti==TI_PAR && t._bt==BT_BOT)
return true;
Expand Down
6 changes: 6 additions & 0 deletions include/minizinc/typecheck.hh
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ namespace MiniZinc {
DeclMap idmap;
/// Map from declarations to positions
PosMap pos;
/// The model
Model* model;

TopoSorter(Model* model0) : model(model0) {}

/// Add a variable declaration
void add(EnvI& env, VarDecl* vd, bool unique);
/// Add a variable declaration item
void add(EnvI& env, VarDeclI* vd, bool unique, bool handleEnums, std::vector<Item*>& enumItems);
/// Remove a variable declaration
void remove(EnvI& env, VarDecl* vd);
/// Get variable declaration from identifier \a id
Expand Down
2 changes: 1 addition & 1 deletion lib/MIPdomains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ namespace MiniZinc {
} else {
MZN_MIPD__assert_for_feas( 0,
"Variable " << vd->id()->str()
<< " of type " << vd->type().toString()
<< " of type " << vd->type().toString(mipd.__env->envi())
<< " has a domain." );
}
// /// Deleting var domain:
Expand Down
9 changes: 5 additions & 4 deletions lib/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,8 @@ namespace MiniZinc {
} else {
throw TypeError(env, getLoc(ta[i],fi),"type-inst variable $"+
tiid.str()+" instantiated with different types ("+
tiit.toString()+" vs "+
it->second.toString()+")");
tiit.toString(env)+" vs "+
it->second.toString(env)+")");
}
}
}
Expand All @@ -720,8 +720,8 @@ namespace MiniZinc {
} else if (it->second!=tiit) {
throw TypeError(env, getLoc(ta[i],fi),"type-inst variable $"+
tiid.str()+" instantiated with different types ("+
tiit.toString()+" vs "+
it->second.toString()+")");
tiit.toString(env)+" vs "+
it->second.toString(env)+")");
}
}
}
Expand All @@ -731,6 +731,7 @@ namespace MiniZinc {
if (it==tmap.end())
throw TypeError(env, fi->loc(),"type-inst variable $"+dh.str()+" used but not defined");
ret.bt(it->second.bt());
ret.enumId(it->second.enumId());
if (ret.st()==Type::ST_PLAIN)
ret.st(it->second.st());
}
Expand Down
Loading

0 comments on commit db9c794

Please sign in to comment.