Executable semantics of transactional futures in PLT Redex.
This repository contains a machine-executable implementation of the operational semantics of ClojureTxTk, using PLT Redex.
It consists of the following files:
clj-base.rkt defines Lb, the “base” language (based on Clojure)clj-futures.rkt defines Lf, the base language extended with support for futures (as in Clojure)clj-tx.rkt defines Lt, which is Lf extended with support for transactions (as in Clojure)tx-futs.rkt defines Ltf, which is Lt extended with support for transactional futures (not in Clojure)map.rkt: helper functions for mapsset.rkt: helper functions for setsEach of the files also contains test cases.
For instance, tx-futs.rkt contains the following test case (named example-tx-futs-3):
(let [(r_0 (ref 0))(f_0 (fork(atomic(let [(x (fork (ref-set r_0 (+ (deref r_0) 1))))(y (fork (ref-set r_0 (+ (deref r_0) 2))))](do (join x) ; => r_0 = original + 1(join y) ; => r_0 = original + 2(deref r_0)))))) ; => returns original + 2(f_1 (fork(atomic(let [(x (fork (ref-set r_0 (+ (deref r_0) 3))))(y (fork (ref-set r_0 (+ (deref r_0) 4))))](do (join x) ; => r_0 = original + 3(join y) ; => r_0 = original + 4(deref r_0))))))] ; => returns original + 4(+ (join f_0) (join f_1)))
There are two possible outcomes of this program:
(term [[(f_0 8) (f_new1 6) (f_new 2)][(r_new 6) (r_new 5) (r_new 2) (r_new 1) (r_new 0)]])(term [[(f_0 10) (f_new1 4) (f_new 6)][(r_new 6) (r_new 5) (r_new 4) (r_new 3) (r_new 0)]])
These correspond to the two possible serializations: the first corresponds to transaction 1 executing first (end result is 8), the second to transaction 2 executing first (end result is 10).
These results can be visualized using:
(traces ->tf example-tx-futs-3)
This is shown in the image in example-tx-futs-3.pdf. You can see how different interleavings lead to different intermediate states, but they collapse into two final states, corresponding to the two possible serializations.