From 8bb4f79d8238b9500f925c555b33ee72b7618430 Mon Sep 17 00:00:00 2001 From: AlexZangerle Date: Mon, 19 Jan 2026 12:56:11 +0100 Subject: [PATCH 1/5] feat: add chameneos example --- chameneos/chameneos.pkl | 53 +++++++++++++++++++++++++++++++++++++++++ chameneos/main.pkl | 14 +++++++++++ chameneos/mall.pkl | 53 +++++++++++++++++++++++++++++++++++++++++ chameneos/services.pkl | 4 ++++ 4 files changed, 124 insertions(+) create mode 100644 chameneos/chameneos.pkl create mode 100644 chameneos/main.pkl create mode 100644 chameneos/mall.pkl create mode 100644 chameneos/services.pkl diff --git a/chameneos/chameneos.pkl b/chameneos/chameneos.pkl new file mode 100644 index 0000000..8c4e0e2 --- /dev/null +++ b/chameneos/chameneos.pkl @@ -0,0 +1,53 @@ +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +sm = new csml.StateMachine { + transient { + ["chameneosId"] = "std:getUniqueId()" + ["color"] = "std:getRandomColor()" + ["individualMeetingCounter"] = "0" + } + states { + ["requestingPartner"] = new csml.Initial { + entry { + new csml.Raise { + event = new csml.Global { + topic = "requestingPartner" + data { ["chameneosId"] = "chameneosId"; ["chameneosColor"] = "color" } + } + } + } + on { + ["matchMade"] = new csml.Transition { + to = "matchFound" + iif = "$chameneos == chameneosId" + } + ["change"] = new csml.Transition { + to = "requestingPartner" + iif = "$partner == chameneosId" + do { + new csml.Eval { expression = "color = std:complement(color, $color)" } + new csml.Eval { expression = "individualMeetingCounter = individualMeetingCounter + 1" } + } + } + ["done"] = new csml.Transition { + to = "done" + } + } + } + ["matchFound"] = new csml.State { + entry { + new csml.Eval { expression = "color = std:complement(color, $color)" } + new csml.Eval { expression = "individualMeetingCounter = individualMeetingCounter + 1" } + new csml.Raise { + event = new csml.Global { + topic = "change" + data { ["partner"] = "$partner"; ["color"] = "color" } + } + } + } + always { new csml.Transition { to = "requestingPartner" } } + } + ["done"] = new csml.Terminal {} + } +} diff --git a/chameneos/main.pkl b/chameneos/main.pkl new file mode 100644 index 0000000..cf5bda8 --- /dev/null +++ b/chameneos/main.pkl @@ -0,0 +1,14 @@ +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +import "chameneos.pkl" +import "defs.pkl" +import "mall.pkl" + +version = "4.0.0" +stateMachines { + ["mall"] = mall.sm + for (_def in defs.chameneos) { + [_def] = chameneos.sm + } +} diff --git a/chameneos/mall.pkl b/chameneos/mall.pkl new file mode 100644 index 0000000..283863b --- /dev/null +++ b/chameneos/mall.pkl @@ -0,0 +1,53 @@ +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +sm = new csml.StateMachine { + transient { + ["waitingList"] = "[...]" + ["meetingCounter"] = "0" + } + states { + ["waitingForChameneos"] = new csml.Initial { + on { + ["requestingPartner"] = new csml.Transition { + to = "waitingForChameneos" + iif = "waitingList.isEmpty() && meetingCounter < 1000000" + do { + new csml.Eval { + expression = "waitingList = std:addToList(\("waitingList"), $chameneosId)" + } + } + or = "scheduleMeeting" + } + } + } + ["scheduleMeeting"] = new csml.State { + always { + new csml.Transition { + to = "waitingForChameneos" + iif = "!waitingList.isEmpty() && meetingCounter < 1000000" + do { + new csml.Eval { expression = "meetingCounter = meetingCounter + 1" } + new csml.Raise { + event = new csml.Global { + topic = "matchMade" + data { + ["chameneos"] = "waitingList.get(0)" + ["partner"] = "$chameneosId" + ["color"] = "$chameneosColor" + } + } + } + new csml.Eval { expression = "waitingList = std:removeFirst(\("waitingList"))" } + } + or = "done" + } + } + } + ["done"] = new csml.Terminal { + entry { + new csml.Raise { event = new csml.Global { topic = "done" } } + } + } + } +} diff --git a/chameneos/services.pkl b/chameneos/services.pkl new file mode 100644 index 0000000..07c151f --- /dev/null +++ b/chameneos/services.pkl @@ -0,0 +1,4 @@ +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/bindings.pkl" + +bindings {} From 9af7b396add559bfdd632bbf75cbfe43b63967e4 Mon Sep 17 00:00:00 2001 From: AlexZangerle Date: Wed, 21 Jan 2026 13:26:51 +0100 Subject: [PATCH 2/5] feat: add big example --- big/big.pkl | 92 +++++++++++++++++++++++++++++++ big/defs.pkl | 1 + big/main.pkl | 14 +++++ big/services.pkl | 4 ++ big/sink.pkl | 59 ++++++++++++++++++++ pingpong/benchmark/Akka.txt | 31 ----------- pingpong/benchmark/AkkaRemote.txt | 30 ---------- 7 files changed, 170 insertions(+), 61 deletions(-) create mode 100644 big/big.pkl create mode 100644 big/defs.pkl create mode 100644 big/main.pkl create mode 100644 big/services.pkl create mode 100644 big/sink.pkl delete mode 100644 pingpong/benchmark/Akka.txt delete mode 100644 pingpong/benchmark/AkkaRemote.txt diff --git a/big/big.pkl b/big/big.pkl new file mode 100644 index 0000000..3ac9522 --- /dev/null +++ b/big/big.pkl @@ -0,0 +1,92 @@ +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +sm = new csml.StateMachine { + transient { + ["bigId"] = "std:getSequentialId()" + ["target"] = "''" + ["otherBigs"] = "[...]" + ["pingCounter"] = "0" + ["pongCounter"] = "0" + } + states { + ["registerBig"] = new csml.Initial { + entry { + new csml.Raise { + event = new csml.Global { topic = "registerBig"; data { ["bigId"] = "bigId" } } + } + } + on { + ["allBigsRegistered"] = new csml.Transition { + to = "sendPing" + do { + new csml.Eval { expression = "otherBigs = std:getAllStateMachines()" } + new csml.Eval { + expression = "otherBigs = std:removeFromList(\("otherBigs"), \("bigId"))" + } + } + } + } + } + ["sendPing"] = new csml.State { + always { + new csml.Transition { + to = "waitForPingOrPong" + iif = "pingCounter < 20000" + do { + new csml.Eval { expression = "pingCounter = pingCounter + 1" } + new csml.Eval { expression = "target = std:takeRandom(\("otherBigs"))" } + new csml.Raise { + event = new csml.Global { + topic = "ping" + data { ["sender"] = "bigId"; ["receiver"] = "target" } + } + } + } + or = "receiveRemaining" + } + } + } + ["waitForPingOrPong"] = new csml.State { + on { + ["ping"] = new csml.Transition { + iif = "$sender != bigId && $receiver == bigId" + do { + new csml.Raise { + event = new csml.Global { + topic = "pong" + data { ["sender"] = "bigId"; ["receiver"] = "$sender" } + } + } + } + } + ["pong"] = new csml.Transition { + iif = "$receiver == bigId && $sender == target" + to = "sendPing" + } + } + } + ["receiveRemaining"] = new csml.State { + entry { + new csml.Raise { event = new csml.Global { topic = "donePinging" } } + } + on { + ["ping"] = new csml.Transition { + iif = "$sender != bigId && $receiver == bigId" + do { + new csml.Raise { + event = new csml.Global { + topic = "pong" + data { ["sender"] = "bigId"; ["receiver"] = "$sender" } + } + } + } + } + ["shutdown"] = new csml.Transition { + to = "done" + } + } + } + ["done"] = new csml.Terminal {} + } +} diff --git a/big/defs.pkl b/big/defs.pkl new file mode 100644 index 0000000..b9bdb2c --- /dev/null +++ b/big/defs.pkl @@ -0,0 +1 @@ +bigs = List("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11") diff --git a/big/main.pkl b/big/main.pkl new file mode 100644 index 0000000..fc70794 --- /dev/null +++ b/big/main.pkl @@ -0,0 +1,14 @@ +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +import "big.pkl" +import "defs.pkl" +import "sink.pkl" + +version = "4.0.0" +stateMachines { + ["sink"] = sink.sm + for (_def in defs.bigs) { + [_def] = big.sm + } +} diff --git a/big/services.pkl b/big/services.pkl new file mode 100644 index 0000000..07c151f --- /dev/null +++ b/big/services.pkl @@ -0,0 +1,4 @@ +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/bindings.pkl" + +bindings {} diff --git a/big/sink.pkl b/big/sink.pkl new file mode 100644 index 0000000..f1f64e2 --- /dev/null +++ b/big/sink.pkl @@ -0,0 +1,59 @@ +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" + +sm = new csml.StateMachine { + transient { + ["registered"] = "''" + ["registeredCounter"] = "0" + ["doneCounter"] = "0" + ["cumulatedPongCounter"] = "0" + } + states { + ["registerBigs"] = new csml.Initial { + on { + ["registerBig"] = new csml.Transition { + to = "evaluateAllBigsReceived" + do { + new csml.Eval { expression = "registeredCounter = registeredCounter + 1" } + new csml.Eval { expression = "registered = std:registerStateMachine(\("$bigId"))" } + } + } + } + } + ["evaluateAllBigsReceived"] = new csml.State { + always { + new csml.Transition { + to = "waitingForBigs" + iif = "registeredCounter == 12" + do { + new csml.Raise { event = new csml.Global { topic = "allBigsRegistered" } } + } + or = "registerBigs" + } + } + } + ["waitingForBigs"] = new csml.State { + on { + ["donePinging"] = new csml.Transition { + to = "isFinal" + do { + new csml.Eval { expression = "doneCounter = doneCounter + 1" } + } + } + } + } + ["isFinal"] = new csml.State { + always { + new csml.Transition { + to = "done" + iif = "doneCounter == 12" + do { + new csml.Raise { event = new csml.Global { topic = "shutdown" } } + } + or = "waitingForBigs" + } + } + } + ["done"] = new csml.Terminal {} + } +} diff --git a/pingpong/benchmark/Akka.txt b/pingpong/benchmark/Akka.txt deleted file mode 100644 index f8f6882..0000000 --- a/pingpong/benchmark/Akka.txt +++ /dev/null @@ -1,31 +0,0 @@ -Number of pings: 50.000 -Execution - Iterations: -PingPongAkkaActorBenchmark Iteration-0: 316.151 ms -PingPongAkkaActorBenchmark Iteration-1: 118.366 ms -PingPongAkkaActorBenchmark Iteration-2: 77.245 ms -PingPongAkkaActorBenchmark Iteration-3: 84.737 ms -PingPongAkkaActorBenchmark Iteration-4: 70.632 ms -PingPongAkkaActorBenchmark Iteration-5: 76.096 ms -PingPongAkkaActorBenchmark Iteration-6: 72.107 ms -PingPongAkkaActorBenchmark Iteration-7: 67.815 ms -PingPongAkkaActorBenchmark Iteration-8: 64.724 ms -PingPongAkkaActorBenchmark Iteration-9: 65.730 ms -PingPongAkkaActorBenchmark Iteration-10: 68.262 ms -PingPongAkkaActorBenchmark Iteration-11: 64.844 ms - - -Execution - Summary: - Total executions = 12 - Filtered executions = 10 -PingPongAkkaActorBenchmark Best Time: 64.724 ms -PingPongAkkaActorBenchmark Worst Time: 84.737 ms -PingPongAkkaActorBenchmark Median: 69.447 ms -PingPongAkkaActorBenchmark Arith. Mean Time: 71.219 ms -PingPongAkkaActorBenchmark Geo. Mean Time: 70.966 ms -PingPongAkkaActorBenchmark Harmonic Mean Time: 70.724 ms -PingPongAkkaActorBenchmark Std. Dev Time: 6.142 ms -PingPongAkkaActorBenchmark Lower Confidence: 67.412 ms -PingPongAkkaActorBenchmark Higher Confidence: 75.026 ms -PingPongAkkaActorBenchmark Error Window: 3.807 ms (5.345 percent) -PingPongAkkaActorBenchmark Coeff. of Variation: 0.086 -PingPongAkkaActorBenchmark Skewness: 0.979 \ No newline at end of file diff --git a/pingpong/benchmark/AkkaRemote.txt b/pingpong/benchmark/AkkaRemote.txt deleted file mode 100644 index 8f63738..0000000 --- a/pingpong/benchmark/AkkaRemote.txt +++ /dev/null @@ -1,30 +0,0 @@ -Number of pings: 50.000 -Execution - Iterations: -PingPongAkkaActorBenchmark Iteration-0: 30511.704 ms -PingPongAkkaActorBenchmark Iteration-1: 25736.073 ms -PingPongAkkaActorBenchmark Iteration-2: 30145.372 ms -PingPongAkkaActorBenchmark Iteration-3: 31287.985 ms -PingPongAkkaActorBenchmark Iteration-4: 33002.205 ms -PingPongAkkaActorBenchmark Iteration-5: 30022.782 ms -PingPongAkkaActorBenchmark Iteration-6: 31745.709 ms -PingPongAkkaActorBenchmark Iteration-7: 32723.041 ms -PingPongAkkaActorBenchmark Iteration-8: 32083.870 ms -PingPongAkkaActorBenchmark Iteration-9: 29523.999 ms -PingPongAkkaActorBenchmark Iteration-10: 24884.690 ms -PingPongAkkaActorBenchmark Iteration-11: 28197.974 ms - -Execution - Summary: - Total executions = 12 - Filtered executions = 12 -PingPongAkkaActorBenchmark Best Time: 24884.690 ms -PingPongAkkaActorBenchmark Worst Time: 33002.205 ms -PingPongAkkaActorBenchmark Median: 30328.538 ms -PingPongAkkaActorBenchmark Arith. Mean Time: 29988.784 ms -PingPongAkkaActorBenchmark Geo. Mean Time: 29881.058 ms -PingPongAkkaActorBenchmark Harmonic Mean Time: 29767.749 ms -PingPongAkkaActorBenchmark Std. Dev Time: 2476.228 ms -PingPongAkkaActorBenchmark Lower Confidence: 28587.726 ms -PingPongAkkaActorBenchmark Higher Confidence: 31389.841 ms -PingPongAkkaActorBenchmark Error Window: 1401.058 ms (4.672 percent) -PingPongAkkaActorBenchmark Coeff. of Variation: 0.083 -PingPongAkkaActorBenchmark Skewness: -0.904 \ No newline at end of file From 9b4885266ed51c06ccd74ede7128264711dceb26 Mon Sep 17 00:00:00 2001 From: AlexZangerle Date: Thu, 22 Jan 2026 13:37:35 +0100 Subject: [PATCH 3/5] feat: add dining philosophers example --- philosophers/arbitrator.pkl | 148 +++++++++++++++------------------- philosophers/main.pkl | 13 ++- philosophers/philosopher.pkl | 152 +++++++++++------------------------ philosophers/services.pkl | 6 +- 4 files changed, 122 insertions(+), 197 deletions(-) diff --git a/philosophers/arbitrator.pkl b/philosophers/arbitrator.pkl index 4551648..161d667 100644 --- a/philosophers/arbitrator.pkl +++ b/philosophers/arbitrator.pkl @@ -1,87 +1,69 @@ -import "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/Csml.pkl" +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" -class StateMachine extends Csml.StateMachineDescription { - name = "arbitrator" - localContext { - variables { - new { - name = "allocated" - value = "[...]" - } - } +sm = new csml.StateMachine { + transient { + ["allocated"] = "[...]" + ["doneCounter"] = "0" } states { - new Csml.StateDescription { - name = "waitingForRequests" - initial = true - on { - new Csml.OnTransitionDescription { - event = "requesting" - guards { - new Csml.GuardDescription { - expression = "utility:notIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" - } - } - actions { - new Csml.AssignActionDescription { - variable = new { - name = "allocated" - value = "utility:addToList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" - } - } - new Csml.RaiseActionDescription { - event { - name = "allocated" - data { - new { - name = "forkOne" - value = "$forkOne" - } - } - channel = "global" - } - } - } - } - new Csml.OnTransitionDescription { - event = "requesting" - guards { - new { - expression = "!utility:notIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" - } - } - actions { - new Csml.RaiseActionDescription { - event { - name = "denied" - data { - new { - name = "forkOne" - value = "$forkOne" - } - } - channel = "global" - } - } - } - } - new Csml.OnTransitionDescription { - event = "finished" - guards { - new Csml.GuardDescription { - expression = "utility:in(\("allocated"), $forkOne, ($forkOne + 1) % 6)" - } - } - actions { - new Csml.AssignActionDescription { - variable = new { - name = "allocated" - value = "utility:removeFromList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" - } - } - } - } - } - } + ["waitingForRequests"] = new csml.Initial { + on { + ["requesting"] = new csml.Transition { + to = "waitingForRequests" + iif = "std:notIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + do { + new csml.Eval { + expression = "allocated = std:addToList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + } + new csml.Raise { + event = new csml.Global { + topic = "allocated" + data { + ["forkOne"] = "$forkOne" + } + } + } + } + or = "denied" + } + ["finished"] = new csml.Transition { + to = "waitingForRequests" + iif = "std:isIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + do { + new csml.Eval { + expression = + "allocated = std:removeFromList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + } + } + } + ["done"] = new csml.Transition { + to = "waitingForRequests" + iif = "doneCounter < 5" + do { + new csml.Eval { expression = "doneCounter = doneCounter + 1" } + } + or = "done" + } + } + } + ["denied"] = new csml.State { + always { + new csml.Transition { + to = "waitingForRequests" + do { + new csml.Raise { + event = new csml.Global { + topic = "denied" + data { + ["forkOne"] = "$forkOne" + } + } + } + } + } + } + } + ["done"] = new csml.Terminal {} } -} \ No newline at end of file +} diff --git a/philosophers/main.pkl b/philosophers/main.pkl index 4be768d..d7fa2ca 100644 --- a/philosophers/main.pkl +++ b/philosophers/main.pkl @@ -1,14 +1,13 @@ -amends "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/Csml.pkl" +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" import "arbitrator.pkl" import "defs.pkl" import "philosopher.pkl" - -name = "benchmark" -version = "3.0.0" +version = "4.0.0" stateMachines { - new arbitrator.StateMachine {} + ["arbitrator"] = arbitrator.sm for (_name in defs.philosophers) { - new philosopher.StateMachine {name = _name } + [_name] = philosopher.sm + } } -} \ No newline at end of file diff --git a/philosophers/philosopher.pkl b/philosophers/philosopher.pkl index 458c60a..bc102e3 100644 --- a/philosophers/philosopher.pkl +++ b/philosophers/philosopher.pkl @@ -1,122 +1,66 @@ -import "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/Csml.pkl" +import + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" -class StateMachine extends Csml.StateMachineDescription { - name = "philosopher" - local self = this - localContext { - variables { - new { - name = "counter" - value = "0" - } - } +sm = new csml.StateMachine { + transient { + ["counter"] = "0" + ["philosopherId"] = "std:getSequentialIdInt()" } states { - new { - name = "requestingFork" - initial = true - entry { - new Csml.AssignActionDescription { - variable = new { - name = "counter" - value = "counter + 1" - } - } - new Csml.RaiseActionDescription { - event { - name = "requesting" - data { - new { - name = "forkOne" - value = self.name - } - } - channel = "global" - } - } - } - on { - new { - event = "allocated" - guards { - new { - expression = "$forkOne == \(self.name) && ($forkOne + 1) % 6 == (\(self.name) + 1) % 6" - } - } - target = "eating" - } - new { - event = "denied" - guards { - new { - expression = "$forkOne == \(self.name) && ($forkOne + 1) % 6 == (\(self.name) + 1) % 6" - } - new { - expression = "counter <= 16000" - } - } - target = "requestingFork" - } - new { - event = "denied" - guards { - new { - expression = "$forkOne == \(self.name) && ($forkOne + 1) % 6 == (\(self.name) + 1) % 6" - } - new { - expression = "counter > 16000" - } - } - target = "leave" - } - } - } - new Csml.StateDescription { - name = "eating" + ["requestingFork"] = new csml.Initial { entry { - new Csml.RaiseActionDescription { - event { - name = "finished" + new csml.Eval { expression = "counter = counter + 1" } + new csml.Raise { + event = new csml.Global { + topic = "requesting" data { - new { - name = "forkOne" - value = self.name - } + ["forkOne"] = "philosopherId" } - channel = "global" } } } on { - new Csml.OnTransitionDescription { - event = "finished" - guards { - new Csml.GuardDescription { - expression = "$forkOne == \(self.name) && ($forkOne + 1) % 6 == (\(self.name) + 1) % 6" - } - new Csml.GuardDescription { - expression = "counter <= 16000" - } - } - target = "requestingFork" + ["allocated"] = new csml.Transition { + to = "eating" + iif = "$forkOne == philosopherId && ($forkOne + 1) % 6 == (philosopherId + 1) % 6" } - new Csml.OnTransitionDescription { - event = "finished" - guards { - new Csml.GuardDescription { - expression = "$forkOne == \(self.name) && ($forkOne + 1) % 6 == (\(self.name) + 1) % 6" - } - new Csml.GuardDescription { - expression = "counter > 16000" + ["denied"] = new csml.Transition { + to = "evaluateCounter" + iif = "$forkOne == philosopherId && ($forkOne + 1) % 6 == (philosopherId + 1) % 6" + } + } + } + ["evaluateCounter"] = new csml.State { + always { + new csml.Transition { + to = "requestingFork" + iif = "counter <= 16000" + or = "leave" + } + } + } + ["eating"] = new csml.State { + entry { + new csml.Raise { + event = new csml.Global { + topic = "finished" + data { + ["forkOne"] = "philosopherId" } } - target = "leave" + } + } + on { + ["finished"] = new csml.Transition { + to = "evaluateCounter" + iif = "$forkOne == philosopherId && ($forkOne + 1) % 6 == (philosopherId + 1) % 6" } } } - new Csml.StateDescription { - name = "leave" - terminal = true + ["leave"] = new csml.Terminal { + entry { + new csml.Raise { event = new csml.Global { topic = "done" } } + } } } -} \ No newline at end of file +} diff --git a/philosophers/services.pkl b/philosophers/services.pkl index 41ac2ec..07c151f 100644 --- a/philosophers/services.pkl +++ b/philosophers/services.pkl @@ -1,4 +1,4 @@ -amends "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/ServiceImplementationBindings.pkl" +amends + "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/bindings.pkl" -bindings { -} \ No newline at end of file +bindings {} From 529fbca1aab796e4dda7321a509883772d34335c Mon Sep 17 00:00:00 2001 From: AlexZangerle Date: Mon, 26 Jan 2026 10:02:15 +0100 Subject: [PATCH 4/5] fix: change philosopher exit logic to match savina --- philosophers/philosopher.pkl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/philosophers/philosopher.pkl b/philosophers/philosopher.pkl index bc102e3..9a8cb3e 100644 --- a/philosophers/philosopher.pkl +++ b/philosophers/philosopher.pkl @@ -3,13 +3,14 @@ import sm = new csml.StateMachine { transient { - ["counter"] = "0" + ["tryCounter"] = "0" + ["eatCounter"] = "0" ["philosopherId"] = "std:getSequentialIdInt()" } states { ["requestingFork"] = new csml.Initial { entry { - new csml.Eval { expression = "counter = counter + 1" } + new csml.Eval { expression = "tryCounter = tryCounter + 1" } new csml.Raise { event = new csml.Global { topic = "requesting" @@ -34,13 +35,14 @@ sm = new csml.StateMachine { always { new csml.Transition { to = "requestingFork" - iif = "counter <= 16000" + iif = "eatCounter <= 16000" or = "leave" } } } ["eating"] = new csml.State { entry { + new csml.Eval { expression = "eatCounter = eatCounter + 1" } new csml.Raise { event = new csml.Global { topic = "finished" From e1101d0aaa01a26734d8c84ff382c7655cfe8dc8 Mon Sep 17 00:00:00 2001 From: AlexZangerle Date: Wed, 28 Jan 2026 11:21:24 +0100 Subject: [PATCH 5/5] fix: remove use of std functions from dining philosophers example --- philosophers/arbitrator.pkl | 9 ++++----- philosophers/defs.pkl | 2 +- philosophers/main.pkl | 4 ++-- philosophers/philosopher.pkl | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/philosophers/arbitrator.pkl b/philosophers/arbitrator.pkl index 161d667..2cf0bc6 100644 --- a/philosophers/arbitrator.pkl +++ b/philosophers/arbitrator.pkl @@ -11,10 +11,10 @@ sm = new csml.StateMachine { on { ["requesting"] = new csml.Transition { to = "waitingForRequests" - iif = "std:notIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + iif = "!(allocated.contains($forkOne) || allocated.contains(($forkOne + 1) % 6))" do { new csml.Eval { - expression = "allocated = std:addToList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + expression = "allocated + [$forkOne, ($forkOne + 1) % 6]" } new csml.Raise { event = new csml.Global { @@ -29,11 +29,10 @@ sm = new csml.StateMachine { } ["finished"] = new csml.Transition { to = "waitingForRequests" - iif = "std:isIn(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + iif = "allocated.contains($forkOne) && allocated.contains(($forkOne + 1) % 6)" do { new csml.Eval { - expression = - "allocated = std:removeFromList(\("allocated"), $forkOne, ($forkOne + 1) % 6)" + expression = "allocated - [$forkOne, ($forkOne + 1) % 6]" } } } diff --git a/philosophers/defs.pkl b/philosophers/defs.pkl index 595fd42..b5f4e25 100644 --- a/philosophers/defs.pkl +++ b/philosophers/defs.pkl @@ -1 +1 @@ -philosophers = List("1", "2", "3", "4", "5", "6") \ No newline at end of file +philosophers = List(1, 2, 3, 4, 5, 6) diff --git a/philosophers/main.pkl b/philosophers/main.pkl index d7fa2ca..2ef8245 100644 --- a/philosophers/main.pkl +++ b/philosophers/main.pkl @@ -7,7 +7,7 @@ import "philosopher.pkl" version = "4.0.0" stateMachines { ["arbitrator"] = arbitrator.sm - for (_name in defs.philosophers) { - [_name] = philosopher.sm + for (n in defs.philosophers) { + [n.toString()] = philosopher.createPhilosopher(n) } } diff --git a/philosophers/philosopher.pkl b/philosophers/philosopher.pkl index 9a8cb3e..8004b49 100644 --- a/philosophers/philosopher.pkl +++ b/philosophers/philosopher.pkl @@ -1,11 +1,11 @@ import "https://raw.githubusercontent.com/CollaborativeStateMachines/Cirrina/refs/heads/develop/src/main/resources/pkl/csm/csml.pkl" -sm = new csml.StateMachine { +function createPhilosopher(id: Int) = new csml.StateMachine { transient { ["tryCounter"] = "0" ["eatCounter"] = "0" - ["philosopherId"] = "std:getSequentialIdInt()" + ["philosopherId"] = "\(id)" } states { ["requestingFork"] = new csml.Initial {