Skip to content

Commit 518bb9e

Browse files
authored
Merge pull request #68648 from slavapestov/update-generics-tex
generics.tex: Protocol component graph, Tarjan's algorithm, etc
2 parents fc7d590 + 8ab4ee9 commit 518bb9e

17 files changed

+656
-473
lines changed

docs/Generics/chapters/basic-operation.tex

Lines changed: 456 additions & 301 deletions
Large diffs are not rendered by default.

docs/Generics/chapters/building-generic-signatures.tex

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ \chapter{Building Generic Signatures}\label{building generic signatures}
8181
\begin{figure}\captionabove{Overview of the inferred generic signature request}\label{inferred generic signature request figure}
8282
\begin{center}
8383
\begin{tikzpicture}[node distance=1.5cm]
84-
\tikzstyle{data} = [rounded corners, draw=black, text centered]
85-
\tikzstyle{stage} = [rectangle, draw=black, text centered]
86-
\tikzstyle{arrow} = [->,>=stealth]
87-
8884
\node (SyntacticRepresentations) [data] {Syntactic representations};
8985
\node (RequirementResolution) [stage, below of=SyntacticRepresentations] {Requirement resolution};
9086
\node (RequirementInference) [stage, below of=RequirementResolution] {Requirement inference};
@@ -125,10 +121,6 @@ \chapter{Building Generic Signatures}\label{building generic signatures}
125121
\begin{figure}\captionabove{Overview of the abstract generic signature request}\label{abstract generic signature request figure}
126122
\begin{center}
127123
\begin{tikzpicture}[node distance=1.5cm]
128-
\tikzstyle{data} = [rounded corners, draw=black, text centered]
129-
\tikzstyle{stage} = [rectangle, draw=black, text centered]
130-
\tikzstyle{arrow} = [->,>=stealth]
131-
132124
\node (Requirements) [data] {Requirements};
133125
\node (RequirementDesugaring) [stage, below of=Requirements] {Requirement desugaring};
134126
\node (RequirementMinimization) [stage, below of=RequirementDesugaring] {Requirement minimization};

docs/Generics/chapters/compilation-model.tex

Lines changed: 24 additions & 26 deletions
Large diffs are not rendered by default.

docs/Generics/chapters/completion.tex

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ \chapter{Completion}\label{completion}
88
\index{completion!z@\igobble|seealso{Knuth-Bendix algorithm}}
99
\lettrine{K}{nuth-Bendix completion} is the central algorithm in the Requirement Machine. Completion attempts to construct a \index{convergent rewrite system}convergent rewrite system from a list of rewrite rules, and a convergent rewrite system allows us to decide if two terms have the same reduced form in a finite number of steps, solving the word problem. As we saw in the previous chapter, our initial rewrite rules are defined by the explicit requirements of a generic signature and its protocol dependencies. A desirable property of this mapping was given by Theorem~\ref{derivation to path}: a \emph{derived} requirement defines a rewrite path over these rewrite rules representing explicit requirements. All of this means that completion gives us a \emph{decision procedure} for the \index{derived requirement}derived requirements formalism: the question of whether any given derived requirement is satisfied---that is, if there exists a valid derivation built from explicit requirements---is easily solved by term reduction in a convergent rewrite system. This is the foundation on which we build both \index{generic signature query}generic signature queries and \index{requirement minimization}minimization.
1010

11-
\paragraph{The algorithm.} We'll give a self-contained description first, with much of the rest of the chapter devoted to examples. Our description can be supplemented with any text on rewrite systems, such as \cite{book2012string} or \cite{andallthat}. The algorithm is somewhat clever; to really ``get it'' might require several attempts. Donald~E.~Knuth and Peter Bendix described the algorithm for term rewrite systems in a 1970 paper \cite{Knuth1983}; a correctness proof was later given by \cite{HUET198111}. In our application, the terms are elements of a free monoid, so we have a string rewrite system; this special case was studied in \cite{narendran}. A survey of related techniques appears in \cite{BUCHBERGER19873}.
11+
\paragraph{The algorithm.} We'll give a self-contained description first, with much of the rest of the chapter devoted to examples. Our description can be supplemented with any text on rewrite systems, such as \cite{book2012string} or \cite{andallthat}. The algorithm is somewhat clever; to really ``get it'' might require several attempts. \index{Donald~Knuth}Donald~E.~Knuth and \index{Peter Bendix}Peter Bendix described the algorithm for term rewrite systems in a 1970 paper \cite{Knuth1983}; a correctness proof was later given by \index{Gerard Huet@G\'erard Huet}G\'erard Huet in \cite{HUET198111}. In our application, the terms are elements of a free monoid, so we have a string rewrite system; this special case was studied in \cite{narendran}. A survey of related techniques appears in \cite{BUCHBERGER19873}.
1212

1313
The entry point into the Knuth-Bendix completion procedure is Algorithm~\ref{knuthbendix}, but we break off four smaller pieces before we get there, so that only the top-level loop remains:
1414
\begin{itemize}
@@ -529,7 +529,7 @@ \section{Rule Simplification}\label{rule reduction}
529529
\item The roles of ``left'' and ``right'' are reversed because requirements use a different convention; in a reduced same-type requirement $\FormalReq{U == V}$, we have $\texttt{U} < \texttt{V}$, whereas in a rewrite rule $u\Rightarrow v$ we have $v<u$.
530530
\item Reduced same-type requirements have the ``shortest'' distance between the left-hand and right-hand side, so if \texttt{T}, \texttt{U} and \texttt{V} are all equivalent and $\texttt{T}<\texttt{U}<\texttt{V}$, the corresponding requirements are $\FormalReq{T == U}$, $\FormalReq{U == V}$. On the other hand, if we have three terms $t$, $u$ and $v$ with $t<u<v$, then the two corresponding rewrite rules would be $u\Rightarrow t$, $v\Rightarrow t$.
531531
\end{itemize}
532-
These differences are explained by the original \Index{GenericSignatureBuilder@\texttt{GenericSignatureBuilder}}\texttt{GenericSignatureBuilder} minimization algorithm, described as finding a minimum spanning tree for a graph of connected components. The notion of reduced requirement output by this algorithm became part of the Swift stable \index{ABI}ABI. In Section~\ref{requirement builder} we show that a list of rewrite rules in a reduced rewrite system defines a list of reduced requirements via a certain transformation.
532+
These differences are explained by the original \Index{GenericSignatureBuilder@\texttt{GenericSignatureBuilder}}\texttt{GenericSignatureBuilder} minimization algorithm, described as finding a minimum \index{spanning tree}spanning tree for a graph of connected components. The notion of reduced requirement output by this algorithm became part of the Swift stable \index{ABI}ABI. In Section~\ref{requirement builder} we show that a list of rewrite rules in a reduced rewrite system defines a list of reduced requirements via a certain transformation.
533533

534534
What we call reduced rewrite systems are sometimes ``normalized'', ``canonical'', or ``inter-reduced'' in the literature. Our rewrite system also implements a third \emph{substitution simplification} pass for rewrite system simplification. Substitution simplification reduces substitution terms appearing in superclass, concrete type and concrete conformance symbols. We will discuss it in Chapter~\ref{propertymap}.
535535

@@ -1075,11 +1075,11 @@ \section{More Critical Pairs}
10751075
\end{gather*}
10761076
We see that applying $\Sigma_{\ConfReq{X}{S}}$ to \texttt{\ttgp{0}{0}.[S]A} and \texttt{\ttgp{0}{0}.[S]C.[S]B} also outputs identical types: $\AssocType{[S]A}\otimes\ConfReq{X}{S}=\AssocType{[S]B}\otimes\ConfReq{Y}{S}=\texttt{Int}$. Is this the case for \emph{every} conformance to \texttt{S}? That is, is it true that $G_\texttt{S}\vDash\FormalReq{\texttt{\ttgp{0}{0}.A} == \texttt{\ttgp{0}{0}.C.B}}$?
10771077

1078-
We will see the answer is ``yes,'' proving that our function \texttt{f()} type checks. For a geometric perspective, we turn to the \index{type parameter graph}type parameter graph\footnote{In our previous formulation, the type parameter graph has a distinguished root node, with every generic parameter as a child of this root. Now, our generic signature only has one generic parameter, so a root node would be superflous; we omit it in what follows.} for $G_\texttt{S}$. Figure~\ref{protocol s fig} constructs this graph in three stages:
1078+
We will see the answer is ``yes,'' proving that our function \texttt{f()} type checks. For a visual perspective, we turn to the \index{type parameter graph}type parameter graph\footnote{In our previous formulation, the type parameter graph has a distinguished root node, with every generic parameter as a child of this root. Now, our generic signature only has one generic parameter, so a root node would be superflous; we omit it in what follows.} for $G_\texttt{S}$. Figure~\ref{protocol s fig} constructs this graph in three steps. Between each step, we have a \index{graph homomorphism}graph homomorphism---in fact, a \index{covering map}covering map, in the sense of Section~\ref{protocol component}---transforming one graph into the other:
10791079
\begin{enumerate}
1080-
\item We first draw the graph as it would be without the protocol stating any same-type requirements; we get an infinite tree where each interior node is the parent of one other interior node, and two leaf nodes.
1080+
\item The first step shows the graph as it would be without the protocol stating any same-type requirements; we get an infinite tree where each interior node is the parent of one other interior node, and two leaf nodes.
10811081

1082-
\item The second step introduces the same-type requirement $\FormalReq{Self == Self.C.C}$, mapping the infinite tree down to a finite graph with a cycle. Those type parameters with an even number of \texttt{C}'s are now equivalent to \texttt{\ttgp{0}{0}}, and those with an odd number, to \texttt{\ttgp{0}{0}.C}.
1082+
\item The second step introduces the requirement $\FormalReq{Self == Self.C.C}$, collapsing the infinite tree down to a finite graph with a cycle. Those type parameters with an even number of \texttt{C}'s are now equivalent to \texttt{\ttgp{0}{0}}, and those with an odd number, to \texttt{\ttgp{0}{0}.C}.
10831083

10841084
\item The final step introduces $\FormalReq{Self.B == Self.C.A}$. This collapses \texttt{\ttgp{0}{0}.B} with \texttt{\ttgp{0}{0}.C.A}, and as one might suspect, \texttt{\ttgp{0}{0}.A} with \texttt{\ttgp{0}{0}.C.B}.
10851085
\end{enumerate}
@@ -1301,7 +1301,7 @@ \section{More Critical Pairs}
13011301

13021302
\smallskip
13031303

1304-
Protocol \texttt{S} is an interesting test case demonstrating the rewrite system's ability to discover non-trivial identities. It originates from a developer's bug report in 2020 \cite{sr12120}; at the time, it broke the \Index{GenericSignatureBuilder@\texttt{GenericSignatureBuilder}}\texttt{GenericSignatureBuilder}'s minimization algorithm. Amusingly, the \index{Rust}Rust compiler's generics implementation is unable to prove the derived requirement:
1304+
Protocol \texttt{S} is an interesting test case demonstrating the rewrite system's ability to discover non-trivial identities. It originates from a developer's bug report in 2020 \cite{sr12120}; \index{history}at the time, it broke the \Index{GenericSignatureBuilder@\texttt{GenericSignatureBuilder}}\texttt{GenericSignatureBuilder}'s minimization algorithm. Amusingly, the \index{Rust}Rust compiler's generics implementation is unable to prove the derived requirement:
13051305
\begin{Verbatim}
13061306
trait S {
13071307
type A;
@@ -1321,7 +1321,7 @@ \section{Tietze Transformations}\label{tietze transformations}
13211321

13221322
Both the \index{Knuth-Bendix algorithm}Knuth-Bendix completion and the \index{left simplification}rule simplification algorithms preserve the equivalence relation on terms. When completion adds a new rewrite rule, it is because the corresponding pair of terms are already joined by a \index{rewrite path}rewrite path. There is an analogous guarantee when \index{right simplification}rule simplification deletes a rewrite rule: the two terms are known to be joined by at least one other rewrite path that does not involve this rule. Intuitively, we understand that these transformations knead the \index{reduction relation}reduction relation into a better form, while the equivalence relation on terms remains completely determined by the relations of our initial \index{monoid presentation}monoid presentation.
13231323

1324-
Mathematically speaking, both algorithms are defined as a transformation on monoid presentations. This transformation decomposes into a composition of sequential steps, where at each step the monoid presentation is changed in such a way that \index{monoid isomorphism}monoid isomorphism is preserved. So far, we've seen two of the four fundamental isomorphism-preserving transformations; two more make the full set:
1324+
Mathematically speaking, both algorithms are defined as a transformation on monoid presentations. This transformation decomposes into a composition of sequential steps, where at each step the monoid presentation is changed in such a way that \index{monoid isomorphism}monoid isomorphism is preserved. So far, we've seen two of the four isomorphism-preserving transformations below, so named after \index{Heinrich Tietze}Heinrich Tietze, who introduced them in 1908:
13251325
\begin{definition}
13261326
Let $\AR$ be a finitely-presented monoid. An \IndexDefinition{Tietze transformation}\emph{elementary Tietze transformation}, or just Tietze transformation, is one of the following:
13271327
\begin{enumerate}

docs/Generics/chapters/concrete-conformances.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ \chapter{Concrete Conformances}\label{concrete conformances}
1515
\end{itemize}
1616
\fi
1717

18-
\section{Type Witnesses}
18+
\section{Type Witnesses}\label{rqm type witnesses}
1919

2020
\IndexTwoFlag{debug-requirement-machine}{concretize-nested-types}
2121

@@ -46,7 +46,7 @@ \section{Recursive Conformances}
4646

4747
\IndexFlag{enable-requirement-machine-opaque-archetypes}
4848

49-
\section{Concrete Contraction}
49+
\section{Concrete Contraction}\label{concrete contraction}
5050

5151
\IndexFlag{disable-requirement-machine-concrete-contraction}
5252
\IndexTwoFlag{debug-requirement-machine}{concrete-contraction}

0 commit comments

Comments
 (0)