2
#include "PetriEngine/Reachability/ReachabilityResult.h"
3
#include "PetriEngine/PetriNetBuilder.h"
4
#include "PetriEngine/options.h"
5
#include "PetriEngine/PQL/Expressions.h"
7
namespace PetriEngine {
8
namespace Reachability {
9
std::pair<AbstractHandler::Result, bool> ResultPrinter::handle(
11
PQL::Condition* query,
13
const std::vector<uint32_t>* maxPlaceBound,
14
size_t expandedStates,
15
size_t exploredStates,
16
size_t discoveredStates,
18
Structures::StateSetInterface* stateset, size_t lastmarking, const MarkVal* initialMarking)
20
if(result == Unknown) return std::make_pair(Unknown,false);
22
Result retval = result;
24
if(options->cpnOverApprox)
26
if(query->getQuantifier() == PQL::Quantifier::UPPERBOUNDS)
28
auto upq = ((PQL::UnfoldedUpperBoundsCondition*)query);
29
auto bnd = upq->bounds();
30
if(initialMarking == nullptr || bnd > upq->value(initialMarking))
33
else if (result == Satisfied)
34
retval = query->isInvariant() ? Unknown : Unknown;
35
else if (result == NotSatisfied)
36
retval = query->isInvariant() ? Satisfied : NotSatisfied;
39
std::cout << "\nUnable to decide if " << querynames[index] << " is satisfied.\n\n";
40
std::cout << "Query is MAYBE satisfied.\n" << std::endl;
41
return std::make_pair(Ignore,false);
44
std::cout << std::endl;
46
bool showTrace = (result == Satisfied);
48
if(!options->statespaceexploration && retval != Unknown)
50
std::cout << "FORMULA " << querynames[index] << " ";
54
uint32_t placeBound = 0;
55
if(maxPlaceBound != nullptr)
57
for (size_t p = 0; p < maxPlaceBound->size(); p++) {
58
placeBound = std::max<uint32_t>(placeBound, (*maxPlaceBound)[p]);
61
// fprintf(stdout,"STATE_SPACE %lli -1 %d %d TECHNIQUES EXPLICIT\n", result.exploredStates(), result.maxTokens(), placeBound);
62
std::cout << "STATE_SPACE STATES "<< exploredStates << " " << techniquesStateSpace
64
<< "STATE_SPACE TRANSITIONS "<< -1 << " " << techniquesStateSpace
66
<< "STATE_SPACE MAX_TOKEN_PER_MARKING "<< maxTokens << " " << techniquesStateSpace
68
<< "STATE_SPACE MAX_TOKEN_IN_PLACE "<< placeBound << " " << techniquesStateSpace
70
return std::make_pair(retval,false);
73
if (result == Satisfied)
74
retval = query->isInvariant() ? NotSatisfied : Satisfied;
75
else if (result == NotSatisfied)
76
retval = query->isInvariant() ? Satisfied : NotSatisfied;
80
if(auto ef = dynamic_cast<PQL::EFCondition*>(query))
82
bound = (*ef)[0].get();
84
bound = dynamic_cast<PQL::UnfoldedUpperBoundsCondition*>(bound);
86
if (retval == Unknown)
88
std::cout << "\nUnable to decide if " << querynames[index] << " is satisfied.";
92
std::cout << ((PQL::UnfoldedUpperBoundsCondition*)bound)->bounds() << " " << techniques << printTechniques() << std::endl;
93
std::cout << "Query index " << index << " was solved" << std::endl;
95
else if (retval == Satisfied) {
96
if(!options->statespaceexploration)
98
std::cout << "TRUE " << techniques << printTechniques() << std::endl;
99
std::cout << "Query index " << index << " was solved" << std::endl;
101
} else if (retval == NotSatisfied) {
102
if(!options->statespaceexploration)
104
std::cout << "FALSE " << techniques << printTechniques() << std::endl;
105
std::cout << "Query index " << index << " was solved" << std::endl;
109
std::cout << std::endl;
111
std::cout << "Query is ";
112
if(options->statespaceexploration)
117
if (result == Satisfied)
118
retval = query->isInvariant() ? NotSatisfied : Satisfied;
119
else if (result == NotSatisfied)
120
retval = query->isInvariant() ? Satisfied : NotSatisfied;
123
if (retval == Unknown)
125
std::cout << "MAYBE ";
127
else if (retval == NotSatisfied) {
130
std::cout << "satisfied." << std::endl;
132
if(options->cpnOverApprox)
133
std::cout << "\nSolved using CPN Approximation\n" << std::endl;
135
if(showTrace && options->trace)
137
if(stateset == nullptr)
139
std::cout << "No trace could be generated" << std::endl;
143
printTrace(stateset, lastmarking);
147
std::cout << std::endl;
148
return std::make_pair(retval, false);
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
171
&& options->siphontrapTimeout == 0)
173
out += "EXPLICIT STATE_COMPRESSION ";
174
if(options->stubbornreduction)
176
out += "STUBBORN_SETS ";
181
out += "TRACE_ABSTRACTION_REFINEMENT ";
183
if(options->siphontrapTimeout > 0)
185
out += "TOPOLOGICAL SIPHON_TRAP ";
191
void ResultPrinter::printTrace(Structures::StateSetInterface* ss, size_t lastmarking)
193
std::cerr << "Trace:\n<trace>\n";
194
std::stack<size_t> transitions;
195
size_t next = lastmarking;
196
while(next != 0) // assume 0 is the index of the first marking.
198
// (parent, transition)
199
std::pair<size_t, size_t> p = ss->getHistory(next);
201
transitions.push(p.second);
205
reducer->initFire(std::cerr);
207
while(transitions.size() > 0)
209
size_t trans = transitions.top();
211
std::string tname = ss->net().transitionNames()[trans];
212
std::cerr << "\t<transition id=\"" << tname << "\" index=\"" << trans << "\">\n";
214
// well, yeah, we are not really efficient in constructing the trace.
215
// feel free to improve
216
for(size_t p = 0; p < ss->net().numberOfPlaces(); ++p)
218
size_t cnt = ss->net().inArc(p, trans);
219
for(size_t token = 0; token < cnt; ++token )
221
std::cerr << "\t\t<token place=\"" << ss->net().placeNames()[p] << "\" age=\"0\"/>\n";
226
reducer->extraConsume(std::cerr, tname);
228
std::cerr << "\t</transition>\n";
231
reducer->postFire(std::cerr, tname);
235
std::cerr << "</trace>\n" << std::endl;