138
138
return BooleanCondition::getShared(K);
142
Condition_ptr makeOr(const std::vector<Condition_ptr>& cptr)
142
Condition_ptr makeOr(const std::vector<Condition_ptr>& cptr)
143
143
{ return makeLog<OrCondition,false>(cptr, true); }
144
Condition_ptr makeAnd(const std::vector<Condition_ptr>& cptr)
144
Condition_ptr makeAnd(const std::vector<Condition_ptr>& cptr)
145
145
{ return makeLog<AndCondition,true>(cptr, true); }
146
Condition_ptr makeOr(const Condition_ptr& a, const Condition_ptr& b) {
147
std::vector<Condition_ptr> cnds{a,b};
148
return makeLog<OrCondition,false>(cnds, true);
150
Condition_ptr makeAnd(const Condition_ptr& a, const Condition_ptr& b)
152
std::vector<Condition_ptr> cnds{a,b};
153
return makeLog<AndCondition,true>(cnds, true);
146
Condition_ptr makeOr(const Condition_ptr& a, const Condition_ptr& b) {
147
std::vector<Condition_ptr> cnds{a,b};
148
return makeLog<OrCondition,false>(cnds, true);
150
Condition_ptr makeAnd(const Condition_ptr& a, const Condition_ptr& b)
152
std::vector<Condition_ptr> cnds{a,b};
153
return makeLog<AndCondition,true>(cnds, true);
158
158
Condition_ptr BooleanCondition::FALSE_CONSTANT = std::make_shared<BooleanCondition>(false);
159
159
Condition_ptr BooleanCondition::TRUE_CONSTANT = std::make_shared<BooleanCondition>(true);
160
160
Condition_ptr DeadlockCondition::DEADLOCK = std::make_shared<DeadlockCondition>();
163
163
Condition_ptr BooleanCondition::getShared(bool val)
1740
1740
unsigned int p;
1743
1743
uint32_t LessThanOrEqualCondition::distance(DistanceContext& context) const {
1744
1744
return _distance(context, delta<LessThanOrEqualCondition>);
1747
1747
uint32_t LessThanCondition::distance(DistanceContext& context) const {
1748
1748
return _distance(context, delta<LessThanCondition>);
1751
1751
uint32_t NotEqualCondition::distance(DistanceContext& context) const {
1752
1752
return _distance(context, delta<NotEqualCondition>);
1755
1755
uint32_t EqualCondition::distance(DistanceContext& context) const {
1756
1756
return _distance(context, delta<EqualCondition>);
1759
1759
/******************** BIN output ********************/
1761
1761
void LiteralExpr::toBinary(std::ostream& out) const {
1762
1762
out.write("l", sizeof(char));
1763
1763
out.write(reinterpret_cast<const char*>(&_value), sizeof(int));
1766
1766
void UnfoldedIdentifierExpr::toBinary(std::ostream& out) const {
1767
1767
out.write("i", sizeof(char));
1768
out.write(reinterpret_cast<const char*>(&_offsetInMarking), sizeof(int));
1768
out.write(reinterpret_cast<const char*>(&_offsetInMarking), sizeof(int));
1771
1771
void MinusExpr::toBinary(std::ostream& out) const
1773
1773
auto e1 = std::make_shared<PQL::LiteralExpr>(0);
1876
1876
out.write(reinterpret_cast<const char*>(&quant), sizeof(Quantifier));
1877
1877
out.write(reinterpret_cast<const char*>(&value), sizeof(bool));
1880
1880
void UnfoldedUpperBoundsCondition::toBinary(std::ostream& out) const
1882
1882
auto path = getPath();
1883
1883
auto quant = Quantifier::UPPERBOUNDS;
1884
1884
out.write(reinterpret_cast<const char*>(&path), sizeof(Path));
1885
out.write(reinterpret_cast<const char*>(&quant), sizeof(Quantifier));
1885
out.write(reinterpret_cast<const char*>(&quant), sizeof(Quantifier));
1886
1886
uint32_t size = _places.size();
1887
out.write(reinterpret_cast<const char*>(&size), sizeof(uint32_t));
1888
out.write(reinterpret_cast<const char*>(&_max), sizeof(double));
1889
out.write(reinterpret_cast<const char*>(&_offset), sizeof(double));
1887
out.write(reinterpret_cast<const char*>(&size), sizeof(uint32_t));
1888
out.write(reinterpret_cast<const char*>(&_max), sizeof(double));
1889
out.write(reinterpret_cast<const char*>(&_offset), sizeof(double));
1890
1890
for(auto& b : _places)
1892
out.write(reinterpret_cast<const char*>(&b._place), sizeof(uint32_t));
1892
out.write(reinterpret_cast<const char*>(&b._place), sizeof(uint32_t));
1893
1893
out.write(reinterpret_cast<const char*>(&b._max), sizeof(double));
1897
1897
void NotCondition::toBinary(std::ostream& out) const
1899
1899
auto path = getPath();
2103
2103
out << "</next>\n" ; out << "</exists-path>\n";
2106
void AXCondition::toXML(std::ostream& out,uint32_t tabs) const {
2106
void AXCondition::toXML(std::ostream& out,uint32_t tabs) const {
2107
2107
generateTabs(out,tabs) << "<all-paths>\n"; generateTabs(out,tabs+1) << "<next>\n";
2108
_cond->toXML(out,tabs+2);
2108
_cond->toXML(out,tabs+2);
2109
2109
generateTabs(out,tabs+1) << "</next>\n"; generateTabs(out,tabs) << "</all-paths>\n";
2112
void AXCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2112
void AXCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2113
2113
out << "<all-paths>\n" ;out << "<next>\n";
2114
2114
_cond->toCompactXML(out,tabs+2, context);
2115
2115
out << "</next>\n" ; out << "</all-paths>\n";
2118
2118
void EFCondition::toXML(std::ostream& out,uint32_t tabs) const {
2119
2119
generateTabs(out,tabs) << "<exists-path>\n" ; generateTabs(out,tabs+1) << "<finally>\n";
2120
2120
_cond->toXML(out,tabs+2);
2121
2121
generateTabs(out,tabs+1) << "</finally>\n" ; generateTabs(out,tabs) << "</exists-path>\n";
2124
void EFCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2124
void EFCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2125
2125
out << "<exists-path>\n" ;out << "<finally>\n";
2126
2126
_cond->toCompactXML(out,tabs+2, context);
2127
2127
out << "</finally>\n" ; out << "</exists-path>\n";
2130
2130
void AFCondition::toXML(std::ostream& out,uint32_t tabs) const {
2131
2131
generateTabs(out,tabs) << "<all-paths>\n" ; generateTabs(out,tabs+1) << "<finally>\n";
2132
2132
_cond->toXML(out,tabs+2);
2133
2133
generateTabs(out,tabs+1) << "</finally>\n" ; generateTabs(out,tabs) << "</all-paths>\n";
2136
void AFCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2136
void AFCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2137
2137
out << "<all-paths>\n" ;out << "<finally>\n";
2138
2138
_cond->toCompactXML(out,tabs+2, context);
2139
2139
out << "</finally>\n" ; out << "</all-paths>\n";
2142
void EGCondition::toXML(std::ostream& out,uint32_t tabs) const {
2142
void EGCondition::toXML(std::ostream& out,uint32_t tabs) const {
2143
2143
generateTabs(out,tabs) << "<exists-path>\n" ; generateTabs(out,tabs+1) << "<globally>\n";
2144
_cond->toXML(out,tabs+2);
2144
_cond->toXML(out,tabs+2);
2145
2145
generateTabs(out,tabs+1) << "</globally>\n" ; generateTabs(out,tabs) << "</exists-path>\n";
2148
void EGCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2148
void EGCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2149
2149
out << "<exists-path>\n" ;out << "<globally>\n";
2150
2150
_cond->toCompactXML(out,tabs+2, context);
2151
2151
out << "</globally>\n" ; out << "</exists-path>\n";
2154
void AGCondition::toXML(std::ostream& out,uint32_t tabs) const {
2154
void AGCondition::toXML(std::ostream& out,uint32_t tabs) const {
2155
2155
generateTabs(out,tabs) << "<all-paths>\n" ; generateTabs(out,tabs+1) << "<globally>\n";
2156
2156
_cond->toXML(out,tabs+2);
2157
2157
generateTabs(out,tabs+1) << "</globally>\n" ; generateTabs(out,tabs) << "</all-paths>\n";
2160
void AGCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2160
void AGCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2161
2161
out << "<all-paths>\n" ;out << "<globally>\n";
2162
2162
_cond->toCompactXML(out,tabs+2, context);
2163
2163
out << "</globally>\n" ; out << "</all-paths>\n";
2166
2166
void EUCondition::toXML(std::ostream& out,uint32_t tabs) const {
2167
2167
generateTabs(out,tabs) << "<exists-path>\n" ; generateTabs(out,tabs+1) << "<until>\n" ; generateTabs(out,tabs+2) << "<before>\n";
2168
2168
_cond1->toXML(out,tabs+3);
2465
2465
out << "<place>" << c._name << "</place>\n";
2466
2466
out << "</tokens-count>\n";
2467
2467
out << "<integer-constant>" << c._upper << "</integer-constant>\n";
2468
out << "</integer-le>\n";
2468
out << "</integer-le>\n";
2472
2472
out << "</conjunction>\n";
2474
if(_negated) out << "</negation>";
2474
if(_negated) out << "</negation>";
2477
2477
void EqualCondition::toXML(std::ostream& out,uint32_t tabs) const {
2478
2478
generateTabs(out,tabs) << "<integer-eq>\n";
2479
2479
_expr1->toXML(out,tabs+1);
2480
2480
_expr2->toXML(out,tabs+1);
2481
generateTabs(out,tabs) << "</integer-eq>\n";
2481
generateTabs(out,tabs) << "</integer-eq>\n";
2484
void EqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2484
void EqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2485
2485
out << "<integer-eq>\n";
2486
2486
_expr1->toCompactXML(out,tabs, context);
2487
2487
_expr2->toCompactXML(out,tabs, context);
2488
2488
out << "</integer-eq>\n";
2491
2491
void NotEqualCondition::toXML(std::ostream& out,uint32_t tabs) const {
2492
2492
generateTabs(out,tabs) << "<integer-ne>\n";
2493
2493
_expr1->toXML(out,tabs+1);
2494
2494
_expr2->toXML(out,tabs+1);
2495
generateTabs(out,tabs) << "</integer-ne>\n";
2495
generateTabs(out,tabs) << "</integer-ne>\n";
2498
void NotEqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2498
void NotEqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2499
2499
out << "<integer-ne>\n";
2500
2500
_expr1->toCompactXML(out,tabs, context);
2501
2501
_expr2->toCompactXML(out,tabs, context);
2502
2502
out << "</integer-ne>\n";
2505
2505
void LessThanCondition::toXML(std::ostream& out,uint32_t tabs) const {
2506
2506
generateTabs(out,tabs) << "<integer-lt>\n";
2507
2507
_expr1->toXML(out,tabs+1);
2508
2508
_expr2->toXML(out,tabs+1);
2509
generateTabs(out,tabs) << "</integer-lt>\n";
2509
generateTabs(out,tabs) << "</integer-lt>\n";
2512
void LessThanCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2512
void LessThanCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2513
2513
out << "<integer-lt>\n";
2514
2514
_expr1->toCompactXML(out,tabs, context);
2515
2515
_expr2->toCompactXML(out,tabs, context);
2516
2516
out << "</integer-lt>\n";
2519
2519
void LessThanOrEqualCondition::toXML(std::ostream& out,uint32_t tabs) const {
2520
2520
generateTabs(out,tabs) << "<integer-le>\n";
2521
2521
_expr1->toXML(out,tabs+1);
2522
2522
_expr2->toXML(out,tabs+1);
2523
generateTabs(out,tabs) << "</integer-le>\n";
2523
generateTabs(out,tabs) << "</integer-le>\n";
2526
void LessThanOrEqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2526
void LessThanOrEqualCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2527
2527
out << "<integer-le>\n";
2528
2528
_expr1->toCompactXML(out,tabs, context);
2529
2529
_expr2->toCompactXML(out,tabs, context);
2530
2530
out << "</integer-le>\n";
2533
2533
void NotCondition::toXML(std::ostream& out,uint32_t tabs) const {
2535
2535
generateTabs(out,tabs) << "<negation>\n";
2536
2536
_cond->toXML(out,tabs+1);
2537
generateTabs(out,tabs) << "</negation>\n";
2537
generateTabs(out,tabs) << "</negation>\n";
2540
void NotCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2540
void NotCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2541
2541
out << "<negation>\n";
2542
2542
_cond->toCompactXML(out,tabs, context);
2543
2543
out << "</negation>\n";
2546
void BooleanCondition::toXML(std::ostream& out,uint32_t tabs) const {
2547
generateTabs(out,tabs) << "<" <<
2548
(value ? "true" : "false")
2552
void BooleanCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2554
(value ? "true" : "false")
2546
void BooleanCondition::toXML(std::ostream& out,uint32_t tabs) const {
2547
generateTabs(out,tabs) << "<" <<
2548
(value ? "true" : "false")
2552
void BooleanCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2554
(value ? "true" : "false")
2558
2558
void DeadlockCondition::toXML(std::ostream& out,uint32_t tabs) const {
2559
generateTabs(out,tabs) << "<deadlock/>\n";
2559
generateTabs(out,tabs) << "<deadlock/>\n";
2562
void DeadlockCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2562
void DeadlockCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2563
2563
out << "<deadlock/>\n";
2566
2566
void UnfoldedUpperBoundsCondition::toXML(std::ostream& out, uint32_t tabs) const {
2567
2567
generateTabs(out, tabs) << "<place-bound>\n";
2568
2568
for(auto& p : _places)
2570
2570
generateTabs(out, tabs) << "</place-bound>\n";
2573
void UnfoldedUpperBoundsCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2573
void UnfoldedUpperBoundsCondition::toCompactXML(std::ostream& out, uint32_t tabs, AnalysisContext& context) const{
2574
2574
out << "<place-bound>\n";
2575
2575
for(auto& p : _places)
2576
2576
out << "<place>" << p._name << "</place>\n";
2577
out << "</place-bound>\n";
2577
out << "</place-bound>\n";
2580
/******************** Query Simplification ********************/
2580
/******************** Query Simplification ********************/
2582
2582
Member LiteralExpr::constraint(SimplificationContext& context) const {
2583
2583
return Member(_value);
2586
Member memberForPlace(size_t p, SimplificationContext& context)
2586
Member memberForPlace(size_t p, SimplificationContext& context)
2588
2588
std::vector<int> row(context.net()->numberOfTransitions(), 0);
2589
2589
row.shrink_to_fit();
2590
2590
for (size_t t = 0; t < context.net()->numberOfTransitions(); t++) {
2591
2591
row[t] = context.net()->outArc(t, p) - context.net()->inArc(p, t);
2593
return Member(std::move(row), context.marking()[p]);
2593
return Member(std::move(row), context.marking()[p]);
2596
2596
Member UnfoldedIdentifierExpr::constraint(SimplificationContext& context) const {
2597
2597
return memberForPlace(_offsetInMarking, context);
2600
2600
Member CommutativeExpr::commutativeCons(int constant, SimplificationContext& context, std::function<void(Member& a, Member b)> op) const
2720
2720
Retval r = _cond->simplify(context);
2721
2721
return context.negated() ? simplifyAX(r, context) : simplifyEX(r, context);
2724
2724
Retval AXCondition::simplify(SimplificationContext& context) const {
2725
2725
Retval r = _cond->simplify(context);
2726
2726
return context.negated() ? simplifyEX(r, context) : simplifyAX(r, context);
2729
2729
Retval EFCondition::simplify(SimplificationContext& context) const {
2730
2730
Retval r = _cond->simplify(context);
2731
return context.negated() ? simplifyAG(r, context) : simplifyEF(r, context);
2731
return context.negated() ? simplifyAG(r, context) : simplifyEF(r, context);
2734
2734
Retval AFCondition::simplify(SimplificationContext& context) const {
2735
2735
Retval r = _cond->simplify(context);
2736
return context.negated() ? simplifyEG(r, context) : simplifyAF(r, context);
2736
return context.negated() ? simplifyEG(r, context) : simplifyAF(r, context);
2739
2739
Retval EGCondition::simplify(SimplificationContext& context) const {
2740
2740
Retval r = _cond->simplify(context);
2741
return context.negated() ? simplifyAF(r, context) : simplifyEG(r, context);
2741
return context.negated() ? simplifyAF(r, context) : simplifyEG(r, context);
2744
2744
Retval AGCondition::simplify(SimplificationContext& context) const {
2745
2745
Retval r = _cond->simplify(context);
2746
return context.negated() ? simplifyEF(r, context) : simplifyAG(r, context);
2746
return context.negated() ? simplifyEF(r, context) : simplifyAG(r, context);
2749
2749
Retval EUCondition::simplify(SimplificationContext& context) const {
2750
2750
// cannot push negation any further
2751
2751
bool neg = context.negated();
3249
3249
int constant = m2.constant() - m1.constant();
3253
3253
std::make_shared<UnionCollection>(
3254
3254
std::make_shared<SingleProgram>(context.cache(), std::move(m1), constant, Simplification::OP_GT),
3255
3255
std::make_shared<SingleProgram>(context.cache(), std::move(m2), constant, Simplification::OP_LT));
3256
3256
Member m3 = m2;
3257
3257
lps = std::make_shared<SingleProgram>(context.cache(), std::move(m3), constant, Simplification::OP_EQ);
3259
3259
if(context.negated()) lps.swap(neglps);
3262
3262
lps = std::make_shared<SingleProgram>();
3263
3263
neglps = std::make_shared<SingleProgram>();
3266
3266
if (!context.timeout() && !lps->satisfiable(context)) {
3267
3267
return Retval(BooleanCondition::FALSE_CONSTANT);
3269
3269
else if(!context.timeout() && !neglps->satisfiable(context))
3271
return Retval(BooleanCondition::TRUE_CONSTANT);
3271
return Retval(BooleanCondition::TRUE_CONSTANT);
3274
3274
if (context.negated()) {
3275
3275
return Retval(std::make_shared<NotEqualCondition>(_expr1, _expr2), std::move(lps), std::move(neglps));
3506
3505
return reachability;
3509
3508
bool CompareCondition::isReachability(uint32_t depth) const {
3510
3509
return depth > 0;
3513
3512
bool NotCondition::isReachability(uint32_t depth) const {
3514
3513
return _cond->isReachability(depth);
3517
3516
bool BooleanCondition::isReachability(uint32_t depth) const {
3518
3517
return depth > 0;
3521
3520
bool DeadlockCondition::isReachability(uint32_t depth) const {
3522
3521
return depth > 0;
3525
3524
bool UnfoldedUpperBoundsCondition::isReachability(uint32_t depth) const {
3526
3525
return depth > 0;
3529
3528
/******************** Prepare Reachability Queries ********************/
3531
3530
Condition_ptr EXCondition::prepareForReachability(bool negated) const {
3532
3531
return nullptr;
3535
3534
Condition_ptr EGCondition::prepareForReachability(bool negated) const {
3536
3535
return nullptr;
3539
3538
Condition_ptr EFCondition::prepareForReachability(bool negated) const {
3540
3539
_cond->setInvariant(negated);
3544
3543
Condition_ptr AXCondition::prepareForReachability(bool negated) const {
3545
3544
return nullptr;
3548
3547
Condition_ptr AGCondition::prepareForReachability(bool negated) const {
3549
3548
Condition_ptr cond = std::make_shared<NotCondition>(_cond);
3550
3549
cond->setInvariant(!negated);
3554
3553
Condition_ptr AFCondition::prepareForReachability(bool negated) const {
3555
3554
return nullptr;
3558
3557
Condition_ptr ACondition::prepareForReachability(bool negated) const {
3559
3558
auto g = std::dynamic_pointer_cast<GCondition>(_cond);
3561
return AGCondition((*g)[0]).prepareForReachability(negated);
3564
// ugly hacking for `A true`.
3565
auto bcond = std::dynamic_pointer_cast<BooleanCondition>(_cond);
3569
else return nullptr;
3559
return g ? AGCondition((*g)[0]).prepareForReachability(negated) : nullptr;
3573
3562
Condition_ptr ECondition::prepareForReachability(bool negated) const {
4217
4206
if(negated == noteq) return std::make_shared<EqualCondition>((*org)[0], (*org)[1]);
4218
4207
else return std::make_shared<NotEqualCondition>((*org)[0], (*org)[1]);
4221
4210
Condition_ptr NotEqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) {
4222
4211
return initialMarkingRW([&]() -> Condition_ptr {
4223
4212
return pushEqual(this, negated, true, context);
4224
4213
}, stats, context, nested, negated, initrw);
4228
4217
Condition_ptr EqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) {
4229
4218
return initialMarkingRW([&]() -> Condition_ptr {
4230
4219
return pushEqual(this, negated, false, context);
4231
4220
}, stats, context, nested, negated, initrw);
4234
4223
Condition_ptr BooleanCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) {
4235
4224
return initialMarkingRW([&]() -> Condition_ptr {
4236
4225
if(negated) return getShared(!value);
4237
4226
else return getShared(value);
4238
4227
}, stats, context, nested, negated, initrw);
4241
4230
Condition_ptr DeadlockCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) {
4242
4231
return initialMarkingRW([&]() -> Condition_ptr {
4243
4232
if(negated) return std::make_shared<NotCondition>(DEADLOCK);
4244
4233
else return DEADLOCK;
4245
4234
}, stats, context, nested, negated, initrw);
4248
4237
Condition_ptr UnfoldedUpperBoundsCondition::pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) {