Symmetry: Bakery Algorithm (NuSMV)¶
Description of the Case Study¶
Lamport’s Bakery algorithm [Lam74] is a classic first-come-first-served mutual exclusion protocol in which each process draws a ticket and enters the critical section once it observes that it holds the smallest number. While safety and liveness are guaranteed, the algorithm breaks ties using the intrinsic process identifier, potentially privileging lower-numbered processes. We examine symmetry: if two executions differ only by swapping process identifiers, the resulting behaviour should remain indistinguishable. The case study models configurations with 3, 7, 9, and 11 processes. HyperQB explores the reachable state space under pessimistic semantics, so any bounded counterexample to symmetry generalises to an infinite execution that demonstrates asymmetric access to the critical section.
The NuSMV model(s)¶
--BAKERY ALGORITHM
MODULE main
VAR
p1_ticket: 0..3; -- the ticket number of p1
p2_ticket: 0..3; -- the ticket number of p2
p3_ticket: 0..3; -- the ticket number of p2
MAX_ticket: 0..3; -- let's say max ticket number is 3
p1_line: 0..4;
p2_line: 0..4;
p3_line: 0..4;
ASSIGN
init(p1_ticket) := 3; -- set to MAX
init(p2_ticket) := 3; -- set to MAX
init(p3_ticket) := 3; -- set to MAX
init(p1_line) := 0;
init(p2_line) := 0;
init(p3_line) := 0;
init(MAX_ticket):= 0;
next(MAX_ticket):=
case
(MAX_ticket=3): 0; --reset
((p1_line=1) | (p2_line=1) | (p3_line=1)): (MAX_ticket+1);
TRUE: MAX_ticket;
esac;
next(p1_line) :=
case
(p1_line=0) : {0,1}; -- stay, or proceed
(p1_line=1) : {2}; -- draw ticket
((p1_line=2) & !p1_TOKEN) : {2}; -- check TOKEN
((p1_line=2) & p1_TOKEN) : {3}; -- check TOKEN
(p1_line=3) : {4}; -- stay in critical section, or leave
(p1_line=4) : {0}; -- back to starting point
TRUE: p1_line;
esac;
next(p1_ticket):=
case
(MAX_ticket=3): 0; --reset
(p1_line=1): MAX_ticket+1;
TRUE: p1_ticket;
esac;
next(p2_line) :=
case
(p2_line=0) : {0,1}; -- stay, or proceed
(p2_line=1) : {2};
((p2_line=2) & !p2_TOKEN): {2}; -- check TOKEN
((p2_line=2) & p2_TOKEN): {3}; -- check TOKEN
(p2_line=3) : {4}; -- stay in critical section, or leave
(p2_line=4) : {0}; -- back to starting point
TRUE: p2_line;
esac;
next(p2_ticket):=
case
(MAX_ticket=3): 0; --reset
(p2_line=1): MAX_ticket+1;
TRUE: p2_ticket;
esac;
next(p3_line) :=
case
(p3_line=0) : {0}; -- stay, or proceed
(p3_line=1) : {2};
((p3_line=2) & !p3_TOKEN) : 2 ; -- check TOKEN
((p3_line=2) & p3_TOKEN) : 3 ; -- check TOKEN
(p3_line=3) : {4}; -- stay in critical section, or leave
(p3_line=4) : {0}; -- back to starting point
TRUE: p3_line;
esac;
next(p3_ticket):=
case
(MAX_ticket=3): 0; --reset
(p3_line=1): MAX_ticket+1;
TRUE: p3_ticket;
esac;
DEFINE
STARTED := ( (p1_line!=0) | (p2_line!=0) | (p3_line!=0));
p1_TOKEN := (STARTED) & (p1_line=2) & (p1_ticket <= p2_ticket) & (p1_ticket <= p3_ticket);
p2_TOKEN := (STARTED) & (p2_line=2) & (((p2_ticket <= p1_ticket) & (p2_ticket <= p3_ticket)) | (!p1_TOKEN));
p3_TOKEN := (STARTED) & (p3_line=2) & (((p3_ticket <= p1_ticket) & (p3_ticket <= p2_ticket)) | ((!p1_TOKEN) & (!p2_TOKEN)));
--BAKERY ALGORITHM
MODULE main
VAR
p1_ticket: 0..7; -- the ticket number of p1
p2_ticket: 0..7; -- the ticket number of p2
p3_ticket: 0..7; -- the ticket number of p3
p4_ticket: 0..7; -- the ticket number of p4
p5_ticket: 0..7; -- the ticket number of p5
p6_ticket: 0..7; -- the ticket number of p6
p7_ticket: 0..7; -- the ticket number of p7
MAX_ticket: 0..7;
p1_line: 0..4;
p2_line: 0..4;
p3_line: 0..4;
p4_line: 0..4;
p5_line: 0..4;
p6_line: 0..4;
p7_line: 0..4;
STARTED : boolean;
p1_TOKEN : boolean;
p2_TOKEN : boolean;
p3_TOKEN : boolean;
p4_TOKEN : boolean;
p5_TOKEN : boolean;
p6_TOKEN : boolean;
p7_TOKEN : boolean;
ASSIGN
init(STARTED) := FALSE;
next(STARTED) := case
((p1_line != 0) | (p2_line != 0) | (p3_line != 0) | (p4_line != 0) | (p5_line != 0) | (p6_line != 0) | (p7_line != 0)) : TRUE;
TRUE : STARTED;
esac;
init(p1_TOKEN) := FALSE;
next(p1_TOKEN) := case
(STARTED & (p1_line = 2) & (p1_ticket <= p2_ticket) & (p1_ticket <= p3_ticket) & (p1_ticket <= p4_ticket) & (p1_ticket <= p5_ticket) &(p1_ticket <= p6_ticket) & (p1_ticket <= p7_ticket)) : TRUE;
TRUE : p1_TOKEN;
esac;
init(p2_TOKEN) := FALSE;
next(p2_TOKEN) := case
(STARTED & (p2_line = 2) & ((p2_ticket <= p1_ticket) & (p2_ticket <= p3_ticket) & (p2_ticket <= p4_ticket) & (p2_ticket <= p5_ticket) & (p2_ticket <= p6_ticket) & (p2_ticket <= p7_ticket) | (!p1_TOKEN))) : TRUE;
TRUE : p2_TOKEN;
esac;
init(p3_TOKEN) := FALSE;
next(p3_TOKEN) := case
(STARTED & (p3_line = 2) & (((p3_ticket <= p1_ticket) & (p3_ticket <= p2_ticket) & (p3_ticket <= p4_ticket) & (p3_ticket <= p5_ticket) & (p3_ticket <= p6_ticket) & (p3_ticket <= p7_ticket)) | (!p1_TOKEN) & (!p2_TOKEN))) : TRUE;
TRUE : p3_TOKEN;
esac;
init(p4_TOKEN) := FALSE;
next(p4_TOKEN) := case
(STARTED & (p4_line = 2) & (((p4_ticket <= p1_ticket) & (p4_ticket <= p2_ticket) & (p4_ticket <= p3_ticket) & (p4_ticket <= p5_ticket) & (p4_ticket <= p6_ticket) & (p4_ticket <= p7_ticket)) |(!p1_TOKEN & !p2_TOKEN & !p3_TOKEN))) : TRUE;
TRUE : p4_TOKEN;
esac;
init(p5_TOKEN) := FALSE;
next(p5_TOKEN) := case
(STARTED & (p5_line = 2) & (((p5_ticket <= p1_ticket) & (p5_ticket <= p2_ticket) & (p5_ticket <= p3_ticket) & (p5_ticket <= p4_ticket) &(p5_ticket <= p6_ticket) & (p5_ticket <= p7_ticket)) |(!p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN))) : TRUE;
TRUE : p5_TOKEN;
esac;
init(p6_TOKEN) := FALSE;
next(p6_TOKEN) := case
(STARTED & (p6_line = 2) & (((p6_ticket <= p1_ticket) & (p6_ticket <= p2_ticket) & (p6_ticket <= p3_ticket) & (p6_ticket <= p4_ticket) &(p6_ticket <= p5_ticket) & (p6_ticket <= p7_ticket)) | (!p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN))) : TRUE;
TRUE : p6_TOKEN;
esac;
init(p7_TOKEN) := FALSE;
next(p7_TOKEN) := case
(STARTED & (p7_line = 2) & (((p7_ticket <= p1_ticket) & (p7_ticket <= p2_ticket) & (p7_ticket <= p3_ticket) & (p7_ticket <= p4_ticket) &(p7_ticket <= p5_ticket) & (p7_ticket <= p6_ticket)) | (!p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN))) : TRUE;
TRUE : p7_TOKEN;
esac;
init(p1_ticket) := 7; -- set to MAX
init(p2_ticket) := 7; -- set to MAX
init(p3_ticket) := 7; -- set to MAX
init(p4_ticket) := 7; -- set to MAX
init(p5_ticket) := 7; -- set to MAX
init(p6_ticket) := 7; -- set to MAX
init(p7_ticket) := 7; -- set to MAX
init(p1_line) := 0;
init(p2_line) := 0;
init(p3_line) := 0;
init(p4_line) := 0;
init(p5_line) := 0;
init(p6_line) := 0;
init(p7_line) := 0;
init(MAX_ticket):= 0;
next(MAX_ticket):=
case
(MAX_ticket=7): 0; --reset
((p1_line=1) | (p2_line=1) | (p3_line=1) | (p4_line=1) | (p5_line=1) | (p6_line=1) | (p7_line=1)): (MAX_ticket+1);
TRUE: MAX_ticket;
esac;
next(p1_line) :=
case
(p1_line=0) : {0,1}; -- stay, or proceed
(p1_line=1) : {2}; -- draw ticket
((p1_line=2) & !p1_TOKEN) : {2}; -- check TOKEN
((p1_line=2) & p1_TOKEN) : {3}; -- check TOKEN
(p1_line=3) : {3, 4}; -- stay in critical section, or leave
(p1_line=4) : {0}; -- back to starting point
TRUE: p1_line;
esac;
next(p1_ticket):=
case
(MAX_ticket=7): 0; --reset
(p1_line=1): MAX_ticket+1;
TRUE: p1_ticket;
esac;
next(p2_line) :=
case
(p2_line=0) : {0,1}; -- stay, or proceed
(p2_line=1) : {2};
((p2_line=2) & !p2_TOKEN): {2}; -- check TOKEN
((p2_line=2) & p2_TOKEN): {3}; -- check TOKEN
(p2_line=3) : {3, 4}; -- stay in critical section, or leave
(p2_line=4) : {0}; -- back to starting point
TRUE: p2_line;
esac;
next(p2_ticket):=
case
(MAX_ticket=7): 0; --reset
(p2_line=1): MAX_ticket+1;
TRUE: p2_ticket;
esac;
next(p3_line) :=
case
(p3_line=0) : {0}; -- stay, or proceed
(p3_line=1) : {2};
((p3_line=2) & !p3_TOKEN) : 2 ; -- check TOKEN
((p3_line=2) & p3_TOKEN) : 3 ; -- check TOKEN
(p3_line=3) : {3, 4}; -- stay in critical section, or leave
(p3_line=4) : {0}; -- back to starting point
TRUE: p3_line;
esac;
next(p3_ticket):=
case
(MAX_ticket=7): 0; --reset
(p3_line=1): (MAX_ticket+1);
TRUE: p3_ticket;
esac;
next(p4_line) :=
case
(p4_line=0) : {0}; -- stay, or proceed
(p4_line=1) : {2};
((p4_line=2) & !p4_TOKEN) : 2 ; -- check TOKEN
((p4_line=2) & p4_TOKEN) : 3 ; -- check TOKEN
(p4_line=3) : {3, 4}; -- stay in critical section, or leave
(p4_line=4) : {0}; -- back to starting point
TRUE: p4_line;
esac;
next(p4_ticket):=
case
(MAX_ticket=7): 0; --reset
(p4_line=1): (MAX_ticket+1);
TRUE: p4_ticket;
esac;
next(p5_line) :=
case
(p5_line=0) : {0}; -- stay, or proceed
(p5_line=1) : {2};
((p5_line=2) & !p5_TOKEN) : 2 ; -- check TOKEN
((p5_line=2) & p5_TOKEN) : 3 ; -- check TOKEN
(p5_line=3) : {3, 4}; -- stay in critical section, or leave
(p5_line=4) : {0}; -- back to starting point
TRUE: p5_line;
esac;
next(p5_ticket):=
case
(MAX_ticket=7): 0; --reset
(p5_line=1): (MAX_ticket+1);
TRUE: p5_ticket;
esac;
next(p6_line) :=
case
(p6_line=0) : {0}; -- stay, or proceed
(p6_line=1) : {2};
((p6_line=2) & !p6_TOKEN) : 2 ; -- check TOKEN
((p6_line=2) & p6_TOKEN) : 3 ; -- check TOKEN
(p6_line=3) : {3, 4}; -- stay in critical section, or leave
(p6_line=4) : {0}; -- back to starting point
TRUE: p6_line;
esac;
next(p6_ticket):=
case
(MAX_ticket=7): 0; --reset
(p6_line=1): (MAX_ticket+1);
TRUE: p6_ticket;
esac;
next(p7_line) :=
case
(p7_line=0) : {0}; -- stay, or proceed
(p7_line=1) : {2};
((p7_line=2) & !p7_TOKEN) : 2 ; -- check TOKEN
((p7_line=2) & p7_TOKEN) : 3 ; -- check TOKEN
(p7_line=3) : {3, 4}; -- stay in critical section, or leave
(p7_line=4) : {0}; -- back to starting point
TRUE: p7_line;
esac;
next(p7_ticket):=
case
(MAX_ticket=7): 0; --reset
(p7_line=1): (MAX_ticket+1);
TRUE: p7_ticket;
esac;
--BAKERY ALGORITHM
MODULE main
VAR
p1_ticket: 0..9; -- the ticket number of p1
p2_ticket: 0..9; -- the ticket number of p2
p3_ticket: 0..9; -- the ticket number of p3
p4_ticket: 0..9; -- the ticket number of p4
p5_ticket: 0..9; -- the ticket number of p5
p6_ticket: 0..9; -- the ticket number of p6
p7_ticket: 0..9; -- the ticket number of p7
p8_ticket: 0..9; -- the ticket number of p8
p9_ticket: 0..9; -- the ticket number of p9
MAX_ticket: 0..9;
p1_line: 0..4;
p2_line: 0..4;
p3_line: 0..4;
p4_line: 0..4;
p5_line: 0..4;
p6_line: 0..4;
p7_line: 0..4;
p8_line: 0..4;
p9_line: 0..4;
ASSIGN
init(p1_ticket) := 9; -- set to MAX
init(p2_ticket) := 9; -- set to MAX
init(p3_ticket) := 9; -- set to MAX
init(p4_ticket) := 9; -- set to MAX
init(p5_ticket) := 9; -- set to MAX
init(p6_ticket) := 9; -- set to MAX
init(p7_ticket) := 9; -- set to MAX
init(p8_ticket) := 9; -- set to MAX
init(p9_ticket) := 9; -- set to MAX
init(p1_line) := 0;
init(p2_line) := 0;
init(p3_line) := 0;
init(p4_line) := 0;
init(p5_line) := 0;
init(p6_line) := 0;
init(p7_line) := 0;
init(p8_line) := 0;
init(p9_line) := 0;
init(MAX_ticket):= 0;
next(MAX_ticket):=
case
(MAX_ticket=9): 0; --reset
((p1_line=1) | (p2_line=1) | (p3_line=1) | (p4_line=1) | (p5_line=1) | (p6_line=1) | (p7_line=1) | (p8_line=1) | (p9_line=1)): (MAX_ticket+1);
TRUE: MAX_ticket;
esac;
next(p1_line) :=
case
(p1_line=0) : {0,1}; -- stay, or proceed
(p1_line=1) : {2}; -- draw ticket
(p1_line=2 & !p1_TOKEN) : {2}; -- check TOKEN
(p1_line=2 & p1_TOKEN) : {3}; -- check TOKEN
(p1_line=3) : {3, 4}; -- stay in critical section, or leave
(p1_line=4) : {0}; -- back to starting point
TRUE: p1_line;
esac;
next(p1_ticket):=
case
(MAX_ticket=9): 0; --reset
(p1_line=1): MAX_ticket+1;
TRUE: p1_ticket;
esac;
next(p2_line) :=
case
(p2_line=0) : {0,1}; -- stay, or proceed
(p2_line=1) : {2};
(p2_line=2 & !p2_TOKEN): {2}; -- check TOKEN
(p2_line=2 & p2_TOKEN): {3}; -- check TOKEN
(p2_line=3) : {3, 4}; -- stay in critical section, or leave
(p2_line=4) : {0}; -- back to starting point
TRUE: p2_line;
esac;
next(p2_ticket):=
case
(MAX_ticket=9): 0; --reset
(p2_line=1): MAX_ticket+1;
TRUE: p2_ticket;
esac;
next(p3_line) :=
case
(p3_line=0) : {0}; -- stay, or proceed
(p3_line=1) : {2};
(p3_line=2 & !p3_TOKEN) : 2 ; -- check TOKEN
(p3_line=2 & p3_TOKEN) : 3 ; -- check TOKEN
(p3_line=3) : {3, 4}; -- stay in critical section, or leave
(p3_line=4) : {0}; -- back to starting point
TRUE: p3_line;
esac;
next(p3_ticket):=
case
(MAX_ticket=9): 0; --reset
(p3_line=1): MAX_ticket+1;
TRUE: p3_ticket;
esac;
next(p4_line) :=
case
(p4_line=0) : {0}; -- stay, or proceed
(p4_line=1) : {2};
(p4_line=2 & !p4_TOKEN) : 2 ; -- check TOKEN
(p4_line=2 & p4_TOKEN) : 3 ; -- check TOKEN
(p4_line=3) : {3, 4}; -- stay in critical section, or leave
(p4_line=4) : {0}; -- back to starting point
TRUE: p4_line;
esac;
next(p4_ticket):=
case
(MAX_ticket=9): 0; --reset
(p4_line=1): MAX_ticket+1;
TRUE: p4_ticket;
esac;
next(p5_line) :=
case
(p5_line=0) : {0}; -- stay, or proceed
(p5_line=1) : {2};
(p5_line=2 & !p5_TOKEN) : 2 ; -- check TOKEN
(p5_line=2 & p5_TOKEN) : 3 ; -- check TOKEN
(p5_line=3) : {3, 4}; -- stay in critical section, or leave
(p5_line=4) : {0}; -- back to starting point
TRUE: p5_line;
esac;
next(p5_ticket):=
case
(MAX_ticket=9): 0; --reset
(p5_line=1): MAX_ticket+1;
TRUE: p5_ticket;
esac;
next(p6_line) :=
case
(p6_line=0) : {0}; -- stay, or proceed
(p6_line=1) : {2};
(p6_line=2 & !p6_TOKEN) : 2 ; -- check TOKEN
(p6_line=2 & p6_TOKEN) : 3 ; -- check TOKEN
(p6_line=3) : {3, 4}; -- stay in critical section, or leave
(p6_line=4) : {0}; -- back to starting point
TRUE: p6_line;
esac;
next(p6_ticket):=
case
(MAX_ticket=9): 0; --reset
(p6_line=1): MAX_ticket+1;
TRUE: p6_ticket;
esac;
next(p7_line) :=
case
(p7_line=0) : {0}; -- stay, or proceed
(p7_line=1) : {2};
(p7_line=2 & !p7_TOKEN) : 2 ; -- check TOKEN
(p7_line=2 & p7_TOKEN) : 3 ; -- check TOKEN
(p7_line=3) : {3, 4}; -- stay in critical section, or leave
(p7_line=4) : {0}; -- back to starting point
TRUE: p7_line;
esac;
next(p7_ticket):=
case
(MAX_ticket=9): 0; --reset
(p7_line=1): MAX_ticket+1;
TRUE: p7_ticket;
esac;
next(p8_line) :=
case
(p8_line=0) : {0}; -- stay, or proceed
(p8_line=1) : {2};
(p8_line=2 & !p8_TOKEN) : 2 ; -- check TOKEN
(p8_line=2 & p8_TOKEN) : 3 ; -- check TOKEN
(p8_line=3) : {3, 4}; -- stay in critical section, or leave
(p8_line=4) : {0}; -- back to starting point
TRUE: p8_line;
esac;
next(p8_ticket):=
case
(MAX_ticket=9): 0; --reset
(p8_line=1): MAX_ticket+1;
TRUE: p8_ticket;
esac;
next(p9_line) :=
case
(p9_line=0) : {0}; -- stay, or proceed
(p9_line=1) : {2};
(p9_line=2 & !p9_TOKEN) : 2 ; -- check TOKEN
(p9_line=2 & p9_TOKEN) : 3 ; -- check TOKEN
(p9_line=3) : {3, 4}; -- stay in critical section, or leave
(p9_line=4) : {0}; -- back to starting point
TRUE: p9_line;
esac;
next(p9_ticket):=
case
(MAX_ticket=9): 0; --reset
(p9_line=1): MAX_ticket+1;
TRUE: p9_ticket;
esac;
DEFINE
STARTED := (p1_line!=0 | p2_line!=0 | p3_line!=0 | p4_line!=0 | p5_line!=0 | p6_line!=0 | p7_line!=0 | p8_line!=0 | p9_line!=0);
p1_TOKEN := STARTED & (p1_line=2) & ((p1_ticket <= p2_ticket) & (p1_ticket <= p3_ticket) & (p1_ticket <= p4_ticket) & (p1_ticket <= p5_ticket) & (p1_ticket <= p6_ticket) & (p1_ticket <= p7_ticket) & (p1_ticket <= p8_ticket) & (p1_ticket <= p9_ticket));
p2_TOKEN := STARTED & (p2_line=2) & (((p2_ticket <= p1_ticket) & (p2_ticket <= p3_ticket) & (p2_ticket <= p4_ticket) & (p2_ticket <= p5_ticket) & (p2_ticket <= p6_ticket) & (p2_ticket <= p7_ticket) & (p2_ticket <= p8_ticket) & (p2_ticket <= p9_ticket)) | !p1_TOKEN);
p3_TOKEN := STARTED & (p3_line=2) & (((p3_ticket <= p1_ticket) & (p3_ticket <= p2_ticket) & (p3_ticket <= p4_ticket) & (p3_ticket <= p5_ticket) & (p3_ticket <= p6_ticket) & (p3_ticket <= p7_ticket) & (p3_ticket <= p8_ticket) & (p3_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN);
p4_TOKEN := STARTED & (p4_line=2) & (((p4_ticket <= p1_ticket) & (p4_ticket <= p2_ticket) & (p4_ticket <= p3_ticket) & (p4_ticket <= p5_ticket) & (p4_ticket <= p6_ticket) & (p4_ticket <= p7_ticket) & (p4_ticket <= p8_ticket) & (p4_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN);
p5_TOKEN := STARTED & (p5_line=2) & (((p5_ticket <= p1_ticket) & (p5_ticket <= p2_ticket) & (p5_ticket <= p3_ticket) & (p5_ticket <= p4_ticket) & (p5_ticket <= p6_ticket) & (p5_ticket <= p7_ticket) & (p5_ticket <= p8_ticket) & (p5_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN);
p6_TOKEN := STARTED & (p6_line=2) & (((p6_ticket <= p1_ticket) & (p6_ticket <= p2_ticket) & (p6_ticket <= p3_ticket) & (p6_ticket <= p4_ticket) & (p6_ticket <= p5_ticket) & (p6_ticket <= p7_ticket) & (p6_ticket <= p8_ticket) & (p6_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN);
p7_TOKEN := STARTED & (p7_line=2) & (((p7_ticket <= p1_ticket) & (p7_ticket <= p2_ticket) & (p7_ticket <= p3_ticket) & (p7_ticket <= p4_ticket) & (p7_ticket <= p5_ticket) & (p7_ticket <= p6_ticket) & (p7_ticket <= p8_ticket) & (p7_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN);
p8_TOKEN := STARTED & (p8_line=2) & (((p8_ticket <= p1_ticket) & (p8_ticket <= p2_ticket) & (p8_ticket <= p3_ticket) & (p8_ticket <= p4_ticket) & (p8_ticket <= p5_ticket) & (p8_ticket <= p6_ticket) & (p8_ticket <= p7_ticket) & (p8_ticket <= p9_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN);
p9_TOKEN := STARTED & (p9_line=2) & (((p9_ticket <= p1_ticket) & (p9_ticket <= p2_ticket) & (p9_ticket <= p3_ticket) & (p9_ticket <= p4_ticket) & (p9_ticket <= p5_ticket) & (p9_ticket <= p6_ticket) & (p9_ticket <= p7_ticket) & (p9_ticket <= p8_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN & !p8_TOKEN);
--BAKERY ALGORITHM
MODULE main
VAR
p1_ticket: 0..11; -- the ticket number of p1
p2_ticket: 0..11; -- the ticket number of p2
p3_ticket: 0..11; -- the ticket number of p3
p4_ticket: 0..11; -- the ticket number of p4
p5_ticket: 0..11; -- the ticket number of p5
p6_ticket: 0..11; -- the ticket number of p6
p7_ticket: 0..11; -- the ticket number of p7
p8_ticket: 0..11; -- the ticket number of p8
p9_ticket: 0..11; -- the ticket number of p9
p10_ticket: 0..11; -- the ticket number of p10
p11_ticket: 0..11; -- the ticket number of p11
MAX_ticket: 0..11;
p1_line: 0..4;
p2_line: 0..4;
p3_line: 0..4;
p4_line: 0..4;
p5_line: 0..4;
p6_line: 0..4;
p7_line: 0..4;
p8_line: 0..4;
p9_line: 0..4;
p10_line: 0..4;
p11_line: 0..4;
ASSIGN
init(p1_ticket) := 11; -- set to MAX
init(p2_ticket) := 11; -- set to MAX
init(p3_ticket) := 11; -- set to MAX
init(p4_ticket) := 11; -- set to MAX
init(p5_ticket) := 11; -- set to MAX
init(p6_ticket) := 11; -- set to MAX
init(p7_ticket) := 11; -- set to MAX
init(p8_ticket) := 11; -- set to MAX
init(p9_ticket) := 11; -- set to MAX
init(p10_ticket) := 11; -- set to MAX
init(p11_ticket) := 11; -- set to MAX
init(p1_line) := 0;
init(p2_line) := 0;
init(p3_line) := 0;
init(p4_line) := 0;
init(p5_line) := 0;
init(p6_line) := 0;
init(p7_line) := 0;
init(p8_line) := 0;
init(p9_line) := 0;
init(p10_line) := 0;
init(p11_line) := 0;
init(MAX_ticket):= 0;
next(MAX_ticket):=
case
(MAX_ticket=11): 0; --reset
((p1_line=1) | (p2_line=1) | (p3_line=1) | (p4_line=1) | (p5_line=1) | (p6_line=1) | (p7_line=1) | (p8_line=1) | (p9_line=1) | (p10_line=1) | (p11_line=1)): MAX_ticket+1;
TRUE: MAX_ticket;
esac;
next(p1_line) :=
case
(p1_line=0) : {0,1}; -- stay, or proceed
(p1_line=1) : {2}; -- draw ticket
(p1_line=2 & !p1_TOKEN) : {2}; -- check TOKEN
(p1_line=2 & p1_TOKEN) : {3}; -- check TOKEN
(p1_line=3) : {3, 4}; -- stay in critical section, or leave
(p1_line=4) : {0}; -- back to starting point
TRUE: p1_line;
esac;
next(p1_ticket):=
case
(MAX_ticket=11): 0; --reset
(p1_line=1): MAX_ticket+1;
TRUE: p1_ticket;
esac;
next(p2_line) :=
case
(p2_line=0) : {0,1}; -- stay, or proceed
(p2_line=1) : {2};
(p2_line=2 & !p2_TOKEN): {2}; -- check TOKEN
(p2_line=2 & p2_TOKEN): {3}; -- check TOKEN
(p2_line=3) : {3, 4}; -- stay in critical section, or leave
(p2_line=4) : {0}; -- back to starting point
TRUE: p2_line;
esac;
next(p2_ticket):=
case
(MAX_ticket=11): 0; --reset
(p2_line=1): MAX_ticket+1;
TRUE: p2_ticket;
esac;
next(p3_line) :=
case
(p3_line=0) : {0}; -- stay, or proceed
(p3_line=1) : {2};
(p3_line=2 & !p3_TOKEN) : 2 ; -- check TOKEN
(p3_line=2 & p3_TOKEN) : 3 ; -- check TOKEN
(p3_line=3) : {3, 4}; -- stay in critical section, or leave
(p3_line=4) : {0}; -- back to starting point
TRUE: p3_line;
esac;
next(p3_ticket):=
case
(MAX_ticket=11): 0; --reset
(p3_line=1): MAX_ticket+1;
TRUE: p3_ticket;
esac;
next(p4_line) :=
case
(p4_line=0) : {0}; -- stay, or proceed
(p4_line=1) : {2};
(p4_line=2 & !p4_TOKEN) : 2 ; -- check TOKEN
(p4_line=2 & p4_TOKEN) : 3 ; -- check TOKEN
(p4_line=3) : {3, 4}; -- stay in critical section, or leave
(p4_line=4) : {0}; -- back to starting point
TRUE: p4_line;
esac;
next(p4_ticket):=
case
(MAX_ticket=11): 0; --reset
(p4_line=1): MAX_ticket+1;
TRUE: p4_ticket;
esac;
next(p5_line) :=
case
(p5_line=0) : {0}; -- stay, or proceed
(p5_line=1) : {2};
(p5_line=2 & !p5_TOKEN) : 2 ; -- check TOKEN
(p5_line=2 & p5_TOKEN) : 3 ; -- check TOKEN
(p5_line=3) : {3, 4}; -- stay in critical section, or leave
(p5_line=4) : {0}; -- back to starting point
TRUE: p5_line;
esac;
next(p5_ticket):=
case
(MAX_ticket=11): 0; --reset
(p5_line=1): MAX_ticket+1;
TRUE: p5_ticket;
esac;
next(p6_line) :=
case
(p6_line=0) : {0}; -- stay, or proceed
(p6_line=1) : {2};
(p6_line=2 & !p6_TOKEN) : 2 ; -- check TOKEN
(p6_line=2 & p6_TOKEN) : 3 ; -- check TOKEN
(p6_line=3) : {3, 4}; -- stay in critical section, or leave
(p6_line=4) : {0}; -- back to starting point
TRUE: p6_line;
esac;
next(p6_ticket):=
case
(MAX_ticket=11): 0; --reset
(p6_line=1): MAX_ticket+1;
TRUE: p6_ticket;
esac;
next(p7_line) :=
case
(p7_line=0) : {0}; -- stay, or proceed
(p7_line=1) : {2};
(p7_line=2 & !p7_TOKEN) : 2 ; -- check TOKEN
(p7_line=2 & p7_TOKEN) : 3 ; -- check TOKEN
(p7_line=3) : {3, 4}; -- stay in critical section, or leave
(p7_line=4) : {0}; -- back to starting point
TRUE: p7_line;
esac;
next(p7_ticket):=
case
(MAX_ticket=11): 0; --reset
(p7_line=1): MAX_ticket+1;
TRUE: p7_ticket;
esac;
next(p8_line) :=
case
(p8_line=0) : {0}; -- stay, or proceed
(p8_line=1) : {2};
(p8_line=2 & !p8_TOKEN) : 2 ; -- check TOKEN
(p8_line=2 & p8_TOKEN) : 3 ; -- check TOKEN
(p8_line=3) : {3, 4}; -- stay in critical section, or leave
(p8_line=4) : {0}; -- back to starting point
TRUE: p8_line;
esac;
next(p8_ticket):=
case
(MAX_ticket=11): 0; --reset
(p8_line=1): MAX_ticket+1;
TRUE: p8_ticket;
esac;
next(p9_line) :=
case
(p9_line=0) : {0}; -- stay, or proceed
(p9_line=1) : {2};
(p9_line=2 & !p9_TOKEN) : 2 ; -- check TOKEN
(p9_line=2 & p9_TOKEN) : 3 ; -- check TOKEN
(p9_line=3) : {3, 4}; -- stay in critical section, or leave
(p9_line=4) : {0}; -- back to starting point
TRUE: p9_line;
esac;
next(p9_ticket):=
case
(MAX_ticket=11): 0; --reset
(p9_line=1): MAX_ticket+1;
TRUE: p9_ticket;
esac;
next(p10_line) :=
case
(p10_line=0) : {0}; -- stay, or proceed
(p10_line=1) : {2};
(p10_line=2 & !p10_TOKEN) : 2 ; -- check TOKEN
(p10_line=2 & p10_TOKEN) : 3 ; -- check TOKEN
(p10_line=3) : {3, 4}; -- stay in critical section, or leave
(p10_line=4) : {0}; -- back to starting point
TRUE: p10_line;
esac;
next(p10_ticket):=
case
(MAX_ticket=11): 0; --reset
(p10_line=1): MAX_ticket+1;
TRUE: p10_ticket;
esac;
next(p11_line) :=
case
(p11_line=0) : {0}; -- stay, or proceed
(p11_line=1) : {2};
(p11_line=2 & !p11_TOKEN) : 2 ; -- check TOKEN
(p11_line=2 & p11_TOKEN) : 3 ; -- check TOKEN
(p11_line=3) : {3, 4}; -- stay in critical section, or leave
(p11_line=4) : {0}; -- back to starting point
TRUE: p9_line;
esac;
next(p11_ticket):=
case
(MAX_ticket=11): 0; --reset
(p11_line=1): MAX_ticket+1;
TRUE: p11_ticket;
esac;
DEFINE
STARTED := (p1_line!=0 | p2_line!=0 | p3_line!=0 | p4_line!=0 | p5_line!=0 | p6_line!=0 | p7_line!=0 | p8_line!=0 | p9_line!=0 | p10_line!=0 | p11_line!=0);
p1_TOKEN := STARTED & (p1_line=2) & ((p1_ticket <= p2_ticket) & (p1_ticket <= p3_ticket) & (p1_ticket <= p4_ticket) & (p1_ticket <= p5_ticket) & (p1_ticket <= p6_ticket) & (p1_ticket <= p7_ticket) & (p1_ticket <= p8_ticket) & (p1_ticket <= p9_ticket) & (p1_ticket <= p10_ticket) & (p1_ticket <= p11_ticket));
p2_TOKEN := STARTED & (p2_line=2) & (((p2_ticket <= p1_ticket) & (p2_ticket <= p3_ticket) & (p2_ticket <= p4_ticket) & (p2_ticket <= p5_ticket) & (p2_ticket <= p6_ticket) & (p2_ticket <= p7_ticket) & (p2_ticket <= p8_ticket) & (p2_ticket <= p9_ticket) & (p2_ticket <= p10_ticket) & (p2_ticket <= p11_ticket)) | !p1_TOKEN);
p3_TOKEN := STARTED & (p3_line=2) & (((p3_ticket <= p1_ticket) & (p3_ticket <= p2_ticket) & (p3_ticket <= p4_ticket) & (p3_ticket <= p5_ticket) & (p3_ticket <= p6_ticket) & (p3_ticket <= p7_ticket) & (p3_ticket <= p8_ticket) & (p3_ticket <= p9_ticket) & (p3_ticket <= p10_ticket) & (p3_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN);
p4_TOKEN := STARTED & (p4_line=2) & (((p4_ticket <= p1_ticket) & (p4_ticket <= p2_ticket) & (p4_ticket <= p3_ticket) & (p4_ticket <= p5_ticket) & (p4_ticket <= p6_ticket) & (p4_ticket <= p7_ticket) & (p4_ticket <= p8_ticket) & (p4_ticket <= p9_ticket) & (p4_ticket <= p10_ticket) & (p4_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN);
p5_TOKEN := STARTED & (p5_line=2) & (((p5_ticket <= p1_ticket) & (p5_ticket <= p2_ticket) & (p5_ticket <= p3_ticket) & (p5_ticket <= p4_ticket) & (p5_ticket <= p6_ticket) & (p5_ticket <= p7_ticket) & (p5_ticket <= p8_ticket) & (p5_ticket <= p9_ticket) & (p5_ticket <= p10_ticket) & (p5_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN);
p6_TOKEN := STARTED & (p6_line=2) & (((p6_ticket <= p1_ticket) & (p6_ticket <= p2_ticket) & (p6_ticket <= p3_ticket) & (p6_ticket <= p4_ticket) & (p6_ticket <= p5_ticket) & (p6_ticket <= p7_ticket) & (p6_ticket <= p8_ticket) & (p6_ticket <= p9_ticket) & (p6_ticket <= p10_ticket) & (p6_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN);
p7_TOKEN := STARTED & (p7_line=2) & (((p7_ticket <= p1_ticket) & (p7_ticket <= p2_ticket) & (p7_ticket <= p3_ticket) & (p7_ticket <= p4_ticket) & (p7_ticket <= p5_ticket) & (p7_ticket <= p6_ticket) & (p7_ticket <= p8_ticket) & (p7_ticket <= p9_ticket) & (p7_ticket <= p10_ticket) & (p7_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN);
p8_TOKEN := STARTED & (p8_line=2) & (((p8_ticket <= p1_ticket) & (p8_ticket <= p2_ticket) & (p8_ticket <= p3_ticket) & (p8_ticket <= p4_ticket) & (p8_ticket <= p5_ticket) & (p8_ticket <= p6_ticket) & (p8_ticket <= p7_ticket) & (p8_ticket <= p9_ticket) & (p8_ticket <= p10_ticket) & (p8_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN);
p9_TOKEN := STARTED & (p9_line=2) & (((p9_ticket <= p1_ticket) & (p9_ticket <= p2_ticket) & (p9_ticket <= p3_ticket) & (p9_ticket <= p4_ticket) & (p9_ticket <= p5_ticket) & (p9_ticket <= p6_ticket) & (p9_ticket <= p7_ticket) & (p9_ticket <= p8_ticket) & (p9_ticket <= p10_ticket) & (p9_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN & !p8_TOKEN);
p10_TOKEN := STARTED & (p10_line=2) & (((p10_ticket <= p1_ticket) & (p10_ticket <= p2_ticket) & (p10_ticket <= p3_ticket) & (p10_ticket <= p4_ticket) & (p10_ticket <= p5_ticket) & (p10_ticket <= p6_ticket) & (p10_ticket <= p7_ticket) & (p10_ticket <= p8_ticket) & (p10_ticket <= p9_ticket) & (p10_ticket <= p11_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN & !p8_TOKEN & !p9_TOKEN);
p11_TOKEN := STARTED & (p11_line=2) & (((p11_ticket <= p1_ticket) & (p11_ticket <= p2_ticket) & (p11_ticket <= p3_ticket) & (p11_ticket <= p4_ticket) & (p11_ticket <= p5_ticket) & (p11_ticket <= p6_ticket) & (p11_ticket <= p7_ticket) & (p11_ticket <= p8_ticket) & (p11_ticket <= p9_ticket) & (p11_ticket <= p10_ticket)) | !p1_TOKEN & !p2_TOKEN & !p3_TOKEN & !p4_TOKEN & !p5_TOKEN & !p6_TOKEN & !p7_TOKEN & !p8_TOKEN & !p9_TOKEN & !p10_TOKEN);
The HyperLTL formula(s)¶
Symmetry can be expressed by relating pairs of traces that exchange process identifiers yet follow the same scheduling choices. The formulas below progressively reinforce the equality constraints on ticket selection and tie-breaking. HyperQB reports SAT for the standard Bakery implementation, producing witnesses that show how lower-numbered processes retain priority even when tickets match.
The predicate \(sym(x_{\pi_A}, x_{\pi_B})\) asserts that traces \(\pi_A\) and \(\pi_B\) coincide up to a swap of process
identifiers; select and pause capture the scheduler state; and sym_break records which process wins the tie after
equal tickets. The program counter \(pc(P_n)\) tracks the stage of process \(P_n\) in the Bakery protocol. Together these
constraints detect any trace where identifier swapping changes the observed behaviour.
Forall A . Exists B .
G(
(
(p1_TOKEN[A] = p2_TOKEN[B])
&(p2_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p2_line[B])
&(p2_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p3_line[B])
&(p3_line[A] = p1_line[B])
)
&
(
(p2_line[A] = p3_line[B])
&(p3_line[A] = p2_line[B])
)
)
Forall A . Exists B .
G(
(
(p1_TOKEN[A] = p2_TOKEN[B])
&(p2_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p2_line[B])
&(p2_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p3_line[B])
&(p3_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p4_line[B])
&(p4_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p5_line[B])
&(p5_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p6_line[B])
&(p6_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p7_line[B])
&(p7_line[A] = p1_line[B])
)
&
(
(p2_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p3_line[B])
&(p3_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p4_line[B])
&(p4_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p5_line[B])
&(p5_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p6_line[B])
&(p6_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p7_line[B])
&(p7_line[A] = p2_line[B])
)
&
(
(p3_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p4_line[B])
&(p4_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p5_line[B])
&(p5_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p6_line[B])
&(p6_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p7_line[B])
&(p7_line[A] = p3_line[B])
)
&
(
(p4_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p5_line[B])
&(p5_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p6_line[B])
&(p6_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p7_line[B])
&(p7_line[A] = p4_line[B])
)
&
(
(p5_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p6_line[B])
&(p6_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p7_line[B])
&(p7_line[A] = p5_line[B])
)
&
(
(p6_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p7_line[B])
&(p7_line[A] = p6_line[B])
)
)
Forall A . Exists B .
G(
(
(p1_TOKEN[A] = p2_TOKEN[B])
&(p2_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p2_line[B])
&(p2_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p3_line[B])
&(p3_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p4_line[B])
&(p4_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p5_line[B])
&(p5_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p6_line[B])
&(p6_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p7_line[B])
&(p7_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p8_line[B])
&(p8_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p9_line[B])
&(p9_line[A] = p1_line[B])
)
&
(
(p2_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p3_line[B])
&(p3_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p4_line[B])
&(p4_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p5_line[B])
&(p5_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p6_line[B])
&(p6_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p7_line[B])
&(p7_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p8_line[B])
&(p8_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p9_line[B])
&(p9_line[A] = p2_line[B])
)
&
(
(p3_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p4_line[B])
&(p4_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p5_line[B])
&(p5_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p6_line[B])
&(p6_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p7_line[B])
&(p7_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p8_line[B])
&(p8_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p9_line[B])
&(p9_line[A] = p3_line[B])
)
&
(
(p4_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p5_line[B])
&(p5_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p6_line[B])
&(p6_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p7_line[B])
&(p7_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p8_line[B])
&(p8_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p9_line[B])
&(p9_line[A] = p4_line[B])
)
&
(
(p5_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p6_line[B])
&(p6_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p7_line[B])
&(p7_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p8_line[B])
&(p8_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p9_line[B])
&(p9_line[A] = p5_line[B])
)
&
(
(p6_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p7_line[B])
&(p7_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p8_line[B])
&(p8_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p9_line[B])
&(p9_line[A] = p6_line[B])
)
&
(
(p7_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p8_line[B])
&(p8_line[A] = p7_line[B])
)
&
(
(p7_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p9_line[B])
&(p9_line[A] = p7_line[B])
)
&
(
(p8_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p8_TOKEN[B])
&(p8_line[A] = p9_line[B])
&(p9_line[A] = p8_line[B])
)
)
Forall A . Exists B .
G(
(
(p1_TOKEN[A] = p2_TOKEN[B])
&(p2_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p2_line[B])
&(p2_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p3_line[B])
&(p3_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p4_line[B])
&(p4_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p5_line[B])
&(p5_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p6_line[B])
&(p6_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p7_line[B])
&(p7_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p8_line[B])
&(p8_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p9_line[B])
&(p9_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p10_line[B])
&(p10_line[A] = p1_line[B])
)
&
(
(p1_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p1_TOKEN[B])
&(p1_line[A] = p11_line[B])
&(p11_line[A] = p1_line[B])
)
&
(
(p2_TOKEN[A] = p3_TOKEN[B])
&(p3_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p3_line[B])
&(p3_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p4_line[B])
&(p4_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p5_line[B])
&(p5_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p6_line[B])
&(p6_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p7_line[B])
&(p7_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p8_line[B])
&(p8_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p9_line[B])
&(p9_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p10_line[B])
&(p10_line[A] = p2_line[B])
)
&
(
(p2_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p2_TOKEN[B])
&(p2_line[A] = p11_line[B])
&(p11_line[A] = p2_line[B])
)
&
(
(p3_TOKEN[A] = p4_TOKEN[B])
&(p4_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p4_line[B])
&(p4_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p5_line[B])
&(p5_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p6_line[B])
&(p6_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p7_line[B])
&(p7_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p8_line[B])
&(p8_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p9_line[B])
&(p9_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p10_line[B])
&(p10_line[A] = p3_line[B])
)
&
(
(p3_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p3_TOKEN[B])
&(p3_line[A] = p11_line[B])
&(p11_line[A] = p3_line[B])
)
&
(
(p4_TOKEN[A] = p5_TOKEN[B])
&(p5_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p5_line[B])
&(p5_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p6_line[B])
&(p6_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p7_line[B])
&(p7_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p8_line[B])
&(p8_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p9_line[B])
&(p9_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p10_line[B])
&(p10_line[A] = p4_line[B])
)
&
(
(p4_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p4_TOKEN[B])
&(p4_line[A] = p11_line[B])
&(p11_line[A] = p4_line[B])
)
&
(
(p5_TOKEN[A] = p6_TOKEN[B])
&(p6_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p6_line[B])
&(p6_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p7_line[B])
&(p7_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p8_line[B])
&(p8_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p9_line[B])
&(p9_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p10_line[B])
&(p10_line[A] = p5_line[B])
)
&
(
(p5_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p5_TOKEN[B])
&(p5_line[A] = p11_line[B])
&(p11_line[A] = p5_line[B])
)
&
(
(p6_TOKEN[A] = p7_TOKEN[B])
&(p7_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p7_line[B])
&(p7_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p8_line[B])
&(p8_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p9_line[B])
&(p9_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p10_line[B])
&(p10_line[A] = p6_line[B])
)
&
(
(p6_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p6_TOKEN[B])
&(p6_line[A] = p11_line[B])
&(p11_line[A] = p6_line[B])
)
&
(
(p7_TOKEN[A] = p8_TOKEN[B])
&(p8_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p8_line[B])
&(p8_line[A] = p7_line[B])
)
&
(
(p7_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p9_line[B])
&(p9_line[A] = p7_line[B])
)
&
(
(p7_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p10_line[B])
&(p10_line[A] = p7_line[B])
)
&
(
(p7_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p7_TOKEN[B])
&(p7_line[A] = p11_line[B])
&(p11_line[A] = p7_line[B])
)
&
(
(p8_TOKEN[A] = p9_TOKEN[B])
&(p9_TOKEN[A] = p8_TOKEN[B])
&(p8_line[A] = p9_line[B])
&(p9_line[A] = p8_line[B])
)
&
(
(p8_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p8_TOKEN[B])
&(p8_line[A] = p10_line[B])
&(p10_line[A] = p8_line[B])
)
&
(
(p8_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p8_TOKEN[B])
&(p8_line[A] = p11_line[B])
&(p11_line[A] = p8_line[B])
)
&
(
(p9_TOKEN[A] = p10_TOKEN[B])
&(p10_TOKEN[A] = p9_TOKEN[B])
&(p9_line[A] = p10_line[B])
&(p10_line[A] = p9_line[B])
)
&
(
(p9_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p9_TOKEN[B])
&(p9_line[A] = p11_line[B])
&(p11_line[A] = p9_line[B])
)
&
(
(p10_TOKEN[A] = p11_TOKEN[B])
&(p11_TOKEN[A] = p10_TOKEN[B])
&(p10_line[A] = p11_line[B])
&(p11_line[A] = p10_line[B])
)
)