├── requirements.txt ├── benchmarks ├── Consensus.cfg ├── TwoPhase.cfg ├── peterson.cfg ├── two_phase_commit.cfg ├── firewall.cfg ├── tla2tools-checkall.jar ├── simple_decentralized_lock.cfg ├── lockserver.cfg ├── consensus_wo_decide.cfg ├── firewall_Ind.cfg ├── toy_consensus_epr.cfg ├── client_server_ae.cfg ├── learning_switch_i4.cfg ├── consensus_epr.cfg ├── consensus_forall.cfg ├── simple_election.cfg ├── sharded_kv.cfg ├── sharded_kv_no_lost_keys.cfg ├── consensus_forall_Ind.cfg ├── naive_consensus.cfg ├── Paxos.cfg ├── paxos_epr.cfg ├── client_server_db_ae.cfg ├── learning_switch.cfg ├── simple_election_Ind.cfg ├── MongoLoglessDynamicRaft.cfg ├── Paxos_ind.cfg ├── Consensus.config.json ├── lockserver.config.json ├── TCommit.config.json ├── Simple.config.json ├── lockserv_automaton.config.json ├── lockserv.config.json ├── quorum_leader_election.config.json ├── toy_consensus.config.json ├── toy_consensus_forall.config.json ├── peterson.config.json ├── MongoLoglessDynamicRaft_Ind.cfg ├── client_server_ae.config.json ├── firewall.config.json ├── learning_switch.config.json ├── sharded_kv_no_lost_keys.config.json ├── toy_consensus_epr.config.json ├── majorityset_leader_election.config.json ├── naive_consensus.config.json ├── sharded_kv.config.json ├── simple_election.config.json ├── SimpleRegular.config.json ├── toy_consensus.tla ├── toy_consensus_epr.tla ├── two_phase_commit.config.json ├── firewall.tla ├── TwoPhase.config.json ├── simple_decentralized_lock.config.json ├── consensus_wo_decide.config.json ├── quorum_leader_election.tla ├── simple_election.tla ├── client_server_db_ae.config.json ├── simple_decentralized_lock.tla ├── learning_switch_i4.config.json ├── consensus_forall.config.json ├── consensus_epr.config.json ├── naive_consensus.tla ├── lockserver_IndProofs.tla ├── majorityset_leader_election.tla ├── client_server_ae.tla ├── lockserver.tla ├── Consensus_IndProofs.tla ├── lockserv_automaton.tla ├── Simple_IndProofs.tla ├── lockserv.tla ├── sharded_kv.tla ├── toy_consensus_forall.tla ├── TCommit_IndProofs.tla ├── sharded_kv_no_lost_keys.tla ├── Consensus.tla ├── sharded_kv_no_lost_keys_IndProofs.tla ├── Paxos.config.json ├── MongoLoglessDynamicRaft.config.json ├── SimpleRegular_IndProofs.tla ├── quorum_leader_election_IndProofs.tla ├── two_phase_commit.tla ├── learning_switch.tla ├── peterson.tla ├── consensus_forall.tla ├── client_server_db_ae.tla ├── simple_decentralized_lock_IndProofs.tla ├── client_server_ae_IndProofs.tla ├── toy_consensus_forall_IndProofs.tla ├── consensus_wo_decide.tla ├── TCommit.tla ├── Randomization.tla ├── learning_switch_i4.tla ├── lockserv_IndProofs.tla ├── consensus_epr.tla ├── two_phase_commit_IndProofs.tla ├── toy_consensus_IndProofs.tla ├── lockserv_automaton_IndProofs.tla ├── naive_consensus_IndProofs.tla ├── toy_consensus_epr_IndProofs.tla ├── paxos_epr.tla ├── MongoStaticRaft.tla └── simple_election_IndProofs.tla ├── tla2tools-checkall.jar ├── .gitignore └── README.md /requirements.txt: -------------------------------------------------------------------------------- 1 | pyeda -------------------------------------------------------------------------------- /benchmarks/Consensus.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT Value = {v1,v2,v3} -------------------------------------------------------------------------------- /benchmarks/TwoPhase.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT RM = {r1,r2,r3} 4 | INVARIANT Test -------------------------------------------------------------------------------- /benchmarks/peterson.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | \* INVARIANT Mutex 4 | CONSTANT ProcSet = {0,1} -------------------------------------------------------------------------------- /tla2tools-checkall.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will62794/endive/HEAD/tla2tools-checkall.jar -------------------------------------------------------------------------------- /benchmarks/two_phase_commit.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT Node = {n1,n2,n3} 4 | INVARIANT Safety -------------------------------------------------------------------------------- /benchmarks/firewall.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT Node={n1,n2,n3} 4 | INVARIANT Inv 5 | INVARIANT TypeOK -------------------------------------------------------------------------------- /benchmarks/tla2tools-checkall.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will62794/endive/HEAD/benchmarks/tla2tools-checkall.jar -------------------------------------------------------------------------------- /benchmarks/simple_decentralized_lock.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT Node = {n1,n2,n3,n4} 4 | INVARIANT Inv 5 | INVARIANT IndHuman -------------------------------------------------------------------------------- /benchmarks/lockserver.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Server = {s1,s2} 5 | Client = {c1,c2} 6 | Nil = Nil 7 | INVARIANT Inv -------------------------------------------------------------------------------- /benchmarks/consensus_wo_decide.cfg: -------------------------------------------------------------------------------- 1 | INIT IInitAuto 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorums = {{n1,n2},{n2,n3},{n1,n3}} 6 | INVARIANT IndAuto -------------------------------------------------------------------------------- /benchmarks/firewall_Ind.cfg: -------------------------------------------------------------------------------- 1 | INIT IndAuto 2 | NEXT Next 3 | CONSTANT Node={n1,n2,n3} 4 | INVARIANT Inv 5 | INVARIANT TypeOK 6 | INVARIANT IndAuto 7 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/toy_consensus_epr.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorum = {{n1,n2},{n2,n3},{n1,n3}} 6 | Value = {v1,v2,v3} 7 | INVARIANT Safety -------------------------------------------------------------------------------- /benchmarks/client_server_ae.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | INVARIANT Safety 4 | CONSTANT 5 | Node={n1,n2,n3} 6 | Request={r1,r2} 7 | Response={p1,p2} 8 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/learning_switch_i4.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3,n4} 5 | Packet = {p1,p2,p3} 6 | INVARIANT Safety 7 | INVARIANT TypeOK 8 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/consensus_epr.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorum = {{n1,n2},{n1,n3},{n2,n3}} 6 | Value = {v1,v2} 7 | \* INVARIANT IndAuto 8 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/consensus_forall.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorum = {{n1,n2},{n1,n3},{n2,n3}} 6 | Value = {v1,v2} 7 | INVARIANT Safety 8 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/simple_election.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Acceptor = {a1,a2,a3} 5 | Quorum = {{a1,a2},{a1,a3},{a2,a3}} 6 | Proposer = {p1,p2} 7 | INVARIANT Safety 8 | INVARIANT TypeOK -------------------------------------------------------------------------------- /benchmarks/sharded_kv.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Key = {k1,k2,k3,k4} 5 | Value = {v1,v2,v3,v4} 6 | Node = {n1,n2,n3,n4} 7 | Nil = Nil 8 | INVARIANT Safety 9 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/sharded_kv_no_lost_keys.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Key = {k1,k2,k3,k4} 5 | Value = {v1,v2,v3} 6 | Node = {n1,n2,n3,n4} 7 | Nil = Nil 8 | INVARIANT Safety 9 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/consensus_forall_Ind.cfg: -------------------------------------------------------------------------------- 1 | INIT IInitAuto 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorum = {{n1,n2},{n1,n3},{n2,n3}} 6 | Value = {v1,v2} 7 | INVARIANT Safety 8 | INVARIANT IInv 9 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/naive_consensus.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Quorum = {{n1,n2},{n1,n3},{n2,n3}} 6 | Value = {v1,v2} 7 | \* INVARIANT IndAuto 8 | SYMMETRY Symmetry 9 | INVARIANT Test 10 | -------------------------------------------------------------------------------- /benchmarks/Paxos.cfg: -------------------------------------------------------------------------------- 1 | SPECIFICATION Spec 2 | CONSTANTS 3 | Acceptor = {a1, a2, a3} 4 | Value = {v1, v2} 5 | Quorum = {{a1, a2}, {a1, a3}, {a2, a3}} 6 | Ballot = {0,1,2} 7 | None = None 8 | 9 | INVARIANT Inv 10 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/paxos_epr.cfg: -------------------------------------------------------------------------------- 1 | SPECIFICATION Spec 2 | CONSTANTS 3 | Node = {a1, a2, a3} 4 | Value = {v1, v2} 5 | Quorum = {{a1, a2}, {a1, a3}, {a2, a3}} 6 | Round = {0,1,2} 7 | 8 | \* INVARIANT Inv 9 | SYMMETRY Symmetry 10 | INVARIANT Safety -------------------------------------------------------------------------------- /benchmarks/client_server_db_ae.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3} 5 | Request = {req1,req2,req3} 6 | Response = {res1,res2,res3} 7 | DbRequestId = {id1,id2} 8 | \* INVARIANT Safety 9 | SYMMETRY Symmetry 10 | \* INVARIANT Test -------------------------------------------------------------------------------- /benchmarks/learning_switch.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Node = {n1,n2,n3,n4} 5 | \* INVARIANT Safety 6 | \* INVARIANT Test 7 | SYMMETRY Symmetry 8 | CONSTRAINT StateConstraint 9 | \* INVARIANT Test 10 | 11 | \* INVARIANT Test 12 | \* INVARIANT A1 13 | \* INVARIANT A2 -------------------------------------------------------------------------------- /benchmarks/simple_election_Ind.cfg: -------------------------------------------------------------------------------- 1 | INIT IndAuto 2 | NEXT Next 3 | CONSTANT 4 | Acceptor = {a1,a2,a3} 5 | Quorum = {{a1,a2},{a1,a3},{a2,a3}} 6 | Proposer = {p1,p2} 7 | 8 | INVARIANT TypeOK 9 | INVARIANT Safety 10 | INVARIANT Inv132_1_0_def 11 | INVARIANT Inv96_1_1_def 12 | INVARIANT Inv200_2_2_def -------------------------------------------------------------------------------- /benchmarks/MongoLoglessDynamicRaft.cfg: -------------------------------------------------------------------------------- 1 | INIT Init 2 | NEXT Next 3 | CONSTANT 4 | Nil=Nil 5 | Server = {n1,n2,n3,n4} 6 | Secondary = Secondary 7 | Primary = Primary 8 | MaxLogLen = 0 9 | MaxTerm = 3 10 | MaxConfigVersion = 3 11 | InitTerm = 0 12 | Nat <- NatFinite 13 | CONSTRAINT StateConstraint 14 | SYMMETRY Symmetry -------------------------------------------------------------------------------- /benchmarks/Paxos_ind.cfg: -------------------------------------------------------------------------------- 1 | INIT Ind 2 | NEXT Next 3 | CONSTANTS 4 | Acceptor = {a1, a2, a3} 5 | Value = {v1, v2} 6 | Quorum = {{a1, a2}, {a1, a3}, {a2, a3}} 7 | Ballot = {0,1,2,3} 8 | None = None 9 | 10 | \* INVARIANT Inv 11 | SYMMETRY Symmetry 12 | INVARIANT Inv 13 | INVARIANT Inv79_1_0 14 | INVARIANT Inv30_1_1 15 | INVARIANT Inv41_1_2 16 | INVARIANT Inv99_1_0 -------------------------------------------------------------------------------- /benchmarks/Consensus.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "chosen = {}", 4 | "v \\in chosen" 5 | ], 6 | "preds_alt" : [], 7 | "safety" : "Inv", 8 | "constants" : "CONSTANTS\nValue={v1,v2,v3}\nv1=v1\nv2=v2\nv3=v3\n", 9 | "constraint" : "", 10 | "quant_inv" : "\\A v \\in Value : ", 11 | "quant_inv_alt" : null, 12 | "quant_vars": [], 13 | "model_consts" : "", 14 | "symmetry" : false, 15 | "typeok" : "TypeOK", 16 | "simulate" : true 17 | } -------------------------------------------------------------------------------- /benchmarks/lockserver.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "semaphore[VARS]", 4 | "VARS \\in clientlocks[VARC]", 5 | "clientlocks[VARC] = {}" 6 | ], 7 | "preds_alt" : [], 8 | "safety" : "Inv", 9 | "constants" : "CONSTANTS\nServer={s1,s2}\nClient={c1,c2}\nNil=Nil\ns1=s1\ns2=s2\nc1=c1\nc2=c2\n", 10 | "constraint" : "", 11 | "quant_inv" : "\\A VARS \\in Server : \\A VARC \\in Client : ", 12 | "quant_inv_alt" : null, 13 | "quant_vars": [], 14 | "model_consts" : "CONSTANT s1,s2,c1,c2", 15 | "symmetry" : false, 16 | "typeok" : "TypeOK", 17 | "simulate" : false 18 | } -------------------------------------------------------------------------------- /benchmarks/TCommit.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "rmState = \"working\"", 4 | "rmState = \"prepared\"", 5 | "rmState = \"committed\"", 6 | "rmState = \"aborted\"" 7 | ], 8 | "preds_alt" : [], 9 | "safety" : "TCConsistent", 10 | "constants" : "CONSTANTS\nRM={rm1,rm2,rm3}\nrm1=rm1\nrm2=rm2\nrm3=rm3\n", 11 | "constraint" : "", 12 | "quant_inv" : "\\A rm \\in RM : ", 13 | "quant_inv_alt" : null, 14 | "quant_vars": [], 15 | "model_consts" : "CONSTANT rm1,rm2,rm3", 16 | "symmetry" : false, 17 | "typeok" : "TCTypeOK", 18 | "simulate" : false 19 | } -------------------------------------------------------------------------------- /benchmarks/Simple.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "pc[VARS] = \"a\"", 4 | "pc[VARS] = \"b\"", 5 | "pc[VARS] = \"Done\"", 6 | "pc[VART] = \"a\"", 7 | "pc[VART] = \"b\"", 8 | "pc[VART] = \"Done\"", 9 | "x[VARS] = 0", 10 | "y[VARS] = 0", 11 | "x[VARS] = y[VARS]", 12 | "x[VARS] = y[VART]" 13 | ], 14 | "preds_alt" : [], 15 | "safety" : "PCorrect", 16 | "constants" : "CONSTANTS\nN=4\n", 17 | "constraint" : "", 18 | "quant_inv" : "\\A VARS \\in ProcSet : \\A VART \\in ProcSet : ", 19 | "quant_inv_alt" : null, 20 | "quant_vars": [], 21 | "model_consts" : "", 22 | "symmetry" : false, 23 | "typeok" : "TypeOK", 24 | "simulate" : false 25 | } -------------------------------------------------------------------------------- /benchmarks/lockserv_automaton.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "lock_msg[VARI]", 4 | "lock_msg[VARJ]", 5 | "unlock_msg[VARI]", 6 | "unlock_msg[VARJ]", 7 | "grant_msg[VARI]", 8 | "grant_msg[VARJ]", 9 | "holds_lock[VARI]", 10 | "holds_lock[VARJ]", 11 | "held", 12 | "VARI=VARJ" 13 | ], 14 | "preds_alt" : [], 15 | "safety" : "Mutex", 16 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 17 | "constraint" : "", 18 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : ", 19 | "quant_inv_alt" : null, 20 | "quant_vars": ["VARI", "VARJ"], 21 | "model_consts" : "CONSTANT n1,n2,n3", 22 | "symmetry" : false, 23 | "typeok" : "TypeOK", 24 | "simulate" : true 25 | } -------------------------------------------------------------------------------- /benchmarks/lockserv.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "lock_msg[VARI]", 4 | "lock_msg[VARJ]", 5 | "unlock_msg[VARI]", 6 | "unlock_msg[VARJ]", 7 | "grant_msg[VARI]", 8 | "grant_msg[VARJ]", 9 | "holds_lock[VARI]", 10 | "holds_lock[VARJ]", 11 | "server_holds_lock", 12 | "VARI=VARJ" 13 | ], 14 | "preds_alt" : [], 15 | "safety" : "Mutex", 16 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 17 | "constraint" : "", 18 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : ", 19 | "quant_inv_alt" : null, 20 | "quant_vars": ["VARI", "VARJ"], 21 | "model_consts" : "CONSTANT n1,n2,n3", 22 | "symmetry" : false, 23 | "typeok" : "TypeOK", 24 | "simulate" : true 25 | } -------------------------------------------------------------------------------- /benchmarks/quorum_leader_election.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "isleader[VARS]", 4 | "isleader[VARN]", 5 | "voted[VARS] = Nil", 6 | "voted[VARN] = Nil", 7 | "voted[VARS] = VART", 8 | "voted[VARN] = VART", 9 | "voted[VARN] = VARS", 10 | "VARS=VART" 11 | ], 12 | "preds_alt" : [], 13 | "safety" : "Inv", 14 | "constants" : "CONSTANTS\nNode={n1,n2,n3,n4}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nn4=n4\n", 15 | "constraint" : "", 16 | "quant_inv" : "\\A VARS \\in Node : \\A VART \\in Node : \\A Q \\in Quorums : \\E VARN \\in Q : ", 17 | "quant_inv_alt" : null, 18 | "quant_vars": [], 19 | "model_consts" : "CONSTANT n1,n2,n3,n4", 20 | "symmetry" : false, 21 | "typeok" : "TypeOK", 22 | "simulate" : false 23 | } -------------------------------------------------------------------------------- /benchmarks/toy_consensus.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "vote[VARI] = Nil", 4 | "vote[VARI] = VARV", 5 | "vote[VARJ] = Nil", 6 | "vote[VARJ] = VARV", 7 | "vote[VART] = Nil", 8 | "vote[VART] = VARV", 9 | "VARV \\in decision", 10 | "ChosenAt(VARV, VARQ)" 11 | ], 12 | "preds_alt" : [], 13 | "safety" : "Inv", 14 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nValue={v1,v2}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nv1=v1\nv2=v2\n", 15 | "constraint" : "", 16 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARV \\in Value : \\A VARQ \\in Quorums : \\E VART \\in VARQ :", 17 | "quant_inv_alt" : null, 18 | "quant_vars": [], 19 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 20 | "symmetry" : false, 21 | "typeok" : "TypeOK", 22 | "simulate" : false 23 | } -------------------------------------------------------------------------------- /benchmarks/toy_consensus_forall.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "voted[s]", 4 | "vote[s] = v", 5 | "vote[s] = Nil", 6 | "voted[n]", 7 | "vote[n] = v", 8 | "vote[n] = Nil", 9 | "voted[t]", 10 | "vote[t] = v", 11 | "vote[t] = Nil", 12 | "decided = {}", 13 | "v \\in decided" 14 | ], 15 | "preds_alt" : [], 16 | "safety" : "Inv", 17 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nValue={v1,v2}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nv1=v1\nv2=v2\n", 18 | "constraint" : "", 19 | "quant_inv" : "\\A s,t \\in Node : \\A Q \\in Quorums : \\A v \\in Value : \\E n \\in Q : ", 20 | "quant_inv_alt" : null, 21 | "quant_vars": [], 22 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 23 | "symmetry" : false, 24 | "typeok" : "TypeOK", 25 | "simulate" : true 26 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | files/ 2 | MongoRaftReconfig_*Check.tla 3 | MongoRaftReconfig_*Check.cfg 4 | *_TautCheck_*.tla 5 | MongoStaticRaftOther_*Check.tla 6 | MongoStaticRaftOther_*Check.cfg 7 | peterson_*Check.tla 8 | peterson_*Check.cfg 9 | TwoPhase_*Check.* 10 | Paxos_*Check.* 11 | SimpleElection_*Check.tla 12 | SimpleElection_*Check.cfg 13 | Bakery_*Check.tla 14 | Bakery_*Check.cfg 15 | consensus_wo_decide_*Check.tla 16 | consensus_wo_decide_*Check.cfg 17 | *_CTIGen.* 18 | *_CTIQuickCheck.* 19 | *_IndQuickCheck.* 20 | *_InvCheck.tla 21 | *_InvCheck.cfg 22 | *_InvCheck_*.tla 23 | *_InvCheck_*.cfg 24 | *_CTIGen_*.tla 25 | *_CTIGen_*.cfg 26 | *_TautCheck.* 27 | states_read 28 | states.json 29 | cti_quick_check_*.json 30 | cppinvs/ 31 | invcheck_runner_* 32 | gen_cpp/ 33 | cpp-invgen-iter*.invs 34 | pregen*.invs 35 | gen_tla 36 | states/ 37 | *.tlaps/ 38 | *.toolbox/ 39 | __pycache__/ 40 | benchmarks.log 41 | *.proofs.html -------------------------------------------------------------------------------- /benchmarks/peterson.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "(pc[self] = \"a1\")", 4 | "(pc[self] = \"a2\")", 5 | "(pc[self] = \"a3\")", 6 | "(pc[self] = \"a4\")", 7 | "(pc[self] = \"cs\")", 8 | "(pc[self] = \"a5\")", 9 | "(pc[other] = \"a1\")", 10 | "(pc[other] = \"a2\")", 11 | "(pc[other] = \"a3\")", 12 | "(pc[other] = \"a4\")", 13 | "(pc[other] = \"cs\")", 14 | "(pc[other] = \"a5\")", 15 | "(turn = other)", 16 | "flag[self]", 17 | "flag[other]", 18 | "(turn = self)" 19 | ], 20 | "preds_alt" : [], 21 | "safety" : "Mutex", 22 | "constants" : "CONSTANTS\nProcSet={0,1}\n", 23 | "constraint" : "", 24 | "quant_inv" : "\\A self,other \\in ProcSet : ", 25 | "quant_inv_alt" : null, 26 | "quant_vars": [], 27 | "model_consts" : "", 28 | "symmetry" : false, 29 | "typeok" : "TypeOK", 30 | "simulate" : true 31 | } -------------------------------------------------------------------------------- /benchmarks/MongoLoglessDynamicRaft_Ind.cfg: -------------------------------------------------------------------------------- 1 | INIT IInitAuto 2 | NEXT Next 3 | CONSTANT 4 | Nil=Nil 5 | Server = {n1,n2,n3} 6 | Secondary = Secondary 7 | Primary = Primary 8 | MaxLogLen = 0 9 | MaxTerm = 3 10 | MaxConfigVersion = 3 11 | InitTerm = 0 12 | Nat <- NatFinite 13 | CONSTRAINT StateConstraint 14 | \* INVARIANT IndAuto 15 | \* INVARIANT TypeOK 16 | \* INVARIANT Safety 17 | \* INVARIANT Inv6243_1_1_def 18 | \* INVARIANT Inv648_1_0_def 19 | \* INVARIANT Inv1925_1_1_def 20 | \* INVARIANT Inv716_1_1_def 21 | \* \* INVARIANT Inv852_1_2_def 22 | \* INVARIANT Inv862_1_0_def 23 | \* \* INVARIANT Inv846_1_0_def 24 | SYMMETRY Symmetry 25 | 26 | INVARIANT Safety 27 | 28 | \* INVARIANT Inv3321_1_0_def_b 29 | INVARIANT Inv2973_1_1_def_b 30 | INVARIANT Inv1758_1_0_def_b 31 | INVARIANT Inv3915_1_1_def_b 32 | INVARIANT Inv3246_1_2_def_b 33 | INVARIANT Inv866_1_0_def_b 34 | 35 | 36 | \* INVARIANT Inv866_1_0_def 37 | \* INVARIANT Inv1758_1_0_def 38 | \* INVARIANT Inv3914_1_1_def 39 | \* INVARIANT Inv3012_1_1_def 40 | \* INVARIANT Inv3245_1_2_def -------------------------------------------------------------------------------- /benchmarks/client_server_ae.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in match", 4 | "<> \\in request_sent", 5 | "<> \\in request_sent", 6 | "<> \\in response_sent", 7 | "<> \\in response_sent", 8 | "<> \\in response_received", 9 | "<> \\in response_received", 10 | "VARI=VARJ /\\ match = match", 11 | "ResponseMatched(VARI,VARP)" 12 | ], 13 | "preds_alt" : [], 14 | "safety" : "Safety", 15 | "constants" : "CONSTANT\nNode = {n1,n2,n3}\nRequest = {r1,r2}\nResponse={p1,p2}\nn1 = n1\nn2 = n2\nn3 = n3\nr1 = r1\nr2 = r2\np1 = p1\np2 = p2\n", 16 | "constraint" : "", 17 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARR \\in Request : \\A VARP \\in Response : ", 18 | "quant_inv_alt" : null, 19 | "quant_vars": [], 20 | "model_consts" : "CONSTANT n1,n2,n3,r1,r2,p1,p2", 21 | "symmetry" : true, 22 | "typeok" : "TypeOK", 23 | "simulate" : true 24 | } -------------------------------------------------------------------------------- /benchmarks/firewall.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "VARI \\in allowed_in", 4 | "VARJ \\in allowed_in", 5 | "VARK \\in allowed_in", 6 | "allowed_in = {}", 7 | "VARI \\in sent[VARI]", 8 | "VARJ \\in sent[VARI]", 9 | "VARI \\in sent[VARJ]", 10 | "VARJ \\in sent[VARJ]", 11 | "VARI \\in sent[VARK]", 12 | "VARJ \\in sent[VARK]", 13 | "VARK \\in sent[VARI]", 14 | "sent[VARI] = {}", 15 | "sent[VARJ] = {}", 16 | "internal[VARI]", 17 | "internal[VARJ]", 18 | "internal[VARK]" 19 | ], 20 | "preds_alt" : [], 21 | "safety" : "Inv", 22 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 23 | "constraint" : "", 24 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\E VARK \\in Node : ", 25 | "quant_inv_alt" : null, 26 | "quant_vars": ["VARI", "VARJ"], 27 | "model_consts" : "CONSTANT n1,n2,n3", 28 | "symmetry" : true, 29 | "typeok" : "TypeOK", 30 | "simulate" : true 31 | } -------------------------------------------------------------------------------- /benchmarks/learning_switch.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in table", 4 | "<> \\in table", 5 | "<> \\in table", 6 | "<> \\in table", 7 | "<> \\in table", 8 | "<> \\in table", 9 | "<> \\in table", 10 | "<> \\in pending", 11 | "VARI = VARJ /\\ table = table", 12 | "VARI = VARK /\\ table = table", 13 | "VARJ = VARK /\\ table = table" 14 | ], 15 | "preds_alt" : [], 16 | "safety" : "Safety", 17 | "constants" : "CONSTANTS\nNode={n1,n2,n3,n4}\nn1=n1\nn2=n2\nn3=n3\nn4=n4\n", 18 | "constraint" : "CONSTRAINT StateConstraint", 19 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARK \\in Node : \\A VARZ \\in Node :", 20 | "quant_inv_alt" : null, 21 | "quant_vars": ["VARI", "VARJ"], 22 | "model_consts" : "CONSTANT n1,n2,n3,n4", 23 | "symmetry" : true, 24 | "typeok" : "TypeOKRandom", 25 | "simulate" : true 26 | } -------------------------------------------------------------------------------- /benchmarks/sharded_kv_no_lost_keys.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "table[NI][KI] = VALI", 4 | "table[NI][KI] = VALJ", 5 | "KI \\in owner[NI]", 6 | "KI \\in owner[NJ]", 7 | "<> \\in transfer_msg", 8 | "<> \\in transfer_msg", 9 | "table[NJ][KI] = VALI", 10 | "table[NJ][KI] = VALJ", 11 | "<> \\in transfer_msg", 12 | "<> \\in transfer_msg", 13 | "NI = NJ /\\ owner = owner", 14 | "VALI = VALJ /\\ owner = owner" 15 | ], 16 | "preds_alt" : [], 17 | "safety" : "Safety", 18 | "constants" : "CONSTANTS\nNode = {n1,n2}\nKey = {k1,k2}\nValue={v1,v2}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nk1=k1\nk2=k2\nk3=k3\nv1=v1\nv2=v2\nv3=v3\n", 19 | "constraint" : "", 20 | "quant_inv" : "\\A KI \\in Key : \\A NI \\in Node : \\E NJ \\in Node : \\E VALI \\in Value : \\A VALJ \\in Value : ", 21 | "quant_inv_alt" : null, 22 | "quant_vars": [], 23 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2,v3,k1,k2,k3", 24 | "symmetry" : true, 25 | "typeok" : "TypeOK", 26 | "simulate" : true 27 | } -------------------------------------------------------------------------------- /benchmarks/toy_consensus_epr.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "VARS \\in voted", 4 | "VART \\in voted", 5 | "<> \\in vote", 6 | "<> \\in vote", 7 | "<> \\in vote", 8 | "<> \\in vote", 9 | "(VARA = VARB) /\\ vote = vote", 10 | "VARA \\in decided", 11 | "VARB \\in decided", 12 | "voted = {}", 13 | "decided = {}", 14 | "ChosenAt(VARQ, VARA)", 15 | "ChosenAt(VARQ, VARB)", 16 | "(VARS = VART) /\\ vote = vote" 17 | ], 18 | "preds_alt" : [], 19 | "safety" : "Safety", 20 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nQuorum = {{n1,n2},{n1,n3},{n2,n3}}\nValue={v1,v2}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nv1=v1\nv2=v2\n", 21 | "constraint" : "", 22 | "quant_inv" : "\\A VARS \\in Node : \\A VART \\in Node : \\E VARQ \\in Quorum : \\A VARA \\in Value : \\A VARB \\in Value : ", 23 | "quant_inv_alt" : null, 24 | "quant_vars": [], 25 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 26 | "symmetry" : true, 27 | "typeok" : "TypeOK", 28 | "simulate" : false 29 | } -------------------------------------------------------------------------------- /benchmarks/majorityset_leader_election.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "DidNotVote(VARI)", 4 | "DidNotVote(VARJ)", 5 | "VARJ \\in vote[VARI]", 6 | "VARJ \\in vote[VARK]", 7 | "VARI \\in vote[VARJ]", 8 | "VARI \\in vote[VARK]", 9 | "VARK \\in vote[VARI]", 10 | "VARK \\in vote[VARJ]", 11 | "VARI \\in leader", 12 | "VARJ \\in leader", 13 | "VARI \\in voters[VARJ]", 14 | "VARJ \\in voters[VARI]", 15 | "voters[VARI] \\in Majority", 16 | "leader = {}", 17 | "VARI = VARJ /\\ vote = vote", 18 | "VARI = VARK /\\ vote = vote", 19 | "VARJ = VARK /\\ vote = vote" 20 | ], 21 | "preds_alt" : [], 22 | "safety" : "Safety", 23 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 24 | "constraint" : "", 25 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARK \\in Node : ", 26 | "quant_inv_alt" : null, 27 | "quant_vars": ["VARI", "VARJ"], 28 | "model_consts" : "CONSTANT n1,n2,n3", 29 | "symmetry" : true, 30 | "typeok" : "TypeOKRandom", 31 | "simulate" : true 32 | } -------------------------------------------------------------------------------- /benchmarks/naive_consensus.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in vote", 4 | "<> \\in vote", 5 | "<> \\in vote", 6 | "<> \\in vote", 7 | "<> \\in decide", 8 | "<> \\in decide", 9 | "VARA \\in decision", 10 | "VARB \\in decision", 11 | "VARS \\in VARQ /\\ vote = vote", 12 | "VART \\in VARQ /\\ vote = vote", 13 | "(VARS=VART) /\\ vote = vote", 14 | "(VARA=VARB) /\\ vote = vote", 15 | "VotedFor(VARA)", 16 | "VotedFor(VARB)" 17 | ], 18 | "preds_alt" : [], 19 | "safety" : "Safety", 20 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nValue={v1,v2}\nQuorum = {{n1,n2},{n2,n3},{n1,n3}}\nn1=n1\nn2=n2\nn3=n3\nv1=v1\nv2=v2\n", 21 | "constraint" : "", 22 | "quant_inv" : "\\A VARS \\in Node : \\A VART \\in Node : \\A VARA \\in Value : \\A VARB \\in Value : \\A VARQ \\in Quorum : ", 23 | "quant_inv_alt" : null, 24 | "quant_vars": [], 25 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 26 | "symmetry" : true, 27 | "typeok" : "TypeOK", 28 | "simulate" : true 29 | } -------------------------------------------------------------------------------- /benchmarks/sharded_kv.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "table[NI][KI] = VALI", 4 | "table[NI][KI] = Nil", 5 | "KI \\in owner[NI]", 6 | "<> \\in transfer_msg", 7 | "<> \\in transfer_msg", 8 | "table[NJ][KI] = VALI", 9 | "table[NJ][KI] = VALJ", 10 | "table[NJ][KI] = Nil", 11 | "KI \\in owner[NJ]", 12 | "<> \\in transfer_msg", 13 | "<> \\in transfer_msg", 14 | "NI = NJ /\\ owner = owner", 15 | "VALI = VALJ /\\ owner = owner" 16 | ], 17 | "preds_alt" : [], 18 | "safety" : "Safety", 19 | "constants" : "CONSTANTS\nNode = {n1,n2,n3}\nKey = {k1,k2}\nValue={v1,v2}\nNil=Nil\nn1=n1\nn2=n2\nn3=n3\nk1=k1\nk2=k2\nk3=k3\nv1=v1\nv2=v2\nv3=v3\n", 20 | "constraint" : "", 21 | "quant_inv" : "\\A NI \\in Node : \\A NJ \\in Node : \\A KI \\in Key : \\A VALI \\in Value : \\A VALJ \\in Value : ", 22 | "quant_inv_alt" : null, 23 | "quant_vars": ["VALI", "VALJ"], 24 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2,v3,k1,k2,k3", 25 | "symmetry" : true, 26 | "typeok" : "TypeOKRandom", 27 | "simulate" : true 28 | } -------------------------------------------------------------------------------- /benchmarks/simple_election.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "VARPA \\in start", 4 | "VARPB \\in start", 5 | "<> \\in promise", 6 | "<> \\in promise", 7 | "<> \\in promise", 8 | "<> \\in promise", 9 | "VARS=VART /\\ promise = promise", 10 | "(VARPA=VARPB) /\\ promise = promise", 11 | "VARPA \\in leader", 12 | "VARPB \\in leader", 13 | "DidNotPromise(VARS)", 14 | "DidNotPromise(VART)", 15 | "ChosenAt(VARQ,VARPA)", 16 | "ChosenAt(VARQ,VARPB)" 17 | ], 18 | "preds_alt" : [], 19 | "safety" : "Safety", 20 | "constants" : "CONSTANTS\nAcceptor = {a1,a2,a3}\nQuorum = {{a1,a2},{a1,a3},{a2,a3},{a1,a2,a3}}\nProposer = {p1,p2}\na1=a1\na2=a2\na3=a3\np1=p1\np2=p2\n", 21 | "constraint" : "", 22 | "quant_inv" : "\\A VARS \\in Acceptor : \\A VART \\in Acceptor : \\A VARPA \\in Proposer : \\A VARPB \\in Proposer : \\E VARQ \\in Quorum : ", 23 | "quant_inv_alt" : null, 24 | "quant_vars": ["VARPA", "VARPB"], 25 | "model_consts" : "CONSTANT a1,a2,a3,p1,p2", 26 | "symmetry" : false, 27 | "typeok" : "TypeOK", 28 | "simulate" : true 29 | } -------------------------------------------------------------------------------- /benchmarks/SimpleRegular.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "pc[VARS] = \"a1\"", 4 | "pc[VARS] = \"a2\"", 5 | "pc[VARS] = \"b\"", 6 | "pc[VARS] = \"Done\"", 7 | "pc[VART] = \"a1\"", 8 | "pc[VART] = \"a2\"", 9 | "pc[VART] = \"b\"", 10 | "pc[VART] = \"Done\"", 11 | "x[VARS] = {}", 12 | "x[VART] = {}", 13 | "0 \\in x[VARS]", 14 | "0 \\in x[(VARS-1) % N]", 15 | "0 \\in x[(VART-1) % N]", 16 | "1 \\in x[(VARS-1) % N]", 17 | "1 \\in x[(VART-1) % N]", 18 | "0 = y[VARS]", 19 | "1 \\in x[VARS]", 20 | "1 = y[VARS]", 21 | "0 \\in x[VART]", 22 | "0 = y[VART]", 23 | "1 \\in x[VART]", 24 | "1 = y[VART]", 25 | "y[VARS] \\in x[VART]", 26 | "y[VARS] \\in x[VARS]" 27 | ], 28 | "preds_alt" : [], 29 | "safety" : "PCorrect", 30 | "constants" : "CONSTANTS\nN=3\n", 31 | "constraint" : "", 32 | "quant_inv" : "\\A VARS \\in ProcSet : \\A VART \\in ProcSet : ", 33 | "quant_inv_alt" : null, 34 | "quant_vars": [], 35 | "model_consts" : "", 36 | "symmetry" : false, 37 | "typeok" : "TypeOK", 38 | "simulate" : true 39 | } -------------------------------------------------------------------------------- /benchmarks/toy_consensus.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus ---- 2 | \* benchmark: ex-toy-consensus 3 | 4 | EXTENDS TLC, FiniteSets, Naturals 5 | 6 | CONSTANT Node 7 | CONSTANT Value 8 | CONSTANT Nil 9 | 10 | VARIABLE vote 11 | VARIABLE decision 12 | 13 | vars == <> 14 | 15 | Quorums == {i \in SUBSET(Node) : Cardinality(i) * 2 > Cardinality(Node)} 16 | 17 | ChosenAt(v, Q) == \A m \in Q : vote[m] = v 18 | 19 | \* Node i casts vote for value 'v'. 20 | CastVote(i, v) == 21 | /\ vote[i] = Nil 22 | /\ vote' = [vote EXCEPT ![i] = v] 23 | /\ UNCHANGED decision 24 | 25 | \* Decide on value 'v' with quorum 'Q'. 26 | Decide(v, Q) == 27 | /\ ChosenAt(v, Q) 28 | /\ decision' = decision \cup {v} 29 | /\ UNCHANGED vote 30 | 31 | Init == 32 | /\ vote = [n \in Node |-> Nil] 33 | /\ decision = {} 34 | 35 | Next == 36 | \/ \E i \in Node, v \in Value : CastVote(i, v) 37 | \/ \E v \in Value, Q \in Quorums : Decide(v, Q) 38 | 39 | TypeOK == 40 | /\ vote \in [Node -> Value \cup {Nil}] 41 | /\ decision \in SUBSET Value 42 | 43 | NextUnchanged == UNCHANGED vars 44 | 45 | \* At most one value is decided upon. 46 | Inv == \A vi, vj \in decision : vi = vj 47 | 48 | Symmetry == Permutations(Node) \cup Permutations(Value) 49 | 50 | ==== -------------------------------------------------------------------------------- /benchmarks/toy_consensus_epr.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus_epr ---- 2 | \* benchmark: pyv-toy-consensus-epr 3 | 4 | EXTENDS TLC, Naturals, FiniteSets 5 | 6 | CONSTANT Node 7 | CONSTANT Quorum 8 | CONSTANT Value 9 | 10 | VARIABLE voted 11 | VARIABLE vote 12 | VARIABLE decided 13 | 14 | vars == <> 15 | 16 | ChosenAt(Q, v) == \A n \in Q : <> \in vote 17 | 18 | \* Node 'i' casts a vote for value 'v'. 19 | CastVote(n, v) == 20 | /\ n \notin voted 21 | /\ vote' = vote \cup {<>} 22 | /\ voted' = voted \cup {n} 23 | /\ UNCHANGED <> 24 | 25 | \* Decide on a value 'v' with quorum 'Q'. 26 | Decide(v, Q) == 27 | /\ ChosenAt(Q, v) 28 | /\ decided' = decided \cup {v} 29 | /\ UNCHANGED <> 30 | 31 | Init == 32 | /\ voted = {} 33 | /\ vote = {} 34 | /\ decided = {} 35 | 36 | Next == 37 | \/ \E i \in Node, v \in Value : CastVote(i, v) 38 | \/ \E v \in Value, Q \in Quorum : Decide(v, Q) 39 | 40 | NextUnchanged == UNCHANGED vars 41 | 42 | TypeOK == 43 | /\ voted \in SUBSET Node 44 | /\ vote \in SUBSET (Node \X Value) 45 | /\ decided \in SUBSET Value 46 | 47 | \* Can only decide on a single value 48 | Safety == \A vi,vj \in decided : vi = vj 49 | 50 | Symmetry == Permutations(Node) \cup Permutations(Value) 51 | 52 | ==== -------------------------------------------------------------------------------- /benchmarks/two_phase_commit.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "VARI \\in alive", 4 | "VARJ \\in alive", 5 | "alive = {}", 6 | "VARI \\in vote_yes", 7 | "VARI \\in vote_no", 8 | "VARI \\in decide_commit", 9 | "VARI \\in decide_abort", 10 | "VARJ \\in vote_yes", 11 | "VARJ \\in vote_no", 12 | "VARJ \\in decide_commit", 13 | "VARJ \\in decide_abort", 14 | "decide_commit = {}", 15 | "decide_abort = {}", 16 | "vote_yes = {}", 17 | "vote_no = {}", 18 | "vote_no = Node", 19 | "VARI \\in go_commit", 20 | "VARI \\in go_abort", 21 | "VARJ \\in go_commit", 22 | "VARJ \\in go_abort", 23 | "go_commit = {}", 24 | "go_abort = {}", 25 | "abort_flag", 26 | "VARI = VARJ /\\ alive = alive" 27 | ], 28 | "preds_alt" : [], 29 | "safety" : "Safety", 30 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 31 | "constraint" : "", 32 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : ", 33 | "quant_inv_alt" : null, 34 | "quant_vars": ["VARI", "VARJ"], 35 | "model_consts" : "CONSTANT n1,n2,n3", 36 | "symmetry" : true, 37 | "typeok" : "TypeOK", 38 | "simulate" : true 39 | } -------------------------------------------------------------------------------- /benchmarks/firewall.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE firewall ---- 2 | \* benchmark: pyv-firewall 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Node 7 | 8 | VARIABLE internal 9 | VARIABLE sent 10 | VARIABLE allowed_in 11 | 12 | vars == <> 13 | 14 | SendFromInternal(src, dest) == 15 | /\ internal[src] 16 | /\ ~internal[dest] 17 | /\ sent' = [sent EXCEPT ![src] = @ \cup {dest}] 18 | /\ allowed_in' = allowed_in \cup {dest} 19 | /\ UNCHANGED internal 20 | 21 | SendToInternal(src, dest) == 22 | /\ ~internal[src] 23 | /\ internal[dest] 24 | /\ src \in allowed_in 25 | /\ sent' = [sent EXCEPT ![src] = @ \cup {dest}] 26 | /\ UNCHANGED <> 27 | 28 | Init == 29 | /\ internal \in [Node -> BOOLEAN] 30 | /\ sent = [n \in Node |-> {}] 31 | /\ allowed_in = {} 32 | 33 | Next == 34 | \/ \E s,t \in Node : SendFromInternal(s,t) 35 | \/ \E s,t \in Node : SendToInternal(s,t) 36 | 37 | Inv == 38 | \A s,d \in Node: 39 | (d \in sent[s] /\ internal[d]) => 40 | (\E i \in Node : internal[i] /\ s \in sent[i]) 41 | 42 | NextUnchanged == UNCHANGED vars 43 | 44 | TypeOK == 45 | /\ internal \in [Node -> BOOLEAN] 46 | /\ sent \in [Node -> SUBSET Node] 47 | /\ allowed_in \in SUBSET Node 48 | 49 | Symmetry == Permutations(Node) 50 | 51 | ==== -------------------------------------------------------------------------------- /benchmarks/TwoPhase.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "tmState = \"init\"", 4 | "[type |-> \"Prepared\", rm |-> rmi] \\in msgs", 5 | "[type |-> \"Prepared\", rm |-> rmj] \\in msgs", 6 | "tmPrepared = RM", 7 | "rmState[rmi] = \"working\"", 8 | "rmState[rmi] = \"working\"", 9 | "rmState[rmj] = \"working\"", 10 | "rmState[rmj] = \"working\"", 11 | "[type |-> \"Commit\"] \\in msgs", 12 | "[type |-> \"Abort\"] \\in msgs", 13 | "rmState[rmi] = \"prepared\"", 14 | "rmState[rmi] = \"aborted\"", 15 | "rmState[rmi] = \"committed\"", 16 | "rmState[rmj] = \"prepared\"", 17 | "rmState[rmj] = \"aborted\"", 18 | "rmState[rmj] = \"committed\"", 19 | "tmPrepared = tmPrepared \\cup {rmi}" 20 | ], 21 | "preds_alt" : [], 22 | "safety" : "TCConsistent", 23 | "constants" : [ 24 | "CONSTANTS", 25 | "RM={rm1,rm2,rm3}", 26 | "rm1 = rm1", 27 | "rm2 = rm2", 28 | "rm3 = rm3" 29 | ], 30 | "constraint" : "", 31 | "quant_inv" : "\\A rmi \\in RM : \\A rmj \\in RM : ", 32 | "quant_inv_alt" : null, 33 | "model_consts" : "CONSTANT rm1,rm2,rm3", 34 | "symmetry" : true, 35 | "typeok" : "TypeOK", 36 | "simulate" : true 37 | } 38 | -------------------------------------------------------------------------------- /benchmarks/simple_decentralized_lock.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in message", 4 | "<> \\in message", 5 | "<> \\in message", 6 | "<> \\in message", 7 | "<> \\in message", 8 | "<> \\in message", 9 | "<> \\in message", 10 | "<> \\in message", 11 | "<> \\in message", 12 | "VARS=VART /\\ message=message", 13 | "VARS=VARU /\\ message=message", 14 | "VART=VARU /\\ message=message", 15 | "VART=VARV /\\ message=message", 16 | "VARS=VARV /\\ message=message", 17 | "VARS \\in has_lock", 18 | "VART \\in has_lock", 19 | "VARU \\in has_lock", 20 | "VARV \\in has_lock", 21 | "has_lock = {}", 22 | "message = {}" 23 | ], 24 | "preds_alt" : [], 25 | "safety" : "Inv", 26 | "constants" : "CONSTANTS\nNode = {n1,n2,n3}\nn1=n1\nn2=n2\nn3=n3\n", 27 | "constraint" : "", 28 | "quant_inv" : "\\A VARS \\in Node : \\A VART \\in Node : \\A VARU \\in Node : \\A VARV \\in Node : ", 29 | "quant_inv_alt" : null, 30 | "quant_vars": [], 31 | "model_consts" : "CONSTANT n1,n2,n3", 32 | "symmetry" : false, 33 | "typeok" : "TypeOK", 34 | "simulate" : true 35 | } -------------------------------------------------------------------------------- /benchmarks/consensus_wo_decide.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "vote_request_msg[<>]", 4 | "vote_request_msg[<>]", 5 | "voted[VARI]", 6 | "voted[VARJ]", 7 | "vote_msg[<>]", 8 | "vote_msg[<>]", 9 | "votes[<>]", 10 | "votes[<>]", 11 | "leader[VARI]", 12 | "leader[VARJ]", 13 | "VARI \\in voting_quorum", 14 | "VARJ \\in voting_quorum", 15 | "VARJ=VARK", 16 | "vote_request_msg[<>]", 17 | "vote_request_msg[<>]", 18 | "voted[VARK]", 19 | "vote_msg[<>]", 20 | "vote_msg[<>]", 21 | "votes[<>]", 22 | "votes[<>]", 23 | "leader[VARK]", 24 | "VARK \\in voting_quorum" 25 | ], 26 | "preds_alt" : [], 27 | "safety" : "Safety", 28 | "constants" : "CONSTANT\nNode = {n1,n2,n3}\nQuorums = {{n1,n2},{n2,n3},{n1,n3}}\nn1 = n1\nn2 = n2\nn3 = n3\n", 29 | "constraint" : "", 30 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARK \\in Node : ", 31 | "quant_inv_alt" : null, 32 | "quant_vars": ["VARI", "VARJ"], 33 | "model_consts" : "CONSTANT n1,n2,n3", 34 | "symmetry" : true, 35 | "typeok" : "TypeOKRandom", 36 | "simulate" : true 37 | } -------------------------------------------------------------------------------- /benchmarks/quorum_leader_election.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE quorum_leader_election ---- 2 | \* benchmark: ex-quorum-leader-election 3 | 4 | EXTENDS TLC, Naturals, FiniteSets 5 | 6 | CONSTANT Node 7 | CONSTANT Nil 8 | 9 | VARIABLE isleader 10 | VARIABLE voted 11 | 12 | vars == <> 13 | 14 | \* The set of all majority quorums in the Node set. 15 | Quorums == {i \in SUBSET(Node) : Cardinality(i) * 2 > Cardinality(Node)} 16 | 17 | \* Node i casts a vote for node j. Can only vote if it has not already. 18 | Vote(i,j) == 19 | /\ voted[i] = Nil 20 | /\ voted' = [voted EXCEPT ![i]=j] 21 | /\ UNCHANGED isleader 22 | 23 | \* Node i becomes leader with the votes of a quorum Q. 24 | BecomeLeader(i,Q) == 25 | \* All nodes in the quorum must have voted for 'i'. 26 | /\ \A v \in Q : voted[v] = i 27 | /\ isleader' = [isleader EXCEPT ![i] = TRUE] 28 | /\ UNCHANGED voted 29 | 30 | Init == 31 | /\ isleader = [n \in Node |-> FALSE] 32 | /\ voted = [n \in Node |-> Nil] 33 | 34 | Next == 35 | \/ \E i,j \in Node : Vote(i,j) 36 | \/ \E i \in Node : \E Q \in Quorums : BecomeLeader(i, Q) 37 | 38 | \* No more than a single leader can be elected. 39 | Inv == \A i,j \in Node : (isleader[i] /\ isleader[j]) => (i=j) 40 | 41 | TypeOK == 42 | /\ isleader \in [Node -> BOOLEAN] 43 | /\ voted \in [Node -> Node \cup {Nil}] 44 | 45 | NextUnchanged == UNCHANGED vars 46 | 47 | ==== -------------------------------------------------------------------------------- /benchmarks/simple_election.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE simple_election ---- 2 | \* benchmark: ex-simple-election 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Acceptor 7 | CONSTANT Quorum 8 | CONSTANT Proposer 9 | 10 | VARIABLE start 11 | VARIABLE promise 12 | VARIABLE leader 13 | 14 | vars == <> 15 | 16 | DidNotPromise(a) == \A p \in Proposer : <> \notin promise 17 | ChosenAt(Q, p) == \A a \in Q : <> \in promise 18 | 19 | \* 20 | \* Actions. 21 | \* 22 | 23 | Send1a(p) == 24 | /\ start' = start \cup {p} 25 | /\ UNCHANGED <> 26 | 27 | Send1b(a, p) == 28 | /\ p \in start 29 | /\ DidNotPromise(a) 30 | /\ promise' = promise \cup {<>} 31 | /\ UNCHANGED <> 32 | 33 | Decide(p, Q) == 34 | /\ ChosenAt(Q, p) 35 | /\ leader' = leader \cup {p} 36 | /\ UNCHANGED <> 37 | 38 | Next == 39 | \/ \E p \in Proposer : Send1a(p) 40 | \/ \E a \in Acceptor, p \in Proposer : Send1b(a, p) 41 | \/ \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 42 | 43 | Init == 44 | /\ start = {} 45 | /\ promise = {} 46 | /\ leader = {} 47 | 48 | NextUnchanged == UNCHANGED vars 49 | 50 | TypeOK == 51 | /\ start \in SUBSET Proposer 52 | /\ promise \in SUBSET (Acceptor \X Proposer) 53 | /\ leader \in SUBSET Proposer 54 | 55 | Safety == \A pi,pj \in Proposer : (pi \in leader /\ pj \in leader) => (pi = pj) 56 | 57 | ==== -------------------------------------------------------------------------------- /benchmarks/client_server_db_ae.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in match", 4 | "<> \\in response_sent", 5 | "<> \\in request_sent", 6 | "<> \\in response_sent", 7 | "<> \\in request_sent", 8 | "<> \\in response_received", 9 | "<> \\in response_received", 10 | "VARI=VARJ /\\ match = match", 11 | "ResponseMatched(VARI,VARP)", 12 | "ResponseMatched(VARJ,VARP)", 13 | "NoneWithId(VARID)", 14 | "<> \\in t", 15 | "<> \\in t", 16 | "<> \\in db_request_sent", 17 | "<> \\in db_response_sent" 18 | ], 19 | "preds_alt" : [], 20 | "safety" : "Safety", 21 | "constants" : "CONSTANT\nNode = {n1,n2,n3}\nRequest = {r1,r2,r3}\nResponse={p1,p2,p3}\nDbRequestId={i1,i2}\nn1 = n1\nn2 = n2\nn3 = n3\nr1 = r1\nr2 = r2\nr3=r3\np1 = p1\np2 = p2\np3=p3\ni1 = i1\ni2 = i2\ni3=i3\n", 22 | "constraint" : "", 23 | "quant_inv" : "\\A VARI \\in Node : \\A VARID \\in DbRequestId : \\A VARR \\in Request : \\A VARJ \\in Node : \\A VARP \\in Response : ", 24 | "quant_inv_alt" : null, 25 | "quant_vars": ["VARI", "VARJ"], 26 | "model_consts" : "CONSTANT n1,n2,n3,r1,r2,r3,p1,p2,p3,i1,i2,i3", 27 | "symmetry" : true, 28 | "typeok" : "TypeOKRandom", 29 | "simulate" : true 30 | } -------------------------------------------------------------------------------- /benchmarks/simple_decentralized_lock.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE simple_decentralized_lock ---- 2 | \* benchmark: ex-simple-decentralized-lock 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Node 7 | 8 | VARIABLE message 9 | VARIABLE has_lock 10 | 11 | vars == <> 12 | 13 | Send(src, dst) == 14 | /\ src \in has_lock 15 | /\ message' = message \cup {<>} 16 | /\ has_lock' = has_lock \ {src} 17 | 18 | Recv(src, dst) == 19 | /\ <> \in message 20 | /\ message' = message \ {<>} 21 | /\ has_lock' = has_lock \cup {dst} 22 | 23 | Next == 24 | \/ \E src,dst \in Node : Send(src,dst) 25 | \/ \E src,dst \in Node : Recv(src,dst) 26 | 27 | NextUnchanged == UNCHANGED vars 28 | 29 | Init == 30 | \E start \in Node : 31 | /\ message = {} 32 | /\ has_lock = {start} 33 | 34 | TypeOK == 35 | /\ message \in SUBSET (Node \X Node) 36 | /\ has_lock \in SUBSET Node 37 | 38 | \* Two nodes can't hold lock at once. 39 | Inv == \A x,y \in Node : (x \in has_lock /\ y \in has_lock) => (x = y) 40 | 41 | \* Human derived inductive invariant. 42 | IndHuman == 43 | /\ TypeOK 44 | /\ Inv 45 | /\ \A n,t \in Node : <> \in message => has_lock = {} 46 | /\ \A a,b \in message : a = b 47 | 48 | \* Human derived inductive invariant. 49 | IndHumanB == 50 | /\ TypeOK 51 | /\ Inv 52 | /\ \A n,t \in Node : <> \in message => has_lock = {} 53 | /\ \A a,b,c,d \in Node : (<> \in message /\ <> \in message) => (a=c /\ b=d) 54 | 55 | ==== -------------------------------------------------------------------------------- /benchmarks/learning_switch_i4.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "i=j", 4 | "pi=pj /\\ pending = pending", 5 | "<> \\in route_dom", 6 | "<> \\in route_dom", 7 | "<> \\in route_tc", 8 | "<> \\in route_tc", 9 | "<> \\in route_tc", 10 | "<> \\in route_tc", 11 | "<> \\in route_tc", 12 | "<> \\in route_tc", 13 | "<> \\in route_tc", 14 | "<> \\in pending", 15 | "<> \\in pending", 16 | "<> \\in pending", 17 | "<> \\in pending", 18 | "src[pi] = i", 19 | "src[pi] = j", 20 | "dst[pi] = i", 21 | "dst[pi] = j", 22 | "link[src[pi]] = i", 23 | "link[src[pi]] = j", 24 | "src[pj] = i", 25 | "src[pj] = j", 26 | "dst[pj] = i", 27 | "dst[pj] = j", 28 | "link[i] = i", 29 | "link[j] = i", 30 | "link[i] = j", 31 | "link[j] = j" 32 | ], 33 | "preds_alt" : [], 34 | "safety" : "Safety", 35 | "constants" : "CONSTANTS\nNode={n1,n2,n3}\nPacket={p1,p2}\nn1=n1\nn2=n2\nn3=n3\nn4=n4\np1=p1\np2=p2\n", 36 | "constraint" : "", 37 | "quant_inv" : "\\A i,j,k \\in Node : \\A pi,pj \\in Packet :", 38 | "quant_inv_alt" : null, 39 | "quant_vars": ["pi", "pj"], 40 | "model_consts" : "CONSTANT n1,n2,n3,n4,p1,p2", 41 | "symmetry" : true, 42 | "typeok" : "TypeOKRandom", 43 | "simulate" : true 44 | } -------------------------------------------------------------------------------- /benchmarks/consensus_forall.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "<> \\in vote_request_msg", 4 | "<> \\in vote_request_msg", 5 | "voted[VARI]", 6 | "voted[VARJ]", 7 | "<> \\in vote_msg", 8 | "<> \\in vote_msg", 9 | "<> \\in votes", 10 | "<> \\in votes", 11 | "leader[VARI]", 12 | "leader[VARJ]", 13 | "VARI \\in voting_quorum", 14 | "VARJ \\in voting_quorum", 15 | "VARJ=VARK", 16 | "<> \\in vote_request_msg", 17 | "<> \\in vote_request_msg", 18 | "voted[VARK]", 19 | "<> \\in vote_msg", 20 | "<> \\in vote_msg", 21 | "<> \\in votes", 22 | "<> \\in votes", 23 | "leader[VARK]", 24 | "VARK \\in voting_quorum", 25 | "<> \\in decided", 26 | "<> \\in decided" 27 | ], 28 | "preds_alt" : [], 29 | "safety" : "Safety", 30 | "constants" : "CONSTANT\nNode = {n1,n2,n3}\nQuorum = {{n1,n2},{n2,n3},{n1,n3}}\nValue={v1,v2}\nn1 = n1\nn2 = n2\nn3 = n3\nv1=v1\nv2=v2\n", 31 | "constraint" : "", 32 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARK \\in Node : \\A VALI \\in Value :", 33 | "quant_inv_alt" : null, 34 | "quant_vars": ["VARI", "VARJ"], 35 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 36 | "symmetry" : true, 37 | "typeok" : "TypeOKRandom", 38 | "simulate" : true 39 | } -------------------------------------------------------------------------------- /benchmarks/consensus_epr.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "voted[VARI]", 4 | "voted[VARJ]", 5 | "voted[VARK]", 6 | "<> \\in vote_msg", 7 | "<> \\in vote_msg", 8 | "<> \\in vote_msg", 9 | "VARI = VARJ /\\ votes = votes", 10 | "VARI = VARK /\\ votes = votes", 11 | "VARJ = VARK /\\ votes = votes", 12 | "VARI \\in votes[VARJ]", 13 | "VARI \\in votes[VARK]", 14 | "VARJ \\in votes[VARI]", 15 | "VARJ \\in votes[VARK]", 16 | "VARK \\in votes[VARI]", 17 | "VARK \\in votes[VARJ]", 18 | "leader[VARI]", 19 | "leader[VARJ]", 20 | "leader[VARK]", 21 | "voted[VARK]", 22 | "voted[VARI]", 23 | "voted[VARJ]", 24 | "VALI \\in decided[VARI]", 25 | "VALI \\in decided[VARJ]", 26 | "VALI \\in decided[VARK]", 27 | "QJ \\subseteq votes[VARI]", 28 | "QJ \\subseteq votes[VARJ]" 29 | ], 30 | "preds_alt" : [], 31 | "safety" : "Safety", 32 | "constants" : "CONSTANT\nNode = {n1,n2,n3}\nQuorum = {{n1,n2},{n2,n3},{n1,n3},{n1,n2,n3}}\nValue={v1,v2}\nn1 = n1\nn2 = n2\nn3 = n3\nv1=v1\nv2=v2\n", 33 | "constraint" : "", 34 | "quant_inv" : "\\A VARI \\in Node : \\A VARJ \\in Node : \\A VARK \\in Node : \\E QJ \\in Quorum : \\A VALI \\in Value : ", 35 | "quant_inv_alt" : null, 36 | "quant_vars": ["VARI", "VARJ"], 37 | "model_consts" : "CONSTANT n1,n2,n3,v1,v2", 38 | "symmetry" : true, 39 | "typeok" : "TypeOKRandom", 40 | "simulate" : true 41 | } -------------------------------------------------------------------------------- /benchmarks/naive_consensus.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE naive_consensus ---- 2 | \* benchmark: ex-naive-consensus 3 | 4 | EXTENDS TLC, FiniteSets, Randomization 5 | 6 | CONSTANT Node 7 | CONSTANT Quorum 8 | CONSTANT Value 9 | 10 | VARIABLE vote 11 | VARIABLE decide 12 | VARIABLE decision 13 | 14 | vars == <> 15 | 16 | VotedFor(v) == \E Q \in Quorum : <> \in decide 17 | 18 | CastVote(n, v) == 19 | /\ \A x \in Value : <> \notin vote 20 | /\ vote' = vote \cup {<>} 21 | /\ UNCHANGED <> 22 | 23 | CollectVotes(Q, v) == 24 | /\ \A n \in Q : <> \in vote 25 | /\ decide' = decide \cup {<>} 26 | /\ UNCHANGED <> 27 | 28 | LearnValue(Q, v) == 29 | /\ <> \in decide 30 | /\ decision' = decision \cup {v} 31 | /\ UNCHANGED <> 32 | 33 | Init == 34 | /\ vote = {} 35 | /\ decide = {} 36 | /\ decision = {} 37 | 38 | Next == 39 | \/ \E n \in Node, v \in Value : CastVote(n,v) 40 | \/ \E Q \in Quorum, v \in Value : CollectVotes(Q,v) 41 | \/ \E Q \in Quorum, v \in Value : LearnValue(Q,v) 42 | 43 | NextUnchanged == UNCHANGED vars 44 | 45 | TypeOK == 46 | /\ vote \in SUBSET (Node \X Value) 47 | /\ decide \in SUBSET (Quorum \X Value) 48 | /\ decision \in SUBSET Value 49 | 50 | \* TODO: May need to fix this. 51 | TypeOKRandom == 52 | /\ vote \in RandomSubset(20, SUBSET (Node \X Value)) 53 | /\ decide \in RandomSubset(20, SUBSET (Quorum \X Value)) 54 | /\ decide \in SUBSET Value 55 | 56 | Safety == \A v1,v2 \in Value : (v1 \in decision /\ v2 \in decision) => (v1=v2) 57 | 58 | Symmetry == Permutations(Node) \cup Permutations(Value) 59 | 60 | ==== -------------------------------------------------------------------------------- /benchmarks/lockserver_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserver_IndProofs ---- 2 | EXTENDS lockserver 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:36:20.113024 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 0.8351531028747559 10 | \* ctielimcheck_duration_secs: 1.1566529273986816 11 | \* ctigen_duration_secs: 3.469104766845703 12 | \* total_duration_secs: 5.47419285774231 13 | \* total_num_ctis_eliminated: 12 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 2 16 | \* total_num_invs_checked: 12 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 13 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv10_1_0_def == \A VARS \in Server : \A VARC \in Client : ~(VARS \in clientlocks[VARC]) \/ (~(semaphore[VARS])) 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TypeOK 36 | /\ Inv 37 | /\ Inv10_1_0_def 38 | 39 | \* TLAPS Proof skeleton. 40 | THEOREM Init => IndAuto 41 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv10_1_0_def 42 | THEOREM IndAuto /\ Next => IndAuto' 43 | <1> SUFFICES ASSUME IndAuto, 44 | Next 45 | PROVE IndAuto' 46 | OBVIOUS 47 | <1>1. CASE \E c \in Client, s \in Server : Connect(c, s) 48 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv10_1_0_def,Connect,Disconnect 49 | <1>2. CASE \E c \in Client, s \in Server : Disconnect(c, s) 50 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv10_1_0_def,Connect,Disconnect 51 | <1>3. QED 52 | BY <1>1, <1>2 DEF Next 53 | 54 | ==== 55 | -------------------------------------------------------------------------------- /benchmarks/majorityset_leader_election.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE majorityset_leader_election ---- 2 | \* benchmark: ex-majorityset-leader-election 3 | 4 | EXTENDS TLC, Naturals, FiniteSets, Randomization 5 | 6 | CONSTANT Node 7 | 8 | VARIABLE vote 9 | VARIABLE leader 10 | VARIABLE voters 11 | 12 | vars == <> 13 | 14 | \* The set of node majorities. 15 | Majority == {i \in SUBSET(Node) : Cardinality(i) * 2 > Cardinality(Node)} 16 | 17 | DidNotVote(n) == vote[n] = {} 18 | 19 | Voting(n1,n2) == 20 | /\ DidNotVote(n1) 21 | /\ vote' = [vote EXCEPT ![n1] = @ \cup {n2}] 22 | /\ UNCHANGED <> 23 | 24 | ReceiveVote(voter,n,vs) == 25 | /\ n \in vote[voter] 26 | /\ voters[n] = vs 27 | /\ voter \notin vs 28 | /\ voters' = [voters EXCEPT ![n] = vs \cup {voter}] 29 | /\ UNCHANGED <> 30 | 31 | BecomeLeader(n, vs) == 32 | /\ voters[n] = vs 33 | /\ vs \in Majority 34 | /\ leader' = leader \cup {n} 35 | /\ UNCHANGED <> 36 | 37 | Next == 38 | \/ \E n1,n2 \in Node : Voting(n1,n2) 39 | \/ \E voter,n \in Node, vs \in SUBSET Node : ReceiveVote(voter,n,vs) 40 | \/ \E n \in Node, vs \in SUBSET Node : BecomeLeader(n, vs) 41 | 42 | EmptySet == {} 43 | 44 | Init == 45 | /\ vote = [n \in Node |-> {}] 46 | /\ leader = {} 47 | /\ voters = [n \in Node |-> {}] 48 | 49 | TypeOK == 50 | /\ vote \in [Node -> SUBSET Node] 51 | /\ leader \in SUBSET Node 52 | /\ voters \in [Node -> SUBSET Node] 53 | 54 | TypeOKRandom == 55 | /\ vote \in RandomSubset(50, [Node -> SUBSET Node]) 56 | /\ leader \in RandomSubset(8, SUBSET Node) 57 | /\ voters \in RandomSubset(35, [Node -> SUBSET Node]) 58 | 59 | Safety == \A x,y \in Node : (x \in leader) /\ (y \in leader) => (x = y) 60 | 61 | Symmetry == Permutations(Node) 62 | 63 | NextUnchanged == UNCHANGED vars 64 | 65 | ==== -------------------------------------------------------------------------------- /benchmarks/client_server_ae.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE client_server_ae ---- 2 | \* benchmark: pyv-client-server-ae 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Node 7 | CONSTANT Request 8 | CONSTANT Response 9 | 10 | VARIABLE match 11 | 12 | VARIABLE request_sent 13 | VARIABLE response_sent 14 | VARIABLE response_received 15 | 16 | vars == <> 17 | 18 | ResponseMatched(n,p) == \E r \in Request : (<> \in request_sent) /\ <> \in match 19 | 20 | NewRequest(n, r) == 21 | /\ request_sent' = request_sent \cup {<>} 22 | /\ UNCHANGED <> 23 | 24 | Respond(n,r,p) == 25 | /\ <> \in request_sent 26 | /\ <> \in match 27 | /\ response_sent' = response_sent \cup {<>} 28 | /\ UNCHANGED <> 29 | 30 | ReceiveResponse(n,p) == 31 | /\ <> \in response_sent 32 | /\ response_received' = response_received \cup {<>} 33 | /\ UNCHANGED <> 34 | 35 | Next == 36 | \/ \E n \in Node, r \in Request : NewRequest(n,r) 37 | \/ \E n \in Node, r \in Request, p \in Response : Respond(n,r,p) 38 | \/ \E n \in Node, p \in Response : ReceiveResponse(n,p) 39 | 40 | Init == 41 | /\ match \in SUBSET (Request \X Response) 42 | /\ request_sent = {} 43 | /\ response_sent = {} 44 | /\ response_received = {} 45 | 46 | TypeOK == 47 | /\ match \in SUBSET (Request \X Response) 48 | /\ request_sent \in SUBSET (Node \X Request) 49 | /\ response_sent \in SUBSET (Node \X Response) 50 | /\ response_received \in SUBSET (Node \X Response) 51 | 52 | NextUnchanged == UNCHANGED vars 53 | 54 | Safety == \A n \in Node, p \in Response : (<> \in response_received) => ResponseMatched(n,p) 55 | 56 | Symmetry == Permutations(Node) \cup Permutations(Request) \cup Permutations(Response) 57 | 58 | ==== -------------------------------------------------------------------------------- /benchmarks/lockserver.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserver ---- 2 | \* benchmark: i4-lock-server 3 | 4 | EXTENDS TLC, Naturals 5 | 6 | \* 7 | \* Simple lock server example. 8 | \* 9 | \* The system consists of a set of servers and a set of clients. 10 | \* Each server maintains a single lock, which can be granted to a 11 | \* client if it currently owns that lock. 12 | \* 13 | 14 | CONSTANT Server,Client 15 | 16 | CONSTANT Nil 17 | 18 | VARIABLE semaphore 19 | VARIABLE clientlocks 20 | 21 | vars == <> 22 | 23 | \* A client c requests a lock from server s. 24 | Connect(c, s) == 25 | \* The server must currently hold the lock. 26 | /\ semaphore[s] = TRUE 27 | \* The client obtains the lock of s. 28 | /\ clientlocks' = [clientlocks EXCEPT ![c] = clientlocks[c] \cup {s}] 29 | /\ semaphore' = [semaphore EXCEPT ![s] = FALSE] 30 | 31 | 32 | \* A client c relinquishes the lock of server s. 33 | Disconnect(c, s) == 34 | \* The client must currently be holding the lock of s. 35 | /\ s \in clientlocks[c] 36 | \* The relinquishes the lock of s. 37 | /\ clientlocks' = [clientlocks EXCEPT ![c] = clientlocks[c] \ {s}] 38 | /\ semaphore' = [semaphore EXCEPT ![s] = TRUE] 39 | 40 | Init == 41 | \* Initially each server holds its lock, and all clients hold 42 | \* no locks. 43 | /\ semaphore = [i \in Server |-> TRUE] 44 | /\ clientlocks = [i \in Client |-> {}] 45 | 46 | Next == 47 | \/ \E c \in Client, s \in Server : Connect(c, s) 48 | \/ \E c \in Client, s \in Server : Disconnect(c, s) 49 | 50 | NextUnchanged == UNCHANGED vars 51 | 52 | TypeOK == 53 | /\ semaphore \in [Server -> BOOLEAN] 54 | /\ clientlocks \in [Client -> SUBSET Server] 55 | 56 | \* Two different clients cannot hold the lock of the same server simultaneously. 57 | Inv == \A ci,cj \in Client : (clientlocks[ci] \cap clientlocks[cj] # {}) => (ci = cj) 58 | 59 | \* The inductive invariant. 60 | Ind == 61 | /\ TypeOK 62 | /\ Inv 63 | \* A client and server never hold the same lock at the same time. 64 | /\ \A c \in Client, s \in Server : (s \in clientlocks[c]) => ~semaphore[s] 65 | 66 | ==== 67 | -------------------------------------------------------------------------------- /benchmarks/Consensus_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ----------------------------- MODULE Consensus_IndProofs ------------------------------ 2 | EXTENDS Consensus,FiniteSetTheorems 3 | 4 | \* invgen.py stats 5 | \* ----------------- 6 | \* date: 2022-07-26T23:10:26.006658 7 | \* is_inductive: True 8 | \* inv_size: 1 9 | \* invcheck_duration_secs: 0 10 | \* ctielimcheck_duration_secs: 0 11 | \* ctigen_duration_secs: 0.9454421997070312 12 | \* total_duration_secs: 0.9580879211425781 13 | \* total_num_ctis_eliminated: 0 14 | \* total_num_cti_elimination_rounds: 0 15 | \* total_num_invs_generated: 0 16 | \* total_num_invs_checked: 0 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 13 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | 32 | \* The inductive invariant candidate. 33 | IndAuto == 34 | /\ TypeOK 35 | /\ Inv 36 | 37 | ASSUME Fin == IsFiniteSet(Value) 38 | 39 | \* TLAPS Proof skeleton. 40 | THEOREM Init => IndAuto 41 | <1> SUFFICES ASSUME Init 42 | PROVE IndAuto 43 | OBVIOUS 44 | <1>1. TypeOK 45 | BY Fin,FS_Subset DEF TypeOK,Init,Next,IndAuto,Inv 46 | <1>2. Inv 47 | BY Fin,FS_Subset,FS_EmptySet DEF TypeOK,Init,Next,IndAuto,Inv 48 | <1>3. QED 49 | BY <1>1, <1>2 DEF IndAuto 50 | 51 | THEOREM IndAuto /\ Next => IndAuto' 52 | <1> SUFFICES ASSUME IndAuto /\ Next 53 | PROVE IndAuto' 54 | OBVIOUS 55 | <1>1. TypeOK' 56 | BY Fin,FS_Subset,FS_EmptySet DEF TypeOK,Init,Next,IndAuto,Inv 57 | <1>2. Inv' 58 | <2>1. TypeOK' 59 | BY Fin,FS_Subset,FS_EmptySet,FS_Singleton DEF TypeOK,Init,Next,IndAuto,Inv 60 | <2>2. (Cardinality(chosen) \leq 1)' 61 | BY Fin,FS_Subset,FS_EmptySet,FS_Singleton DEF TypeOK,Init,Next,IndAuto,Inv 62 | <2>3. QED 63 | BY <2>1, <2>2 DEF Inv 64 | 65 | <1>3. QED 66 | BY <1>1, <1>2 DEF IndAuto 67 | 68 | ============================================================================= 69 | -------------------------------------------------------------------------------- /benchmarks/lockserv_automaton.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserv_automaton ---- 2 | \* benchmark: ex-lockserv-automaton 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Node 7 | 8 | VARIABLE lock_msg 9 | VARIABLE unlock_msg 10 | VARIABLE grant_msg 11 | 12 | VARIABLE holds_lock 13 | 14 | VARIABLE held 15 | 16 | vars == <> 17 | 18 | Lock(n) == 19 | /\ lock_msg' = [lock_msg EXCEPT ![n] = TRUE] 20 | /\ UNCHANGED <> 21 | 22 | Unlock(n) == 23 | /\ holds_lock[n] 24 | /\ holds_lock' = [holds_lock EXCEPT ![n] = FALSE] 25 | /\ unlock_msg' = [unlock_msg EXCEPT ![n] = TRUE] 26 | /\ UNCHANGED <> 27 | 28 | RecvLock(sender) == 29 | /\ lock_msg[sender] 30 | /\ ~held 31 | /\ held' = TRUE 32 | /\ lock_msg' = [lock_msg EXCEPT ![sender] = FALSE] 33 | /\ grant_msg' = [grant_msg EXCEPT ![sender] = TRUE] 34 | /\ UNCHANGED <> 35 | 36 | RecvGrant(n) == 37 | /\ grant_msg[n] 38 | /\ grant_msg' = [grant_msg EXCEPT ![n] = FALSE] 39 | /\ holds_lock' = [holds_lock EXCEPT ![n] = TRUE] 40 | /\ UNCHANGED <> 41 | 42 | RecvUnlock(sender) == 43 | /\ unlock_msg[sender] 44 | /\ unlock_msg' = [unlock_msg EXCEPT ![sender] = FALSE] 45 | /\ held' = FALSE 46 | /\ UNCHANGED <> 47 | 48 | Next == 49 | \/ \E n \in Node : Lock(n) 50 | \/ \E n \in Node : Unlock(n) 51 | \/ \E n \in Node : RecvLock(n) 52 | \/ \E n \in Node : RecvGrant(n) 53 | \/ \E n \in Node : RecvUnlock(n) 54 | 55 | Init == 56 | /\ lock_msg = [n \in Node |-> FALSE] 57 | /\ unlock_msg = [n \in Node |-> FALSE] 58 | /\ grant_msg = [n \in Node |-> FALSE] 59 | /\ holds_lock = [n \in Node |-> FALSE] 60 | /\ held = FALSE 61 | 62 | NextUnchanged == UNCHANGED vars 63 | 64 | TypeOK == 65 | /\ lock_msg \in [Node -> BOOLEAN] 66 | /\ unlock_msg \in [Node -> BOOLEAN] 67 | /\ grant_msg \in [Node -> BOOLEAN] 68 | /\ holds_lock \in [Node -> BOOLEAN] 69 | /\ held \in BOOLEAN 70 | 71 | \* No two clients think they hold the lock simultaneously. 72 | Mutex == \A x,y \in Node : (holds_lock[x] /\ holds_lock[y]) => (x = y) 73 | 74 | ==== -------------------------------------------------------------------------------- /benchmarks/Simple_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE Simple_IndProofs ---- 2 | EXTENDS Simple 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:38:51.963579 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 0.9801361560821533 10 | \* ctielimcheck_duration_secs: 1.4184200763702393 11 | \* ctigen_duration_secs: 4.748556852340698 12 | \* total_duration_secs: 7.15749192237854 13 | \* total_num_ctis_eliminated: 15 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 18 16 | \* total_num_invs_checked: 180 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 12 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv31_1_0_def == \A VARS \in ProcSet : (pc[VARS] = "a") \/ (~(x[VARS] = 0)) 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TypeOK 36 | /\ PCorrect 37 | /\ Inv31_1_0_def 38 | 39 | ASSUME NType == (N \in Nat) /\ (N > 0) 40 | ASSUME ProcType == ProcSet \in SUBSET Nat 41 | 42 | \* TLAPS Proof skeleton. 43 | THEOREM Init => IndAuto 44 | <1> SUFFICES ASSUME Init 45 | PROVE IndAuto 46 | OBVIOUS 47 | <1>1. TypeOK 48 | BY DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def, ProcSet 49 | <1>2. PCorrect 50 | BY NType DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def, ProcSet 51 | <1>3. Inv31_1_0_def 52 | BY DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def 53 | <1>4. QED 54 | BY <1>1, <1>2, <1>3 DEF IndAuto 55 | 56 | THEOREM IndAuto /\ Next => IndAuto' 57 | <1> SUFFICES ASSUME IndAuto /\ Next 58 | PROVE IndAuto' 59 | OBVIOUS 60 | <1>1. TypeOK' 61 | BY NType DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def, proc, a, b, ProcSet 62 | <1>2. PCorrect' 63 | BY NType DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def, proc, a, b, ProcSet 64 | <1>3. Inv31_1_0_def' 65 | BY NType DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv31_1_0_def, proc, a, b, ProcSet 66 | <1>4. QED 67 | BY <1>1, <1>2, <1>3 DEF IndAuto 68 | 69 | ==== 70 | -------------------------------------------------------------------------------- /benchmarks/lockserv.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserv ---- 2 | EXTENDS TLC 3 | 4 | CONSTANT Node 5 | 6 | VARIABLE lock_msg 7 | VARIABLE grant_msg 8 | VARIABLE unlock_msg 9 | VARIABLE holds_lock 10 | VARIABLE server_holds_lock 11 | 12 | vars == <> 13 | 14 | SendLock(n) == 15 | /\ lock_msg' = [lock_msg EXCEPT ![n] = TRUE] 16 | /\ UNCHANGED <> 17 | 18 | RecvLock(n) == 19 | /\ server_holds_lock 20 | /\ lock_msg[n] 21 | /\ server_holds_lock' = FALSE 22 | /\ lock_msg' = [k \in Node |-> lock_msg[k] /\ k # n] 23 | /\ grant_msg' = [grant_msg EXCEPT ![n] = TRUE] 24 | /\ UNCHANGED <> 25 | 26 | RecvGrant(n) == 27 | /\ grant_msg[n] 28 | /\ grant_msg' = [k \in Node |-> grant_msg[k] /\ k # n] 29 | /\ holds_lock' = [holds_lock EXCEPT ![n] = TRUE] 30 | /\ UNCHANGED <> 31 | 32 | Unlock(n) == 33 | /\ holds_lock[n] 34 | /\ holds_lock' = [k \in Node |-> holds_lock[k] /\ k # n] 35 | /\ unlock_msg' = [unlock_msg EXCEPT ![n] = TRUE] 36 | /\ UNCHANGED <> 37 | 38 | 39 | RecvUnlock(n) == 40 | /\ unlock_msg[n] 41 | /\ unlock_msg' = [k \in Node |-> unlock_msg[k] /\ k # n] 42 | /\ server_holds_lock' = TRUE 43 | /\ UNCHANGED <> 44 | 45 | Next == 46 | \/ \E n \in Node : SendLock(n) 47 | \/ \E n \in Node : RecvLock(n) 48 | \/ \E n \in Node : RecvGrant(n) 49 | \/ \E n \in Node : Unlock(n) 50 | \/ \E n \in Node : RecvUnlock(n) 51 | 52 | Init == 53 | /\ lock_msg = [n \in Node |-> FALSE] 54 | /\ unlock_msg = [n \in Node |-> FALSE] 55 | /\ grant_msg = [n \in Node |-> FALSE] 56 | /\ holds_lock = [n \in Node |-> FALSE] 57 | /\ server_holds_lock = TRUE 58 | 59 | TypeOK == 60 | /\ lock_msg \in [Node -> BOOLEAN] 61 | /\ grant_msg \in [Node -> BOOLEAN] 62 | /\ unlock_msg \in [Node -> BOOLEAN] 63 | /\ holds_lock \in [Node -> BOOLEAN] 64 | /\ server_holds_lock \in BOOLEAN 65 | 66 | NextUnchanged == UNCHANGED vars 67 | 68 | \* No two clients think they hold the lock simultaneously. 69 | Mutex == \A x,y \in Node : (holds_lock[x] /\ holds_lock[y]) => (x = y) 70 | 71 | ==== -------------------------------------------------------------------------------- /benchmarks/sharded_kv.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE sharded_kv ---- 2 | EXTENDS TLC, Randomization 3 | 4 | CONSTANT Key 5 | CONSTANT Value 6 | CONSTANT Node 7 | 8 | CONSTANT Nil 9 | 10 | \* The key-value store state on each node. 11 | VARIABLE table 12 | 13 | \* The set of keys owned by each node. 14 | VARIABLE owner 15 | 16 | \* The set of active transfer messages. 17 | VARIABLE transfer_msg 18 | 19 | vars == <> 20 | 21 | Reshard(k,v,n_old,n_new) == 22 | /\ table[n_old][k] = v 23 | /\ table' = [table EXCEPT ![n_old][k] = Nil] 24 | /\ owner' = [owner EXCEPT ![n_old] = owner[n_old] \ {k}] 25 | /\ transfer_msg' = transfer_msg \cup {<>} 26 | 27 | RecvTransferMsg(n, k, v) == 28 | /\ <> \in transfer_msg 29 | /\ transfer_msg' = transfer_msg \ {<>} 30 | /\ table' = [table EXCEPT ![n][k] = v] 31 | \* Become the owner of this key. 32 | /\ owner' = [owner EXCEPT ![n] = owner[n] \cup {k}] 33 | 34 | Put(n, k, v) == 35 | /\ k \in owner[n] 36 | /\ table' = [table EXCEPT ![n][k] = v] 37 | /\ UNCHANGED <> 38 | 39 | Next == 40 | \/ \E k \in Key, v \in Value, n_old,n_new \in Node : Reshard(k,v,n_old,n_new) 41 | \/ \E n \in Node, k \in Key, v \in Value : RecvTransferMsg(n,k,v) 42 | \/ \E n \in Node, k \in Key, v \in Value : Put(n,k,v) 43 | 44 | Init == 45 | /\ table = [n \in Node |-> [k \in Key |-> Nil]] 46 | \* Each node owns some subset of keys, and different nodes 47 | \* can't own the same key. 48 | /\ owner \in [Node -> SUBSET Key] 49 | /\ \A i,j \in Node : \A k \in Key : (k \in owner[i] /\ k \in owner[j]) => (i=j) 50 | /\ transfer_msg = {} 51 | 52 | TypeOK == 53 | /\ table \in [Node -> [Key -> Value \cup {Nil}]] 54 | /\ owner \in [Node -> SUBSET Key] 55 | /\ transfer_msg \in SUBSET (Node \times Key \times Value) 56 | 57 | TypeOKRandom == 58 | /\ owner \in [Node -> SUBSET Key] 59 | /\ table \in [Node -> [Key -> Value \cup {Nil}]] 60 | /\ transfer_msg \in RandomSetOfSubsets(150, 5, (Node \times Key \times Value)) 61 | 62 | \* Keys unique. 63 | Safety == 64 | \A n1,n2 \in Node, k \in Key, v1,v2 \in Value : 65 | (table[n1][k]=v1 /\ table[n2][k]=v2) => (n1=n2 /\ v1=v2) 66 | 67 | Symmetry == Permutations(Key) \cup Permutations(Value) \cup Permutations(Node) 68 | 69 | NextUnchanged == UNCHANGED vars 70 | 71 | ==== -------------------------------------------------------------------------------- /benchmarks/toy_consensus_forall.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus_forall ---- 2 | \* benchmark: pyv-toy-consensus-forall 3 | 4 | EXTENDS TLC, Naturals, FiniteSets 5 | 6 | CONSTANT Node 7 | CONSTANT Value 8 | CONSTANT Nil 9 | 10 | VARIABLE vote 11 | VARIABLE voted 12 | VARIABLE decided 13 | 14 | vars == <> 15 | 16 | \* The set of all majority quorums in the Node set. 17 | Quorums == {i \in SUBSET(Node) : Cardinality(i) * 2 > Cardinality(Node)} 18 | 19 | \* Node 'i' casts a vote for value 'v'. 20 | CastVote(i, v) == 21 | /\ ~voted[i] 22 | /\ vote' = [vote EXCEPT ![i] = v] 23 | /\ voted' = [voted EXCEPT ![i] = TRUE] 24 | /\ UNCHANGED <> 25 | 26 | \* Decide on a value 'v' with quorum 'Q'. 27 | Decide(v, Q) == 28 | /\ \A n \in Q : vote[n] = v 29 | /\ decided' = decided \cup {v} 30 | /\ UNCHANGED <> 31 | 32 | Init == 33 | /\ vote = [n \in Node |-> Nil] 34 | /\ voted = [n \in Node |-> FALSE] 35 | /\ decided = {} 36 | 37 | Next == 38 | \/ \E i \in Node, v \in Value : CastVote(i, v) 39 | \/ \E v \in Value, Q \in Quorums : Decide(v, Q) 40 | 41 | NextUnchanged == UNCHANGED vars 42 | 43 | \* Can only decide on a single value 44 | Inv == \A vi,vj \in decided : vi = vj 45 | 46 | TypeOK == 47 | /\ vote \in [Node -> Value \cup {Nil}] 48 | /\ voted \in [Node -> BOOLEAN] 49 | /\ decided \in SUBSET Value 50 | 51 | Symmetry == Permutations(Node) 52 | 53 | \* 54 | \* Weakest precondition. 55 | \* 56 | 57 | (** 58 | 59 | Inv == \A vi,vj \in decided : vi = vj 60 | wp(Next, Inv) == 61 | /\ ENABLED CastVote(i,v) => wp(Post(CastVote), Inv) 62 | /\ ENABLED Decide(v,Q) => wp(Post(Decide), Inv) 63 | 64 | A1 == wp(Decide, Inv) == 65 | /\ \A v \in Value, Q \in Quorum : 66 | \A n \in Q : (vote[n] = v) => \A vi,vj \in (decided \cup {v}) : vi = vj 67 | 68 | A2 == wp(CastVote, A1) == 69 | \A i \in Node, v \in Value : 70 | ~voted[i] => 71 | \A vz \in Value, Q \in Quorum : 72 | \A n \in Q : ([vote EXCEPT ![i] = v][n] = vz) => \A vi,vj \in (decided \cup {vz}) : vi = vj 73 | 74 | A3 == wp(Decide, A1) == 75 | \A v \in Value, Q \in Quorum : 76 | (\A n \in Q : vote[n] = v) => 77 | \A vz \in Value, Q \in Quorum : 78 | \A n \in Q : (vote[n] = vz) => \A vi,vj \in ((decided \cup {v}) \cup {vz}) : vi = vj 79 | 80 | **) 81 | 82 | 83 | ==== -------------------------------------------------------------------------------- /benchmarks/TCommit_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ------------------------------- MODULE TCommit_IndProofs ------------------------------ 2 | EXTENDS TCommit 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-06T22:24:59.962811 7 | \* is_inductive: True 8 | \* inv_size: 1 9 | \* invcheck_duration_secs: 0 10 | \* ctielimcheck_duration_secs: 0 11 | \* ctigen_duration_secs: 1.2457199096679688 12 | \* total_duration_secs: 1.2991712093353271 13 | \* total_num_ctis_eliminated: 0 14 | \* total_num_cti_elimination_rounds: 0 15 | \* total_num_invs_generated: 0 16 | \* total_num_invs_checked: 0 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* java_version_info: openjdk version "15.0.3" 2021-04-20 OpenJDK Runtime Environment Zulu15.32+15-CA (build 15.0.3+3) OpenJDK 64-Bit Server VM Zulu15.32+15-CA (build 15.0.3+3, mixed mode) 28 | \* processor: arm 29 | \* cpu_count: 8 30 | 31 | \* Inductive strengthening conjuncts 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TCTypeOK 36 | /\ TCConsistent 37 | 38 | \* TLAPS Proof skeleton. 39 | THEOREM Init => IndAuto 40 | <1> SUFFICES ASSUME Init 41 | PROVE IndAuto 42 | OBVIOUS 43 | <1>1. TCTypeOK 44 | BY DEF TCTypeOK,Init,Next,IndAuto,TCConsistent 45 | <1>2. TCConsistent 46 | BY DEF TCTypeOK,Init,Next,IndAuto,TCConsistent 47 | <1>3. QED 48 | BY <1>1, <1>2 DEF IndAuto 49 | 50 | THEOREM IndAuto /\ Next => IndAuto' 51 | <1> SUFFICES ASSUME IndAuto /\ Next 52 | PROVE IndAuto' 53 | OBVIOUS 54 | <1>1. TCTypeOK' 55 | BY DEF TCTypeOK,Init,Next,IndAuto,TCConsistent,Prepare,Decide 56 | <1>2. TCConsistent' 57 | <2> SUFFICES ASSUME NEW rm \in RM, 58 | Prepare(rm) \/ Decide(rm) 59 | PROVE TCConsistent' 60 | BY DEF Next 61 | <2>1. CASE Prepare(rm) 62 | BY <2>1 DEF TCTypeOK,Init,Next,IndAuto,TCConsistent,Prepare,Decide 63 | <2>2. CASE Decide(rm) 64 | BY <2>2 DEF TCTypeOK,Init,Next,IndAuto,TCConsistent,Prepare,Decide,notCommitted,canCommit 65 | <2>3. QED 66 | BY <2>1, <2>2 67 | 68 | <1>3. QED 69 | BY <1>1, <1>2 DEF IndAuto 70 | 71 | 72 | ============================================================================= 73 | -------------------------------------------------------------------------------- /benchmarks/sharded_kv_no_lost_keys.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE sharded_kv_no_lost_keys ---- 2 | EXTENDS TLC, Randomization 3 | 4 | CONSTANT Key 5 | CONSTANT Value 6 | CONSTANT Node 7 | 8 | CONSTANT Nil 9 | 10 | \* The key-value store state on each node. 11 | VARIABLE table 12 | 13 | \* The set of keys owned by each node. 14 | VARIABLE owner 15 | 16 | \* The set of active transfer messages. 17 | VARIABLE transfer_msg 18 | 19 | vars == <> 20 | 21 | Reshard(k,v,n_old,n_new) == 22 | /\ table[n_old][k] = v 23 | /\ table' = [table EXCEPT ![n_old][k] = Nil] 24 | /\ owner' = [owner EXCEPT ![n_old] = owner[n_old] \ {k}] 25 | /\ transfer_msg' = transfer_msg \cup {<>} 26 | 27 | RecvTransferMsg(n, k, v) == 28 | /\ <> \in transfer_msg 29 | /\ transfer_msg' = transfer_msg \ {<>} 30 | /\ table' = [table EXCEPT ![n][k] = v] 31 | \* Become the owner of this key. 32 | /\ owner' = [owner EXCEPT ![n] = owner[n] \cup {k}] 33 | 34 | Put(n, k, v) == 35 | /\ k \in owner[n] 36 | /\ table' = [table EXCEPT ![n][k] = v] 37 | /\ UNCHANGED <> 38 | 39 | Next == 40 | \/ \E k \in Key, v \in Value, n_old,n_new \in Node : Reshard(k,v,n_old,n_new) 41 | \/ \E n \in Node, k \in Key, v \in Value : RecvTransferMsg(n,k,v) 42 | \/ \E n \in Node, k \in Key, v \in Value : Put(n,k,v) 43 | 44 | Init == 45 | /\ table = [n \in Node |-> [k \in Key |-> Nil]] 46 | /\ transfer_msg = {} 47 | \* Each node owns some subset of keys, and different nodes 48 | \* can't own the same key. 49 | /\ owner \in [Node -> SUBSET Key] 50 | /\ \A i,j \in Node : \A k \in Key : (k \in owner[i] /\ k \in owner[j]) => (i=j) 51 | \* No lost keys assumption: every key is owned by some node. 52 | /\ \A k \in Key : \E n \in Node : k \in owner[n] 53 | 54 | TypeOK == 55 | /\ table \in [Node -> [Key -> Value \cup {Nil}]] 56 | /\ owner \in [Node -> SUBSET Key] 57 | /\ transfer_msg \in SUBSET (Node \X Key \X Value) 58 | 59 | TypeOKRandom == 60 | /\ owner \in RandomSubset(35, [Node -> SUBSET Key]) 61 | /\ table \in RandomSubset(35, [Node -> [Key -> Value \cup {Nil}]]) 62 | /\ transfer_msg \in RandomSetOfSubsets(35, 6, (Node \times Key \times Value)) 63 | 64 | \* invariant [safety] (exists N,K,V. transfer_msg(N,K,V)) | (forall K. exists N. owner(N,K)) 65 | Safety == 66 | \/ \E n \in Node, k \in Key, v \in Value : <> \in transfer_msg 67 | \/ \A k \in Key : \E n \in Node : k \in owner[n] 68 | 69 | Symmetry == Permutations(Key) \cup Permutations(Value) \cup Permutations(Node) 70 | 71 | NextUnchanged == UNCHANGED vars 72 | 73 | ==== -------------------------------------------------------------------------------- /benchmarks/Consensus.tla: -------------------------------------------------------------------------------- 1 | ----------------------------- MODULE Consensus ------------------------------ 2 | \* benchmark: tla-consensus 3 | 4 | EXTENDS Naturals, FiniteSets 5 | 6 | CONSTANT Value 7 | (*************************************************************************) 8 | (* The set of all values that can be chosen. *) 9 | (*************************************************************************) 10 | 11 | VARIABLE chosen 12 | (*************************************************************************) 13 | (* The set of all values that have been chosen. *) 14 | (*************************************************************************) 15 | 16 | (***************************************************************************) 17 | (* The type-correctness invariant. *) 18 | (***************************************************************************) 19 | TypeOK == /\ chosen \in SUBSET Value 20 | 21 | (***************************************************************************) 22 | (* The initial predicate and next-state relation. *) 23 | (***************************************************************************) 24 | Init == chosen = {} 25 | 26 | Next == /\ chosen = {} 27 | /\ \E v \in Value : chosen' = {v} 28 | 29 | (***************************************************************************) 30 | (* The complete spec. *) 31 | (***************************************************************************) 32 | Spec == Init /\ [][Next]_chosen 33 | ----------------------------------------------------------------------------- 34 | (***************************************************************************) 35 | (* Safety: At most one value is chosen. *) 36 | (***************************************************************************) 37 | Inv == /\ TypeOK 38 | /\ Cardinality(chosen) \leq 1 39 | 40 | THEOREM Invariance == Spec => []Inv 41 | <1>1. Init => Inv 42 | <1>2. Inv /\ [Next]_chosen => Inv' 43 | <1>3. QED 44 | <2>1. Inv /\ [][Next]_chosen => []Inv 45 | BY <1>2 \* and a TLA proof rule 46 | <2>2. QED 47 | BY <1>1, <2>1 \* and simple logic 48 | ----------------------------------------------------------------------------- 49 | (***************************************************************************) 50 | (* Liveness: A value is eventually chosen. *) 51 | (***************************************************************************) 52 | Success == <>(chosen # {}) 53 | LiveSpec == Spec /\ WF_chosen(Next) 54 | 55 | THEOREM LivenessTheorem == LiveSpec => Success 56 | ============================================================================= 57 | -------------------------------------------------------------------------------- /benchmarks/sharded_kv_no_lost_keys_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE sharded_kv_no_lost_keys_IndProofs ---- 2 | EXTENDS sharded_kv_no_lost_keys, FiniteSetTheorems 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-05T19:29:54.095415 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 1.4542489051818848 10 | \* ctielimcheck_duration_secs: 2.2698278427124023 11 | \* ctigen_duration_secs: 7.955007791519165 12 | \* total_duration_secs: 11.684753894805908 13 | \* total_num_ctis_eliminated: 404 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 179 16 | \* total_num_invs_checked: 264 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv45_1_0_def == \A KI \in Key : \E NJ \in Node : \E VALI \in Value : (<> \in transfer_msg) \/ ((KI \in owner[NJ])) 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TypeOK 36 | /\ Safety 37 | /\ Inv45_1_0_def 38 | 39 | ASSUME Fin == IsFiniteSet(Node) /\ IsFiniteSet(Key) /\ IsFiniteSet(Value) 40 | ASSUME NonEmpty == Node # {} /\ Value # {} /\ Key # {} 41 | 42 | \* TLAPS Proof skeleton. 43 | THEOREM Init => IndAuto 44 | <1> SUFFICES ASSUME Init 45 | PROVE IndAuto 46 | OBVIOUS 47 | <1>1. TypeOK 48 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def 49 | <1>2. Safety 50 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def 51 | <1>3. Inv45_1_0_def 52 | BY NonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def 53 | <1>4. QED 54 | BY <1>1, <1>2, <1>3 DEF IndAuto 55 | 56 | 57 | THEOREM IndAuto /\ Next => IndAuto' 58 | <1> SUFFICES ASSUME IndAuto /\ Next 59 | PROVE IndAuto' 60 | OBVIOUS 61 | <1>1. TypeOK' 62 | <2>1. CASE \E k \in Key, v \in Value, n_old,n_new \in Node : Reshard(k,v,n_old,n_new) 63 | BY <2>1, Fin,NonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def,Reshard,RecvTransferMsg,Put 64 | <2>2. CASE \E n \in Node, k \in Key, v \in Value : RecvTransferMsg(n,k,v) 65 | BY <2>2, Fin,NonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def,Reshard,RecvTransferMsg,Put 66 | <2>3. CASE \E n \in Node, k \in Key, v \in Value : Put(n,k,v) 67 | BY <2>3, Fin,NonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def,Reshard,RecvTransferMsg,Put 68 | <2>4. QED 69 | BY <2>1, <2>2, <2>3 DEF Next 70 | 71 | <1>2. Safety' 72 | BY Fin,NonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def,Reshard,RecvTransferMsg,Put 73 | <1>3. Inv45_1_0_def' 74 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv45_1_0_def,Reshard,RecvTransferMsg,Put 75 | <1>4. QED 76 | BY <1>1, <1>2, <1>3 DEF IndAuto 77 | 78 | 79 | ==== 80 | -------------------------------------------------------------------------------- /benchmarks/Paxos.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "maxBal[ACCI] = -1", 4 | "maxVBal[ACCI] = -1", 5 | "maxBal[ACCI] < BALI", 6 | "maxBal[ACCI] = BALI", 7 | "maxBal[ACCI] < BALJ", 8 | "maxBal[ACCI] = BALJ", 9 | "maxBal[ACCI] < BALK", 10 | "maxBal[ACCI] = BALK", 11 | "maxBal[ACCI] < maxVBal[ACCI]", 12 | "maxVBal[ACCI] > BALI", 13 | "maxVBal[ACCI] = BALI", 14 | "maxVBal[ACCI] > BALJ", 15 | "maxVBal[ACCI] = BALJ", 16 | "maxVal[ACCI] = VALI", 17 | "ChosenAt(BALI, VALI)", 18 | "ChosenAt(BALI, VALJ)", 19 | "ChosenAt(BALJ, VALI)", 20 | "ChosenAt(BALJ, VALJ)", 21 | "ChosenAt(BALK, VALI)", 22 | "ChosenAt(BALK, VALJ)", 23 | "ChosenAt(maxBal[ACCI], VALI)", 24 | "ChosenAt(maxVBal[ACCI], VALI)", 25 | "msg1a(ACCI,BALI)", 26 | "msg1a(ACCI,BALJ)", 27 | "msg1a(ACCI,BALK)", 28 | "msg1b(ACCI,BALI,BALJ,VALI)", 29 | "msg1b(ACCI,BALI,BALJ,VALJ)", 30 | "msg1b(ACCI,BALJ,BALK,VALI)", 31 | "msg1b(ACCI,BALJ,BALK,VALJ)", 32 | "msg2a(BALI,VALI)", 33 | "msg2a(BALJ,VALI)", 34 | "msg2a(BALK,VALI)", 35 | "msg2a(BALI,VALJ)", 36 | "msg2a(BALJ,VALJ)", 37 | "msg2a(BALK,VALJ)", 38 | "msg2b(ACCI,BALI,VALI)", 39 | "msg2b(ACCI,BALJ,VALI)", 40 | "msg2b(ACCI,BALK,VALI)", 41 | "msg2b(ACCI,BALI,VALJ)", 42 | "msg2b(ACCI,BALJ,VALJ)", 43 | "msg2b(ACCI,BALK,VALJ)", 44 | "\\E m \\in msgs : m.bal >= maxBal[ACCI]", 45 | "\\E Q \\in Quorum : ShowsSafeAt(Q, maxBal[ACCI], VALI)", 46 | "VotedFor(ACCI,BALI,VALI)", 47 | "VotedFor(ACCI,BALI,VALJ)", 48 | "VotedFor(ACCI,BALJ,VALI)", 49 | "VotedFor(ACCI,BALJ,VALJ)", 50 | "VotedFor(ACCI,BALK,VALI)", 51 | "VotedFor(ACCI,BALK,VALJ)", 52 | "VALI=VALJ /\\ maxBal = maxBal", 53 | "SafeAt(BALI, VALI)", 54 | "SafeAt(BALI, VALJ)", 55 | "SafeAt(BALJ, VALI)", 56 | "SafeAt(BALJ, VALJ)", 57 | "SafeAt(BALK, VALI)", 58 | "SafeAt(BALK, VALJ)", 59 | "BALI = -1 /\\ maxBal = maxBal", 60 | "BALJ = -1 /\\ maxBal = maxBal", 61 | "BALK = -1 /\\ maxBal = maxBal", 62 | "VALI = None /\\ maxBal = maxBal", 63 | "VALJ = None /\\ maxBal = maxBal" 64 | ], 65 | "preds_alt" : [], 66 | "safety" : "Inv", 67 | "constants" : "CONSTANTS\nAcceptor={a1,a2,a3}\nQuorum={{a1, a2}, {a1, a3}, {a2, a3}}\nBallot={0,1,2}\nNone=None\nValue={v1,v2}\nv1=v1\nv2=v2\na1=a1\na2=a2\na3=a3\n", 68 | "constraint" : "", 69 | "quant_inv" : "\\A ACCI \\in Acceptor : \\A VALI \\in Value : \\A VALJ \\in Value : \\A BALI \\in Ballot : \\A BALJ \\in Ballot : \\A BALK \\in Ballot : ", 70 | "quant_inv_alt" : null, 71 | "quant_vars": ["VALI", "VALJ"], 72 | "model_consts" : "CONSTANT a1,a2,a3,v1,v2", 73 | "symmetry" : true, 74 | "typeok" : "TypeOKRandom", 75 | "simulate" : true 76 | } -------------------------------------------------------------------------------- /benchmarks/MongoLoglessDynamicRaft.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preds" : [ 3 | "(configTerm[VARI] = configTerm[VARJ])", 4 | 5 | "(configTerm[VARI] > configTerm[VARJ])", 6 | "(configTerm[VARJ] > configTerm[VARI])", 7 | 8 | "(configTerm[VARI] >= configTerm[VARJ])", 9 | "(configTerm[VARJ] >= configTerm[VARI])", 10 | 11 | "(configTerm[VARI] <= configTerm[VARJ])", 12 | "(configTerm[VARJ] <= configTerm[VARI])", 13 | 14 | "(configTerm[VARI] = currentTerm[VARI])", 15 | "(configTerm[VARI] = currentTerm[VARJ])", 16 | "(configTerm[VARJ] = currentTerm[VARI])", 17 | "(configTerm[VARI] = configTerm[VARJ])", 18 | 19 | "(currentTerm[VARI] > currentTerm[VARJ])", 20 | "(currentTerm[VARJ] > currentTerm[VARI])", 21 | 22 | "(currentTerm[VARI] >= currentTerm[VARJ])", 23 | "(currentTerm[VARJ] >= currentTerm[VARI])", 24 | 25 | "(currentTerm[VARI] <= currentTerm[VARJ])", 26 | "(currentTerm[VARJ] <= currentTerm[VARI])", 27 | 28 | "(currentTerm[VARI] = currentTerm[VARJ])", 29 | 30 | "(state[VARI] = Primary)", 31 | "(state[VARJ] = Primary)", 32 | 33 | "(configVersion[VARI] > configVersion[VARJ])", 34 | "(configVersion[VARJ] > configVersion[VARI])", 35 | 36 | "(configVersion[VARI] >= configVersion[VARJ])", 37 | "(configVersion[VARJ] >= configVersion[VARI])", 38 | 39 | "(configVersion[VARI] <= configVersion[VARJ])", 40 | "(configVersion[VARJ] <= configVersion[VARI])", 41 | 42 | "(configVersion[VARI] = configVersion[VARJ])", 43 | 44 | "(config[VARI] = config[VARJ])", 45 | 46 | "QuorumsOverlap(config[VARI], config[VARJ])", 47 | 48 | "(config[VARI] = {})", 49 | "(config[VARJ] = {})", 50 | "(VARI \\in config[VARI])", 51 | "(VARJ \\in config[VARJ])", 52 | 53 | "IsNewerConfig(VARI, VARJ)", 54 | "IsNewerConfig(VARJ, VARI)", 55 | "IsNewerOrEqualConfig(VARI, VARJ)", 56 | "IsNewerOrEqualConfig(VARJ, VARI)", 57 | "ConfigDisabled(VARI)", 58 | "ConfigDisabled(VARJ)" 59 | 60 | 61 | 62 | 63 | ], 64 | "preds_alt" : [], 65 | "safety" : "Safety", 66 | "constants" : [ 67 | "CONSTANTS" , 68 | "Nil = Nil", 69 | "Server = {n1,n2,n3,n4}", 70 | "Secondary = Secondary", 71 | "Primary = Primary", 72 | "MaxLogLen = 0", 73 | "MaxTerm = 3", 74 | "MaxConfigVersion = 3", 75 | "InitTerm = 0", 76 | "Nat <- NatFinite", 77 | "n1 = n1", 78 | "n2 = n2", 79 | "n3 = n3", 80 | "n4 = n4" 81 | ], 82 | "constraint" : "CONSTRAINT StateConstraint", 83 | "quant_inv" : "\\A VARI \\in Server : \\A VARJ \\in Server : ", 84 | "quant_inv_alt" : null, 85 | "quant_vars": ["VARI", "VARJ"], 86 | "model_consts" : "CONSTANT n1,n2,n3,n4", 87 | "symmetry" : true, 88 | "typeok" : "TypeOKRandom", 89 | "try_final_minimize": true, 90 | "load_inv_cache": "benchmarks/mldr-db.inv", 91 | "simulate" : true 92 | } -------------------------------------------------------------------------------- /benchmarks/SimpleRegular_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE SimpleRegular_IndProofs ---- 2 | EXTENDS SimpleRegular 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:41:29.182120 7 | \* is_inductive: True 8 | \* inv_size: 4 9 | \* invcheck_duration_secs: 1.44685697555542 10 | \* ctielimcheck_duration_secs: 2.992962121963501 11 | \* ctigen_duration_secs: 4.984469413757324 12 | \* total_duration_secs: 9.432929992675781 13 | \* total_num_ctis_eliminated: 1972 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 165 16 | \* total_num_invs_checked: 1104 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv417_1_0_def == \A VARS \in ProcSet : (1 \in x[VARS]) \/ ((pc[VARS] = "a1")) 32 | Inv921_1_1_def == \A VARS \in ProcSet : ~(0 \in x[VARS]) \/ (~(pc[VARS] = "Done")) 33 | Inv924_1_2_def == \A VARS \in ProcSet : ~(0 \in x[VARS]) \/ (~(pc[VARS] = "b")) 34 | 35 | \* The inductive invariant candidate. 36 | IndAuto == 37 | /\ TypeOK 38 | /\ PCorrect 39 | /\ Inv417_1_0_def 40 | /\ Inv921_1_1_def 41 | /\ Inv924_1_2_def 42 | 43 | \* TLAPS Proof skeleton. 44 | THEOREM Init => IndAuto 45 | <1> SUFFICES ASSUME Init 46 | PROVE IndAuto 47 | OBVIOUS 48 | <1>1. TypeOK 49 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,ProcSet 50 | <1>2. PCorrect 51 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,ProcSet 52 | <1>3. Inv417_1_0_def 53 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def 54 | <1>4. Inv921_1_1_def 55 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def 56 | <1>5. Inv924_1_2_def 57 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def 58 | <1>6. QED 59 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 60 | 61 | 62 | THEOREM IndAuto /\ Next => IndAuto' 63 | <1> SUFFICES ASSUME IndAuto /\ Next 64 | PROVE IndAuto' 65 | OBVIOUS 66 | <1>1. TypeOK' 67 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,a1,a2,b,proc 68 | <1>2. PCorrect' 69 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,a1,a2,b,proc,ProcSet 70 | <1>3. Inv417_1_0_def' 71 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,a1,a2,b,proc,ProcSet 72 | <1>4. Inv921_1_1_def' 73 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,a1,a2,b,proc,ProcSet 74 | <1>5. Inv924_1_2_def' 75 | BY NAssump DEF TypeOK,Init,Next,IndAuto,PCorrect,Inv417_1_0_def,Inv921_1_1_def,Inv924_1_2_def,a1,a2,b,proc,ProcSet 76 | <1>6. QED 77 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 78 | 79 | 80 | ==== 81 | -------------------------------------------------------------------------------- /benchmarks/quorum_leader_election_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE quorum_leader_election_IndProofs ---- 2 | EXTENDS quorum_leader_election 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:37:08.237334 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 1.3358678817749023 10 | \* ctielimcheck_duration_secs: 1.7536170482635498 11 | \* ctigen_duration_secs: 6.9433581829071045 12 | \* total_duration_secs: 10.044521808624268 13 | \* total_num_ctis_eliminated: 204 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 19 16 | \* total_num_invs_checked: 112 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: False 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv55_1_0_def == \A VARS \in Node : \A VART \in Node : \A Q \in Quorums : \E VARN \in Q : (voted[VARN] = VARS) \/ (~(isleader[VARS])) 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TypeOK 36 | /\ Inv 37 | /\ Inv55_1_0_def 38 | 39 | ASSUME QuorumType == Quorums \subseteq SUBSET Node 40 | ASSUME NodeFinite == IsFiniteSet(Node) 41 | ASSUME QuorumsAreNonEmpty == \A Q \in Quorums : Q # {} 42 | ASSUME QuorumsIntersect == \A Q1,Q2 \in Quorums : Q1 \cap Q2 # {} 43 | ASSUME NilType == Nil \notin Node 44 | 45 | \* TLAPS Proof skeleton. 46 | THEOREM Init => IndAuto 47 | <1> SUFFICES ASSUME Init 48 | PROVE IndAuto 49 | OBVIOUS 50 | <1>1. TypeOK 51 | BY QuorumType, QuorumsAreNonEmpty DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def 52 | <1>2. Inv 53 | BY QuorumType DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def 54 | <1>3. Inv55_1_0_def 55 | BY QuorumType, QuorumsAreNonEmpty DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def 56 | <1>4. QED 57 | BY <1>1, <1>2, <1>3 DEF IndAuto 58 | 59 | THEOREM IndAuto /\ Next => IndAuto' 60 | <1> SUFFICES ASSUME IndAuto, 61 | Next 62 | PROVE IndAuto' 63 | OBVIOUS 64 | <1>1. CASE \E i,j \in Node : Vote(i,j) 65 | <2>1. TypeOK' 66 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote,BecomeLeader 67 | <2>2. Inv' 68 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote,BecomeLeader 69 | <2>3. Inv55_1_0_def' 70 | BY <1>1, QuorumType, QuorumsAreNonEmpty, NodeFinite, QuorumsIntersect, NilType DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote 71 | <2>4. QED 72 | BY <2>1, <2>2, <2>3 DEF IndAuto 73 | 74 | <1>2. CASE \E i \in Node : \E Q \in Quorums : BecomeLeader(i, Q) 75 | <2>1. TypeOK' 76 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote,BecomeLeader 77 | <2>2. Inv' 78 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote,BecomeLeader 79 | <2>3. Inv55_1_0_def' 80 | BY <1>2, QuorumsIntersect, QuorumType, QuorumsAreNonEmpty, NodeFinite DEF TypeOK,Init,Next,IndAuto,Inv,Inv55_1_0_def,Vote,BecomeLeader 81 | <2>4. QED 82 | BY <2>1, <2>2, <2>3 DEF IndAuto 83 | 84 | <1>3. QED 85 | BY <1>1, <1>2 DEF Next 86 | 87 | ==== 88 | -------------------------------------------------------------------------------- /benchmarks/two_phase_commit.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE two_phase_commit ---- 2 | \* benchmark: i4-two-phase-commit 3 | 4 | EXTENDS TLC 5 | 6 | CONSTANT Node 7 | 8 | VARIABLE vote_yes 9 | VARIABLE vote_no 10 | VARIABLE alive 11 | VARIABLE go_commit 12 | VARIABLE go_abort 13 | VARIABLE decide_commit 14 | VARIABLE decide_abort 15 | 16 | VARIABLE abort_flag 17 | 18 | vars == <> 19 | 20 | Vote1(n) == 21 | /\ n \in alive 22 | /\ n \notin vote_no 23 | /\ n \notin decide_commit 24 | /\ n \notin decide_abort 25 | /\ vote_yes' = vote_yes \cup {n} 26 | /\ UNCHANGED <> 27 | 28 | Vote2(n) == 29 | /\ n \in alive 30 | /\ n \notin vote_yes 31 | /\ n \notin decide_commit 32 | /\ n \notin decide_abort 33 | /\ vote_no' = vote_no \cup {n} 34 | /\ abort_flag' = TRUE 35 | /\ decide_abort' = decide_abort \cup {n} 36 | /\ UNCHANGED <> 37 | 38 | Fail(n) == 39 | /\ n \in alive 40 | /\ alive' = alive \ {n} 41 | /\ abort_flag' = TRUE 42 | /\ UNCHANGED <> 43 | 44 | Go1 == 45 | /\ \A n \in Node : n \notin go_commit 46 | /\ \A n \in Node : n \notin go_abort 47 | /\ \A n \in Node : n \in vote_yes 48 | /\ go_commit' = Node 49 | /\ UNCHANGED <> 50 | 51 | Go2 == 52 | /\ \A n \in Node : n \notin go_commit 53 | /\ \A n \in Node : n \notin go_abort 54 | /\ \E n \in Node : (n \in vote_no) \/ (n \notin alive) 55 | /\ go_abort' = Node 56 | /\ UNCHANGED <> 57 | 58 | Commit(n) == 59 | /\ n \in alive 60 | /\ n \in go_commit 61 | /\ decide_commit' = decide_commit \cup {n} 62 | /\ UNCHANGED <> 63 | 64 | Abort(n) == 65 | /\ n \in alive 66 | /\ n \in go_abort 67 | /\ decide_abort' = decide_abort \cup {n} 68 | /\ UNCHANGED <> 69 | 70 | Next == 71 | \/ \E n \in Node : Vote1(n) 72 | \/ \E n \in Node : Vote2(n) 73 | \/ \E n \in Node : Fail(n) 74 | \/ Go1 75 | \/ Go2 76 | \/ \E n \in Node : Commit(n) 77 | \/ \E n \in Node : Abort(n) 78 | 79 | Init == 80 | /\ vote_yes = {} 81 | /\ vote_no = {} 82 | /\ alive = Node 83 | /\ go_commit = {} 84 | /\ go_abort = {} 85 | /\ decide_commit = {} 86 | /\ decide_abort = {} 87 | /\ abort_flag = FALSE 88 | 89 | NextUnchanged == UNCHANGED vars 90 | 91 | TypeOK == 92 | /\ vote_yes \in SUBSET Node 93 | /\ vote_no \in SUBSET Node 94 | /\ alive \in SUBSET Node 95 | /\ go_commit \in SUBSET Node 96 | /\ go_abort \in SUBSET Node 97 | /\ decide_commit \in SUBSET Node 98 | /\ decide_abort \in SUBSET Node 99 | /\ abort_flag \in BOOLEAN 100 | 101 | Safety == 102 | /\ \A n,n2 \in Node : (n \in decide_commit) => (n2 \notin decide_abort) 103 | /\ \A n,n2 \in Node : (n \in decide_commit) => (n2 \in vote_yes) 104 | /\ \A n,n2 \in Node : (n \in decide_abort) => abort_flag 105 | 106 | Symmetry == Permutations(Node) 107 | 108 | ==== -------------------------------------------------------------------------------- /benchmarks/learning_switch.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE learning_switch ---- 2 | \* benchmark: pyv-learning-switch 3 | 4 | EXTENDS TLC, Naturals, FiniteSets, Randomization 5 | 6 | CONSTANT 7 | \* @type: Set(Str); 8 | Node 9 | 10 | VARIABLE 11 | \* @type: Set(<>); 12 | table, 13 | \* @type: Set(<>); 14 | pending 15 | 16 | 17 | \* @type: (Str, Str) => Bool; 18 | NewPacket(ps,pd) == 19 | /\ pending' = pending \cup {<>} 20 | /\ UNCHANGED table 21 | 22 | \* @type: (Str, Str, Str, Str, Str) => Bool; 23 | Forward(ps,pd,sw0,sw1,nondet) == 24 | /\ <> \in pending 25 | \* Remove all elements whose first element is not 'nondet', 26 | \* and also add elements for all d \in Node. 27 | /\ pending' = 28 | {<> \in pending : psa = nondet} \cup 29 | {<> : d \in Node} 30 | /\ table' = IF ( (ps # sw1) /\ (\A w \in Node : w # sw1 => <> \notin table) ) 31 | THEN table \cup 32 | {<> \in Node \X Node \X Node : 33 | /\ px = ps 34 | /\ (<> \in table /\ <> \in table) } 35 | ELSE table 36 | 37 | Next == 38 | \/ \E ps,pd \in Node : NewPacket(ps,pd) 39 | \/ \E ps,pd,sw0,sw1,nondet \in Node : Forward(ps,pd,sw0,sw1,nondet) 40 | 41 | Init == 42 | /\ table = {<> \in (Node \X Node \X Node) : n1 = n2} 43 | /\ pending = {} 44 | 45 | NextUnchanged == UNCHANGED <> 46 | 47 | TypeOK == 48 | /\ table \in SUBSET (Node \X Node \X Node) 49 | /\ pending \in SUBSET (Node \X Node \X Node \X Node) 50 | 51 | \* invariant [safety] 52 | \* (forall T, X. table(T,X,X)) & 53 | \* (forall T, X, Y, Z. table(T,X,Y) & table(T,Y,Z) -> table(T,X,Z)) & 54 | \* (forall T, X, Y. table(T,X,Y) & table(T,Y,X) -> X = Y) & 55 | \* (forall T, X, Y, Z. table(T,X,Y) & table(T,X,Z) -> table(T,Y,Z) | table(T,Z,Y)) 56 | Safety == 57 | \* /\ TRUE 58 | \* /\ TypeOK 59 | /\ \A t,x \in Node : <> \in table 60 | /\ \A t,x,y,z \in Node : (<> \in table /\ <> \in table) => (<> \in table) 61 | /\ \A t,x,y \in Node : (<> \in table /\ <> \in table) => (x = y) 62 | /\ \A t,x,y,z \in Node : (<> \in table /\ <> \in table) => (<> \in table \/ <> \in table) 63 | 64 | \* Correct strengthening conjuncts. 65 | \* /\ \A ps,pd,s,d \in Node : (<> \in pending /\ ps # s) => <> \in table 66 | \* /\ \A t,x,y \in Node : (<> \in table /\ t # y /\ x # y) => <> \in table 67 | 68 | \* #invariant [help_3] pending(PS,PD,S,D) & PS ~= S -> table(PS,S,PS) 69 | \* #invariant [help_4] table(T,X,Y) & T ~= Y & X ~= Y -> table(T,Y,T) 70 | 71 | StateConstraint == Cardinality(pending) < 5 72 | 73 | Symmetry == Permutations(Node) 74 | 75 | Test == Cardinality(pending) < 3 76 | 77 | \* RandomSetOfSubsets(k,n,S) equals a pseudo-randomly chosen set of subets of S. 78 | \* That is, each element T of the returned set is a subset of S, and k such choices 79 | \* of T are made when selecting these subsets. 80 | \* The average number of elements in each subset is n. 81 | 82 | \* TODO: Figure out proper tuning for this. 83 | TypeOKRandom == 84 | /\ table \in RandomSetOfSubsets(80000, RandomElement(16..24), (Node \X Node \X Node)) 85 | /\ pending \in RandomSetOfSubsets(50, 8, (Node \X Node \X Node \X Node)) 86 | 87 | \* \* A1 == <> \notin table 88 | \* Test == Cardinality(pending) < 2 89 | \* A2 == Cardinality(table) = 16 90 | 91 | ==== -------------------------------------------------------------------------------- /benchmarks/peterson.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE peterson ---- 2 | EXTENDS TLC, Naturals, FiniteSets 3 | \* 4 | \* Specification of Peterson's algorithm in TLA+. 5 | \* 6 | 7 | (* 8 | Summary of the algorithm in pseudocode (i.e. PlusCal). 9 | 10 | variables flag = [i \in {0, 1} |-> FALSE], turn = 0; 11 | \* Declares the global variables flag and turn and their initial values; 12 | \* flag is a 2-element array with initially flag[0] = flag[1] = FALSE. 13 | process (proc \in {0,1}) { 14 | \* Declares two processes with identifier self equal to 0 and 1. 15 | a1: while (TRUE) { 16 | skip ; \* the noncritical section 17 | a2: flag[self] := TRUE ; 18 | a3: turn := 1 - self ; 19 | a4: await (flag[1-self] = FALSE) \/ (turn = self); 20 | cs: skip ; \* the critical section 21 | a5: flag[self] := FALSE } } } 22 | *) 23 | 24 | VARIABLE flag, turn 25 | 26 | \* The program counter for each process. 27 | VARIABLE pc 28 | 29 | vars == << flag, turn, pc >> 30 | 31 | \* The set of processes. 32 | CONSTANT ProcSet 33 | 34 | ASSUME Cardinality(ProcSet) = 2 35 | 36 | \* Return the other process. 37 | Other(p) == CHOOSE q \in ProcSet : q # p 38 | 39 | Init == 40 | /\ flag = [i \in ProcSet |-> FALSE] 41 | /\ turn \in ProcSet 42 | /\ pc = [self \in ProcSet |-> "a1"] 43 | 44 | \* 45 | \* The transitions of the protocol. 46 | \* 47 | 48 | a1(self) == /\ pc[self] = "a1" 49 | /\ TRUE 50 | /\ pc' = [pc EXCEPT ![self] = "a2"] 51 | /\ UNCHANGED << flag, turn >> 52 | 53 | \* A process sets its own flag to TRUE. 54 | a2(self) == /\ pc[self] = "a2" 55 | /\ flag' = [flag EXCEPT ![self] = TRUE] 56 | /\ pc' = [pc EXCEPT ![self] = "a3"] 57 | /\ turn' = turn 58 | 59 | 60 | \* A process updates 'turn'. 61 | a3(self, other) == /\ pc[self] = "a3" 62 | /\ self # other 63 | /\ turn' = other 64 | /\ pc' = [pc EXCEPT ![self] = "a4"] 65 | /\ flag' = flag 66 | 67 | \* A process enters the critical section. 68 | a4(self, other) == 69 | /\ self # other 70 | /\ pc[self] = "a4" 71 | /\ (flag[other] = FALSE) \/ (turn = self) 72 | /\ pc' = [pc EXCEPT ![self] = "cs"] 73 | /\ UNCHANGED << flag, turn >> 74 | 75 | \* A process exits the critical section. 76 | cs(self) == /\ pc[self] = "cs" 77 | /\ TRUE 78 | /\ pc' = [pc EXCEPT ![self] = "a5"] 79 | /\ UNCHANGED << flag, turn >> 80 | 81 | \* A process resets its own flag to FALSE after it left the critical section. 82 | a5(self) == /\ pc[self] = "a5" 83 | /\ flag' = [flag EXCEPT ![self] = FALSE] 84 | /\ pc' = [pc EXCEPT ![self] = "a1"] 85 | /\ turn' = turn 86 | 87 | Next == 88 | \E self,other \in ProcSet : 89 | \/ a1(self) 90 | \/ a2(self) 91 | \/ a3(self, other) 92 | \/ a4(self, other) 93 | \/ cs(self) 94 | \/ a5(self) 95 | 96 | Spec == /\ Init /\ [][Next]_vars 97 | 98 | \* The mutual exclusion property i.e. the processes cannot be 99 | \* inside the critical sectuion at the same time. 100 | Mutex == \A p,q \in ProcSet : (p # q) => ~(pc[p] = "cs" /\ pc[q] = "cs") 101 | 102 | Symmetry == Permutations(ProcSet) 103 | -------------------------------------------------------- 104 | 105 | TypeOK == 106 | /\ flag \in [ProcSet -> {TRUE, FALSE}] 107 | /\ turn \in ProcSet 108 | /\ pc \in [ProcSet -> {"a1","a2","a3","a4","a5","cs"}] 109 | 110 | 111 | NextUnchanged == UNCHANGED vars 112 | ==== 113 | -------------------------------------------------------------------------------- /benchmarks/consensus_forall.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE consensus_forall ---- 2 | \* benchmark: pyv-consensus-forall 3 | 4 | EXTENDS TLC, Naturals, Randomization 5 | 6 | CONSTANT Node,Value,Quorum 7 | 8 | VARIABLE vote_request_msg 9 | VARIABLE voted 10 | VARIABLE vote_msg 11 | VARIABLE votes 12 | VARIABLE leader 13 | VARIABLE voting_quorum 14 | VARIABLE decided 15 | 16 | vars == <> 17 | 18 | SendRequestVote(i,j) == 19 | /\ vote_request_msg' = vote_request_msg \cup {<>} 20 | /\ UNCHANGED <> 21 | 22 | SendVote(src,dst)== 23 | /\ ~voted[src] 24 | /\ <> \in vote_request_msg 25 | /\ vote_msg' = vote_msg \cup {<>} 26 | /\ voted' = [voted EXCEPT ![src] = TRUE] 27 | /\ UNCHANGED <> 28 | 29 | RecvVote(i,sender)== 30 | /\ <> \in vote_msg 31 | /\ votes' = votes \cup {<>} 32 | /\ UNCHANGED <> 33 | 34 | ChooseVotingQuorum(i) == 35 | \E Q \in Quorum : 36 | /\ \A v \in Q : <> \in votes 37 | /\ voting_quorum' = Q 38 | /\ UNCHANGED <> 39 | 40 | BecomeLeader(i) == 41 | /\ voting_quorum # {} 42 | /\ \A v \in voting_quorum : <> \in votes 43 | /\ leader' = [leader EXCEPT ![i] = TRUE] 44 | /\ UNCHANGED <> 45 | 46 | Decide(i,v) == 47 | /\ leader[i] 48 | /\ \A vx \in Value : <> \notin decided 49 | /\ decided' = decided \cup {<>} 50 | /\ UNCHANGED <> 51 | 52 | Init == 53 | /\ vote_request_msg = {} 54 | /\ voted = [s \in Node |-> FALSE] 55 | /\ vote_msg = {} 56 | /\ votes = {} 57 | /\ leader = [s \in Node |-> FALSE] 58 | /\ voting_quorum \in Quorum 59 | /\ decided = {} 60 | 61 | SendRequestVoteAction == \E i,j \in Node : SendRequestVote(i,j) 62 | SendVoteAction == \E i,j \in Node : SendVote(i,j) 63 | RecvVoteAction == \E i,j \in Node : RecvVote(i,j) 64 | ChooseVotingQuorumAction == \E i \in Node : ChooseVotingQuorum(i) 65 | BecomeLeaderAction == \E i \in Node : BecomeLeader(i) 66 | DecideAction == \E i \in Node, v \in Value : Decide(i, v) 67 | 68 | Next == 69 | \/ SendRequestVoteAction 70 | \/ SendVoteAction 71 | \/ RecvVoteAction 72 | \/ ChooseVotingQuorumAction 73 | \/ BecomeLeaderAction 74 | \/ DecideAction 75 | 76 | TypeOK == 77 | /\ vote_request_msg \in SUBSET (Node \X Node) 78 | /\ voted \in [Node -> BOOLEAN] 79 | /\ vote_msg \in SUBSET (Node \X Node) 80 | /\ votes \in SUBSET (Node \X Node) 81 | /\ leader \in [Node -> BOOLEAN] 82 | /\ voting_quorum \in Quorum 83 | /\ decided \in SUBSET (Node \X Value) 84 | 85 | TypeOKRandom == 86 | /\ vote_request_msg \in RandomSubset(15, SUBSET (Node \X Node)) 87 | /\ voted \in RandomSubset(5, [Node -> BOOLEAN]) 88 | /\ vote_msg \in RandomSubset(15, SUBSET (Node \X Node)) 89 | /\ votes \in RandomSubset(15, SUBSET (Node \X Node)) 90 | /\ leader \in RandomSubset(5, [Node -> BOOLEAN]) 91 | /\ voting_quorum \in RandomSubset(5, Quorum) 92 | /\ decided \in RandomSubset(15, SUBSET (Node \X Value)) 93 | 94 | Safety == 95 | \A n1,n2 \in Node : \A v1,v2 \in Value : 96 | (<> \in decided /\ <> \in decided) => (v1=v2) 97 | 98 | NoLeader == ~\E i \in Node : leader[i] 99 | 100 | Symmetry == Permutations(Node) \cup Permutations(Value) 101 | 102 | NextUnchanged == UNCHANGED vars 103 | 104 | ==== -------------------------------------------------------------------------------- /benchmarks/client_server_db_ae.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE client_server_db_ae ---- 2 | \* benchmark: pyv-client-server-db-ae 3 | 4 | EXTENDS TLC, Randomization 5 | 6 | CONSTANT Node 7 | CONSTANT Request 8 | CONSTANT Response 9 | CONSTANT DbRequestId 10 | 11 | VARIABLE match 12 | 13 | VARIABLE request_sent 14 | VARIABLE response_sent 15 | VARIABLE response_received 16 | 17 | VARIABLE db_request_sent 18 | VARIABLE db_response_sent 19 | 20 | VARIABLE t 21 | 22 | vars == <> 23 | 24 | NoneWithId(i) == \A n \in Node : <> \notin t 25 | ResponseMatched(n,p) == \E r \in Request : (<> \in request_sent) /\ <> \in match 26 | 27 | 28 | NewRequest(n, r) == 29 | /\ request_sent' = request_sent \cup {<>} 30 | /\ UNCHANGED <> 31 | 32 | ServerProcessRequest(n,r,i) == 33 | /\ <> \in request_sent 34 | /\ NoneWithId(i) 35 | /\ t' = t \cup {<>} 36 | /\ db_request_sent' = db_request_sent \cup {<>} 37 | /\ UNCHANGED <> 38 | 39 | DbProcessRequest(i,r,p) == 40 | /\ <> \in db_request_sent 41 | /\ <> \in match 42 | /\ db_response_sent' = db_response_sent \cup {<>} 43 | /\ UNCHANGED <> 44 | 45 | ServerProcessDbResponse(n,i,p) == 46 | /\ <> \in db_response_sent 47 | /\ <> \in t 48 | /\ response_sent' = response_sent \cup {<>} 49 | /\ UNCHANGED <> 50 | 51 | ReceiveResponse(n,p) == 52 | /\ <> \in response_sent 53 | /\ response_received' = response_received \cup {<>} 54 | /\ UNCHANGED <> 55 | 56 | Next == 57 | \/ \E n \in Node, r \in Request : NewRequest(n,r) 58 | \/ \E n \in Node, r \in Request, i \in DbRequestId : ServerProcessRequest(n,r,i) 59 | \/ \E r \in Request, i \in DbRequestId, p \in Response : DbProcessRequest(i,r,p) 60 | \/ \E n \in Node, i \in DbRequestId, p \in Response : ServerProcessDbResponse(n,i,p) 61 | \/ \E n \in Node, p \in Response : ReceiveResponse(n,p) 62 | 63 | Init == 64 | /\ match \in SUBSET (Request \X Response) 65 | /\ request_sent = {} 66 | /\ response_sent = {} 67 | /\ response_received = {} 68 | /\ db_request_sent = {} 69 | /\ db_response_sent = {} 70 | /\ t = {} 71 | 72 | TypeOK == 73 | /\ match \in SUBSET (Request \X Response) 74 | /\ request_sent \in SUBSET (Node \X Request) 75 | /\ response_sent \in SUBSET (Node \X Response) 76 | /\ response_received \in SUBSET (Node \X Response) 77 | /\ db_request_sent \in SUBSET (DbRequestId \X Request) 78 | /\ db_response_sent \in SUBSET (DbRequestId \X Response) 79 | /\ t \in SUBSET (DbRequestId \X Node) 80 | 81 | TypeOKRandom == 82 | /\ match \in RandomSubset(20, SUBSET (Request \X Response)) 83 | /\ request_sent \in RandomSubset(10, SUBSET (Node \X Request)) 84 | /\ response_sent \in RandomSubset(10, SUBSET (Node \X Response)) 85 | /\ response_received \in RandomSubset(10, SUBSET (Node \X Response)) 86 | /\ db_request_sent \in RandomSubset(10, SUBSET (DbRequestId \X Request)) 87 | /\ db_response_sent \in RandomSetOfSubsets(10, 4, (DbRequestId \X Response)) 88 | /\ t \in RandomSetOfSubsets(10, 5, (DbRequestId \X Node)) 89 | 90 | Safety == \A n \in Node, p \in Response : (<> \in response_received) => ResponseMatched(n,p) 91 | 92 | Symmetry == Permutations(Node) \cup Permutations(Request) \cup Permutations(Response) \cup Permutations(DbRequestId) 93 | 94 | NextUnchanged == UNCHANGED vars 95 | 96 | Test == response_received = {} 97 | 98 | ==== -------------------------------------------------------------------------------- /benchmarks/simple_decentralized_lock_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE simple_decentralized_lock_IndProofs ---- 2 | EXTENDS simple_decentralized_lock, FiniteSetTheorems 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-03T00:08:27.264494 7 | \* is_inductive: True 8 | \* inv_size: 4 9 | \* invcheck_duration_secs: 6.678245782852173 10 | \* ctielimcheck_duration_secs: 17.967918634414673 11 | \* ctigen_duration_secs: 8.398974895477295 12 | \* total_duration_secs: 33.082804918289185 13 | \* total_num_ctis_eliminated: 2035 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 1674 16 | \* total_num_invs_checked: 8144 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv531_1_0_def == (has_lock = {}) \/ ((message = {})) 32 | Inv4437_2_1_def == \A VARS \in Node : \A VART \in Node : \A VARU \in Node : \A VARV \in Node : (VARS=VART /\ message=message) \/ (~(<> \in message) \/ (~(<> \in message))) 33 | Inv4494_2_2_def == \A VARS \in Node : \A VART \in Node : \A VARU \in Node : (VARS=VART /\ message=message) \/ (~(<> \in message) \/ (~(<> \in message))) 34 | 35 | \* The inductive invariant candidate. 36 | IndAuto == 37 | /\ TypeOK 38 | /\ Inv 39 | /\ Inv531_1_0_def 40 | /\ Inv4437_2_1_def 41 | /\ Inv4494_2_2_def 42 | 43 | ASSUME NodeFin == IsFiniteSet(Node) 44 | 45 | \* TLAPS Proof skeleton. 46 | THEOREM Init => IndAuto 47 | <1> SUFFICES ASSUME Init 48 | PROVE IndAuto 49 | OBVIOUS 50 | <1>1. TypeOK 51 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def 52 | <1>2. Inv 53 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def 54 | <1>3. Inv531_1_0_def 55 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def 56 | <1>4. Inv4437_2_1_def 57 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def 58 | <1>5. Inv4494_2_2_def 59 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def 60 | <1>6. QED 61 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 62 | 63 | THEOREM IndAuto /\ Next => IndAuto' 64 | <1> SUFFICES ASSUME IndAuto /\ Next 65 | PROVE IndAuto' 66 | OBVIOUS 67 | <1>1. TypeOK' 68 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 69 | <1>2. Inv' 70 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 71 | <1>3. Inv531_1_0_def' 72 | <2>1. CASE \E src,dst \in Node : Send(src,dst) 73 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 74 | <2>2. CASE \E src,dst \in Node : Recv(src,dst) 75 | BY NodeFin, <2>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 76 | <2>3. QED 77 | BY <2>1, <2>2 DEF Next 78 | 79 | <1>4. Inv4437_2_1_def' 80 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 81 | <1>5. Inv4494_2_2_def' 82 | <2>1. CASE \E src,dst \in Node : Send(src,dst) 83 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 84 | <2>2. CASE \E src,dst \in Node : Recv(src,dst) 85 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv531_1_0_def,Inv4437_2_1_def,Inv4494_2_2_def,Send,Recv 86 | <2>3. QED 87 | BY <2>1, <2>2 DEF Next 88 | 89 | <1>6. QED 90 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 91 | 92 | ==== 93 | -------------------------------------------------------------------------------- /benchmarks/client_server_ae_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE client_server_ae_IndProofs ---- 2 | EXTENDS client_server_ae, FiniteSetTheorems 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-07T13:13:29.901277 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 1.5558500289916992 10 | \* ctielimcheck_duration_secs: 4.081765174865723 11 | \* ctigen_duration_secs: 27.741323947906494 12 | \* total_duration_secs: 33.48468089103699 13 | \* total_num_ctis_eliminated: 10000 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 4 16 | \* total_num_invs_checked: 144 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 6 23 | \* seed: 13 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java 27 | \* java_version_info: openjdk version "15.0.3" 2021-04-20 OpenJDK Runtime Environment Zulu15.32+15-CA (build 15.0.3+3) OpenJDK 64-Bit Server VM Zulu15.32+15-CA (build 15.0.3+3, mixed mode) 28 | \* processor: arm 29 | \* cpu_count: 8 30 | 31 | \* Inductive strengthening conjuncts 32 | Inv93_1_0_def == \A VARI \in Node : \A VARP \in Response : (ResponseMatched(VARI,VARP)) \/ (~(<> \in response_sent)) 33 | 34 | \* The inductive invariant candidate. 35 | IndAuto == 36 | /\ TypeOK 37 | /\ Safety 38 | /\ Inv93_1_0_def 39 | 40 | ASSUME Fin == IsFiniteSet(Node) /\ IsFiniteSet(Request) /\ IsFiniteSet(Response) 41 | ASSUME Nonempty == Request # {} /\ Response # {} 42 | 43 | \* TLAPS Proof skeleton. 44 | THEOREM Init => IndAuto 45 | <1> SUFFICES ASSUME Init 46 | PROVE IndAuto 47 | OBVIOUS 48 | <1>1. TypeOK 49 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def 50 | <1>2. Safety 51 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def 52 | <1>3. Inv93_1_0_def 53 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def 54 | <1>4. QED 55 | BY <1>1, <1>2, <1>3 DEF IndAuto 56 | 57 | THEOREM IndAuto /\ Next => IndAuto' 58 | <1> SUFFICES ASSUME IndAuto, 59 | Next 60 | PROVE IndAuto' 61 | OBVIOUS 62 | <1>1. CASE \E n \in Node, r \in Request : NewRequest(n,r) 63 | <2>1. TypeOK' 64 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 65 | <2>2. Safety' 66 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 67 | <2>3. Inv93_1_0_def' 68 | BY <1>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 69 | <2>4. QED 70 | BY <2>1, <2>2, <2>3 DEF IndAuto 71 | 72 | <1>2. CASE \E n \in Node, r \in Request, p \in Response : Respond(n,r,p) 73 | <2>1. TypeOK' 74 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 75 | <2>2. Safety' 76 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 77 | <2>3. Inv93_1_0_def' 78 | BY <1>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 79 | <2>4. QED 80 | BY <2>1, <2>2, <2>3 DEF IndAuto 81 | 82 | <1>3. CASE \E n \in Node, p \in Response : ReceiveResponse(n,p) 83 | <2>1. TypeOK' 84 | BY <1>3 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 85 | <2>2. Safety' 86 | BY <1>3, Fin, Nonempty DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 87 | <2>3. Inv93_1_0_def' 88 | BY <1>3 DEF TypeOK,Init,Next,IndAuto,Safety,Inv93_1_0_def,ResponseMatched,NewRequest,Respond,ReceiveResponse 89 | <2>4. QED 90 | BY <2>1, <2>2, <2>3 DEF IndAuto 91 | 92 | <1>4. QED 93 | BY <1>1, <1>2, <1>3 DEF Next 94 | 95 | 96 | 97 | ==== 98 | -------------------------------------------------------------------------------- /benchmarks/toy_consensus_forall_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus_forall_IndProofs ---- 2 | EXTENDS toy_consensus_forall 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:38:14.322369 7 | \* is_inductive: True 8 | \* inv_size: 3 9 | \* invcheck_duration_secs: 1.1260368824005127 10 | \* ctielimcheck_duration_secs: 1.9848048686981201 11 | \* ctigen_duration_secs: 11.332494974136353 12 | \* total_duration_secs: 14.453804016113281 13 | \* total_num_ctis_eliminated: 412 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 18 16 | \* total_num_invs_checked: 220 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: False 22 | \* tlc_workers: 8 23 | \* seed: 12 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv150_1_0_def == \A s,t \in Node : \A Q \in Quorums : \A v \in Value : \E n \in Q : (voted[s]) \/ (~(vote[s] = v)) 32 | Inv65_1_1_def == \A s,t \in Node : \A Q \in Quorums : \A v \in Value : \E n \in Q : (vote[n] = v) \/ (~(v \in decided)) 33 | 34 | \* The inductive invariant candidate. 35 | IndAuto == 36 | /\ TypeOK 37 | /\ Inv 38 | /\ Inv150_1_0_def 39 | /\ Inv65_1_1_def 40 | 41 | ASSUME QuorumType == Quorums \subseteq SUBSET Node 42 | ASSUME NodeFinite == IsFiniteSet(Node) 43 | ASSUME QuorumsAreNonEmpty == \A Q \in Quorums : Q # {} 44 | ASSUME QuorumsIntersect == \A Q1,Q2 \in Quorums : Q1 \cap Q2 # {} 45 | ASSUME NilType == Nil \notin Value 46 | 47 | \* TLAPS Proof skeleton. 48 | THEOREM Init => IndAuto 49 | <1> SUFFICES ASSUME Init 50 | PROVE IndAuto 51 | OBVIOUS 52 | <1>1. TypeOK 53 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def 54 | <1>2. Inv 55 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def 56 | <1>3. Inv150_1_0_def 57 | BY QuorumType, NodeFinite, QuorumsAreNonEmpty, NilType DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def 58 | <1>4. Inv65_1_1_def 59 | BY QuorumType, NodeFinite, QuorumsAreNonEmpty, NilType DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def 60 | <1>5. QED 61 | BY <1>1, <1>2, <1>3, <1>4 DEF IndAuto 62 | 63 | THEOREM IndAuto /\ Next => IndAuto' 64 | <1> SUFFICES ASSUME IndAuto /\ Next 65 | PROVE IndAuto' 66 | OBVIOUS 67 | <1>1. TypeOK' 68 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 69 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, CastVote 70 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 71 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, Decide 72 | <2>3. QED 73 | BY <2>1, <2>2 DEF Next 74 | 75 | <1>2. Inv' 76 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 77 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, CastVote 78 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 79 | BY <2>2, QuorumType, NodeFinite, QuorumsAreNonEmpty, NilType DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, Decide 80 | <2>3. QED 81 | BY <2>1, <2>2 DEF Next 82 | 83 | <1>3. Inv150_1_0_def' 84 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 85 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, CastVote 86 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 87 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, Decide 88 | <2>3. QED 89 | BY <2>1, <2>2 DEF Next 90 | 91 | <1>4. Inv65_1_1_def' 92 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 93 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, CastVote 94 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 95 | BY <2>2, QuorumType, NodeFinite, QuorumsAreNonEmpty, NilType, QuorumsIntersect DEF TypeOK,Init,Next,IndAuto,Inv,Inv150_1_0_def,Inv65_1_1_def, Decide 96 | <2>3. QED 97 | BY <2>1, <2>2 DEF Next 98 | 99 | <1>5. QED 100 | BY <1>1, <1>2, <1>3, <1>4 DEF IndAuto 101 | 102 | ==== 103 | -------------------------------------------------------------------------------- /benchmarks/consensus_wo_decide.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE consensus_wo_decide ---- 2 | \* benchmark: pyv-consensus-wo-decide 3 | 4 | EXTENDS TLC, Randomization 5 | 6 | CONSTANT Node 7 | CONSTANT Quorums 8 | 9 | VARIABLE vote_request_msg 10 | VARIABLE voted 11 | VARIABLE vote_msg 12 | VARIABLE votes 13 | VARIABLE leader 14 | VARIABLE voting_quorum 15 | 16 | \* mutable relation vote_request_msg(node, node) 17 | \* mutable relation voted(node) 18 | \* mutable relation vote_msg(node, node) 19 | \* mutable relation votes(node, node) 20 | \* mutable relation leader(node) 21 | \* mutable constant voting_quorum: quorum 22 | 23 | 24 | \* transition send_request_vote(src: node, dst: node) 25 | \* transition send_vote(src: node, dst: node) 26 | \* transition recv_vote(n: node, sender: node) 27 | \* transition choose_voting_quorum(q, sn) 28 | \* transition become_leader(n: node) 29 | 30 | SendRequestVote(i,j) == 31 | /\ vote_request_msg' = [vote_request_msg EXCEPT ![<>] = TRUE] 32 | /\ UNCHANGED <> 33 | 34 | SendVote(src,dst)== 35 | /\ ~voted[src] 36 | /\ vote_request_msg[<>] 37 | /\ vote_msg' = [vote_msg EXCEPT ![<>] = TRUE] 38 | /\ voted' = [voted EXCEPT ![src] = TRUE] 39 | /\ UNCHANGED <> 40 | 41 | RecvVote(i,sender)== 42 | /\ vote_msg[<>] 43 | /\ votes' = [votes EXCEPT ![<>] = TRUE] 44 | /\ UNCHANGED <> 45 | 46 | ChooseVotingQuorum(i) == 47 | \E Q \in Quorums : 48 | /\ \A v \in Q : votes[<>] 49 | /\ voting_quorum' = Q 50 | /\ UNCHANGED <> 51 | 52 | BecomeLeader(i) == 53 | /\ voting_quorum # {} 54 | /\ \A v \in voting_quorum : votes[<>] 55 | /\ leader' = [leader EXCEPT ![i] = TRUE] 56 | /\ UNCHANGED <> 57 | 58 | Init == 59 | /\ vote_request_msg = [s \in Node \X Node |-> FALSE] 60 | /\ voted = [s \in Node |-> FALSE] 61 | /\ vote_msg = [s \in Node \X Node |-> FALSE] 62 | /\ votes = [s \in Node \X Node |-> FALSE] 63 | /\ leader = [s \in Node |-> FALSE] 64 | /\ voting_quorum \in Quorums 65 | 66 | Next == 67 | \/ \E i,j \in Node : SendRequestVote(i,j) 68 | \/ \E i,j \in Node : SendVote(i,j) 69 | \/ \E i,j \in Node : RecvVote(i,j) 70 | \/ \E i \in Node : ChooseVotingQuorum(i) 71 | \/ \E i \in Node : BecomeLeader(i) 72 | 73 | TypeOK == 74 | /\ vote_request_msg \in [Node \X Node -> BOOLEAN] 75 | /\ voted \in [Node -> BOOLEAN] 76 | /\ vote_msg \in [Node \X Node -> BOOLEAN] 77 | /\ votes \in [Node \X Node -> BOOLEAN] 78 | /\ leader \in [Node -> BOOLEAN] 79 | /\ voting_quorum \in Quorums 80 | 81 | TypeOKRandom == 82 | /\ vote_request_msg \in RandomSubset(25, [Node \X Node -> BOOLEAN]) 83 | /\ voted \in RandomSubset(6, [Node -> BOOLEAN]) 84 | /\ vote_msg \in RandomSubset(25, [Node \X Node -> BOOLEAN]) 85 | /\ votes \in RandomSubset(25, [Node \X Node -> BOOLEAN]) 86 | /\ leader \in RandomSubset(6, [Node -> BOOLEAN]) 87 | /\ voting_quorum \in RandomSubset(4, Quorums) 88 | 89 | Safety == \A i,j \in Node : (leader[i] /\ leader[j]) => (i = j) 90 | 91 | NoLeader == ~\E i \in Node : leader[i] 92 | 93 | Symmetry == Permutations(Node) 94 | 95 | NextUnchanged == UNCHANGED <> 96 | 97 | \* 98 | \* Inductive invariant definition. 99 | \* 100 | 101 | \* invariant votes(N, N1) -> vote_msg(N1, N) 102 | A1 == \A n,n1 \in Node : votes[<>] => vote_msg[<>] 103 | 104 | \* invariant vote_msg(N, N1) & vote_msg(N, N2) -> N1 = N2 105 | A2 == 106 | \A n,n1,n2 \in Node : 107 | vote_msg[<>] /\ vote_msg[<>] => n1=n2 108 | 109 | \* vote_msg(N, N1) -> voted(N) 110 | A3 == \A n,n1 \in Node : vote_msg[<>] => voted[n] 111 | 112 | \* invariant leader(N) & member(N1, voting_quorum) -> votes(N, N1) 113 | A4 == \A n,n1 \in Node: (leader[n] /\ n1 \in voting_quorum) => votes[<>] 114 | 115 | \* The human generated invariant. 116 | IndHuman == 117 | /\ Safety 118 | /\ A1 119 | /\ A2 120 | /\ A3 121 | /\ A4 122 | 123 | Ind == 124 | /\ Safety 125 | 126 | IInit == 127 | /\ TypeOKRandom 128 | /\ Ind 129 | 130 | ==== -------------------------------------------------------------------------------- /benchmarks/TCommit.tla: -------------------------------------------------------------------------------- 1 | ------------------------------- MODULE TCommit ------------------------------ 2 | \* benchmark: tla-tcommit 3 | EXTENDS TLC 4 | 5 | CONSTANT RM \* The set of participating resource managers 6 | VARIABLE rmState \* `rmState[rm]' is the state of resource manager rm. 7 | ----------------------------------------------------------------------------- 8 | TCTypeOK == 9 | (*************************************************************************) 10 | (* The type-correctness invariant *) 11 | (*************************************************************************) 12 | rmState \in [RM -> {"working", "prepared", "committed", "aborted"}] 13 | 14 | Init == rmState = [rm \in RM |-> "working"] 15 | (*************************************************************************) 16 | (* The initial predicate. *) 17 | (*************************************************************************) 18 | 19 | canCommit == \A rm \in RM : rmState[rm] \in {"prepared", "committed"} 20 | (*************************************************************************) 21 | (* True iff all RMs are in the "prepared" or "committed" state. *) 22 | (*************************************************************************) 23 | 24 | notCommitted == \A rm \in RM : rmState[rm] # "committed" 25 | (*************************************************************************) 26 | (* True iff neither no resource manager has decided to commit. *) 27 | (*************************************************************************) 28 | ----------------------------------------------------------------------------- 29 | (***************************************************************************) 30 | (* We now define the actions that may be performed by the RMs, and then *) 31 | (* define the complete next-state action of the specification to be the *) 32 | (* disjunction of the possible RM actions. *) 33 | (***************************************************************************) 34 | Prepare(rm) == /\ rmState[rm] = "working" 35 | /\ rmState' = [rmState EXCEPT ![rm] = "prepared"] 36 | 37 | Decide(rm) == \/ /\ rmState[rm] = "prepared" 38 | /\ canCommit 39 | /\ rmState' = [rmState EXCEPT ![rm] = "committed"] 40 | \/ /\ rmState[rm] \in {"working", "prepared"} 41 | /\ notCommitted 42 | /\ rmState' = [rmState EXCEPT ![rm] = "aborted"] 43 | 44 | Next == \E rm \in RM : Prepare(rm) \/ Decide(rm) 45 | (*************************************************************************) 46 | (* The next-state action. *) 47 | (*************************************************************************) 48 | ----------------------------------------------------------------------------- 49 | TCSpec == Init /\ [][Next]_rmState 50 | (*************************************************************************) 51 | (* The complete specification of the protocol. *) 52 | (*************************************************************************) 53 | ----------------------------------------------------------------------------- 54 | (***************************************************************************) 55 | (* We now assert invariance properties of the specification. *) 56 | (***************************************************************************) 57 | TCConsistent == 58 | (*************************************************************************) 59 | (* A state predicate asserting that two RMs have not arrived at *) 60 | (* conflicting decisions. *) 61 | (*************************************************************************) 62 | \A rm1, rm2 \in RM : ~ /\ rmState[rm1] = "aborted" 63 | /\ rmState[rm2] = "committed" 64 | 65 | THEOREM TCSpec => [](TCTypeOK /\ TCConsistent) 66 | (*************************************************************************) 67 | (* Asserts that TCTypeOK and TCConsistent are invariants of the protocol. *) 68 | (*************************************************************************) 69 | 70 | Symmetry == Permutations(RM) 71 | ============================================================================= 72 | -------------------------------------------------------------------------------- /benchmarks/Randomization.tla: -------------------------------------------------------------------------------- 1 | -------------------------- MODULE Randomization------------------------------ 2 | (***************************************************************************) 3 | (* This module defines operators for choosing pseudo-random subsets of a *) 4 | (* set. It is useful for inductive invariance checking, where the *) 5 | (* operators appear only in the initial predicate. However, it may have *) 6 | (* other uses. *) 7 | (* *) 8 | (* In breadth-first search model checking, the pseudo-random choices made *) 9 | (* when computing possible steps satisfying the next-state relation are *) 10 | (* determined by the first state of the step. Thus, the choices made for *) 11 | (* a particular state will be the same in successive runs of TLC. This is *) 12 | (* done to permit TLC to generate an error trace if an error is found. *) 13 | (* This applies only when TLC is run in breadth-first search mode. In *) 14 | (* particular, the choices made in simulation mode are independent of the *) 15 | (* state for which they are made. *) 16 | (***************************************************************************) 17 | 18 | (***************************************************************************) 19 | (* Except for TestRandomSetOfSubsets, all these definitions are overridden *) 20 | (* by TLC in the Java class tlc2.module.Randomization. Each operator is *) 21 | (* overridden by the Java method with the same name. *) 22 | (***************************************************************************) 23 | LOCAL INSTANCE Naturals 24 | LOCAL INSTANCE FiniteSets 25 | 26 | (***************************************************************************) 27 | (* RandomSubset(k, S) equals a randomly chosen subset of S containing k *) 28 | (* elements, where 0 < k < Cardinality(S). *) 29 | (***************************************************************************) 30 | RandomSubset(k, S) == CHOOSE T \in SUBSET S : Cardinality(T) = T 31 | 32 | (***************************************************************************) 33 | (* RandomSetOfSubsets(k, n, S) equals a pseudo-randomly chosen set of *) 34 | (* subsets of S -- that is, a randomly chosen subset of SUBSET S . Thus, *) 35 | (* each element T of this set is a subset of S. Each such T is chosen so *) 36 | (* that each element of S has a probability n / Cardinality(S) of being in *) 37 | (* T. Thus, the average number of elements in each chosen subset T is n. *) 38 | (* The set RandomSetOfSubsets(k, n, S) is obtained by making k such *) 39 | (* choices of T . Because this can produce duplicate choices, the number *) 40 | (* of elements T in this set may be less than k. The average number of *) 41 | (* elements in RandomSetOfSubsets(k, n, S) seems to be difficult to *) 42 | (* compute in general. However, there is very little variation in the *) 43 | (* actual number of elements in the chosen set for fixed values of k, n, *) 44 | (* and Cardinality(S). You can therefore use the operator *) 45 | (* TestRandomSetOfSubsets defined below to find out approximately how *) 46 | (* close to k the cardinality of the chosen set of subsets is. *) 47 | (***************************************************************************) 48 | RandomSetOfSubsets(k, n, S) == CHOOSE T \in SUBSET SUBSET S : 49 | Cardinality(T) \leq k 50 | 51 | (***************************************************************************) 52 | (* The value of TestRandomSetOfSubsets(k, n, S) is a sequence of five *) 53 | (* values that are the cardinality of the set of subsets produced by five *) 54 | (* executions of RandomSetOfSubsets(k, n, S). For constant values of k, *) 55 | (* n, and S, you can enter TestRandomSetOfSubsets(k, n, S) in the Evaluate *) 56 | (* Constant Expression section of a TLC model in the TLA+ Toolbox. *) 57 | (* Running TLC will then tell you the approximate number of elements in *) 58 | (* the set of subsets produced by RandomSetOfSubsets for these parameters. *) 59 | (* You can then choose k to obtain a set of the desired size. *) 60 | (***************************************************************************) 61 | TestRandomSetOfSubsets(k, n, S) == 62 | [i \in 1..5 |-> Cardinality(RandomSetOfSubsets(k, n, S))] 63 | 64 | ============================================================================= -------------------------------------------------------------------------------- /benchmarks/learning_switch_i4.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE learning_switch_i4 ---- 2 | \* benchmark: i4-learning-switch 3 | 4 | EXTENDS TLC, Randomization 5 | 6 | CONSTANT Packet 7 | CONSTANT Node 8 | 9 | VARIABLE pending 10 | VARIABLE src 11 | VARIABLE dst 12 | VARIABLE link 13 | 14 | VARIABLE route_dom 15 | VARIABLE route_tc 16 | 17 | vars == <> 18 | 19 | NewPacket(p) == 20 | /\ pending' = pending \cup {<>} 21 | /\ UNCHANGED <> 22 | 23 | Flood(p,sw0,sw1,sw2) == 24 | /\ <> \in pending 25 | /\ <> \notin route_dom 26 | /\ LET cond1 == (<> \notin route_dom) /\ (src[p] # sw1) 27 | cond2 == dst[p] # sw1 IN 28 | /\ route_dom' = IF cond1 THEN route_dom \cup {<>} ELSE route_dom 29 | /\ route_tc' = IF cond1 30 | THEN ((route_tc \ ({src[p]} \X Node \X Node)) \cup 31 | {<> \in ({src[p]} \X Node \X Node) : 32 | (\/ <> \in route_tc 33 | \/ (<> \in route_tc /\ <> \in route_tc))}) 34 | ELSE route_tc 35 | /\ pending' = IF cond2 36 | THEN ((pending \ ({p} \X {sw1} \X Node)) \cup 37 | {<> \in ({p} \X {sw1} \X Node) : link[sw1a]=y /\ y # sw0}) 38 | ELSE pending 39 | /\ UNCHANGED <> 40 | 41 | Route(p,sw0,sw1,sw2) == 42 | /\ <> \in pending 43 | /\ <> \in route_dom 44 | /\ <> \in route_tc 45 | /\ sw1 # sw2 46 | /\ \A z \in Node : (<> \in route_tc /\ sw1 # z) => (<> \in route_tc) 47 | /\ LET cond1 == (<> \notin route_dom) /\ (src[p] # sw1) 48 | cond2 == dst[p] # sw1 IN 49 | /\ route_dom' = IF cond1 THEN route_dom \cup {<>} ELSE route_dom 50 | /\ route_tc' = IF cond1 51 | THEN ((route_tc \ ({src[p]} \X Node \X Node)) \cup 52 | {<> \in ({src[p]} \X Node \X Node) : 53 | (\/ <> \in route_tc 54 | \/ (<> \in route_tc /\ <> \in route_tc))}) 55 | ELSE route_tc 56 | /\ pending' = IF cond2 THEN pending \cup {<>} ELSE pending 57 | /\ UNCHANGED <> 58 | 59 | Next == 60 | \/ \E p \in Packet : NewPacket(p) 61 | \/ \E p \in Packet, sw0,sw1,sw2 \in Node : Flood(p,sw0,sw1,sw2) 62 | \/ \E p \in Packet, sw0,sw1,sw2 \in Node : Route(p,sw0,sw1,sw2) 63 | 64 | Init == 65 | /\ route_dom = {} 66 | /\ route_tc = {<> \in Node \X Node \X Node : x = y} 67 | /\ pending = {} 68 | /\ src \in [Packet -> Node] 69 | /\ dst \in [Packet -> Node] 70 | /\ link \in [Node -> Node] 71 | \* No self-loops in links. 72 | /\ \A x \in Node : link[x] # x 73 | \* Symmetric links. 74 | /\ \A x,y \in Node : (link[x] = y) => (link[y] = x) 75 | 76 | \* invariant [1000000] 77 | \* route_tc(N, X, X) & 78 | \* (route_tc(N, X, Y) & route_tc(N, Y, Z) -> route_tc(N, X, Z)) & 79 | \* (route_tc(N, X, Y) & route_tc(N, Y, X) -> X = Y) & 80 | \* (route_tc(N, X, Y) & route_tc(N, X, Z) -> (route_tc(N, Y, Z) | route_tc(N, Z, Y))) 81 | Safety == 82 | \A n,x,y,z \in Node : 83 | /\ <> \in route_tc 84 | /\ (<> \in route_tc /\ <> \in route_tc) => <> \in route_tc 85 | /\ (<> \in route_tc /\ <> \in route_tc) => (x = y) 86 | /\ <> \in route_tc /\ <> \in route_tc => (<> \in route_tc \/ <> \in route_tc) 87 | 88 | TypeOK == 89 | /\ route_dom \in SUBSET (Node \X Node) 90 | /\ route_tc \in SUBSET (Node \X Node \X Node) 91 | /\ pending \in SUBSET (Packet \X Node \X Node) 92 | /\ src \in [Packet -> Node] 93 | /\ dst \in [Packet -> Node] 94 | /\ link \in [Node -> Node] 95 | 96 | TypeOKRandom == 97 | /\ route_dom \in RandomSetOfSubsets(35, 5, (Node \X Node)) 98 | /\ route_tc \in RandomSetOfSubsets(35, 5, {<> \in Node \X Node \X Node: y=z}) 99 | /\ pending \in RandomSetOfSubsets(35, 5, (Packet \X Node \X Node)) 100 | /\ src \in RandomSubset(20, [Packet -> Node]) 101 | /\ dst \in RandomSubset(20, [Packet -> Node]) 102 | /\ link \in RandomSubset(10, [Node -> Node]) 103 | 104 | Symmetry == Permutations(Node) \cup Permutations(Packet) 105 | 106 | NextUnchanged == UNCHANGED vars 107 | 108 | ==== -------------------------------------------------------------------------------- /benchmarks/lockserv_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserv_IndProofs ---- 2 | EXTENDS lockserv 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-02T23:33:26.222821 7 | \* is_inductive: True 8 | \* inv_size: 9 9 | \* invcheck_duration_secs: 6.777111530303955 10 | \* ctielimcheck_duration_secs: 13.321575403213501 11 | \* ctigen_duration_secs: 9.559056282043457 12 | \* total_duration_secs: 29.70569896697998 13 | \* total_num_ctis_eliminated: 3654 14 | \* total_num_cti_elimination_rounds: 2 15 | \* total_num_invs_generated: 410 16 | \* total_num_invs_checked: 1760 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv151_1_0_def == \A VARI \in Node : \A VARJ \in Node : ~(grant_msg[VARI]) \/ (~(unlock_msg[VARJ])) 32 | Inv162_1_1_def == \A VARI \in Node : ~(holds_lock[VARI]) \/ (~(server_holds_lock)) 33 | Inv146_1_2_def == \A VARI \in Node : \A VARJ \in Node : ~(grant_msg[VARI]) \/ (~(holds_lock[VARJ])) 34 | Inv164_1_3_def == \A VARI \in Node : \A VARJ \in Node : ~(holds_lock[VARI]) \/ (~(unlock_msg[VARJ])) 35 | Inv149_1_4_def == \A VARI \in Node : ~(grant_msg[VARI]) \/ (~(server_holds_lock)) 36 | Inv177_1_5_def == \A VARI \in Node : ~(server_holds_lock) \/ (~(unlock_msg[VARI])) 37 | Inv96_2_6_def == \A VARI \in Node : \A VARJ \in Node : (VARI=VARJ) \/ (~(grant_msg[VARJ])) \/ (~(grant_msg[VARI])) 38 | Inv128_2_0_def == \A VARI \in Node : \A VARJ \in Node : (VARI=VARJ) \/ (~(unlock_msg[VARI]) \/ (~(unlock_msg[VARJ]))) 39 | 40 | \* The inductive invariant candidate. 41 | IndAuto == 42 | /\ TypeOK 43 | /\ Mutex 44 | /\ Inv151_1_0_def 45 | /\ Inv162_1_1_def 46 | /\ Inv146_1_2_def 47 | /\ Inv164_1_3_def 48 | /\ Inv149_1_4_def 49 | /\ Inv177_1_5_def 50 | /\ Inv96_2_6_def 51 | /\ Inv128_2_0_def 52 | 53 | \* TLAPS Proof skeleton. 54 | THEOREM Init => IndAuto 55 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def 56 | 57 | THEOREM IndAuto /\ Next => IndAuto' 58 | <1> SUFFICES ASSUME IndAuto /\ Next 59 | PROVE IndAuto' 60 | OBVIOUS 61 | <1>1. TypeOK' 62 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 63 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 64 | <1>2. Mutex' 65 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 66 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 67 | <1>3. Inv151_1_0_def' 68 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 69 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 70 | <1>4. Inv162_1_1_def' 71 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 72 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 73 | <1>5. Inv146_1_2_def' 74 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 75 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 76 | <1>6. Inv164_1_3_def' 77 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 78 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 79 | <1>7. Inv149_1_4_def' 80 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 81 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 82 | <1>8. Inv177_1_5_def' 83 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 84 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 85 | <1>9. Inv96_2_6_def' 86 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 87 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 88 | <1>10. Inv128_2_0_def' 89 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv162_1_1_def,Inv146_1_2_def,Inv164_1_3_def,Inv149_1_4_def,Inv177_1_5_def,Inv96_2_6_def,Inv128_2_0_def, 90 | SendLock,RecvLock,RecvGrant,Unlock,RecvUnlock 91 | <1>11. QED 92 | BY <1>1, <1>10, <1>2, <1>3, <1>4, <1>5, <1>6, <1>7, <1>8, <1>9 DEF IndAuto 93 | 94 | 95 | ==== 96 | -------------------------------------------------------------------------------- /benchmarks/consensus_epr.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE consensus_epr ---- 2 | EXTENDS TLC, Naturals, FiniteSets, Sequences, Randomization 3 | 4 | CONSTANT 5 | \* @type: Set(Str); 6 | Node, 7 | \* @type: Set(Str); 8 | Quorum, 9 | \* @type: Set(Str); 10 | Value 11 | 12 | 13 | VARIABLE 14 | \* @type: Set(<>); 15 | vote_request_msg, 16 | \* @type: Str -> Str; 17 | voted, 18 | \* @type: Set(<>) 19 | vote_msg, 20 | \* @type: Str -> Set(Str) 21 | votes, 22 | \* @type: Str -> Bool 23 | leader, 24 | \* @type: Str -> Set(Str) 25 | decided 26 | 27 | vars == <> 28 | 29 | SendRequestVote(src, dst) == 30 | /\ vote_request_msg' = vote_request_msg \cup {<> } 31 | /\ UNCHANGED <> 32 | 33 | SendVote(src, dst) == 34 | /\ ~voted[src] 35 | /\ <> \in vote_request_msg 36 | /\ vote_msg' = vote_msg \cup {<>} 37 | /\ voted' = [voted EXCEPT ![src] = TRUE] 38 | /\ \/ vote_request_msg' = vote_request_msg \cup {<>} 39 | \/ vote_request_msg' = vote_request_msg \ {<>} 40 | /\ UNCHANGED <> 41 | 42 | RecvVote(n, sender) == 43 | /\ <> \in vote_msg 44 | /\ votes' = [votes EXCEPT ![n] = votes[n] \cup {sender}] 45 | /\ UNCHANGED <> 46 | 47 | BecomeLeader(n, Q) == 48 | /\ Q \subseteq votes[n] 49 | /\ leader' = [leader EXCEPT ![n] = TRUE] 50 | /\ UNCHANGED <> 51 | 52 | Decide(n, v) == 53 | /\ leader[n] 54 | /\ decided[n] = {} 55 | /\ decided' = [decided EXCEPT ![n] = decided[n] \cup {v}] 56 | /\ UNCHANGED <> 57 | 58 | Init == 59 | /\ vote_request_msg = {} 60 | /\ voted = [i \in Node |-> FALSE] 61 | /\ vote_msg = {} 62 | /\ votes = [i \in Node |-> {}] 63 | /\ leader = [i \in Node |-> FALSE] 64 | /\ decided = [i \in Node |-> {}] 65 | 66 | Next == 67 | \/ \E i,j \in Node : SendRequestVote(i,j) 68 | \/ \E i,j \in Node : SendVote(i,j) 69 | \/ \E i,j \in Node : RecvVote(i,j) 70 | \/ \E i \in Node, Q \in Quorum : BecomeLeader(i,Q) 71 | \/ \E i,j \in Node, v \in Value : Decide(i,v) 72 | 73 | Symmetry == Permutations(Node) \cup Permutations(Value) 74 | 75 | TypeOK == 76 | /\ vote_request_msg \in SUBSET(Node \X Node) 77 | /\ voted \in [Node -> BOOLEAN] 78 | /\ vote_msg \in SUBSET(Node \X Node) 79 | /\ votes \in [Node -> SUBSET Node] 80 | /\ leader \in [Node -> BOOLEAN] 81 | /\ decided \in [Node -> SUBSET Value] 82 | 83 | TypeOKRandom == 84 | /\ vote_request_msg \in RandomSubset(40, SUBSET (Node \X Node)) 85 | /\ voted \in RandomSubset(7, [Node -> BOOLEAN]) 86 | /\ vote_msg \in RandomSubset(40, SUBSET(Node \X Node)) 87 | /\ votes \in RandomSubset(10, [Node -> SUBSET Node]) 88 | /\ leader \in RandomSubset(4, [Node -> BOOLEAN]) 89 | /\ decided \in RandomSubset(10, [Node -> SUBSET Value]) 90 | 91 | \* TypeOKRandom == 92 | \* /\ vote_request_msg \in RandomSubset(80, SUBSET (Node \X Node)) 93 | \* /\ voted \in RandomSubset(7, [Node -> BOOLEAN]) 94 | \* /\ vote_msg \in RandomSubset(80, SUBSET(Node \X Node)) 95 | \* /\ votes \in RandomSubset(10, [Node -> SUBSET Node]) 96 | \* /\ leader \in RandomSubset(4, [Node -> BOOLEAN]) 97 | \* /\ decided \in RandomSubset(15, [Node -> SUBSET Value]) 98 | 99 | \* \A VARI \in Node : \A VARK \in Node : (<> \in vote_msg) \/ (~(VARI \in votes[VARK])) 100 | \* \A VARI \in Node : \A VALI \in Value : (leader[VARI]) \/ (~(VALI \in decided[VARI])) 101 | \* \A VARI \in Node : \A VARJ \in Node : (voted[VARI]) \/ (~(VARI \in votes[VARJ])) 102 | \* \A VARI \in Node : \A VARJ \in Node : \A VARK \in Node : (VARJ = VARK /\ votes = votes) \/ (~(<> \in vote_msg)) \/ (~(VARI \in votes[VARJ])) 103 | \* \E QJ \in Quorum : \A VARJ \in Node : \A VALI \in Value : ~(VALI \in decided[VARJ]) \/ (~(VARJ \in QJ /\ votes = votes)) 104 | \* \A VARI \in Node : \A VARJ \in Node : (<> \in vote_msg) \/ (~(<> \in vote_msg) \/ (~(leader[VARI]))) 105 | \* \A VARI \in Node : \A VARJ \in Node : \A VARK \in Node : (VARI = VARJ /\ votes = votes) \/ (~(VARK \in votes[VARJ])) \/ (~(VARK \in votes[VARI])) 106 | \* \E QJ \in Quorum : \A VARI \in Node : ~(VARI \in QJ /\ votes = votes) \/ (~(leader[VARI])) 107 | \* \A BBBVARI \in Node : \A BBBVARK \in Node : (<> \in vote_msg) \/ (~(BBBVARI \in votes[BBBVARK])) 108 | \* \E QJ \in Quorum : \A VARI \in Node : ~(VARI \in QJ /\ votes = votes) \/ (~(leader[VARI])) 109 | 110 | Safety == 111 | \A n1,n2 \in Node, v1,v2 \in Value : 112 | (v1 \in decided[n1] /\ v2 \in decided[n2]) => (v1 = v2) 113 | 114 | SafetyWithTypeOK == 115 | /\ TypeOK 116 | /\ \A n1,n2 \in Node, v1,v2 \in Value : 117 | (v1 \in decided[n1] /\ v2 \in decided[n2]) => (v1 = v2) 118 | 119 | 120 | NextUnchanged == UNCHANGED vars 121 | ==== -------------------------------------------------------------------------------- /benchmarks/two_phase_commit_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE two_phase_commit_IndProofs ---- 2 | EXTENDS two_phase_commit 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-03T00:16:17.205265 7 | \* is_inductive: True 8 | \* inv_size: 11 9 | \* invcheck_duration_secs: 10.691004276275635 10 | \* ctielimcheck_duration_secs: 27.401139974594116 11 | \* ctigen_duration_secs: 26.458534717559814 12 | \* total_duration_secs: 64.70636224746704 13 | \* total_num_ctis_eliminated: 10408 14 | \* total_num_cti_elimination_rounds: 3 15 | \* total_num_invs_generated: 3027 16 | \* total_num_invs_checked: 10901 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 11 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv703_1_0_def == (go_abort = {}) \/ ((go_commit = {})) 32 | Inv1049_1_1_def == \A VARJ \in Node : ~(VARJ \in vote_no) \/ (~(VARJ \in vote_yes)) 33 | Inv648_1_2_def == (decide_abort = {}) \/ ((go_commit = {})) 34 | Inv699_1_3_def == (decide_commit = {}) \/ (~(go_commit = {})) 35 | Inv346_1_4_def == \A VARJ \in Node : (VARJ \in alive) \/ ((abort_flag)) 36 | Inv313_1_5_def == \A VARI \in Node : (VARI \in vote_yes) \/ ((go_commit = {})) 37 | Inv588_1_0_def == (abort_flag) \/ ((go_abort = {})) 38 | Inv591_1_1_def == (abort_flag) \/ ((vote_no = {})) 39 | Inv2455_2_2_def == \A VARI \in Node : (VARI \in go_abort) \/ ((decide_abort = {})) \/ (~(vote_no = {})) 40 | Inv192_1_0_def == \A VARI \in Node : (VARI \in go_abort) \/ ((go_abort = {})) 41 | 42 | \* The inductive invariant candidate. 43 | IndAuto == 44 | /\ TypeOK 45 | /\ Safety 46 | /\ Inv703_1_0_def 47 | /\ Inv1049_1_1_def 48 | /\ Inv648_1_2_def 49 | /\ Inv699_1_3_def 50 | /\ Inv346_1_4_def 51 | /\ Inv313_1_5_def 52 | /\ Inv588_1_0_def 53 | /\ Inv591_1_1_def 54 | /\ Inv2455_2_2_def 55 | /\ Inv192_1_0_def 56 | 57 | \* TLAPS Proof skeleton. 58 | THEOREM Init => IndAuto 59 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 60 | 61 | THEOREM IndAuto /\ Next => IndAuto' 62 | <1> SUFFICES ASSUME IndAuto /\ Next 63 | PROVE IndAuto' 64 | OBVIOUS 65 | <1>1. TypeOK' 66 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 67 | <1>2. Safety' 68 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 69 | <1>3. Inv703_1_0_def' 70 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 71 | <1>4. Inv1049_1_1_def' 72 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 73 | <1>5. Inv648_1_2_def' 74 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 75 | <1>6. Inv699_1_3_def' 76 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 77 | <1>7. Inv346_1_4_def' 78 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 79 | <1>8. Inv313_1_5_def' 80 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 81 | <1>9. Inv588_1_0_def' 82 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 83 | <1>10. Inv591_1_1_def' 84 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 85 | <1>11. Inv2455_2_2_def' 86 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 87 | <1>12. Inv192_1_0_def' 88 | BY DEF Vote1,Vote2,Fail,Go1,Go2,Commit,Abort,TypeOK,Init,Next,IndAuto,Safety,Inv703_1_0_def,Inv1049_1_1_def,Inv648_1_2_def,Inv699_1_3_def,Inv346_1_4_def,Inv313_1_5_def,Inv588_1_0_def,Inv591_1_1_def,Inv2455_2_2_def,Inv192_1_0_def 89 | <1>13. QED 90 | BY <1>1, <1>10, <1>11, <1>12, <1>2, <1>3, <1>4, <1>5, <1>6, <1>7, <1>8, <1>9 DEF IndAuto 91 | 92 | ==== 93 | 94 | -------------------------------------------------------------------------------- /benchmarks/toy_consensus_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus_IndProofs ---- 2 | EXTENDS toy_consensus 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-05T19:37:07.783974 7 | \* is_inductive: True 8 | \* inv_size: 2 9 | \* invcheck_duration_secs: 1.1238219738006592 10 | \* ctielimcheck_duration_secs: 1.4977319240570068 11 | \* ctigen_duration_secs: 3.98393177986145 12 | \* total_duration_secs: 6.611572027206421 13 | \* total_num_ctis_eliminated: 14 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 8 16 | \* total_num_invs_checked: 112 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: False 22 | \* tlc_workers: 8 23 | \* seed: 12 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv78_1_0_def == \A VARI \in Node : \A VARJ \in Node : \A VARV \in Value : \A VARQ \in Quorums : \E VART \in VARQ :(vote[VART] = VARV) \/ (~(VARV \in decision)) 32 | 33 | \* The inductive invariant candidate. 34 | IndAuto == 35 | /\ TypeOK 36 | /\ Inv 37 | /\ Inv78_1_0_def 38 | 39 | ASSUME QuorumType == Quorums \subseteq SUBSET Node 40 | ASSUME NodeFinite == IsFiniteSet(Node) 41 | ASSUME QuorumsAreNonEmpty == \A Q \in Quorums : Q # {} 42 | ASSUME QuorumsExist == Quorums # {} 43 | ASSUME ValueNonEmpty == Value # {} 44 | ASSUME NodeNonEmpty == Node # {} 45 | ASSUME QuorumsIntersect == \A Q1,Q2 \in Quorums : Q1 \cap Q2 # {} 46 | ASSUME NilType == Nil \notin Node /\ Nil \notin Value 47 | 48 | 49 | \* TLAPS Proof skeleton. 50 | THEOREM Init => IndAuto 51 | <1> SUFFICES ASSUME Init 52 | PROVE IndAuto 53 | OBVIOUS 54 | <1>1. TypeOK 55 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv78_1_0_def 56 | <1>2. Inv 57 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv78_1_0_def 58 | <1>3. Inv78_1_0_def 59 | BY QuorumType, QuorumsAreNonEmpty DEF TypeOK,Init,Next,IndAuto,Inv,Inv78_1_0_def 60 | <1>4. QED 61 | BY <1>1, <1>2, <1>3 DEF IndAuto 62 | 63 | THEOREM IndAuto /\ Next => IndAuto' 64 | <1> SUFFICES ASSUME IndAuto, Next 65 | PROVE IndAuto' 66 | OBVIOUS 67 | <1>1. TypeOK' 68 | BY DEF TypeOK,Init,Next,IndAuto,Inv,Inv78_1_0_def,CastVote,Decide 69 | 70 | \* Inv == \A vi, vj \in decision : vi = vj 71 | <1>2. Inv' 72 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 73 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Inv,Inv78_1_0_def,CastVote,Decide 74 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 75 | <3>1. PICK v \in Value, Q \in Quorums : Decide(v, Q) BY <2>2 76 | <3>2. SUFFICES ASSUME NEW vi \in decision', 77 | NEW vj \in decision', 78 | vi # vj 79 | PROVE FALSE BY DEF Inv 80 | <3>3. vi \in decision \/ vj \in decision BY <3>1, <3>2 DEF Decide, IndAuto, TypeOK 81 | <3>4. CASE vi \in decision 82 | <4>1. vj = v BY <3>1, <3>2, <3>4 DEF Decide, IndAuto, TypeOK, Inv 83 | <4>2. ChosenAt(vj, Q) BY <3>1, <4>1 DEF Decide 84 | <4>3. PICK t \in Q : vote[t] = vi 85 | BY <3>4, NodeNonEmpty, ValueNonEmpty, QuorumsExist DEF IndAuto, Inv78_1_0_def, TypeOK 86 | <4>4. vote[t] = vj BY <4>2 DEF ChosenAt 87 | <4>. QED BY <3>2, <4>3, <4>4 DEF IndAuto, TypeOK 88 | <3>5. CASE vj \in decision 89 | <4>1. vi = v BY <3>1, <3>2, <3>4 DEF Decide, IndAuto, TypeOK, Inv 90 | <4>2. ChosenAt(vi, Q) BY <3>1, <4>1 DEF Decide 91 | <4>3. PICK t \in Q : vote[t] = vj 92 | BY <3>5, NodeNonEmpty, ValueNonEmpty, QuorumsExist DEF IndAuto, Inv78_1_0_def, TypeOK 93 | <4>4. vote[t] = vi BY <4>2 DEF ChosenAt 94 | <4>. QED BY <3>2, <4>3, <4>4 DEF IndAuto, TypeOK 95 | <3>. QED BY <3>3, <3>4, <3>5 96 | <2>3. QED 97 | BY <2>1, <2>2 DEF Next 98 | 99 | <1>3. Inv78_1_0_def' 100 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 101 | <3>1. PICK i \in Node, v \in Value : CastVote(i, v) BY <2>1 102 | <3>2. vote[i] # v BY <3>1, NilType DEF CastVote 103 | <3>3. SUFFICES ASSUME NEW Q \in Quorums', 104 | NEW val \in Value, 105 | \A t \in Q : (vote'[t] # val) /\ (val \in decision') 106 | PROVE FALSE 107 | BY NodeNonEmpty, ValueNonEmpty DEF Inv78_1_0_def 108 | <3>4. Q \in Quorums BY <3>1, <3>3 DEF CastVote 109 | <3>5. CASE val # v 110 | <4>1. \A t \in Q : (vote[t] # val) /\ (val \in decision) 111 | BY <3>1, <3>3, <3>5, NilType, QuorumType DEF CastVote, IndAuto, TypeOK 112 | <4>2. ~Inv78_1_0_def BY <3>3, <3>4, <4>1 DEF Inv78_1_0_def 113 | <4>. QED BY <4>2 DEF IndAuto 114 | <3>6. CASE val = v 115 | <4>1. i \notin Q BY <3>1, <3>3, <3>6 DEF CastVote, IndAuto, TypeOK 116 | <4>2. \A t \in Q : (vote[t] # val) /\ (val \in decision) 117 | BY <3>1, <3>3, <3>6, <4>1, NilType, QuorumType DEF CastVote, IndAuto, TypeOK 118 | <4>3. ~Inv78_1_0_def BY <3>3, <3>4, <4>2 DEF Inv78_1_0_def 119 | <4>. QED BY <4>3 DEF IndAuto 120 | <3>. QED BY <3>5, <3>6 121 | <2>2. CASE \E v \in Value, Q \in Quorums : Decide(v, Q) 122 | <3>1. PICK v \in Value, Q \in Quorums : Decide(v, Q) BY <2>2 123 | <3>2. \A m \in Q : vote[m] = v BY <3>1 DEF Decide, ChosenAt 124 | <3>3. \A Qt \in Quorums : \E t \in Qt : vote[t] = v BY <3>2, QuorumsIntersect 125 | <3>4. SUFFICES ASSUME NEW Qt \in Quorums', 126 | NEW val \in Value 127 | PROVE \E t \in Qt : (vote'[t] = val) \/ (val \notin decision') 128 | BY NodeNonEmpty, ValueNonEmpty DEF Inv78_1_0_def 129 | <3>5. \E t \in Qt : vote[t] = v BY <3>3, <3>4 130 | <3>6. CASE v = val BY <3>1, <3>4, <3>5, <3>6 DEF Decide 131 | <3>7. CASE v # val 132 | <4>1. CASE val \notin decision BY <3>1, <3>5, <3>7, <4>1 DEF Decide 133 | <4>2. CASE val \in decision 134 | <5>1. \E t \in Q : vote[t] = val 135 | BY <3>7, <4>2, NodeNonEmpty, ValueNonEmpty DEF IndAuto, Inv78_1_0_def 136 | <5>. QED BY <3>2, <3>7, <5>1 137 | <4>. QED BY <4>1, <4>2 138 | <3>. QED BY <3>6, <3>7 139 | <2>3. QED 140 | BY <2>1, <2>2 DEF Next 141 | 142 | <1>4. QED 143 | BY <1>1, <1>2, <1>3 DEF IndAuto 144 | 145 | ==== 146 | -------------------------------------------------------------------------------- /benchmarks/lockserv_automaton_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE lockserv_automaton_IndProofs ---- 2 | EXTENDS lockserv_automaton 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-01T20:40:44.948594 7 | \* is_inductive: True 8 | \* inv_size: 9 9 | \* invcheck_duration_secs: 3.6202454566955566 10 | \* ctielimcheck_duration_secs: 8.511093854904175 11 | \* ctigen_duration_secs: 6.537862062454224 12 | \* total_duration_secs: 18.69947385787964 13 | \* total_num_ctis_eliminated: 3624 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 262 16 | \* total_num_invs_checked: 1140 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 10 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv151_1_0_def == \A VARI \in Node : \A VARJ \in Node : ~(grant_msg[VARI]) \/ (~(unlock_msg[VARJ])) 32 | Inv60_1_1_def == \A VARI \in Node : (held) \/ (~(holds_lock[VARI])) 33 | Inv147_1_2_def == \A VARI \in Node : \A VARJ \in Node : ~(grant_msg[VARI]) \/ (~(holds_lock[VARJ])) 34 | Inv169_1_3_def == \A VARI \in Node : \A VARJ \in Node : ~(holds_lock[VARI]) \/ (~(unlock_msg[VARJ])) 35 | Inv58_1_4_def == \A VARI \in Node : (held) \/ (~(grant_msg[VARI])) 36 | Inv64_1_5_def == \A VARI \in Node : (held) \/ (~(unlock_msg[VARI])) 37 | Inv96_2_6_def == \A VARI \in Node : \A VARJ \in Node : (VARI=VARJ) \/ (~(grant_msg[VARJ])) \/ (~(grant_msg[VARI])) 38 | Inv134_2_7_def == \A VARI \in Node : \A VARJ \in Node : (VARI=VARJ) \/ (~(unlock_msg[VARI]) \/ (~(unlock_msg[VARJ]))) 39 | 40 | \* The inductive invariant candidate. 41 | IndAuto == 42 | /\ TypeOK 43 | /\ Mutex 44 | /\ Inv151_1_0_def 45 | /\ Inv60_1_1_def 46 | /\ Inv147_1_2_def 47 | /\ Inv169_1_3_def 48 | /\ Inv58_1_4_def 49 | /\ Inv64_1_5_def 50 | /\ Inv96_2_6_def 51 | /\ Inv134_2_7_def 52 | 53 | \* TLAPS Proof skeleton. 54 | THEOREM Init => IndAuto 55 | <1> SUFFICES ASSUME Init 56 | PROVE IndAuto 57 | OBVIOUS 58 | <1>1. TypeOK 59 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 60 | <1>2. Mutex 61 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 62 | <1>3. Inv151_1_0_def 63 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 64 | <1>4. Inv60_1_1_def 65 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 66 | <1>5. Inv147_1_2_def 67 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 68 | <1>6. Inv169_1_3_def 69 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 70 | <1>7. Inv58_1_4_def 71 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 72 | <1>8. Inv64_1_5_def 73 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 74 | <1>9. Inv96_2_6_def 75 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 76 | <1>10. Inv134_2_7_def 77 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def 78 | <1>11. QED 79 | BY <1>1, <1>10, <1>2, <1>3, <1>4, <1>5, <1>6, <1>7, <1>8, <1>9 DEF IndAuto 80 | 81 | THEOREM IndAuto /\ Next => IndAuto' 82 | <1> SUFFICES ASSUME IndAuto /\ Next 83 | PROVE IndAuto' 84 | OBVIOUS 85 | <1>1. TypeOK' 86 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 87 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 88 | <1>2. Mutex' 89 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 90 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 91 | <1>3. Inv151_1_0_def' 92 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 93 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 94 | <1>4. Inv60_1_1_def' 95 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 96 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 97 | <1>5. Inv147_1_2_def' 98 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 99 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 100 | <1>6. Inv169_1_3_def' 101 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 102 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 103 | <1>7. Inv58_1_4_def' 104 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 105 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 106 | <1>8. Inv64_1_5_def' 107 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 108 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 109 | <1>9. Inv96_2_6_def' 110 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 111 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 112 | <1>10. Inv134_2_7_def' 113 | BY DEF TypeOK,Init,Next,IndAuto,Mutex,Inv151_1_0_def,Inv60_1_1_def,Inv147_1_2_def,Inv169_1_3_def,Inv58_1_4_def,Inv64_1_5_def,Inv96_2_6_def,Inv134_2_7_def, 114 | Lock,Unlock,RecvLock,RecvGrant,RecvUnlock 115 | <1>11. QED 116 | BY <1>1, <1>10, <1>2, <1>3, <1>4, <1>5, <1>6, <1>7, <1>8, <1>9 DEF IndAuto 117 | 118 | 119 | ==== 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # endive 2 | 3 | endive is a tool for automatically inferring inductive invariants of protocols specified in TLA+. It was primarily developed for targeting safety verification of distributed protocols, but works for any TLA+ specifications accepted by TLC. Correctness of discovered invariants are formally verified using the [TLA+ proof system](https://tla.msr-inria.inria.fr/tlaps/content/Home.html) (TLAPS). 4 | 5 | For more details see the [FMCAD 2022](https://fmcad.org/FMCAD22/accepted/) paper, *[Plain and Simple Inductive Invariant Inference for Distributed Protocols in TLA+](https://arxiv.org/abs/2205.06360)*, which presents the design and ideas behind endive. 6 | 7 | ## Setup 8 | 9 | In order to run the tool you will need the following prerequisites: 10 | 11 | - Java version >= 11 12 | - Python 3 with pip installed 13 | - Install Python dependencies with `python3 -m pip install -r requirements.txt` 14 | 15 | Note that the endive tool makes use of a slightly modified version of the TLC model checker, whose source code can be found [here](https://github.com/will62794/tlaplus/tree/ce9e63ab5242a596b8dec15000b5ed5f97f63300). The binary of this modified version of TLC is included in this repo, so there is no need to download and build it manually. 16 | 17 | ## Example Usage 18 | 19 | As a demonstration of using endive, you can run it on the [TwoPhase](benchmarks/TwoPhase.tla) benchmark, a TLA+ specification of the two-phase commit protocol. This will attempt to generate an inductive invariant for proving the [`TCConsistent`](https://github.com/will62794/endive/blob/master/benchmarks/TwoPhase.tla#L163-L168) safety property: 20 | 21 | ```bash 22 | python3 endive.py --spec benchmarks/TwoPhase --seed 20 --ninvs 15000 --niters 3 --nrounds 4 --num_simulate_traces 50000 --simulate_depth 6 --tlc_workers 6 23 | ``` 24 | 25 | When this run terminates, you should see output like the following, showing a candidate inductive invariant along with some other statistics about the run: 26 | ``` 27 | \* The inductive invariant candidate. 28 | IndAuto == 29 | /\ TCConsistent 30 | /\ Inv276_1_0_def 31 | /\ Inv45_1_1_def 32 | /\ Inv79_1_2_def 33 | /\ Inv349_1_3_def 34 | /\ Inv318_1_4_def 35 | /\ Inv331_1_5_def 36 | /\ Inv334_1_6_def 37 | /\ Inv386_1_7_def 38 | /\ Inv1896_2_8_def 39 | /\ Inv344_1_0_def 40 | ---------------------------------------- 41 | Initial random seed: 20 42 | opt_quant_minimize: 0 43 | Total number of CTIs eliminated: 10001 44 | Total number of invariants generated: 1124 45 | Total number of invariants checked: 4033 46 | CTI generation duration: 20.689125 secs. 47 | Invariant checking duration: 13.481307 secs. 48 | CTI elimination checks duration: 48.955196 secs. 49 | Total duration: 83.30 secs. 50 | ``` 51 | 52 | This generated inductive invariant is not necessarily a true inductive invariant, but one that endive reports as likely to be correct, based on probabilistic counterexample sampling. 53 | 54 | In order to formally verify the correctness of this invariant, you will need to use TLAPS. You can see an example of a proof for an inductive invariant discovered by endive for the `TwoPhase` protocol benchmark [here](benchmarks/TwoPhase_IndProofs.tla). 55 | 56 | ## Command line options 57 | 58 | ``` 59 | python3 endive.py --spec benchmarks/ [options] 60 | ``` 61 | 62 | Detailed command line options: 63 | ``` 64 | $ python3 endive.py -h 65 | usage: endive.py [-h] --spec SPEC [--ninvs NINVS] [--niters NITERS] [--nrounds NROUNDS] [--seed SEED] [--num_simulate_traces NUM_SIMULATE_TRACES] [--simulate_depth SIMULATE_DEPTH] 66 | [--tlc_workers TLC_WORKERS] [--java_exe JAVA_EXE] [--debug] [--cache_invs CACHE_INVS] [--cache_num_conjuncts CACHE_NUM_CONJUNCTS] [--load_inv_cache LOAD_INV_CACHE] 67 | [--log_file LOG_FILE] [--save_result] [--opt_quant_minimize] [--try_final_minimize] [--results_dir RESULTS_DIR] 68 | 69 | optional arguments: 70 | -h, --help show this help message and exit 71 | --spec SPEC Name of the protocol benchmark to run (given as 'benchmarks/'). 72 | --ninvs NINVS Maximum number of invariants to generate at each iteration. 73 | --niters NITERS Maximum number of invariant generation iterations to run in each CTI elimination round. 74 | --nrounds NROUNDS Maximum number of CTI elimination rounds to run. 75 | --seed SEED Seed for RNG. 76 | --num_simulate_traces NUM_SIMULATE_TRACES 77 | The maximum number of traces TLC will run when searching for counterexamples to inductions (CTIs). 78 | --simulate_depth SIMULATE_DEPTH 79 | Maximum depth of counterexample to induction (CTI) traces to search for. 80 | --tlc_workers TLC_WORKERS 81 | Number of TLC worker threads to use when checking candidate invariants. 82 | --java_exe JAVA_EXE Path to Java binary. 83 | --debug Output debug info to log. 84 | --cache_invs CACHE_INVS 85 | Save generated invariants to the given file. 86 | --cache_num_conjuncts CACHE_NUM_CONJUNCTS 87 | Number of conjuncts in generated invariants to be cached. 88 | --load_inv_cache LOAD_INV_CACHE 89 | Load pre-generated invariants from a file. 90 | --log_file LOG_FILE Log output file. 91 | --save_result Whether to save result statistics to a file 92 | --opt_quant_minimize Enable quantifier minimization optimization for faster invariant checking. 93 | --try_final_minimize Attempt to minimize the final discovered invariant. 94 | --results_dir RESULTS_DIR 95 | Directory to save results. 96 | ``` 97 | 98 | ## Creating a new benchmark 99 | 100 | To create a new benchmark, you will need to define two files inside the `benchmarks` directory: 101 | 102 | - `.tla`: a TLA+ specification of your protocol, with initial state and next state relation defined as `Init` and `Next`, respectively. 103 | - `.config.json`: A configuration file for running endive on your specification. 104 | 105 | The configuration file is a JSON file with the following required, top-level fields: 106 | 107 | - `preds`: a list of atomic TLA+ state predicates that define the grammar over which to search for candidate invariants to be used as conjuncts of an overall inductive invariant. 108 | - `safety`: a string giving the TLA+ definition of the safety property to be verified. 109 | - `constants`: a list of TLC configuration constant instantiations used for model checking the specification. 110 | - `quant_inv`: a quantifier template that will be prepended to the candidate invariants generated from the atomic predicates given in `preds` 111 | - `model_consts`: string giving a list of CONSTANT model values that are instantiated. 112 | - `typeok`: definition of the TLA+ type invariant predicate to use during invariant inference (e.g. `TypeOK`). 113 | 114 | Typically the easiest way to create a new benchmark configuration is to start from an example such as [`TwoPhase.config.json`](benchmarks/TwoPhase.config.json) (with corresponding TLA+ spec, [`TwoPhase.tla`](benchmarks/TwoPhase.tla)) and modify it as needed. -------------------------------------------------------------------------------- /benchmarks/naive_consensus_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE naive_consensus_IndProofs ---- 2 | EXTENDS naive_consensus 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-05T19:32:12.415475 7 | \* is_inductive: True 8 | \* inv_size: 4 9 | \* invcheck_duration_secs: 5.137019872665405 10 | \* ctielimcheck_duration_secs: 15.13862681388855 11 | \* ctigen_duration_secs: 11.058095932006836 12 | \* total_duration_secs: 31.39272975921631 13 | \* total_num_ctis_eliminated: 10000 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 141 16 | \* total_num_invs_checked: 3259 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 13 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv255_1_0_def == \A VARA \in Value : (VotedFor(VARA)) \/ (~(VARA \in decision)) 32 | Inv1230_2_1_def == \A VARS \in Node : \A VARA \in Value : \A VARQ \in Quorum : (<> \in vote) \/ (~(<> \in decide) \/ (~(VARS \in VARQ /\ vote = vote))) 33 | Inv217_2_2_def == \A VARS \in Node : \A VARA \in Value : \A VARB \in Value : ((VARA=VARB) /\ vote = vote) \/ (~(<> \in vote) \/ (~(<> \in vote))) 34 | 35 | \* The inductive invariant candidate. 36 | IndAuto == 37 | /\ TypeOK 38 | /\ Safety 39 | /\ Inv255_1_0_def 40 | /\ Inv1230_2_1_def 41 | /\ Inv217_2_2_def 42 | 43 | 44 | AXIOM QuorumsAreNodePowersets == Quorum \subseteq SUBSET Node 45 | AXIOM QuorumsOverlap == \A Q1,Q2 \in Quorum : Q1 \cap Q2 # {} 46 | AXIOM Nonempty == Node # {} /\ Quorum # {} /\ Value # {} 47 | 48 | 49 | \* TLAPS Proof skeleton. 50 | THEOREM Init => IndAuto 51 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv255_1_0_def,Inv1230_2_1_def,Inv217_2_2_def 52 | 53 | THEOREM IndAuto /\ Next => IndAuto' 54 | <1>. SUFFICES ASSUME IndAuto, Next 55 | PROVE IndAuto' OBVIOUS 56 | <1>1. TypeOK' 57 | <2>1. CASE \E n \in Node, v \in Value : CastVote(n,v) BY <2>1 DEF CastVote, IndAuto, TypeOK 58 | <2>2. CASE \E Q \in Quorum, v \in Value : CollectVotes(Q,v) BY <2>2 DEF CollectVotes, IndAuto, TypeOK 59 | <2>3. CASE \E Q \in Quorum, v \in Value : LearnValue(Q,v) BY <2>3 DEF LearnValue, IndAuto, TypeOK 60 | <2>. QED BY <2>1, <2>2, <2>3 DEF Next 61 | <1>2. Safety' 62 | <2>1. CASE \E n \in Node, v \in Value : CastVote(n,v) BY <2>1 DEF CastVote, IndAuto, TypeOK, Safety 63 | <2>2. CASE \E Q \in Quorum, v \in Value : CollectVotes(Q,v) BY <2>2 DEF CollectVotes, IndAuto, TypeOK, Safety 64 | <2>3. CASE \E Q \in Quorum, v \in Value : LearnValue(Q,v) 65 | <3>1. PICK Q \in Quorum, v \in Value : LearnValue(Q,v) BY <2>3 66 | <3>2. <> \in decide BY <3>1 DEF LearnValue 67 | <3>3. \A t \in Q : <> \in vote BY <3>1, <3>2, QuorumsAreNodePowersets DEF IndAuto, TypeOK, Inv1230_2_1_def 68 | <3>4. SUFFICES ASSUME NEW v1 \in Value, 69 | NEW v2 \in Value, 70 | v1 \in decision', 71 | v2 \in decision', 72 | v1 # v2 73 | PROVE FALSE BY DEF Safety 74 | <3>5. v1 \notin decision \/ v2 \notin decision BY <3>1, <3>4 DEF IndAuto, Safety 75 | <3>6. CASE v1 \notin decision 76 | <4>1. v = v1 BY <3>1, <3>2, <3>4, <3>6 DEF LearnValue 77 | <4>2. v2 \in decision BY <3>1, <3>4, <3>6 DEF LearnValue 78 | \* Inv255_1_0_def == \A s,t \in Node : \A va,vb \in Value : \A Qa \in Quorum : ~(va \in decision) \/ ((VotedFor(va)) /\ (TRUE)) 79 | <4>3. \A s,t \in Node, vb \in Value, Qa \in Quorum : \E Q2 \in Quorum : <> \in decide 80 | BY <4>2 DEF IndAuto, Inv255_1_0_def, VotedFor 81 | <4>4. PICK Q2 \in Quorum : <> \in decide BY <4>3, Nonempty 82 | <4>5. PICK n \in Node : n \in Q /\ n \in Q2 BY <3>1, <4>4, QuorumsOverlap, QuorumsAreNodePowersets 83 | <4>6. <> \in vote BY <4>4, <4>5 DEF IndAuto, TypeOK, Inv1230_2_1_def 84 | <4>7. <> \in vote BY <3>3, <4>1, <4>5 85 | <4>. QED BY <3>4, <4>6, <4>7 DEF IndAuto, Inv217_2_2_def 86 | <3>7. CASE v2 \notin decision 87 | <4>1. v = v2 BY <3>1, <3>2, <3>4, <3>7 DEF LearnValue 88 | <4>2. v1 \in decision BY <3>1, <3>4, <3>7 DEF LearnValue 89 | \* Inv255_1_0_def == \A s,t \in Node : \A va,vb \in Value : \A Qa \in Quorum : ~(va \in decision) \/ ((VotedFor(va)) /\ (TRUE)) 90 | <4>3. \A s,t \in Node, vb \in Value, Qa \in Quorum : \E Q2 \in Quorum : <> \in decide 91 | BY <4>2 DEF IndAuto, Inv255_1_0_def, VotedFor 92 | <4>4. PICK Q2 \in Quorum : <> \in decide BY <4>3, Nonempty 93 | <4>5. PICK n \in Node : n \in Q /\ n \in Q2 BY <3>1, <4>4, QuorumsOverlap, QuorumsAreNodePowersets 94 | <4>6. <> \in vote BY <4>4, <4>5 DEF IndAuto, TypeOK, Inv1230_2_1_def 95 | <4>7. <> \in vote BY <3>3, <4>1, <4>5 96 | <4>. QED BY <3>4, <4>6, <4>7 DEF IndAuto, Inv217_2_2_def 97 | <3>. QED BY <3>5, <3>6, <3>7 98 | <2>. QED BY <2>1, <2>2, <2>3 DEF Next 99 | 100 | <1>3. Inv255_1_0_def' 101 | <2>1. CASE \E n \in Node, v \in Value : CastVote(n,v) 102 | BY <2>1 DEF CastVote, IndAuto, TypeOK, Safety, Inv255_1_0_def, Inv1230_2_1_def, Inv217_2_2_def, VotedFor 103 | <2>2. CASE \E Q \in Quorum, v \in Value : CollectVotes(Q,v) 104 | BY <2>2 DEF CollectVotes, IndAuto, TypeOK, Safety, Inv255_1_0_def, Inv1230_2_1_def, Inv217_2_2_def, VotedFor 105 | <2>3. CASE \E Q \in Quorum, v \in Value : LearnValue(Q,v) 106 | BY <2>3 DEF LearnValue, IndAuto, TypeOK, Safety, Inv255_1_0_def, Inv1230_2_1_def, Inv217_2_2_def, VotedFor 107 | <2>. QED BY <2>1, <2>2, <2>3 DEF Next 108 | 109 | <1>4. Inv1230_2_1_def' 110 | <2>1. CASE \E n \in Node, v \in Value : CastVote(n,v) BY <2>1 DEF CastVote, IndAuto, TypeOK, Inv1230_2_1_def 111 | <2>2. CASE \E Q \in Quorum, v \in Value : CollectVotes(Q,v) 112 | BY <2>2, QuorumsOverlap, QuorumsAreNodePowersets DEF CollectVotes, IndAuto, TypeOK, Inv1230_2_1_def 113 | <2>3. CASE \E Q \in Quorum, v \in Value : LearnValue(Q,v) BY <2>3 DEF LearnValue, IndAuto, TypeOK, Inv1230_2_1_def 114 | <2>. QED BY <2>1, <2>2, <2>3 DEF Next 115 | 116 | <1>5. Inv217_2_2_def' 117 | <2>1. CASE \E n \in Node, v \in Value : CastVote(n,v) BY <2>1 DEF CastVote, IndAuto, TypeOK, Inv217_2_2_def 118 | <2>2. CASE \E Q \in Quorum, v \in Value : CollectVotes(Q,v) BY <2>2 DEF CollectVotes, IndAuto, TypeOK, Inv217_2_2_def 119 | <2>3. CASE \E Q \in Quorum, v \in Value : LearnValue(Q,v) BY <2>3 DEF LearnValue, IndAuto, TypeOK, Inv217_2_2_def 120 | <2>. QED BY <2>1, <2>2, <2>3 DEF Next 121 | <1>. QED BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 122 | ==== 123 | 124 | -------------------------------------------------------------------------------- /benchmarks/toy_consensus_epr_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE toy_consensus_epr_IndProofs ---- 2 | EXTENDS toy_consensus_epr, FiniteSetTheorems 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-05T19:36:35.009271 7 | \* is_inductive: True 8 | \* inv_size: 4 9 | \* invcheck_duration_secs: 4.827651500701904 10 | \* ctielimcheck_duration_secs: 6.351951360702515 11 | \* ctigen_duration_secs: 5.40147066116333 12 | \* total_duration_secs: 16.597809076309204 13 | \* total_num_ctis_eliminated: 384 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 627 16 | \* total_num_invs_checked: 3260 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 11 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv220_1_0_def == \A VARS \in Node : \A VARA \in Value : (VARS \in voted) \/ (~(<> \in vote)) 32 | Inv155_1_1_def == \E VARQ \in Quorum : \A VARA \in Value : (ChosenAt(VARQ, VARA)) \/ (~(VARA \in decided)) 33 | Inv201_2_2_def == \A VARS \in Node : \A VARA \in Value : \A VARB \in Value : ((VARA = VARB) /\ vote = vote) \/ (~(<> \in vote)) \/ (~(<> \in vote)) 34 | 35 | \* The inductive invariant candidate. 36 | IndAuto == 37 | /\ TypeOK 38 | /\ Safety 39 | /\ Inv220_1_0_def 40 | /\ Inv155_1_1_def 41 | /\ Inv201_2_2_def 42 | 43 | ASSUME QuorumType == Quorum \subseteq SUBSET Node 44 | ASSUME NodeFinite == IsFiniteSet(Node) 45 | ASSUME QuorumsAreNonEmpty == \A Q \in Quorum : Q # {} 46 | ASSUME QuorumsExist == Quorum # {} 47 | ASSUME ValueNonEmpty == Value # {} 48 | ASSUME NodeNonEmpty == Node # {} 49 | ASSUME QuorumsIntersect == \A Q1,Q2 \in Quorum : Q1 \cap Q2 # {} 50 | 51 | \* TLAPS Proof skeleton. 52 | THEOREM Init => IndAuto 53 | <1> SUFFICES ASSUME Init 54 | PROVE IndAuto 55 | OBVIOUS 56 | <1>1. TypeOK 57 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def 58 | <1>2. Safety 59 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def 60 | <1>3. Inv220_1_0_def 61 | BY QuorumsExist, NodeFinite, QuorumType, FS_Subset DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,ChosenAt 62 | <1>4. Inv155_1_1_def 63 | BY NodeFinite, QuorumType, QuorumsExist DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,ChosenAt 64 | <1>5. Inv201_2_2_def 65 | BY QuorumsExist, NodeFinite, QuorumType, FS_Subset DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,ChosenAt 66 | <1>6. QED 67 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 68 | 69 | THEOREM IndAuto /\ Next => IndAuto' 70 | <1> SUFFICES ASSUME IndAuto, Next 71 | PROVE IndAuto' 72 | OBVIOUS 73 | <1>1. TypeOK' 74 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 75 | 76 | <1>2. Safety' 77 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 78 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 79 | <2>2. CASE \E v \in Value, Q \in Quorum : Decide(v, Q) 80 | <3>1. PICK v \in Value, Q \in Quorum : Decide(v, Q) BY <2>2 81 | <3>2. SUFFICES ASSUME NEW vi \in decided', 82 | NEW vj \in decided', 83 | vi # vj 84 | PROVE FALSE BY DEF Safety 85 | <3>3. vi \in decided \/ vj \in decided BY <3>1, <3>2 DEF Decide, IndAuto, TypeOK 86 | <3>4. CASE vi \in decided 87 | <4>1. vj = v BY <3>1, <3>2, <3>4 DEF Decide, IndAuto, TypeOK, Safety 88 | <4>2. ChosenAt(Q, vj) BY <3>1, <4>1 DEF Decide 89 | <4>3. PICK Qvi \in Quorum : ChosenAt(Qvi, vi) 90 | BY <3>4, NodeNonEmpty, ValueNonEmpty DEF IndAuto, Inv155_1_1_def, TypeOK 91 | <4>4. PICK t \in Node : t \in Q /\ t \in Qvi BY QuorumsIntersect, QuorumType 92 | <4>5. <> \in vote /\ <> \in vote BY <4>2, <4>3, <4>4 DEF ChosenAt 93 | <4>. QED BY <3>2, <4>5 DEF IndAuto, Inv201_2_2_def, TypeOK 94 | <3>5. CASE vj \in decided 95 | <4>1. vi = v BY <3>1, <3>2, <3>5 DEF Decide, IndAuto, TypeOK, Safety 96 | <4>2. ChosenAt(Q, vi) BY <3>1, <4>1 DEF Decide 97 | <4>3. PICK Qvj \in Quorum : ChosenAt(Qvj, vj) 98 | BY <3>5, NodeNonEmpty, ValueNonEmpty DEF IndAuto, Inv155_1_1_def, TypeOK 99 | <4>4. PICK t \in Node : t \in Q /\ t \in Qvj BY QuorumsIntersect, QuorumType 100 | <4>5. <> \in vote /\ <> \in vote BY <4>2, <4>3, <4>4 DEF ChosenAt 101 | <4>. QED BY <3>2, <4>5 DEF IndAuto, Inv201_2_2_def, TypeOK 102 | <3>. QED BY <3>3, <3>4, <3>5 103 | 104 | <2>3. QED 105 | BY <2>1, <2>2 DEF Next 106 | <1>3. Inv220_1_0_def' 107 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 108 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 109 | <2>2. CASE \E v \in Value, Q \in Quorum : Decide(v, Q) 110 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 111 | <2>3. QED 112 | BY <2>1, <2>2 DEF Next 113 | 114 | \* Inv155_1_1_def == \E VARQ \in Quorum : \A VARA \in Value : (ChosenAt(VARQ, VARA)) \/ (~(VARA \in decided)) 115 | <1>4. Inv155_1_1_def' 116 | <2>1. CASE \E i \in Node, v \in Value : CastVote(i, v) 117 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 118 | <2>2. CASE \E v \in Value, Q \in Quorum : Decide(v, Q) 119 | <3>1. PICK v \in Value, Qv \in Quorum : Decide(v, Qv) BY <2>2 120 | <3>2. SUFFICES ASSUME 121 | \A Q \in Quorum : \E vb \in Value : ~ChosenAt(Q, vb)' /\ (vb \in decided') 122 | PROVE FALSE BY DEF Inv155_1_1_def 123 | <3>3. PICK va,vb \in Value : (vb \in decided') /\ ~ChosenAt(Qv, vb)' BY <3>1, <3>2 124 | <3>4. CASE v # vb 125 | <4>1. vb \in decided BY <3>1, <3>3, <3>4 DEF Decide, IndAuto, TypeOK 126 | <4>2. ~ChosenAt(Qv, vb) BY <3>1, <3>3, <3>4 DEF Decide, ChosenAt, IndAuto, TypeOK 127 | <4>3. PICK Q \in Quorum : ChosenAt(Q, vb) BY <4>1 DEF IndAuto, Inv155_1_1_def 128 | <4>4. PICK n \in Node : n \in Qv /\ n \in Q BY QuorumsIntersect, QuorumType 129 | <4>5. <> \in vote BY <4>3, <4>4 DEF ChosenAt 130 | <4>. QED BY <3>1, <3>4, <4>4, <4>5 DEF Decide, ChosenAt, IndAuto, Inv201_2_2_def, TypeOK 131 | <3>5. CASE v = vb 132 | <4>1. ~ChosenAt(Qv, v)' BY <3>2, <3>3, <3>5 133 | <4>. QED BY <3>1, <4>1 DEF Decide, ChosenAt, IndAuto, TypeOK 134 | <3>. QED BY <3>4, <3>5 135 | <2>3. QED 136 | BY <2>1, <2>2 DEF Next 137 | 138 | <1>5. Inv201_2_2_def' 139 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv220_1_0_def,Inv155_1_1_def,Inv201_2_2_def,CastVote,Decide,ChosenAt 140 | <1>6. QED 141 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 142 | 143 | ==== 144 | 145 | -------------------------------------------------------------------------------- /benchmarks/paxos_epr.tla: -------------------------------------------------------------------------------- 1 | -------------------------------- MODULE paxos_epr ------------------------------- 2 | 3 | \* 4 | \* Specification of Paxos based on the model presented in 5 | \* the paper 'Paxos Made EPR' (OOPSLA 2017). 6 | \* 7 | \* See two online sources of this model: 8 | \* - https://github.com/secure-foundations/SWISS/blob/348b9c4f9b0b2f124b50c8f420d071f4bc0789b3/benchmarks/paxos_epr_missing1.ivy 9 | \* - https://github.com/wilcoxjay/mypyvy/blob/12a8f5434a25587c56814d090b6ab7fa95851e71/examples/pd/paxos_epr.pyv 10 | \* 11 | 12 | EXTENDS Integers, FiniteSets, TLC, Randomization 13 | ----------------------------------------------------------------------------- 14 | 15 | CONSTANT Value, Node, Quorum 16 | 17 | ASSUME QuorumAssumption == /\ \A Q \in Quorum : Q \subseteq Node 18 | /\ \A Q1, Q2 \in Quorum : Q1 \cap Q2 # {} 19 | 20 | Round == Nat 21 | 22 | None == -1 23 | \* None == CHOOSE v : v \notin Value 24 | (*************************************************************************) 25 | (* An unspecified value that is not a ballot number. *) 26 | (*************************************************************************) 27 | 28 | VARIABLE one_a \* Round 29 | VARIABLE one_b_max_vote \* Node \X Round \X Round \X Value 30 | VARIABLE one_b \* Node \X Round 31 | VARIABLE left_rnd \* Node \X Round 32 | VARIABLE proposal \* Round \X Value 33 | VARIABLE vote \* Node \X Round \X Value 34 | VARIABLE decision \* Node \X Round \X Value 35 | 36 | vars == <> 37 | 38 | (***************************************************************************) 39 | (* The type invariant and initial predicate. *) 40 | (***************************************************************************) 41 | \* TypeOK == /\ maxBal \in [Acceptor -> Round \cup {-1}] 42 | \* /\ maxVBal \in [Acceptor -> Round \cup {-1}] 43 | \* /\ maxVal \in [Acceptor -> Value \cup {None}] 44 | \* /\ msgs \subseteq Message 45 | 46 | 47 | \* NumRandSubsets == 6 48 | 49 | \* kNumSubsets == 4 50 | \* nAvgSubsetSize == 3 51 | 52 | \* TypeOKRandom == 53 | \* /\ maxBal \in RandomSubset(NumRandSubsets, [Acceptor -> Round \cup {-1}]) 54 | \* /\ maxVBal \in RandomSubset(NumRandSubsets, [Acceptor -> Round \cup {-1}]) 55 | \* /\ maxVal \in RandomSubset(NumRandSubsets, [Acceptor -> Value \cup {None}]) 56 | \* /\ msgs \in RandomSetOfSubsets(kNumSubsets, nAvgSubsetSize, Message) 57 | 58 | 59 | \* Init == /\ maxBal = [a \in Acceptor |-> -1] 60 | \* /\ maxVBal = [a \in Acceptor |-> -1] 61 | \* /\ maxVal = [a \in Acceptor |-> None] 62 | \* /\ msgs = {} 63 | 64 | Send1a(b) == 65 | /\ one_a' = one_a \cup {b} 66 | /\ UNCHANGED <> 67 | 68 | JoinRound(n, r) == 69 | \E maxr \in Round \cup {None}, maxv \in Value : 70 | /\ r \in one_a 71 | /\ <> \notin left_rnd 72 | \* Send the 1b message. 73 | \* Find maximal vote made by this node in an earlier round. 74 | /\ \/ (maxr = None /\ \A rx \in Round, vx \in Value : ~((r > rx) /\ <> \in vote)) 75 | \/ /\ maxr # None 76 | /\ (r > maxr) /\ <> \in vote 77 | /\ (\A mr \in Round, v \in Value : ((r > mr) /\ <> \in vote) => (mr <= maxr)) 78 | /\ one_b_max_vote' = one_b_max_vote \cup {<>} 79 | /\ one_b' = one_b \cup {<>} 80 | /\ left_rnd' = left_rnd 81 | /\ UNCHANGED <> 82 | 83 | Propose(r,Q) == 84 | \E maxr \in Round \cup {None}, v \in Value : 85 | /\ \/ (maxr = None /\ \A n \in Node, mr \in Round, mv \in Value : ~(n \in Q /\ (r > mr) /\ <> \in vote)) 86 | \/ /\ maxr # None 87 | /\ (\E n \in Node : n \in Q /\ ~(r <= maxr) /\ <> \in vote) 88 | /\ (\A n \in Node, mr \in Round, mv \in Value : (n \in Q /\ ~(r <= mr) /\ <> \in vote) => (mr<=maxr)) 89 | /\ \A mv \in Value : <> \notin proposal 90 | /\ \A n \in Node : n \in Q => <> \in one_b 91 | /\ proposal' = proposal \cup {<>} 92 | /\ UNCHANGED <> 93 | 94 | CastVote(n,v,r) == 95 | /\ r # None 96 | /\ <> \notin left_rnd 97 | /\ <> \in proposal 98 | /\ vote' = vote \cup {<>} 99 | /\ UNCHANGED <> 100 | 101 | 102 | Decide(n,r,v,Q) == 103 | /\ r # None 104 | /\ \A m \in Node : m \in Q => <> \in vote 105 | /\ decision' = decision \cup {<>} 106 | /\ UNCHANGED <> 107 | 108 | Init == 109 | /\ one_a = {} \* Round 110 | /\ one_b_max_vote = {} \* Node \X Round \X Round \X Value 111 | /\ one_b = {} \* Node \X Round 112 | /\ left_rnd = {} \* Node \X Round 113 | /\ proposal = {} \* Round \X Value 114 | /\ vote = {} \* Node \X Round \X Value 115 | /\ decision = {} \* Node \X Round \X Value 116 | 117 | (***************************************************************************) 118 | (* Below are defined the next-state action and the complete spec. *) 119 | (***************************************************************************) 120 | Next == 121 | \/ \E b \in Round : Send1a(b) 122 | \/ \E n \in Node, r \in Round : JoinRound(n, r) 123 | \/ \E r \in Round, Q \in Quorum : Propose(r,Q) 124 | \/ \E n \in Node, v \in Value, r \in Round : CastVote(n,v,r) 125 | \/ \E n \in Node, v \in Value, r \in Round, Q \in Quorum : Decide(n,v,r,Q) 126 | 127 | \* \/ \E b \in Round : \/ Phase1a(b) 128 | \* \/ \E v \in Value : Phase2a(b, v) 129 | \* \/ \E a \in Acceptor : Phase1b(a) \/ Phase2b(a) 130 | 131 | Spec == Init /\ [][Next]_vars 132 | ---------------------------------------------------------------------------- 133 | 134 | (***************************************************************************) 135 | (* As we observed, votes are registered by sending phase 2b messages. So *) 136 | (* the array `votes' describing the votes cast by the acceptors is defined *) 137 | (* as follows. *) 138 | (***************************************************************************) 139 | \* votes == [a \in Acceptor |-> 140 | \* {<> : m \in {mm \in msgs: /\ mm.type = "2b" 141 | \* /\ mm.acc = a }}] 142 | 143 | \* VotedFor(a, b, v) == <> \in votes[a] 144 | 145 | \* ChosenAt(b, v) == \E Q \in Quorum : \A a \in Q : VotedFor(a, b, v) 146 | 147 | \* chosen == {v \in Value : \E b \in Round : ChosenAt(b, v)} 148 | 149 | \* Inv == Cardinality(chosen) <= 1 150 | 151 | \* Ind == 152 | \* /\ TypeOKRandom 153 | \* /\ Inv 154 | 155 | Symmetry == Permutations(Node) \cup Permutations(Value) 156 | 157 | NextUnchanged == UNCHANGED vars 158 | 159 | \* conjecture ( 160 | \* decision(N1,R1,V1) & 161 | \* decision(N2,R2,V2) 162 | \* ) -> V1 = V2 163 | Safety == 164 | \A n1,n2 \in Node, r1,r2 \in Round, v1,v2 \in Value : 165 | (<> \in decision /\ <> \in decision) => v1 = v2 166 | 167 | ============================================================================ -------------------------------------------------------------------------------- /benchmarks/MongoStaticRaft.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE MongoStaticRaft ---- 2 | \* 3 | \* Basic, static version of MongoDB Raft protocol. No reconfiguration is allowed. 4 | \* 5 | 6 | EXTENDS Naturals, Integers, FiniteSets, Sequences, TLC 7 | 8 | CONSTANTS Server 9 | CONSTANTS Secondary, Primary, Nil 10 | CONSTANT InitTerm 11 | 12 | VARIABLE currentTerm 13 | VARIABLE state 14 | VARIABLE log 15 | VARIABLE committed 16 | 17 | vars == <> 18 | 19 | \* 20 | \* Helper operators. 21 | \* 22 | 23 | \* Is a sequence empty. 24 | Empty(s) == Len(s) = 0 25 | 26 | \* Is log entry e = <> in the log of node 'i'. 27 | InLog(e, i) == \E x \in DOMAIN log[i] : x = e[1] /\ log[i][x] = e[2] 28 | 29 | \* The term of the last entry in a log, or 0 if the log is empty. 30 | LastTerm(xlog) == IF Len(xlog) = 0 THEN 0 ELSE xlog[Len(xlog)] 31 | LastEntry(xlog) == <> 32 | GetTerm(xlog, index) == IF index = 0 THEN 0 ELSE xlog[index] 33 | LogTerm(i, index) == GetTerm(log[i], index) 34 | 35 | \* The set of all quorums in a given set. 36 | Quorums(S) == {i \in SUBSET(S) : Cardinality(i) * 2 > Cardinality(S)} 37 | 38 | \* Is it possible for log 'i' to roll back against log 'j'. 39 | \* If this is true, it implies that log 'i' should remove entries from the end of its log. 40 | CanRollback(i, j) == 41 | /\ Len(log[i]) > 0 42 | /\ \* The log with later term is more up-to-date. 43 | LastTerm(log[i]) < LastTerm(log[j]) 44 | /\ \/ Len(log[i]) > Len(log[j]) 45 | \* There seems no short-cut of OR clauses, so we specify the negative case. 46 | \/ /\ Len(log[i]) <= Len(log[j]) 47 | /\ LastTerm(log[i]) /= LogTerm(j, Len(log[i])) 48 | 49 | \* Can node 'i' currently cast a vote for node 'j' in term 'term'. 50 | CanVoteForOplog(i, j, term) == 51 | LET logOk == 52 | \/ LastTerm(log[j]) > LastTerm(log[i]) 53 | \/ /\ LastTerm(log[j]) = LastTerm(log[i]) 54 | /\ Len(log[j]) >= Len(log[i]) IN 55 | /\ currentTerm[i] < term 56 | /\ logOk 57 | 58 | \* Is a log entry 'e'=<> immediately committed in term 't' with a quorum 'Q'. 59 | ImmediatelyCommitted(e, Q) == 60 | LET eind == e[1] 61 | eterm == e[2] IN 62 | \A s \in Q : 63 | /\ Len(log[s]) >= eind 64 | /\ InLog(e, s) \* they have the entry. 65 | /\ currentTerm[s] = eterm \* they are in the same term as the log entry. 66 | 67 | \* Helper operator for actions that propagate the term between two nodes. 68 | UpdateTermsExpr(i, j) == 69 | /\ currentTerm[i] > currentTerm[j] 70 | /\ currentTerm' = [currentTerm EXCEPT ![j] = currentTerm[i]] 71 | /\ state' = [state EXCEPT ![j] = Secondary] 72 | 73 | -------------------------------------------------------------------------------- 74 | 75 | \* 76 | \* Next state actions. 77 | \* 78 | 79 | \* Node 'i', a primary, handles a new client request and places the entry 80 | \* in its log. 81 | ClientRequest(i) == 82 | /\ state[i] = Primary 83 | /\ log' = [log EXCEPT ![i] = Append(log[i], currentTerm[i])] 84 | /\ UNCHANGED <> 85 | 86 | \* Node 'i' gets a new log entry from node 'j'. 87 | GetEntries(i, j) == 88 | /\ state[i] = Secondary 89 | \* Node j must have more entries than node i. 90 | /\ Len(log[j]) > Len(log[i]) 91 | \* Ensure that the entry at the last index of node i's log must match the entry at 92 | \* the same index in node j's log. If the log of node i is empty, then the check 93 | \* trivially passes. This is the essential 'log consistency check'. 94 | /\ LET logOk == IF Empty(log[i]) 95 | THEN TRUE 96 | ELSE log[j][Len(log[i])] = log[i][Len(log[i])] IN 97 | /\ logOk \* log consistency check 98 | \* If the log of node i is empty, then take the first entry from node j's log. 99 | \* Otherwise take the entry following the last index of node i. 100 | /\ LET newEntryIndex == IF Empty(log[i]) THEN 1 ELSE Len(log[i]) + 1 101 | newEntry == log[j][newEntryIndex] 102 | newLog == Append(log[i], newEntry) IN 103 | /\ log' = [log EXCEPT ![i] = newLog] 104 | /\ UNCHANGED <> 105 | 106 | \* Node 'i' rolls back against the log of node 'j'. 107 | RollbackEntries(i, j) == 108 | /\ state[i] = Secondary 109 | /\ CanRollback(i, j) 110 | \* Roll back one log entry. 111 | /\ log' = [log EXCEPT ![i] = SubSeq(log[i], 1, Len(log[i])-1)] 112 | /\ UNCHANGED <> 113 | 114 | \* Node 'i' gets elected as a primary. 115 | BecomeLeader(i, voteQuorum) == 116 | \* Primaries make decisions based on their current configuration. 117 | LET newTerm == currentTerm[i] + 1 IN 118 | /\ i \in voteQuorum \* The new leader should vote for itself. 119 | /\ \A v \in voteQuorum : CanVoteForOplog(v, i, newTerm) 120 | \* Update the terms of each voter. 121 | /\ currentTerm' = [s \in Server |-> IF s \in voteQuorum THEN newTerm ELSE currentTerm[s]] 122 | /\ state' = [s \in Server |-> 123 | IF s = i THEN Primary 124 | ELSE IF s \in voteQuorum THEN Secondary \* All voters should revert to secondary state. 125 | ELSE state[s]] 126 | /\ UNCHANGED <> 127 | 128 | \* Primary 'i' commits its latest log entry. 129 | CommitEntry(i, commitQuorum) == 130 | LET ind == Len(log[i]) IN 131 | \* Must have some entries to commit. 132 | /\ ind > 0 133 | \* This node is leader. 134 | /\ state[i] = Primary 135 | \* The entry was written by this leader. 136 | /\ log[i][ind] = currentTerm[i] 137 | \* all nodes have this log entry and are in the term of the leader. 138 | /\ ImmediatelyCommitted(<>, commitQuorum) 139 | \* Don't mark an entry as committed more than once. 140 | /\ ~\E c \in committed : c.entry = <> 141 | /\ committed' = committed \cup 142 | {[ entry |-> <>, 143 | term |-> currentTerm[i]]} 144 | /\ UNCHANGED <> 145 | 146 | \* Action that exchanges terms between two nodes and step down the primary if 147 | \* needed. This can be safely specified as a separate action, rather than 148 | \* occurring atomically on other replication actions that involve communication 149 | \* between two nodes. This makes it clearer to see where term propagation is 150 | \* strictly necessary for guaranteeing safety. 151 | UpdateTerms(i, j) == 152 | /\ UpdateTermsExpr(i, j) 153 | /\ UNCHANGED <> 154 | 155 | Init == 156 | /\ currentTerm = [i \in Server |-> InitTerm] 157 | /\ state = [i \in Server |-> Secondary] 158 | /\ log = [i \in Server |-> <<>>] 159 | /\ committed = {} 160 | 161 | ClientRequestAction == \E s \in Server : ClientRequest(s) 162 | GetEntriesAction == \E s, t \in Server : GetEntries(s, t) 163 | RollbackEntriesAction == \E s, t \in Server : RollbackEntries(s, t) 164 | BecomeLeaderAction == \E s \in Server : \E Q \in Quorums(Server) : BecomeLeader(s, Q) 165 | UpdateTermsActions == \E s,t \in Server : UpdateTerms(s, t) 166 | 167 | Next == 168 | \/ ClientRequestAction 169 | \/ GetEntriesAction 170 | \/ RollbackEntriesAction 171 | \/ BecomeLeaderAction 172 | \/ UpdateTermsActions 173 | 174 | Spec == Init /\ [][Next]_vars 175 | 176 | ============================================================================= 177 | -------------------------------------------------------------------------------- /benchmarks/simple_election_IndProofs.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE simple_election_IndProofs ---- 2 | EXTENDS simple_election,FiniteSetTheorems,TLAPS 3 | 4 | \* endive.py stats 5 | \* ----------------- 6 | \* date: 2022-08-05T19:34:46.096179 7 | \* is_inductive: True 8 | \* inv_size: 4 9 | \* invcheck_duration_secs: 5.3670713901519775 10 | \* ctielimcheck_duration_secs: 7.457974672317505 11 | \* ctigen_duration_secs: 6.388131380081177 12 | \* total_duration_secs: 19.23183298110962 13 | \* total_num_ctis_eliminated: 551 14 | \* total_num_cti_elimination_rounds: 1 15 | \* total_num_invs_generated: 555 16 | \* total_num_invs_checked: 3255 17 | \* num_invs: 15000 18 | \* num_iters: 3 19 | \* num_round: 4 20 | \* num_simulate_traces: 50000 21 | \* opt_quant_minimize: True 22 | \* tlc_workers: 8 23 | \* seed: 12 24 | \* os: posix 25 | \* system: Darwin 26 | \* java_exe: /Users/willyschultz/Downloads/zulu15.32.15-ca-jdk15.0.3-macosx_aarch64/bin/java -Xss16M 27 | \* processor: arm 28 | \* cpu_count: 8 29 | 30 | \* Inductive strengthening conjuncts 31 | Inv219_1_0_def == \A VARS \in Acceptor : \A VARPA \in Proposer : (VARPA \in start) \/ (~(<> \in promise)) 32 | Inv136_1_1_def == \A VARPA \in Proposer : \E VARQ \in Quorum : (ChosenAt(VARQ,VARPA)) \/ (~(VARPA \in leader)) 33 | Inv200_2_2_def == \A VARS \in Acceptor : \A VARPA \in Proposer : \A VARPB \in Proposer : ((VARPA=VARPB) /\ promise = promise) \/ (~(<> \in promise)) \/ (~(<> \in promise)) 34 | 35 | \* The inductive invariant candidate. 36 | IndAuto == 37 | /\ TypeOK 38 | /\ Safety 39 | /\ Inv219_1_0_def 40 | /\ Inv136_1_1_def 41 | /\ Inv200_2_2_def 42 | 43 | 44 | ASSUME QuorumsNonEmpty == Quorum # {} 45 | ASSUME Fin == IsFiniteSet(Acceptor) /\ IsFiniteSet(Proposer) 46 | ASSUME QuorumsType == Quorum \subseteq SUBSET Acceptor 47 | ASSUME QuorumsIntersect == \A Q1,Q2 \in Quorum : Q1 \cap Q2 # {} 48 | ASSUME NonEmpty == Proposer # {} 49 | 50 | \* TLAPS Proof skeleton. 51 | THEOREM Init => IndAuto 52 | <1> SUFFICES ASSUME Init 53 | PROVE IndAuto 54 | OBVIOUS 55 | <1>1. TypeOK 56 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def 57 | <1>2. Safety 58 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def 59 | <1>3. Inv219_1_0_def 60 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def 61 | <1>4. Inv136_1_1_def 62 | BY QuorumsNonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,ChosenAt 63 | <1>5. Inv200_2_2_def 64 | BY DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def 65 | <1>6. QED 66 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 67 | 68 | THEOREM IndAuto /\ Next => IndAuto' 69 | <1> SUFFICES ASSUME IndAuto /\ Next 70 | PROVE IndAuto' 71 | OBVIOUS 72 | <1>1. TypeOK' 73 | <2>1. CASE \E p \in Proposer : Send1a(p) 74 | BY <2>1, QuorumsNonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 75 | <2>2. CASE \E a \in Acceptor, p \in Proposer : Send1b(a, p) 76 | BY <2>2, QuorumsNonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 77 | <2>3. CASE \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 78 | BY <2>3,QuorumsNonEmpty DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 79 | <2>4. QED 80 | BY <2>1, <2>2, <2>3 DEF Next 81 | 82 | <1>2. Safety' 83 | <2>1. CASE \E p \in Proposer : Send1a(p) 84 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 85 | <2>2. CASE \E a \in Acceptor, p \in Proposer : Send1b(a, p) 86 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 87 | <2>3. CASE \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 88 | <3>1. PICK p \in Proposer, Q \in Quorum : Decide(p, Q) BY <2>3 89 | <3>2. ChosenAt(Q, p) BY <3>1 DEF Decide 90 | <3>3. SUFFICES ASSUME NEW x \in leader', 91 | NEW y \in leader', 92 | x # y 93 | PROVE FALSE BY DEF Safety 94 | <3>4. x = p \/ y = p BY <3>1, <3>3 DEF Decide, IndAuto, Safety, TypeOK 95 | <3>5. CASE x = p 96 | <4>1. y \in leader BY <3>1, <3>3, <3>5 DEF Decide 97 | <4>2. PICK Qy \in Quorum : ChosenAt(Qy, y) BY <4>1 DEF IndAuto, Inv136_1_1_def, TypeOK 98 | <4>3. PICK n \in Acceptor : n \in Q /\ n \in Qy BY <3>2, <4>2, QuorumsIntersect, QuorumsType 99 | <4>4. <> \in promise BY <3>1, <3>2, <4>3 DEF ChosenAt 100 | <4>5. <> \in promise BY <4>2, <4>3 DEF ChosenAt 101 | <4>. QED BY <3>3, <3>5, <4>4, <4>5 DEF IndAuto, Inv200_2_2_def, TypeOK 102 | <3>6. CASE y = p 103 | <4>1. x \in leader BY <3>1, <3>3, <3>6 DEF Decide 104 | <4>2. PICK Qx \in Quorum : ChosenAt(Qx, x) BY <4>1 DEF IndAuto, Inv136_1_1_def, TypeOK 105 | <4>3. PICK n \in Acceptor : n \in Q /\ n \in Qx BY <3>2, <4>2, QuorumsIntersect, QuorumsType 106 | <4>4. <> \in promise BY <3>1, <3>2, <4>3 DEF ChosenAt 107 | <4>5. <> \in promise BY <4>2, <4>3 DEF ChosenAt 108 | <4>. QED BY <3>3, <3>6, <4>4, <4>5 DEF IndAuto, Inv200_2_2_def, TypeOK 109 | <3>. QED BY <3>4, <3>5, <3>6 110 | <2>4. QED 111 | BY <2>1, <2>2, <2>3 DEF Next 112 | 113 | <1>3. Inv219_1_0_def' 114 | <2>1. CASE \E p \in Proposer : Send1a(p) 115 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 116 | <2>2. CASE \E a \in Acceptor, p \in Proposer : Send1b(a, p) 117 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 118 | <2>3. CASE \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 119 | BY <2>3 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 120 | <2>4. QED 121 | BY <2>1, <2>2, <2>3 DEF Next 122 | 123 | <1>4. Inv136_1_1_def' 124 | <2>1. CASE \E p \in Proposer : Send1a(p) 125 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 126 | <2>2. CASE \E a \in Acceptor, p \in Proposer : Send1b(a, p) 127 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 128 | <2>3. CASE \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 129 | BY <2>3 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 130 | <2>4. QED 131 | BY <2>1, <2>2, <2>3 DEF Next 132 | 133 | <1>5. Inv200_2_2_def' 134 | <2>1. CASE \E p \in Proposer : Send1a(p) 135 | BY <2>1 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 136 | <2>2. CASE \E a \in Acceptor, p \in Proposer : Send1b(a, p) 137 | BY <2>2 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt,DidNotPromise 138 | <2>3. CASE \E p \in Proposer : \E Q \in Quorum : Decide(p, Q) 139 | BY <2>3 DEF TypeOK,Init,Next,IndAuto,Safety,Inv219_1_0_def,Inv136_1_1_def,Inv200_2_2_def,Send1a,Send1b,Decide,ChosenAt 140 | <2>4. QED 141 | BY <2>1, <2>2, <2>3 DEF Next 142 | 143 | <1>6. QED 144 | BY <1>1, <1>2, <1>3, <1>4, <1>5 DEF IndAuto 145 | 146 | ==== 147 | --------------------------------------------------------------------------------