X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=article.tex;h=2dc644fc140c32fc9f59552bb70cbb1ec5ac72e7;hb=030848b7699003e7fa4d8d7044cb9bcf46a1af4f;hp=4cb6c96b79aa3fb9c5b7039feb222305a8e06ce6;hpb=b49f4a4167ff535af48ccaba87e7ff8a02b77347;p=topbloke-formulae.git diff --git a/article.tex b/article.tex index 4cb6c96..2dc644f 100644 --- a/article.tex +++ b/article.tex @@ -59,7 +59,17 @@ {\hbox{\scriptsize$\forall$}}}% } -\newcommand{\proof}[1]{{\it Proof.} #1 $\square$} +\newcommand{\Largeexists}{\mathop{\hbox{\Large$\exists$}}} +\newcommand{\Largenexists}{\mathop{\hbox{\Large$\nexists$}}} + +\newcommand{\qed}{\square} +\newcommand{\proof}[1]{{\it Proof.} #1 $\qed$} + +\newcommand{\gathbegin}{\begin{gather} \tag*{}} +\newcommand{\gathnext}{\\ \tag*{}} + +\newcommand{\true}{t} +\newcommand{\false}{f} \begin{document} @@ -112,7 +122,7 @@ 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. +See Unique Base, below. \item[ $ C \haspatch \p $ ] $\displaystyle \bigforall_{D \in \py} D \isin C \equiv D \le C $. @@ -213,12 +223,15 @@ 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}} +\gathbegin + \patchof{C} +\gathnext + \baseof{C}, \text{ if } C \in \py +\gathnext + \bigforall_{\pa{Q}} + \text{ either } C \haspatch \pa{Q} \text{ or } C \nothaspatch \pa{Q} +\gathnext + \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 @@ -226,16 +239,137 @@ make it wrong to make 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} +\section{Simple commit} + +A simple single-parent forward commit $C$ as made by git-commit. +\begin{gather} +\tag*{} C \hasparents \{ A \} \\ +\tag*{} \patchof{C} = \patchof{A} \\ +\tag*{} D \isin C \equiv D \isin A \lor D = C +\end{gather} + +\subsection{No Replay} +Trivial. + +\subsection{Unique Base} +If $A, C \in \py$ then $\baseof{C} = \baseof{A}$. $\qed$ + +\subsection{Tip Contents} +We need to consider only $A, C \in \py$. From Tip Contents for $A$: +\[ D \isin A \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A ) \] +Substitute into the contents of $C$: +\[ D \isin C \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A ) + \lor D = C \] +Since $D = C \implies D \in \py$, +and substituting in $\baseof{C}$, this gives: +\[ D \isin C \equiv D \isin \baseof{C} \lor + (D \in \py \land D \le A) \lor + (D = C \land D \in \py) \] +\[ \equiv D \isin \baseof{C} \lor + [ D \in \py \land ( D \le A \lor D = C ) ] \] +So by Exact Ancestors: +\[ D \isin C \equiv D \isin \baseof{C} \lor ( D \in \py \land D \le C +) \] +$\qed$ + +\subsection{Base Acyclic} + +Need to consider only $A, C \in \pn$. + +For $D = C$: $D \in \pn$ so $D \not\in \py$. OK. + +For $D \neq C$: $D \isin C \equiv D \isin A$, so by Base Acyclic for +$A$, $D \isin C \implies D \not\in \py$. $\qed$ + +\subsection{Coherence and patch inclusion} + +Need to consider $D \in \py$ + +\subsubsection{For $A \haspatch P, D = C$:} + +Ancestors of $C$: +$ D \le C $. + +Contents of $C$: +$ D \isin C \equiv \ldots \lor \true \text{ so } D \haspatch C $. + +\subsubsection{For $A \haspatch P, D \neq C$:} +Ancestors: $ D \le C \equiv D \le A $. + +Contents: $ D \isin C \equiv D \isin A \lor f $ +so $ D \isin C \equiv D \isin A $. + +So: +\[ A \haspatch P \implies C \haspatch P \] + +\subsubsection{For $A \nothaspatch P$:} + +Firstly, $C \not\in \py$ since if it were, $A \in \py$. +Thus $D \neq C$. + +Now by contents of $A$, $D \notin A$, so $D \notin C$. + +So: +\[ A \nothaspatch P \implies C \nothaspatch P \] +$\qed$ + +\subsection{Foreign inclusion:} + +If $D = C$, trivial. For $D \neq C$: +$D \isin C \equiv D \isin A \equiv D \le A \equiv D \le C$. $\qed$ + +\section{Merge} + +Merge commits $L$ and $R$ using merge base $M$ ($M < L, M < R$): +\gathbegin + C \hasparents \{ L, R \} +\gathnext + \patchof{C} = \patchof{L} +\gathnext + D \isin C \equiv + \begin{cases} + (D \isin L \land D \isin R) \lor D = C : & \true \\ + (D \not\isin L \land D \not\isin R) \land D \neq C : & \false \\ + \text{otherwise} : & D \not\isin M + \end{cases} +\end{gather} + +\subsection{Conditions} + +\[ \eqn{ Tip Merge }{ + L \in \py \implies + \begin{cases} + R \in \py : & \baseof{R} \ge \baseof{L} + \land [\baseof{L} = M \lor \baseof{L} = \baseof{M}] \\ + R \in \pn : & R \ge \baseof{L} + \land M = \baseof{L} \\ + \text{otherwise} : & \false + \end{cases} +}\] + +\subsection{No Replay} + +\subsubsection{For $D=C$:} $D \isin C, D \le C$. OK. + +\subsubsection{For $D \isin L \land D \isin R$:} +$D \isin C$. And $D \isin L \implies D \le L \implies D \le C$. OK. -$ C \haspatch \p $ +\subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:} +$D \not\isin C$. OK. -$ C \nothaspatch \p $ +\subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:} +$D \not\isin C$. OK. -$ \p \patchisin C $ +\subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R) + \land D \not\isin M$:} +$D \isin C$. Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le +R$ so $D \le C$. OK. -$ \p \notpatchisin C $ +\subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R) + \land D \isin M$:} +$D \not\isin C$. Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le +R$ so $D \le C$. OK. -$ \{ B \} \areparents C $ +$\qed$ \end{document}