chiark / gitweb /
992f0d46204d5007e96878b888bf084b01d57dbc
[topbloke-formulae.git] / article.tex
1 \documentclass[a4paper,leqno]{strayman}
2 \let\numberwithin=\notdef
3 \usepackage{amsmath}
4 \usepackage{mathabx}
5 \usepackage{txfonts}
6 \usepackage{amsfonts}
7 \usepackage{mdwlist}
8 %\usepackage{accents}
9
10 \renewcommand{\ge}{\geqslant}
11 \renewcommand{\le}{\leqslant}
12
13 \newcommand{\has}{\sqsupseteq}
14 \newcommand{\isin}{\sqsubseteq}
15
16 \newcommand{\nothaspatch}{\mathrel{\,\not\!\not\relax\haspatch}}
17 \newcommand{\notpatchisin}{\mathrel{\,\not\!\not\relax\patchisin}}
18 \newcommand{\haspatch}{\sqSupset}
19 \newcommand{\patchisin}{\sqSubset}
20
21 \newcommand{\set}[1]{\mathbb #1}
22 \newcommand{\pa}[1]{\varmathbb #1}
23 \newcommand{\pay}[1]{\pa{#1}^+}
24 \newcommand{\pan}[1]{\pa{#1}^-}
25
26 \newcommand{\p}{\pa{P}}
27 \newcommand{\py}{\pay{P}}
28 \newcommand{\pn}{\pan{P}}
29
30 %\newcommand{\hasparents}{\underaccent{1}{>}}
31 %\newcommand{\hasparents}{{%
32 %  \declareslashed{}{_{_1}}{0}{-0.8}{>}\slashed{>}}}
33 \newcommand{\hasparents}{>_{\mkern-7.0mu _1}}
34 \newcommand{\areparents}{<_{\mkern-14.0mu _1\mkern+5.0mu}}
35
36 \renewcommand{\implies}{\Rightarrow}
37 \renewcommand{\equiv}{\Leftrightarrow}
38 \renewcommand{\land}{\wedge}
39 \renewcommand{\lor}{\vee}
40
41 \newcommand{\pancs}{{\mathcal A}}
42 \newcommand{\pends}{{\mathcal E}}
43
44 \newcommand{\pancsof}[2]{\pancs ( #1 , #2 ) }
45 \newcommand{\pendsof}[2]{\pends ( #1 , #2 ) }
46
47 \newcommand{\patchof}[1]{{\mathcal P} ( #1 ) }
48 \newcommand{\baseof}[1]{{\mathcal B} ( #1 ) }
49
50 \newcommand{\eqn}[2]{ #2 \tag*{\mbox{\bf #1}} }
51 \newcommand{\corrolary}[1]{ #1 \tag*{\mbox{\it Corrolary.}} }
52
53 %\newcommand{\bigforall}{\mathop{\hbox{\huge$\forall$}}}
54 \newcommand{\bigforall}{%
55   \mathop{\mathchoice%
56     {\hbox{\huge$\forall$}}%
57     {\hbox{\Large$\forall$}}%
58     {\hbox{\normalsize$\forall$}}%
59     {\hbox{\scriptsize$\forall$}}}%
60 }
61
62 \newcommand{\proof}[1]{{\it Proof.} #1 $\square$}
63
64 \begin{document}
65
66 \section{Notation}
67
68 \begin{basedescript}{
69 \desclabelwidth{5em}
70 \desclabelstyle{\nextlinelabel}
71 }
72 \item[ $ C \hasparents \set X $ ]
73 The parents of commit $C$ are exactly the set
74 $\set X$.
75
76 \item[ $ C \ge D $ ]
77 $C$ is a descendant of $D$ in the git commit
78 graph.  This is a partial order, namely the transitive closure of 
79 $ D \in \set X $ where $ C \hasparents \set X $.
80
81 \item[ $ C \has D $ ]
82 Informally, the tree at commit $C$ contains the change
83 made in commit $D$.  Does not take account of deliberate reversions by
84 the user or in non-Topbloke-controlled branches; these are considered
85 normal, forward, commits.  For merges and Topbloke-generated
86 anticommits, the ``change made'' is only to be thought of as any
87 conflict resolution.  This is not a partial order because it is not
88 transitive.
89
90 \item[ $ \p, \py, \pn $ ]
91 A patch $\p$ consists of two sets of commits $\pn$ and $\py$, which
92 are respectively the base and tip git branches.  $\p$ may be used
93 where the context requires a set, in which case the statement
94 is to be taken as applying to both $\py$ and $\pn$.
95 All these sets are distinct.  Hence:
96
97 \item[ $ \patchof{ C } $ ]
98 Either $\p$ s.t. $ C \in \p $, or $\bot$.  
99 A function from commits to patches' sets $\p$.
100
101 \item[ $ \pancsof{C}{\set P} $ ]
102 $ \{ A \; | \; A \le C \land A \in \set P \} $ 
103 i.e. all the ancestors of $C$
104 which are in $\set P$.
105
106 \item[ $ \pendsof{C}{\set P} $ ]
107 $ \{ E \; | \; E \in \pancsof{C}{\set P}
108   \land \mathop{\not\exists}_{A \in \pancsof{C}{\set P}}
109   A \neq E \land E \le A \} $ 
110 i.e. all $\le$-maximal commits in $\pancsof{C}{\set P}$.
111
112 \item[ $ \baseof{C} $ ]
113 $ \pendsof{C}{\pn} = \{ \baseof{C} \} $ where $ C \in \py $.
114 A partial function from commits to commits.
115 See ``unique base'', below.
116
117 \item[ $ C \haspatch \p $ ]
118 $\displaystyle \bigforall_{D \in \py} D \isin C \equiv D \le C $.
119 ~ Informally, $C$ has the contents of $\p$.
120
121 \item[ $ C \nothaspatch \p $ ]
122 $\displaystyle \bigforall_{D \in \py} D \not\isin C $.
123 ~ Informally, $C$ has none of the contents of $\p$.  
124
125 Non-Topbloke commits are $\nothaspatch \p$ for all $\p$; if
126 a patch is merged into a non-Topbloke branch and we inherit
127 it, we hope that git's merge algorithm will DTRT.
128
129 \end{basedescript}
130
131 \section{Invariants}
132
133 \[ \eqn{No Replay:}{
134   C \has D \implies C \ge D
135 }\]
136 \[\eqn{Unique Base:}{
137  \bigforall_{C \in \py} \pendsof{C}{\pn} = \{ B \}
138 }\]
139 \[\eqn{Tip Contents:}{
140   \bigforall_{C \in \py} D \isin C \equiv
141     { D \isin \baseof{C} \lor \atop
142       (D \in \py \land D \le C) }
143 }\]
144 \[\eqn{Base Acyclic:}{
145   \bigforall_{B \in \pn} D \isin B \implies D \notin \py
146 }\]
147 \[\eqn{Coherence:}{
148   \bigforall_{C,\p} C \haspatch \p \lor C \nothaspatch \p
149 }\]
150
151 \section{Some lemmas}
152
153 \[ \eqn{Exclusive Tip Contents:}{
154   \bigforall_{C \in \py} 
155     \neg \left[ D \isin \baseof{C} \land (D \in \py \land D \le C
156       \right )]
157 }\]
158 Ie, the two limbs of the RHS of Tip Contents are mutually exclusive.
159
160 \proof{
161 Let $B = \baseof{C}$ in $D \isin \baseof{C}$.  Now $B \in \pn$.
162 So by Base Acyclic $D \isin B \implies D \notin \py$.
163 }
164 \[ \corrolary{
165   \bigforall_{C \in \py} D \isin C \equiv
166   \begin{cases}
167     D \in \py : & D \le C \\
168     D \not\in \py : & D \isin \baseof{C}
169   \end{cases}
170 }\]
171
172 \[ \eqn{Tip Self Inpatch:}{
173   \bigforall_{C \in \py} C \haspatch \p
174 }\]
175 Ie, tip commits contain their own patch.
176
177 \proof{
178 Apply Exclusive Tip Contents to some $D \in \py$:
179 $ \bigforall_{C \in \py}\bigforall_{D \in \py}
180   D \isin C \equiv D \le C $
181 }
182
183 \[ \eqn{Exact Ancestors:}{
184   \bigforall_{ C \hasparents \set{R} }
185   D \le C \equiv
186     ( \mathop{\hbox{\huge{$\vee$}}}_{R \in \set R} D \le R )
187     \lor D = C
188 }\]
189
190 \[ \eqn{Transitive Ancestors:}{
191   \left[ \bigforall_{ E \in \pendsof{C}{\set P} } E \le M \right] \equiv
192   \left[ \bigforall_{ A \in \pancsof{C}{\set P} } A \le M \right]
193 }\]
194
195 \proof{
196 The implication from right to left is trivial because
197 $ \pends() \subset \pancs() $.
198 For the implication from left to right: 
199 by the definition of $\mathcal E$,
200 for every such $A$, either $A \in \pends()$ which implies
201 $A \le C$, or $\exists_{A' \in \pancs()} \; A' \neq A \land A \le A' $
202 in which case we repeat for $A'$.  Since there are finitely many
203 commits, this terminates with $A'' \in \pends()$, ie $A'' \le M$
204 by the LHS.  And $A \le A''$.
205 }
206
207 \section{Commit annotation}
208
209 We annotate each Topbloke commit $C$ with:
210 \begin{gather}
211 \tag*{} \patchof{C} \\
212 \tag*{} \baseof{C}, \text{ if } C \in \py \\
213 \tag*{} \bigforall_{\pa{Q}} 
214         \text{ either } C \haspatch \pa{Q} \text{ or } C \nothaspatch \pa{Q} \\
215 \tag*{} \bigforall_{\pay{Q} \not\ni C} \pendsof{C}{\pay{Q}}
216 \end{gather}
217
218 We do not annotate $\pendsof{C}{\py}$ for $C \in \py$ doing so would
219 break making plain commits with git because the recorded $\pends$
220 would have to be updated.  The annotation is not needed because
221 $\forall_{\py \ni C} \pendsof{C}{\py} = \{C\}$.
222
223 \section{Test more symbols}
224
225 $ C \haspatch \p $
226
227 $ C \nothaspatch \p $
228
229 $ \p \patchisin C $
230
231 $ \p \notpatchisin C $
232
233 $ \{ B \} \areparents C $
234
235 \end{document}