2
#include "ReachabilityResult.h"
3
#include "../PetriNetBuilder.h"
4
#include "../options.h"
5
#include "PetriEngine/PQL/Expressions.h"
7
namespace PetriEngine {
8
namespace Reachability {
9
ResultPrinter::Result ResultPrinter::printResult(
11
PQL::Condition* query,
12
ResultPrinter::Result result,
13
size_t expandedStates,
14
size_t exploredStates,
15
size_t discoveredStates,
16
const std::vector<size_t> enabledTransitionsCount,
18
const std::vector<uint32_t> maxPlaceBound, Structures::StateSetInterface* stateset,
21
if(result == Unknown) return Unknown;
23
Result retval = result;
25
if(options->cpnOverApprox)
27
if (result == Satisfied)
28
retval = query->isInvariant() ? Unknown : Unknown;
29
else if (result == NotSatisfied)
30
retval = query->isInvariant() ? Satisfied : NotSatisfied;
33
std::cout << "\nUnable to decide if " << querynames[index] << " is satisfied.\n\n";
34
std::cout << "Query is MAYBE satisfied.\n" << std::endl;
38
std::cout << std::endl;
40
bool showTrace = (result == Satisfied);
42
if(!options->statespaceexploration && retval != Unknown)
44
std::cout << "FORMULA " << querynames[index] << " ";
48
uint32_t placeBound = 0;
49
for (size_t p = 0; p < maxPlaceBound.size(); p++) {
50
placeBound = std::max<uint32_t>(placeBound, maxPlaceBound[p]);
52
// fprintf(stdout,"STATE_SPACE %lli -1 %d %d TECHNIQUES EXPLICIT\n", result.exploredStates(), result.maxTokens(), placeBound);
53
std::cout << "STATE_SPACE STATES "<< exploredStates << " " << techniquesStateSpace
55
<< "STATE_SPACE TRANSITIONS "<< -1 << " " << techniquesStateSpace
57
<< "STATE_SPACE MAX_TOKEN_PER_MARKING "<< maxTokens << " " << techniquesStateSpace
59
<< "STATE_SPACE MAX_TOKEN_IN_PLACE "<< placeBound << " " << techniquesStateSpace
64
if (result == Satisfied)
65
retval = query->isInvariant() ? NotSatisfied : Satisfied;
66
else if (result == NotSatisfied)
67
retval = query->isInvariant() ? Satisfied : NotSatisfied;
71
if(auto ef = dynamic_cast<PQL::EFCondition*>(query))
73
bound = (*ef)[0].get();
75
bound = dynamic_cast<PQL::UnfoldedUpperBoundsCondition*>(bound);
77
if (retval == Unknown)
79
std::cout << "\nUnable to decide if " << querynames[index] << " is satisfied.";
83
std::cout << ((PQL::UnfoldedUpperBoundsCondition*)bound)->bounds() << " " << techniques << printTechniques() << std::endl;
84
std::cout << "Query index " << index << " was solved" << std::endl;
86
else if (retval == Satisfied) {
87
if(!options->statespaceexploration)
89
std::cout << "TRUE " << techniques << printTechniques() << std::endl;
90
std::cout << "Query index " << index << " was solved" << std::endl;
92
} else if (retval == NotSatisfied) {
93
if(!options->statespaceexploration)
95
std::cout << "FALSE " << techniques << printTechniques() << std::endl;
96
std::cout << "Query index " << index << " was solved" << std::endl;
100
std::cout << std::endl;
102
std::cout << "Query is ";
103
if(options->statespaceexploration)
108
if (result == Satisfied)
109
retval = query->isInvariant() ? NotSatisfied : Satisfied;
110
else if (result == NotSatisfied)
111
retval = query->isInvariant() ? Satisfied : NotSatisfied;
114
if (retval == Unknown)
116
std::cout << "MAYBE ";
118
else if (retval == NotSatisfied) {
121
std::cout << "satisfied." << std::endl;
123
if(options->cpnOverApprox)
124
std::cout << "\nSolved using CPN Approximation\n" << std::endl;
126
if(showTrace && options->trace)
132
std::cout << "No trace could be generated" << std::endl;
136
// No trace was generated, printing the empty trace
137
std::cerr << "Trace:\n<trace>\n";
138
std::cerr << "</trace>\n" << std::endl;
143
printTrace(stateset, lastmarking);
147
std::cout << std::endl;
151
std::string ResultPrinter::printTechniques() {
154
if(options->queryReductionTimeout > 0)
159
if(options->cpnOverApprox)
161
out += "CPN_APPROX ";
164
if(options->isCPN && !options->cpnOverApprox)
166
out += "UNFOLDING_TO_PT ";
169
if(options->queryReductionTimeout == 0
173
&& options->siphontrapTimeout == 0)
175
out += "EXPLICIT STATE_COMPRESSION ";
176
if(options->stubbornreduction)
178
out += "STUBBORN_SETS ";
184
out += "TRACE_ABSTRACTION_REFINEMENT ";
187
if(options->siphontrapTimeout > 0)
189
out += "TOPOLOGICAL SIPHON_TRAP ";
195
void ResultPrinter::printTrace(Structures::StateSetInterface* ss, size_t lastmarking)
197
std::cerr << "Trace:\n<trace>\n";
198
std::stack<size_t> transitions;
199
size_t next = lastmarking;
200
while(next != 0) // assume 0 is the index of the first marking.
202
// (parent, transition)
203
std::pair<size_t, size_t> p = ss->getHistory(next);
205
transitions.push(p.second);
209
reducer->initFire(std::cerr);
211
while(transitions.size() > 0)
213
size_t trans = transitions.top();
215
std::string tname = ss->net().transitionNames()[trans];
216
std::cerr << "\t<transition id=\"" << tname << "\">\n";
218
// well, yeah, we are not really efficient in constructing the trace.
219
// feel free to improve
220
for(size_t p = 0; p < ss->net().numberOfPlaces(); ++p)
222
size_t cnt = ss->net().inArc(p, trans);
223
for(size_t token = 0; token < cnt; ++token )
225
std::cerr << "\t\t<token place=\"" << ss->net().placeNames()[p] << "\" age=\"0\"/>\n";
230
reducer->extraConsume(std::cerr, tname);
232
std::cerr << "\t</transition>\n";
235
reducer->postFire(std::cerr, tname);
239
std::cerr << "</trace>\n" << std::endl;