chiark / gitweb /
ends, work, etc.
[topbloke-formulae.git] / article.tex
index 405dbbd2f47f080002190ddb4989b06a918626e9..992f0d46204d5007e96878b888bf084b01d57dbc 100644 (file)
-\documentclass[a4paper]{article}
-\usepackage{MnSymbol}
-\usepackage{stmaryrd}
-\usepackage{slashed}
+\documentclass[a4paper,leqno]{strayman}
+\let\numberwithin=\notdef
+\usepackage{amsmath}
+\usepackage{mathabx}
+\usepackage{txfonts}
+\usepackage{amsfonts}
+\usepackage{mdwlist}
+%\usepackage{accents}
+
+\renewcommand{\ge}{\geqslant}
+\renewcommand{\le}{\leqslant}
+
+\newcommand{\has}{\sqsupseteq}
+\newcommand{\isin}{\sqsubseteq}
+
+\newcommand{\nothaspatch}{\mathrel{\,\not\!\not\relax\haspatch}}
+\newcommand{\notpatchisin}{\mathrel{\,\not\!\not\relax\patchisin}}
+\newcommand{\haspatch}{\sqSupset}
+\newcommand{\patchisin}{\sqSubset}
+
+\newcommand{\set}[1]{\mathbb #1}
+\newcommand{\pa}[1]{\varmathbb #1}
+\newcommand{\pay}[1]{\pa{#1}^+}
+\newcommand{\pan}[1]{\pa{#1}^-}
+
+\newcommand{\p}{\pa{P}}
+\newcommand{\py}{\pay{P}}
+\newcommand{\pn}{\pan{P}}
+
+%\newcommand{\hasparents}{\underaccent{1}{>}}
+%\newcommand{\hasparents}{{%
+%  \declareslashed{}{_{_1}}{0}{-0.8}{>}\slashed{>}}}
+\newcommand{\hasparents}{>_{\mkern-7.0mu _1}}
+\newcommand{\areparents}{<_{\mkern-14.0mu _1\mkern+5.0mu}}
+
+\renewcommand{\implies}{\Rightarrow}
+\renewcommand{\equiv}{\Leftrightarrow}
+\renewcommand{\land}{\wedge}
+\renewcommand{\lor}{\vee}
+
+\newcommand{\pancs}{{\mathcal A}}
+\newcommand{\pends}{{\mathcal E}}
+
+\newcommand{\pancsof}[2]{\pancs ( #1 , #2 ) }
+\newcommand{\pendsof}[2]{\pends ( #1 , #2 ) }
+
+\newcommand{\patchof}[1]{{\mathcal P} ( #1 ) }
+\newcommand{\baseof}[1]{{\mathcal B} ( #1 ) }
+
+\newcommand{\eqn}[2]{ #2 \tag*{\mbox{\bf #1}} }
+\newcommand{\corrolary}[1]{ #1 \tag*{\mbox{\it Corrolary.}} }
+
+%\newcommand{\bigforall}{\mathop{\hbox{\huge$\forall$}}}
+\newcommand{\bigforall}{%
+  \mathop{\mathchoice%
+    {\hbox{\huge$\forall$}}%
+    {\hbox{\Large$\forall$}}%
+    {\hbox{\normalsize$\forall$}}%
+    {\hbox{\scriptsize$\forall$}}}%
+}
+
+\newcommand{\proof}[1]{{\it Proof.} #1 $\square$}
+
 \begin{document}
-\newcommand{\nothaspatch}{{%
-  \declareslashed{}{\sslash}{-0.04}{0}{\Sqsupset}\slashed{\Sqsupset}}}
-\newcommand{\notinpatch}{{%
-  \declareslashed{}{\sslash}{-0.04}{0}{\Sqsubset}\slashed{\Sqsubset}}}
-\newcommand{\haspatch}{\Sqsupset}
-\newcommand{\inpatch}{\Sqsubset}
-sponge
-$ A \sqsubseteq B $
-$ A \not \sqsubseteq B $
-$ A \nsqsubseteq B $
-$ A \Sqsubset B $
-$ A \Sqsupset B $
-$ A \haspatch B $
-$ A \nothaspatch B $
-$ A \inpatch B $
-$ A \notinpatch B $
+
+\section{Notation}
+
+\begin{basedescript}{
+\desclabelwidth{5em}
+\desclabelstyle{\nextlinelabel}
+}
+\item[ $ C \hasparents \set X $ ]
+The parents of commit $C$ are exactly the set
+$\set X$.
+
+\item[ $ C \ge D $ ]
+$C$ is a descendant of $D$ in the git commit
+graph.  This is a partial order, namely the transitive closure of 
+$ D \in \set X $ where $ C \hasparents \set X $.
+
+\item[ $ C \has D $ ]
+Informally, the tree at commit $C$ contains the change
+made in commit $D$.  Does not take account of deliberate reversions by
+the user or in non-Topbloke-controlled branches; these are considered
+normal, forward, commits.  For merges and Topbloke-generated
+anticommits, the ``change made'' is only to be thought of as any
+conflict resolution.  This is not a partial order because it is not
+transitive.
+
+\item[ $ \p, \py, \pn $ ]
+A patch $\p$ consists of two sets of commits $\pn$ and $\py$, which
+are respectively the base and tip git branches.  $\p$ may be used
+where the context requires a set, in which case the statement
+is to be taken as applying to both $\py$ and $\pn$.
+All these sets are distinct.  Hence:
+
+\item[ $ \patchof{ C } $ ]
+Either $\p$ s.t. $ C \in \p $, or $\bot$.  
+A function from commits to patches' sets $\p$.
+
+\item[ $ \pancsof{C}{\set P} $ ]
+$ \{ A \; | \; A \le C \land A \in \set P \} $ 
+i.e. all the ancestors of $C$
+which are in $\set P$.
+
+\item[ $ \pendsof{C}{\set P} $ ]
+$ \{ E \; | \; E \in \pancsof{C}{\set P}
+  \land \mathop{\not\exists}_{A \in \pancsof{C}{\set P}}
+  A \neq E \land E \le A \} $ 
+i.e. all $\le$-maximal commits in $\pancsof{C}{\set P}$.
+
+\item[ $ \baseof{C} $ ]
+$ \pendsof{C}{\pn} = \{ \baseof{C} \} $ where $ C \in \py $.
+A partial function from commits to commits.
+See ``unique base'', below.
+
+\item[ $ C \haspatch \p $ ]
+$\displaystyle \bigforall_{D \in \py} D \isin C \equiv D \le C $.
+~ Informally, $C$ has the contents of $\p$.
+
+\item[ $ C \nothaspatch \p $ ]
+$\displaystyle \bigforall_{D \in \py} D \not\isin C $.
+~ Informally, $C$ has none of the contents of $\p$.  
+
+Non-Topbloke commits are $\nothaspatch \p$ for all $\p$; if
+a patch is merged into a non-Topbloke branch and we inherit
+it, we hope that git's merge algorithm will DTRT.
+
+\end{basedescript}
+
+\section{Invariants}
+
+\[ \eqn{No Replay:}{
+  C \has D \implies C \ge D
+}\]
+\[\eqn{Unique Base:}{
+ \bigforall_{C \in \py} \pendsof{C}{\pn} = \{ B \}
+}\]
+\[\eqn{Tip Contents:}{
+  \bigforall_{C \in \py} D \isin C \equiv
+    { D \isin \baseof{C} \lor \atop
+      (D \in \py \land D \le C) }
+}\]
+\[\eqn{Base Acyclic:}{
+  \bigforall_{B \in \pn} D \isin B \implies D \notin \py
+}\]
+\[\eqn{Coherence:}{
+  \bigforall_{C,\p} C \haspatch \p \lor C \nothaspatch \p
+}\]
+
+\section{Some lemmas}
+
+\[ \eqn{Exclusive Tip Contents:}{
+  \bigforall_{C \in \py} 
+    \neg \left[ D \isin \baseof{C} \land (D \in \py \land D \le C
+      \right )]
+}\]
+Ie, the two limbs of the RHS of Tip Contents are mutually exclusive.
+
+\proof{
+Let $B = \baseof{C}$ in $D \isin \baseof{C}$.  Now $B \in \pn$.
+So by Base Acyclic $D \isin B \implies D \notin \py$.
+}
+\[ \corrolary{
+  \bigforall_{C \in \py} D \isin C \equiv
+  \begin{cases}
+    D \in \py : & D \le C \\
+    D \not\in \py : & D \isin \baseof{C}
+  \end{cases}
+}\]
+
+\[ \eqn{Tip Self Inpatch:}{
+  \bigforall_{C \in \py} C \haspatch \p
+}\]
+Ie, tip commits contain their own patch.
+
+\proof{
+Apply Exclusive Tip Contents to some $D \in \py$:
+$ \bigforall_{C \in \py}\bigforall_{D \in \py}
+  D \isin C \equiv D \le C $
+}
+
+\[ \eqn{Exact Ancestors:}{
+  \bigforall_{ C \hasparents \set{R} }
+  D \le C \equiv
+    ( \mathop{\hbox{\huge{$\vee$}}}_{R \in \set R} D \le R )
+    \lor D = C
+}\]
+
+\[ \eqn{Transitive Ancestors:}{
+  \left[ \bigforall_{ E \in \pendsof{C}{\set P} } E \le M \right] \equiv
+  \left[ \bigforall_{ A \in \pancsof{C}{\set P} } A \le M \right]
+}\]
+
+\proof{
+The implication from right to left is trivial because
+$ \pends() \subset \pancs() $.
+For the implication from left to right: 
+by the definition of $\mathcal E$,
+for every such $A$, either $A \in \pends()$ which implies
+$A \le C$, or $\exists_{A' \in \pancs()} \; A' \neq A \land A \le A' $
+in which case we repeat for $A'$.  Since there are finitely many
+commits, this terminates with $A'' \in \pends()$, ie $A'' \le M$
+by the LHS.  And $A \le A''$.
+}
+
+\section{Commit annotation}
+
+We annotate each Topbloke commit $C$ with:
+\begin{gather}
+\tag*{} \patchof{C} \\
+\tag*{} \baseof{C}, \text{ if } C \in \py \\
+\tag*{} \bigforall_{\pa{Q}} 
+        \text{ either } C \haspatch \pa{Q} \text{ or } C \nothaspatch \pa{Q} \\
+\tag*{} \bigforall_{\pay{Q} \not\ni C} \pendsof{C}{\pay{Q}}
+\end{gather}
+
+We do not annotate $\pendsof{C}{\py}$ for $C \in \py$ doing so would
+break making plain commits with git because the recorded $\pends$
+would have to be updated.  The annotation is not needed because
+$\forall_{\py \ni C} \pendsof{C}{\py} = \{C\}$.
+
+\section{Test more symbols}
+
+$ C \haspatch \p $
+
+$ C \nothaspatch \p $
+
+$ \p \patchisin C $
+
+$ \p \notpatchisin C $
+
+$ \{ B \} \areparents C $
+
 \end{document}