1
#include "CTL/Algorithm/CertainZeroFPA.h"
6
using namespace DependencyGraph;
7
using namespace SearchStrategy;
9
bool Algorithm::CertainZeroFPA::search(DependencyGraph::BasicDependencyGraph &t_graph)
14
vertex = graph->initialConfiguration();
20
while(!strategy->empty())
22
while (auto e = strategy->popEdge(false))
25
assert(e->refcnt >= 1);
27
assert(e->refcnt >= -1);
28
if(e->refcnt > 0) --e->refcnt;
29
if(e->refcnt == 0) graph->release(e);
31
if((cnt % 1000) == 0) strategy->trivialNegation();
32
if(vertex->isDone()) return vertex->assignment == ONE;
35
if(vertex->isDone()) return vertex->assignment == ONE;
37
if(!strategy->trivialNegation())
40
strategy->releaseNegationEdges(strategy->maxDistance());
45
return vertex->assignment == ONE;
48
void Algorithm::CertainZeroFPA::checkEdge(Edge* e, bool only_assign)
50
if(e->handled) return;
51
if(e->source->isDone())
53
if(e->refcnt == 0) graph->release(e);
58
bool hasCZero = false;
59
Configuration *lastUndecided = nullptr;
60
for (auto c : e->targets) {
61
if (c->assignment == ONE)
69
if (c->assignment == CZERO) {
72
else if(lastUndecided == nullptr)
77
if(lastUndecided != nullptr && hasCZero) break;
81
_processedNegationEdges += 1;
82
//Process negation edge
86
assert(e->refcnt > 0);
87
if(only_assign) --e->refcnt;
88
if (e->source->nsuccs == 0) {
89
finalAssign(e->source, CZERO);
91
if(e->refcnt == 0) { graph->release(e);}
92
} else if (hasCZero) {
93
finalAssign(e->source, ONE);
95
assert(lastUndecided != nullptr);
96
if(only_assign) return;
97
if (lastUndecided->assignment == ZERO && e->processed) {
98
finalAssign(e->source, ONE);
102
strategy->pushNegation(e);
104
addDependency(e, lastUndecided);
105
if (lastUndecided->assignment == UNKNOWN) {
106
explore(lastUndecided);
111
_processedEdges += 1;
114
finalAssign(e->source, ONE);
115
} else if (hasCZero) {
118
assert(e->refcnt > 0);
119
if(only_assign) --e->refcnt;
120
if (e->source->nsuccs == 0) {
121
finalAssign(e->source, CZERO);
123
if(e->refcnt == 0) {graph->release(e);}
125
} else if (lastUndecided != nullptr) {
126
if(only_assign) return;
128
for (auto t : e->targets)
129
if(!lastUndecided->isDone())
132
if (lastUndecided->assignment == UNKNOWN) {
133
explore(lastUndecided);
137
if(e->refcnt > 0 && !only_assign) e->processed = true;
138
if(e->refcnt == 0) graph->release(e);
141
void Algorithm::CertainZeroFPA::finalAssign(DependencyGraph::Configuration *c, DependencyGraph::Assignment a)
143
assert(a == ONE || a == CZERO);
147
for (DependencyGraph::Edge *e : c->dependency_set) {
148
if(e->source->isDone()) continue;
149
if(!e->is_negated || a == CZERO)
151
strategy->pushDependency(e);
155
strategy->pushNegation(e);
157
assert(e->refcnt > 0);
159
if(e->refcnt == 0) graph->release(e);
162
c->dependency_set.clear();
165
void Algorithm::CertainZeroFPA::explore(Configuration *c)
168
c->assignment = ZERO;
171
auto succs = graph->successors(c);
172
c->nsuccs = succs.size();
174
_exploredConfigurations += 1;
175
_numberOfEdges += c->nsuccs;
176
// before we start exploring, lets check if any of them determine
177
// the outcome already!
179
for(int32_t i = c->nsuccs-1; i >= 0; --i)
181
checkEdge(succs[i], true);
184
for(Edge *e : succs){
185
assert(e->refcnt <= 1);
186
if(e->refcnt >= 1) --e->refcnt;
187
if(e->refcnt == 0) graph->release(e);
193
if (c->nsuccs == 0) {
194
for(Edge *e : succs){
195
assert(e->refcnt <= 1);
196
if(e->refcnt >= 1) --e->refcnt;
197
if(e->refcnt == 0) graph->release(e);
199
finalAssign(c, CZERO);
203
for (Edge *succ : succs) {
204
assert(succ->refcnt <= 1);
207
strategy->pushEdge(succ);
209
if(succ->refcnt == 0) graph->release(succ);
211
else if(succ->refcnt == 0)
213
graph->release(succ);
220
void Algorithm::CertainZeroFPA::addDependency(Edge *e, Configuration *target)
222
auto sDist = e->is_negated ? e->source->getDistance() + 1 : e->source->getDistance();
223
auto tDist = target->getDistance();
225
target->setDistance(std::max(sDist, tDist));
226
auto lb = std::lower_bound(std::begin(target->dependency_set), std::end(target->dependency_set), e);
227
if(lb == std::end(target->dependency_set) || *lb != e)
229
target->dependency_set.insert(lb, e);
230
assert(e->refcnt >= 0);