Last active
December 2, 2018 01:22
-
-
Save ryo33/0e3dfb374fdd9a76846ea361d7bab836 to your computer and use it in GitHub Desktop.
食事する哲学者の問題 with Cizen ref: https://qiita.com/ryo33/items/3d3fc82cdcb929e0b9ec
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mix new cizen_dining_philosophers | |
cd cizen_dining_philosophers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defp deps do | |
[ | |
{:cizen, "~> 0.14.1"} | |
] | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BorrowChopstick do | |
defstruct [:chopstick_id] | |
use Cizen.Request # to use defresponse/3 | |
defresponse LendChopstick, :request_id do | |
defstruct [:request_id] | |
end | |
end | |
defmodule ReturnChopstick do | |
defstruct [:chopstick_id] | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Chopstick do | |
use Cizen.Automaton | |
defstruct [] | |
alias Cizen.Effects.{Dispatch, Receive, Subscribe} | |
alias Cizen.{Event, Filter} | |
@impl true | |
def spawn(id, %__MODULE__{}) do | |
perform id, %Subscribe{ | |
event_filter: Filter.any([ | |
Filter.new(fn %Event{body: %BorrowChopstick{chopstick_id: ^id}} -> true end), | |
Filter.new(fn %Event{body: %ReturnChopstick{chopstick_id: ^id}} -> true end) | |
]) | |
} | |
:available | |
end | |
@impl true | |
def yield(id, :available) do | |
received = perform id, %Receive{ | |
event_filter: Filter.new(fn %Event{body: %BorrowChopstick{}} -> true end) | |
} | |
alias BorrowChopstick.LendChopstick | |
perform id, %Dispatch{ | |
body: %LendChopstick{ | |
request_id: received.id | |
} | |
} | |
:not_available | |
end | |
@impl true | |
def yield(id, :not_available) do | |
perform id, %Receive{ | |
event_filter: Filter.new(fn %Event{body: %ReturnChopstick{}} -> true end) | |
} | |
:available | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Philosopher do | |
use Cizen.Automaton | |
defstruct [:name, :left_chopstick, :right_chopstick] | |
alias Cizen.Effects.{Request, Dispatch} | |
@impl true | |
def spawn(_id, struct) do | |
{:hungry, struct} | |
end | |
@impl true | |
def yield(id, {:hungry, struct}) do | |
%__MODULE__{ | |
name: name, | |
left_chopstick: left_chopstick, | |
right_chopstick: right_chopstick | |
} = struct | |
IO.puts("#{name} is hungry.") | |
perform id, %Request{ | |
body: %BorrowChopstick{ | |
chopstick_id: left_chopstick | |
} | |
} | |
IO.puts("#{name} has a chopstick in their left hand.") | |
perform id, %Request{ | |
body: %BorrowChopstick{ | |
chopstick_id: right_chopstick | |
} | |
} | |
IO.puts("#{name} has chopstics in both hands.") | |
{:eating, struct} | |
end | |
@impl true | |
def yield(id, {:eating, struct}) do | |
%__MODULE__{ | |
name: name, | |
left_chopstick: left_chopstick, | |
right_chopstick: right_chopstick | |
} = struct | |
IO.puts("#{name} is eating.") | |
perform id, %Dispatch{ | |
body: %ReturnChopstick{ | |
chopstick_id: left_chopstick | |
} | |
} | |
perform id, %Dispatch{ | |
body: %ReturnChopstick{ | |
chopstick_id: right_chopstick | |
} | |
} | |
{:hungry, struct} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Dining do | |
use Cizen.Effectful # for handle/1 and perform/2 | |
alias Cizen.Effects.{All, Start} | |
def run do | |
handle fn id -> | |
chopstick_1 = perform id, %Start{saga: %Chopstick{}} | |
chopstick_2 = perform id, %Start{saga: %Chopstick{}} | |
chopstick_3 = perform id, %Start{saga: %Chopstick{}} | |
chopstick_4 = perform id, %Start{saga: %Chopstick{}} | |
chopstick_5 = perform id, %Start{saga: %Chopstick{}} | |
philosophers = [ | |
%Philosopher{ | |
name: "Plato", | |
left_chopstick: chopstick_1, | |
right_chopstick: chopstick_2 | |
}, | |
%Philosopher{ | |
name: "Konfuzius", | |
left_chopstick: chopstick_2, | |
right_chopstick: chopstick_3 | |
}, | |
%Philosopher{ | |
name: "Socrates", | |
left_chopstick: chopstick_3, | |
right_chopstick: chopstick_4 | |
}, | |
%Philosopher{ | |
name: "Voltaire", | |
left_chopstick: chopstick_4, | |
right_chopstick: chopstick_5 | |
}, | |
%Philosopher{ | |
name: "Descartes", | |
left_chopstick: chopstick_5, | |
right_chopstick: chopstick_1 | |
} | |
] | |
perform id, %All{ | |
effects: Enum.map(philosophers, &(%Start{saga: &1})) | |
} | |
receive do | |
_ -> :ok | |
end | |
end | |
end | |
end | |
Dining.run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Plato is hungry. | |
Konfuzius is hungry. | |
Socrates is hungry. | |
Voltaire is hungry. | |
Descartes is hungry. | |
Plato has a chopstick in their left hand. | |
Konfuzius has a chopstick in their left hand. | |
Socrates has a chopstick in their left hand. | |
Voltaire has a chopstick in their left hand. | |
Descartes has a chopstick in their left hand. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%Philosopher{ | |
name: "Descartes", | |
left_chopstick: chopstick_1, | |
right_chopstick: chopstick_5 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Plato is hungry. | |
Konfuzius is hungry. | |
Socrates is hungry. | |
Voltaire is hungry. | |
Descartes is hungry. | |
Plato has a chopstick in their left hand. | |
Konfuzius has a chopstick in their left hand. | |
Socrates has a chopstick in their left hand. | |
Voltaire has a chopstick in their left hand. | |
Voltaire has chopstics in both hands. | |
Voltaire is eating. | |
Voltaire is hungry. | |
Socrates has chopstics in both hands. | |
Socrates is eating. | |
Socrates is hungry. | |
Konfuzius has chopstics in both hands. | |
Konfuzius is eating. | |
Voltaire has a chopstick in their left hand. | |
Konfuzius is hungry. | |
Plato has chopstics in both hands. | |
Plato is eating. | |
Plato is hungry. | |
Socrates has a chopstick in their left hand. | |
Voltaire has chopstics in both hands. | |
Voltaire is eating. | |
Voltaire is hungry. | |
Descartes has a chopstick in their left hand. | |
Konfuzius has a chopstick in their left hand. | |
Socrates has chopstics in both hands. | |
Socrates is eating. | |
Socrates is hungry. | |
Descartes has chopstics in both hands. | |
Descartes is eating. | |
Descartes is hungry. | |
. | |
. | |
. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment