You are on page 1of 4

---- MODULE baschung_adrien_1 ----

EXTENDS TLC, Integers, FiniteSets \* FiniteSets gives the `Cardinality` op


CONSTANTS N, UNDEF

(*--fair algorithm ex_distributed_sum

variables CHAN = {};

define
MessagesForP3 == { msg \in CHAN : msg[3] = "P3" }
end define;

macro remove_from_channel(messages) begin (*Supprimer un message de CHAN*)


CHAN := CHAN \ messages;
end macro;

macro send(content, sender, receiver) begin (*sender envoye le message content à


receiver *)
CHAN := CHAN \union { << content, sender, receiver >> };
end macro;

macro send_and_remove_from_channel(content, sender, receiver, messages_to_remove)


begin (*combiner send et remove en une seule instruction*)
CHAN := (CHAN \union { << content, sender, receiver >> }) \ messages_to_remove;
end macro;

process P1 = "P1"
variables sumP1 = 0; iP1 = 0;
begin
P1_loop: while pc["P3"] /= "Done" do
if 2*iP1 <= N \* computation not finished
then
computeP1: sumP1 := sumP1 + 2 * iP1; \* compute one step further
incriP1: iP1 := iP1 + 1;
else
send(iP1,"P1","P3"); \* emit result
end if;
end while;
end process;

process P2 = "P2"
variables sumP2 = 0; iP2 = 0;
begin
P2_loop: while pc["P3"] /= "Done" do
if 2*iP2 + 1 <= N \* computation not finished
then
computeP2: sumP2 := sumP2 + 2*iP2 + 1; \* compute one step further
incriP2: iP2 := iP2 + 1;
else
send(iP2,"P2","P3"); \* emit result
end if;
end while;
end process;

process P3 = "P3"
variables sumP3 = 0; resultP1 = UNDEF; resultP2 = UNDEF;
begin
P3_loop: while (resultP1 = UNDEF \/ resultP2 = UNDEF) do
with message \in MessagesForP3 do \* receive a message and read result
if message[2] = "P1" then
resultP1 := message[1];
elsif message[2] = "P2" then
resultP2 := message[1];
else
assert FALSE;
end if;
end with;
end while;
P3_finish: sumP3 := resultP1 + resultP2; print(sumP3); \* Compute sum and print
it
end process;

end algorithm; *)

\* BEGIN TRANSLATION (chksum(pcal) = "49bbbf64" /\ chksum(tla) = "6ed00855")


VARIABLES CHAN, pc

(* define statement *)
MessagesForP3 == { msg \in CHAN : msg[3] = "P3" }

VARIABLES sumP1, iP1, sumP2, iP2, sumP3, resultP1, resultP2

vars == << CHAN, pc, sumP1, iP1, sumP2, iP2, sumP3, resultP1, resultP2 >>

ProcSet == {"P1"} \cup {"P2"} \cup {"P3"}

Init == (* Global variables *)


/\ CHAN = {}
(* Process P1 *)
/\ sumP1 = 0
/\ iP1 = 0
(* Process P2 *)
/\ sumP2 = 0
/\ iP2 = 0
(* Process P3 *)
/\ sumP3 = 0
/\ resultP1 = UNDEF
/\ resultP2 = UNDEF
/\ pc = [self \in ProcSet |-> CASE self = "P1" -> "P1_loop"
[] self = "P2" -> "P2_loop"
[] self = "P3" -> "P3_loop"]

P1_loop == /\ pc["P1"] = "P1_loop"


/\ IF pc["P3"] /= "Done"
THEN /\ IF 2*iP1 <= N
THEN /\ pc' = [pc EXCEPT !["P1"] = "computeP1"]
/\ CHAN' = CHAN
ELSE /\ CHAN' = (CHAN \union { << iP1, "P1", "P3" >> })
/\ pc' = [pc EXCEPT !["P1"] = "P1_loop"]
ELSE /\ pc' = [pc EXCEPT !["P1"] = "Done"]
/\ CHAN' = CHAN
/\ UNCHANGED << sumP1, iP1, sumP2, iP2, sumP3, resultP1, resultP2 >>

computeP1 == /\ pc["P1"] = "computeP1"


/\ sumP1' = sumP1 + 2 * iP1
/\ pc' = [pc EXCEPT !["P1"] = "incriP1"]
/\ UNCHANGED << CHAN, iP1, sumP2, iP2, sumP3, resultP1, resultP2 >>

incriP1 == /\ pc["P1"] = "incriP1"


/\ iP1' = iP1 + 1
/\ pc' = [pc EXCEPT !["P1"] = "P1_loop"]
/\ UNCHANGED << CHAN, sumP1, sumP2, iP2, sumP3, resultP1, resultP2 >>

P1 == P1_loop \/ computeP1 \/ incriP1

P2_loop == /\ pc["P2"] = "P2_loop"


/\ IF pc["P3"] /= "Done"
THEN /\ IF 2*iP2 + 1 <= N
THEN /\ pc' = [pc EXCEPT !["P2"] = "computeP2"]
/\ CHAN' = CHAN
ELSE /\ CHAN' = (CHAN \union { << iP2, "P2", "P3" >> })
/\ pc' = [pc EXCEPT !["P2"] = "P2_loop"]
ELSE /\ pc' = [pc EXCEPT !["P2"] = "Done"]
/\ CHAN' = CHAN
/\ UNCHANGED << sumP1, iP1, sumP2, iP2, sumP3, resultP1, resultP2 >>

computeP2 == /\ pc["P2"] = "computeP2"


/\ sumP2' = sumP2 + 2*iP2 + 1
/\ pc' = [pc EXCEPT !["P2"] = "incriP2"]
/\ UNCHANGED << CHAN, sumP1, iP1, iP2, sumP3, resultP1, resultP2 >>

incriP2 == /\ pc["P2"] = "incriP2"


/\ iP2' = iP2 + 1
/\ pc' = [pc EXCEPT !["P2"] = "P2_loop"]
/\ UNCHANGED << CHAN, sumP1, iP1, sumP2, sumP3, resultP1, resultP2 >>

P2 == P2_loop \/ computeP2 \/ incriP2

P3_loop == /\ pc["P3"] = "P3_loop"


/\ IF (resultP1 = UNDEF \/ resultP2 = UNDEF)
THEN /\ \E message \in MessagesForP3:
IF message[2] = "P1"
THEN /\ resultP1' = message[1]
/\ UNCHANGED resultP2
ELSE /\ IF message[2] = "P2"
THEN /\ resultP2' = message[1]
ELSE /\ Assert(FALSE,
"Failure of assertion at
line 64, column 17.")
/\ UNCHANGED resultP2
/\ UNCHANGED resultP1
/\ pc' = [pc EXCEPT !["P3"] = "P3_loop"]
ELSE /\ pc' = [pc EXCEPT !["P3"] = "P3_finish"]
/\ UNCHANGED << resultP1, resultP2 >>
/\ UNCHANGED << CHAN, sumP1, iP1, sumP2, iP2, sumP3 >>

P3_finish == /\ pc["P3"] = "P3_finish"


/\ sumP3' = resultP1 + resultP2
/\ PrintT((sumP3'))
/\ pc' = [pc EXCEPT !["P3"] = "Done"]
/\ UNCHANGED << CHAN, sumP1, iP1, sumP2, iP2, resultP1, resultP2 >>

P3 == P3_loop \/ P3_finish

(* Allow infinite stuttering to prevent deadlock on termination. *)


Terminating == /\ \A self \in ProcSet: pc[self] = "Done"
/\ UNCHANGED vars

Next == P1 \/ P2 \/ P3
\/ Terminating

Spec == /\ Init /\ [][Next]_vars


/\ WF_vars(Next)

Termination == <>(\A self \in ProcSet: pc[self] = "Done")

\* END TRANSLATION

====

You might also like