1
#include "CertainZeroFPA.h"
7
using namespace DependencyGraph;
8
using namespace SearchStrategy;
10
bool Algorithm::CertainZeroFPA::search(DependencyGraph::BasicDependencyGraph &t_graph)
15
vertex = graph->initialConfiguration();
21
while(!strategy->empty())
23
while (auto e = strategy->popEdge(false))
26
assert(e->refcnt >= 1);
28
assert(e->refcnt >= -1);
29
if(e->refcnt > 0) --e->refcnt;
30
if(e->refcnt == 0) graph->release(e);
32
if((cnt % 1000) == 0) strategy->trivialNegation();
33
if(vertex->isDone()) return (vertex->assignment == ONE) ? true : false;
36
if(vertex->isDone()) return (vertex->assignment == ONE) ? true : false;
38
if(!strategy->trivialNegation())
41
strategy->releaseNegationEdges(strategy->maxDistance());
46
return (vertex->assignment == ONE) ? true : false;
49
void Algorithm::CertainZeroFPA::checkEdge(Edge* e, bool only_assign)
51
if(e->handled) return;
52
if(e->source->isDone())
54
if(e->refcnt == 0) graph->release(e);
59
bool hasCZero = false;
60
Configuration *lastUndecided = nullptr;
61
for (auto c : e->targets) {
62
if (c->assignment == ONE)
70
if (c->assignment == CZERO) {
73
else if(lastUndecided == nullptr)
78
if(lastUndecided != nullptr && hasCZero) break;
82
_processedNegationEdges += 1;
83
//Process negation edge
87
assert(e->refcnt > 0);
88
if(only_assign) --e->refcnt;
89
if (e->source->nsuccs == 0) {
90
finalAssign(e->source, CZERO);
92
if(e->refcnt == 0) { graph->release(e);}
93
} else if (hasCZero) {
94
finalAssign(e->source, ONE);
96
assert(lastUndecided != nullptr);
97
if(only_assign) return;
98
if (lastUndecided->assignment == ZERO && e->processed) {
99
finalAssign(e->source, ONE);
103
strategy->pushNegation(e);
105
addDependency(e, lastUndecided);
106
if (lastUndecided->assignment == UNKNOWN) {
107
explore(lastUndecided);
112
_processedEdges += 1;
115
finalAssign(e->source, ONE);
116
} else if (hasCZero) {
119
assert(e->refcnt > 0);
120
if(only_assign) --e->refcnt;
121
if (e->source->nsuccs == 0) {
122
finalAssign(e->source, CZERO);
124
if(e->refcnt == 0) {graph->release(e);}
126
} else if (lastUndecided != nullptr) {
127
if(only_assign) return;
129
for (auto t : e->targets)
130
if(!lastUndecided->isDone())
133
if (lastUndecided->assignment == UNKNOWN) {
134
explore(lastUndecided);
138
if(e->refcnt > 0 && !only_assign) e->processed = true;
139
if(e->refcnt == 0) graph->release(e);
142
void Algorithm::CertainZeroFPA::finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a)
144
assert(a == ONE || a == CZERO);
148
for (DependencyGraph::Edge *e : c->dependency_set) {
149
if(e->source->isDone()) continue;
150
if(!e->is_negated || a == CZERO)
152
strategy->pushDependency(e);
156
strategy->pushNegation(e);
158
assert(e->refcnt > 0);
160
if(e->refcnt == 0) graph->release(e);
163
c->dependency_set.clear();
166
void Algorithm::CertainZeroFPA::explore(Configuration *c)
169
c->assignment = ZERO;
172
auto succs = graph->successors(c);
173
c->nsuccs = succs.size();
175
_exploredConfigurations += 1;
176
_numberOfEdges += c->nsuccs;
177
// before we start exploring, lets check if any of them determine
178
// the outcome already!
180
for(int32_t i = c->nsuccs-1; i >= 0; --i)
182
checkEdge(succs[i], true);
185
for(Edge *e : succs){
186
assert(e->refcnt <= 1);
187
if(e->refcnt >= 1) --e->refcnt;
188
if(e->refcnt == 0) graph->release(e);
194
if (c->nsuccs == 0) {
195
for(Edge *e : succs){
196
assert(e->refcnt <= 1);
197
if(e->refcnt >= 1) --e->refcnt;
198
if(e->refcnt == 0) graph->release(e);
200
finalAssign(c, CZERO);
204
for (Edge *succ : succs) {
205
assert(succ->refcnt <= 1);
208
strategy->pushEdge(succ);
210
if(succ->refcnt == 0) graph->release(succ);
212
else if(succ->refcnt == 0)
214
graph->release(succ);
221
void Algorithm::CertainZeroFPA::addDependency(Edge *e, Configuration *target)
223
auto sDist = e->is_negated ? e->source->getDistance() + 1 : e->source->getDistance();
224
auto tDist = target->getDistance();
226
target->setDistance(std::max(sDist, tDist));
227
auto lb = std::lower_bound(std::begin(target->dependency_set), std::end(target->dependency_set), e);
228
if(lb == std::end(target->dependency_set) || *lb != e)
230
target->dependency_set.insert(lb, e);
231
assert(e->refcnt >= 0);