import datatypes; import DSM.coremetamodel.Editor; import DSM.metamodel.PetriNet.PetriNetEditor.PetriNet; @incremental machine petriNetCorruptor{ asmfunction temp/1; asmfunction model/0; asmfunction violations/0; /** * ViolationMask: Self + Invalid*2 + LonelyNodes*4 + Duplicates*8 + SMViolatingTransition*16 + MGViolatingPlace*32 (integer) */ rule main(in PetriNetModel, in ViolationNumber, in ViolationMask) = let R = undef in seq{ println("Petri Net Corruption Sequence Starting..."); if(PetriNetModel != undef && find petriNetModel(ref(PetriNetModel))) seq{ println(" >> Target: " + PetriNetModel); update model() = ref(PetriNetModel); } else seq{ println("Model not found or not a PetriNet"); fail; } if(ViolationNumber != undef && toInteger(ViolationNumber) > 0) seq{ println(" >> ViolationNumber: " + ViolationNumber); update violations() = toInteger(ViolationNumber); } iterate seq{ if(violations() <= 0) fail; if(toInteger(ViolationMask) % 2 >= 1) seq{ println("Let's create Self edges"); try choose Place in model() with find place(Place) do seq{ new(Place.OutArc(R,Place,Place)); rename(R,"self"+name(Place)); println("Self edge created: " + name(R)); update violations() = violations() - 1; } } if(toInteger(ViolationMask) % 4 >= 2) seq{ println("Let's create Invalid edges"); try choose Node1,Node2 in model() with find notConnectedSameTypeNodes(Node1,Node2) do seq{ if( find place(Node1) ) seq{ new(Place.OutArc(R,Node1,Node2)); rename(R,"invalid"+name(Node1)+name(Node2)); println("Invalid edge created: " + name(R)); } else if (find transition(Node1)) seq{ new(Transition.InArc(R,Node1,Node2)); rename(R,"invalid"+name(Node1)+name(Node2)); println("Invalid edge created: " + name(R)); } update violations() = violations() - 1; } } if(toInteger(ViolationMask) % 8 >= 4) let P = undef, T = undef in seq{ println("Let's create Lonely nodes"); new(Place(P) in model()); rename(P,"PLonely"+violations()); println("Lonely place created " + name(P)); new(places(R,model(),P)); update violations() = violations() - 1; new(Transition(T) in model()); rename(T,"TLonely"+violations()); println("Lonely transition created " + name(T)); new(transitions(R,model(),T)); update violations() = violations() - 1; } if(toInteger(ViolationMask) % 16 >= 8) seq{ println("Let's create Duplicate edges"); iterate choose Node1,Node2 in model() with find connectedNodes(Node1,Node2) do seq{ if( find place(Node1) && find transition(Node2)) seq{ new(Place.OutArc(R,Node1,Node2)); rename(R,"duplicate"+name(Node1)+name(Node2)); println("Duplicate edge created: " + name(R)); update violations() = violations() - 1; fail; } else if (find transition(Node1) && find place(Node2)) seq{ new(Transition.InArc(R,Node1,Node2)); rename(R,"duplicate"+name(Node1)+name(Node2)); println("Duplicate edge created: " + name(R)); update violations() = violations() - 1; fail; } } } if(toInteger(ViolationMask) % 32 >= 16) seq{ println("Let's create State Machine Violating transitions"); try choose T in model() with find transition(T) do seq{ try choose P in model() with find notConnectedToPlace(T,P) do seq{ new(Transition.InArc(R,T,P)); rename(R,"SMviolating"+name(T)+name(P)); println("State Machine Violation " + name(R)); } try choose P in model() with find notConnectedToTrans(P,T) do seq{ new(Place.OutArc(R,P,T)); rename(R,"SMviolating"+name(P)+name(T)); println("State Machine Violation " + name(R)); } update violations() = violations() - 1; } } if(toInteger(ViolationMask) % 64 >= 32) seq{ println("Let's create Marked Graph Violating places"); try choose P in model() with find place(P) do seq{ try choose T in model() with find notConnectedToPlace(T,P) do seq{ new(Transition.InArc(R,T,P)); rename(R,"MGviolating"+name(T)+name(P)); println("Marked Graph Violation " + name(R)); } try choose T in model() with find notConnectedToTrans(P,T) do seq{ new(Place.OutArc(R,P,T)); rename(R,"MGviolating"+name(P)+name(T)); println("Marked Graph Violation " + name(R)); } update violations() = violations() - 1; } } } } pattern petriNetModel(Model) = { DSM.metamodel.PetriNet.PetriNetEditor.PetriNet(Model); } @Random pattern place(P) = {Place(P);} @Random pattern transition(T) = {Transition(T);} @Random pattern notConnectedToPlace(T,P) = { Place(P); Transition(T); find notConnectedNodes(T,P); } @Random pattern notConnectedToTrans(P,T) = { Place(P); Transition(T); find notConnectedNodes(P,T); } @Random pattern notConnectedNodes(N1, N2) = { Node(N1); Node(N2); neg pattern arcbetween(N1,N2) = { Node(N1); Node(N2); Node.Edge(Arc,N1,N2); } } @Random pattern connectedNodes(N1, N2) = { Node(N1); Node(N2); Node.Edge(Arc,N1,N2); } @Random pattern notConnectedSameTypeNodes(N1,N2) = { Node(N1); Node(N2); find notConnectedNodes(N1,N2); find sameType(N1,N2); } pattern selfArc(Arc) = { Node(N); Node.Edge(Arc,N,N); } pattern invalidArc(Arc) = { Node(N1); Node(N2); Node.Edge(Arc,N1,N2); find sameType(N1,N2); } pattern sameType(N1,N2) = { Place(N1); Place(N2); } or { Transition(N1); Transition(N2); } pattern lonelyToken(Token) = { Place.Token(Token); neg pattern place(Token,P) = { Place.Token(Token); Place(P); Place.tokens(R,P,Token); } } pattern lonelyPlace(Place) = { Place(Place); neg pattern toTransition(Place,Transition) = { Place(Place); Transition(Transition); Node.Edge(R,Place,Transition); } neg pattern fromTransition(Place,Transition) = { Place(Place); Transition(Transition); Node.Edge(R,Transition,Place); } } pattern lonelyTransition(Transition) = { Transition(Transition); neg pattern fromPlace(Place,Transition) = { Place(Place); Transition(Transition); Node.Edge(R,Place,Transition); } neg pattern toPlace(Place,Transition) = { Place(Place); Transition(Transition); Node.Edge(R,Transition,Place); } } pattern stateMachineViolatingTransition(T) = { Transition(T); find MoreThanOneOutPlace(T); } or { Transition(T); find MoreThanOneInPlace(T); } pattern MoreThanOneOutPlace(T) = { Place(P1); Place(P2); Transition(T); Transition.InArc(R1,T,P1); Transition.InArc(R2,T,P2); } pattern MoreThanOneInPlace(T) = { Place(P1); Place(P2); Transition(T); Place.OutArc(R1,P1,T); Place.OutArc(R2,P2,T); } pattern markedGraphViolatingPlace(P) = { Place(P); find MoreThanOneInTransition(P); } or { Place(P); find MoreThanOneOutTransition(P); } pattern MoreThanOneInTransition(P) = { Transition(T1); Transition(T2); Place(P); Transition.InArc(R1,T1,P); Transition.InArc(R2,T2,P); } pattern MoreThanOneOutTransition(P) = { Transition(T1); Transition(T2); Place(P); Place.OutArc(R1,P,T1); Place.OutArc(R2,P,T2); } //@goal //pattern freeChoiceViolatingPlace(Place) //@goal //pattern assimetricChoiceViolatingPlaces(Place1, Place2) }