chiark / gitweb /
define \merge and add it to notation section
[topbloke-formulae.git] / article.tex
1 \documentclass[a4paper,leqno]{strayman}
2 \errorcontextlines=50
3 \let\numberwithin=\notdef
4 \usepackage{amsmath}
5 \usepackage{mathabx}
6 \usepackage{txfonts}
7 \usepackage{amsfonts}
8 \usepackage{mdwlist}
9 %\usepackage{accents}
10
11 \renewcommand{\ge}{\geqslant}
12 \renewcommand{\le}{\leqslant}
13
14 \newcommand{\has}{\sqsupseteq}
15 \newcommand{\isin}{\sqsubseteq}
16
17 \newcommand{\nothaspatch}{\mathrel{\,\not\!\not\relax\haspatch}}
18 \newcommand{\notpatchisin}{\mathrel{\,\not\!\not\relax\patchisin}}
19 \newcommand{\haspatch}{\sqSupset}
20 \newcommand{\patchisin}{\sqSubset}
21
22         \newif\ifhidehack\hidehackfalse
23         \DeclareRobustCommand\hidefromedef[2]{%
24           \hidehacktrue\ifhidehack#1\else#2\fi\hidehackfalse}
25         \newcommand{\pa}[1]{\hidefromedef{\varmathbb{#1}}{#1}}
26
27 \newcommand{\set}[1]{\mathbb{#1}}
28 \newcommand{\pay}[1]{\pa{#1}^+}
29 \newcommand{\pan}[1]{\pa{#1}^-}
30
31 \newcommand{\p}{\pa{P}}
32 \newcommand{\py}{\pay{P}}
33 \newcommand{\pn}{\pan{P}}
34
35 \newcommand{\pr}{\pa{R}}
36 \newcommand{\pry}{\pay{R}}
37 \newcommand{\prn}{\pan{R}}
38
39 %\newcommand{\hasparents}{\underaccent{1}{>}}
40 %\newcommand{\hasparents}{{%
41 %  \declareslashed{}{_{_1}}{0}{-0.8}{>}\slashed{>}}}
42 \newcommand{\hasparents}{>_{\mkern-7.0mu _1}}
43 \newcommand{\areparents}{<_{\mkern-14.0mu _1\mkern+5.0mu}}
44
45 \renewcommand{\implies}{\Rightarrow}
46 \renewcommand{\equiv}{\Leftrightarrow}
47 \renewcommand{\land}{\wedge}
48 \renewcommand{\lor}{\vee}
49
50 \newcommand{\pancs}{{\mathcal A}}
51 \newcommand{\pends}{{\mathcal E}}
52
53 \newcommand{\pancsof}[2]{\pancs ( #1 , #2 ) }
54 \newcommand{\pendsof}[2]{\pends ( #1 , #2 ) }
55
56 \newcommand{\merge}[4]{{\mathcal M}(#1,#2,#3,#4)}
57 %\newcommand{\merge}[4]{{#2 {{\frac{ #1 }{ #3 } #4}}}}
58
59 \newcommand{\patchof}[1]{{\mathcal P} ( #1 ) }
60 \newcommand{\baseof}[1]{{\mathcal B} ( #1 ) }
61
62 \newcommand{\eqn}[2]{ #2 \tag*{\mbox{\bf #1}} }
63 \newcommand{\corrolary}[1]{ #1 \tag*{\mbox{\it Corrolary.}} }
64
65 %\newcommand{\bigforall}{\mathop{\hbox{\huge$\forall$}}}
66 \newcommand{\bigforall}{%
67   \mathop{\mathchoice%
68     {\hbox{\huge$\forall$}}%
69     {\hbox{\Large$\forall$}}%
70     {\hbox{\normalsize$\forall$}}%
71     {\hbox{\scriptsize$\forall$}}}%
72 }
73
74 \newcommand{\Largeexists}{\mathop{\hbox{\Large$\exists$}}}
75 \newcommand{\Largenexists}{\mathop{\hbox{\Large$\nexists$}}}
76
77 \newcommand{\qed}{\square}
78 \newcommand{\proof}[1]{{\it Proof.} #1 $\qed$}
79
80 \newcommand{\gathbegin}{\begin{gather} \tag*{}}
81 \newcommand{\gathnext}{\\ \tag*{}}
82
83 \newcommand{\true}{t}
84 \newcommand{\false}{f}
85
86 \begin{document}
87
88 \section{Notation}
89
90 \begin{basedescript}{
91 \desclabelwidth{5em}
92 \desclabelstyle{\nextlinelabel}
93 }
94 \item[ $ C \hasparents \set X $ ]
95 The parents of commit $C$ are exactly the set
96 $\set X$.
97
98 \item[ $ C \ge D $ ]
99 $C$ is a descendant of $D$ in the git commit
100 graph.  This is a partial order, namely the transitive closure of 
101 $ D \in \set X $ where $ C \hasparents \set X $.
102
103 \item[ $ C \has D $ ]
104 Informally, the tree at commit $C$ contains the change
105 made in commit $D$.  Does not take account of deliberate reversions by
106 the user or reversion, rebasing or rewinding in
107 non-Topbloke-controlled branches.  For merges and Topbloke-generated
108 anticommits or re-commits, the ``change made'' is only to be thought
109 of as any conflict resolution.  This is not a partial order because it
110 is not transitive.
111
112 \item[ $ \p, \py, \pn $ ]
113 A patch $\p$ consists of two sets of commits $\pn$ and $\py$, which
114 are respectively the base and tip git branches.  $\p$ may be used
115 where the context requires a set, in which case the statement
116 is to be taken as applying to both $\py$ and $\pn$.
117 All these sets are distinct.  Hence:
118
119 \item[ $ \patchof{ C } $ ]
120 Either $\p$ s.t. $ C \in \p $, or $\bot$.  
121 A function from commits to patches' sets $\p$.
122
123 \item[ $ \pancsof{C}{\set P} $ ]
124 $ \{ A \; | \; A \le C \land A \in \set P \} $ 
125 i.e. all the ancestors of $C$
126 which are in $\set P$.
127
128 \item[ $ \pendsof{C}{\set P} $ ]
129 $ \{ E \; | \; E \in \pancsof{C}{\set P}
130   \land \mathop{\not\exists}_{A \in \pancsof{C}{\set P}}
131   E \neq A \land E \le A \} $ 
132 i.e. all $\le$-maximal commits in $\pancsof{C}{\set P}$.
133
134 \item[ $ \baseof{C} $ ]
135 $ \pendsof{C}{\pn} = \{ \baseof{C} \} $ where $ C \in \py $.
136 A partial function from commits to commits.
137 See Unique Base, below.
138
139 \item[ $ C \haspatch \p $ ]
140 $\displaystyle \bigforall_{D \in \py} D \isin C \equiv D \le C $.
141 ~ Informally, $C$ has the contents of $\p$.
142
143 \item[ $ C \nothaspatch \p $ ]
144 $\displaystyle \bigforall_{D \in \py} D \not\isin C $.
145 ~ Informally, $C$ has none of the contents of $\p$.  
146
147 Non-Topbloke commits are $\nothaspatch \p$ for all $\p$; if a Topbloke
148 patch is applied to a non-Topbloke branch and then bubbles back to
149 the Topbloke patch itself, we hope that git's merge algorithm will
150 DTRT or that the user will no longer care about the Topbloke patch.
151
152 \item[ $\displaystyle \merge{C}{L}{M}{R} $ ]
153 The contents of a git merge result:
154
155 $\displaystyle D \isin C \equiv
156   \begin{cases}
157     (D \isin L \land D \isin R) \lor D = C : & \true \\
158     (D \not\isin L \land D \not\isin R) \land D \neq C : & \false \\
159     \text{otherwise} : & D \not\isin M
160   \end{cases}
161
162
163 \end{basedescript}
164 \newpage
165 \section{Invariants}
166
167 We maintain these each time we construct a new commit. \\
168 \[ \eqn{No Replay:}{
169   C \has D \implies C \ge D
170 }\]
171 \[\eqn{Unique Base:}{
172  \bigforall_{C \in \py} \pendsof{C}{\pn} = \{ B \}
173 }\]
174 \[\eqn{Tip Contents:}{
175   \bigforall_{C \in \py} D \isin C \equiv
176     { D \isin \baseof{C} \lor \atop
177       (D \in \py \land D \le C) }
178 }\]
179 \[\eqn{Base Acyclic:}{
180   \bigforall_{B \in \pn} D \isin B \implies D \notin \py
181 }\]
182 \[\eqn{Coherence:}{
183   \bigforall_{C,\p} C \haspatch \p \lor C \nothaspatch \p
184 }\]
185 \[\eqn{Foreign Inclusion:}{
186   \bigforall_{D \text{ s.t. } \patchof{D} = \bot} D \isin C \equiv D \leq C
187 }\]
188
189 \section{Some lemmas}
190
191 \[ \eqn{Exclusive Tip Contents:}{
192   \bigforall_{C \in \py} 
193     \neg \Bigl[ D \isin \baseof{C} \land ( D \in \py \land D \le C )
194       \Bigr]
195 }\]
196 Ie, the two limbs of the RHS of Tip Contents are mutually exclusive.
197
198 \proof{
199 Let $B = \baseof{C}$ in $D \isin \baseof{C}$.  Now $B \in \pn$.
200 So by Base Acyclic $D \isin B \implies D \notin \py$.
201 }
202 \[ \corrolary{
203   \bigforall_{C \in \py} D \isin C \equiv
204   \begin{cases}
205     D \in \py : & D \le C \\
206     D \not\in \py : & D \isin \baseof{C}
207   \end{cases}
208 }\]
209
210 \[ \eqn{Tip Self Inpatch:}{
211   \bigforall_{C \in \py} C \haspatch \p
212 }\]
213 Ie, tip commits contain their own patch.
214
215 \proof{
216 Apply Exclusive Tip Contents to some $D \in \py$:
217 $ \bigforall_{C \in \py}\bigforall_{D \in \py}
218   D \isin C \equiv D \le C $
219 }
220
221 \[ \eqn{Exact Ancestors:}{
222   \bigforall_{ C \hasparents \set{R} }
223   D \le C \equiv
224     ( \mathop{\hbox{\huge{$\vee$}}}_{R \in \set R} D \le R )
225     \lor D = C
226 }\]
227
228 \[ \eqn{Transitive Ancestors:}{
229   \left[ \bigforall_{ E \in \pendsof{C}{\set P} } E \le M \right] \equiv
230   \left[ \bigforall_{ A \in \pancsof{C}{\set P} } A \le M \right]
231 }\]
232
233 \proof{
234 The implication from right to left is trivial because
235 $ \pends() \subset \pancs() $.
236 For the implication from left to right: 
237 by the definition of $\mathcal E$,
238 for every such $A$, either $A \in \pends()$ which implies
239 $A \le M$ by the LHS directly,
240 or $\exists_{A' \in \pancs()} \; A' \neq A \land A \le A' $
241 in which case we repeat for $A'$.  Since there are finitely many
242 commits, this terminates with $A'' \in \pends()$, ie $A'' \le M$
243 by the LHS.  And $A \le A''$.
244 }
245 \[ \eqn{Calculation Of Ends:}{
246   \bigforall_{C \hasparents \set A}
247     \pendsof{C}{\set P} =
248        \Bigl\{ E \Big|
249            \Bigl[ \Largeexists_{A \in \set A} 
250                        E \in \pendsof{A}{\set P} \Bigr] \land
251            \Bigl[ \Largenexists_{B \in \set A} 
252                        E \neq B \land E \le B \Bigr]
253        \Bigr\}
254 }\]
255 XXX proof TBD.
256
257 \section{Commit annotation}
258
259 We annotate each Topbloke commit $C$ with:
260 \gathbegin
261  \patchof{C}
262 \gathnext
263  \baseof{C}, \text{ if } C \in \py
264 \gathnext
265  \bigforall_{\pa{Q}} 
266    \text{ either } C \haspatch \pa{Q} \text{ or } C \nothaspatch \pa{Q}
267 \gathnext
268  \bigforall_{\pay{Q} \not\ni C} \pendsof{C}{\pay{Q}}
269 \end{gather}
270
271 We do not annotate $\pendsof{C}{\py}$ for $C \in \py$.  Doing so would
272 make it wrong to make plain commits with git because the recorded $\pends$
273 would have to be updated.  The annotation is not needed because
274 $\forall_{\py \ni C} \; \pendsof{C}{\py} = \{C\}$.
275
276 \section{Simple commit}
277
278 A simple single-parent forward commit $C$ as made by git-commit.
279 \begin{gather}
280 \tag*{} C \hasparents \{ A \} \\
281 \tag*{} \patchof{C} = \patchof{A} \\
282 \tag*{} D \isin C \equiv D \isin A \lor D = C
283 \end{gather}
284
285 \subsection{No Replay}
286 Trivial.
287
288 \subsection{Unique Base}
289 If $A, C \in \py$ then $\baseof{C} = \baseof{A}$. $\qed$
290
291 \subsection{Tip Contents}
292 We need to consider only $A, C \in \py$.  From Tip Contents for $A$:
293 \[ D \isin A \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A ) \]
294 Substitute into the contents of $C$:
295 \[ D \isin C \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A )
296     \lor D = C \]
297 Since $D = C \implies D \in \py$, 
298 and substituting in $\baseof{C}$, this gives:
299 \[ D \isin C \equiv D \isin \baseof{C} \lor
300     (D \in \py \land D \le A) \lor
301     (D = C \land D \in \py) \]
302 \[ \equiv D \isin \baseof{C} \lor
303    [ D \in \py \land ( D \le A \lor D = C ) ] \]
304 So by Exact Ancestors:
305 \[ D \isin C \equiv D \isin \baseof{C} \lor ( D \in \py \land D \le C
306 ) \]
307 $\qed$
308
309 \subsection{Base Acyclic}
310
311 Need to consider only $A, C \in \pn$.  
312
313 For $D = C$: $D \in \pn$ so $D \not\in \py$. OK.
314
315 For $D \neq C$: $D \isin C \equiv D \isin A$, so by Base Acyclic for
316 $A$, $D \isin C \implies D \not\in \py$. $\qed$
317
318 \subsection{Coherence and patch inclusion}
319
320 Need to consider $D \in \py$
321
322 \subsubsection{For $A \haspatch P, D = C$:}
323
324 Ancestors of $C$:
325 $ D \le C $.
326
327 Contents of $C$:
328 $ D \isin C \equiv \ldots \lor \true \text{ so } D \haspatch C $.
329
330 \subsubsection{For $A \haspatch P, D \neq C$:}
331 Ancestors: $ D \le C \equiv D \le A $.
332
333 Contents: $ D \isin C \equiv D \isin A \lor f $
334 so $ D \isin C \equiv D \isin A $.
335
336 So:
337 \[ A \haspatch P \implies C \haspatch P \]
338
339 \subsubsection{For $A \nothaspatch P$:}
340
341 Firstly, $C \not\in \py$ since if it were, $A \in \py$.  
342 Thus $D \neq C$.
343
344 Now by contents of $A$, $D \notin A$, so $D \notin C$.
345
346 So:
347 \[ A \nothaspatch P \implies C \nothaspatch P \]
348 $\qed$
349
350 \subsection{Foreign inclusion:}
351
352 If $D = C$, trivial.  For $D \neq C$:
353 $D \isin C \equiv D \isin A \equiv D \le A \equiv D \le C$.  $\qed$
354
355 \section{Anticommit}
356
357 Given $L, R^+, R^-$ where
358 $\patchof{R^+} = \pry, \patchof{R^-} = \prn$.  
359 Construct $C$ which has $\pr$ removed.
360 Used for removing a branch dependency.
361 \gathbegin
362  C \hasparents \{ L \}
363 \gathnext
364  \patchof{C} = \patchof{L}
365 \gathnext
366  D \isin C \equiv
367    \begin{cases}
368       R \in \py : & \baseof{R} \ge \baseof{L}
369               \land [\baseof{L} = M \lor \baseof{L} = \baseof{M}] \\
370       R \in \pn : & R \ge \baseof{L}
371               \land M = \baseof{L} \\
372       \text{otherwise} : & \false
373    \end{cases}
374 \end{gather}
375
376 xxx want to prove $D \isin C \equiv D \not\in pry \land D \isin L$.
377
378 \section{Merge}
379
380 Merge commits $L$ and $R$ using merge base $M$ ($M < L, M < R$):
381 \gathbegin
382  C \hasparents \{ L, R \}
383 \gathnext
384  \patchof{C} = \patchof{L}
385 \gathnext
386  D \isin C \equiv
387   \begin{cases}
388     (D \isin L \land D \isin R) \lor D = C : & \true \\
389     (D \not\isin L \land D \not\isin R) \land D \neq C : & \false \\
390     \text{otherwise} : & D \not\isin M
391   \end{cases}
392 \end{gather}
393
394 \subsection{Conditions}
395
396 \[ \eqn{ Tip Merge }{
397  L \in \py \implies
398    \begin{cases}
399       R \in \py : & \baseof{R} \ge \baseof{L}
400               \land [\baseof{L} = M \lor \baseof{L} = \baseof{M}] \\
401       R \in \pn : & R \ge \baseof{L}
402               \land M = \baseof{L} \\
403       \text{otherwise} : & \false
404    \end{cases}
405 }\]
406
407 \subsection{No Replay}
408
409 \subsubsection{For $D=C$:} $D \isin C, D \le C$.  OK.
410
411 \subsubsection{For $D \isin L \land D \isin R$:}
412 $D \isin C$.  And $D \isin L \implies D \le L \implies D \le C$.  OK.
413
414 \subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:}
415 $D \not\isin C$.  OK.
416
417 \subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:}
418 $D \not\isin C$.  OK.
419
420 \subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R)
421  \land D \not\isin M$:}
422 $D \isin C$.  Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le
423 R$ so $D \le C$.  OK.
424
425 \subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R)
426  \land D \isin M$:}
427 $D \not\isin C$.  Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le
428 R$ so $D \le C$.  OK.
429
430 $\qed$
431
432 \subsection{Unique Base}
433
434 Need to consider only $C \in \py$, ie $L \in \py$,
435 and calculate $\pendsof{C}{\pn}$.  So we will consider some
436 putative ancestor $A \in \pn$ and see whether $A \le C$.
437
438 By Exact Ancestors for C, $A \le C \equiv A \le L \lor A \le R \lor A = C$.
439 But $C \in py$ and $A \in \pn$ so $A \neq C$.  
440 Thus $A \le C \equiv A \le L \lor A \le R$.
441
442 By Unique Base of L and Transitive Ancestors,
443 $A \le L \equiv A \le \baseof{L}$.
444
445 \subsubsection{For $R \in \py$:}
446
447 By Unique Base of $R$ and Transitive Ancestors,
448 $A \le R \equiv A \le \baseof{R}$.
449
450 But by Tip Merge condition on $\baseof{R}$,
451 $A \le \baseof{L} \implies A \le \baseof{R}$, so
452 $A \le \baseof{R} \lor A \le \baseof{L} \equiv A \le \baseof{R}$.
453 Thus $A \le C \equiv A \le \baseof{R}$.  
454 That is, $\baseof{C} = \baseof{R}$.
455
456 \subsubsection{For $R \in \pn$:}
457
458 By Tip Merge condition on $R$,
459 $A \le \baseof{L} \implies A \le R$, so
460 $A \le R \lor A \le \baseof{L} \equiv A \le R$.  
461 Thus $A \le C \equiv A \le R$.  
462 That is, $\baseof{C} = R$.
463
464 $\qed$
465
466 \end{document}