-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathElementVariable.cc
More file actions
123 lines (105 loc) · 3.84 KB
/
ElementVariable.cc
File metadata and controls
123 lines (105 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "ElementVariable.h"
#include "solver/Solver.h"
#include "utils/Constants.h"
using namespace Cosoco;
//----------------------------------------------
// Check validity and correct definition
//----------------------------------------------
bool ElementVariable::isSatisfiedBy(vec<int> &tuple) {
return true;
int idx = posIndex == -1 ? tuple[tuple.size() - 2] : tuple[posIndex];
int res = tuple[tuple.size() - 1];
return tuple[idx - (startAtOne ? 1 : 0)] == res;
}
bool ElementVariable::isCorrectlyDefined() {
if(index == value)
throw std::logic_error("Constraint " + std::to_string(idc) + ": ElementVariable has index=result");
return Element::isCorrectlyDefined();
}
//----------------------------------------------
// Filtering
//----------------------------------------------
bool ElementVariable::filter(Variable *dummy) {
if(index->size() > 1) {
if(filterValue() == false)
return false;
while(true) {
// updating idom (and indexSentinels)
int sizeBefore = index->size();
if(filterIndex() == false)
return false;
if(sizeBefore == index->size())
break;
// updating vdom (and valueSentinels)
sizeBefore = value->size();
if(filterValue() == false)
return false;
if(sizeBefore == value->size())
break;
}
}
// If index is singleton, we update dom(list[index]) and vdom so that they are both equal to the
// intersection of the two domains
if(index->size() == 1) {
Variable *x = list[index->value()];
if(solver->delValuesNotInDomain(x, value->domain) == false)
return false;
if(solver->delValuesNotInDomain(value, x->domain) == false)
return false;
if(value->size() == 1)
solver->entail(this);
}
return true;
}
bool ElementVariable::validIndex(int posx) {
int v = indexSentinels[posx];
if(v != STAR && list[posx]->containsValue(v) && value->containsValue(v))
return true;
for(int idv2 : list[posx]->domain) { // int a = dom.first(); a != -1; a = dom.next(a)) {
int v2 = list[posx]->domain.toVal(idv2);
if(value->containsValue(v2)) {
indexSentinels[posx] = v2;
return true;
}
}
return false;
}
bool ElementVariable::filterIndex() {
for(int idv : index->domain) {
int v = index->domain.toVal(idv);
if((v < 0 || v >= list.size() || validIndex(v) == false) && solver->delIdv(index, idv) == false)
return false;
}
return true;
}
bool ElementVariable::validValue(int idv) {
int v = value->domain.toVal(idv);
int sentinel = valueSentinels[idv];
if(sentinel != -1 && index->containsValue(sentinel) && list[sentinel]->containsValue(v))
return true;
for(int idv2 : index->domain) {
int v2 = index->domain.toVal(idv2);
if(v2 >= 0 && v2 < list.size() && list[v2]->containsValue(v)) {
valueSentinels[idv] = v2;
return true;
}
}
return false;
}
bool ElementVariable::filterValue() {
for(int idv : value->domain)
if(validValue(idv) == false && solver->delIdv(value, idv) == false)
return false;
return true;
}
//----------------------------------------------
// Constructor and initialisation methods
//----------------------------------------------
ElementVariable::ElementVariable(Problem &p, std::string n, vec<Variable *> &vars, Variable *i, Variable *r, bool one)
: Element(p, n, "Element Variable", Constraint::createScopeVec(&vars, i, r), i, one), value(r) {
szVector = vars.size();
posIndex = vars.firstOccurrenceOf(i);
vars.copyTo(list);
valueSentinels.growTo(value->domain.maxSize(), -1);
indexSentinels.growTo(vars.size(), STAR);
}