├── paper ├── isabelletags.sty ├── Makefile ├── round2.tex ├── proof-structure.tex ├── author-response.txt ├── happens-before.tex ├── rga-example.tex ├── proof-strategy.tex ├── isabelle.tex ├── acmart-pacmpl-template.tex ├── splash-reviews.txt ├── isabelle.sty └── comment.sty ├── src ├── ocaml │ ├── .merlin │ ├── wrapper.ml │ ├── Makefile │ ├── test.sh │ ├── counter.ml │ ├── network.ml │ ├── orset.ml │ └── rga.ml ├── supplemental │ ├── ocaml │ │ ├── .merlin │ │ ├── Makefile │ │ ├── test.sh │ │ ├── counter.ml │ │ ├── network.ml │ │ ├── orset.ml │ │ └── rga.ml │ ├── annotated_proofs.pdf │ ├── ROOT │ ├── Counter.thy │ ├── README.md │ ├── document │ │ └── root.tex │ └── Util.thy ├── supplementary.tar.gz ├── ROOT ├── AFP │ ├── ROOT │ ├── ocaml │ │ ├── counter.ml │ │ ├── orset.ml │ │ └── rga.ml │ ├── Counter.thy │ ├── document │ │ └── root.tex │ └── Util.thy ├── Counter.thy ├── document │ └── root.tex └── Util.thy ├── .gitignore ├── README.md ├── talks ├── rems-march-2017 │ ├── beamerthememetropolis.sty │ ├── beamercolorthememetropolis.sty │ ├── beamerouterthememetropolis.sty │ └── beamerinnerthememetropolis.sty └── srepls-may-2017 │ ├── beamerthememetropolis.sty │ ├── beamercolorthememetropolis.sty │ ├── beamerouterthememetropolis.sty │ └── beamerinnerthememetropolis.sty └── LICENSE /paper/isabelletags.sty: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/ocaml/.merlin: -------------------------------------------------------------------------------- 1 | S . 2 | 3 | B _build/ 4 | 5 | PKG core async 6 | -------------------------------------------------------------------------------- /src/supplemental/ocaml/.merlin: -------------------------------------------------------------------------------- 1 | S . 2 | 3 | B _build/ 4 | 5 | PKG core async 6 | -------------------------------------------------------------------------------- /src/supplementary.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trvedata/crdt-isabelle/HEAD/src/supplementary.tar.gz -------------------------------------------------------------------------------- /src/supplemental/annotated_proofs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trvedata/crdt-isabelle/HEAD/src/supplemental/annotated_proofs.pdf -------------------------------------------------------------------------------- /src/supplemental/ocaml/Makefile: -------------------------------------------------------------------------------- 1 | # Dependencies: 2 | # Core Async 3 | 4 | network.native: network.ml 5 | corebuild -pkg async network.native -------------------------------------------------------------------------------- /src/ocaml/wrapper.ml: -------------------------------------------------------------------------------- 1 | open Counter.Counter 2 | 3 | let _ = 4 | Js.export_all 5 | (object%js 6 | method counter_op = counter_op 7 | end) 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | src/output 4 | *.cut 5 | *.aux 6 | *.bbl 7 | *.blg 8 | *.log 9 | *.out 10 | *.pdf 11 | *.nav 12 | *.snm 13 | *.toc 14 | *.vrb 15 | _build 16 | *.native 17 | src/ocaml/wrapper.js 18 | /paper/ms.tex 19 | /paper/arxiv.zip 20 | -------------------------------------------------------------------------------- /src/ROOT: -------------------------------------------------------------------------------- 1 | chapter AFP 2 | 3 | session CRDT (AFP) = HOL + 4 | options [timeout = 600] 5 | sessions 6 | "HOL-Library" 7 | theories 8 | Network 9 | RGA 10 | Counter 11 | ORSet 12 | document_files 13 | "root.tex" 14 | "root.bib" 15 | -------------------------------------------------------------------------------- /src/supplemental/ROOT: -------------------------------------------------------------------------------- 1 | session "CRDT" = "HOL" + 2 | options [document = pdf, document_output = "output"] 3 | theories [document = false] 4 | "~~/src/Tools/Adhoc_Overloading" 5 | "~~/src/HOL/Library/Monad_Syntax" 6 | theories 7 | Network 8 | RGA 9 | Counter 10 | ORSet 11 | document_files 12 | "root.tex" 13 | "root.bib" 14 | -------------------------------------------------------------------------------- /src/AFP/ROOT: -------------------------------------------------------------------------------- 1 | session "CRDT" = "HOL" + 2 | options [document = pdf, document_output = "output"] 3 | theories [document = false] 4 | "~~/src/Tools/Adhoc_Overloading" 5 | "~~/src/HOL/Library/Monad_Syntax" 6 | "~~/src/HOL/Library/Code_Target_Numeral" 7 | theories 8 | Network 9 | RGA 10 | Counter 11 | ORSet 12 | document_files 13 | "root.tex" 14 | "root.bib" 15 | -------------------------------------------------------------------------------- /src/ocaml/Makefile: -------------------------------------------------------------------------------- 1 | # Dependencies: 2 | # Core Async 3 | 4 | .SUFFIXES: .ml .byte .js .native 5 | 6 | all: network.native wrapper.js 7 | 8 | clean: 9 | rm -f *.{byte,js,native,cmo,cmi} 10 | 11 | test: clean wrapper.js 12 | node -e 'const { counter } = require("./wrapper.js")' 13 | 14 | .ml.native: 15 | corebuild -pkg async $@ 16 | 17 | .ml.byte: 18 | ocamlbuild -use-ocamlfind -lflag -g -pkgs js_of_ocaml,js_of_ocaml.ppx $@ 19 | 20 | .byte.js: 21 | js_of_ocaml --pretty -o $@ $< 22 | -------------------------------------------------------------------------------- /src/ocaml/test.sh: -------------------------------------------------------------------------------- 1 | ./network.native -id 0 -port 8765 -nodes \ 2 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 3 | ./network.native -id 1 -port 8766 -nodes \ 4 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 5 | ./network.native -id 2 -port 8767 -nodes \ 6 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 7 | ./network.native -id 3 -port 8768 -nodes \ 8 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 9 | 10 | # to terminate nodes: pkill -9 network 11 | # to probe nodes: nc 127.0.0.1 8765 12 | # either log or showall -------------------------------------------------------------------------------- /src/supplemental/ocaml/test.sh: -------------------------------------------------------------------------------- 1 | ./network.native -id 0 -port 8765 -nodes \ 2 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 3 | ./network.native -id 1 -port 8766 -nodes \ 4 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 5 | ./network.native -id 2 -port 8767 -nodes \ 6 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 7 | ./network.native -id 3 -port 8768 -nodes \ 8 | "localhost:8765;localhost:8766;localhost:8767;localhost:8768" & 9 | 10 | # to terminate nodes: pkill -9 network 11 | # to probe nodes: nc 127.0.0.1 8765 12 | # either log or showall -------------------------------------------------------------------------------- /paper/Makefile: -------------------------------------------------------------------------------- 1 | .SUFFIXES: .tex .sty .bib .aux .bbl .dvi .ps .pdf .zip 2 | 3 | all: oopsla.pdf 4 | 5 | oopsla.pdf: oopsla.bbl 6 | pdflatex oopsla 7 | pdflatex oopsla 8 | 9 | oopsla.bbl: references.bib oopsla.aux 10 | bibtex oopsla 11 | 12 | oopsla.aux: *.tex 13 | pdflatex oopsla 14 | 15 | # ms.tex is the top-level filename expected by arxiv. See https://arxiv.org/help/submit_tex 16 | ms.tex: oopsla.tex oopsla.bbl 17 | sed -e '/\\bibliography{references}/ r oopsla.bbl' -e '/\\bibliography{references}/ d' oopsla.tex > ms.tex 18 | 19 | arxiv.zip: ms.tex acmart.cls comment.sty isabelle.sty isabellesym.sty isabelletags.sty \ 20 | proof-strategy.tex proof-structure.tex isabelle.tex convergence.tex \ 21 | network.tex rga.tex simple-crdts.tex relwork.tex 22 | zip $@ $^ 23 | 24 | clean: 25 | rm -f *.{log,aux,out,bbl,blg,dvi,ps,pdf} ms.tex arxiv.zip 26 | -------------------------------------------------------------------------------- /src/AFP/ocaml/counter.ml: -------------------------------------------------------------------------------- 1 | module Arith : sig 2 | type int = Int_of_integer of Big_int.big_int 3 | type num = One | Bit0 of num | Bit1 of num 4 | val plus_int : int -> int -> int 5 | val minus_int : int -> int -> int 6 | end = struct 7 | 8 | type int = Int_of_integer of Big_int.big_int;; 9 | 10 | type num = One | Bit0 of num | Bit1 of num;; 11 | 12 | let rec integer_of_int (Int_of_integer k) = k;; 13 | 14 | let rec plus_int 15 | k l = Int_of_integer 16 | (Big_int.add_big_int (integer_of_int k) (integer_of_int l));; 17 | 18 | let rec minus_int 19 | k l = Int_of_integer 20 | (Big_int.sub_big_int (integer_of_int k) (integer_of_int l));; 21 | 22 | end;; (*struct Arith*) 23 | 24 | module Counter : sig 25 | type operation = Increment | Decrement 26 | val counter_op : operation -> Arith.int -> Arith.int option 27 | end = struct 28 | 29 | type operation = Increment | Decrement;; 30 | 31 | let rec counter_op 32 | xa0 x = match xa0, x with 33 | Increment, x -> 34 | Some (Arith.plus_int x (Arith.Int_of_integer (Big_int.big_int_of_int 1))) 35 | | Decrement, x -> 36 | Some (Arith.minus_int x 37 | (Arith.Int_of_integer (Big_int.big_int_of_int 1)));; 38 | 39 | end;; (*struct Counter*) 40 | -------------------------------------------------------------------------------- /src/supplemental/ocaml/counter.ml: -------------------------------------------------------------------------------- 1 | module Arith : sig 2 | type int = Int_of_integer of Big_int.big_int 3 | type num = One | Bit0 of num | Bit1 of num 4 | val plus_int : int -> int -> int 5 | val minus_int : int -> int -> int 6 | end = struct 7 | 8 | type int = Int_of_integer of Big_int.big_int;; 9 | 10 | type num = One | Bit0 of num | Bit1 of num;; 11 | 12 | let rec integer_of_int (Int_of_integer k) = k;; 13 | 14 | let rec plus_int 15 | k l = Int_of_integer 16 | (Big_int.add_big_int (integer_of_int k) (integer_of_int l));; 17 | 18 | let rec minus_int 19 | k l = Int_of_integer 20 | (Big_int.sub_big_int (integer_of_int k) (integer_of_int l));; 21 | 22 | end;; (*struct Arith*) 23 | 24 | module Counter : sig 25 | type operation = Increment | Decrement 26 | val counter_op : operation -> Arith.int -> Arith.int option 27 | end = struct 28 | 29 | type operation = Increment | Decrement;; 30 | 31 | let rec counter_op 32 | xa0 x = match xa0, x with 33 | Increment, x -> 34 | Some (Arith.plus_int x (Arith.Int_of_integer (Big_int.big_int_of_int 1))) 35 | | Decrement, x -> 36 | Some (Arith.minus_int x 37 | (Arith.Int_of_integer (Big_int.big_int_of_int 1)));; 38 | 39 | end;; (*struct Counter*) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Isabelle formalisation of CRDTs 2 | =============================== 3 | 4 | This repository shows how to use [Isabelle](http://isabelle.in.tum.de/) 5 | (theorem-proving software) to prove the correctness of several operation-based 6 | [CRDTs](https://hal.inria.fr/inria-00555588) (data structures that can be edited 7 | concurrently and merged automatically). 8 | 9 | The results from this work were published in a paper titled 10 | [Verifying strong eventual consistency in distributed systems](https://dl.acm.org/citation.cfm?doid=3152284.3133933) 11 | at OOPSLA 2017 ([arXiv version](https://arxiv.org/abs/1707.01747)). Please cite it as: 12 | 13 | > Victor B. F. Gomes, Martin Kleppmann, Dominic P. Mulligan, and Alastair R. Beresford. 14 | > Verifying Strong Eventual Consistency in Distributed Systems. 15 | > Proceedings of the ACM on Programming Languages (PACMPL), Vol. 1, Issue OOPSLA, October 2017. 16 | > [doi:10.1145/3133933](https://doi.org/10.1145/3133933) 17 | 18 | The formal proof development is published in the 19 | [Isabelle Archive of Formal Proofs](https://www.isa-afp.org/index.html) under the title 20 | [A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Datatypes](https://www.isa-afp.org/entries/CRDT.html) (July 2017). 21 | 22 | About 23 | ----- 24 | 25 | This project was developed by 26 | [Victor Gomes](http://www.cl.cam.ac.uk/~vb358/), 27 | [Martin Kleppmann](http://martin.kleppmann.com/), 28 | [Dominic Mulligan](http://dominic-mulligan.co.uk/), and 29 | [Alastair Beresford](http://www.cl.cam.ac.uk/~arb33/). 30 | 31 | Copyright 2017, University of Cambridge. 32 | This software is released under the Apache License, Version 2.0 (see `LICENSE`). 33 | 34 | Unless required by applicable law or agreed to in writing, software 35 | distributed under the License is distributed on an "AS IS" BASIS, 36 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 37 | See the License for the specific language governing permissions and 38 | limitations under the License. 39 | -------------------------------------------------------------------------------- /src/AFP/Counter.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Increment-Decrement Counter\ 8 | 9 | text\The Increment-Decrement Counter is perhaps the simplest CRDT, and a paradigmatic example of a 10 | replicated data structure with commutative operations.\ 11 | 12 | theory 13 | Counter 14 | imports 15 | Network 16 | begin 17 | 18 | datatype operation = Increment | Decrement 19 | 20 | fun counter_op :: "operation \ int \ int" where 21 | "counter_op Increment x = Some (x + 1)" | 22 | "counter_op Decrement x = Some (x - 1)" 23 | 24 | locale counter = network_with_ops _ counter_op 0 25 | 26 | lemma (in counter) "counter_op x \ counter_op y = counter_op y \ counter_op x" 27 | by(case_tac x; case_tac y; auto simp add: kleisli_def) 28 | 29 | lemma (in counter) concurrent_operations_commute: 30 | assumes "xs prefix of i" 31 | shows "hb.concurrent_ops_commute (node_deliver_messages xs)" 32 | using assms 33 | apply(clarsimp simp: hb.concurrent_ops_commute_def) 34 | apply(rename_tac a b x y) 35 | apply(case_tac b; case_tac y; force simp add: interp_msg_def kleisli_def) 36 | done 37 | 38 | corollary (in counter) counter_convergence: 39 | assumes "set (node_deliver_messages xs) = set (node_deliver_messages ys)" 40 | and "xs prefix of i" 41 | and "ys prefix of j" 42 | shows "apply_operations xs = apply_operations ys" 43 | using assms by(auto simp add: apply_operations_def intro: hb.convergence_ext 44 | concurrent_operations_commute node_deliver_messages_distinct hb_consistent_prefix) 45 | 46 | context counter begin 47 | 48 | sublocale sec: strong_eventual_consistency weak_hb hb interp_msg 49 | "\ops. \xs i. xs prefix of i \ node_deliver_messages xs = ops" 0 50 | apply(standard; clarsimp simp add: hb_consistent_prefix drop_last_message 51 | node_deliver_messages_distinct concurrent_operations_commute) 52 | apply(metis (full_types) interp_msg_def counter_op.elims) 53 | using drop_last_message apply blast 54 | done 55 | 56 | end 57 | end -------------------------------------------------------------------------------- /src/Counter.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Increment-Decrement Counter\ 8 | 9 | text\The Increment-Decrement Counter is perhaps the simplest CRDT, and a paradigmatic example of a 10 | replicated data structure with commutative operations.\ 11 | 12 | theory 13 | Counter 14 | imports 15 | Network 16 | begin 17 | 18 | datatype operation = Increment | Decrement 19 | 20 | fun counter_op :: "operation \ int \ int" where 21 | "counter_op Increment x = Some (x + 1)" | 22 | "counter_op Decrement x = Some (x - 1)" 23 | 24 | locale counter = network_with_ops _ counter_op 0 25 | 26 | lemma (in counter) "counter_op x \ counter_op y = counter_op y \ counter_op x" 27 | by(case_tac x; case_tac y; auto simp add: kleisli_def) 28 | 29 | lemma (in counter) concurrent_operations_commute: 30 | assumes "xs prefix of i" 31 | shows "hb.concurrent_ops_commute (node_deliver_messages xs)" 32 | using assms 33 | apply(clarsimp simp: hb.concurrent_ops_commute_def) 34 | apply(rename_tac a b x y) 35 | apply(case_tac b; case_tac y; force simp add: interp_msg_def kleisli_def) 36 | done 37 | 38 | corollary (in counter) counter_convergence: 39 | assumes "set (node_deliver_messages xs) = set (node_deliver_messages ys)" 40 | and "xs prefix of i" 41 | and "ys prefix of j" 42 | shows "apply_operations xs = apply_operations ys" 43 | using assms by(auto simp add: apply_operations_def intro: hb.convergence_ext 44 | concurrent_operations_commute node_deliver_messages_distinct hb_consistent_prefix) 45 | 46 | context counter begin 47 | 48 | sublocale sec: strong_eventual_consistency weak_hb hb interp_msg 49 | "\ops. \xs i. xs prefix of i \ node_deliver_messages xs = ops" 0 50 | apply(standard; clarsimp simp add: hb_consistent_prefix drop_last_message 51 | node_deliver_messages_distinct concurrent_operations_commute) 52 | apply(metis (full_types) interp_msg_def counter_op.elims) 53 | using drop_last_message apply blast 54 | done 55 | 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /src/supplemental/Counter.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Increment-Decrement Counter\ 8 | 9 | text\The Increment-Decrement Counter is perhaps the simplest CRDT, and a paradigmatic example of a 10 | replicated data structure with commutative operations.\ 11 | 12 | theory 13 | Counter 14 | imports 15 | Network 16 | "~~/src/HOL/Library/Code_Target_Numeral" 17 | begin 18 | 19 | datatype operation = Increment | Decrement 20 | 21 | fun counter_op :: "operation \ int \ int" where 22 | "counter_op Increment x = Some (x + 1)" | 23 | "counter_op Decrement x = Some (x - 1)" 24 | 25 | export_code Increment counter_op in OCaml file "ocaml/counter.ml" 26 | 27 | locale counter = network_with_ops _ counter_op 0 28 | 29 | lemma (in counter) "counter_op x \ counter_op y = counter_op y \ counter_op x" 30 | by(case_tac x; case_tac y; auto simp add: kleisli_def) 31 | 32 | lemma (in counter) concurrent_operations_commute: 33 | assumes "xs prefix of i" 34 | shows "hb.concurrent_ops_commute (node_deliver_messages xs)" 35 | using assms 36 | apply(clarsimp simp: hb.concurrent_ops_commute_def) 37 | apply(unfold interp_msg_def, simp) 38 | apply(case_tac "b"; case_tac "ba") 39 | apply(auto simp add: kleisli_def) 40 | done 41 | 42 | corollary (in counter) counter_convergence: 43 | assumes "set (node_deliver_messages xs) = set (node_deliver_messages ys)" 44 | and "xs prefix of i" 45 | and "ys prefix of j" 46 | shows "apply_operations xs = apply_operations ys" 47 | using assms by(auto simp add: apply_operations_def intro: hb.convergence_ext concurrent_operations_commute 48 | node_deliver_messages_distinct hb_consistent_prefix) 49 | 50 | context counter begin 51 | 52 | sublocale sec: strong_eventual_consistency weak_hb hb interp_msg 53 | "\ops. \xs i. xs prefix of i \ node_deliver_messages xs = ops" 0 54 | apply(standard; clarsimp) 55 | apply(auto simp add: hb_consistent_prefix drop_last_message node_deliver_messages_distinct concurrent_operations_commute) 56 | apply(metis (full_types) interp_msg_def counter_op.elims) 57 | using drop_last_message apply blast 58 | done 59 | 60 | end 61 | end -------------------------------------------------------------------------------- /paper/round2.tex: -------------------------------------------------------------------------------- 1 | \documentclass{letter} 2 | \usepackage[margin=1in]{geometry} 3 | \usepackage{url} 4 | \address{OOPSLA Paper \#94: \\ Verifying Strong Eventual Consistency \\ in Distributed Systems} 5 | \signature{The authors} 6 | \begin{document} 7 | \begin{letter}{} 8 | \opening{Dear reviewers,} 9 | 10 | Thank you for your helpful comments on our paper in the first round. 11 | We enclose a revised version and trust that it addresses your comments. 12 | Our changes compared to the last round are as follows: 13 | 14 | \begin{itemize} 15 | \item Our full proof is now published on the Isabelle Archive of Formal Proofs (\url{https://www.isa-afp.org/entries/CRDT.shtml}), and we have referenced it from the paper. 16 | \item As requested by reviewer A, we now back up our claim of flawed proofs of SEC algorithms in the introduction by including a literature reference and a forward reference to Section 8. 17 | \item As requested by reviewer B, we included a brief explanation of the distinction between the $\longrightarrow$ and $\Longrightarrow$ arrows in Isabelle at the bottom of page 5. 18 | It is difficult to explain concisely, because the distinction amounts essentially to an implementation detail of Isabelle, and a full explanation would require several pages of digression into Isabelle's internals. 19 | However, we hope that the brief explanation will nevertheless be useful. 20 | \item Addressing a question by reviewer A, we added the second paragraph of Section 5.2 to explain why our network uses a broadcast abstraction, and to outline how it is often implemented in practice (as an overlay network atop unicast TCP). 21 | \item Reviewer B also suggested discussing the robustness of algorithms to minor variations in infrastructure assumptions, which we have done briefly in the penultimate paragraph of Section 5, on page 14. 22 | \item In Section 8.1 we added the 4th, 5th and 6th paragraphs (top half of page 22) to explain the $\mathit{TP}_1$ and $\mathit{TP}_2$ properties, as requested by reviewer A. 23 | \item Following on from reviewer A's comment on Jepsen testing, we added a final paragraph to Section 9 to explain that the purpose of generating executable OCaml code is not to perform an empirical evaluation, but merely to demonstrate that we have not used any uncomputable functions. 24 | \item We have made the inline Isabelle code snippets easier to read by making the presentation neater (indentation, spacing, line breaks, font size). 25 | The content of the snippets is unchanged. 26 | \item Improved clarity through minor (semantically neutral) rewordings throughout the paper. 27 | \end{itemize} 28 | 29 | \closing{Regards,} 30 | \end{letter} 31 | \end{document} 32 | -------------------------------------------------------------------------------- /paper/proof-structure.tex: -------------------------------------------------------------------------------- 1 | \begin{tikzpicture}[auto,scale=1.0] 2 | 3 | \tikzstyle{locale}=[draw,anchor=base,minimum width=30pt,text height=8pt,text depth=3pt] 4 | 5 | %\node (preorder) at (0,7.5) [locale] {$\isa{preorder}$}; 6 | \node (hb) at (0,6) [locale] {$\isa{happens-before}$}; 7 | \node (sec) at (0,4) [locale] {$\isa{strong-eventual-consistency}$}; 8 | \node (hist) at (5,6) [locale] {$\isa{node-histories}$}; 9 | \node (network) at (5,5) [locale] {$\isa{network}$}; 10 | \node (causal) at (5,4) [locale] {$\isa{causal-network}$}; 11 | \node (netops) at (5,3) [locale] {$\isa{network-with-ops}$}; 12 | \node (netops2) at (7,1.8) [locale] {$\isa{network-with-constrained-ops}$}; 13 | \node (counter) at (1,0) [locale] {$\isa{counter}$}; 14 | \node (orset) at (3,0) [locale] {$\isa{orset}$}; 15 | \node (rga) at (5,0) [locale] {$\isa{rga}$}; 16 | 17 | \begin{scope}[thick,dotted] 18 | %\path [draw] (-2.5,6.8) -- ( 10,6.8); 19 | \path [draw] (-2.5,0.8) -- ( 10,0.8); 20 | \path [draw] ( 2.8,0.8) -- (2.8,6.8); 21 | \end{scope} 22 | 23 | \begin{scope}[left,text width=5cm,text ragged left,font=\footnotesize] 24 | %\node at (10, 7.2) {Isabelle standard library}; 25 | \node at (10, 6.2) {Network model\\(Section \ref{sect.network})}; 26 | \end{scope} 27 | \begin{scope}[text width=5cm,font=\footnotesize] 28 | \node at (0, 1.4) {Abstract convergence\\(Section \ref{sect.abstract.convergence})}; 29 | \node at (0, 0.2) {Example CRDTs\\(Sections \ref{sect.rga} and \ref{sect.simple.crdts})}; 30 | \end{scope} 31 | 32 | \begin{scope}[>=open triangle 60] 33 | \tikzstyle{every path}=[thick,->] 34 | %\draw (hb) to (preorder); 35 | \draw (sec) to (hb); 36 | \draw (network) to (hist); 37 | \draw (causal) to (network); 38 | \draw (netops) to (causal); 39 | \draw (node cs:name=netops2,angle=164) to [out=90,in=270] (node cs:name=netops, angle=340); 40 | \draw (node cs:name=counter,angle=50) to [out=90,in=270] (node cs:name=netops, angle=200); 41 | \draw (node cs:name=orset, angle=50) to [out=90,in=270] (node cs:name=netops2,angle=191); 42 | \draw (node cs:name=rga, angle=50) to [out=90,in=270] (node cs:name=netops2,angle=210); 43 | \tikzstyle{every path}=[thick,dashed,->] 44 | \draw (node cs:name=causal, angle=160) to [out=90,in=270] (node cs:name=hb, angle=340); 45 | \draw (node cs:name=counter,angle=90) to [out=90,in=270] (node cs:name=sec,angle=210); 46 | \draw (node cs:name=orset, angle=90) to [out=90,in=270] (node cs:name=sec,angle=270); 47 | \draw (node cs:name=rga, angle=90) to [out=90,in=270] (node cs:name=sec,angle=330); 48 | \end{scope} 49 | \end{tikzpicture} 50 | -------------------------------------------------------------------------------- /src/ocaml/counter.ml: -------------------------------------------------------------------------------- 1 | module Arith : sig 2 | type num 3 | type int 4 | val one_int : int 5 | val plus_int : int -> int -> int 6 | val minus_int : int -> int -> int 7 | end = struct 8 | 9 | type num = One | Bit0 of num | Bit1 of num;; 10 | 11 | type int = Zero_int | Pos of num | Neg of num;; 12 | 13 | let rec dup = function Neg n -> Neg (Bit0 n) 14 | | Pos n -> Pos (Bit0 n) 15 | | Zero_int -> Zero_int;; 16 | 17 | let rec uminus_int = function Neg m -> Pos m 18 | | Pos m -> Neg m 19 | | Zero_int -> Zero_int;; 20 | 21 | let rec plus_num 22 | x0 x1 = match x0, x1 with Bit1 m, Bit1 n -> Bit0 (plus_num (plus_num m n) One) 23 | | Bit1 m, Bit0 n -> Bit1 (plus_num m n) 24 | | Bit1 m, One -> Bit0 (plus_num m One) 25 | | Bit0 m, Bit1 n -> Bit1 (plus_num m n) 26 | | Bit0 m, Bit0 n -> Bit0 (plus_num m n) 27 | | Bit0 m, One -> Bit1 m 28 | | One, Bit1 n -> Bit0 (plus_num n One) 29 | | One, Bit0 n -> Bit1 n 30 | | One, One -> Bit0 One;; 31 | 32 | let one_int : int = Pos One;; 33 | 34 | let rec bitM = function One -> One 35 | | Bit0 n -> Bit1 (bitM n) 36 | | Bit1 n -> Bit1 (Bit0 n);; 37 | 38 | let rec sub 39 | x0 x1 = match x0, x1 with Bit0 m, Bit1 n -> minus_int (dup (sub m n)) one_int 40 | | Bit1 m, Bit0 n -> plus_int (dup (sub m n)) one_int 41 | | Bit1 m, Bit1 n -> dup (sub m n) 42 | | Bit0 m, Bit0 n -> dup (sub m n) 43 | | One, Bit1 n -> Neg (Bit0 n) 44 | | One, Bit0 n -> Neg (bitM n) 45 | | Bit1 m, One -> Pos (Bit0 m) 46 | | Bit0 m, One -> Pos (bitM m) 47 | | One, One -> Zero_int 48 | and plus_int k l = match k, l with Neg m, Neg n -> Neg (plus_num m n) 49 | | Neg m, Pos n -> sub n m 50 | | Pos m, Neg n -> sub m n 51 | | Pos m, Pos n -> Pos (plus_num m n) 52 | | Zero_int, l -> l 53 | | k, Zero_int -> k 54 | and minus_int k l = match k, l with Neg m, Neg n -> sub n m 55 | | Neg m, Pos n -> Neg (plus_num m n) 56 | | Pos m, Neg n -> Pos (plus_num m n) 57 | | Pos m, Pos n -> sub m n 58 | | Zero_int, l -> uminus_int l 59 | | k, Zero_int -> k;; 60 | 61 | end;; (*struct Arith*) 62 | 63 | module Counter : sig 64 | type operation = Increment | Decrement 65 | val counter_op : operation -> Arith.int -> Arith.int option 66 | end = struct 67 | 68 | type operation = Increment | Decrement;; 69 | 70 | let rec counter_op 71 | xa0 x = match xa0, x with 72 | Increment, x -> Some (Arith.plus_int x Arith.one_int) 73 | | Decrement, x -> Some (Arith.minus_int x Arith.one_int);; 74 | 75 | end;; (*struct Counter*) 76 | -------------------------------------------------------------------------------- /src/ocaml/network.ml: -------------------------------------------------------------------------------- 1 | open Core.Std 2 | open Async.Std 3 | open Counter.Arith 4 | open Counter.Counter 5 | 6 | exception Error 7 | 8 | let integer_of_int (Int_of_integer k) = k;; 9 | 10 | let state = ref (Int_of_integer Big_int.zero_big_int) 11 | let update = function 12 | | Some s -> state := s 13 | | None -> () 14 | let string_of_state () = Big_int.string_of_big_int (integer_of_int !state) 15 | 16 | let choose_msg () = 17 | match Random.int 2 with 18 | | 0 -> "inc" 19 | | 1 -> "dec" 20 | | _ -> raise Error 21 | 22 | let log id = 23 | let str = "Node " ^ string_of_int id ^ ": " ^ string_of_state () in 24 | print_endline str 25 | 26 | let broadcast hps m = 27 | let send m (h, p) = 28 | try_with (fun () -> 29 | Tcp.connect (Tcp.to_host_and_port h p) 30 | >>= fun (_, _, w) -> 31 | (*print_endline ("Send to: " ^ h ^ ":" ^ string_of_int p ^ ": " ^ m);*) 32 | return (Writer.write_line w m) 33 | ) >>= return 34 | in 35 | List.iter hps ~f:(fun hp -> ignore (send m hp)) 36 | 37 | let random_msg hps = 38 | Clock.every (sec (Random.float 5.0)) 39 | (fun () -> broadcast hps (choose_msg ())) 40 | 41 | let rec deliver id hps r = 42 | let update_state op = update (counter_op op !state) in 43 | let update_state res = 44 | match res with 45 | | `Ok m -> 46 | (*print_endline ("Deliver " ^ string_of_int id ^ ": " ^ m);*) 47 | begin match m with 48 | | "inc" -> update_state Increment 49 | | "dec" -> update_state Decrement 50 | | "log" -> log id 51 | | "showall" -> broadcast hps "log" 52 | | s -> print_endline ("Unknown action: " ^ s) 53 | end 54 | | `Eof -> () 55 | in 56 | Reader.read_line r 57 | >>= fun res -> 58 | update_state res; 59 | deliver id hps r 60 | 61 | let get_host_and_port nodes = 62 | let list_to_hp = function 63 | | [a; b] -> (a, int_of_string b) 64 | | _ -> raise Error 65 | in 66 | let hps = String.split_on_chars ~on:[';'] nodes in 67 | List.map hps ~f: 68 | begin fun node -> 69 | String.split_on_chars ~on:[':'] node 70 | |> list_to_hp 71 | end 72 | 73 | let run ~id ~port ~nodes = 74 | let hps = get_host_and_port nodes in 75 | let host_and_port = 76 | Tcp.Server.create 77 | ~on_handler_error:`Raise 78 | (Tcp.on_port port) 79 | (fun _ r _ -> deliver id hps r) 80 | in 81 | ignore host_and_port; 82 | ignore (random_msg hps); 83 | Deferred.never() 84 | 85 | let () = 86 | Command.async 87 | ~summary:"Start a test node" 88 | Command.Spec.( 89 | empty 90 | +> flag "-id" (required int) 91 | ~doc:" Node id" 92 | +> flag "-port" (required int) 93 | ~doc:" Node port" 94 | +> flag "-nodes" (required string) 95 | ~doc:" Other nodes in the network" 96 | ) 97 | (fun id port nodes () -> run ~id ~port ~nodes) 98 | |> Command.run -------------------------------------------------------------------------------- /src/supplemental/ocaml/network.ml: -------------------------------------------------------------------------------- 1 | open Core.Std 2 | open Async.Std 3 | open Counter.Arith 4 | open Counter.Counter 5 | 6 | exception Error 7 | 8 | let integer_of_int (Int_of_integer k) = k;; 9 | 10 | let state = ref (Int_of_integer Big_int.zero_big_int) 11 | let update = function 12 | | Some s -> state := s 13 | | None -> () 14 | let string_of_state () = Big_int.string_of_big_int (integer_of_int !state) 15 | 16 | let choose_msg () = 17 | match Random.int 2 with 18 | | 0 -> "inc" 19 | | 1 -> "dec" 20 | | _ -> raise Error 21 | 22 | let log id = 23 | let str = "Node " ^ string_of_int id ^ ": " ^ string_of_state () in 24 | print_endline str 25 | 26 | let broadcast hps m = 27 | let send m (h, p) = 28 | try_with (fun () -> 29 | Tcp.connect (Tcp.to_host_and_port h p) 30 | >>= fun (_, _, w) -> 31 | (*print_endline ("Send to: " ^ h ^ ":" ^ string_of_int p ^ ": " ^ m);*) 32 | return (Writer.write_line w m) 33 | ) >>= return 34 | in 35 | List.iter hps ~f:(fun hp -> ignore (send m hp)) 36 | 37 | let random_msg hps = 38 | Clock.every (sec (Random.float 5.0)) 39 | (fun () -> broadcast hps (choose_msg ())) 40 | 41 | let rec deliver id hps r = 42 | let update_state op = update (counter_op op !state) in 43 | let update_state res = 44 | match res with 45 | | `Ok m -> 46 | (*print_endline ("Deliver " ^ string_of_int id ^ ": " ^ m);*) 47 | begin match m with 48 | | "inc" -> update_state Increment 49 | | "dec" -> update_state Decrement 50 | | "log" -> log id 51 | | "showall" -> broadcast hps "log" 52 | | s -> print_endline ("Unknown action: " ^ s) 53 | end 54 | | `Eof -> () 55 | in 56 | Reader.read_line r 57 | >>= fun res -> 58 | update_state res; 59 | deliver id hps r 60 | 61 | let get_host_and_port nodes = 62 | let list_to_hp = function 63 | | [a; b] -> (a, int_of_string b) 64 | | _ -> raise Error 65 | in 66 | let hps = String.split_on_chars ~on:[';'] nodes in 67 | List.map hps ~f: 68 | begin fun node -> 69 | String.split_on_chars ~on:[':'] node 70 | |> list_to_hp 71 | end 72 | 73 | let run ~id ~port ~nodes = 74 | let hps = get_host_and_port nodes in 75 | let host_and_port = 76 | Tcp.Server.create 77 | ~on_handler_error:`Raise 78 | (Tcp.on_port port) 79 | (fun _ r _ -> deliver id hps r) 80 | in 81 | ignore host_and_port; 82 | ignore (random_msg hps); 83 | Deferred.never() 84 | 85 | let () = 86 | Command.async 87 | ~summary:"Start a test node" 88 | Command.Spec.( 89 | empty 90 | +> flag "-id" (required int) 91 | ~doc:" Node id" 92 | +> flag "-port" (required int) 93 | ~doc:" Node port" 94 | +> flag "-nodes" (required string) 95 | ~doc:" Other nodes in the network" 96 | ) 97 | (fun id port nodes () -> run ~id ~port ~nodes) 98 | |> Command.run -------------------------------------------------------------------------------- /paper/author-response.txt: -------------------------------------------------------------------------------- 1 | We thank the reviewers for their reading of the paper and helpful suggestions. 2 | 3 | Reviewer A found Section 1 misleading, noted missing citations, and also 4 | suggested we expand discussion of TP1 and TP2. We will fix all of these points. 5 | Briefly, TP1 and TP2 are defined as follows: 6 | 7 | Given two concurrent operations $x$ and $y$ that modify the same initial state, 8 | TP1 requires that $y$ can be transformed into an operation $y'$ that performs an 9 | equivalent modification on a state where $x$ has already been applied, and vice 10 | versa, such that $x \circ y' = y \circ x'$. When all operations are sequenced 11 | through a central server, TP1 is sufficient to allow a client to reorder its 12 | operations with respect to the server's operation sequence. 13 | 14 | If there are three concurrent operations $x$, $y$, and $z$ that modify the same 15 | initial state, and those operations can be applied in any order, TP1 does 16 | not suffice. TP2 requires that if transformations of $x$ and $y$ are applied in 17 | either order, the same transformation of $z$ can be applied to the result: 18 | $x \circ y' \circ z' = y \circ x' \circ z'$. Since transformed operations may 19 | be different from original operations, this property demands much more than just 20 | commutativity, making it difficult to implement correctly. 21 | 22 | Reviewer A asks why our network model uses message broadcast rather than 23 | unicast. The reason is that full replication requires every change to be sent to 24 | every node, which is naturally modelled as a broadcast abstraction. Broadcast 25 | can be implemented on top of unicast using well-known network protocols (Cachin 26 | et al.) 27 | 28 | Reviewer A also asks about our OCaml extraction. At present we have not used 29 | Jepsen or similar testing tools, leaving this to future work. Our primary focus 30 | in this work was algorithm correctness, rather than empirical analysis, or even 31 | implementation correctness. The OCaml extraction demonstrates that our 32 | definitions are "reasonable": Isabelle allows the user to define uncomputable 33 | functions, and extracting executable code guards against this problem. We will 34 | clarify this point in the paper. 35 | 36 | Reviewer B suggests that it may be informative to show an example of how an 37 | attempted proof of a faulty algorithm goes wrong. This is easily achieved, but 38 | it is not clear what lesson can be drawn from this. We could briefly mention 39 | Isabelle's counterexample checker, and show how Isabelle can automatically spot 40 | faulty theorem statements, however. 41 | 42 | Reviewer B asks about variations in the assumed network axioms. We believe that 43 | there is a degree of flexibility here, as one can implement stronger properties 44 | on top of weak networks: for example the msg-id-unique and histories-distinct 45 | axioms can be implemented using sequence numbers, making those axioms 46 | unnecessary. We plan to explore this reduction of axioms in future work. 47 | However, the read-your-own-writes property mentioned by the reviewer is, we 48 | believe, necessary for the correct functioning of our CRDTs. 49 | 50 | Reviewer B also asks about the distinction between arrows in Isabelle. We will 51 | explain this aspect as they are indeed confusing. 52 | -------------------------------------------------------------------------------- /paper/happens-before.tex: -------------------------------------------------------------------------------- 1 | \begin{tikzpicture}[auto,scale=1.35] 2 | 3 | \tikzstyle{event}=[circle,fill,minimum size=2pt] 4 | \tikzstyle{label}=[text height=8pt,text depth=3pt] 5 | \tikzstyle{leftlabel}=[label,left=3pt] 6 | \tikzstyle{rightlabel}=[label,right=3pt] 7 | \tikzstyle{every path}=[thick,->] 8 | \tikzstyle{caption}=[text width=4cm,text centered,text height=8pt,below=5pt] 9 | 10 | \node [label] (i1name) at (0,2.5) {Node $i$:}; 11 | \node [label] (j1name) at (1,2.5) {Node $j$:}; 12 | \node [event] (op1send) at (0,2.0) {}; 13 | \node [event] (op1recv) at (1,1.5) {}; 14 | \node [event] (op2send) at (0,1.0) {}; 15 | \node [event] (op2recv) at (1,0.5) {}; 16 | \node [leftlabel] at (0,2.0) {$\isa{m1}$}; 17 | \node [rightlabel] at (1,1.5) {$\isa{m1}$}; 18 | \node [leftlabel] at (0,1.0) {$\isa{m2}$}; 19 | \node [rightlabel] at (1,0.5) {$\isa{m2}$}; 20 | \draw (i1name) -- (0,0) node [left=5pt,at end] {\footnotesize time}; 21 | \draw (j1name) -- (1,0); 22 | \draw (op1send) -- (op1recv); 23 | \draw (op2send) -- (op2recv); 24 | \node [caption] at (0.5,0) { 25 | $\isa{m1} \prec \isa{m2}$ 26 | because node $i$ broadcast $\isa{m1}$ before $\isa{m2}$ 27 | }; 28 | 29 | \node [label] (i2name) at (3,2.5) {Node $i$:}; 30 | \node [label] (j2name) at (4,2.5) {Node $j$:}; 31 | \node [label] (k2name) at (5,2.5) {Node $k$:}; 32 | \node [event] (op3send) at (3,2.0) {}; 33 | \node [event] (op3recj) at (4,1.5) {}; 34 | \node [event] (op3reck) at (5,1.5) {}; 35 | \node [event] (op4send) at (4,1.0) {}; 36 | \node [event] (op4reck) at (5,0.5) {}; 37 | \node [leftlabel] at (3,2.0) {$\isa{m1}$}; 38 | \node [rightlabel] at (5,1.5) {$\isa{m1}$}; 39 | \node [leftlabel] at (4,1.0) {$\isa{m2}$}; 40 | \node [rightlabel] at (5,0.5) {$\isa{m2}$}; 41 | \draw (i2name) -- (3,0); 42 | \draw (j2name) -- (4,0); 43 | \draw (k2name) -- (5,0); 44 | \draw (op3send) -- (op3recj); 45 | \draw (op3send) -- (op3reck); 46 | \draw (op4send) -- (op4reck); 47 | \node [caption] at (4.0,0) { 48 | $\isa{m1} \prec \isa{m2}$ 49 | because node $j$ delivered $\isa{m1}$ before broadcasting $\isa{m2}$ 50 | }; 51 | 52 | \node [label] (i3name) at (7,2.5) {Node $i$:}; 53 | \node [label] (j3name) at (8,2.5) {Node $j$:}; 54 | \node [label] (k3name) at (9,2.5) {Node $k$:}; 55 | \node [label] (m3name) at (10,2.5) {Node $m$:}; 56 | \node [event] (op5send) at (7,2.0) {}; 57 | \node [event] (op5recj) at (8,1.7) {}; 58 | \node [event] (op5recm) at (10,1.7) {}; 59 | \node [event] (op6send) at (8,1.4) {}; 60 | \node [event] (op6reck) at (9,1.1) {}; 61 | \node [event] (op6recm) at (10,1.1) {}; 62 | \node [event] (op7send) at (9,0.8) {}; 63 | \node [event] (op7recm) at (10,0.5) {}; 64 | \node [leftlabel] at (7,2.0) {$\isa{m1}$}; 65 | \node [rightlabel] at (10,1.7) {$\isa{m1}$}; 66 | \node [leftlabel] at (8,1.4) {$\isa{m2}$}; 67 | \node [rightlabel] at (10,1.1) {$\isa{m2}$}; 68 | \node [leftlabel] at (9,0.8) {$\isa{m3}$}; 69 | \node [rightlabel] at (10,0.5) {$\isa{m3}$}; 70 | \draw (i3name) -- (7,0); 71 | \draw (j3name) -- (8,0); 72 | \draw (k3name) -- (9,0); 73 | \draw (m3name) -- (10,0); 74 | \draw (op5send) -- (op5recj); 75 | \draw (op5send) -- (op5recm); 76 | \draw (op6send) -- (op6reck); 77 | \draw (op6send) -- (op6recm); 78 | \draw (op7send) -- (op7recm); 79 | \node [caption] at (8.5,0) { 80 | $\isa{m1} \prec \isa{m3}$ because 81 | $\isa{m1} \prec \isa{m2}$ and 82 | $\isa{m2} \prec \isa{m3}$ 83 | }; 84 | 85 | \end{tikzpicture} 86 | -------------------------------------------------------------------------------- /talks/rems-march-2017/beamerthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerthememetropolis} 21 | [2016/03/14 v1.1 Metropolis Beamer theme] 22 | \RequirePackage{etoolbox} 23 | \RequirePackage{pgfopts} 24 | \pgfkeys{/metropolis/.cd, 25 | .search also={ 26 | /metropolis/inner, 27 | /metropolis/outer, 28 | /metropolis/color, 29 | /metropolis/font, 30 | } 31 | } 32 | \pgfkeys{ 33 | /metropolis/titleformat plain/.cd, 34 | .is choice, 35 | regular/.code={% 36 | \let\metropolis@plaintitleformat\@empty% 37 | \setbeamerfont{standout}{shape=\normalfont}% 38 | }, 39 | smallcaps/.code={% 40 | \let\metropolis@plaintitleformat\@empty% 41 | \setbeamerfont{standout}{shape=\scshape}% 42 | }, 43 | allsmallcaps/.code={% 44 | \let\metropolis@plaintitleformat\MakeLowercase% 45 | \setbeamerfont{standout}{shape=\scshape}% 46 | \PackageWarning{beamerthememetropolis}{% 47 | Be aware that titleformat plain=allsmallcaps can lead to problems% 48 | } 49 | }, 50 | allcaps/.code={% 51 | \let\metropolis@plaintitleformat\MakeUppercase% 52 | \setbeamerfont{standout}{shape=\normalfont}% 53 | \PackageWarning{beamerthememetropolis}{% 54 | Be aware that titleformat plain=allcaps can lead to problems% 55 | } 56 | }, 57 | } 58 | \pgfkeys{ 59 | /metropolis/titleformat/.code=\pgfkeysalso{ 60 | font/titleformat title=#1, 61 | font/titleformat subtitle=#1, 62 | font/titleformat section=#1, 63 | font/titleformat frame=#1, 64 | titleformat plain=#1, 65 | } 66 | } 67 | \pgfkeys{/metropolis/.cd, 68 | usetitleprogressbar/.code=\pgfkeysalso{outer/progressbar=frametitle}, 69 | noslidenumbers/.code=\pgfkeysalso{outer/numbering=none}, 70 | usetotalslideindicator/.code=\pgfkeysalso{outer/numbering=fraction}, 71 | nosectionslide/.code=\pgfkeysalso{inner/sectionpage=none}, 72 | darkcolors/.code=\pgfkeysalso{color/background=dark}, 73 | blockbg/.code=\pgfkeysalso{color/block=fill, inner/block=fill}, 74 | } 75 | \newcommand{\metropolis@setdefaults}{ 76 | \pgfkeys{/metropolis/.cd, 77 | titleformat plain=regular, 78 | } 79 | } 80 | \useinnertheme{metropolis} 81 | \useoutertheme{metropolis} 82 | \usecolortheme{metropolis} 83 | \usefonttheme{metropolis} 84 | \AtEndPreamble{% 85 | \@ifpackageloaded{pgfplots}{% 86 | \RequirePackage{pgfplotsthemetol} 87 | }{} 88 | } 89 | \newcommand{\metroset}[1]{\pgfkeys{/metropolis/.cd,#1}} 90 | \def\metropolis@plaintitleformat#1{#1} 91 | \newcommand{\plain}[2][]{% 92 | \PackageWarning{beamerthememetropolis}{% 93 | The syntax `\plain' may be deprecated in a future version of Metropolis. 94 | Please use a frame with [standout] instead. 95 | } 96 | \begin{frame}[standout]{#1} 97 | \metropolis@plaintitleformat{#2} 98 | \end{frame} 99 | } 100 | \newcommand{\mreducelistspacing}{\vspace{-\topsep}} 101 | \metropolis@setdefaults 102 | \ProcessPgfOptions{/metropolis} 103 | \endinput 104 | %% 105 | %% End of file `beamerthememetropolis.sty'. 106 | -------------------------------------------------------------------------------- /talks/srepls-may-2017/beamerthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerthememetropolis} 21 | [2016/03/14 v1.1 Metropolis Beamer theme] 22 | \RequirePackage{etoolbox} 23 | \RequirePackage{pgfopts} 24 | \pgfkeys{/metropolis/.cd, 25 | .search also={ 26 | /metropolis/inner, 27 | /metropolis/outer, 28 | /metropolis/color, 29 | /metropolis/font, 30 | } 31 | } 32 | \pgfkeys{ 33 | /metropolis/titleformat plain/.cd, 34 | .is choice, 35 | regular/.code={% 36 | \let\metropolis@plaintitleformat\@empty% 37 | \setbeamerfont{standout}{shape=\normalfont}% 38 | }, 39 | smallcaps/.code={% 40 | \let\metropolis@plaintitleformat\@empty% 41 | \setbeamerfont{standout}{shape=\scshape}% 42 | }, 43 | allsmallcaps/.code={% 44 | \let\metropolis@plaintitleformat\MakeLowercase% 45 | \setbeamerfont{standout}{shape=\scshape}% 46 | \PackageWarning{beamerthememetropolis}{% 47 | Be aware that titleformat plain=allsmallcaps can lead to problems% 48 | } 49 | }, 50 | allcaps/.code={% 51 | \let\metropolis@plaintitleformat\MakeUppercase% 52 | \setbeamerfont{standout}{shape=\normalfont}% 53 | \PackageWarning{beamerthememetropolis}{% 54 | Be aware that titleformat plain=allcaps can lead to problems% 55 | } 56 | }, 57 | } 58 | \pgfkeys{ 59 | /metropolis/titleformat/.code=\pgfkeysalso{ 60 | font/titleformat title=#1, 61 | font/titleformat subtitle=#1, 62 | font/titleformat section=#1, 63 | font/titleformat frame=#1, 64 | titleformat plain=#1, 65 | } 66 | } 67 | \pgfkeys{/metropolis/.cd, 68 | usetitleprogressbar/.code=\pgfkeysalso{outer/progressbar=frametitle}, 69 | noslidenumbers/.code=\pgfkeysalso{outer/numbering=none}, 70 | usetotalslideindicator/.code=\pgfkeysalso{outer/numbering=fraction}, 71 | nosectionslide/.code=\pgfkeysalso{inner/sectionpage=none}, 72 | darkcolors/.code=\pgfkeysalso{color/background=dark}, 73 | blockbg/.code=\pgfkeysalso{color/block=fill, inner/block=fill}, 74 | } 75 | \newcommand{\metropolis@setdefaults}{ 76 | \pgfkeys{/metropolis/.cd, 77 | titleformat plain=regular, 78 | } 79 | } 80 | \useinnertheme{metropolis} 81 | \useoutertheme{metropolis} 82 | \usecolortheme{metropolis} 83 | \usefonttheme{metropolis} 84 | \AtEndPreamble{% 85 | \@ifpackageloaded{pgfplots}{% 86 | \RequirePackage{pgfplotsthemetol} 87 | }{} 88 | } 89 | \newcommand{\metroset}[1]{\pgfkeys{/metropolis/.cd,#1}} 90 | \def\metropolis@plaintitleformat#1{#1} 91 | \newcommand{\plain}[2][]{% 92 | \PackageWarning{beamerthememetropolis}{% 93 | The syntax `\plain' may be deprecated in a future version of Metropolis. 94 | Please use a frame with [standout] instead. 95 | } 96 | \begin{frame}[standout]{#1} 97 | \metropolis@plaintitleformat{#2} 98 | \end{frame} 99 | } 100 | \newcommand{\mreducelistspacing}{\vspace{-\topsep}} 101 | \metropolis@setdefaults 102 | \ProcessPgfOptions{/metropolis} 103 | \endinput 104 | %% 105 | %% End of file `beamerthememetropolis.sty'. 106 | -------------------------------------------------------------------------------- /talks/rems-march-2017/beamercolorthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamercolorthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamercolorthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamercolorthememetropolis}[2016/03/14 Metropolis color theme] 21 | \RequirePackage{pgfopts} 22 | \pgfkeys{ 23 | /metropolis/color/block/.cd, 24 | .is choice, 25 | transparent/.code=\metropolis@block@transparent, 26 | fill/.code=\metropolis@block@fill, 27 | } 28 | \pgfkeys{ 29 | /metropolis/color/background/.cd, 30 | .is choice, 31 | dark/.code=\metropolis@colors@dark, 32 | light/.code=\metropolis@colors@light, 33 | } 34 | \newcommand{\metropolis@color@setdefaults}{ 35 | \pgfkeys{/metropolis/color/.cd, 36 | background=light, 37 | block=transparent, 38 | } 39 | } 40 | \definecolor{mDarkBrown}{HTML}{604c38} 41 | \definecolor{mDarkTeal}{HTML}{23373b} 42 | \definecolor{mLightBrown}{HTML}{EB811B} 43 | \definecolor{mLightGreen}{HTML}{14B03D} 44 | \newcommand{\metropolis@colors@dark}{ 45 | \setbeamercolor{normal text}{% 46 | fg=black!2, 47 | bg=mDarkTeal 48 | } 49 | \usebeamercolor[fg]{normal text} 50 | } 51 | \newcommand{\metropolis@colors@light}{ 52 | \setbeamercolor{normal text}{% 53 | fg=mDarkTeal, 54 | bg=black!2 55 | } 56 | } 57 | \setbeamercolor{alerted text}{% 58 | fg=mLightBrown 59 | } 60 | \setbeamercolor{example text}{% 61 | fg=mLightGreen 62 | } 63 | \setbeamercolor{titlelike}{use=normal text, parent=normal text} 64 | \setbeamercolor{author}{use=normal text, parent=normal text} 65 | \setbeamercolor{date}{use=normal text, parent=normal text} 66 | \setbeamercolor{institute}{use=normal text, parent=normal text} 67 | \setbeamercolor{structure}{use=normal text, fg=normal text.fg} 68 | \setbeamercolor{palette primary}{% 69 | use=normal text, 70 | fg=normal text.bg, 71 | bg=normal text.fg 72 | } 73 | \setbeamercolor{frametitle}{% 74 | use=palette primary, 75 | parent=palette primary 76 | } 77 | \setbeamercolor{progress bar}{% 78 | use=alerted text, 79 | fg=alerted text.fg, 80 | bg=alerted text.fg!50!black!30 81 | } 82 | \setbeamercolor{title separator}{ 83 | use=progress bar, 84 | parent=progress bar 85 | } 86 | \setbeamercolor{progress bar in head/foot}{% 87 | use=progress bar, 88 | parent=progress bar 89 | } 90 | \setbeamercolor{progress bar in section page}{ 91 | use=progress bar, 92 | parent=progress bar 93 | } 94 | \newcommand{\metropolis@block@transparent}{ 95 | \setbeamercolor{block title}{% 96 | use=normal text, 97 | fg=normal text.fg, 98 | bg= 99 | } 100 | \setbeamercolor{block body}{ 101 | bg= 102 | } 103 | } 104 | \newcommand{\metropolis@block@fill}{ 105 | \setbeamercolor{block title}{% 106 | use=normal text, 107 | fg=normal text.fg, 108 | bg=normal text.bg!80!fg 109 | } 110 | \setbeamercolor{block body}{ 111 | use={block title, normal text}, 112 | bg=block title.bg!50!normal text.bg 113 | } 114 | } 115 | \setbeamercolor{block title alerted}{% 116 | use={block title, alerted text}, 117 | bg=block title.bg, 118 | fg=alerted text.fg 119 | } 120 | \setbeamercolor{block title example}{% 121 | use={block title, example text}, 122 | bg=block title.bg, 123 | fg=example text.fg 124 | } 125 | \setbeamercolor{block body alerted}{use=block body, parent=block body} 126 | \setbeamercolor{block body example}{use=block body, parent=block body} 127 | \setbeamercolor{footnote}{fg=normal text.fg!90} 128 | \setbeamercolor{footnote mark}{fg=.} 129 | \metropolis@color@setdefaults 130 | \ProcessPgfPackageOptions{/metropolis/color} 131 | \mode 132 | \endinput 133 | %% 134 | %% End of file `beamercolorthememetropolis.sty'. 135 | -------------------------------------------------------------------------------- /talks/srepls-may-2017/beamercolorthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamercolorthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamercolorthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamercolorthememetropolis}[2016/03/14 Metropolis color theme] 21 | \RequirePackage{pgfopts} 22 | \pgfkeys{ 23 | /metropolis/color/block/.cd, 24 | .is choice, 25 | transparent/.code=\metropolis@block@transparent, 26 | fill/.code=\metropolis@block@fill, 27 | } 28 | \pgfkeys{ 29 | /metropolis/color/background/.cd, 30 | .is choice, 31 | dark/.code=\metropolis@colors@dark, 32 | light/.code=\metropolis@colors@light, 33 | } 34 | \newcommand{\metropolis@color@setdefaults}{ 35 | \pgfkeys{/metropolis/color/.cd, 36 | background=light, 37 | block=transparent, 38 | } 39 | } 40 | \definecolor{mDarkBrown}{HTML}{604c38} 41 | \definecolor{mDarkTeal}{HTML}{23373b} 42 | \definecolor{mLightBrown}{HTML}{EB811B} 43 | \definecolor{mLightGreen}{HTML}{14B03D} 44 | \newcommand{\metropolis@colors@dark}{ 45 | \setbeamercolor{normal text}{% 46 | fg=black!2, 47 | bg=mDarkTeal 48 | } 49 | \usebeamercolor[fg]{normal text} 50 | } 51 | \newcommand{\metropolis@colors@light}{ 52 | \setbeamercolor{normal text}{% 53 | fg=mDarkTeal, 54 | bg=black!2 55 | } 56 | } 57 | \setbeamercolor{alerted text}{% 58 | fg=mLightBrown 59 | } 60 | \setbeamercolor{example text}{% 61 | fg=mLightGreen 62 | } 63 | \setbeamercolor{titlelike}{use=normal text, parent=normal text} 64 | \setbeamercolor{author}{use=normal text, parent=normal text} 65 | \setbeamercolor{date}{use=normal text, parent=normal text} 66 | \setbeamercolor{institute}{use=normal text, parent=normal text} 67 | \setbeamercolor{structure}{use=normal text, fg=normal text.fg} 68 | \setbeamercolor{palette primary}{% 69 | use=normal text, 70 | fg=normal text.bg, 71 | bg=normal text.fg 72 | } 73 | \setbeamercolor{frametitle}{% 74 | use=palette primary, 75 | parent=palette primary 76 | } 77 | \setbeamercolor{progress bar}{% 78 | use=alerted text, 79 | fg=alerted text.fg, 80 | bg=alerted text.fg!50!black!30 81 | } 82 | \setbeamercolor{title separator}{ 83 | use=progress bar, 84 | parent=progress bar 85 | } 86 | \setbeamercolor{progress bar in head/foot}{% 87 | use=progress bar, 88 | parent=progress bar 89 | } 90 | \setbeamercolor{progress bar in section page}{ 91 | use=progress bar, 92 | parent=progress bar 93 | } 94 | \newcommand{\metropolis@block@transparent}{ 95 | \setbeamercolor{block title}{% 96 | use=normal text, 97 | fg=normal text.fg, 98 | bg= 99 | } 100 | \setbeamercolor{block body}{ 101 | bg= 102 | } 103 | } 104 | \newcommand{\metropolis@block@fill}{ 105 | \setbeamercolor{block title}{% 106 | use=normal text, 107 | fg=normal text.fg, 108 | bg=normal text.bg!80!fg 109 | } 110 | \setbeamercolor{block body}{ 111 | use={block title, normal text}, 112 | bg=block title.bg!50!normal text.bg 113 | } 114 | } 115 | \setbeamercolor{block title alerted}{% 116 | use={block title, alerted text}, 117 | bg=block title.bg, 118 | fg=alerted text.fg 119 | } 120 | \setbeamercolor{block title example}{% 121 | use={block title, example text}, 122 | bg=block title.bg, 123 | fg=example text.fg 124 | } 125 | \setbeamercolor{block body alerted}{use=block body, parent=block body} 126 | \setbeamercolor{block body example}{use=block body, parent=block body} 127 | \setbeamercolor{footnote}{fg=normal text.fg!90} 128 | \setbeamercolor{footnote mark}{fg=.} 129 | \metropolis@color@setdefaults 130 | \ProcessPgfPackageOptions{/metropolis/color} 131 | \mode 132 | \endinput 133 | %% 134 | %% End of file `beamercolorthememetropolis.sty'. 135 | -------------------------------------------------------------------------------- /paper/rga-example.tex: -------------------------------------------------------------------------------- 1 | \begin{tikzpicture}[auto,scale=1.0] 2 | \onehalfspacing 3 | \path [draw,dotted] (2.5,-0.5) -- (2.5,17.5); 4 | 5 | \tikzstyle{initstate}=[rectangle,draw,inner xsep=6pt,text height=8pt,text depth=3pt] 6 | \tikzstyle{state}=[matrix,column sep={30pt,between origins}] 7 | \tikzstyle{val}=[draw,anchor=base,minimum width=30pt,text height=8pt,text depth=3pt] 8 | \tikzstyle{oid}=[anchor=base] 9 | \tikzstyle{leftevent}=[left,text width=5cm,text ragged left,midway] 10 | \tikzstyle{rightevent}=[right,text width=5cm,text ragged,midway] 11 | \tikzstyle{every path}=[thick,->] 12 | 13 | \node (leftR) at (0,17) {Node $j$:}; 14 | \node (left1) at (0,16) [initstate] {initial state (empty list)}; 15 | \node (left2) at (0,12) [state] { 16 | \node [val] {$b$}; \\ 17 | \node [oid] {$(1,j)$}; \\ 18 | }; 19 | \node (left3) at (0,8) [state] { 20 | \node [val] {$a$}; & \node [val] {$b$}; \\ 21 | \node [oid] {$(1,k)$}; & \node [oid] {$(1,j)$}; \\ 22 | }; 23 | \node (left4) at (0,4) [state] { 24 | \node [val] {$a$}; & \node [val] {$x$}; & \node [val] {$b$}; \\ 25 | \node [oid] {$(1,k)$}; & \node [oid] {$(2,j)$}; & \node [oid] {$(1,j)$}; \\ 26 | }; 27 | \node (left5) at (0,0) [state] { 28 | \node [val] {$a$}; & \node [val] {$y$}; & \node [val] {$x$}; & \node [val] {$b$}; \\ 29 | \node [oid] {$(1,k)$}; & \node [oid] {$(2,k)$}; & \node [oid] {$(2,j)$}; & \node [oid] {$(1,j)$}; \\ 30 | }; 31 | 32 | \draw (left1) -- (left2) node (send1j) [leftevent] { 33 | \hfill $\mathit{op}_{1,j} = \mathsf{Insert}((1, j), b, \mathsf{None})$ \\ 34 | \hfill $\text{Broadcast } \mathit{op}_{1,j}$ \\ 35 | \hfill $\text{Deliver } \mathit{op}_{1,j}$ \\ 36 | }; 37 | \draw (left2) -- (left3) node (recv1k) [leftevent] { 38 | \hfill $\text{Deliver } \mathit{op}_{1,k}$ \\ 39 | \hfill $(1,k) > (1,j)$ \\ 40 | }; 41 | \draw (left3) -- (left4) node (send2j) [leftevent] { 42 | \hfill $\mathit{op}_{2,j} = \mathsf{Insert}((2, j), x, \mathsf{Some}(1,k))$ \\ 43 | \hfill $\text{Broadcast } \mathit{op}_{2,j}$ \\ 44 | \hfill $\text{Deliver } \mathit{op}_{2,j}$ \\ 45 | }; 46 | \draw (left4) -- (left5) node (recv2k) [leftevent] { 47 | \hfill $\text{Deliver } \mathit{op}_{2,k}$ \\ 48 | \hfill $(2,k) > (2,j)$ \\ 49 | }; 50 | 51 | \node (rightR) at (5,17) {Node $k$:}; 52 | \node (right1) at (5,16) [initstate] {initial state (empty list)}; 53 | \node (right2) at (5,12) [state] { 54 | \node [val] {$a$}; \\ 55 | \node [oid] {$(1,k)$}; \\ 56 | }; 57 | \node (right3) at (5,8) [state] { 58 | \node [val] {$a$}; & \node [val] {$y$}; \\ 59 | \node [oid] {$(1,k)$}; & \node [oid] {$(2,k)$}; \\ 60 | }; 61 | \node (right4) at (5,4) [state] { 62 | \node [val] {$a$}; & \node [val] {$y$}; & \node [val] {$b$}; \\ 63 | \node [oid] {$(1,k)$}; & \node [oid] {$(2,k)$}; & \node [oid] {$(1,j)$}; \\ 64 | }; 65 | \node (right5) at (5,0) [state] { 66 | \node [val] {$a$}; & \node [val] {$y$}; & \node [val] {$x$}; & \node [val] {$b$}; \\ 67 | \node [oid] {$(1,k)$}; & \node [oid] {$(2,k)$}; & \node [oid] {$(2,j)$}; & \node [oid] {$(1,j)$}; \\ 68 | }; 69 | 70 | \draw (right1) -- (right2) node (send1k) [rightevent] { 71 | $\mathit{op}_{1,k} = \mathsf{Insert}((1, k), a, \mathsf{None})$ \\ 72 | $\text{Broadcast } \mathit{op}_{1,k}$ \\ 73 | $\text{Deliver } \mathit{op}_{1,k}$ \\ 74 | }; 75 | \draw (right2) -- (right3) node (send2k) [rightevent] { 76 | $\mathit{op}_{2,k} = \mathsf{Insert}((2, k), y, \mathsf{Some}(1, k))$ \\ 77 | $\text{Broadcast } \mathit{op}_{2,k}$ \\ 78 | $\text{Deliver } \mathit{op}_{2,k}$ \\ 79 | }; 80 | \draw (right3) -- (right4) node (recv1j) [rightevent] { 81 | $\text{Deliver } \mathit{op}_{1,j}$ \\ 82 | $(1,j) < (1,k)$ \\ 83 | $(1,j) < (2,k)$ \\ 84 | }; 85 | \draw (right4) -- (right5) node (recv2j) [rightevent] { 86 | $\text{Deliver } \mathit{op}_{2,j}$ \\ 87 | $(2,j) < (2,k)$ \\ 88 | $(2,j) > (1,j)$ \\ 89 | }; 90 | 91 | \begin{scope}[dashed,blue] 92 | \tikzstyle{every node}=[text centered] 93 | \draw (send1j.east) to [out=0,in=180] (recv1j.west); 94 | \draw (send2j.east) to [out=0,in=180] (recv2j.west); 95 | \draw (send1k.west) to [out=180,in=0] (recv1k.east); 96 | \draw (send2k.west) to [out=180,in=0] (recv2k.east); 97 | \node at (0.8,14.4) {$\mathit{op}_{1,j}$}; 98 | \node at (0.8, 6.2) {$\mathit{op}_{2,j}$}; 99 | \node at (4.2,14.4) {$\mathit{op}_{1,k}$}; 100 | \node at (4.2,10.2) {$\mathit{op}_{2,k}$}; 101 | \end{scope} 102 | \end{tikzpicture} 103 | -------------------------------------------------------------------------------- /src/ocaml/orset.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal = {equal : 'a -> 'a -> bool} 3 | val equal : 'a equal -> 'a -> 'a -> bool 4 | val eq : 'a equal -> 'a -> 'a -> bool 5 | end = struct 6 | 7 | type 'a equal = {equal : 'a -> 'a -> bool};; 8 | let equal _A = _A.equal;; 9 | 10 | let rec eq _A a b = equal _A a b;; 11 | 12 | end;; (*struct HOL*) 13 | 14 | module Fun : sig 15 | val fun_upd : 'a HOL.equal -> ('a -> 'b) -> 'a -> 'b -> 'a -> 'b 16 | end = struct 17 | 18 | let rec fun_upd _A f a b = (fun x -> (if HOL.eq _A x a then b else f x));; 19 | 20 | end;; (*struct Fun*) 21 | 22 | module List : sig 23 | val fold : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b 24 | val filter : ('a -> bool) -> 'a list -> 'a list 25 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 26 | val insert : 'a HOL.equal -> 'a -> 'a list -> 'a list 27 | val removeAll : 'a HOL.equal -> 'a -> 'a list -> 'a list 28 | val list_all : ('a -> bool) -> 'a list -> bool 29 | end = struct 30 | 31 | let rec fold f x1 s = match f, x1, s with f, x :: xs, s -> fold f xs (f x s) 32 | | f, [], s -> s;; 33 | 34 | let rec filter 35 | p x1 = match p, x1 with p, [] -> [] 36 | | p, x :: xs -> (if p x then x :: filter p xs else filter p xs);; 37 | 38 | let rec member _A x0 y = match x0, y with [], y -> false 39 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 40 | 41 | let rec insert _A x xs = (if member _A xs x then xs else x :: xs);; 42 | 43 | let rec removeAll _A 44 | x xa1 = match x, xa1 with x, [] -> [] 45 | | x, y :: xs -> 46 | (if HOL.eq _A x y then removeAll _A x xs else y :: removeAll _A x xs);; 47 | 48 | let rec list_all p x1 = match p, x1 with p, [] -> true 49 | | p, x :: xs -> p x && list_all p xs;; 50 | 51 | end;; (*struct List*) 52 | 53 | module Set : sig 54 | type 'a set 55 | val equal_set : 'a HOL.equal -> 'a set HOL.equal 56 | val insert : 'a HOL.equal -> 'a -> 'a set -> 'a set 57 | val bot_set : 'a set 58 | val sup_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 59 | val minus_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 60 | end = struct 61 | 62 | type 'a set = Set of 'a list | Coset of 'a list;; 63 | 64 | let rec member _A 65 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 66 | | x, Set xs -> List.member _A xs x;; 67 | 68 | let rec less_eq_set _A 69 | a b = match a, b with Coset [], Set [] -> false 70 | | a, Coset ys -> List.list_all (fun y -> not (member _A y a)) ys 71 | | Set xs, b -> List.list_all (fun x -> member _A x b) xs;; 72 | 73 | let rec equal_seta _A a b = less_eq_set _A a b && less_eq_set _A b a;; 74 | 75 | let rec equal_set _A = ({HOL.equal = equal_seta _A} : 'a set HOL.equal);; 76 | 77 | let rec insert _A 78 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.removeAll _A x xs) 79 | | x, Set xs -> Set (List.insert _A x xs);; 80 | 81 | let rec remove _A 82 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.insert _A x xs) 83 | | x, Set xs -> Set (List.removeAll _A x xs);; 84 | 85 | let bot_set : 'a set = Set [];; 86 | 87 | let rec sup_set _A 88 | x0 a = match x0, a with 89 | Coset xs, a -> Coset (List.filter (fun x -> not (member _A x a)) xs) 90 | | Set xs, a -> List.fold (insert _A) xs a;; 91 | 92 | let rec minus_set _A 93 | a x1 = match a, x1 with 94 | a, Coset xs -> Set (List.filter (fun x -> member _A x a) xs) 95 | | a, Set xs -> List.fold (remove _A) xs a;; 96 | 97 | end;; (*struct Set*) 98 | 99 | module ORSet : sig 100 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b 101 | val interpret_op : 102 | 'a HOL.equal -> 'b HOL.equal -> 103 | ('a, 'b) operation -> ('b -> 'a Set.set) -> ('b -> 'a Set.set) option 104 | val valid_behaviours : 105 | 'b HOL.equal -> ('a -> 'b Set.set) -> 'b * ('b, 'a) operation -> bool 106 | end = struct 107 | 108 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b;; 109 | 110 | let rec op_elem oper = (match oper with Add (_, e) -> e | Rem (_, e) -> e);; 111 | 112 | let rec interpret_op _A _B 113 | oper state = 114 | (let before = state (op_elem oper) in 115 | let after = 116 | (match oper 117 | with Add (i, _) -> Set.sup_set _A before (Set.insert _A i Set.bot_set) 118 | | Rem (is, _) -> Set.minus_set _A before is) 119 | in 120 | Some (Fun.fun_upd _B state (op_elem oper) after));; 121 | 122 | let rec valid_behaviours _B 123 | state msg = 124 | (match msg with (i, Add (j, _)) -> HOL.eq _B i j 125 | | (_, Rem (is, e)) -> HOL.eq (Set.equal_set _B) is (state e));; 126 | 127 | end;; (*struct ORSet*) 128 | -------------------------------------------------------------------------------- /src/AFP/ocaml/orset.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal = {equal : 'a -> 'a -> bool} 3 | val equal : 'a equal -> 'a -> 'a -> bool 4 | val eq : 'a equal -> 'a -> 'a -> bool 5 | end = struct 6 | 7 | type 'a equal = {equal : 'a -> 'a -> bool};; 8 | let equal _A = _A.equal;; 9 | 10 | let rec eq _A a b = equal _A a b;; 11 | 12 | end;; (*struct HOL*) 13 | 14 | module Fun : sig 15 | val fun_upd : 'a HOL.equal -> ('a -> 'b) -> 'a -> 'b -> 'a -> 'b 16 | end = struct 17 | 18 | let rec fun_upd _A f a b = (fun x -> (if HOL.eq _A x a then b else f x));; 19 | 20 | end;; (*struct Fun*) 21 | 22 | module List : sig 23 | val fold : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b 24 | val filter : ('a -> bool) -> 'a list -> 'a list 25 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 26 | val insert : 'a HOL.equal -> 'a -> 'a list -> 'a list 27 | val removeAll : 'a HOL.equal -> 'a -> 'a list -> 'a list 28 | val list_all : ('a -> bool) -> 'a list -> bool 29 | end = struct 30 | 31 | let rec fold f x1 s = match f, x1, s with f, x :: xs, s -> fold f xs (f x s) 32 | | f, [], s -> s;; 33 | 34 | let rec filter 35 | p x1 = match p, x1 with p, [] -> [] 36 | | p, x :: xs -> (if p x then x :: filter p xs else filter p xs);; 37 | 38 | let rec member _A x0 y = match x0, y with [], y -> false 39 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 40 | 41 | let rec insert _A x xs = (if member _A xs x then xs else x :: xs);; 42 | 43 | let rec removeAll _A 44 | x xa1 = match x, xa1 with x, [] -> [] 45 | | x, y :: xs -> 46 | (if HOL.eq _A x y then removeAll _A x xs else y :: removeAll _A x xs);; 47 | 48 | let rec list_all p x1 = match p, x1 with p, [] -> true 49 | | p, x :: xs -> p x && list_all p xs;; 50 | 51 | end;; (*struct List*) 52 | 53 | module Set : sig 54 | type 'a set 55 | val equal_set : 'a HOL.equal -> 'a set HOL.equal 56 | val insert : 'a HOL.equal -> 'a -> 'a set -> 'a set 57 | val bot_set : 'a set 58 | val sup_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 59 | val minus_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 60 | end = struct 61 | 62 | type 'a set = Set of 'a list | Coset of 'a list;; 63 | 64 | let rec member _A 65 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 66 | | x, Set xs -> List.member _A xs x;; 67 | 68 | let rec less_eq_set _A 69 | a b = match a, b with Coset [], Set [] -> false 70 | | a, Coset ys -> List.list_all (fun y -> not (member _A y a)) ys 71 | | Set xs, b -> List.list_all (fun x -> member _A x b) xs;; 72 | 73 | let rec equal_seta _A a b = less_eq_set _A a b && less_eq_set _A b a;; 74 | 75 | let rec equal_set _A = ({HOL.equal = equal_seta _A} : 'a set HOL.equal);; 76 | 77 | let rec insert _A 78 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.removeAll _A x xs) 79 | | x, Set xs -> Set (List.insert _A x xs);; 80 | 81 | let rec remove _A 82 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.insert _A x xs) 83 | | x, Set xs -> Set (List.removeAll _A x xs);; 84 | 85 | let bot_set : 'a set = Set [];; 86 | 87 | let rec sup_set _A 88 | x0 a = match x0, a with 89 | Coset xs, a -> Coset (List.filter (fun x -> not (member _A x a)) xs) 90 | | Set xs, a -> List.fold (insert _A) xs a;; 91 | 92 | let rec minus_set _A 93 | a x1 = match a, x1 with 94 | a, Coset xs -> Set (List.filter (fun x -> member _A x a) xs) 95 | | a, Set xs -> List.fold (remove _A) xs a;; 96 | 97 | end;; (*struct Set*) 98 | 99 | module ORSet : sig 100 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b 101 | val interpret_op : 102 | 'a HOL.equal -> 'b HOL.equal -> 103 | ('a, 'b) operation -> ('b -> 'a Set.set) -> ('b -> 'a Set.set) option 104 | val valid_behaviours : 105 | 'b HOL.equal -> ('a -> 'b Set.set) -> 'b * ('b, 'a) operation -> bool 106 | end = struct 107 | 108 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b;; 109 | 110 | let rec op_elem oper = (match oper with Add (_, e) -> e | Rem (_, e) -> e);; 111 | 112 | let rec interpret_op _A _B 113 | oper state = 114 | (let before = state (op_elem oper) in 115 | let after = 116 | (match oper 117 | with Add (i, _) -> Set.sup_set _A before (Set.insert _A i Set.bot_set) 118 | | Rem (is, _) -> Set.minus_set _A before is) 119 | in 120 | Some (Fun.fun_upd _B state (op_elem oper) after));; 121 | 122 | let rec valid_behaviours _B 123 | state msg = 124 | (match msg with (i, Add (j, _)) -> HOL.eq _B i j 125 | | (_, Rem (is, e)) -> HOL.eq (Set.equal_set _B) is (state e));; 126 | 127 | end;; (*struct ORSet*) 128 | -------------------------------------------------------------------------------- /src/supplemental/ocaml/orset.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal = {equal : 'a -> 'a -> bool} 3 | val equal : 'a equal -> 'a -> 'a -> bool 4 | val eq : 'a equal -> 'a -> 'a -> bool 5 | end = struct 6 | 7 | type 'a equal = {equal : 'a -> 'a -> bool};; 8 | let equal _A = _A.equal;; 9 | 10 | let rec eq _A a b = equal _A a b;; 11 | 12 | end;; (*struct HOL*) 13 | 14 | module Fun : sig 15 | val fun_upd : 'a HOL.equal -> ('a -> 'b) -> 'a -> 'b -> 'a -> 'b 16 | end = struct 17 | 18 | let rec fun_upd _A f a b = (fun x -> (if HOL.eq _A x a then b else f x));; 19 | 20 | end;; (*struct Fun*) 21 | 22 | module List : sig 23 | val fold : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b 24 | val filter : ('a -> bool) -> 'a list -> 'a list 25 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 26 | val insert : 'a HOL.equal -> 'a -> 'a list -> 'a list 27 | val removeAll : 'a HOL.equal -> 'a -> 'a list -> 'a list 28 | val list_all : ('a -> bool) -> 'a list -> bool 29 | end = struct 30 | 31 | let rec fold f x1 s = match f, x1, s with f, x :: xs, s -> fold f xs (f x s) 32 | | f, [], s -> s;; 33 | 34 | let rec filter 35 | p x1 = match p, x1 with p, [] -> [] 36 | | p, x :: xs -> (if p x then x :: filter p xs else filter p xs);; 37 | 38 | let rec member _A x0 y = match x0, y with [], y -> false 39 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 40 | 41 | let rec insert _A x xs = (if member _A xs x then xs else x :: xs);; 42 | 43 | let rec removeAll _A 44 | x xa1 = match x, xa1 with x, [] -> [] 45 | | x, y :: xs -> 46 | (if HOL.eq _A x y then removeAll _A x xs else y :: removeAll _A x xs);; 47 | 48 | let rec list_all p x1 = match p, x1 with p, [] -> true 49 | | p, x :: xs -> p x && list_all p xs;; 50 | 51 | end;; (*struct List*) 52 | 53 | module Set : sig 54 | type 'a set 55 | val equal_set : 'a HOL.equal -> 'a set HOL.equal 56 | val insert : 'a HOL.equal -> 'a -> 'a set -> 'a set 57 | val bot_set : 'a set 58 | val sup_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 59 | val minus_set : 'a HOL.equal -> 'a set -> 'a set -> 'a set 60 | end = struct 61 | 62 | type 'a set = Set of 'a list | Coset of 'a list;; 63 | 64 | let rec member _A 65 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 66 | | x, Set xs -> List.member _A xs x;; 67 | 68 | let rec less_eq_set _A 69 | a b = match a, b with Coset [], Set [] -> false 70 | | a, Coset ys -> List.list_all (fun y -> not (member _A y a)) ys 71 | | Set xs, b -> List.list_all (fun x -> member _A x b) xs;; 72 | 73 | let rec equal_seta _A a b = less_eq_set _A a b && less_eq_set _A b a;; 74 | 75 | let rec equal_set _A = ({HOL.equal = equal_seta _A} : 'a set HOL.equal);; 76 | 77 | let rec insert _A 78 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.removeAll _A x xs) 79 | | x, Set xs -> Set (List.insert _A x xs);; 80 | 81 | let rec remove _A 82 | x xa1 = match x, xa1 with x, Coset xs -> Coset (List.insert _A x xs) 83 | | x, Set xs -> Set (List.removeAll _A x xs);; 84 | 85 | let bot_set : 'a set = Set [];; 86 | 87 | let rec sup_set _A 88 | x0 a = match x0, a with 89 | Coset xs, a -> Coset (List.filter (fun x -> not (member _A x a)) xs) 90 | | Set xs, a -> List.fold (insert _A) xs a;; 91 | 92 | let rec minus_set _A 93 | a x1 = match a, x1 with 94 | a, Coset xs -> Set (List.filter (fun x -> member _A x a) xs) 95 | | a, Set xs -> List.fold (remove _A) xs a;; 96 | 97 | end;; (*struct Set*) 98 | 99 | module ORSet : sig 100 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b 101 | val interpret_op : 102 | 'a HOL.equal -> 'b HOL.equal -> 103 | ('a, 'b) operation -> ('b -> 'a Set.set) -> ('b -> 'a Set.set) option 104 | val valid_behaviours : 105 | 'b HOL.equal -> ('a -> 'b Set.set) -> 'b * ('b, 'a) operation -> bool 106 | end = struct 107 | 108 | type ('a, 'b) operation = Add of 'a * 'b | Rem of 'a Set.set * 'b;; 109 | 110 | let rec op_elem oper = (match oper with Add (_, e) -> e | Rem (_, e) -> e);; 111 | 112 | let rec interpret_op _A _B 113 | oper state = 114 | (let before = state (op_elem oper) in 115 | let after = 116 | (match oper 117 | with Add (i, _) -> Set.sup_set _A before (Set.insert _A i Set.bot_set) 118 | | Rem (is, _) -> Set.minus_set _A before is) 119 | in 120 | Some (Fun.fun_upd _B state (op_elem oper) after));; 121 | 122 | let rec valid_behaviours _B 123 | state msg = 124 | (match msg with (i, Add (j, _)) -> HOL.eq _B i j 125 | | (_, Rem (is, e)) -> HOL.eq (Set.equal_set _B) is (state e));; 126 | 127 | end;; (*struct ORSet*) 128 | -------------------------------------------------------------------------------- /paper/proof-strategy.tex: -------------------------------------------------------------------------------- 1 | \section{High-level Proof Strategy} 2 | \label{sect.high-level.proof.strategy} 3 | 4 | Since our formalisation of distributed algorithms goes into greater depth than prior work on strong eventual consistency, it is important to have a structure that keeps the proofs manageable. 5 | Our approach breaks the proof into simple modules with cleanly defined properties---called \emph{locales}, a standard sectioning mechanism of Isabelle/HOL that will be described in Section~\ref{subsect.an.overview.of.isabelle} below---and composes them in order to describe more complex objects. 6 | This locale structure is illustrated in Figure~\ref{fig.proof.structure} and explained below. 7 | %See Section~\ref{sect.isabelle.locales} for more detail on locales. 8 | 9 | \begin{figure} 10 | \centering 11 | \input{proof-structure} 12 | \caption{The main locales (modules) of our proof, and the relationships between them. 13 | Solid arrows indicate a more specialised locale that extends a more general locale (like extending interfaces in OOP). 14 | Dashed arrows indicate a sublocale that satisfies the assumptions of the superlocale (like implementing an interface in OOP). 15 | }\label{fig.proof.structure} 16 | \end{figure} 17 | 18 | By lines of code, more than half of our proof is used to construct a general-purpose model of consistency in distributed systems, described in Section~\ref{sect.abstract.convergence}, and an axiomatic model of a computer network, described in Section~\ref{sect.network}, with both modules independent of any particular replication algorithm. 19 | The remainder describes a formalisation of three CRDTs and their proofs of correctness, described in Sections~\ref{sect.rga} and~\ref{sect.simple.crdts}. 20 | By keeping the general-purpose modules abstract and implementation-independent, we construct a reusable library of specifications and theorems. 21 | 22 | We describe our formalisation of strong eventual consistency in Section~\ref{sect.abstract.convergence}. 23 | In particular, we define what we mean by convergence, and prove an \emph{abstract convergence theorem}, which shows that the state of nodes converges if concurrent operations commute. 24 | We are able to prove this fact without mentioning networks or any particular CRDT, but merely by reasoning about the ordering and properties of operations. 25 | This definition constitutes a formal specification of what we mean by strong eventual consistency. 26 | 27 | In Section~\ref{sect.network} we describe an axiomatic model of asynchronous networks. 28 | The definition of the network is important because it allows us to prove that the desired properties hold in \emph{all} possible network behaviours, and that we are not making any dangerous assumptions that might be violated---an aspect that has dogged previous verification efforts for related algorithms (see Section~\ref{sect.related.verification}). 29 | The network is the only part of our proof in which we make any axiomatic assumptions, and we show in Section~\ref{sect.network} that our assumptions are realistic, reflecting both standard conventions for modelling distributed systems, and the practical realities of network protocols today. 30 | We then prove that our network satisfies the ordering properties required by the abstract convergence theorem of Section~\ref{sect.abstract.convergence}, and thus deduce a convergence theorem for our network model. 31 | 32 | We use the general-purpose theorems and definitions from Sections~\ref{sect.abstract.convergence} and~\ref{sect.network} to prove the strong eventual consistency properties of concrete algorithms. 33 | In Section~\ref{sect.rga} we describe our formalisation of the Replicated Growable Array (RGA), a CRDT for ordered lists. 34 | We first show how to implement the RGA's insert and delete operations, with proofs that each operation commutes with itself, and that all operations commute with each other. 35 | Insertion and deletion only commute under various conditions, so we prove that these conditions are satisfied in all possible network behaviours, and thus we obtain a concrete convergence theorem for our RGA implementation. 36 | Next, in Section~\ref{sect.simple.crdts}, we demonstrate the generality of our proof framework with definitions of two simple CRDTs: a Counter and an Observed-Remove Set. 37 | %We show that with the previously established tooling in place, it is very easy to prove that these algorithms implement the abstract specification of strong eventual consistency. 38 | 39 | As illustrated in Figure~\ref{fig.proof.structure}, the $\isa{counter}$, $\isa{orset}$, and $\isa{rga}$ locales can use the definitions and lemmas of the network model because they extend that model. 40 | We then prove that all three locales satisfy the abstract specification $\isa{strong-eventual-consistency}$, and therefore show that these algorithms provide strong eventual consistency. 41 | -------------------------------------------------------------------------------- /src/ocaml/rga.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal 3 | val eq : 'a equal -> 'a -> 'a -> bool 4 | end = struct 5 | 6 | type 'a equal = {equal : 'a -> 'a -> bool};; 7 | let equal _A = _A.equal;; 8 | 9 | let rec eq _A a b = equal _A a b;; 10 | 11 | end;; (*struct HOL*) 12 | 13 | module Product_Type : sig 14 | val fst : 'a * 'b -> 'a 15 | end = struct 16 | 17 | let rec fst (x1, x2) = x1;; 18 | 19 | end;; (*struct Product_Type*) 20 | 21 | module Orderings : sig 22 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool} 23 | val less_eq : 'a ord -> 'a -> 'a -> bool 24 | val less : 'a ord -> 'a -> 'a -> bool 25 | type 'a preorder = {ord_preorder : 'a ord} 26 | type 'a order = {preorder_order : 'a preorder} 27 | type 'a linorder = {order_linorder : 'a order} 28 | end = struct 29 | 30 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool};; 31 | let less_eq _A = _A.less_eq;; 32 | let less _A = _A.less;; 33 | 34 | type 'a preorder = {ord_preorder : 'a ord};; 35 | 36 | type 'a order = {preorder_order : 'a preorder};; 37 | 38 | type 'a linorder = {order_linorder : 'a order};; 39 | 40 | end;; (*struct Orderings*) 41 | 42 | module Option : sig 43 | val bind : 'a option -> ('a -> 'b option) -> 'b option 44 | end = struct 45 | 46 | let rec bind x0 f = match x0, f with None, f -> None 47 | | Some x, f -> f x;; 48 | 49 | end;; (*struct Option*) 50 | 51 | module Ordered_List : sig 52 | val delete : 53 | 'a HOL.equal * 'a Orderings.linorder -> 54 | ('a * ('b * bool)) list -> 'a -> (('a * ('b * bool)) list) option 55 | val insert : 56 | 'a HOL.equal * 'a Orderings.linorder -> 57 | ('a * ('b * bool)) list -> 58 | 'a * ('b * bool) -> 'a option -> (('a * ('b * bool)) list) option 59 | end = struct 60 | 61 | let rec delete (_A1, _A2) 62 | x0 i = match x0, i with [], i -> None 63 | | (ia, (v, flag)) :: xs, i -> 64 | (if HOL.eq _A1 ia i then Some ((ia, (v, true)) :: xs) 65 | else Option.bind (delete (_A1, _A2) xs i) 66 | (fun t -> Some ((ia, (v, flag)) :: t)));; 67 | 68 | let rec insert_body _A 69 | x0 e = match x0, e with [], e -> [e] 70 | | x :: xs, e -> 71 | (if Orderings.less 72 | _A.Orderings.order_linorder.Orderings.preorder_order.Orderings.ord_preorder 73 | (Product_Type.fst x) (Product_Type.fst e) 74 | then e :: x :: xs else x :: insert_body _A xs e);; 75 | 76 | let rec insert (_A1, _A2) 77 | xs e x2 = match xs, e, x2 with xs, e, None -> Some (insert_body _A2 xs e) 78 | | [], e, Some i -> None 79 | | x :: xs, e, Some i -> 80 | (if HOL.eq _A1 (Product_Type.fst x) i 81 | then Some (x :: insert_body _A2 xs e) 82 | else Option.bind (insert (_A1, _A2) xs e (Some i)) 83 | (fun t -> Some (x :: t)));; 84 | 85 | end;; (*struct Ordered_List*) 86 | 87 | module List : sig 88 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 89 | val map : ('a -> 'b) -> 'a list -> 'b list 90 | end = struct 91 | 92 | let rec member _A x0 y = match x0, y with [], y -> false 93 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 94 | 95 | let rec map f x1 = match f, x1 with f, [] -> [] 96 | | f, x21 :: x22 -> f x21 :: map f x22;; 97 | 98 | end;; (*struct List*) 99 | 100 | module Set : sig 101 | type 'a set = Set of 'a list | Coset of 'a list 102 | val member : 'a HOL.equal -> 'a -> 'a set -> bool 103 | end = struct 104 | 105 | type 'a set = Set of 'a list | Coset of 'a list;; 106 | 107 | let rec member _A 108 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 109 | | x, Set xs -> List.member _A xs x;; 110 | 111 | end;; (*struct Set*) 112 | 113 | module RGA : sig 114 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 115 | Delete of 'a 116 | val valid_rga_msg : 117 | 'a HOL.equal * 'a Orderings.linorder -> 118 | ('a * ('b * bool)) list -> 'a * ('a, 'b) operation -> bool 119 | val interpret_opers : 120 | 'a HOL.equal * 'a Orderings.linorder -> 121 | ('a, 'b) operation -> 122 | ('a * ('b * bool)) list -> (('a * ('b * bool)) list) option 123 | end = struct 124 | 125 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 126 | Delete of 'a;; 127 | 128 | let rec element_ids lista = Set.Set (List.map Product_Type.fst lista);; 129 | 130 | let rec valid_rga_msg (_A1, _A2) 131 | lista msg = 132 | (match msg with (i, Insert (e, None)) -> HOL.eq _A1 (Product_Type.fst e) i 133 | | (i, Insert (e, Some pos)) -> 134 | HOL.eq _A1 (Product_Type.fst e) i && 135 | Set.member _A1 pos (element_ids lista) 136 | | (_, Delete pos) -> Set.member _A1 pos (element_ids lista));; 137 | 138 | let rec interpret_opers (_A1, _A2) 139 | x0 xs = match x0, xs with 140 | Insert (e, n), xs -> Ordered_List.insert (_A1, _A2) xs e n 141 | | Delete n, xs -> Ordered_List.delete (_A1, _A2) xs n;; 142 | 143 | end;; (*struct RGA*) 144 | -------------------------------------------------------------------------------- /src/AFP/ocaml/rga.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal 3 | val eq : 'a equal -> 'a -> 'a -> bool 4 | end = struct 5 | 6 | type 'a equal = {equal : 'a -> 'a -> bool};; 7 | let equal _A = _A.equal;; 8 | 9 | let rec eq _A a b = equal _A a b;; 10 | 11 | end;; (*struct HOL*) 12 | 13 | module Product_Type : sig 14 | val fst : 'a * 'b -> 'a 15 | end = struct 16 | 17 | let rec fst (x1, x2) = x1;; 18 | 19 | end;; (*struct Product_Type*) 20 | 21 | module Orderings : sig 22 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool} 23 | val less_eq : 'a ord -> 'a -> 'a -> bool 24 | val less : 'a ord -> 'a -> 'a -> bool 25 | type 'a preorder = {ord_preorder : 'a ord} 26 | type 'a order = {preorder_order : 'a preorder} 27 | type 'a linorder = {order_linorder : 'a order} 28 | end = struct 29 | 30 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool};; 31 | let less_eq _A = _A.less_eq;; 32 | let less _A = _A.less;; 33 | 34 | type 'a preorder = {ord_preorder : 'a ord};; 35 | 36 | type 'a order = {preorder_order : 'a preorder};; 37 | 38 | type 'a linorder = {order_linorder : 'a order};; 39 | 40 | end;; (*struct Orderings*) 41 | 42 | module Option : sig 43 | val bind : 'a option -> ('a -> 'b option) -> 'b option 44 | end = struct 45 | 46 | let rec bind x0 f = match x0, f with None, f -> None 47 | | Some x, f -> f x;; 48 | 49 | end;; (*struct Option*) 50 | 51 | module Ordered_List : sig 52 | val delete : 53 | 'a HOL.equal * 'a Orderings.linorder -> 54 | ('a * ('b * bool)) list -> 'a -> (('a * ('b * bool)) list) option 55 | val insert : 56 | 'a HOL.equal * 'a Orderings.linorder -> 57 | ('a * ('b * bool)) list -> 58 | 'a * ('b * bool) -> 'a option -> (('a * ('b * bool)) list) option 59 | end = struct 60 | 61 | let rec delete (_A1, _A2) 62 | x0 i = match x0, i with [], i -> None 63 | | (ia, (v, flag)) :: xs, i -> 64 | (if HOL.eq _A1 ia i then Some ((ia, (v, true)) :: xs) 65 | else Option.bind (delete (_A1, _A2) xs i) 66 | (fun t -> Some ((ia, (v, flag)) :: t)));; 67 | 68 | let rec insert_body _A 69 | x0 e = match x0, e with [], e -> [e] 70 | | x :: xs, e -> 71 | (if Orderings.less 72 | _A.Orderings.order_linorder.Orderings.preorder_order.Orderings.ord_preorder 73 | (Product_Type.fst x) (Product_Type.fst e) 74 | then e :: x :: xs else x :: insert_body _A xs e);; 75 | 76 | let rec insert (_A1, _A2) 77 | xs e x2 = match xs, e, x2 with xs, e, None -> Some (insert_body _A2 xs e) 78 | | [], e, Some i -> None 79 | | x :: xs, e, Some i -> 80 | (if HOL.eq _A1 (Product_Type.fst x) i 81 | then Some (x :: insert_body _A2 xs e) 82 | else Option.bind (insert (_A1, _A2) xs e (Some i)) 83 | (fun t -> Some (x :: t)));; 84 | 85 | end;; (*struct Ordered_List*) 86 | 87 | module List : sig 88 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 89 | val map : ('a -> 'b) -> 'a list -> 'b list 90 | end = struct 91 | 92 | let rec member _A x0 y = match x0, y with [], y -> false 93 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 94 | 95 | let rec map f x1 = match f, x1 with f, [] -> [] 96 | | f, x21 :: x22 -> f x21 :: map f x22;; 97 | 98 | end;; (*struct List*) 99 | 100 | module Set : sig 101 | type 'a set = Set of 'a list | Coset of 'a list 102 | val member : 'a HOL.equal -> 'a -> 'a set -> bool 103 | end = struct 104 | 105 | type 'a set = Set of 'a list | Coset of 'a list;; 106 | 107 | let rec member _A 108 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 109 | | x, Set xs -> List.member _A xs x;; 110 | 111 | end;; (*struct Set*) 112 | 113 | module RGA : sig 114 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 115 | Delete of 'a 116 | val valid_rga_msg : 117 | 'a HOL.equal * 'a Orderings.linorder -> 118 | ('a * ('b * bool)) list -> 'a * ('a, 'b) operation -> bool 119 | val interpret_opers : 120 | 'a HOL.equal * 'a Orderings.linorder -> 121 | ('a, 'b) operation -> 122 | ('a * ('b * bool)) list -> (('a * ('b * bool)) list) option 123 | end = struct 124 | 125 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 126 | Delete of 'a;; 127 | 128 | let rec element_ids lista = Set.Set (List.map Product_Type.fst lista);; 129 | 130 | let rec valid_rga_msg (_A1, _A2) 131 | lista msg = 132 | (match msg with (i, Insert (e, None)) -> HOL.eq _A1 (Product_Type.fst e) i 133 | | (i, Insert (e, Some pos)) -> 134 | HOL.eq _A1 (Product_Type.fst e) i && 135 | Set.member _A1 pos (element_ids lista) 136 | | (_, Delete pos) -> Set.member _A1 pos (element_ids lista));; 137 | 138 | let rec interpret_opers (_A1, _A2) 139 | x0 xs = match x0, xs with 140 | Insert (e, n), xs -> Ordered_List.insert (_A1, _A2) xs e n 141 | | Delete n, xs -> Ordered_List.delete (_A1, _A2) xs n;; 142 | 143 | end;; (*struct RGA*) 144 | -------------------------------------------------------------------------------- /src/supplemental/ocaml/rga.ml: -------------------------------------------------------------------------------- 1 | module HOL : sig 2 | type 'a equal 3 | val eq : 'a equal -> 'a -> 'a -> bool 4 | end = struct 5 | 6 | type 'a equal = {equal : 'a -> 'a -> bool};; 7 | let equal _A = _A.equal;; 8 | 9 | let rec eq _A a b = equal _A a b;; 10 | 11 | end;; (*struct HOL*) 12 | 13 | module Product_Type : sig 14 | val fst : 'a * 'b -> 'a 15 | end = struct 16 | 17 | let rec fst (x1, x2) = x1;; 18 | 19 | end;; (*struct Product_Type*) 20 | 21 | module Orderings : sig 22 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool} 23 | val less_eq : 'a ord -> 'a -> 'a -> bool 24 | val less : 'a ord -> 'a -> 'a -> bool 25 | type 'a preorder = {ord_preorder : 'a ord} 26 | type 'a order = {preorder_order : 'a preorder} 27 | type 'a linorder = {order_linorder : 'a order} 28 | end = struct 29 | 30 | type 'a ord = {less_eq : 'a -> 'a -> bool; less : 'a -> 'a -> bool};; 31 | let less_eq _A = _A.less_eq;; 32 | let less _A = _A.less;; 33 | 34 | type 'a preorder = {ord_preorder : 'a ord};; 35 | 36 | type 'a order = {preorder_order : 'a preorder};; 37 | 38 | type 'a linorder = {order_linorder : 'a order};; 39 | 40 | end;; (*struct Orderings*) 41 | 42 | module Option : sig 43 | val bind : 'a option -> ('a -> 'b option) -> 'b option 44 | end = struct 45 | 46 | let rec bind x0 f = match x0, f with None, f -> None 47 | | Some x, f -> f x;; 48 | 49 | end;; (*struct Option*) 50 | 51 | module Ordered_List : sig 52 | val delete : 53 | 'a HOL.equal * 'a Orderings.linorder -> 54 | ('a * ('b * bool)) list -> 'a -> (('a * ('b * bool)) list) option 55 | val insert : 56 | 'a HOL.equal * 'a Orderings.linorder -> 57 | ('a * ('b * bool)) list -> 58 | 'a * ('b * bool) -> 'a option -> (('a * ('b * bool)) list) option 59 | end = struct 60 | 61 | let rec delete (_A1, _A2) 62 | x0 i = match x0, i with [], i -> None 63 | | (ia, (v, flag)) :: xs, i -> 64 | (if HOL.eq _A1 ia i then Some ((ia, (v, true)) :: xs) 65 | else Option.bind (delete (_A1, _A2) xs i) 66 | (fun t -> Some ((ia, (v, flag)) :: t)));; 67 | 68 | let rec insert_body _A 69 | x0 e = match x0, e with [], e -> [e] 70 | | x :: xs, e -> 71 | (if Orderings.less 72 | _A.Orderings.order_linorder.Orderings.preorder_order.Orderings.ord_preorder 73 | (Product_Type.fst x) (Product_Type.fst e) 74 | then e :: x :: xs else x :: insert_body _A xs e);; 75 | 76 | let rec insert (_A1, _A2) 77 | xs e x2 = match xs, e, x2 with xs, e, None -> Some (insert_body _A2 xs e) 78 | | [], e, Some i -> None 79 | | x :: xs, e, Some i -> 80 | (if HOL.eq _A1 (Product_Type.fst x) i 81 | then Some (x :: insert_body _A2 xs e) 82 | else Option.bind (insert (_A1, _A2) xs e (Some i)) 83 | (fun t -> Some (x :: t)));; 84 | 85 | end;; (*struct Ordered_List*) 86 | 87 | module List : sig 88 | val member : 'a HOL.equal -> 'a list -> 'a -> bool 89 | val map : ('a -> 'b) -> 'a list -> 'b list 90 | end = struct 91 | 92 | let rec member _A x0 y = match x0, y with [], y -> false 93 | | x :: xs, y -> HOL.eq _A x y || member _A xs y;; 94 | 95 | let rec map f x1 = match f, x1 with f, [] -> [] 96 | | f, x21 :: x22 -> f x21 :: map f x22;; 97 | 98 | end;; (*struct List*) 99 | 100 | module Set : sig 101 | type 'a set = Set of 'a list | Coset of 'a list 102 | val member : 'a HOL.equal -> 'a -> 'a set -> bool 103 | end = struct 104 | 105 | type 'a set = Set of 'a list | Coset of 'a list;; 106 | 107 | let rec member _A 108 | x xa1 = match x, xa1 with x, Coset xs -> not (List.member _A xs x) 109 | | x, Set xs -> List.member _A xs x;; 110 | 111 | end;; (*struct Set*) 112 | 113 | module RGA : sig 114 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 115 | Delete of 'a 116 | val valid_rga_msg : 117 | 'a HOL.equal * 'a Orderings.linorder -> 118 | ('a * ('b * bool)) list -> 'a * ('a, 'b) operation -> bool 119 | val interpret_opers : 120 | 'a HOL.equal * 'a Orderings.linorder -> 121 | ('a, 'b) operation -> 122 | ('a * ('b * bool)) list -> (('a * ('b * bool)) list) option 123 | end = struct 124 | 125 | type ('a, 'b) operation = Insert of ('a * ('b * bool)) * 'a option | 126 | Delete of 'a;; 127 | 128 | let rec element_ids lista = Set.Set (List.map Product_Type.fst lista);; 129 | 130 | let rec valid_rga_msg (_A1, _A2) 131 | lista msg = 132 | (match msg with (i, Insert (e, None)) -> HOL.eq _A1 (Product_Type.fst e) i 133 | | (i, Insert (e, Some pos)) -> 134 | HOL.eq _A1 (Product_Type.fst e) i && 135 | Set.member _A1 pos (element_ids lista) 136 | | (_, Delete pos) -> Set.member _A1 pos (element_ids lista));; 137 | 138 | let rec interpret_opers (_A1, _A2) 139 | x0 xs = match x0, xs with 140 | Insert (e, n), xs -> Ordered_List.insert (_A1, _A2) xs e n 141 | | Delete n, xs -> Ordered_List.delete (_A1, _A2) xs n;; 142 | 143 | end;; (*struct RGA*) 144 | -------------------------------------------------------------------------------- /talks/rems-march-2017/beamerouterthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerouterthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerouterthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerouterthememetropolis}[2016/03/14 Metropolis outer theme] 21 | \RequirePackage{etoolbox} 22 | \RequirePackage{calc} 23 | \RequirePackage{pgfopts} 24 | \pgfkeys{ 25 | /metropolis/outer/numbering/.cd, 26 | .is choice, 27 | none/.code=\setbeamertemplate{frame numbering}[none], 28 | counter/.code=\setbeamertemplate{frame numbering}[counter], 29 | fraction/.code=\setbeamertemplate{frame numbering}[fraction], 30 | } 31 | \pgfkeys{ 32 | /metropolis/outer/progressbar/.cd, 33 | .is choice, 34 | none/.code={% 35 | \setbeamertemplate{headline}[plain] 36 | \setbeamertemplate{frametitle}[plain] 37 | \setbeamertemplate{footline}[plain] 38 | }, 39 | head/.code={\pgfkeys{/metropolis/outer/progressbar=none} 40 | \addtobeamertemplate{headline}{}{% 41 | \usebeamertemplate*{progress bar in head/foot} 42 | } 43 | }, 44 | frametitle/.code={\pgfkeys{/metropolis/outer/progressbar=none} 45 | \addtobeamertemplate{frametitle}{}{% 46 | \usebeamertemplate*{progress bar in head/foot} 47 | } 48 | }, 49 | foot/.code={\pgfkeys{/metropolis/outer/progressbar=none} 50 | \addtobeamertemplate{footline}{}{% 51 | \usebeamertemplate*{progress bar in head/foot}% 52 | } 53 | }, 54 | } 55 | \newcommand{\metropolis@outer@setdefaults}{ 56 | \pgfkeys{/metropolis/outer/.cd, 57 | numbering=counter, 58 | progressbar=none, 59 | } 60 | } 61 | \setbeamertemplate{navigation symbols}{} 62 | \defbeamertemplate{frame footer}{none}{} 63 | \defbeamertemplate{frame footer}{custom}[1]{ #1 } 64 | \defbeamertemplate{frame numbering}{none}{} 65 | \defbeamertemplate{frame numbering}{counter}{\insertframenumber} 66 | \defbeamertemplate{frame numbering}{fraction}{ 67 | \insertframenumber/\inserttotalframenumber 68 | } 69 | \defbeamertemplate{headline}{plain}{} 70 | \defbeamertemplate{footline}{plain}{% 71 | \begin{beamercolorbox}[wd=\textwidth, sep=3ex]{footline}% 72 | \usebeamerfont{page number in head/foot}% 73 | \usebeamertemplate*{frame footer} 74 | \hfill% 75 | \usebeamertemplate*{frame numbering} 76 | \end{beamercolorbox}% 77 | } 78 | \newlength{\metropolis@frametitle@padding} 79 | \setlength{\metropolis@frametitle@padding}{2.2ex} 80 | \newcommand{\metropolis@frametitlestrut@start}{ 81 | \rule{0pt}{\metropolis@frametitle@padding +% 82 | \totalheightof{% 83 | \ifcsdef{metropolis@frametitleformat}{\metropolis@frametitleformat X}{X}% 84 | }% 85 | }% 86 | } 87 | \newcommand{\metropolis@frametitlestrut@end}{ 88 | \rule[-\metropolis@frametitle@padding]{0pt}{\metropolis@frametitle@padding} 89 | } 90 | \defbeamertemplate{frametitle}{plain}{% 91 | \nointerlineskip% 92 | \begin{beamercolorbox}[% 93 | wd=\paperwidth,% 94 | sep=0pt,% 95 | leftskip=\metropolis@frametitle@padding,% 96 | rightskip=\metropolis@frametitle@padding,% 97 | ]{frametitle}% 98 | \metropolis@frametitlestrut@start% 99 | \insertframetitle% 100 | \nolinebreak% 101 | \metropolis@frametitlestrut@end% 102 | \end{beamercolorbox}% 103 | } 104 | \setbeamertemplate{frametitle continuation}{% 105 | \usebeamerfont{frametitle} 106 | \romannumeral \insertcontinuationcount 107 | } 108 | \newlength{\metropolis@progressinheadfoot} 109 | \setbeamertemplate{progress bar in head/foot}{ 110 | \nointerlineskip 111 | \setlength{\metropolis@progressinheadfoot}{% 112 | \paperwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}% 113 | }% 114 | \begin{beamercolorbox}[wd=\paperwidth]{progress bar in head/foot} 115 | \begin{tikzpicture} 116 | \fill[bg] (0,0) rectangle (\paperwidth, 0.4pt); 117 | \fill[fg] (0,0) rectangle (\metropolis@progressinheadfoot, 0.4pt); 118 | \end{tikzpicture}% 119 | \end{beamercolorbox} 120 | } 121 | \AtBeginDocument{% 122 | \apptocmd{\appendix}{% 123 | \pgfkeys{% 124 | /metropolis/outer/.cd, 125 | numbering=none, 126 | progressbar=none} 127 | }{}{} 128 | } 129 | \metropolis@outer@setdefaults 130 | \ProcessPgfPackageOptions{/metropolis/outer} 131 | \endinput 132 | %% 133 | %% End of file `beamerouterthememetropolis.sty'. 134 | -------------------------------------------------------------------------------- /talks/srepls-may-2017/beamerouterthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerouterthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerouterthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerouterthememetropolis}[2016/03/14 Metropolis outer theme] 21 | \RequirePackage{etoolbox} 22 | \RequirePackage{calc} 23 | \RequirePackage{pgfopts} 24 | \pgfkeys{ 25 | /metropolis/outer/numbering/.cd, 26 | .is choice, 27 | none/.code=\setbeamertemplate{frame numbering}[none], 28 | counter/.code=\setbeamertemplate{frame numbering}[counter], 29 | fraction/.code=\setbeamertemplate{frame numbering}[fraction], 30 | } 31 | \pgfkeys{ 32 | /metropolis/outer/progressbar/.cd, 33 | .is choice, 34 | none/.code={% 35 | \setbeamertemplate{headline}[plain] 36 | \setbeamertemplate{frametitle}[plain] 37 | \setbeamertemplate{footline}[plain] 38 | }, 39 | head/.code={\pgfkeys{/metropolis/outer/progressbar=none} 40 | \addtobeamertemplate{headline}{}{% 41 | \usebeamertemplate*{progress bar in head/foot} 42 | } 43 | }, 44 | frametitle/.code={\pgfkeys{/metropolis/outer/progressbar=none} 45 | \addtobeamertemplate{frametitle}{}{% 46 | \usebeamertemplate*{progress bar in head/foot} 47 | } 48 | }, 49 | foot/.code={\pgfkeys{/metropolis/outer/progressbar=none} 50 | \addtobeamertemplate{footline}{}{% 51 | \usebeamertemplate*{progress bar in head/foot}% 52 | } 53 | }, 54 | } 55 | \newcommand{\metropolis@outer@setdefaults}{ 56 | \pgfkeys{/metropolis/outer/.cd, 57 | numbering=counter, 58 | progressbar=none, 59 | } 60 | } 61 | \setbeamertemplate{navigation symbols}{} 62 | \defbeamertemplate{frame footer}{none}{} 63 | \defbeamertemplate{frame footer}{custom}[1]{ #1 } 64 | \defbeamertemplate{frame numbering}{none}{} 65 | \defbeamertemplate{frame numbering}{counter}{\insertframenumber} 66 | \defbeamertemplate{frame numbering}{fraction}{ 67 | \insertframenumber/\inserttotalframenumber 68 | } 69 | \defbeamertemplate{headline}{plain}{} 70 | \defbeamertemplate{footline}{plain}{% 71 | \begin{beamercolorbox}[wd=\textwidth, sep=3ex]{footline}% 72 | \usebeamerfont{page number in head/foot}% 73 | \usebeamertemplate*{frame footer} 74 | \hfill% 75 | \usebeamertemplate*{frame numbering} 76 | \end{beamercolorbox}% 77 | } 78 | \newlength{\metropolis@frametitle@padding} 79 | \setlength{\metropolis@frametitle@padding}{2.2ex} 80 | \newcommand{\metropolis@frametitlestrut@start}{ 81 | \rule{0pt}{\metropolis@frametitle@padding +% 82 | \totalheightof{% 83 | \ifcsdef{metropolis@frametitleformat}{\metropolis@frametitleformat X}{X}% 84 | }% 85 | }% 86 | } 87 | \newcommand{\metropolis@frametitlestrut@end}{ 88 | \rule[-\metropolis@frametitle@padding]{0pt}{\metropolis@frametitle@padding} 89 | } 90 | \defbeamertemplate{frametitle}{plain}{% 91 | \nointerlineskip% 92 | \begin{beamercolorbox}[% 93 | wd=\paperwidth,% 94 | sep=0pt,% 95 | leftskip=\metropolis@frametitle@padding,% 96 | rightskip=\metropolis@frametitle@padding,% 97 | ]{frametitle}% 98 | \metropolis@frametitlestrut@start% 99 | \insertframetitle% 100 | \nolinebreak% 101 | \metropolis@frametitlestrut@end% 102 | \end{beamercolorbox}% 103 | } 104 | \setbeamertemplate{frametitle continuation}{% 105 | \usebeamerfont{frametitle} 106 | \romannumeral \insertcontinuationcount 107 | } 108 | \newlength{\metropolis@progressinheadfoot} 109 | \setbeamertemplate{progress bar in head/foot}{ 110 | \nointerlineskip 111 | \setlength{\metropolis@progressinheadfoot}{% 112 | \paperwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}% 113 | }% 114 | \begin{beamercolorbox}[wd=\paperwidth]{progress bar in head/foot} 115 | \begin{tikzpicture} 116 | \fill[bg] (0,0) rectangle (\paperwidth, 0.4pt); 117 | \fill[fg] (0,0) rectangle (\metropolis@progressinheadfoot, 0.4pt); 118 | \end{tikzpicture}% 119 | \end{beamercolorbox} 120 | } 121 | \AtBeginDocument{% 122 | \apptocmd{\appendix}{% 123 | \pgfkeys{% 124 | /metropolis/outer/.cd, 125 | numbering=none, 126 | progressbar=none} 127 | }{}{} 128 | } 129 | \metropolis@outer@setdefaults 130 | \ProcessPgfPackageOptions{/metropolis/outer} 131 | \endinput 132 | %% 133 | %% End of file `beamerouterthememetropolis.sty'. 134 | -------------------------------------------------------------------------------- /src/supplemental/README.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | In this directory we provide (non-anonymised) supplementary material for the 4 | OOPSLA/SPLASH 2017 submissions "Verifying Strong Eventual Consistency in 5 | Distributed Systems" by Gomes, Kleppmann, Mulligan, and Beresford. 6 | 7 | The directory consists of three components: 8 | 9 | 1. An annotated auto-generated PDF of all of our Isabelle definitions and theorems. 10 | 2. Our Isabelle theory files, containing our definitions and theorems which can be 11 | checked by Isabelle2016-1. 12 | 3. An OCaml extraction of our three CRDTs, plus a simple asynchronous network, built 13 | atop TCP, of an arbitrary number of communicating nodes using the OCaml 14 | extraction of our counter CRDT to demonstrate that our definitions are usable in 15 | practice. 16 | 17 | To verify that our proofs are correct follow these instructions: 18 | 19 | Download Isabelle2016-1 from the Isabelle homepage: 20 | 21 | https://isabelle.in.tum.de/ 22 | 23 | (Assuming Linux) extract the .tar.gz file by 24 | 25 | tar xzf file.tar.gz 26 | 27 | Run Isabelle for the first time by running 28 | 29 | $Isabelle2016-1-DIRECTORY/Isabelle2016-1.run 30 | 31 | This will open a jEdit window after which Isabelle will begin building various 32 | "heaps". Once Complex_Main has been built, which should take around 15 minutes on 33 | a moderately fast machine, open one of RGA.thy, ORSet.thy, or Counter.thy. 34 | 35 | Isabelle will ask whether all theory dependencies should be loaded. Click "yes". 36 | 37 | After a few minutes, Isabelle will start to process the file that you have opened, 38 | once all dependencies have been processed. This is indicated by a "purple wave" 39 | flowing down the theory file. Scroll to the bottom of the file, and the entirety 40 | of the theory should be processed. Note that purple indicates Isabelle is processing 41 | the definition or theorem (some steps may take a while), whereas red indicates 42 | processing has failed with an error. Isabelle should not show any red when processing 43 | our development. 44 | 45 | Alternatively, if you do not wish to install Isabelle to check our proofs, you can 46 | read through the annotated_proofs.pdf document instead. This is automatically 47 | generated by Isabelle from our theory files, and contains passages from our paper 48 | inserted as comments, so you can orient yourself within our development. 49 | 50 | # Evaluation 51 | 52 | A description of the Isabelle proof contained within the theory files in our artefact 53 | submission forms the largest component of our paper (Sections 4--7). 54 | 55 | To check that our theorems are "real" theorems: press CTRL+F to open search. Type 56 | sorry into the search box, click the "All buffers" radio button, and click "Search". 57 | No instances of "sorry" (i.e. an admitted theorem, without proof) should be present, 58 | indicating that we rely on no axioms other than those described in our paper. 59 | 60 | One may also use the included "annotated-proofs.pdf" file, automatically generated 61 | from our Isabelle proofs, to see that our Isabelle code and Sections 4--7 of our 62 | paper are in synchrony. 63 | 64 | Next, we claimed that our CRDT definitions are "executable" in our paper (Section 9). 65 | To check that this is the case, one can examine the OCaml source code that Isabelle's 66 | code generation mechanism produces, and also check that this process does not fail. 67 | Within our three CRDT implementation theories (ORSet.thy, RGA.thy, and Counter.thy) 68 | is an Isabelle command that starts with "export_code". This is an instruction to 69 | Isabelle to generate OCaml code from the definitions listed after the command. Every 70 | time the theory file is processed, this code generation mechanism will extract code 71 | and write to the specified file. To check that this is happening correctly, simply 72 | delete the existing OCaml files that we supplied in our artefact submission and 73 | recheck the relevant theories, causing Isabelle to create new OCaml files as a 74 | side-effect. 75 | 76 | Lastly, to run our network experiment (assuming OCaml's OPAM is installed) mentioned 77 | briefly in Section 9: 78 | 79 | Ensure Jane Street Core and the Async libraries are installed: 80 | 81 | opam install core async 82 | 83 | Run the Makefile in the ocaml/ directory provided in this distribution: 84 | 85 | make 86 | 87 | Run the test.sh shell script in ocaml/ to create a network of four communicating 88 | nodes. Edit the contents of test.sh to change the size of the network. 89 | 90 | Once running, the network should generate increment/decrement messages randomly, 91 | with nodes generating messages potentially concurrently. 92 | 93 | To kill the network, run 94 | 95 | pkill -9 network 96 | 97 | Nodes can be run on remote machines by editing the contents of test.sh also (i.e. 98 | change localhost to some other address). This network experiment uses the OCaml 99 | code generated from the Counter.thy theory file. If this is deleted, simply 100 | reprocess Counter.thy with Isabelle to reproduce, as described above. -------------------------------------------------------------------------------- /src/supplemental/document/root.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage{isabelle,isabellesym} 3 | \usepackage[a4paper,portrait,margin=1in]{geometry} 4 | 5 | % further packages required for unusual symbols (see also 6 | % isabellesym.sty), use only when needed 7 | 8 | \usepackage{amsmath} 9 | \usepackage{amssymb} 10 | %for \, \, \, \, \, \, 11 | %\, \, \, \, \, 12 | %\, \, \ 13 | 14 | %\usepackage{eurosym} 15 | %for \ 16 | 17 | %\usepackage[only,bigsqcap]{stmaryrd} 18 | %for \ 19 | 20 | %\usepackage{eufrak} 21 | %for \ ... \, \ ... \ (also included in amssymb) 22 | 23 | %\usepackage{textcomp} 24 | %for \, \, \, \, \, 25 | %\ 26 | 27 | % this should be the last package used 28 | \usepackage{pdfsetup} 29 | 30 | % urls in roman style, theory text in math-similar italics 31 | \urlstyle{rm} 32 | \isabellestyle{it} 33 | 34 | % for uniform font size 35 | %\renewcommand{\isastyle}{\isastyleminor} 36 | 37 | 38 | \begin{document} 39 | 40 | \title{Verifying Strong Eventual Consistency in Distributed Systems} 41 | \author{Victor B.~F.~Gomes, Martin Kleppmann, Dominic P.~Mulligan,\\Alastair R. Beresford} 42 | \maketitle 43 | 44 | \begin{abstract} 45 | In this work, we focus on the correctness of Conflict-free Replicated Data Types (CRDTs), a class of algorithm that provides strong eventual consistency guarantees for replicated data. 46 | We develop a modular and reusable framework for verifying the correctness of CRDT algorithms. 47 | We avoid correctness issues that have dogged previous mechanised proofs in this area by including a network model in our formalisation, and proving that our theorems hold in all possible network behaviours. 48 | Our axiomatic network model is a standard abstraction that accurately reflects the behaviour of real-world computer networks. 49 | Moreover, we identify an abstract convergence theorem, a property of order relations, which provides a formal definition of strong eventual consistency. 50 | We then obtain the first machine-checked correctness theorems for three concrete CRDTs: the Replicated Growable Array, the Observed-Remove Set, and an Increment-Decrement Counter. 51 | \end{abstract} 52 | 53 | \tableofcontents 54 | 55 | % sane default for proof documents 56 | \parindent 0pt\parskip 0.5ex 57 | 58 | \section {Introduction} 59 | 60 | \emph{Strong eventual consistency} (SEC) is a model that strikes a compromise between strong and eventual consistency~\cite{Shapiro:2011un}. 61 | Informally, it guarantees that whenever two nodes have received the same set of messages---possibly in a different order---their view of the shared state is identical, and any conflicting concurrent updates must be merged automatically. 62 | Large-scale deployments of SEC algorithms include datacentre-based applications using the Riak distributed database \cite{Brown:2014hs}, and collaborative editing applications such as Google Docs \cite{DayRichter:2010tt}. 63 | Unlike strong consistency models, it is possible to implement SEC in decentralised settings without any central server or leader, and it allows local execution at each node to proceed without waiting for communication with other nodes. 64 | However, algorithms for achieving decentralised SEC are currently poorly understood: several such algorithms, published in peer-reviewed venues, were subsequently shown to violate their supposed guarantees \cite{Imine:2003ks,Imine:2006kn,Oster:2005vi}. 65 | Informal reasoning has repeatedly produced plausible-looking but incorrect algorithms, and there have even been examples of mechanised formal proofs of SEC algorithm correctness later being shown to be flawed. 66 | These mechanised proofs failed because, in formalising the algorithm, they made false assumptions about the execution environment. 67 | 68 | In this work we use the Isabelle/HOL proof assistant~\cite{DBLP:conf/tphol/WenzelPN08} to create a framework for reliably reasoning about the correctness of a particular class of decentralised replication algorithms. 69 | We do this by formalising not only the replication algorithms, but also the network in which they execute, allowing us to prove that the algorithm's assumptions hold in all possible network behaviours. 70 | We model the network using the axioms of \emph{asynchronous unreliable causal broadcast}, a well-understood abstraction that is commonly implemented by network protocols, and which can run on almost any computer network, including large-scale networks that delay, reorder, or drop messages, and in which nodes may fail. 71 | 72 | We then use this framework to produce machine-checked proofs of correctness for three Conflict-Free Replicated Data Types (CRDTs), a class of replication algorithms that ensure strong eventual consistency \cite{Shapiro:2011wy,Shapiro:2011un}. 73 | To our knowledge, this is the first machine-checked verification of SEC algorithms that explicitly models the network and reasons about all possible network behaviours. 74 | The framework is modular and reusable, making it easy to formulate proofs for new algorithms. 75 | We provide the first mechanised proofs of the Replicated Growable Array, the operation-based Observed-Remove Set, and the operation-based counter CRDT. 76 | 77 | % generated text of all theories 78 | \input{session} 79 | 80 | % optional bibliography 81 | \bibliographystyle{abbrv} 82 | \bibliography{root} 83 | 84 | \end{document} 85 | 86 | %%% Local Variables: 87 | %%% mode: latex 88 | %%% TeX-master: t 89 | %%% End: 90 | -------------------------------------------------------------------------------- /src/AFP/document/root.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage{isabelle,isabellesym} 3 | \usepackage[a4paper,portrait,margin=1in]{geometry} 4 | 5 | % further packages required for unusual symbols (see also 6 | % isabellesym.sty), use only when needed 7 | 8 | \usepackage{amsmath} 9 | \usepackage{amssymb} 10 | %for \, \, \, \, \, \, 11 | %\, \, \, \, \, 12 | %\, \, \ 13 | 14 | %\usepackage{eurosym} 15 | %for \ 16 | 17 | %\usepackage[only,bigsqcap]{stmaryrd} 18 | %for \ 19 | 20 | %\usepackage{eufrak} 21 | %for \ ... \, \ ... \ (also included in amssymb) 22 | 23 | %\usepackage{textcomp} 24 | %for \, \, \, \, \, 25 | %\ 26 | 27 | % this should be the last package used 28 | \usepackage{pdfsetup} 29 | 30 | % urls in roman style, theory text in math-similar italics 31 | \urlstyle{rm} 32 | \isabellestyle{it} 33 | 34 | % for uniform font size 35 | %\renewcommand{\isastyle}{\isastyleminor} 36 | 37 | 38 | \begin{document} 39 | 40 | \title{A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Data types} 41 | \author{Victor B.~F.~Gomes, Martin Kleppmann, Dominic P.~Mulligan,\\Alastair R. Beresford} 42 | \maketitle 43 | 44 | \begin{abstract} 45 | In this work, we focus on the correctness of Conflict-free Replicated Data Types (CRDTs), a class of algorithm that provides strong eventual consistency guarantees for replicated data. 46 | We develop a modular and reusable framework for verifying the correctness of CRDT algorithms. 47 | We avoid correctness issues that have dogged previous mechanised proofs in this area by including a network model in our formalisation, and proving that our theorems hold in all possible network behaviours. 48 | Our axiomatic network model is a standard abstraction that accurately reflects the behaviour of real-world computer networks. 49 | Moreover, we identify an abstract convergence theorem, a property of order relations, which provides a formal definition of strong eventual consistency. 50 | We then obtain the first machine-checked correctness theorems for three concrete CRDTs: the Replicated Growable Array, the Observed-Remove Set, and an Increment-Decrement Counter. 51 | \end{abstract} 52 | 53 | \tableofcontents 54 | 55 | % sane default for proof documents 56 | \parindent 0pt\parskip 0.5ex 57 | 58 | \section {Introduction} 59 | 60 | \emph{Strong eventual consistency} (SEC) is a model that strikes a compromise between strong and eventual consistency~\cite{Shapiro:2011un}. 61 | Informally, it guarantees that whenever two nodes have received the same set of messages---possibly in a different order---their view of the shared state is identical, and any conflicting concurrent updates must be merged automatically. 62 | Large-scale deployments of SEC algorithms include datacentre-based applications using the Riak distributed database \cite{Brown:2014hs}, and collaborative editing applications such as Google Docs \cite{DayRichter:2010tt}. 63 | Unlike strong consistency models, it is possible to implement SEC in decentralised settings without any central server or leader, and it allows local execution at each node to proceed without waiting for communication with other nodes. 64 | However, algorithms for achieving decentralised SEC are currently poorly understood: several such algorithms, published in peer-reviewed venues, were subsequently shown to violate their supposed guarantees \cite{Imine:2003ks,Imine:2006kn,Oster:2005vi}. 65 | Informal reasoning has repeatedly produced plausible-looking but incorrect algorithms, and there have even been examples of mechanised formal proofs of SEC algorithm correctness later being shown to be flawed. 66 | These mechanised proofs failed because, in formalising the algorithm, they made false assumptions about the execution environment. 67 | 68 | In this work we use the Isabelle/HOL proof assistant~\cite{DBLP:conf/tphol/WenzelPN08} to create a framework for reliably reasoning about the correctness of a particular class of decentralised replication algorithms. 69 | We do this by formalising not only the replication algorithms, but also the network in which they execute, allowing us to prove that the algorithm's assumptions hold in all possible network behaviours. 70 | We model the network using the axioms of \emph{asynchronous unreliable causal broadcast}, a well-understood abstraction that is commonly implemented by network protocols, and which can run on almost any computer network, including large-scale networks that delay, reorder, or drop messages, and in which nodes may fail. 71 | 72 | We then use this framework to produce machine-checked proofs of correctness for three Conflict-Free Replicated Data Types (CRDTs), a class of replication algorithms that ensure strong eventual consistency \cite{Shapiro:2011wy,Shapiro:2011un}. 73 | To our knowledge, this is the first machine-checked verification of SEC algorithms that explicitly models the network and reasons about all possible network behaviours. 74 | The framework is modular and reusable, making it easy to formulate proofs for new algorithms. 75 | We provide the first mechanised proofs of the Replicated Growable Array, the operation-based Observed-Remove Set, and the operation-based counter CRDT. 76 | 77 | % generated text of all theories 78 | \input{session} 79 | 80 | % optional bibliography 81 | \bibliographystyle{abbrv} 82 | \bibliography{root} 83 | 84 | \end{document} 85 | 86 | %%% Local Variables: 87 | %%% mode: latex 88 | %%% TeX-master: t 89 | %%% End: 90 | -------------------------------------------------------------------------------- /src/document/root.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage[T1]{fontenc} 3 | \usepackage{isabelle,isabellesym} 4 | \usepackage[a4paper,portrait,margin=1in]{geometry} 5 | 6 | % further packages required for unusual symbols (see also 7 | % isabellesym.sty), use only when needed 8 | 9 | \usepackage{amsmath} 10 | \usepackage{amssymb} 11 | %for \, \, \, \, \, \, 12 | %\, \, \, \, \, 13 | %\, \, \ 14 | 15 | %\usepackage{eurosym} 16 | %for \ 17 | 18 | %\usepackage[only,bigsqcap]{stmaryrd} 19 | %for \ 20 | 21 | %\usepackage{eufrak} 22 | %for \ ... \, \ ... \ (also included in amssymb) 23 | 24 | %\usepackage{textcomp} 25 | %for \, \, \, \, \, 26 | %\ 27 | 28 | % this should be the last package used 29 | \usepackage{pdfsetup} 30 | 31 | % urls in roman style, theory text in math-similar italics 32 | \urlstyle{rm} 33 | \isabellestyle{it} 34 | 35 | % for uniform font size 36 | %\renewcommand{\isastyle}{\isastyleminor} 37 | 38 | 39 | \begin{document} 40 | 41 | \title{A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Data types} 42 | \author{Victor B.~F.~Gomes, Martin Kleppmann, Dominic P.~Mulligan,\\Alastair R. Beresford} 43 | \maketitle 44 | 45 | \begin{abstract} 46 | In this work, we focus on the correctness of Conflict-free Replicated Data Types (CRDTs), a class of algorithm that provides strong eventual consistency guarantees for replicated data. 47 | We develop a modular and reusable framework for verifying the correctness of CRDT algorithms. 48 | We avoid correctness issues that have dogged previous mechanised proofs in this area by including a network model in our formalisation, and proving that our theorems hold in all possible network behaviours. 49 | Our axiomatic network model is a standard abstraction that accurately reflects the behaviour of real-world computer networks. 50 | Moreover, we identify an abstract convergence theorem, a property of order relations, which provides a formal definition of strong eventual consistency. 51 | We then obtain the first machine-checked correctness theorems for three concrete CRDTs: the Replicated Growable Array, the Observed-Remove Set, and an Increment-Decrement Counter. 52 | \end{abstract} 53 | 54 | \tableofcontents 55 | 56 | % sane default for proof documents 57 | \parindent 0pt\parskip 0.5ex 58 | 59 | \section {Introduction} 60 | 61 | \emph{Strong eventual consistency} (SEC) is a model that strikes a compromise between strong and eventual consistency~\cite{Shapiro:2011un}. 62 | Informally, it guarantees that whenever two nodes have received the same set of messages---possibly in a different order---their view of the shared state is identical, and any conflicting concurrent updates must be merged automatically. 63 | Large-scale deployments of SEC algorithms include datacentre-based applications using the Riak distributed database \cite{Brown:2014hs}, and collaborative editing applications such as Google Docs \cite{DayRichter:2010tt}. 64 | Unlike strong consistency models, it is possible to implement SEC in decentralised settings without any central server or leader, and it allows local execution at each node to proceed without waiting for communication with other nodes. 65 | However, algorithms for achieving decentralised SEC are currently poorly understood: several such algorithms, published in peer-reviewed venues, were subsequently shown to violate their supposed guarantees \cite{Imine:2003ks,Imine:2006kn,Oster:2005vi}. 66 | Informal reasoning has repeatedly produced plausible-looking but incorrect algorithms, and there have even been examples of mechanised formal proofs of SEC algorithm correctness later being shown to be flawed. 67 | These mechanised proofs failed because, in formalising the algorithm, they made false assumptions about the execution environment. 68 | 69 | In this work we use the Isabelle/HOL proof assistant~\cite{DBLP:conf/tphol/WenzelPN08} to create a framework for reliably reasoning about the correctness of a particular class of decentralised replication algorithms. 70 | We do this by formalising not only the replication algorithms, but also the network in which they execute, allowing us to prove that the algorithm's assumptions hold in all possible network behaviours. 71 | We model the network using the axioms of \emph{asynchronous unreliable causal broadcast}, a well-understood abstraction that is commonly implemented by network protocols, and which can run on almost any computer network, including large-scale networks that delay, reorder, or drop messages, and in which nodes may fail. 72 | 73 | We then use this framework to produce machine-checked proofs of correctness for three Conflict-Free Replicated Data Types (CRDTs), a class of replication algorithms that ensure strong eventual consistency \cite{Shapiro:2011wy,Shapiro:2011un}. 74 | To our knowledge, this is the first machine-checked verification of SEC algorithms that explicitly models the network and reasons about all possible network behaviours. 75 | The framework is modular and reusable, making it easy to formulate proofs for new algorithms. 76 | We provide the first mechanised proofs of the Replicated Growable Array, the operation-based Observed-Remove Set, and the operation-based counter CRDT. 77 | 78 | % generated text of all theories 79 | \input{session} 80 | 81 | % optional bibliography 82 | \bibliographystyle{abbrv} 83 | \bibliography{root} 84 | 85 | \end{document} 86 | 87 | %%% Local Variables: 88 | %%% mode: latex 89 | %%% TeX-master: t 90 | %%% End: 91 | -------------------------------------------------------------------------------- /src/supplemental/Util.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Technical Lemmas\ 8 | 9 | text\This section contains a list of helper definitions and lemmas about sets, lists and 10 | the option monad.\ 11 | 12 | theory 13 | Util 14 | imports 15 | Main 16 | "~~/src/HOL/Library/Monad_Syntax" 17 | begin 18 | 19 | subsection\Kleisli arrow composition\ 20 | 21 | definition kleisli :: "('b \ 'b option) \ ('b \ 'b option) \ ('b \ 'b option)" (infixr "\" 65) where 22 | "f \ g \ \x. (f x \ (\y. g y))" 23 | 24 | lemma kleisli_comm_cong: 25 | assumes "x \ y = y \ x" 26 | shows "z \ x \ y = z \ y \ x" 27 | using assms by(clarsimp simp add: kleisli_def) 28 | 29 | lemma kleisli_assoc: 30 | shows "(z \ x) \ y = z \ (x \ y)" 31 | by(auto simp add: kleisli_def) 32 | 33 | subsection\Lemmas about sets\ 34 | 35 | lemma distinct_set_notin [dest]: 36 | assumes "distinct (x#xs)" 37 | shows "x \ set xs" 38 | using assms by(induction xs, auto) 39 | 40 | lemma set_membership_equality_technicalD [dest]: 41 | assumes "{x} \ (set xs) = {y} \ (set ys)" 42 | shows "x = y \ y \ set xs" 43 | using assms by(induction xs, auto) 44 | 45 | lemma set_equality_technical: 46 | assumes "{x} \ (set xs) = {y} \ (set ys)" 47 | and "x \ set xs" 48 | and "y \ set ys" 49 | and "y \ set xs" 50 | shows "{x} \ (set xs - {y}) = set ys" 51 | using assms by (induction xs) auto 52 | 53 | lemma set_elem_nth: 54 | assumes "x \ set xs" 55 | shows "\m. m < length xs \ xs ! m = x" 56 | using assms by(induction xs, simp) (meson in_set_conv_nth) 57 | 58 | subsection\Lemmas about list\ 59 | 60 | lemma list_nil_or_snoc: 61 | shows "xs = [] \ (\y ys. xs = ys@[y])" 62 | by (induction xs, auto) 63 | 64 | lemma suffix_eq_distinct_list: 65 | assumes "distinct xs" 66 | and "ys@suf1 = xs" 67 | and "ys@suf2 = xs" 68 | shows "suf1 = suf2" 69 | using assms by(induction xs arbitrary: suf1 suf2 rule: rev_induct, simp) (metis append_eq_append_conv) 70 | 71 | lemma pre_suf_eq_distinct_list: 72 | assumes "distinct xs" 73 | and "ys \ []" 74 | and "pre1@ys@suf1 = xs" 75 | and "pre2@ys@suf2 = xs" 76 | shows "pre1 = pre2 \ suf1 = suf2" 77 | using assms 78 | apply(induction xs arbitrary: pre1 pre2 ys, simp) 79 | apply(case_tac "pre1"; case_tac "pre2"; clarify) 80 | apply(metis suffix_eq_distinct_list append_Nil) 81 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 82 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 83 | apply(metis distinct.simps(2) hd_append2 list.sel(1) list.sel(3) list.simps(3) tl_append2) 84 | done 85 | 86 | lemma list_head_unaffected: 87 | assumes "hd (x @ [y, z]) = v" 88 | shows "hd (x @ [y ]) = v" 89 | using assms by (metis hd_append list.sel(1)) 90 | 91 | lemma list_head_butlast: 92 | assumes "hd xs = v" 93 | and "length xs > 1" 94 | shows "hd (butlast xs) = v" 95 | using assms by (metis hd_conv_nth length_butlast length_greater_0_conv less_trans nth_butlast zero_less_diff zero_less_one) 96 | 97 | lemma list_head_length_one: 98 | assumes "hd xs = x" 99 | and "length xs = 1" 100 | shows "xs = [x]" 101 | using assms by(metis One_nat_def Suc_length_conv hd_Cons_tl length_0_conv list.sel(3)) 102 | 103 | lemma list_two_at_end: 104 | assumes "length xs > 1" 105 | shows "\xs' x y. xs = xs' @ [x, y]" 106 | using assms apply(induction xs rule: rev_induct, simp) 107 | apply(case_tac "length xs = 1", simp) 108 | apply(rule_tac x="[]" in exI, rule_tac x="hd xs" in exI) 109 | apply(simp_all add: list_head_length_one) 110 | apply(rule_tac x="butlast xs" in exI, rule_tac x="last xs" in exI, simp) 111 | done 112 | 113 | lemma list_nth_split_technical: 114 | assumes "m < length cs" 115 | and "cs \ []" 116 | shows "\xs ys. cs = xs@(cs!m)#ys" 117 | using assms 118 | apply(induction m arbitrary: cs) 119 | apply(meson in_set_conv_decomp nth_mem) 120 | apply(metis in_set_conv_decomp length_list_update set_swap set_update_memI) 121 | done 122 | 123 | lemma list_nth_split: 124 | assumes "m < length cs" 125 | and "n < m" 126 | and "1 < length cs" 127 | shows "\xs ys zs. cs = xs@(cs!n)#ys@(cs!m)#zs" 128 | using assms 129 | apply(induction n arbitrary: cs m) 130 | apply(rule_tac x="[]" in exI, clarsimp) 131 | apply(case_tac cs; clarsimp) 132 | apply(rule list_nth_split_technical, simp, force) 133 | apply(case_tac cs; clarsimp) 134 | apply(erule_tac x="list" in meta_allE, erule_tac x="m-1" in meta_allE) 135 | apply(subgoal_tac "m-1 < length list", subgoal_tac "n set cs" 143 | and "y \ set cs" 144 | and "x \ y" 145 | shows "\pre mid suf. cs = pre @ x # mid @ y # suf \ cs = pre @ y # mid @ x # suf" 146 | using assms 147 | apply(subgoal_tac "\xi. xi < length cs \ x = cs ! xi") 148 | apply(subgoal_tac "\yi. yi < length cs \ y = cs ! yi") 149 | apply clarsimp 150 | apply(subgoal_tac "xi \ yi") 151 | apply(case_tac "xi < yi") 152 | apply(metis list_nth_split One_nat_def less_Suc_eq linorder_neqE_nat not_less_zero) 153 | apply(subgoal_tac "yi < xi") 154 | apply(metis list_nth_split One_nat_def less_Suc_eq linorder_neqE_nat not_less_zero) 155 | using set_elem_nth linorder_neqE_nat apply fastforce+ 156 | done 157 | 158 | lemma split_list_unique_prefix: 159 | assumes "x \ set xs" 160 | shows "\pre suf. xs = pre @ x # suf \ (\y \ set pre. x \ y)" 161 | using assms 162 | apply(induction xs; clarsimp) 163 | apply(case_tac "a = x") 164 | apply(rule_tac x="[]" in exI, force) 165 | apply(subgoal_tac "x \ set xs", clarsimp) 166 | apply(rule_tac x="a # pre" in exI) 167 | apply force+ 168 | done 169 | 170 | lemma map_filter_append: 171 | shows "List.map_filter P (xs @ ys) = List.map_filter P xs @ List.map_filter P ys" 172 | by(auto simp add: List.map_filter_def) 173 | 174 | end -------------------------------------------------------------------------------- /src/Util.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Technical Lemmas\ 8 | 9 | text\This section contains a list of helper definitions and lemmas about sets, lists and 10 | the option monad.\ 11 | 12 | theory 13 | Util 14 | imports 15 | Main 16 | "HOL-Library.Monad_Syntax" 17 | begin 18 | 19 | subsection\Kleisli arrow composition\ 20 | 21 | definition kleisli :: "('b \ 'b option) \ ('b \ 'b option) \ ('b \ 'b option)" (infixr "\" 65) where 22 | "f \ g \ \x. (f x \ (\y. g y))" 23 | 24 | lemma kleisli_comm_cong: 25 | assumes "x \ y = y \ x" 26 | shows "z \ x \ y = z \ y \ x" 27 | using assms by(clarsimp simp add: kleisli_def) 28 | 29 | lemma kleisli_assoc: 30 | shows "(z \ x) \ y = z \ (x \ y)" 31 | by(auto simp add: kleisli_def) 32 | 33 | subsection\Lemmas about sets\ 34 | 35 | lemma distinct_set_notin [dest]: 36 | assumes "distinct (x#xs)" 37 | shows "x \ set xs" 38 | using assms by(induction xs, auto) 39 | 40 | lemma set_membership_equality_technicalD [dest]: 41 | assumes "{x} \ (set xs) = {y} \ (set ys)" 42 | shows "x = y \ y \ set xs" 43 | using assms by(induction xs, auto) 44 | 45 | lemma set_equality_technical: 46 | assumes "{x} \ (set xs) = {y} \ (set ys)" 47 | and "x \ set xs" 48 | and "y \ set ys" 49 | and "y \ set xs" 50 | shows "{x} \ (set xs - {y}) = set ys" 51 | using assms by (induction xs) auto 52 | 53 | lemma set_elem_nth: 54 | assumes "x \ set xs" 55 | shows "\m. m < length xs \ xs ! m = x" 56 | using assms by(induction xs, simp) (meson in_set_conv_nth) 57 | 58 | subsection\Lemmas about list\ 59 | 60 | lemma list_nil_or_snoc: 61 | shows "xs = [] \ (\y ys. xs = ys@[y])" 62 | by (induction xs, auto) 63 | 64 | lemma suffix_eq_distinct_list: 65 | assumes "distinct xs" 66 | and "ys@suf1 = xs" 67 | and "ys@suf2 = xs" 68 | shows "suf1 = suf2" 69 | using assms by(induction xs arbitrary: suf1 suf2 rule: rev_induct, simp) (metis append_eq_append_conv) 70 | 71 | lemma pre_suf_eq_distinct_list: 72 | assumes "distinct xs" 73 | and "ys \ []" 74 | and "pre1@ys@suf1 = xs" 75 | and "pre2@ys@suf2 = xs" 76 | shows "pre1 = pre2 \ suf1 = suf2" 77 | using assms 78 | apply(induction xs arbitrary: pre1 pre2 ys, simp) 79 | apply(case_tac "pre1"; case_tac "pre2"; clarify) 80 | apply(metis suffix_eq_distinct_list append_Nil) 81 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 82 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 83 | apply(metis distinct.simps(2) hd_append2 list.sel(1) list.sel(3) list.simps(3) tl_append2) 84 | done 85 | 86 | lemma list_head_unaffected: 87 | assumes "hd (x @ [y, z]) = v" 88 | shows "hd (x @ [y ]) = v" 89 | using assms by (metis hd_append list.sel(1)) 90 | 91 | lemma list_head_butlast: 92 | assumes "hd xs = v" 93 | and "length xs > 1" 94 | shows "hd (butlast xs) = v" 95 | using assms by (metis hd_conv_nth length_butlast length_greater_0_conv less_trans nth_butlast zero_less_diff zero_less_one) 96 | 97 | lemma list_head_length_one: 98 | assumes "hd xs = x" 99 | and "length xs = 1" 100 | shows "xs = [x]" 101 | using assms by(metis One_nat_def Suc_length_conv hd_Cons_tl length_0_conv list.sel(3)) 102 | 103 | lemma list_two_at_end: 104 | assumes "length xs > 1" 105 | shows "\xs' x y. xs = xs' @ [x, y]" 106 | using assms 107 | apply(induction xs rule: rev_induct, simp) 108 | apply(case_tac "length xs = 1", simp) 109 | apply(metis append_self_conv2 length_0_conv length_Suc_conv) 110 | apply(rule_tac x="butlast xs" in exI, rule_tac x="last xs" in exI, simp) 111 | done 112 | 113 | lemma list_nth_split_technical: 114 | assumes "m < length cs" 115 | and "cs \ []" 116 | shows "\xs ys. cs = xs@(cs!m)#ys" 117 | using assms 118 | apply(induction m arbitrary: cs) 119 | apply(meson in_set_conv_decomp nth_mem) 120 | apply(metis in_set_conv_decomp length_list_update set_swap set_update_memI) 121 | done 122 | 123 | lemma list_nth_split: 124 | assumes "m < length cs" 125 | and "n < m" 126 | and "1 < length cs" 127 | shows "\xs ys zs. cs = xs@(cs!n)#ys@(cs!m)#zs" 128 | using assms proof(induction n arbitrary: cs m) 129 | case 0 thus ?case 130 | apply(case_tac cs; clarsimp) 131 | apply(rule_tac x="[]" in exI, clarsimp) 132 | apply(rule list_nth_split_technical, simp, force) 133 | done 134 | next 135 | case (Suc n) 136 | thus ?case 137 | proof (cases cs) 138 | case Nil 139 | then show ?thesis 140 | using Suc.prems by auto 141 | next 142 | case (Cons a as) 143 | hence "m-1 < length as" "n < m-1" 144 | using Suc by force+ 145 | then obtain xs ys zs where "as = xs @ as ! n # ys @ as ! (m-1) # zs" 146 | using Suc by force 147 | thus ?thesis 148 | apply(rule_tac x="a#xs" in exI) 149 | using Suc Cons apply force 150 | done 151 | qed 152 | qed 153 | 154 | lemma list_split_two_elems: 155 | assumes "distinct cs" 156 | and "x \ set cs" 157 | and "y \ set cs" 158 | and "x \ y" 159 | shows "\pre mid suf. cs = pre @ x # mid @ y # suf \ cs = pre @ y # mid @ x # suf" 160 | proof - 161 | obtain xi yi where *: "xi < length cs \ x = cs ! xi" "yi < length cs \ y = cs ! yi" "xi \ yi" 162 | using set_elem_nth linorder_neqE_nat assms by metis 163 | thus ?thesis 164 | by (metis list_nth_split One_nat_def less_Suc_eq linorder_neqE_nat not_less_zero) 165 | qed 166 | 167 | lemma split_list_unique_prefix: 168 | assumes "x \ set xs" 169 | shows "\pre suf. xs = pre @ x # suf \ (\y \ set pre. x \ y)" 170 | using assms proof(induction xs) 171 | case Nil thus ?case by clarsimp 172 | next 173 | case (Cons y ys) 174 | then show ?case 175 | proof (cases "y=x") 176 | case True 177 | then show ?thesis by force 178 | next 179 | case False 180 | then obtain pre suf where "ys = pre @ x # suf \ (\y\set pre. x \ y)" 181 | using assms Cons by auto 182 | thus ?thesis 183 | using split_list_first by force 184 | qed 185 | qed 186 | 187 | lemma map_filter_append: 188 | shows "List.map_filter P (xs @ ys) = List.map_filter P xs @ List.map_filter P ys" 189 | by(auto simp add: List.map_filter_def) 190 | 191 | end 192 | -------------------------------------------------------------------------------- /src/AFP/Util.thy: -------------------------------------------------------------------------------- 1 | (* Victor B. F. Gomes, University of Cambridge 2 | Martin Kleppmann, University of Cambridge 3 | Dominic P. Mulligan, University of Cambridge 4 | Alastair R. Beresford, University of Cambridge 5 | *) 6 | 7 | section\Technical Lemmas\ 8 | 9 | text\This section contains a list of helper definitions and lemmas about sets, lists and 10 | the option monad.\ 11 | 12 | theory 13 | Util 14 | imports 15 | Main 16 | "~~/src/HOL/Library/Monad_Syntax" 17 | begin 18 | 19 | subsection\Kleisli arrow composition\ 20 | 21 | definition kleisli :: "('b \ 'b option) \ ('b \ 'b option) \ ('b \ 'b option)" (infixr "\" 65) where 22 | "f \ g \ \x. (f x \ (\y. g y))" 23 | 24 | lemma kleisli_comm_cong: 25 | assumes "x \ y = y \ x" 26 | shows "z \ x \ y = z \ y \ x" 27 | using assms by(clarsimp simp add: kleisli_def) 28 | 29 | lemma kleisli_assoc: 30 | shows "(z \ x) \ y = z \ (x \ y)" 31 | by(auto simp add: kleisli_def) 32 | 33 | subsection\Lemmas about sets\ 34 | 35 | lemma distinct_set_notin [dest]: 36 | assumes "distinct (x#xs)" 37 | shows "x \ set xs" 38 | using assms by(induction xs, auto) 39 | 40 | lemma set_membership_equality_technicalD [dest]: 41 | assumes "{x} \ (set xs) = {y} \ (set ys)" 42 | shows "x = y \ y \ set xs" 43 | using assms by(induction xs, auto) 44 | 45 | lemma set_equality_technical: 46 | assumes "{x} \ (set xs) = {y} \ (set ys)" 47 | and "x \ set xs" 48 | and "y \ set ys" 49 | and "y \ set xs" 50 | shows "{x} \ (set xs - {y}) = set ys" 51 | using assms by (induction xs) auto 52 | 53 | lemma set_elem_nth: 54 | assumes "x \ set xs" 55 | shows "\m. m < length xs \ xs ! m = x" 56 | using assms by(induction xs, simp) (meson in_set_conv_nth) 57 | 58 | subsection\Lemmas about list\ 59 | 60 | lemma list_nil_or_snoc: 61 | shows "xs = [] \ (\y ys. xs = ys@[y])" 62 | by (induction xs, auto) 63 | 64 | lemma suffix_eq_distinct_list: 65 | assumes "distinct xs" 66 | and "ys@suf1 = xs" 67 | and "ys@suf2 = xs" 68 | shows "suf1 = suf2" 69 | using assms by(induction xs arbitrary: suf1 suf2 rule: rev_induct, simp) (metis append_eq_append_conv) 70 | 71 | lemma pre_suf_eq_distinct_list: 72 | assumes "distinct xs" 73 | and "ys \ []" 74 | and "pre1@ys@suf1 = xs" 75 | and "pre2@ys@suf2 = xs" 76 | shows "pre1 = pre2 \ suf1 = suf2" 77 | using assms 78 | apply(induction xs arbitrary: pre1 pre2 ys, simp) 79 | apply(case_tac "pre1"; case_tac "pre2"; clarify) 80 | apply(metis suffix_eq_distinct_list append_Nil) 81 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 82 | apply(metis Un_iff append_eq_Cons_conv distinct.simps(2) list.set_intros(1) set_append suffix_eq_distinct_list) 83 | apply(metis distinct.simps(2) hd_append2 list.sel(1) list.sel(3) list.simps(3) tl_append2) 84 | done 85 | 86 | lemma list_head_unaffected: 87 | assumes "hd (x @ [y, z]) = v" 88 | shows "hd (x @ [y ]) = v" 89 | using assms by (metis hd_append list.sel(1)) 90 | 91 | lemma list_head_butlast: 92 | assumes "hd xs = v" 93 | and "length xs > 1" 94 | shows "hd (butlast xs) = v" 95 | using assms by (metis hd_conv_nth length_butlast length_greater_0_conv less_trans nth_butlast zero_less_diff zero_less_one) 96 | 97 | lemma list_head_length_one: 98 | assumes "hd xs = x" 99 | and "length xs = 1" 100 | shows "xs = [x]" 101 | using assms by(metis One_nat_def Suc_length_conv hd_Cons_tl length_0_conv list.sel(3)) 102 | 103 | lemma list_two_at_end: 104 | assumes "length xs > 1" 105 | shows "\xs' x y. xs = xs' @ [x, y]" 106 | using assms 107 | apply(induction xs rule: rev_induct, simp) 108 | apply(case_tac "length xs = 1", simp) 109 | apply(metis append_self_conv2 length_0_conv length_Suc_conv) 110 | apply(rule_tac x="butlast xs" in exI, rule_tac x="last xs" in exI, simp) 111 | done 112 | 113 | lemma list_nth_split_technical: 114 | assumes "m < length cs" 115 | and "cs \ []" 116 | shows "\xs ys. cs = xs@(cs!m)#ys" 117 | using assms 118 | apply(induction m arbitrary: cs) 119 | apply(meson in_set_conv_decomp nth_mem) 120 | apply(metis in_set_conv_decomp length_list_update set_swap set_update_memI) 121 | done 122 | 123 | lemma list_nth_split: 124 | assumes "m < length cs" 125 | and "n < m" 126 | and "1 < length cs" 127 | shows "\xs ys zs. cs = xs@(cs!n)#ys@(cs!m)#zs" 128 | using assms proof(induction n arbitrary: cs m) 129 | case 0 thus ?case 130 | apply(case_tac cs; clarsimp) 131 | apply(rule_tac x="[]" in exI, clarsimp) 132 | apply(rule list_nth_split_technical, simp, force) 133 | done 134 | next 135 | case (Suc n) 136 | thus ?case 137 | proof (cases cs) 138 | case Nil 139 | then show ?thesis 140 | using Suc.prems by auto 141 | next 142 | case (Cons a as) 143 | hence "m-1 < length as" "n < m-1" 144 | using Suc by force+ 145 | then obtain xs ys zs where "as = xs @ as ! n # ys @ as ! (m-1) # zs" 146 | using Suc by force 147 | thus ?thesis 148 | apply(rule_tac x="a#xs" in exI) 149 | using Suc Cons apply force 150 | done 151 | qed 152 | qed 153 | 154 | lemma list_split_two_elems: 155 | assumes "distinct cs" 156 | and "x \ set cs" 157 | and "y \ set cs" 158 | and "x \ y" 159 | shows "\pre mid suf. cs = pre @ x # mid @ y # suf \ cs = pre @ y # mid @ x # suf" 160 | proof - 161 | obtain xi yi where *: "xi < length cs \ x = cs ! xi" "yi < length cs \ y = cs ! yi" "xi \ yi" 162 | using set_elem_nth linorder_neqE_nat assms by metis 163 | thus ?thesis 164 | by (metis list_nth_split One_nat_def less_Suc_eq linorder_neqE_nat not_less_zero) 165 | qed 166 | 167 | lemma split_list_unique_prefix: 168 | assumes "x \ set xs" 169 | shows "\pre suf. xs = pre @ x # suf \ (\y \ set pre. x \ y)" 170 | using assms proof(induction xs) 171 | case Nil thus ?case by clarsimp 172 | next 173 | case (Cons y ys) 174 | then show ?case 175 | proof (cases "y=x") 176 | case True 177 | then show ?thesis by force 178 | next 179 | case False 180 | then obtain pre suf where "ys = pre @ x # suf \ (\y\set pre. x \ y)" 181 | using assms Cons by auto 182 | thus ?thesis 183 | using split_list_first by force 184 | qed 185 | qed 186 | 187 | lemma map_filter_append: 188 | shows "List.map_filter P (xs @ ys) = List.map_filter P xs @ List.map_filter P ys" 189 | by(auto simp add: List.map_filter_def) 190 | 191 | end -------------------------------------------------------------------------------- /paper/isabelle.tex: -------------------------------------------------------------------------------- 1 | \section{An Introduction to Isabelle} 2 | \label{subsect.an.overview.of.isabelle} 3 | 4 | We now provide a brief introduction to the key concepts and syntax of Isabelle/HOL. 5 | Familiar readers may skip to Section~\ref{sect.abstract.convergence}. 6 | A more detailed introduction can be found in the standard tutorial material~\cite{DBLP:books/sp/NipkowK14}. 7 | 8 | \paragraph{Syntax of expressions.} 9 | 10 | Isabelle/HOL is a logic with a strict, polymorphic, inferred type system. 11 | \emph{Function types} are written $\tau_1 \Rightarrow \tau_2$, and are inhabited by \emph{total} functions, mapping elements of $\tau_1$ to elements of $\tau_2$. 12 | We write $\tau_1 \times \tau_2$ for the \emph{product type} of $\tau_1$ and $\tau_2$, inhabited by pairs of elements of type $\tau_1$ and $\tau_2$, respectively. 13 | In a similar fashion to Standard ML and OCaml, \emph{type operators} are applied to arguments in reverse order, and therefore $\tau\ \isa{list}$ denotes the type of lists of elements of type $\tau$, and $\tau\ \isa{set}$ denotes the type of mathematical (i.e., potentially infinite) sets of type $\tau$. 14 | Type variables are written in lowercase, and preceded with a prime: ${\isacharprime}a \Rightarrow {\isacharprime}a$ denotes the type of a polymorphic identity function, for example. 15 | \emph{Tagged union} types are introduced with the $\isacommand{datatype}$ keyword, with constructors of these types usually written with an initial upper case letter. 16 | 17 | In Isabelle/HOL's term language we write $\isa{t} \mathbin{::} \tau$ for a \emph{type ascription}, constraining the type of the term $\isa{t}$ to the type $\tau$. 18 | We write $\lambda{x}.\: t$ for an anonymous function mapping an argument $\isa{x}$ to $\isa{t(x)}$, and write the application of term $\isa{t}$ with function type to an argument $\isa{u}$ as $\isa{t\ u}$, as usual. 19 | Terms of list type are introduced using one of two constructors: the empty list $[\,]$ or `nil', and the infix operator $\isa{\#}$ which is pronounced ``cons'', and which prepends an element to an existing list. 20 | We use $[t_1, \ldots, t_n]$ as syntactic sugar for a list literal, and $\isa{xs} \mathbin{\isacharat} \isa{ys}$ to express the concatenation (appending) of two lists $\isa{xs}$ and $\isa{ys}$. 21 | We write $\{\,\}$ for the empty set, and use usual mathematical notation for set union, disjunction, membership tests, and so on: $\isa{t} \cup \isa{u}$, $\isa{t} \cap \isa{u}$, and $\isa{x} \in \isa{t}$. 22 | We write $t \longrightarrow s$ for logical implication between formulae (terms of type $\isa{bool}$). 23 | Strictly speaking Isabelle is a logical framework, providing a weak meta-logic within which object logics are embedded, including the Isabelle/HOL object logic that we use in this work. 24 | Accordingly, the implication arrow of Isabelle's meta-logic, $\isa{t} \Longrightarrow \isa{u}$, is required in certain contexts over the object-logic implication arrow, $t \longrightarrow s$, already introduced. 25 | However, for purposes of an intuitive understanding, the two forms of implication can be regarded as equivalent by the reader, with the requirement to use one over the other merely being an implementation detail of Isabelle itself. 26 | We will sometimes use the shorthand ${\isasymlbrakk}\isa{H}_1{\isacharsemicolon}\ \ldots{\isacharsemicolon}\ \isa{H}_n{\isasymrbrakk}\ {\isasymLongrightarrow}\ C$ instead of iterated meta-logic implications, i.e., $H_1\ {\isasymLongrightarrow}\ \ldots\ {\isasymLongrightarrow}\ H_n\ {\isasymLongrightarrow}\ C$. 27 | 28 | \paragraph{Definitions and theorems.} 29 | 30 | New non-recursive definitions are entered into Isabelle's global context using the $\mathbf{definition}$ keyword. 31 | Recursive functions are defined using the $\mathbf{fun}$ keyword, and support pattern matching on their arguments. 32 | All functions are total, and therefore every recursive function must be provably terminating. 33 | The termination proofs in this work are generated automatically by Isabelle itself. 34 | 35 | Inductive relations are defined with the $\mathbf{inductive}$ keyword. 36 | For example, the definition 37 | \begin{isabelle} 38 | \isacommand{inductive} only-fives\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ list\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\\ 39 | ~~~~{\isachardoublequoteopen}only-fives\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequoteclose}\ {\isacharbar}\\ 40 | ~~~~{\isachardoublequoteopen}{\isasymlbrakk}\ only-fives\ xs\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ only-fives {\isacharparenleft}5\#xs{\isacharparenright}{\isachardoublequoteclose} 41 | \end{isabelle} 42 | \noindent 43 | introduces a new constant $\isa{only-fives}$ of type $\isa{nat list} \Rightarrow \isa{bool}$. 44 | The two clauses in the body of the definition enumerate the conditions under which $\isa{only-fives}\ \isa{xs}$ is true, for arbitrary $\isa{xs}$: firstly, $\isa{only-fives}$ is true for the empty list; and secondly, if you know that $\isa{only-fives}\ \isa{xs}$ is true for some $\isa{xs}$, then you can deduce that $\isa{only-fives}\ (5\#\isa{xs})$ (i.e., $\isa{xs}$ prefixed with the number 5) is also true. 45 | Moreover, $\isa{only-fives}\ \isa{xs}$ is true in no other circumstances---it is the \emph{smallest} relation closed under the rules defining it. 46 | In short, the clauses above state that $\isa{only-fives}\ \isa{xs}$ holds exactly in the case where $\isa{xs}$ is a (potentially empty) list containing only repeated copies of the natural number $5$. 47 | 48 | Lemmas, theorems, and corollaries can be asserted using the $\isacommand{lemma}$, $\isacommand{theorem}$, and $\isacommand{corollary}$ keywords, respectively. 49 | There is no semantic difference between these keywords in Isabelle. 50 | For example, 51 | \begin{isabelle} 52 | ~~~~\isakeyword{assumes}\ \=\kill 53 | \isacommand{theorem} only-fives-concat{\isacharcolon}\\ 54 | ~~~~\isakeyword{assumes}\>only-fives\ xs \isakeyword{and}\ only-fives\ ys\\ 55 | ~~~~\isakeyword{shows}\>only-fives (xs \isacharat ys) 56 | \end{isabelle} 57 | \noindent 58 | conjectures that if $\isa{xs}$ and $\isa{ys}$ are both lists of fives, then their concatenation $xs \mathbin{\isacharat} ys$ is also a list of fives. 59 | Isabelle then requires that this claim be proved by using one of its proof methods, for example by induction. 60 | Some proofs can be automated, whilst others require the user to provide explicit reasoning steps. 61 | The theorem is assigned a name, here $\isa{only-fives-concat}$, so that it may be referenced in later proofs. 62 | 63 | \paragraph{Locales.} 64 | 65 | Lastly, we use \emph{locales}---or local theories~\cite{DBLP:conf/tphol/KammullerWP99,DBLP:conf/types/HaftmannW08}---extensively to structure the proof, as shown in Figure~\ref{fig.proof.structure}. 66 | In programming terms, Isabelle's locales may be thought of as an interface with associated laws that implementations must obey. 67 | In particular, a declaration of the form 68 | \begin{isabelle} 69 | ~~~~\isakeyword{assumes}\ \=\kill 70 | \isacommand{locale} semigroup =\\ 71 | ~~~~\isakeyword{fixes}\>f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\\ 72 | ~~~~\isakeyword{assumes}\>{\isachardoublequoteopen}f\ x\ (f\ y\ z)\ =\ f\ (f\ x\ y)\ z{\isachardoublequoteclose} 73 | \end{isabelle} 74 | \noindent 75 | introduces a locale, with a fixed, typed constant $\isa{f}$, and a law asserting that $\isa{f}$ is associative. 76 | Functions and constants may now be defined, and theorems conjectured and proved, within the context of the $\isa{semigoup}$ locale, i.e. definitions may be made ``generic'' in a semigroup. 77 | This is indicated syntactically by writing $(\isacommand{in}\ \isa{semigroup})$ before the name of the constant being defined, or the theorem being conjectured, at the point of definition or conjecture. 78 | Any function, constant, or theorem, marked in this way may make reference to $\isa{f}$, or the fact that $\isa{f}$ is associative. 79 | \emph{Interpreting} a locale---such as $\isa{semigroup}$ above---involves providing a concrete implementation of $\isa{f}$ coupled with a proof that the concrete implementation satisfies the associated law, and is akin to implementing an interface. 80 | Once interpreted, all functions, definitions, and theorems made within the $\isa{semigroup}$ locale become available to use for that concrete implementation. 81 | Like interfaces, locales may be extended with new functionality, and may be specialised, by other ``sublocales'', forming a hierarchy. 82 | -------------------------------------------------------------------------------- /paper/acmart-pacmpl-template.tex: -------------------------------------------------------------------------------- 1 | %% For double-blind review submission 2 | \documentclass[acmlarge,review,anonymous]{acmart}\settopmatter{printfolios=true} 3 | %% For single-blind review submission 4 | %\documentclass[acmlarge,review]{acmart}\settopmatter{printfolios=true} 5 | %% For final camera-ready submission 6 | %\documentclass[acmlarge]{acmart}\settopmatter{} 7 | 8 | %% Note: Authors migrating a paper from PACMPL format to traditional 9 | %% SIGPLAN proceedings format should change 'acmlarge' to 10 | %% 'sigplan,10pt'. 11 | 12 | 13 | %% Some recommended packages. 14 | \usepackage{booktabs} %% For formal tables: 15 | %% http://ctan.org/pkg/booktabs 16 | \usepackage{subcaption} %% For complex figures with subfigures/subcaptions 17 | %% http://ctan.org/pkg/subcaption 18 | 19 | 20 | \makeatletter\if@ACM@journal\makeatother 21 | %% Journal information (used by PACMPL format) 22 | %% Supplied to authors by publisher for camera-ready submission 23 | \acmJournal{PACMPL} 24 | \acmVolume{1} 25 | \acmNumber{1} 26 | \acmArticle{1} 27 | \acmYear{2017} 28 | \acmMonth{1} 29 | \acmDOI{10.1145/nnnnnnn.nnnnnnn} 30 | \startPage{1} 31 | \else\makeatother 32 | %% Conference information (used by SIGPLAN proceedings format) 33 | %% Supplied to authors by publisher for camera-ready submission 34 | \acmConference[PL'17]{ACM SIGPLAN Conference on Programming Languages}{January 01--03, 2017}{New York, NY, USA} 35 | \acmYear{2017} 36 | \acmISBN{978-x-xxxx-xxxx-x/YY/MM} 37 | \acmDOI{10.1145/nnnnnnn.nnnnnnn} 38 | \startPage{1} 39 | \fi 40 | 41 | 42 | %% Copyright information 43 | %% Supplied to authors (based on authors' rights management selection; 44 | %% see authors.acm.org) by publisher for camera-ready submission 45 | \setcopyright{none} %% For review submission 46 | %\setcopyright{acmcopyright} 47 | %\setcopyright{acmlicensed} 48 | %\setcopyright{rightsretained} 49 | %\copyrightyear{2017} %% If different from \acmYear 50 | 51 | 52 | %% Bibliography style 53 | \bibliographystyle{ACM-Reference-Format} 54 | %% Citation style 55 | %% Note: author/year citations are required for papers published as an 56 | %% issue of PACMPL. 57 | \citestyle{acmauthoryear} %% For author/year citations 58 | 59 | 60 | 61 | \begin{document} 62 | 63 | %% Title information 64 | \title[Short Title]{Full Title} %% [Short Title] is optional; 65 | %% when present, will be used in 66 | %% header instead of Full Title. 67 | \titlenote{with title note} %% \titlenote is optional; 68 | %% can be repeated if necessary; 69 | %% contents suppressed with 'anonymous' 70 | \subtitle{Subtitle} %% \subtitle is optional 71 | \subtitlenote{with subtitle note} %% \subtitlenote is optional; 72 | %% can be repeated if necessary; 73 | %% contents suppressed with 'anonymous' 74 | 75 | 76 | %% Author information 77 | %% Contents and number of authors suppressed with 'anonymous'. 78 | %% Each author should be introduced by \author, followed by 79 | %% \authornote (optional), \orcid (optional), \affiliation, and 80 | %% \email. 81 | %% An author may have multiple affiliations and/or emails; repeat the 82 | %% appropriate command. 83 | %% Many elements are not rendered, but should be provided for metadata 84 | %% extraction tools. 85 | 86 | %% Author with single affiliation. 87 | \author{First1 Last1} 88 | \authornote{with author1 note} %% \authornote is optional; 89 | %% can be repeated if necessary 90 | \orcid{nnnn-nnnn-nnnn-nnnn} %% \orcid is optional 91 | \affiliation{ 92 | \position{Position1} 93 | \department{Department1} %% \department is recommended 94 | \institution{Institution1} %% \institution is required 95 | \streetaddress{Street1 Address1} 96 | \city{City1} 97 | \state{State1} 98 | \postcode{Post-Code1} 99 | \country{Country1} 100 | } 101 | \email{first1.last1@inst1.edu} %% \email is recommended 102 | 103 | %% Author with two affiliations and emails. 104 | \author{First2 Last2} 105 | \authornote{with author2 note} %% \authornote is optional; 106 | %% can be repeated if necessary 107 | \orcid{nnnn-nnnn-nnnn-nnnn} %% \orcid is optional 108 | \affiliation{ 109 | \position{Position2a} 110 | \department{Department2a} %% \department is recommended 111 | \institution{Institution2a} %% \institution is required 112 | \streetaddress{Street2a Address2a} 113 | \city{City2a} 114 | \state{State2a} 115 | \postcode{Post-Code2a} 116 | \country{Country2a} 117 | } 118 | \email{first2.last2@inst2a.com} %% \email is recommended 119 | \affiliation{ 120 | \position{Position2b} 121 | \department{Department2b} %% \department is recommended 122 | \institution{Institution2b} %% \institution is required 123 | \streetaddress{Street3b Address2b} 124 | \city{City2b} 125 | \state{State2b} 126 | \postcode{Post-Code2b} 127 | \country{Country2b} 128 | } 129 | \email{first2.last2@inst2b.org} %% \email is recommended 130 | 131 | 132 | %% Paper note 133 | %% The \thanks command may be used to create a "paper note" --- 134 | %% similar to a title note or an author note, but not explicitly 135 | %% associated with a particular element. It will appear immediately 136 | %% above the permission/copyright statement. 137 | \thanks{with paper note} %% \thanks is optional 138 | %% can be repeated if necesary 139 | %% contents suppressed with 'anonymous' 140 | 141 | 142 | %% Abstract 143 | %% Note: \begin{abstract}...\end{abstract} environment must come 144 | %% before \maketitle command 145 | \begin{abstract} 146 | Text of abstract \ldots. 147 | \end{abstract} 148 | 149 | 150 | %% 2012 ACM Computing Classification System (CSS) concepts 151 | %% Generate at 'http://dl.acm.org/ccs/ccs.cfm'. 152 | \begin{CCSXML} 153 | 154 | 155 | 10011007.10011006.10011008 156 | Software and its engineering~General programming languages 157 | 500 158 | 159 | 160 | 10003456.10003457.10003521.10003525 161 | Social and professional topics~History of programming languages 162 | 300 163 | 164 | 165 | \end{CCSXML} 166 | 167 | \ccsdesc[500]{Software and its engineering~General programming languages} 168 | \ccsdesc[300]{Social and professional topics~History of programming languages} 169 | %% End of generated code 170 | 171 | 172 | %% Keywords 173 | %% comma separated list 174 | \keywords{keyword1, keyword2, keyword3} %% \keywords is optional 175 | 176 | 177 | %% \maketitle 178 | %% Note: \maketitle command must come after title commands, author 179 | %% commands, abstract environment, Computing Classification System 180 | %% environment and commands, and keywords command. 181 | \maketitle 182 | 183 | 184 | \section{Introduction} 185 | 186 | Text of paper \ldots 187 | 188 | 189 | %% Acknowledgments 190 | \begin{acks} %% acks environment is optional 191 | %% contents suppressed with 'anonymous' 192 | %% Commands \grantsponsor{}{}{} and 193 | %% \grantnum[]{}{} should be used to 194 | %% acknowledge financial support and will be used by metadata 195 | %% extraction tools. 196 | This material is based upon work supported by the 197 | \grantsponsor{GS100000001}{National Science 198 | Foundation}{http://dx.doi.org/10.13039/100000001} under Grant 199 | No.~\grantnum{GS100000001}{nnnnnnn} and Grant 200 | No.~\grantnum{GS100000001}{mmmmmmm}. Any opinions, findings, and 201 | conclusions or recommendations expressed in this material are those 202 | of the author and do not necessarily reflect the views of the 203 | National Science Foundation. 204 | \end{acks} 205 | 206 | 207 | %% Bibliography 208 | %\bibliography{bibfile} 209 | 210 | 211 | %% Appendix 212 | \appendix 213 | \section{Appendix} 214 | 215 | Text of appendix \ldots 216 | 217 | \end{document} 218 | -------------------------------------------------------------------------------- /paper/splash-reviews.txt: -------------------------------------------------------------------------------- 1 | =========================================================================== 2 | OOPSLA'17 Review #94A 3 | --------------------------------------------------------------------------- 4 | Paper #94: Verifying Strong Eventual Consistency in Distributed Systems 5 | --------------------------------------------------------------------------- 6 | 7 | Overall merit: A. Good paper, I will champion it 8 | Confidence: Y. I am knowledgeable in this area, 9 | but not an expert 10 | 11 | ===== Paper summary ===== 12 | 13 | The paper provides a formal treatment of the issue of consistency in distributed systems. More specifically, the authors provide a formal foundation for “strong eventual consistency”, a model that states that at any time, network nodes that received the same set of updates up to that time must have converged to the same state. 14 | 15 | The authors indicate that proving consistency algorithms correct is a tricky business, with failed past attempts because of invalid assumptions made of real computer networks. To avoid this flaw, the authors first define a mechanized general formal model of asynchronous networks. This formal model is then extended to provide proofs of correctness for three existing conflict-free replicated data types (CRDTs): a counter, an observed-remove set and a replicated growable array (i.e. an ordered list). The formalisation starts from an abstract convergence theorem that provides insight into why strong eventual consistency protocols work. The proof strategy is general and follows the same pattern for all three CRDT proofs, indicating it may be applicable to future proofs and showcasing the foundational nature of the work. 16 | 17 | The authors also claim to provide the first mechanised proof of operation-based CRDTs in general. 18 | 19 | All proofs have been mechanised using the Isabelle/HOL proof assistant (and attached as supplementary material). 20 | 21 | ===== Comments for author ===== 22 | 23 | Points in favor: 24 | 25 | * The paper tackles a fundamental and important problem in distributed systems. 26 | * The authors have taken care that the paper remains accessible even to readers that are not deep experts in formal correctness proofs. For instance, the general introduction to Isabelle/HOL (section 3) makes the paper stand largely on its own. 27 | * The proof strategy is first laid out at a high-level, and the rest of the paper faithfully follows this general strategy. Despite the complexity of the subject matter, the paper is well-written and the content remains accessible. 28 | * The authors do a good job of putting the work in context and citing relevant and appropriate related work. 29 | 30 | General remarks: 31 | 32 | In the abstract and section 1, the authors highlight that past peer-reviewed publications have claimed mechanised proofs of correctness for consistency models that have later been disproven. However, it is unclear from the given citations what work proposed the flawed results and what work disproved those results. It becomes much clearer in Section 8.2. My advice would be to do a slight rewording and making the citations more explicit in section 1 (or perhaps put a forward reference to sec 8.2 so the reader knows this explanation is coming). 33 | 34 | Continuing with section 8.2, given that this section is really key to one of the main points of the paper (namely that past attempts at formalising SEC were flawed), it would be helpful to provide a bit more intuition on what TP1 and TP2 refer to, and why it is that TP2 is so problematic. 35 | 36 | Detailed comments: 37 | 38 | page 1: “and there have even been examples of mechanised formal proofs of SEC algorithm correctness later being shown to be flawed.” => this sentence should be followed by a citation to support the claim. 39 | 40 | Section 5: it wasn’t entirely clear to me why the modeled primitive event for communication is a broadcast rather than a unicast. Is it because the most common type of communication is to broadcast an update to all replicas? Is it because broadcast is the most general and subsumes unicast? (in the sense that it’s allowed behaviour for a ‘broadcast’ event to generate only 1 subsequent ‘deliver’ event in another node) 41 | 42 | page 13, line 42, typo: “Is a little more” => “It is a little more” 43 | 44 | page 20, lines 13-14: what you describe here seems to be an initial empirical evaluation of the work (trying to establish that an implementation based on the proofs is actually correct and robust in real networks). This could benefit from more explanation. In particular, I wonder if you used (or are considering using) a tool like Kyle Kingsbury’s Jepsen to induce network partitions. 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | =========================================================================== 53 | OOPSLA'17 Review #94B 54 | --------------------------------------------------------------------------- 55 | Paper #94: Verifying Strong Eventual Consistency in Distributed Systems 56 | --------------------------------------------------------------------------- 57 | 58 | Overall merit: A. Good paper, I will champion it 59 | Confidence: Y. I am knowledgeable in this area, 60 | but not an expert 61 | 62 | ===== Paper summary ===== 63 | 64 | This paper presents a self-contained set of Isabelle definitions 65 | and theorems showing that three CRDTs obey Strong Eventual 66 | Consistency. 67 | 68 | ===== Comments for author ===== 69 | 70 | 71 | The paper presents useful results, and in doing so, it establishes a 72 | basis for others to show similar properties of similar alorithms. 73 | 74 | The presentation is really good for this kind of paper. It keeps 75 | readers attention, with enough anticipation to follow the main lines 76 | of argument/derivation. Rationales for each step are nicely presented. 77 | I'm not an expert in Isabelle (but have read enough Isabelle proofs to 78 | have basic familiarity), so I might not (and did not) notice technical 79 | flaws. 80 | 81 | It might be informative to show an example of how an attempted proof 82 | of a faulty algorithm goes wrong. 83 | 84 | Some discussion of the robustness of algorithms to minor variations in 85 | infrastructure assumptions might be informative. For example, what if 86 | read-your-own-writes is not strictly enforced?. 87 | 88 | Page 5: I've never learned exactly how thin/thick implication arrows 89 | differ, and still don't know. Do us a favor and briefly explain. 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | =========================================================================== 98 | OOPSLA'17 Review #94C 99 | --------------------------------------------------------------------------- 100 | Paper #94: Verifying Strong Eventual Consistency in Distributed Systems 101 | --------------------------------------------------------------------------- 102 | 103 | Overall merit: A. Good paper, I will champion it 104 | Confidence: Z. I am not an expert; my evaluation 105 | is that of an informed outsider 106 | 107 | ===== Paper summary ===== 108 | 109 | The problem that this paper is addressing is verifying the correctness of algorithms for maintaining up-to-date copies of shared data across multiple computers. 110 | 111 | This problem is important because data replication is key to supporting fault tolerance in distributed systems. As mentioned in the paper, algorithms for achieving consistency in replicated systems are still poorly understood. Furthermore, many published algorithms have later been shown to be incorrect, even for those accompanied with mechanized proofs of correctness. 112 | 113 | The proposed solution is a modular and reusable framework in the Isabelle/HOL interactive proof assistant for verifying the correctness of Conflict-free Replicated Data Types (CRDT) algorithms. 114 | 115 | The claimed benefit of this approach is that the framework is highly reusable, developing proofs of correctness for the later two CRDTs in a few hours and with relatively little CRDT-specific code. 116 | 117 | The authors validate their claims by applying their framework to prove well-known operation-based CRDTs: the Observed-Remove Set and the Increment-Decrement Counter. Increment-Decrement Counter was proved correct in a matter of minutes. The specification and correctness proof for Observed-Remove Set was performed in about four hours. 118 | 119 | ===== Comments for author ===== 120 | 121 | The paper is well written and presents informative and convincing results. The framework helps for others prove related properties for similar algorithms. The Isabelle introduction enables the paper to be self-contained. 122 | 123 | 124 | -------------------------------------------------------------------------------- /paper/isabelle.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% macros for Isabelle generated LaTeX output 3 | %% 4 | 5 | %%% Simple document preparation (based on theory token language and symbols) 6 | 7 | % isabelle environments 8 | 9 | \newcommand{\isabellecontext}{UNKNOWN} 10 | \newcommand{\setisabellecontext}[1]{\def\isabellecontext{#1}} 11 | 12 | \newcommand{\isastyle}{\UNDEF} 13 | \newcommand{\isastylett}{\UNDEF} 14 | \newcommand{\isastyleminor}{\UNDEF} 15 | \newcommand{\isastyleminortt}{\UNDEF} 16 | \newcommand{\isastylescript}{\UNDEF} 17 | \newcommand{\isastyletext}{\normalsize\rm} 18 | \newcommand{\isastyletxt}{\rm} 19 | \newcommand{\isastylecmt}{\rm} 20 | 21 | \newcommand{\isaspacing}{% 22 | \sfcode 42 1000 % . 23 | \sfcode 63 1000 % ? 24 | \sfcode 33 1000 % ! 25 | \sfcode 58 1000 % : 26 | \sfcode 59 1000 % ; 27 | \sfcode 44 1000 % , 28 | } 29 | 30 | %symbol markup -- \emph achieves decent spacing via italic corrections 31 | \newcommand{\isamath}[1]{\emph{$#1$}} 32 | \newcommand{\isatext}[1]{\emph{#1}} 33 | \DeclareRobustCommand{\isascriptstyle}{\def\isamath##1{##1}\def\isatext##1{\mbox{\isaspacing\isastylescript##1}}} 34 | \newcommand{\isactrlsub}[1]{\emph{\isascriptstyle${}\sb{#1}$}} 35 | \newcommand{\isactrlsup}[1]{\emph{\isascriptstyle${}\sp{#1}$}} 36 | \DeclareRobustCommand{\isactrlbsub}{\emph\bgroup\math{}\sb\bgroup\mbox\bgroup\isaspacing\isastylescript} 37 | \DeclareRobustCommand{\isactrlesub}{\egroup\egroup\endmath\egroup} 38 | \DeclareRobustCommand{\isactrlbsup}{\emph\bgroup\math{}\sp\bgroup\mbox\bgroup\isaspacing\isastylescript} 39 | \DeclareRobustCommand{\isactrlesup}{\egroup\egroup\endmath\egroup} 40 | \newcommand{\isactrlbold}[1]{{\bfseries\upshape\boldmath#1}} 41 | 42 | \newcommand{\isaantiqcontrol}[1]{\isatt{{\char`\\}{\char`\<}{\char`\^}#1{\char`\>}}} 43 | \newenvironment{isaantiq}{{\isacharat\isacharbraceleft}}{{\isacharbraceright}} 44 | 45 | \newdimen\isa@parindent\newdimen\isa@parskip 46 | 47 | \newenvironment{isabellebody}{% 48 | \isamarkuptrue\par% 49 | \isa@parindent\parindent\parindent0pt% 50 | \isa@parskip\parskip\parskip0pt% 51 | \isaspacing\isastyle}{\par} 52 | 53 | \newenvironment{isabellebodytt}{% 54 | \isamarkuptrue\par% 55 | \isa@parindent\parindent\parindent0pt% 56 | \isa@parskip\parskip\parskip0pt% 57 | \isaspacing\isastylett}{\par} 58 | 59 | \newenvironment{isabelle} 60 | {\begin{trivlist}\begin{isabellebody}\item\relax} 61 | {\end{isabellebody}\end{trivlist}} 62 | 63 | \newenvironment{isabellett} 64 | {\begin{trivlist}\begin{isabellebodytt}\item\relax} 65 | {\end{isabellebodytt}\end{trivlist}} 66 | 67 | \newcommand{\isa}[1]{\emph{\isaspacing\isastyleminor #1}} 68 | \newcommand{\isatt}[1]{\emph{\isaspacing\isastyleminortt #1}} 69 | 70 | \newcommand{\isaindent}[1]{\hphantom{#1}} 71 | \newcommand{\isanewline}{\mbox{}\par\mbox{}} 72 | \newcommand{\isasep}{} 73 | \newcommand{\isadigit}[1]{#1} 74 | 75 | \newcommand{\isachardefaults}{% 76 | \def\isacharbell{\isamath{\bigbox}}%requires stmaryrd 77 | \chardef\isacharbang=`\!% 78 | \chardef\isachardoublequote=`\"% 79 | \chardef\isachardoublequoteopen=`\"% 80 | \chardef\isachardoublequoteclose=`\"% 81 | \chardef\isacharhash=`\#% 82 | \chardef\isachardollar=`\$% 83 | \chardef\isacharpercent=`\%% 84 | \chardef\isacharampersand=`\&% 85 | \chardef\isacharprime=`\'% 86 | \chardef\isacharparenleft=`\(% 87 | \chardef\isacharparenright=`\)% 88 | \chardef\isacharasterisk=`\*% 89 | \chardef\isacharplus=`\+% 90 | \chardef\isacharcomma=`\,% 91 | \chardef\isacharminus=`\-% 92 | \chardef\isachardot=`\.% 93 | \chardef\isacharslash=`\/% 94 | \chardef\isacharcolon=`\:% 95 | \chardef\isacharsemicolon=`\;% 96 | \chardef\isacharless=`\<% 97 | \chardef\isacharequal=`\=% 98 | \chardef\isachargreater=`\>% 99 | \chardef\isacharquery=`\?% 100 | \chardef\isacharat=`\@% 101 | \chardef\isacharbrackleft=`\[% 102 | \chardef\isacharbackslash=`\\% 103 | \chardef\isacharbrackright=`\]% 104 | \chardef\isacharcircum=`\^% 105 | \chardef\isacharunderscore=`\_% 106 | \def\isacharunderscorekeyword{\_}% 107 | \chardef\isacharbackquote=`\`% 108 | \chardef\isacharbackquoteopen=`\`% 109 | \chardef\isacharbackquoteclose=`\`% 110 | \chardef\isacharbraceleft=`\{% 111 | \chardef\isacharbar=`\|% 112 | \chardef\isacharbraceright=`\}% 113 | \chardef\isachartilde=`\~% 114 | \def\isacharverbatimopen{\isacharbraceleft\isacharasterisk}% 115 | \def\isacharverbatimclose{\isacharasterisk\isacharbraceright}% 116 | \def\isacartoucheopen{\isatext{\raise.3ex\hbox{$\scriptscriptstyle\langle$}}}% 117 | \def\isacartoucheclose{\isatext{\raise.3ex\hbox{$\scriptscriptstyle\rangle$}}}% 118 | } 119 | 120 | 121 | % keyword and section markup 122 | 123 | \newcommand{\isakeyword}[1] 124 | {\emph{\bf\def\isachardot{.}\def\isacharunderscore{\isacharunderscorekeyword}% 125 | \def\isacharbraceleft{\{}\def\isacharbraceright{\}}#1}} 126 | \newcommand{\isacommand}[1]{\isakeyword{#1}} 127 | 128 | \newcommand{\isamarkupheader}[1]{\section{#1}} 129 | \newcommand{\isamarkupchapter}[1]{\chapter{#1}} 130 | \newcommand{\isamarkupsection}[1]{\section{#1}} 131 | \newcommand{\isamarkupsubsection}[1]{\subsection{#1}} 132 | \newcommand{\isamarkupsubsubsection}[1]{\subsubsection{#1}} 133 | \newcommand{\isamarkupparagraph}[1]{\paragraph{#1}} 134 | \newcommand{\isamarkupsubparagraph}[1]{\subparagraph{#1}} 135 | 136 | \newif\ifisamarkup 137 | \newcommand{\isabeginpar}{\par\ifisamarkup\relax\else\medskip\fi} 138 | \newcommand{\isaendpar}{\par\medskip} 139 | \newenvironment{isapar}{\parindent\isa@parindent\parskip\isa@parskip\isabeginpar}{\isaendpar} 140 | \newenvironment{isamarkuptext}{\par\isastyletext\begin{isapar}}{\end{isapar}} 141 | \newenvironment{isamarkuptxt}{\par\isastyletxt\begin{isapar}}{\end{isapar}} 142 | \newcommand{\isamarkupcmt}[1]{{\isastylecmt--- #1}} 143 | 144 | 145 | % styles 146 | 147 | \def\isabellestyle#1{\csname isabellestyle#1\endcsname} 148 | 149 | \newcommand{\isabellestyledefault}{% 150 | \def\isastyle{\small\tt\slshape}% 151 | \def\isastylett{\small\tt}% 152 | \def\isastyleminor{\small\tt\slshape}% 153 | \def\isastyleminortt{\small\tt}% 154 | \def\isastylescript{\footnotesize\tt\slshape}% 155 | \isachardefaults% 156 | } 157 | \isabellestyledefault 158 | 159 | \newcommand{\isabellestylett}{% 160 | \def\isastyle{\small\tt}% 161 | \def\isastylett{\small\tt}% 162 | \def\isastyleminor{\small\tt}% 163 | \def\isastyleminortt{\small\tt}% 164 | \def\isastylescript{\footnotesize\tt}% 165 | \isachardefaults% 166 | } 167 | 168 | \newcommand{\isabellestyleit}{% 169 | \def\isastyle{\it}% 170 | \def\isastylett{\tt}% 171 | \def\isastyleminor{\it}% 172 | \def\isastyleminortt{\tt}% 173 | \def\isastylescript{\footnotesize\it}% 174 | \isachardefaults% 175 | \def\isacharunderscorekeyword{\mbox{-}}% 176 | \def\isacharbang{\isamath{!}}% 177 | \def\isachardoublequote{}% 178 | \def\isachardoublequoteopen{}% 179 | \def\isachardoublequoteclose{}% 180 | \def\isacharhash{\isamath{\#}}% 181 | \def\isachardollar{\isamath{\$}}% 182 | \def\isacharpercent{\isamath{\%}}% 183 | \def\isacharampersand{\isamath{\&}}% 184 | \def\isacharprime{\isamath{\mskip2mu{'}\mskip-2mu}}% 185 | \def\isacharparenleft{\isamath{(}}% 186 | \def\isacharparenright{\isamath{)}}% 187 | \def\isacharasterisk{\isamath{*}}% 188 | \def\isacharplus{\isamath{+}}% 189 | \def\isacharcomma{\isamath{\mathord,}}% 190 | \def\isacharminus{\isamath{-}}% 191 | \def\isachardot{\isamath{\mathord.}}% 192 | \def\isacharslash{\isamath{/}}% 193 | \def\isacharcolon{\isamath{\mathord:}}% 194 | \def\isacharsemicolon{\isamath{\mathord;}}% 195 | \def\isacharless{\isamath{<}}% 196 | \def\isacharequal{\isamath{=}}% 197 | \def\isachargreater{\isamath{>}}% 198 | \def\isacharat{\isamath{@}}% 199 | \def\isacharbrackleft{\isamath{[}}% 200 | \def\isacharbackslash{\isamath{\backslash}}% 201 | \def\isacharbrackright{\isamath{]}}% 202 | \def\isacharunderscore{\mbox{-}}% 203 | \def\isacharbraceleft{\isamath{\{}}% 204 | \def\isacharbar{\isamath{\mid}}% 205 | \def\isacharbraceright{\isamath{\}}}% 206 | \def\isachartilde{\isamath{{}\sp{\sim}}}% 207 | \def\isacharbackquoteopen{\isatext{\raise.3ex\hbox{$\scriptscriptstyle\langle$}}}% 208 | \def\isacharbackquoteclose{\isatext{\raise.3ex\hbox{$\scriptscriptstyle\rangle$}}}% 209 | \def\isacharverbatimopen{\isamath{\langle\!\langle}}% 210 | \def\isacharverbatimclose{\isamath{\rangle\!\rangle}}% 211 | } 212 | 213 | \newcommand{\isabellestyleliteral}{% 214 | \isabellestyleit% 215 | \def\isacharunderscore{\_}% 216 | \def\isacharunderscorekeyword{\_}% 217 | \chardef\isacharbackquoteopen=`\`% 218 | \chardef\isacharbackquoteclose=`\`% 219 | } 220 | 221 | \newcommand{\isabellestyleliteralunderscore}{% 222 | \isabellestyleliteral% 223 | \def\isacharunderscore{\textunderscore}% 224 | \def\isacharunderscorekeyword{\textunderscore}% 225 | } 226 | 227 | \newcommand{\isabellestylesl}{% 228 | \isabellestyleit% 229 | \def\isastyle{\small\sl}% 230 | \def\isastylett{\small\tt}% 231 | \def\isastyleminor{\sl}% 232 | \def\isastyleminortt{\tt}% 233 | \def\isastylescript{\footnotesize\sl}% 234 | } 235 | 236 | 237 | % tagged regions 238 | 239 | %plain TeX version of comment package -- much faster! 240 | \let\isafmtname\fmtname\def\fmtname{plain} 241 | \usepackage{comment} 242 | \let\fmtname\isafmtname 243 | 244 | \newcommand{\isafold}[1]{\emph{$\langle\mathord{\mathit{#1}}\rangle$}} 245 | 246 | \newcommand{\isakeeptag}[1]% 247 | {\includecomment{isadelim#1}\includecomment{isatag#1}\csarg\def{isafold#1}{}} 248 | \newcommand{\isadroptag}[1]% 249 | {\excludecomment{isadelim#1}\excludecomment{isatag#1}\csarg\def{isafold#1}{}} 250 | \newcommand{\isafoldtag}[1]% 251 | {\includecomment{isadelim#1}\excludecomment{isatag#1}\csarg\def{isafold#1}{\isafold{#1}}} 252 | 253 | \isakeeptag{theory} 254 | \isakeeptag{proof} 255 | \isakeeptag{ML} 256 | \isakeeptag{visible} 257 | \isadroptag{invisible} 258 | 259 | \IfFileExists{isabelletags.sty}{\usepackage{isabelletags}}{} 260 | -------------------------------------------------------------------------------- /talks/rems-march-2017/beamerinnerthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerinnerthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerinnerthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerinnerthememetropolis}[2016/03/14 Metropolis inner theme] 21 | \RequirePackage{etoolbox} 22 | \RequirePackage{keyval} 23 | \RequirePackage{calc} 24 | \RequirePackage{pgfopts} 25 | \RequirePackage{tikz} 26 | \pgfkeys{ 27 | /metropolis/inner/sectionpage/.cd, 28 | .is choice, 29 | none/.code=\metropolis@disablesectionpage, 30 | simple/.code={\metropolis@enablesectionpage 31 | \setbeamertemplate{section page}[simple]}, 32 | progressbar/.code={\metropolis@enablesectionpage 33 | \setbeamertemplate{section page}[progressbar]}, 34 | } 35 | \pgfkeys{ 36 | /metropolis/inner/subsectionpage/.cd, 37 | .is choice, 38 | none/.code=\metropolis@disablesubsectionpage, 39 | simple/.code={\metropolis@enablesubsectionpage 40 | \setbeamertemplate{section page}[simple]}, 41 | progressbar/.code={\metropolis@enablesubsectionpage 42 | \setbeamertemplate{section page}[progressbar]}, 43 | } 44 | \newcommand{\metropolis@inner@setdefaults}{ 45 | \pgfkeys{/metropolis/inner/.cd, 46 | sectionpage=progressbar, 47 | subsectionpage=none 48 | } 49 | } 50 | \setbeamertemplate{title page}{ 51 | \begin{minipage}[b][\paperheight]{\textwidth} 52 | \ifx\inserttitlegraphic\@empty\else\usebeamertemplate*{title graphic}\fi 53 | \vfill% 54 | \ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi 55 | \ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi 56 | \usebeamertemplate*{title separator} 57 | \ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi 58 | \ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi 59 | \vfill 60 | \ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi 61 | \vspace*{10mm} 62 | \end{minipage} 63 | } 64 | \def\maketitle{% 65 | \ifbeamer@inframe 66 | \titlepage 67 | \else 68 | \frame[plain,noframenumbering]{\titlepage} 69 | \fi 70 | } 71 | \def\titlepage{% 72 | \usebeamertemplate{title page} 73 | } 74 | \setbeamertemplate{title graphic}{ 75 | \vbox to 0pt { 76 | \vspace*{2em} 77 | \inserttitlegraphic% 78 | }% 79 | \nointerlineskip% 80 | } 81 | \setbeamertemplate{title}{ 82 | \raggedright% 83 | \linespread{1.0}% 84 | \inserttitle% 85 | \par% 86 | \vspace*{0.5em} 87 | } 88 | \setbeamertemplate{subtitle}{ 89 | \raggedright% 90 | \insertsubtitle% 91 | \par% 92 | \vspace*{0.5em} 93 | } 94 | \setbeamertemplate{title separator}{ 95 | \begin{tikzpicture} 96 | \fill[fg] (0,0) rectangle (\textwidth, 0.4pt); 97 | \end{tikzpicture}% 98 | \par% 99 | } 100 | \setbeamertemplate{author}{ 101 | \vspace*{2em} 102 | \insertauthor% 103 | \par% 104 | \vspace*{0.25em} 105 | } 106 | \setbeamertemplate{date}{ 107 | \insertdate% 108 | \par% 109 | } 110 | \setbeamertemplate{institute}{ 111 | \vspace*{3mm} 112 | \insertinstitute% 113 | \par% 114 | } 115 | \defbeamertemplate{section page}{simple}{ 116 | \begin{center} 117 | \usebeamercolor[fg]{section title} 118 | \usebeamerfont{section title} 119 | \insertsectionhead\par 120 | \ifx\insertsubsectionhead\@empty\else 121 | \usebeamercolor[fg]{subsection title} 122 | \usebeamerfont{subsection title} 123 | \insertsubsectionhead 124 | \fi 125 | \end{center} 126 | } 127 | \defbeamertemplate{section page}{progressbar}{ 128 | \centering 129 | \begin{minipage}{22em} 130 | \raggedright 131 | \usebeamercolor[fg]{section title} 132 | \usebeamerfont{section title} 133 | \insertsectionhead\\[-1ex] 134 | \usebeamertemplate*{progress bar in section page} 135 | \par 136 | \ifx\insertsubsectionhead\@empty\else% 137 | \usebeamercolor[fg]{subsection title}% 138 | \usebeamerfont{subsection title}% 139 | \insertsubsectionhead 140 | \fi 141 | \end{minipage} 142 | \par 143 | \vspace{\baselineskip} 144 | } 145 | \newcommand{\metropolis@disablesectionpage}{ 146 | \AtBeginSection{ 147 | % intentionally empty 148 | } 149 | } 150 | \newcommand{\metropolis@enablesectionpage}{ 151 | \AtBeginSection{ 152 | \ifbeamer@inframe 153 | \sectionpage 154 | \else 155 | \frame[plain,c,noframenumbering]{\sectionpage} 156 | \fi 157 | } 158 | } 159 | \setbeamertemplate{subsection page}{% 160 | \usebeamertemplate*{section page} 161 | } 162 | \newcommand{\metropolis@disablesubsectionpage}{ 163 | \AtBeginSubsection{ 164 | % intentionally empty 165 | } 166 | } 167 | \newcommand{\metropolis@enablesubsectionpage}{ 168 | \AtBeginSubsection{ 169 | \ifbeamer@inframe 170 | \subsectionpage 171 | \else 172 | \frame[plain,c,noframenumbering]{\subsectionpage} 173 | \fi 174 | } 175 | } 176 | \newlength{\metropolis@progressonsectionpage} 177 | \setbeamertemplate{progress bar in section page}{ 178 | \setlength{\metropolis@progressonsectionpage}{% 179 | \textwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}% 180 | }% 181 | \begin{tikzpicture} 182 | \fill[bg] (0,0) rectangle (\textwidth, 0.4pt); 183 | \fill[fg] (0,0) rectangle (\metropolis@progressonsectionpage, 0.4pt); 184 | \end{tikzpicture}% 185 | } 186 | \def\inserttotalframenumber{100} 187 | \newlength{\metropolis@blocksep} 188 | \newlength{\metropolis@blockadjust} 189 | \setlength{\metropolis@blocksep}{0.75ex} 190 | \setlength{\metropolis@blockadjust}{0.25ex} 191 | \providecommand{\metropolis@strut}{% 192 | \vphantom{ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz()}% 193 | } 194 | \newcommand{\metropolis@block}[1]{ 195 | \par\vskip\medskipamount% 196 | \setlength{\parskip}{0pt} 197 | \ifbeamercolorempty[bg]{block title#1}{% 198 | \begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}}{% 199 | \ifbeamercolorempty[bg]{block title}{% 200 | \begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}% 201 | }% 202 | {% 203 | \begin{beamercolorbox}[ 204 | sep=\dimexpr\metropolis@blocksep-\metropolis@blockadjust\relax, 205 | leftskip=\metropolis@blockadjust, 206 | rightskip=\dimexpr\metropolis@blockadjust plus 4em\relax 207 | ]{block title#1}% 208 | }}% 209 | \usebeamerfont*{block title#1}% 210 | \metropolis@strut% 211 | \insertblocktitle% 212 | \metropolis@strut% 213 | \end{beamercolorbox}% 214 | \nointerlineskip% 215 | \ifbeamercolorempty[bg]{block body#1}{% 216 | \begin{beamercolorbox}[vmode]{block body#1}}{ 217 | \ifbeamercolorempty[bg]{block body}{% 218 | \begin{beamercolorbox}[vmode]{block body#1}% 219 | }{% 220 | \begin{beamercolorbox}[sep=\metropolis@blocksep, vmode]{block body#1}% 221 | \vspace{-\metropolis@parskip} 222 | }}% 223 | \usebeamerfont{block body#1}% 224 | \setlength{\parskip}{\metropolis@parskip}% 225 | } 226 | \setbeamertemplate{block begin}{\metropolis@block{}} 227 | \setbeamertemplate{block alerted begin}{\metropolis@block{ alerted}} 228 | \setbeamertemplate{block example begin}{\metropolis@block{ example}} 229 | \setbeamertemplate{block end}{\end{beamercolorbox}\vspace*{0.2ex}} 230 | \setbeamertemplate{block alerted end}{\end{beamercolorbox}\vspace*{0.2ex}} 231 | \setbeamertemplate{block example end}{\end{beamercolorbox}\vspace*{0.2ex}} 232 | \setbeamertemplate{itemize items}{\textbullet} 233 | \setbeamertemplate{caption label separator}{: } 234 | \setbeamertemplate{caption}[numbered] 235 | \setbeamertemplate{footnote}{% 236 | \parindent 0em\noindent% 237 | \raggedright 238 | \usebeamercolor{footnote}\hbox to 0.8em{\hfil\insertfootnotemark}\insertfootnotetext\par% 239 | } 240 | \newlength{\metropolis@parskip} 241 | \setlength{\metropolis@parskip}{0.5em} 242 | \setlength{\parskip}{\metropolis@parskip} 243 | \linespread{1.15} 244 | \define@key{beamerframe}{c}[true]{% centered 245 | \beamer@frametopskip=0pt plus 1fill\relax% 246 | \beamer@framebottomskip=0pt plus 1fill\relax% 247 | \beamer@frametopskipautobreak=0pt plus .4\paperheight\relax% 248 | \beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax% 249 | \def\beamer@initfirstlineunskip{}% 250 | } 251 | \providebool{metropolis@standout} 252 | \define@key{beamerframe}{standout}[true]{% 253 | \booltrue{metropolis@standout} 254 | \begingroup 255 | \setkeys{beamerframe}{c} 256 | \setkeys{beamerframe}{noframenumbering} 257 | \ifbeamercolorempty[bg]{palette primary}{ 258 | \setbeamercolor{background canvas}{ 259 | use=palette primary, 260 | bg=-palette primary.fg 261 | } 262 | }{ 263 | \setbeamercolor{background canvas}{ 264 | use=palette primary, 265 | bg=palette primary.bg 266 | } 267 | } 268 | \centering 269 | \usebeamercolor[fg]{palette primary} 270 | \usebeamerfont{standout} 271 | } 272 | \apptocmd{\beamer@reseteecodes}{% 273 | \ifbool{metropolis@standout}{ 274 | \endgroup 275 | \boolfalse{metropolis@standout} 276 | }{} 277 | }{}{} 278 | \metropolis@inner@setdefaults 279 | \ProcessPgfPackageOptions{/metropolis/inner} 280 | \endinput 281 | %% 282 | %% End of file `beamerinnerthememetropolis.sty'. 283 | -------------------------------------------------------------------------------- /talks/srepls-may-2017/beamerinnerthememetropolis.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `beamerinnerthememetropolis.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% beamerinnerthememetropolis.dtx (with options: `package') 8 | %% --------------------------------------------------------------------------- 9 | %% Copyright 2015 Matthias Vogelgesang and the LaTeX community. A full list of 10 | %% contributors can be found at 11 | %% 12 | %% https://github.com/matze/mtheme/graphs/contributors 13 | %% 14 | %% and the original template was based on the HSRM theme by Benjamin Weiss. 15 | %% 16 | %% This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 17 | %% International License (https://creativecommons.org/licenses/by-sa/4.0/). 18 | %% --------------------------------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{beamerinnerthememetropolis}[2016/03/14 Metropolis inner theme] 21 | \RequirePackage{etoolbox} 22 | \RequirePackage{keyval} 23 | \RequirePackage{calc} 24 | \RequirePackage{pgfopts} 25 | \RequirePackage{tikz} 26 | \pgfkeys{ 27 | /metropolis/inner/sectionpage/.cd, 28 | .is choice, 29 | none/.code=\metropolis@disablesectionpage, 30 | simple/.code={\metropolis@enablesectionpage 31 | \setbeamertemplate{section page}[simple]}, 32 | progressbar/.code={\metropolis@enablesectionpage 33 | \setbeamertemplate{section page}[progressbar]}, 34 | } 35 | \pgfkeys{ 36 | /metropolis/inner/subsectionpage/.cd, 37 | .is choice, 38 | none/.code=\metropolis@disablesubsectionpage, 39 | simple/.code={\metropolis@enablesubsectionpage 40 | \setbeamertemplate{section page}[simple]}, 41 | progressbar/.code={\metropolis@enablesubsectionpage 42 | \setbeamertemplate{section page}[progressbar]}, 43 | } 44 | \newcommand{\metropolis@inner@setdefaults}{ 45 | \pgfkeys{/metropolis/inner/.cd, 46 | sectionpage=progressbar, 47 | subsectionpage=none 48 | } 49 | } 50 | \setbeamertemplate{title page}{ 51 | \begin{minipage}[b][\paperheight]{\textwidth} 52 | \ifx\inserttitlegraphic\@empty\else\usebeamertemplate*{title graphic}\fi 53 | \vfill% 54 | \ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi 55 | \ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi 56 | \usebeamertemplate*{title separator} 57 | \ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi 58 | \ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi 59 | \vfill 60 | \ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi 61 | \vspace*{10mm} 62 | \end{minipage} 63 | } 64 | \def\maketitle{% 65 | \ifbeamer@inframe 66 | \titlepage 67 | \else 68 | \frame[plain,noframenumbering]{\titlepage} 69 | \fi 70 | } 71 | \def\titlepage{% 72 | \usebeamertemplate{title page} 73 | } 74 | \setbeamertemplate{title graphic}{ 75 | \vbox to 0pt { 76 | \vspace*{2em} 77 | \inserttitlegraphic% 78 | }% 79 | \nointerlineskip% 80 | } 81 | \setbeamertemplate{title}{ 82 | \raggedright% 83 | \linespread{1.0}% 84 | \inserttitle% 85 | \par% 86 | \vspace*{0.5em} 87 | } 88 | \setbeamertemplate{subtitle}{ 89 | \raggedright% 90 | \insertsubtitle% 91 | \par% 92 | \vspace*{0.5em} 93 | } 94 | \setbeamertemplate{title separator}{ 95 | \begin{tikzpicture} 96 | \fill[fg] (0,0) rectangle (\textwidth, 0.4pt); 97 | \end{tikzpicture}% 98 | \par% 99 | } 100 | \setbeamertemplate{author}{ 101 | \vspace*{2em} 102 | \insertauthor% 103 | \par% 104 | \vspace*{0.25em} 105 | } 106 | \setbeamertemplate{date}{ 107 | \insertdate% 108 | \par% 109 | } 110 | \setbeamertemplate{institute}{ 111 | \vspace*{3mm} 112 | \insertinstitute% 113 | \par% 114 | } 115 | \defbeamertemplate{section page}{simple}{ 116 | \begin{center} 117 | \usebeamercolor[fg]{section title} 118 | \usebeamerfont{section title} 119 | \insertsectionhead\par 120 | \ifx\insertsubsectionhead\@empty\else 121 | \usebeamercolor[fg]{subsection title} 122 | \usebeamerfont{subsection title} 123 | \insertsubsectionhead 124 | \fi 125 | \end{center} 126 | } 127 | \defbeamertemplate{section page}{progressbar}{ 128 | \centering 129 | \begin{minipage}{22em} 130 | \raggedright 131 | \usebeamercolor[fg]{section title} 132 | \usebeamerfont{section title} 133 | \insertsectionhead\\[-1ex] 134 | \usebeamertemplate*{progress bar in section page} 135 | \par 136 | \ifx\insertsubsectionhead\@empty\else% 137 | \usebeamercolor[fg]{subsection title}% 138 | \usebeamerfont{subsection title}% 139 | \insertsubsectionhead 140 | \fi 141 | \end{minipage} 142 | \par 143 | \vspace{\baselineskip} 144 | } 145 | \newcommand{\metropolis@disablesectionpage}{ 146 | \AtBeginSection{ 147 | % intentionally empty 148 | } 149 | } 150 | \newcommand{\metropolis@enablesectionpage}{ 151 | \AtBeginSection{ 152 | \ifbeamer@inframe 153 | \sectionpage 154 | \else 155 | \frame[plain,c,noframenumbering]{\sectionpage} 156 | \fi 157 | } 158 | } 159 | \setbeamertemplate{subsection page}{% 160 | \usebeamertemplate*{section page} 161 | } 162 | \newcommand{\metropolis@disablesubsectionpage}{ 163 | \AtBeginSubsection{ 164 | % intentionally empty 165 | } 166 | } 167 | \newcommand{\metropolis@enablesubsectionpage}{ 168 | \AtBeginSubsection{ 169 | \ifbeamer@inframe 170 | \subsectionpage 171 | \else 172 | \frame[plain,c,noframenumbering]{\subsectionpage} 173 | \fi 174 | } 175 | } 176 | \newlength{\metropolis@progressonsectionpage} 177 | \setbeamertemplate{progress bar in section page}{ 178 | \setlength{\metropolis@progressonsectionpage}{% 179 | \textwidth * \ratio{\insertframenumber pt}{\inserttotalframenumber pt}% 180 | }% 181 | \begin{tikzpicture} 182 | \fill[bg] (0,0) rectangle (\textwidth, 0.4pt); 183 | \fill[fg] (0,0) rectangle (\metropolis@progressonsectionpage, 0.4pt); 184 | \end{tikzpicture}% 185 | } 186 | \def\inserttotalframenumber{100} 187 | \newlength{\metropolis@blocksep} 188 | \newlength{\metropolis@blockadjust} 189 | \setlength{\metropolis@blocksep}{0.75ex} 190 | \setlength{\metropolis@blockadjust}{0.25ex} 191 | \providecommand{\metropolis@strut}{% 192 | \vphantom{ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz()}% 193 | } 194 | \newcommand{\metropolis@block}[1]{ 195 | \par\vskip\medskipamount% 196 | \setlength{\parskip}{0pt} 197 | \ifbeamercolorempty[bg]{block title#1}{% 198 | \begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}}{% 199 | \ifbeamercolorempty[bg]{block title}{% 200 | \begin{beamercolorbox}[rightskip=0pt plus 4em]{block title#1}% 201 | }% 202 | {% 203 | \begin{beamercolorbox}[ 204 | sep=\dimexpr\metropolis@blocksep-\metropolis@blockadjust\relax, 205 | leftskip=\metropolis@blockadjust, 206 | rightskip=\dimexpr\metropolis@blockadjust plus 4em\relax 207 | ]{block title#1}% 208 | }}% 209 | \usebeamerfont*{block title#1}% 210 | \metropolis@strut% 211 | \insertblocktitle% 212 | \metropolis@strut% 213 | \end{beamercolorbox}% 214 | \nointerlineskip% 215 | \ifbeamercolorempty[bg]{block body#1}{% 216 | \begin{beamercolorbox}[vmode]{block body#1}}{ 217 | \ifbeamercolorempty[bg]{block body}{% 218 | \begin{beamercolorbox}[vmode]{block body#1}% 219 | }{% 220 | \begin{beamercolorbox}[sep=\metropolis@blocksep, vmode]{block body#1}% 221 | \vspace{-\metropolis@parskip} 222 | }}% 223 | \usebeamerfont{block body#1}% 224 | \setlength{\parskip}{\metropolis@parskip}% 225 | } 226 | \setbeamertemplate{block begin}{\metropolis@block{}} 227 | \setbeamertemplate{block alerted begin}{\metropolis@block{ alerted}} 228 | \setbeamertemplate{block example begin}{\metropolis@block{ example}} 229 | \setbeamertemplate{block end}{\end{beamercolorbox}\vspace*{0.2ex}} 230 | \setbeamertemplate{block alerted end}{\end{beamercolorbox}\vspace*{0.2ex}} 231 | \setbeamertemplate{block example end}{\end{beamercolorbox}\vspace*{0.2ex}} 232 | \setbeamertemplate{itemize items}{\textbullet} 233 | \setbeamertemplate{caption label separator}{: } 234 | \setbeamertemplate{caption}[numbered] 235 | \setbeamertemplate{footnote}{% 236 | \parindent 0em\noindent% 237 | \raggedright 238 | \usebeamercolor{footnote}\hbox to 0.8em{\hfil\insertfootnotemark}\insertfootnotetext\par% 239 | } 240 | \newlength{\metropolis@parskip} 241 | \setlength{\metropolis@parskip}{0.5em} 242 | \setlength{\parskip}{\metropolis@parskip} 243 | \linespread{1.15} 244 | \define@key{beamerframe}{c}[true]{% centered 245 | \beamer@frametopskip=0pt plus 1fill\relax% 246 | \beamer@framebottomskip=0pt plus 1fill\relax% 247 | \beamer@frametopskipautobreak=0pt plus .4\paperheight\relax% 248 | \beamer@framebottomskipautobreak=0pt plus .6\paperheight\relax% 249 | \def\beamer@initfirstlineunskip{}% 250 | } 251 | \providebool{metropolis@standout} 252 | \define@key{beamerframe}{standout}[true]{% 253 | \booltrue{metropolis@standout} 254 | \begingroup 255 | \setkeys{beamerframe}{c} 256 | \setkeys{beamerframe}{noframenumbering} 257 | \ifbeamercolorempty[bg]{palette primary}{ 258 | \setbeamercolor{background canvas}{ 259 | use=palette primary, 260 | bg=-palette primary.fg 261 | } 262 | }{ 263 | \setbeamercolor{background canvas}{ 264 | use=palette primary, 265 | bg=palette primary.bg 266 | } 267 | } 268 | \centering 269 | \usebeamercolor[fg]{palette primary} 270 | \usebeamerfont{standout} 271 | } 272 | \apptocmd{\beamer@reseteecodes}{% 273 | \ifbool{metropolis@standout}{ 274 | \endgroup 275 | \boolfalse{metropolis@standout} 276 | }{} 277 | }{}{} 278 | \metropolis@inner@setdefaults 279 | \ProcessPgfPackageOptions{/metropolis/inner} 280 | \endinput 281 | %% 282 | %% End of file `beamerinnerthememetropolis.sty'. 283 | -------------------------------------------------------------------------------- /paper/comment.sty: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Comment.sty version 3.6, October 1999 3 | % 4 | % Purpose: 5 | % selectively in/exclude pieces of text: the user can define new 6 | % comment versions, and each is controlled separately. 7 | % Special comments can be defined where the user specifies the 8 | % action that is to be taken with each comment line. 9 | % 10 | % Author 11 | % Victor Eijkhout 12 | % Department of Computer Science 13 | % University of Tennessee 14 | % 107 Ayres Hall 15 | % Knoxville TN 37996 16 | % USA 17 | % 18 | % victor@eijkhout.net 19 | % 20 | % This program is free software; you can redistribute it and/or 21 | % modify it under the terms of the GNU General Public License 22 | % as published by the Free Software Foundation; either version 2 23 | % of the License, or (at your option) any later version. 24 | % 25 | % This program is distributed in the hope that it will be useful, 26 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | % GNU General Public License for more details. 29 | % 30 | % For a copy of the GNU General Public License, write to the 31 | % Free Software Foundation, Inc., 32 | % 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, 33 | % or find it on the net, for instance at 34 | % http://www.gnu.org/copyleft/gpl.html 35 | % 36 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 | % This style can be used with plain TeX or LaTeX, and probably 38 | % most other packages too. 39 | % 40 | % Usage: all text included between 41 | % \comment ... \endcomment 42 | % or \begin{comment} ... \end{comment} 43 | % is discarded. 44 | % 45 | % The opening and closing commands should appear on a line 46 | % of their own. No starting spaces, nothing after it. 47 | % This environment should work with arbitrary amounts 48 | % of comment, and the comment can be arbitrary text. 49 | % 50 | % Other `comment' environments are defined by 51 | % and are selected/deselected with 52 | % \includecomment{versiona} 53 | % \excludecoment{versionb} 54 | % 55 | % These environments are used as 56 | % \versiona ... \endversiona 57 | % or \begin{versiona} ... \end{versiona} 58 | % with the opening and closing commands again on a line of 59 | % their own. 60 | % 61 | % LaTeX users note: for an included comment, the 62 | % \begin and \end lines act as if they don't exist. 63 | % In particular, they don't imply grouping, so assignments 64 | % &c are not local. 65 | % 66 | % Special comments are defined as 67 | % \specialcomment{name}{before commands}{after commands} 68 | % where the second and third arguments are executed before 69 | % and after each comment block. You can use this for global 70 | % formatting commands. 71 | % To keep definitions &c local, you can include \begingroup 72 | % in the `before commands' and \endgroup in the `after commands'. 73 | % ex: 74 | % \specialcomment{smalltt} 75 | % {\begingroup\ttfamily\footnotesize}{\endgroup} 76 | % You do *not* have to do an additional 77 | % \includecomment{smalltt} 78 | % To remove 'smalltt' blocks, give \excludecomment{smalltt} 79 | % after the definition. 80 | % 81 | % Processing comments can apply processing to each line. 82 | % \processcomment{name}{each-line commands}% 83 | % {before commands}{after commands} 84 | % By defining a control sequence 85 | % \def\Thiscomment##1{...} in the before commands the user can 86 | % specify what is to be done with each comment line. 87 | % BUG this does not work quite yet BUG 88 | % 89 | % Trick for short in/exclude macros (such as \maybe{this snippet}): 90 | %\includecomment{cond} 91 | %\newcommand{\maybe}[1]{} 92 | %\begin{cond} 93 | %\renewcommand{\maybe}[1]{#1} 94 | %\end{cond} 95 | % 96 | % Basic approach of the implementation: 97 | % to comment something out, scoop up every line in verbatim mode 98 | % as macro argument, then throw it away. 99 | % For inclusions, in LaTeX the block is written out to 100 | % a file \CommentCutFile (default "comment.cut"), which is 101 | % then included. 102 | % In plain TeX (and other formats) both the opening and 103 | % closing comands are defined as noop. 104 | % 105 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 106 | % Changes in version 3.1 107 | % - updated author's address 108 | % - cleaned up some code 109 | % - trailing contents on \begin{env} line is always discarded 110 | % even if you've done \includecomment{env} 111 | % - comments no longer define grouping!! you can even 112 | % \includecomment{env} 113 | % \begin{env} 114 | % \begin{itemize} 115 | % \end{env} 116 | % Isn't that something ... 117 | % - included comments are written to file and input again. 118 | % Changes in 3.2 119 | % - \specialcomment brought up to date (thanks to Ivo Welch). 120 | % Changes in 3.3 121 | % - updated author's address again 122 | % - parametrised \CommentCutFile 123 | % Changes in 3.4 124 | % - added GNU public license 125 | % - added \processcomment, because Ivo's fix (above) brought an 126 | % inconsistency to light. 127 | % Changes in 3.5 128 | % - corrected typo in header. 129 | % - changed author email 130 | % - corrected \specialcomment yet again. 131 | % - fixed excludecomment of an earlier defined environment. 132 | % Changes in 3.6 133 | % - The 'cut' file is now written more verbatim, using \meaning; 134 | % some people reported having trouble with ISO latin 1, or umlaute.sty. 135 | % - removed some \newif statements. 136 | % Has this suddenly become \outer again? 137 | % 138 | % Known bugs: 139 | % - excludecomment leads to one superfluous space 140 | % - processcomment leads to a superfluous line break 141 | % 142 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 143 | 144 | \def\makeinnocent#1{\catcode`#1=12 } 145 | \def\csarg#1#2{\expandafter#1\csname#2\endcsname} 146 | \def\latexname{lplain}\def\latexename{LaTeX2e} 147 | \newwrite\CommentStream 148 | \def\CommentCutFile{comment.cut} 149 | 150 | \def\ProcessComment#1% start it all of 151 | {\begingroup 152 | \def\CurrentComment{#1}% 153 | \let\do\makeinnocent \dospecials 154 | \makeinnocent\^^L% and whatever other special cases 155 | \endlinechar`\^^M \catcode`\^^M=12 \xComment} 156 | %\def\ProcessCommentWithArg#1#2% to be used in \leveledcomment 157 | % {\begingroup 158 | % \def\CurrentComment{#1}% 159 | % \let\do\makeinnocent \dospecials 160 | % \makeinnocent\^^L% and whatever other special cases 161 | % \endlinechar`\^^M \catcode`\^^M=12 \xComment} 162 | {\catcode`\^^M=12 \endlinechar=-1 % 163 | \gdef\xComment#1^^M{% 164 | \expandafter\ProcessCommentLine} 165 | \gdef\ProcessCommentLine#1^^M{\def\test{#1} 166 | \csarg\ifx{End\CurrentComment Test}\test 167 | \edef\next{\noexpand\EndOfComment{\CurrentComment}}% 168 | \else \ThisComment{#1}\let\next\ProcessCommentLine 169 | \fi \next} 170 | } 171 | 172 | \def\CSstringmeaning#1{\expandafter\CSgobblearrow\meaning#1} 173 | \def\CSstringcsnoescape#1{\expandafter\CSgobbleescape\string#1} 174 | {\escapechar-1 175 | \expandafter\expandafter\expandafter\gdef 176 | \expandafter\expandafter\expandafter\CSgobblearrow 177 | \expandafter\string\csname macro:->\endcsname{} 178 | } 179 | \def\CSgobbleescape#1{\ifnum`\\=`#1 \else #1\fi} 180 | \def\WriteCommentLine#1{\def\CStmp{#1}% 181 | \immediate\write\CommentStream{\CSstringmeaning\CStmp}} 182 | 183 | % 3.1 change: in LaTeX and LaTeX2e prevent grouping 184 | \if 0% 185 | \ifx\fmtname\latexename 186 | 0% 187 | \else \ifx\fmtname\latexname 188 | 0% 189 | \else 190 | 1% 191 | \fi \fi 192 | %%%% 193 | %%%% definitions for LaTeX 194 | %%%% 195 | \def\AfterIncludedComment 196 | {\immediate\closeout\CommentStream 197 | \input{\CommentCutFile}\relax 198 | }% 199 | \def\TossComment{\immediate\closeout\CommentStream} 200 | \def\BeforeIncludedComment 201 | {\immediate\openout\CommentStream=\CommentCutFile 202 | \let\ThisComment\WriteCommentLine} 203 | \def\includecomment 204 | #1{\message{Include comment '#1'}% 205 | \csarg\let{After#1Comment}\AfterIncludedComment 206 | \csarg\def{#1}{\BeforeIncludedComment 207 | \ProcessComment{#1}}% 208 | \CommentEndDef{#1}} 209 | \long\def\specialcomment 210 | #1#2#3{\message{Special comment '#1'}% 211 | % note: \AfterIncludedComment does \input, so #2 goes here! 212 | \csarg\def{After#1Comment}{#2\AfterIncludedComment#3}% 213 | \csarg\def{#1}{\BeforeIncludedComment\relax 214 | \ProcessComment{#1}}% 215 | \CommentEndDef{#1}} 216 | \long\def\processcomment 217 | #1#2#3#4{\message{Lines-Processing comment '#1'}% 218 | \csarg\def{After#1Comment}{#3\AfterIncludedComment#4}% 219 | \csarg\def{#1}{\BeforeIncludedComment#2\relax 220 | \ProcessComment{#1}}% 221 | \CommentEndDef{#1}} 222 | \def\leveledcomment 223 | #1#2{\message{Include comment '#1' up to level '#2'}% 224 | %\csname #1IsLeveledCommenttrue\endcsname 225 | \csarg\let{After#1Comment}\AfterIncludedComment 226 | \csarg\def{#1}{\BeforeIncludedComment 227 | \ProcessCommentWithArg{#1}}% 228 | \CommentEndDef{#1}} 229 | \else 230 | %%%% 231 | %%%%plain TeX and other formats 232 | %%%% 233 | \def\includecomment 234 | #1{\message{Including comment '#1'}% 235 | \csarg\def{#1}{}% 236 | \csarg\def{end#1}{}} 237 | \long\def\specialcomment 238 | #1#2#3{\message{Special comment '#1'}% 239 | \csarg\def{#1}{\def\ThisComment{}\def\AfterComment{#3}#2% 240 | \ProcessComment{#1}}% 241 | \CommentEndDef{#1}} 242 | \fi 243 | 244 | %%%% 245 | %%%% general definition of skipped comment 246 | %%%% 247 | \def\excludecomment 248 | #1{\message{Excluding comment '#1'}% 249 | \csarg\def{#1}{\let\AfterComment\relax 250 | \def\ThisComment####1{}\ProcessComment{#1}}% 251 | \csarg\let{After#1Comment}\TossComment 252 | \CommentEndDef{#1}} 253 | 254 | \if 0% 255 | \ifx\fmtname\latexename 256 | 0% 257 | \else \ifx\fmtname\latexname 258 | 0% 259 | \else 260 | 1% 261 | \fi \fi 262 | % latex & latex2e: 263 | \def\EndOfComment#1{\endgroup\end{#1}% 264 | \csname After#1Comment\endcsname} 265 | \def\CommentEndDef#1{{\escapechar=-1\relax 266 | \csarg\xdef{End#1Test}{\string\\end\string\{#1\string\}}% 267 | }} 268 | \else 269 | % plain & other 270 | \def\EndOfComment#1{\endgroup\AfterComment} 271 | \def\CommentEndDef#1{{\escapechar=-1\relax 272 | \csarg\xdef{End#1Test}{\string\\end#1}% 273 | }} 274 | \fi 275 | 276 | \excludecomment{comment} 277 | 278 | \endinput 279 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | --------------------------------------------------------------------------------