1
/* PeTe - Petri Engine exTremE
2
* Copyright (C) 2011 Jonas Finnemann Jensen <jopsen@gmail.com>,
3
* Thomas Søndersø Nielsen <primogens@gmail.com>,
4
* Lars Kærlund Østergaard <larsko@gmail.com>,
5
* Peter Gjøl Jensen <root@petergjoel.dk>
7
* This program is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation, either version 3 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
29
#include "..//Simplification/Member.h"
30
#include "../Simplification/LinearPrograms.h"
31
#include "../Simplification/Retval.h"
33
using namespace PetriEngine::Simplification;
35
namespace PetriEngine {
38
std::string generateTabs(uint32_t tabs);
39
class CompareCondition;
41
/******************** EXPRESSIONS ********************/
43
/** Base class for all binary expressions */
44
class NaryExpr : public Expr {
49
NaryExpr(std::vector<Expr_ptr>&& exprs) : _exprs(std::move(exprs)) {
51
virtual void analyze(AnalysisContext& context) override;
52
int evaluate(const EvaluationContext& context) override;
53
int formulaSize() const override{
55
for(auto& e : _exprs) sum += e->formulaSize();
58
void toString(std::ostream&) const override;
59
bool placeFree() const override;
60
auto& expressions() const { return _exprs; }
62
virtual int apply(int v1, int v2) const = 0;
63
virtual std::string op() const = 0;
64
std::vector<Expr_ptr> _exprs;
65
virtual int32_t preOp(const EvaluationContext& context) const;
71
class CommutativeExpr : public NaryExpr
74
friend CompareCondition;
75
virtual void analyze(AnalysisContext& context) override;
76
int evaluate(const EvaluationContext& context) override;
77
void toBinary(std::ostream&) const override;
78
int formulaSize() const override{
79
size_t sum = _ids.size();
80
for(auto& e : _exprs) sum += e->formulaSize();
83
void toString(std::ostream&) const override;
84
bool placeFree() const override;
85
auto constant() const { return _constant; }
86
auto& places() const { return _ids; }
88
CommutativeExpr(int constant): _constant(constant) {};
89
void init(std::vector<Expr_ptr>&& exprs);
90
virtual int32_t preOp(const EvaluationContext& context) const override;
92
std::vector<std::pair<uint32_t,std::string>> _ids;
93
Member commutativeCons(int constant, SimplificationContext& context, std::function<void(Member& a, Member b)> op) const;
96
/** Binary plus expression */
97
class PlusExpr : public CommutativeExpr {
100
PlusExpr(std::vector<Expr_ptr>&& exprs, bool tk = false);
102
Expr::Types type() const override;
103
Member constraint(SimplificationContext& context) const override;
104
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
106
void incr(ReducingSuccessorGenerator& generator) const override;
107
void decr(ReducingSuccessorGenerator& generator) const override;
108
void visit(Visitor& visitor) const override;
110
int apply(int v1, int v2) const override;
111
//int binaryOp() const;
112
std::string op() const override;
115
/** Binary minus expression */
116
class SubtractExpr : public NaryExpr {
119
SubtractExpr(std::vector<Expr_ptr>&& exprs) : NaryExpr(std::move(exprs))
122
Expr::Types type() const override;
123
Member constraint(SimplificationContext& context) const override;
124
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
125
void incr(ReducingSuccessorGenerator& generator) const override;
126
void decr(ReducingSuccessorGenerator& generator) const override;
127
void toBinary(std::ostream&) const override;
128
void visit(Visitor& visitor) const override;
130
int apply(int v1, int v2) const override;
131
//int binaryOp() const;
132
std::string op() const override;
135
/** Binary multiplication expression **/
136
class MultiplyExpr : public CommutativeExpr {
139
MultiplyExpr(std::vector<Expr_ptr>&& exprs);
140
Expr::Types type() const override;
141
Member constraint(SimplificationContext& context) const override;
142
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
143
void incr(ReducingSuccessorGenerator& generator) const override;
144
void decr(ReducingSuccessorGenerator& generator) const override;
145
void visit(Visitor& visitor) const override;
147
int apply(int v1, int v2) const override;
148
//int binaryOp() const;
149
std::string op() const override;
152
/** Unary minus expression*/
153
class MinusExpr : public Expr {
156
MinusExpr(const Expr_ptr expr) {
159
void analyze(AnalysisContext& context) override;
160
int evaluate(const EvaluationContext& context) override;
161
void toString(std::ostream&) const override;
162
Expr::Types type() const override;
163
Member constraint(SimplificationContext& context) const override;
164
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
165
void toBinary(std::ostream&) const override;
166
void incr(ReducingSuccessorGenerator& generator) const override;
167
void decr(ReducingSuccessorGenerator& generator) const override;
168
void visit(Visitor& visitor) const override;
169
int formulaSize() const override{
170
return _expr->formulaSize() + 1;
172
bool placeFree() const override;
173
const Expr_ptr& operator[](size_t i) const { return _expr; };
178
/** Literal integer value expression */
179
class LiteralExpr : public Expr {
182
LiteralExpr(int value) : _value(value) {
184
void analyze(AnalysisContext& context) override;
185
int evaluate(const EvaluationContext& context) override;
186
void toString(std::ostream&) const override;
187
Expr::Types type() const override;
188
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
189
void toBinary(std::ostream&) const override;
190
void incr(ReducingSuccessorGenerator& generator) const override;
191
void decr(ReducingSuccessorGenerator& generator) const override;
192
void visit(Visitor& visitor) const override;
193
int formulaSize() const override{
199
Member constraint(SimplificationContext& context) const override;
200
bool placeFree() const override { return true; }
206
class IdentifierExpr : public Expr {
208
IdentifierExpr(const std::string& name) : _name(name) {}
209
void analyze(AnalysisContext& context) override;
210
int evaluate(const EvaluationContext& context) override {
211
return _compiled->evaluate(context);
213
void toString(std::ostream& os) const override {
215
_compiled->toString(os);
219
Expr::Types type() const override {
220
if(_compiled) return _compiled->type();
221
return Expr::IdentifierExpr;
223
void toXML(std::ostream& os, uint32_t tabs, bool tokencount = false) const override {
224
_compiled->toXML(os, tabs, tokencount);
226
void incr(ReducingSuccessorGenerator& generator) const override {
227
_compiled->incr(generator);
229
void decr(ReducingSuccessorGenerator& generator) const override {
230
_compiled->decr(generator);
232
int formulaSize() const override {
233
if(_compiled) return _compiled->formulaSize();
236
virtual bool placeFree() const override {
237
if(_compiled) return _compiled->placeFree();
241
Member constraint(SimplificationContext& context) const override {
242
return _compiled->constraint(context);
245
void toBinary(std::ostream& s) const override {
246
_compiled->toBinary(s);
248
void visit(Visitor& visitor) const override;
254
/** Identifier expression */
255
class UnfoldedIdentifierExpr : public Expr {
257
UnfoldedIdentifierExpr(const std::string& name, int offest)
258
: _offsetInMarking(offest), _name(name) {
261
UnfoldedIdentifierExpr(const std::string& name) : UnfoldedIdentifierExpr(name, -1) {
264
void analyze(AnalysisContext& context) override;
265
int evaluate(const EvaluationContext& context) override;
266
void toString(std::ostream&) const override;
267
Expr::Types type() const override;
268
void toXML(std::ostream&, uint32_t tabs, bool tokencount = false) const override;
269
void toBinary(std::ostream&) const override;
270
void incr(ReducingSuccessorGenerator& generator) const override;
271
void decr(ReducingSuccessorGenerator& generator) const override;
272
int formulaSize() const override{
275
/** Offset in marking or valuation */
277
return _offsetInMarking;
279
const std::string& name()
283
Member constraint(SimplificationContext& context) const override;
284
bool placeFree() const override { return false; }
285
void visit(Visitor& visitor) const override;
287
/** Offset in marking, -1 if undefined, should be resolved during analysis */
288
int _offsetInMarking;
289
/** Identifier text */
293
class ShallowCondition : public Condition
295
Result evaluate(const EvaluationContext& context) override
296
{ return _compiled->evaluate(context); }
297
Result evalAndSet(const EvaluationContext& context) override
298
{ return _compiled->evalAndSet(context); }
299
uint32_t distance(DistanceContext& context) const override
300
{ return _compiled->distance(context); }
301
void toTAPAALQuery(std::ostream& out,TAPAALConditionExportContext& context) const override
302
{ _compiled->toTAPAALQuery(out, context); }
303
void toBinary(std::ostream& out) const override
304
{ return _compiled->toBinary(out); }
305
Retval simplify(SimplificationContext& context) const override
306
{ return _compiled->simplify(context); }
307
Condition_ptr prepareForReachability(bool negated) const override
308
{ return _compiled->prepareForReachability(negated); }
309
bool isReachability(uint32_t depth) const override
310
{ return _compiled->isReachability(depth); }
312
void toXML(std::ostream& out, uint32_t tabs) const override
313
{ _compiled->toXML(out, tabs); }
314
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override
315
{ _compiled->findInteresting(generator, negated);}
316
Quantifier getQuantifier() const override
317
{ return _compiled->getQuantifier(); }
318
Path getPath() const override { return _compiled->getPath(); }
319
CTLType getQueryType() const override { return _compiled->getQueryType(); }
320
bool containsNext() const override { return _compiled->containsNext(); }
321
bool nestedDeadlock() const override { return _compiled->nestedDeadlock(); }
323
virtual z3::expr encodeSat(const PetriNet& net, z3::context& context, std::vector<int32_t>& uses, std::vector<bool>& incremented) const
324
{ return _compiled->encodeSat(net, context, uses, incremented); }
326
int formulaSize() const override{
327
return _compiled->formulaSize();
330
virtual Condition_ptr pushNegation(negstat_t& neg, const EvaluationContext& context, bool nested, bool negated, bool initrw) override
333
return _compiled->pushNegation(neg, context, nested, negated, initrw);
336
return std::static_pointer_cast<Condition>(std::make_shared<NotCondition>(clone()));
342
void analyze(AnalysisContext& context) override
344
if (_compiled) _compiled->analyze(context);
345
else _analyze(context);
347
void toString(std::ostream &out) const {
348
if (_compiled) _compiled->toString(out);
353
virtual void _analyze(AnalysisContext& context) = 0;
354
virtual void _toString(std::ostream& out) const = 0;
355
virtual Condition_ptr clone() = 0;
356
Condition_ptr _compiled = nullptr;
360
class NotCondition : public Condition {
363
NotCondition(const Condition_ptr cond) {
365
_temporal = _cond->isTemporal();
366
_loop_sensitive = _cond->isLoopSensitive();
368
int formulaSize() const override{
369
return _cond->formulaSize() + 1;
371
void analyze(AnalysisContext& context) override;
372
Result evaluate(const EvaluationContext& context) override;
373
Result evalAndSet(const EvaluationContext& context) override;
374
void visit(Visitor&) const override;
375
uint32_t distance(DistanceContext& context) const override;
376
void toString(std::ostream&) const override;
377
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
378
Retval simplify(SimplificationContext& context) const override;
379
bool isReachability(uint32_t depth) const override;
380
Condition_ptr prepareForReachability(bool negated) const override;
381
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
382
void toXML(std::ostream&, uint32_t tabs) const override;
383
void toBinary(std::ostream&) const override;
384
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
385
Quantifier getQuantifier() const override { return Quantifier::NEG; }
386
Path getPath() const override { return Path::pError; }
387
CTLType getQueryType() const override { return CTLType::LOPERATOR; }
388
const Condition_ptr& operator[](size_t i) const { return _cond; };
389
virtual bool isTemporal() const override { return _temporal;}
390
bool containsNext() const override { return _cond->containsNext(); }
391
bool nestedDeadlock() const override { return _cond->nestedDeadlock(); }
394
bool _temporal = false;
398
/******************** TEMPORAL OPERATORS ********************/
400
class QuantifierCondition : public Condition
403
virtual bool isTemporal() const override { return true;}
404
CTLType getQueryType() const override { return CTLType::PATHQEURY; }
405
virtual const Condition_ptr& operator[] (size_t i) const = 0;
408
class SimpleQuantifierCondition : public QuantifierCondition {
410
SimpleQuantifierCondition(const Condition_ptr cond) {
412
_loop_sensitive = cond->isLoopSensitive();
414
int formulaSize() const override{
415
return _cond->formulaSize() + 1;
418
void analyze(AnalysisContext& context) override;
419
Result evaluate(const EvaluationContext& context) override;
420
Result evalAndSet(const EvaluationContext& context) override;
421
void toString(std::ostream&) const override;
422
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
423
void toBinary(std::ostream& out) const override;
424
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
425
virtual const Condition_ptr& operator[] (size_t i) const override { return _cond;}
426
virtual bool containsNext() const override { return _cond->containsNext(); }
427
bool nestedDeadlock() const override { return _cond->nestedDeadlock(); }
429
virtual std::string op() const = 0;
435
class EXCondition : public SimpleQuantifierCondition {
437
using SimpleQuantifierCondition::SimpleQuantifierCondition;
438
Retval simplify(SimplificationContext& context) const override;
439
bool isReachability(uint32_t depth) const override;
440
Condition_ptr prepareForReachability(bool negated) const override;
441
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
442
void toXML(std::ostream&, uint32_t tabs) const override;
443
Quantifier getQuantifier() const override { return Quantifier::E; }
444
Path getPath() const override { return Path::X; }
445
uint32_t distance(DistanceContext& context) const override;
446
bool containsNext() const override { return true; }
447
virtual bool isLoopSensitive() const override { return true; }
448
void visit(Visitor&) const override;
450
std::string op() const override;
453
class EGCondition : public SimpleQuantifierCondition {
455
using SimpleQuantifierCondition::SimpleQuantifierCondition;
457
Retval simplify(SimplificationContext& context) const override;
458
bool isReachability(uint32_t depth) const override;
459
Condition_ptr prepareForReachability(bool negated) const override;
460
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
461
void toXML(std::ostream&, uint32_t tabs) const override;
462
Quantifier getQuantifier() const override { return Quantifier::E; }
463
Path getPath() const override { return Path::G; }
464
uint32_t distance(DistanceContext& context) const override;
465
Result evaluate(const EvaluationContext& context) override;
466
Result evalAndSet(const EvaluationContext& context) override;
467
virtual bool isLoopSensitive() const override { return true; }
468
void visit(Visitor&) const override;
470
std::string op() const override;
473
class EFCondition : public SimpleQuantifierCondition {
475
using SimpleQuantifierCondition::SimpleQuantifierCondition;
477
Retval simplify(SimplificationContext& context) const override;
478
bool isReachability(uint32_t depth) const override;
479
Condition_ptr prepareForReachability(bool negated) const override;
480
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
481
void toXML(std::ostream&, uint32_t tabs) const override;
482
Quantifier getQuantifier() const override { return Quantifier::E; }
483
Path getPath() const override { return Path::F; }
484
uint32_t distance(DistanceContext& context) const override;
485
Result evaluate(const EvaluationContext& context) override;
486
Result evalAndSet(const EvaluationContext& context) override;
487
void visit(Visitor&) const override;
489
std::string op() const override;
492
class AXCondition : public SimpleQuantifierCondition {
494
using SimpleQuantifierCondition::SimpleQuantifierCondition;
495
Retval simplify(SimplificationContext& context) const override;
496
bool isReachability(uint32_t depth) const override;
497
Condition_ptr prepareForReachability(bool negated) const override;
498
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
499
void toXML(std::ostream&, uint32_t tabs) const override;
500
Quantifier getQuantifier() const override { return Quantifier::A; }
501
Path getPath() const override { return Path::X; }
502
uint32_t distance(DistanceContext& context) const override;
503
bool containsNext() const override { return true; }
504
virtual bool isLoopSensitive() const override { return true; }
505
void visit(Visitor&) const override;
507
std::string op() const override;
510
class AGCondition : public SimpleQuantifierCondition {
512
using SimpleQuantifierCondition::SimpleQuantifierCondition;
513
Retval simplify(SimplificationContext& context) const override;
514
bool isReachability(uint32_t depth) const override;
515
Condition_ptr prepareForReachability(bool negated) const override;
516
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
517
void toXML(std::ostream&, uint32_t tabs) const override;
518
Quantifier getQuantifier() const override { return Quantifier::A; }
519
Path getPath() const override { return Path::G; }
520
uint32_t distance(DistanceContext& context) const override;
521
Result evaluate(const EvaluationContext& context) override;
522
Result evalAndSet(const EvaluationContext& context) override;
523
void visit(Visitor&) const override;
525
std::string op() const override;
528
class AFCondition : public SimpleQuantifierCondition {
530
using SimpleQuantifierCondition::SimpleQuantifierCondition;
531
Retval simplify(SimplificationContext& context) const override;
532
bool isReachability(uint32_t depth) const override;
533
Condition_ptr prepareForReachability(bool negated) const override;
534
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
535
void toXML(std::ostream&, uint32_t tabs) const override;
536
Quantifier getQuantifier() const override { return Quantifier::A; }
537
Path getPath() const override { return Path::F; }
538
uint32_t distance(DistanceContext& context) const override;
539
Result evaluate(const EvaluationContext& context) override;
540
Result evalAndSet(const EvaluationContext& context) override;
541
void visit(Visitor&) const override;
542
virtual bool isLoopSensitive() const override { return true; }
544
std::string op() const override;
547
class UntilCondition : public QuantifierCondition {
549
UntilCondition(const Condition_ptr cond1, const Condition_ptr cond2) {
552
_loop_sensitive = _cond1->isLoopSensitive() || _cond2->isLoopSensitive();
554
int formulaSize() const override{
555
return _cond1->formulaSize() + _cond2->formulaSize() + 1;
558
void analyze(AnalysisContext& context) override;
559
Result evaluate(const EvaluationContext& context) override;
560
void toString(std::ostream&) const override;
561
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
562
void toBinary(std::ostream& out) const override;
563
bool isReachability(uint32_t depth) const override;
564
Condition_ptr prepareForReachability(bool negated) const override;
565
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
566
Result evalAndSet(const EvaluationContext& context) override;
568
virtual const Condition_ptr& operator[] (size_t i) const override
569
{ if(i == 0) return _cond1; return _cond2;}
570
Path getPath() const override
572
bool containsNext() const override { return _cond1->containsNext() || _cond2->containsNext(); }
573
bool nestedDeadlock() const override { return _cond1->nestedDeadlock() || _cond2->nestedDeadlock(); }
575
virtual std::string op() const = 0;
578
Condition_ptr _cond1;
579
Condition_ptr _cond2;
582
class EUCondition : public UntilCondition {
584
using UntilCondition::UntilCondition;
585
Retval simplify(SimplificationContext& context) const override;
586
Quantifier getQuantifier() const override { return Quantifier::E; }
587
void visit(Visitor&) const override;
588
uint32_t distance(DistanceContext& context) const override;
589
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
590
void toXML(std::ostream&, uint32_t tabs) const override;
593
std::string op() const override;
596
class AUCondition : public UntilCondition {
598
using UntilCondition::UntilCondition;
599
Retval simplify(SimplificationContext& context) const override;
600
Quantifier getQuantifier() const override { return Quantifier::A; }
601
void visit(Visitor&) const override;
602
uint32_t distance(DistanceContext& context) const override;
603
void toXML(std::ostream&, uint32_t tabs) const override;
604
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
605
virtual bool isLoopSensitive() const override { return true; }
607
std::string op() const override;
610
/******************** CONDITIONS ********************/
612
class UnfoldedFireableCondition : public ShallowCondition {
614
UnfoldedFireableCondition(const std::string& tname) : ShallowCondition(), _name(tname) {};
615
Condition_ptr pushNegation(negstat_t& stat, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
616
void visit(Visitor&) const override;
618
void _analyze(AnalysisContext& context) override;
619
virtual void _toString(std::ostream& out) const;
620
Condition_ptr clone() { return std::make_shared<UnfoldedFireableCondition>(_name); }
622
const std::string _name;
625
class FireableCondition : public ShallowCondition {
627
FireableCondition(const std::string& tname) : _name(tname) {};
628
Condition_ptr pushNegation(negstat_t& stat, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
629
void visit(Visitor&) const override;
631
void _analyze(AnalysisContext& context) override;
632
virtual void _toString(std::ostream& out) const;
633
Condition_ptr clone() { return std::make_shared<FireableCondition>(_name); }
635
const std::string _name;
638
/* Logical conditon */
639
class LogicalCondition : public Condition {
641
int formulaSize() const override {
643
for(auto& c : _conds) i += c->formulaSize();
646
void analyze(AnalysisContext& context) override;
648
uint32_t distance(DistanceContext& context) const override;
649
void toString(std::ostream&) const override;
650
void toBinary(std::ostream& out) const override;
651
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
652
bool isReachability(uint32_t depth) const override;
653
Condition_ptr prepareForReachability(bool negated) const override;
654
const Condition_ptr& operator[](size_t i) const
658
CTLType getQueryType() const override { return CTLType::LOPERATOR; }
659
Path getPath() const override { return Path::pError; }
661
bool isTemporal() const override
665
auto begin() { return _conds.begin(); }
666
auto end() { return _conds.end(); }
667
auto begin() const { return _conds.begin(); }
668
auto end() const { return _conds.end(); }
669
bool empty() const { return _conds.size() == 0; }
670
bool singular() const { return _conds.size() == 1; }
671
size_t size() const { return _conds.size(); }
672
bool containsNext() const override
673
{ return std::any_of(begin(), end(), [](auto& a){return a->containsNext();}); }
674
bool nestedDeadlock() const override;
677
LogicalCondition() {};
678
Retval simplifyOr(SimplificationContext& context) const;
679
Retval simplifyAnd(SimplificationContext& context) const;
682
virtual uint32_t delta(uint32_t d1, uint32_t d2, const DistanceContext& context) const = 0;
683
virtual std::string op() const = 0;
686
bool _temporal = false;
687
std::vector<Condition_ptr> _conds;
690
/* Conjunctive and condition */
691
class AndCondition : public LogicalCondition {
694
AndCondition(std::vector<Condition_ptr>&& conds);
696
AndCondition(const std::vector<Condition_ptr>& conds);
698
AndCondition(Condition_ptr left, Condition_ptr right);
700
Retval simplify(SimplificationContext& context) const override;
701
Result evaluate(const EvaluationContext& context) override;
702
Result evalAndSet(const EvaluationContext& context) override;
703
void visit(Visitor&) const override;
704
void toXML(std::ostream&, uint32_t tabs) const override;
705
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
706
Quantifier getQuantifier() const override { return Quantifier::AND; }
707
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
709
//int logicalOp() const;
710
uint32_t delta(uint32_t d1, uint32_t d2, const DistanceContext& context) const override;
711
std::string op() const override;
714
/* Disjunctive or conditon */
715
class OrCondition : public LogicalCondition {
718
OrCondition(std::vector<Condition_ptr>&& conds);
720
OrCondition(const std::vector<Condition_ptr>& conds);
722
OrCondition(Condition_ptr left, Condition_ptr right);
724
Retval simplify(SimplificationContext& context) const override;
725
Result evaluate(const EvaluationContext& context) override;
726
Result evalAndSet(const EvaluationContext& context) override;
727
void visit(Visitor&) const override;
728
void toXML(std::ostream&, uint32_t tabs) const override;
729
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
730
Quantifier getQuantifier() const override { return Quantifier::OR; }
731
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
733
//int logicalOp() const;
734
uint32_t delta(uint32_t d1, uint32_t d2, const DistanceContext& context) const override;
735
std::string op() const override;
738
class CompareConjunction : public Condition
743
uint32_t _upper = std::numeric_limits<uint32_t>::max();
746
bool operator<(const cons_t& other) const
748
return _place < other._place;
753
if(_lower == 0 && _upper == std::numeric_limits<uint32_t>::max())
755
assert(_lower == 0 || _upper == std::numeric_limits<uint32_t>::max());
759
_upper = std::numeric_limits<uint32_t>::max();
761
else if(_upper == std::numeric_limits<uint32_t>::max())
772
void intersect(const cons_t& other)
774
_lower = std::max(_lower, other._lower);
775
_upper = std::min(_upper, other._upper);
779
CompareConjunction(bool negated = false)
780
: _negated(false) {};
781
friend FireableCondition;
782
CompareConjunction(const std::vector<cons_t>&& cons, bool negated)
783
: _constraints(cons), _negated(negated) {};
784
CompareConjunction(const std::vector<Condition_ptr>&, bool negated);
785
CompareConjunction(const CompareConjunction& other, bool negated = false)
786
: _constraints(other._constraints), _negated(other._negated != negated)
790
void merge(const CompareConjunction& other);
791
void merge(const std::vector<Condition_ptr>&, bool negated);
793
int formulaSize() const override{
795
for(auto& c : _constraints)
797
assert(c._place >= 0);
798
if(c._lower == c._upper) ++sum;
800
if(c._lower != 0) ++sum;
801
if(c._upper != std::numeric_limits<uint32_t>::max()) ++sum;
804
if(sum == 1) return 2;
805
else return (sum*2) + 1;
807
void analyze(AnalysisContext& context) override;
808
uint32_t distance(DistanceContext& context) const override;
809
void toString(std::ostream& stream) const override;
810
void toTAPAALQuery(std::ostream& stream,TAPAALConditionExportContext& context) const override;
811
void toBinary(std::ostream& out) const override;
812
bool isReachability(uint32_t depth) const override { return depth > 0; };
813
Condition_ptr prepareForReachability(bool negated) const override;
814
CTLType getQueryType() const override { return CTLType::LOPERATOR; }
815
Path getPath() const override { return Path::pError; }
816
virtual void toXML(std::ostream& stream, uint32_t tabs) const override;
817
Retval simplify(SimplificationContext& context) const override;
818
Result evaluate(const EvaluationContext& context) override;
819
Result evalAndSet(const EvaluationContext& context) override;
820
void visit(Visitor&) const override;
821
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
822
Quantifier getQuantifier() const override { return _negated ? Quantifier::OR : Quantifier::AND; }
823
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
824
bool isNegated() const { return _negated; }
825
bool singular() const
827
return _constraints.size() == 1 &&
828
(_constraints[0]._lower == 0 ||
829
_constraints[0]._upper == std::numeric_limits<uint32_t>::max());
831
bool containsNext() const override { return false;}
832
bool nestedDeadlock() const override { return false; }
833
const std::vector<cons_t>& constraints() const { return _constraints; }
834
std::vector<cons_t>::const_iterator begin() const { return _constraints.begin(); }
835
std::vector<cons_t>::const_iterator end() const { return _constraints.end(); }
837
std::vector<cons_t> _constraints;
838
bool _negated = false;
842
/* Comparison conditon */
843
class CompareCondition : public Condition {
846
CompareCondition(const Expr_ptr expr1, const Expr_ptr expr2)
847
: _expr1(expr1), _expr2(expr2) {}
849
int formulaSize() const override{
850
return _expr1->formulaSize() + _expr2->formulaSize() + 1;
852
void analyze(AnalysisContext& context) override;
853
Result evaluate(const EvaluationContext& context) override;
854
Result evalAndSet(const EvaluationContext& context) override;
855
void toString(std::ostream&) const override;
856
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
857
void toBinary(std::ostream& out) const override;
858
bool isReachability(uint32_t depth) const override;
859
Condition_ptr prepareForReachability(bool negated) const override;
860
Quantifier getQuantifier() const override { return Quantifier::EMPTY; }
861
Path getPath() const override { return Path::pError; }
862
CTLType getQueryType() const override { return CTLType::EVAL; }
863
const Expr_ptr& operator[](uint32_t id) const
865
if(id == 0) return _expr1;
868
bool containsNext() const override { return false; }
869
bool nestedDeadlock() const override { return false; }
870
bool isTrivial() const;
872
uint32_t _distance(DistanceContext& c,
873
std::function<uint32_t(uint32_t, uint32_t, bool)> d) const
875
return d(_expr1->evaluate(c), _expr2->evaluate(c), c.negated());
878
virtual bool apply(int v1, int v2) const = 0;
879
virtual std::string op() const = 0;
880
/** Operator when exported to TAPAAL */
881
virtual std::string opTAPAAL() const = 0;
882
/** Swapped operator when exported to TAPAAL, e.g. operator when operands are swapped */
883
virtual std::string sopTAPAAL() const = 0;
892
uint32_t delta(int v1, int v2, bool negated)
895
class EqualCondition : public CompareCondition {
898
using CompareCondition::CompareCondition;
899
Retval simplify(SimplificationContext& context) const override;
900
void toXML(std::ostream&, uint32_t tabs) const override;
901
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
902
uint32_t distance(DistanceContext& context) const override;
903
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
904
void visit(Visitor&) const override;
906
bool apply(int v1, int v2) const override;
907
std::string op() const override;
908
std::string opTAPAAL() const override;
909
std::string sopTAPAAL() const override;
912
/* None equality conditon */
913
class NotEqualCondition : public CompareCondition {
916
using CompareCondition::CompareCondition;
917
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
918
Retval simplify(SimplificationContext& context) const override;
919
void toXML(std::ostream&, uint32_t tabs) const override;
920
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
921
uint32_t distance(DistanceContext& context) const override;
922
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
923
void visit(Visitor&) const override;
925
bool apply(int v1, int v2) const override;
926
std::string op() const override;
927
std::string opTAPAAL() const override;
928
std::string sopTAPAAL() const override;
931
/* Less-than conditon */
932
class LessThanCondition : public CompareCondition {
935
using CompareCondition::CompareCondition;
936
Retval simplify(SimplificationContext& context) const override;
937
void toXML(std::ostream&, uint32_t tabs) const override;
938
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
939
uint32_t distance(DistanceContext& context) const override;
940
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
941
void visit(Visitor&) const override;
943
bool apply(int v1, int v2) const override;
944
std::string op() const override;
945
std::string opTAPAAL() const override;
946
std::string sopTAPAAL() const override;
949
/* Less-than-or-equal conditon */
950
class LessThanOrEqualCondition : public CompareCondition {
953
using CompareCondition::CompareCondition;
954
Retval simplify(SimplificationContext& context) const override;
955
void toXML(std::ostream&, uint32_t tabs) const override;
956
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
957
uint32_t distance(DistanceContext& context) const override;
958
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
959
void visit(Visitor&) const override;
961
bool apply(int v1, int v2) const override;
962
std::string op() const override;
963
std::string opTAPAAL() const override;
964
std::string sopTAPAAL() const override;
967
/* Greater-than conditon */
968
class GreaterThanCondition : public CompareCondition {
971
using CompareCondition::CompareCondition;
972
Retval simplify(SimplificationContext& context) const override;
973
void toXML(std::ostream&, uint32_t tabs) const override;
974
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
975
uint32_t distance(DistanceContext& context) const override;
976
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
977
void visit(Visitor&) const override;
979
bool apply(int v1, int v2) const override;
980
std::string op() const override;
981
std::string opTAPAAL() const override;
982
std::string sopTAPAAL() const override;
985
/* Greater-than-or-equal conditon */
986
class GreaterThanOrEqualCondition : public CompareCondition {
988
using CompareCondition::CompareCondition;
989
Retval simplify(SimplificationContext& context) const override;
990
void toXML(std::ostream&, uint32_t tabs) const override;
991
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
992
uint32_t distance(DistanceContext& context) const override;
993
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
994
void visit(Visitor&) const override;
996
bool apply(int v1, int v2) const override;
997
std::string op() const override;
998
std::string opTAPAAL() const override;
999
std::string sopTAPAAL() const override;
1002
/* Bool condition */
1003
class BooleanCondition : public Condition {
1006
BooleanCondition(bool value) : _value(value) {
1013
int formulaSize() const override{
1016
void analyze(AnalysisContext& context) override;
1017
Result evaluate(const EvaluationContext& context) override;
1018
Result evalAndSet(const EvaluationContext& context) override;
1019
void visit(Visitor&) const override;
1020
uint32_t distance(DistanceContext& context) const override;
1021
static Condition_ptr TRUE_CONSTANT;
1022
static Condition_ptr FALSE_CONSTANT;
1023
void toString(std::ostream&) const override;
1024
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
1025
static Condition_ptr getShared(bool val);
1026
Retval simplify(SimplificationContext& context) const override;
1027
bool isReachability(uint32_t depth) const override;
1028
Condition_ptr prepareForReachability(bool negated) const override;
1029
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
1030
void toXML(std::ostream&, uint32_t tabs) const override;
1031
void toBinary(std::ostream&) const override;
1032
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
1033
Quantifier getQuantifier() const override { return Quantifier::EMPTY; }
1034
Path getPath() const override { return Path::pError; }
1035
CTLType getQueryType() const override { return CTLType::EVAL; }
1036
bool containsNext() const override { return false; }
1037
bool nestedDeadlock() const override { return false; }
1042
/* Deadlock condition */
1043
class DeadlockCondition : public Condition {
1046
DeadlockCondition() {
1047
_loop_sensitive = true;
1049
int formulaSize() const override{
1052
void analyze(AnalysisContext& context) override;
1053
Result evaluate(const EvaluationContext& context) override;
1054
Result evalAndSet(const EvaluationContext& context) override;
1055
void visit(Visitor&) const override;
1056
uint32_t distance(DistanceContext& context) const override;
1057
void toString(std::ostream&) const override;
1058
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
1059
Retval simplify(SimplificationContext& context) const override;
1060
bool isReachability(uint32_t depth) const override;
1061
Condition_ptr prepareForReachability(bool negated) const override;
1062
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
1063
void toXML(std::ostream&, uint32_t tabs) const override;
1064
void toBinary(std::ostream&) const override;
1065
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
1066
static Condition_ptr DEADLOCK;
1067
Quantifier getQuantifier() const override { return Quantifier::DEADLOCK; }
1068
Path getPath() const override { return Path::pError; }
1069
CTLType getQueryType() const override { return CTLType::EVAL; }
1070
bool containsNext() const override { return false; }
1071
bool nestedDeadlock() const override { return false; }
1074
class KSafeCondition : public ShallowCondition
1077
KSafeCondition(const Expr_ptr& expr1) : _bound(expr1)
1081
void _analyze(AnalysisContext& context) override;
1082
void _toString(std::ostream& out) const override;
1083
void visit(Visitor&) const override;
1084
Condition_ptr clone() override
1086
return std::make_shared<KSafeCondition>(_bound);
1089
Expr_ptr _bound = nullptr;
1092
class LivenessCondition : public ShallowCondition
1095
LivenessCondition() {}
1097
void _analyze(AnalysisContext& context) override;
1098
void _toString(std::ostream& out) const override;
1099
void visit(Visitor&) const override;
1100
Condition_ptr clone() override { return std::make_shared<LivenessCondition>(); }
1103
class QuasiLivenessCondition : public ShallowCondition
1106
QuasiLivenessCondition() {}
1108
void _analyze(AnalysisContext& context) override;
1109
void _toString(std::ostream& out) const override;
1110
void visit(Visitor&) const override;
1111
Condition_ptr clone() override { return std::make_shared<QuasiLivenessCondition>(); }
1114
class StableMarkingCondition : public ShallowCondition
1117
StableMarkingCondition() {}
1119
void _analyze(AnalysisContext& context) override;
1120
void _toString(std::ostream& out) const override;
1121
void visit(Visitor&) const override;
1122
Condition_ptr clone() override { return std::make_shared<StableMarkingCondition>(); }
1125
class UpperBoundsCondition : public ShallowCondition
1129
UpperBoundsCondition(const std::vector<std::string>& places) : _places(places)
1132
void _toString(std::ostream& out) const override;
1133
void _analyze(AnalysisContext& context) override;
1134
void visit(Visitor&) const override;
1135
Condition_ptr clone() override
1137
return std::make_shared<UpperBoundsCondition>(_places);
1141
std::vector<std::string> _places;
1144
class UnfoldedUpperBoundsCondition : public Condition
1149
uint32_t _place = 0;
1150
double _max = std::numeric_limits<double>::infinity();
1151
bool _maxed_out = false;
1152
place_t(const std::string& name)
1156
place_t(const place_t& other, double max)
1158
_name = other._name;
1159
_place = other._place;
1162
bool operator<(const place_t& other) const{
1163
return _place < other._place;
1167
UnfoldedUpperBoundsCondition(const std::vector<std::string>& places)
1169
for(auto& s : places) _places.push_back(s);
1171
UnfoldedUpperBoundsCondition(const std::vector<place_t>& places, double max, double offset)
1172
: _places(places), _max(max), _offset(offset) {
1174
int formulaSize() const override{
1175
return _places.size();
1177
void analyze(AnalysisContext& context) override;
1178
size_t value(const MarkVal*);
1179
Result evaluate(const EvaluationContext& context) override;
1180
Result evalAndSet(const EvaluationContext& context) override;
1181
void visit(Visitor&) const override;
1182
uint32_t distance(DistanceContext& context) const override;
1183
void toString(std::ostream&) const override;
1184
void toTAPAALQuery(std::ostream&,TAPAALConditionExportContext& context) const override;
1185
void toBinary(std::ostream&) const override;
1186
Retval simplify(SimplificationContext& context) const override;
1187
bool isReachability(uint32_t depth) const override;
1188
Condition_ptr prepareForReachability(bool negated) const override;
1189
Condition_ptr pushNegation(negstat_t&, const EvaluationContext& context, bool nested, bool negated, bool initrw) override;
1190
void toXML(std::ostream&, uint32_t tabs) const override;
1191
void findInteresting(ReducingSuccessorGenerator& generator, bool negated) const override;
1192
Quantifier getQuantifier() const override { return Quantifier::UPPERBOUNDS; }
1193
Path getPath() const override { return Path::pError; }
1194
CTLType getQueryType() const override { return CTLType::EVAL; }
1195
bool containsNext() const override { return false; }
1196
bool nestedDeadlock() const override { return false; }
1198
double bounds(bool add_offset = true) const {
1199
return (add_offset ? _offset : 0 ) + _bound;
1202
virtual void setUpperBound(size_t bound)
1204
_bound = std::max(_bound, bound);
1207
const std::vector<place_t>& places() const { return _places; }
1210
std::vector<place_t> _places;
1212
double _max = std::numeric_limits<double>::infinity();
1221
#endif // EXPRESSIONS_H