1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker 35a3110598 Squashed 'software/chuffed/' content from commit 2ed0c015
git-subtree-dir: software/chuffed
git-subtree-split: 2ed0c01558d2a5c49c1ce57e048d32c17adf92d3
2021-06-18 09:36:35 +10:00

362 lines
8.6 KiB
C++

#ifndef int_var_h
#define int_var_h
#include <new>
#include <stdint.h>
#include <chuffed/support/misc.h>
#include <chuffed/core/sat-types.h>
#include <chuffed/core/engine.h>
#include <chuffed/vars/vars.h>
#include <chuffed/vars/bool-view.h>
#ifndef INT64_MAX
#define INT64_MAX 9223372036854775807LL
#endif
#ifndef INT64_MIN
#define INT64_MIN (-INT64_MAX-1)
#endif
// Controls whether active domain values are stored in a trailed linked list,
// to allow fast enumeration of domain values. Also whether a count is kept.
// NOTE: Makes search a bit slower, so kept it conditional at this stage,
// turning this off selects compatibility routines that scan value-by-value.
#define INT_DOMAIN_LIST 0
/*
IntVar descriptions
IntVar: Base class, no lits
IntVarEL: Eager lit class, lits are eagerly generated
supports bounds and/or value lits
use for "small" vars, or when we need the lits for clausified propagators
IntVarLL;: Lazy lit class, lits are lazily generated
supports bounds lits only
remVal ignored
use for large or unbounded vars
*/
// Bye bye macros
#undef min
#undef max
//-----
class IntVar : public Var {
public:
int const var_id;
Tint min;
Tint max;
int min0; // Initial minimum
int max0; // Initial maximum
int shadow_val;
bool in_scip;
bool all_in_scip;
bool should_be_learnable;
bool should_be_decidable;
Tchar *vals;
#if INT_DOMAIN_LIST
Tint *vals_list;
Tint vals_count;
#endif
PreferredVal preferred_val;
double activity;
IntVar(int min, int max);
friend IntVar* newIntVar(int min, int max);
#if !INT_DOMAIN_LIST
void updateMin();
void updateMax();
#endif
void updateFixed();
public:
static const int max_limit = 500000000;
static const int min_limit = -500000000;
//--------------------------------------------------
// Engine stuff
struct PropInfo {
Propagator *p;
int pos; // what is var's id w.r.t. the propagator
int eflags; // what var events should wake this propagator
PropInfo(Propagator *_p, int _pos, int _eflags)
: p(_p), pos(_pos), eflags(_eflags) {}
};
// intermediate state
int changes;
bool in_queue;
// persistent state
vec<PropInfo> pinfo;
virtual void attach(Propagator *p, int pos, int eflags);
void pushInQueue();
void wakePropagators();
void clearPropState();
int simplifyWatches();
//--------------------------------------------------
// Branching stuff
bool finished() { return isFixed(); }
double getScore(VarBranch vb);
void setPreferredVal(PreferredVal p) { preferred_val = p; }
DecInfo* branch();
//--------------------------------------------------
// Type specialisation
VarType getType() { return INT_VAR; }
void specialiseToEL();
void specialiseToLL();
void specialiseToSL(vec<int>& values);
void initVals(bool optional = false);
//--------------------------------------------------
// Read data
bool isFixed() const { return min == max; }
int getMin() const { return min; }
int getMax() const { return max; }
int getMin0() const { return min0; }
int getMax0() const { return max0; }
int getVal() const { assert(isFixed()); return min; }
int getShadowVal() const {
if (in_scip) return shadow_val;
return min;
}
bool indomain(int64_t v) const {
return v >= min && v <= max && (!vals || vals[v]);
}
class iterator {
const IntVar* var;
int val;
public:
iterator() {}
iterator(const IntVar* _var, int _val) : var(_var), val(_val) {}
int operator *() const {
assert(val >= var->min && val <= var->max && var->vals && var->vals[val]);
return val;
}
iterator& operator ++() {
assert(val >= var->min && val <= var->max && var->vals && var->vals[val]);
if (val == var->max)
val = static_cast<int>(0x80000000);
else
#if INT_DOMAIN_LIST
val = var->vals_list[2*val+1];
#else
while (!var->vals[++val])
;
#endif
return *this;
}
iterator operator ++(int dummy) {
iterator temp = *this;
++*this;
return temp;
}
iterator& operator --() {
if (val == static_cast<int>(0x80000000))
val = var->max;
else {
assert(val > var->min && val <= var->max && var->vals && var->vals[val]);
#if INT_DOMAIN_LIST
val = var->vals_list[2*val];
#else
while (!var->vals[--val])
;
#endif
}
return *this;
}
iterator operator --(int dummy) {
iterator temp = *this;
--*this;
return temp;
}
bool operator ==(const iterator& rhs) const {
assert(var == rhs.var);
return (val == rhs.val);
}
bool operator !=(const iterator& rhs) const {
assert(var == rhs.var);
return (val != rhs.val);
}
};
typedef iterator const_iterator;
iterator begin() const { return iterator(this, min); }
iterator end() const { return iterator(this, static_cast<int>(0x80000000)); }
class reverse_iterator {
iterator forward;
public:
reverse_iterator() {}
reverse_iterator(iterator _forward) : forward(_forward) {}
int operator *() const {
iterator temp = forward;
return *--temp;
}
reverse_iterator& operator ++() {
--forward;
return *this;
}
reverse_iterator operator ++(int dummy) {
reverse_iterator temp = *this;
++*this;
return temp;
}
reverse_iterator& operator --() {
++forward;
return *this;
}
reverse_iterator operator --(int dummy) {
reverse_iterator temp = *this;
--*this;
return temp;
}
iterator base() const {
return forward;
}
bool operator ==(const reverse_iterator& rhs) const {
return (forward == rhs.forward);
}
bool operator !=(const reverse_iterator& rhs) const {
return (forward != rhs.forward);
}
};
typedef reverse_iterator const_reverse_iterator;
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
int size() const {
assert(vals);
#if INT_DOMAIN_LIST
return vals_count;
#else
if (isFixed())
return 1;
int count = 2;
for (int i = min + 1; i < max; ++i)
count += vals[i];
return count;
#endif
}
//--------------------------------------------------
// Explanations:
virtual Lit getMinLit() const { NEVER; }
virtual Lit getMaxLit() const { NEVER; }
virtual Lit getValLit() const { NEVER; }
virtual Lit getFMinLit(int64_t v) { NEVER; }
virtual Lit getFMaxLit(int64_t v) { NEVER; }
// NOTE: No support for INT_VAR_LL vars yet!
// t = 0: [x != v], t = 1: [x = v], t = 2: [x >= v], t = 3: [x <= v]
virtual Lit getLit(int64_t v, int t) { NEVER; }
//--------------------------------------------------
// Domain operations
void set(int val, int type, bool channel = true);
bool setMinNotR(int64_t v) const { return v > min; }
bool setMaxNotR(int64_t v) const { return v < max; }
bool setValNotR(int64_t v) const { return v != min || v != max; }
bool remValNotR(int64_t v) const { return indomain(v); }
virtual bool setMin(int64_t v, Reason r = NULL, bool channel = true);
virtual bool setMax(int64_t v, Reason r = NULL, bool channel = true);
virtual bool setVal(int64_t v, Reason r = NULL, bool channel = true);
virtual bool remVal(int64_t v, Reason r = NULL, bool channel = true);
virtual bool allowSet(vec<int>& v, Reason r = NULL, bool channel = true);
virtual void channel(int val, int val_type, int sign) {
set(val, val_type * 3 ^ sign, false);
}
Lit operator >= (int val) { return getLit(val, 2); }
Lit operator <= (int val) { return getLit(val, 3); }
Lit operator > (int val) { return getLit(val+1, 2); }
Lit operator < (int val) { return getLit(val-1, 3); }
Lit operator = (int val) { return getLit(val, 1); }
Lit operator != (int val) { return getLit(val, 0); }
operator BoolView () { assert(min >= 0 && max <= 1); return getLit(1, 2); }
//--------------------------------------------------
// Debug
void printLit(int val, int type);
void print();
};
IntVar* newIntVar(int min = IntVar::min_limit, int max = IntVar::max_limit);
IntVar* getConstant(int v);
inline void IntVar::pushInQueue() {
if (!in_queue) {
in_queue = true;
engine.v_queue.push(this);
}
}
inline void IntVar::clearPropState() {
changes = 0;
in_queue = false;
}
inline void IntVar::set(int val, int type, bool channel) {
switch (type) {
case 0: remVal(val, NULL, channel); break;
case 1: setVal(val, NULL, channel); break;
case 2: setMin(val+1, NULL, channel); break;
case 3: setMax(val, NULL, channel); break;
default: NEVER;
}
}
inline void IntVar::printLit(int val, int type) {
printf("[v%d ", var_id);
switch (type) {
case 0: printf("!= %d]", val); break;
case 1: printf("== %d]", val); break;
case 2: printf(">= %d]", val+1); break;
case 3: printf("<= %d]", val); break;
}
}
inline void IntVar::print() {
fprintf(stderr, "v%d: min = %d, max = %d\n", var_id, (int) min, (int) max);
}
#include <chuffed/vars/int-var-el.h>
#include <chuffed/vars/int-var-ll.h>
#include <chuffed/vars/int-var-sl.h>
#endif