\subsection{Category adjunctions}\label{subsec:category_adjunctions}

\begin{remark}\label{rem:adjoint_functors}\cite{StanfordPlato:category_theory}
  When the functor \( G: \cat{D} \to \cat{C} \) is left adjoint to \( F: \cat{C} \to \cat{D} \) and \( F \) is not invertible, then \( G \) finds a \enquote{generalized inverse} under \( F \) for every object in \( \cat{C} \) that try to \enquote{act the same} with respect to morphisms.

  \Fullref{def:category_adjunction} contains two equivalent definition of an adjunction, and \fullref{rem:universal_mapping_property} describes how they can be characterized via universal mapping properties.
\end{remark}

\begin{definition}\label{def:category_adjunction}\mcite[sec. 2.2]{Leinster2016Basic}
  An \term{adjunction} between the \hyperref[def:category]{categories} \( \cat{C} \) and \( \cat{D} \) can be defined in several equivalent ways. Let \( F: \cat{C} \to \cat{D} \) and \( G: \cat{D} \to \cat{C} \) be arbitrary functors.

  In all the cases below, if there exists an adjunction between \( F \) and \( G \), we say that \( F \) is \term{left adjoint} to \( G \) and, correspondingly, that \( G \) is \term{right adjoint} to \( F \). A conventional notation for adjoint functors is \( F \dashv G \).

  \begin{thmenum}
    \thmitem{def:category_adjunction/hom} A \term{hom-adjunction} is a triple \( (F, G, \varphi) \), where \( \varphi \) is \hyperref[thm:natural_isomorphism]{natural isomorphism}
    \begin{equation}\label{eq:def:category_adjunction/hom}
      \varphi: \cat{D}(F(\anon*), \anon*) \Rightarrow \cat{C}(\anon*, G(\anon*)).
    \end{equation}

    The functors
    \begin{align*}
      &\cat{D}(F(\anon*), \anon*): \cat{C}^{\opcat} \times \cat{D} \to \cat{Set}, \\
      &\cat{C}(\anon*, G(\anon*)): \cat{C}^{\opcat} \times \cat{D} \to \cat{Set}
    \end{align*}
    are straightforward modifications of the \hyperref[eq:def:hom_functor/binary]{binary hom-functor} on \( \cat{C} \).

    Naturality of \( \varphi \) in this case means that, for every two morphisms \( f: B \to A \) in \( \cat{C} \) and \( g: X \to Y \) in \( \cat{D} \), the following diagram commutes:
    \begin{equation}\label{eq:def:category_adjunction/varphi_nat}
      \begin{aligned}
        \includegraphics[page=1]{output/def__category_adjunction.pdf}
      \end{aligned}
    \end{equation}

    \thmitem{def:category_adjunction/unit_counit} A \term{unit-counit adjunction} is a quadruple \( (F, G, \eta, \varepsilon) \), where
    \begin{equation}\label{eq:def:category_adjunction/unit_counit/signature}
      \begin{aligned}
               \eta &: \id_{\cat{C}} \Rightarrow G \bincirc F, \\
        \varepsilon &: F \bincirc G \Rightarrow \id_{\cat{D}}
      \end{aligned}
    \end{equation}
    are natural transformations satisfying the condition that, for any pair of objects \( A \) in \( \cat{C} \) and \( Y \) in \( \cat{D} \), the following triangle diagrams commute:

    \begin{minipage}{0.43\textwidth}
      \begin{equation}\label{eq:def:category_adjunction/d_triangle}
        \begin{aligned}
          \includegraphics[page=2]{output/def__category_adjunction.pdf}
        \end{aligned}
      \end{equation}
    \end{minipage}
    \hfill
    \begin{minipage}{0.44\textwidth}
      \raggedright
      \begin{equation}\label{eq:def:category_adjunction/c_triangle}
        \begin{aligned}
          \includegraphics[page=3]{output/def__category_adjunction.pdf}
        \end{aligned}
      \end{equation}
    \end{minipage}
    \smallskip

    Note that an adjunction is not an \hyperref[def:category_equivalence]{equivalence}, they simply have a common setup. Similarly to \hyperref[def:category_equivalence]{equivalence}, we call the \hyperref[def:natural_transformation]{natural transformation} \( \eta \) the \term{unit} of the adjunction and \( \varepsilon \) the \term{counit}.
  \end{thmenum}
\end{definition}
\begin{defproof}
  \ImplicationSubProof{def:category_adjunction/hom}{def:category_adjunction/unit_counit} Let \( (F, G, \varphi) \) be a hom-adjunction.

  For every morphism \( f: B \to A \) in \( \cat{C} \), from the naturality of \( \varphi \) we have
  \begin{equation}\label{eq:def:category_adjunction/varphi_eta}
    \begin{aligned}
      \includegraphics[page=4]{output/def__category_adjunction.pdf}
    \end{aligned}
  \end{equation}

  Since \( \varphi_{A,F(B)} \) is a morphism in \( \cat{Set} \), it is a function, and we can apply it in order to define the family
  \begin{equation*}
    \begin{aligned}
      &\eta: \id_{\cat{C}} \Rightarrow G \bincirc F, \\
      &\eta_A \coloneqq \varphi_{A,F(A)}(\id_{F(A)}).
    \end{aligned}
  \end{equation*}

  We must show that \( \eta \) is a natural transformation. On the diagram \eqref{eq:def:category_adjunction/varphi_eta}, we can start in the top left corner with \( F(\id_A) \) and top right corner with \( F(\id_B) \) and reach the middle.

  We obtain that,
  \begin{equation*}
    \cat{C}(f, [G \bincirc F](\id_A))\parens[\Big]{ \underbrace{\varphi_{A, F(A)}(\id_A)}_{\eta_A} }
    =
    \eta_A \bincirc f
  \end{equation*}
  and
  \begin{equation*}
    \cat{C}(\id_B, [G \bincirc F](f))\parens[\Big]{ \underbrace{\varphi_{B, F(B)}(\id_B)}_{\eta_B} }
    =
    [G \bincirc F](f) \bincirc \eta_B
  \end{equation*}
  are equal. That is, the following diagram commutes:
  \begin{equation}\label{eq:def:category_adjunction/eta_nat}
    \begin{aligned}
      \includegraphics[page=5]{output/def__category_adjunction.pdf}
    \end{aligned}
  \end{equation}

  In order to define the natural transformation \( \varepsilon: F \bincirc G \Rightarrow \id_{\cat{D}} \), we use the inverse transformation \( \varphi^{-1} \). For every morphism \( g: X \to Y \) in \( \cat{D} \), we have
  \begin{equation}\label{eq:def:category_adjunction/varphi_varepsilon}
    \begin{aligned}
      \includegraphics[page=6]{output/def__category_adjunction.pdf}
    \end{aligned}
  \end{equation}

  Thus, we define the family
  \begin{equation*}
    \begin{aligned}
      &\varepsilon: F \bincirc G \Rightarrow \id_{\cat{D}}, \\
      &\varepsilon_X \coloneqq \varphi_{G(X),X}^{-1}(\id_{G(X)}).
    \end{aligned}
  \end{equation*}

  We can prove that \( \varepsilon \) is a natural transformation analogously to how we proved it for \( \eta \), and we will skip the details.

  We will now show that the triangle diagram \eqref{eq:def:category_adjunction/d_triangle} commutes. Consider the morphism \( (\eta_A, F(\id_A)) \) in \( \cat{C}^{\opcat} \times \cat{D} \). Applying the functors \( \cat{D}(F(\anon*), \anon*) \) and \( \cat{D}(\anon*, G(\anon*)) \) to this morphism and using the naturality of \( \varphi \), we obtain
  \begin{equation}\label{eq:def:category_adjunction/d_triangle_proof}
    \begin{aligned}
      \includegraphics[page=7]{output/def__category_adjunction.pdf}
    \end{aligned}
  \end{equation}

  Note that \( \varepsilon_{F(A)} \) is a member of \( \cat{D}([F \bincirc G \bincirc F](A), F(A)) \).

  Composing the functions in \eqref{eq:def:category_adjunction/d_triangle_proof} in one direction, we obtain
  \begin{balign*}
    &\phantom{{}={}}
    \varphi_{A,F(A)}^{-1} \parens[\Bigg]{ \cat{C}\parens[\Big]{ \eta_A, [G \bincirc F](\id_A) } \parens[\Big]{ \varphi_{[G \bincirc F](A),F(A)} (\varepsilon_{F(A)}) } }
    = \\ &=
    \varphi_{A,F(A)}^{-1} \parens[\Bigg]{ \parens[\Big]{ \varphi_{[G \bincirc F](A),F(A)} (\varepsilon_{F(A)}) } \bincirc \eta_A }
    = \\ &=
    \varphi_{A,F(A)}^{-1} \parens[\Big]{ \id_{[G \bincirc F](A)} \bincirc \eta_A }
    = \\ &=
    \id_{F(A)}.
  \end{balign*}

  Composing the functions in \eqref{eq:def:category_adjunction/d_triangle_proof} in the other direction, we obtain
  \begin{equation*}
    \cat{D}\parens[\Big]{ F(\eta_A), F(\id_A) } (\varepsilon_{F(A)})
    =
    \varepsilon_{F(A)} \bincirc F(\eta_A).
  \end{equation*}

  Therefore,
  \begin{equation*}
    \id_{F(A)} = \varepsilon_{F(A)} \bincirc F(\eta_A).
  \end{equation*}
  and thus \eqref{eq:def:category_adjunction/d_triangle} commutes.

  We can similarly prove that \eqref{eq:def:category_adjunction/c_triangle} commutes.

  Therefore, \( (F, G, \eta, \varepsilon) \) is a unit-counit adjunction.

  \ImplicationSubProof{def:category_adjunction/unit_counit}{def:category_adjunction/hom} Let \( (F, G, \eta, \varepsilon) \) be a unit-counit adjunction.

  For every pair of objects \( A \in \cat{C} \) and \( X \in \cat{D} \), define the functions
  \begin{equation*}
    \begin{aligned}
      &\varphi_{A,X}: \cat{D}(F(A), X) \to \cat{C}(A, G(X)) \\
      &\varphi_{A,X}(g) \coloneqq G(g) \bincirc \eta_A.
    \end{aligned}
  \end{equation*}
  and
  \begin{equation*}
    \begin{aligned}
      &\psi_{A,X}^{-1}: \cat{C}(A, G(X)) \to \cat{D}(F(A), X) \\
      &\psi_{A,X}^{-1}(f) \coloneqq \varepsilon_X \bincirc F(f),
    \end{aligned}
  \end{equation*}

  From the naturality of \( \varepsilon \) and from \eqref{eq:def:category_adjunction/d_triangle} it follows that the following diagram commutes:
  \begin{equation}\label{eq:def:category_adjunction/varphi_inverse_def}
    \begin{aligned}
      \includegraphics[page=8]{output/def__category_adjunction.pdf}
    \end{aligned}
  \end{equation}

  Therefore,
  \begin{equation*}
    g = \varepsilon_X \bincirc \underbrace{[F \bincirc G](f) \bincirc F(\eta_A)}_{F(\varphi_{A,X}(g))} = [\phi_{A,X} \bincirc \varphi_{A,X}](g)
  \end{equation*}
  and thus \( \psi_{A,X} \) is a left inverse of \( \varphi_{A,X} \).

  We can analogously show that \( \psi_{A,X} \) is a right inverse, and hence that \( \varphi_{A,X} \) is invertible.

  Since we have already shown that \( \varphi \) is a bijective function, it remains to verify the naturality of \( \varphi \) in order to show that it is a natural isomorphism. Let \( f: B \to A \) be a morphism in \( \cat{C} \) and \( g: X \to Y \) be a morphism in \( \cat{D} \). Fix some morphism \( s: F(A) \to X \).

  Composing the functions of \eqref{eq:def:category_adjunction/varphi_nat} in one direction, we obtain
  \begin{equation}\label{eq:def:category_adjunction/varphi_nat_chase_right}
    \varphi_{B, Y}\parens[\Big]{ \cat{D}(F(f), g)(s) }
    =
    \varphi_{B, Y}\parens[\Big]{ g \bincirc s \bincirc F(f) }
    =
    G(g) \bincirc G(s) \bincirc [G \bincirc F](f) \bincirc \eta_B.
  \end{equation}

  In the other direction, we have
  \begin{equation}\label{eq:def:category_adjunction/varphi_nat_chase_down}
    \cat{C}(f, G(g))\parens[\Big]{ \varphi_{A, X}(s) }
    =
    \cat{C}(f, G(g))\parens[\Big]{ G(s) \bincirc \eta_A }
    =
    G(g) \bincirc G(s) \bincirc \eta_A \bincirc f.
  \end{equation}

  From the naturality of \( \eta \), we have that \eqref{eq:def:category_adjunction/eta_nat} commutes and hence
  \begin{equation*}
    \eta_A \bincirc f
    =
    [G \bincirc F](s) \bincirc \eta_B.
  \end{equation*}

  Therefore, \eqref{eq:def:category_adjunction/varphi_nat_chase_right} and \eqref{eq:def:category_adjunction/varphi_nat_chase_down} are equal and, thus, \eqref{eq:def:category_adjunction/varphi_nat} also commutes.

  This proves the naturality of \( \varphi \).
\end{defproof}

\begin{proposition}\label{thm:category_adjunction_duality}
  The functor \( F: \cat{C} \to \cat{D} \) is \hyperref[def:category_adjunction]{left adjoint} to \( G: \cat{D} \to \cat{C} \) if and only if the \hyperref[def:dual_functor]{dual functor} \( F^{\opcat} \) is right adjoint to \( G^{\opcat} \).

  This is part of the duality principles listed in \fullref{thm:categorical_principle_of_duality}.
\end{proposition}
\begin{proof}
  \begin{equation*}
    \cat{C^{\opcat}}(G^{\opcat}(X), A) = \cat{C}(A, G(X)) \cong \cat{D}(F(A), X) = \cat{D^{\opcat}}(X, F^{\opcat}(A)).
  \end{equation*}
\end{proof}

\begin{definition}\label{def:concrete_category}\mcite[26]{MacLane1994}
  A \term{concrete category} is a pair \( (\cat{C}, U) \), where \( \cat{C} \) is a category and \( U: \cat{C} \to \cat{Set} \) is a \hyperref[def:functor_invertibility/faithful]{faithful functor} that gives us a set for any object of \( \cat{C} \). More generally, a \( \cat{D} \)-concrete category is a pair \( (\cat{C}, U) \), where \( U: \cat{C} \to \cat{D} \).

  In the context of a concrete category, we call \( U \) a \term{forgetful functor} and any \hyperref[def:category_adjunction]{left adjoint} to \( U \) functor a \term{free functor}. According to Jean-Pierre Marquis in \cite{StanfordPlato:category_theory}, the motivation for this terminology is that free functors build objects that are free from additional restrictions.

  We list several examples in \fullref{ex:def:category_adjunction}. The forgetful functor is usually clear from the context, and we identify a concrete category \( (\cat{C}, U) \) with its underlying set \( \cat{C} \). The corresponding free functor, however, often requires a nontrivial but straightforward construction.
\end{definition}

\begin{example}\label{ex:def:category_adjunction}
  We list some examples of \hyperref[def:category_adjunction]{category adjunctions}. Note that only some of them are commonly referred to as \enquote{free}.

  \begin{thmenum}
    \thmitem{ex:def:category_adjunction/set_top} Perhaps the simplest meaningful example of an adjunction is the \hyperref[def:standard_topologies/discrete]{discrete topology} functor \( D: \cat{Set} \to \cat{Top} \), which is left adjoint to the forgetful functor \( U: \cat{Top} \to \cat{Set} \), which maps a small \hyperref[def:topological_space]{topological space} \( (\mscrX, \mscrT) \) into its underlying set \( \mscrX \).

    Given a set \( A \) and a topological space \( (\mscrX, \mscrT) \), every function \( s: A \to \mscrX \) is \hyperref[def:global_continuity]{continuous} when \( A \) is endowed with the discrete topology. Conversely, every continuous function is obviously a \hyperref[def:function]{function}. It follows that there is an equality
    \begin{equation*}
      \cat{Top}\parens[\Big]{ \underbrace{(A, \pow(A))}_{D(A)}, (\mscrX, \mscrT) } = \cat{Set}\parens[\Big]{ A, \mscrX }.
    \end{equation*}

    Therefore, \( (D, U, \id) \) is a hom-adjunction. Furthermore, \( (D, U, \id, \id) \) is a unit-counit adjunction.

    \thmitem{ex:def:category_adjunction/top_set} The \hyperref[def:standard_topologies/discrete]{indiscrete topology} functor \( I: \cat{Set} \to \cat{Top} \) is right-adjoint to the same forgetful functor \( U: \cat{Top} \to \cat{Set} \), again with identities for all natural transformations of the adjunction.

    Therefore, we have
    \begin{equation*}
      D \dashv U \dashv I.
    \end{equation*}

    \thmitem{ex:def:category_adjunction/set_cat} We discussed in \fullref{ex:discrete_category_adjunction} the \hyperref[def:discrete_category]{discrete category} functor \( D: \cat{Set} \to \cat{Cat} \). We showed in \fullref{ex:set_discr_cat_isomorphism} that, when restricted to the subcategory \( \cat{DiscrCat} \) rather than \( \cat{Cat} \), \( D \) it is an inverse to the forgetful functor \( U \). In the general case, however, this is an adjunction rather than an isomorphism. More precisely, \( D \) is left adjoint to \( U \).

    Note that for any functor \( F: \cat{C} \to \cat{D} \), we have \( U(F) \coloneqq F\restr_{\obj(C)} \). Thus, \( U \) is not only a functor in \( [\cat{Cat}, \cat{Set}] \); it also induces a natural isomorphism between the functors \( \cat{Cat}(D(\anon*), \cat{\anon*}) \) and \( \cat{Set}(\anon*, U(\anon*)) \).

    Indeed, fix a small category \( \cat{C} \) and a set \( A \). From our discussion in \fullref{ex:set_discr_cat_isomorphism} it is obvious that the restriction
    \begin{equation*}
      U: \cat{Cat}(D(A), \cat{C}) \to \cat{Set}(A, U(\cat{C}))
    \end{equation*}
    is a bijective function.

    In order to verify the naturality of the transformation induced by \( U \), we must show that for any function \( f: B \to A \) and functor \( F: \cat{C} \to \cat{D} \), the following diagram commutes
    \begin{equation}\label{eq:ex:def:category_adjunction/set_cat/u_nat}
      \begin{aligned}
        \includegraphics[page=1]{output/ex__def__category_adjunction.pdf}
      \end{aligned}
    \end{equation}

    The commutativity of \eqref{eq:ex:def:category_adjunction/set_cat/u_nat} follows from the following: for every functor \( S: D(A) \to \cat{C} \) we have
    \begin{equation*}
      U(F \bincirc S \bincirc D(f))
      =
      U(F) \bincirc U(S) \bincirc U(D(f))
      =
      U(F) \bincirc U(S) \bincirc f.
    \end{equation*}

    Therefore, \( (D, U, U) \) is a \hyperref[def:category_adjunction/hom]{hom-adjunction}.

    We can also explicitly define a unit-counit adjunction. The unit \( \eta: \id_{\cat{Set}} \Rightarrow U \bincirc D \) is simply the identity.

    The counit is slightly more interesting. Given a small category \( \cat{C} \), applying \( D \bincirc U \) gives us the subcategory consisting only of the objects and identity morphisms of \( \cat{C} \). Then the counit \( \varepsilon: D \bincirc U \Rightarrow \id_{\cat{Cat}} \) is simply the inclusion functor \( \Iota \) from this subcategory to \( \cat{C} \).

    The triangle
    \begin{equation}\label{eq:ex:def:category_adjunction/set_cat/triangles}
      \begin{aligned}
        \includegraphics[page=2]{output/ex__def__category_adjunction.pdf}
        \quad\quad
        \includegraphics[page=3]{output/ex__def__category_adjunction.pdf}
      \end{aligned}
    \end{equation}
    corresponding to \eqref{eq:def:category_adjunction/d_triangle} and \eqref{eq:def:category_adjunction/c_triangle}, obviously commute.

    The quadruple \( (D, U, \eta, \varepsilon) \) is a \hyperref[def:category_adjunction/unit_counit]{unit-counit adjunction}.

    \thmitem{ex:def:category_adjunction/quiv_cat} The left adjoint of the forgetful functor \( U: \cat{Cat} \to \cat{Quiv} \) is the free category functor defined in \fullref{def:quiver_free_category}. We denote this functor by \( F: \cat{Quiv} \to \cat{Cat} \).

    We can define the family of functions
    \begin{equation}\label{eq:ex:def:category_adjunction/quiv_cat/varphi_family}
      \begin{aligned}
        &\varphi: \cat{Cat}(F(\anon*), \cat{\anon*}) \Rightarrow \cat{Quiv}(\anon*, U(\cat{\anon*})), \\
        &\varphi_{Q, \cat{C}}(S) \coloneqq \parens[\Big]{ v \mapsto S(v), a \mapsto S(\iota(a)) }.
      \end{aligned}
    \end{equation}

    For every functor \( S: F(Q) \to \cat{C} \), \( \varphi_{Q, \cat{C}} \) defines a quiver homomorphism that restricts \( S \) to \hyperref[def:quiver_path]{quiver paths} of containing only one arc. Formally, \( \iota \) is the canonical embedding
    \begin{equation*}
      \begin{aligned}
        &\iota: Q \to [U \bincirc F](Q) \\
        &\iota_V(v) \coloneqq v,
        &\iota_A(a) \coloneqq (h(a), a).
      \end{aligned}
    \end{equation*}

    We will later see that \( \iota \) is the unit of a unit-counit adjunction.

    Now, from \eqref{eq:def:quiver_free_category/functor_from_homomorphism}, it is clear that the free category functor \( F \), when restricted to the set of quiver homomorphisms \( \cat{Quiv}(Q, U(\cat{C})) \), is the two-sided inverse of \( \varphi_{Q, \cat{C}} \).

    We will show that \( \varphi \) is a natural transformation. Fix a functor \( G: \cat{C} \to \cat{D} \) and a homomorphism \( (g_V, g_A): Q \to R \). We must show that the following diagram commutes:
    \begin{equation}\label{eq:ex:def:category_adjunction/quiv_cat/varphi_nat}
      \begin{aligned}
        \includegraphics[page=4]{output/ex__def__category_adjunction.pdf}
      \end{aligned}
    \end{equation}

    That is, for every functor \( S: F(A) \to \cat{C} \), we must show
    \begin{equation*}
      \varphi_{R, \cat{D}}(G \bincirc S \bincirc F(g_V, g_A))
      =
      U(G) \bincirc \varphi_{R, \cat{D}}(S) \bincirc (g_V, g_A).
    \end{equation*}

    This is also clear from \eqref{eq:def:quiver_free_category/functor_from_homomorphism}.

    Therefore, \( (F, U, \varphi) \) is a \hyperref[def:category_adjunction/hom]{hom-adjunction}.

    Furthermore, the canonical embedding \( \iota \) defined above, when parameterized by \( Q \), is a unit of adjunction.

    The counit  \( \varepsilon: F \bincirc U \Rightarrow \id_{\cat{Cat}} \) is more involved. As discussed in \fullref{def:quiver_free_category}, for every finite path \( p \) in the quiver \( U(\cat{C}) \) with arcs \( a_1, \ldots, a_n \), the functor \( F \bincirc U \) simply \enquote{evaluates} \( p \) as
    \begin{equation*}
      a_n \bincirc a_{n-1} \bincirc \cdots \bincirc a_1.
    \end{equation*}

    Since the embedding only produces paths with a single arc, the adjunction triangles commute:
    \begin{equation}\label{eq:ex:def:category_adjunction/quiv_cat/triangles}
      \begin{aligned}
        \includegraphics[page=5]{output/ex__def__category_adjunction.pdf}
        \quad\quad
        \includegraphics[page=6]{output/ex__def__category_adjunction.pdf}
      \end{aligned}
    \end{equation}

    \thmitem{ex:def:category_adjunction/multgph_quiv} In \fullref{def:quiver/forgetful}, we have defined the \hyperref[def:concrete_category]{forgetful functor} \( U: \hyperref[def:category_of_small_quivers]{\cat{Quiv}} \to \hyperref[def:undirected_multigraph]{\cat{MultGph}} \). Given a \hyperref[def:grothendieck_universe]{Grothendieck universe} \( \mscrU \) and a choice function \( c \) for the family of two-element sets in \( \mscrU \), we have an orientation functor \( O_c: \cat{MultGph} \to \cat{Quiv} \) defined in \fullref{def:multigraph_orientation}.

    It may seem that, for a fixed choice function, \( O_c \) is \hyperref[def:category_adjunction]{left adjoint} to \( U \). This is not true, however, as shown in \cref{fig:ex:def:category_adjunction/multgph_quiv}.

    \begin{figure}
      \hfill
      \includegraphics[page=7]{output/ex__def__category_adjunction.pdf}
      \hfill
      \includegraphics[page=8]{output/ex__def__category_adjunction.pdf}
      \hfill\hfill
      \caption{Two undirected homomorphisms from \( G \) to \( U(Q) \), denoted using dashed lines, only one of which is a quiver homomorphism from \( O_c(G) \) to \( Q \)}
      \label{fig:ex:def:category_adjunction/multgph_quiv}
    \end{figure}
  \end{thmenum}
\end{example}

\begin{definition}\label{def:adjoint_equivalence}
  We call the quadruple \( (F, G, \eta, \varepsilon) \) with signature \eqref{eq:def:category_equivalence/signature} an \term{adjoint equivalence} if it is both an \hyperref[def:category_adjunction]{adjunction} and \hyperref[def:category_equivalence]{equivalence}.
\end{definition}

\begin{proposition}\label{thm:adjoint_equivalence}
  Let \( (F, G, \eta, \varepsilon) \) be a \hyperref[def:category_equivalence]{category equivalence} between \( \cat{C} \) and \( \cat{D} \).

  There exists a natural isomorphism \( \zeta: \id_{\cat{C}} \Rightarrow G \bincirc F \) such that \( (F, G, \zeta, \varepsilon) \) is an \hyperref[def:adjoint_equivalence]{adjoint equivalence}.
\end{proposition}
\begin{proof}
  From \fullref{thm:equivalence_induces_fully_faithful_and_essentially_surjective_functor} it follows that \( F \) is fully faithful and essentially surjective.

  We will now use the same trick as in the end of the proof of \fullref{thm:fully_faithful_and_essentially_surjective_functor_induces_equivalence} to define \( \zeta \).

  Since \( F \) is fully faithful, there is a bijective function
  \begin{equation*}
    \varphi: \cat{D}\parens[\Big]{ F(A), [F \bincirc G \bincirc F](A) } \to \cat{C}\parens[\Big]{ A, [F \bincirc G](A) }.
  \end{equation*}

  Hence, we can define
  \begin{equation*}
    \begin{aligned}
      &\zeta: \id_{\cat{C}} \to G \bincirc F, \\
      &\zeta_A \coloneqq \varphi(\varepsilon_{F(A)}^{-1})
    \end{aligned}
  \end{equation*}
  so that \( F(\zeta_A) = \varepsilon_{F(A)}^{-1} \). By \fullref{thm:def:functor_invertibility/properties/fully_faithful_reflects_isomorphisms}, \( \zeta_A \) is also an isomorphism.

  As in \fullref{thm:fully_faithful_and_essentially_surjective_functor_induces_equivalence}, we use \fullref{thm:commutative_diagrams_preserved_and_reflected} and the naturality of \( \varepsilon \) to prove that \eqref{eq:thm:fully_faithful_and_essentially_surjective_functor_induces_equivalence/varepsilon_source_nat} implies \eqref{eq:thm:fully_faithful_and_essentially_surjective_functor_induces_equivalence/varepsilon_image_nat} (with \( \eta \) replaced by \( \zeta \)).

  Therefore, \( \zeta \) is a natural isomorphism and the quadruple \( (F, G, \zeta, \varepsilon) \) is an equivalence of categories.
\end{proof}

\begin{proposition}\label{thm:functor_adjoint_uniqueness}
  If a functor has two \hyperref[def:category_adjunction]{left adjoints} (resp. right adjoints), then there exists a unique natural isomorphism between them.

  We say that left adjoints (resp. right adjoints) are unique up to a natural isomorphism.
\end{proposition}
\begin{proof}
  We will first prove the statement for left adjoints. Suppose that \( (F', G, \eta', \varepsilon') \) and \( (F', G, \eta^\dprime, \varepsilon^\dprime) \) are two unit-counit adjunctions.

  \SubProof{Proof of existence of isomorphism}\mcite{MathSE:left_adjoint_uniqueness} We can utilize the naturality of the units \( \eta' \) and \( \eta^\dprime \) and counits \( \varepsilon' \) and \( \varepsilon^\dprime \) to show that the following diagram commutes:
  \begin{equation}\label{eq:thm:functor_adjoint_uniqueness/existence}
    \begin{aligned}
      \includegraphics[page=1]{output/thm__functor_adjoint_uniqueness.pdf}
    \end{aligned}
  \end{equation}

  By the commuting triangle \eqref{eq:def:category_adjunction/d_triangle}, all paths from \( F'(A) \) to \( F'(A) \) above are identities.

  The bottom-most path in \eqref{eq:thm:functor_adjoint_uniqueness/existence} justifies defining the natural transformation
  \begin{equation*}
    \begin{aligned}
      &\alpha: F' \Rightarrow F^\dprime \\
      &\alpha_A \coloneqq \varepsilon'_{F^\dprime(A)} \bincirc F'(\eta_A^\dprime).
    \end{aligned}
  \end{equation*}

  Then \( \alpha_A \) is an isomorphism for every object \( A \) in \( \cat{C} \) with inverse \( \varepsilon_{F'(A)}^\dprime \bincirc F^\dprime(\eta_A') \). Therefore, it is a natural isomorphism from \( F' \) to \( F^\dprime \).

  \SubProof{Proof of uniqueness of isomorphism} Suppose that \( \beta: F' \Rightarrow F^\dprime \) is another natural isomorphism. Then, by the commuting triangle \eqref{eq:def:category_adjunction/d_triangle}, the following diagram also commutes:
  \begin{equation}\label{eq:thm:functor_adjoint_uniqueness/uniqueness}
    \begin{aligned}
      \includegraphics[page=2]{output/thm__functor_adjoint_uniqueness.pdf}
    \end{aligned}
  \end{equation}

  Therefore,
  \begin{equation*}
    \beta_A
    =
    \varepsilon^\dprime_{F^\dprime(A)} \bincirc F^\dprime(\eta^\dprime_A) \bincirc \alpha_A
    \reloset {\eqref{eq:def:category_adjunction/d_triangle}} =
    \alpha_A.
  \end{equation*}

  This finishes the proof for left adjoints. The other direction is \hyperref[thm:categorical_principle_of_duality]{dual}. If \( G' \) and \( G^\dprime \) are two right adjoints to \( F \), then by \fullref{thm:category_adjunction_duality}, \( G'^{\opcat} \) and \( {G^\dprime}^{\opcat} \) are left adjoints and are thus isomorphic. Then by \fullref{thm:morphism_invertibility_duality}, \( G' \) and \( G^\dprime \) are also isomorphic.
\end{proof}

\begin{proposition}\label{thm:universal_objects_as_adjunctions}
  Fix a category \( \cat{C} \). We can characterize the universal objects in \( \cat{C} \) from \fullref{def:universal_objects} via adjunctions with the \hyperref[def:universal_categories]{terminal category} \( \cat{1} \).

  Let \( \Delta^{\cat{1}}: \cat{C} \to \cat{1} \) be the \hyperref[def:diagonal_functor]{constant functor} into \( \cat{1} \).

  \begin{thmenum}
    \thmitem{thm:universal_objects_as_adjunctions/initial} The object \( I \) of \( \cat{C} \) is \hyperref[def:universal_objects]{initial} if and only if it is (the unique value of) a left adjoint to \( \Delta^{\cat{1}} \) functor.

    In particular, the uniqueness proved in \fullref{thm:def:universal_objects/properties/initial} follows from \fullref{thm:functor_adjoint_uniqueness}.

    \thmitem{thm:universal_objects_as_adjunctions/terminal} \hyperref[thm:categorical_principle_of_duality]{Dually}, the \hyperref[def:universal_objects]{terminal objects} are exactly the right adjoint to \( \Delta_I^{\cat{1}} \) functors.
  \end{thmenum}
\end{proposition}
\begin{proof}
  We will only prove \fullref{thm:universal_objects_as_adjunctions/initial} since the other direction is \hyperref[thm:categorical_principle_of_duality]{dual}.

  \SufficiencySubProof Let \( I \) be an initial object in \( \cat{C} \). We can then regard it as a functor \( F: \cat{1} \to \cat{C} \).

  We define the natural transformations
  \begin{equation*}
    \begin{aligned}
      &\eta: \id_{\cat{1}} \Rightarrow \Delta_I^{\cat{1}} \bincirc F \\
      &\eta_{\cat{0}} \coloneqq \id_{\cat{0}}
    \end{aligned}
  \end{equation*}
  and
  \begin{equation*}
    \begin{aligned}
      &\varepsilon: F \bincirc \Delta_I^{\cat{1}} \Rightarrow \id_{\cat{C}} \\
      &\varepsilon_A \T{is the unique morphism} I \to A
    \end{aligned}
  \end{equation*}

  Since \( I \) has a unique morphism into any other object of \( \cat{C} \), for every morphism \( f: A \to B \), the following diagram commutes:
  \begin{equation}\label{eq:thm:universal_objects_as_adjunctions/sufficiency_nat}
    \begin{aligned}
      \includegraphics[page=1]{output/thm__universal_objects_as_adjunctions.pdf}
    \end{aligned}
  \end{equation}

  It follows that both \( \eta \) and \( \varepsilon \) are natural transformations. Furthermore, they trivially satisfy the triangle diagrams triangle \eqref{eq:def:category_adjunction/d_triangle} and \eqref{eq:def:category_adjunction/c_triangle}.

  Hence, \( (F, \Delta_I^{\cat{1}}, \eta, \varepsilon) \) is a \hyperref[def:category_adjunction/unit_counit]{unit-counit adjunction}.

  \NecessitySubProof Conversely, suppose that \( (F, \Delta_I^{\cat{1}}, \eta, \varepsilon) \) is a unit-counit adjunction.

  Let \( I \coloneqq F(\cat{0}) \). Then \( \varepsilon_A \) is a morphism from \( I \) to \( A \). By \eqref{eq:def:category_adjunction/d_triangle}, \( \varepsilon_I = \id_I \) since the following diagram commutes:
  \begin{equation}\label{eq:thm:universal_objects_as_adjunctions/d_triangle}
    \begin{aligned}
      \includegraphics[page=2]{output/thm__universal_objects_as_adjunctions.pdf}
    \end{aligned}
  \end{equation}

  Suppose that \( \zeta \) is another morphism from \( I \) to \( A \). The naturality of \( \varepsilon \) implies that, for the morphism \( \id_A: A \to A \), the following diagram commutes:
  \begin{equation}\label{eq:thm:universal_objects_as_adjunctions/necessity_nat}
    \begin{aligned}
      \includegraphics[page=3]{output/thm__universal_objects_as_adjunctions.pdf}
    \end{aligned}
  \end{equation}

  The upper left triangle in \eqref{eq:thm:universal_objects_as_adjunctions/necessity_nat} is \eqref{eq:thm:universal_objects_as_adjunctions/d_triangle}.

  We conclude that \( \zeta = \varepsilon_A \) and, generalizing on \( A \), that every morphism from \( I \) is unique.
\end{proof}

\begin{remark}\label{rem:left_and_right_adjoint_not_equivalence}
  We discussed in \fullref{ex:def:universal_objects/grp} that \enquote{the} trivial group \( \set{ e } \) is a \hyperref[def:universal_objects/zero]{zero object} of \( \cat{Grp} \). By \fullref{thm:universal_objects_as_adjunctions}, this object induces a functor that is both left adjoint and right adjoint of \( \Delta_I^{\cat{1}} \). Nevertheless, the categories \( \cat{Grp} \) and \( \cat{1} \) are not \hyperref[def:category_equivalence]{equivalent}.
\end{remark}

\begin{remark}\label{rem:universal_mapping_property}
  We will now regard adjoint functors as a way to \enquote{construct} new objects.

  Let \( (F, G, \iota, \pi) \) be a \hyperref[def:category_adjunction/unit_counit]{unit-counit adjunction} between the categories \( \cat{C} \) and \( \cat{D} \). In the current context, especially in connection with \hyperref[def:category_of_cones/limit]{limits} and \hyperref[def:category_of_cones/colimit]{colimits}, we will call the components of the counit \( \pi: F \bincirc G \Rightarrow \id_{\cat{D}} \) --- \term{projections}, and the components of the unit \( \iota: \id_{\cat{C}} \Rightarrow G \bincirc F \) --- \term{coprojections}.

  Take objects \( A \) in \( \cat{C} \) and \( X \) in \( \cat{D} \) and a morphism \( f: A \to G(X) \). We want to obtain a morphism \( \widetilde{f}: F(A) \to X \), for which the following diagram commutes:
  \begin{equation}\label{eq:rem:universal_mapping_property/c_triangle}
    \begin{aligned}
      \includegraphics[page=1]{output/rem__universal_mapping_property.pdf}
    \end{aligned}
  \end{equation}

  From the naturality of \( \iota \) and from the triangle diagram \eqref{eq:def:category_adjunction/c_triangle} it follows that the following diagram commutes:
  \begin{equation}\label{eq:rem:universal_mapping_property/f_tilde_existence}
    \begin{aligned}
      \includegraphics[page=2]{output/rem__universal_mapping_property.pdf}
    \end{aligned}
  \end{equation}

  It is clear from \eqref{eq:rem:universal_mapping_property/f_tilde_existence} that
  \begin{equation*}
    G(\widetilde{f}) = G(\pi_X) \bincirc [G \bincirc F](f) = G(\pi_X \bincirc F(f)).
  \end{equation*}

  Furthermore, this value is unique. From the naturality of \( \pi \) and the triangle diagram \eqref{eq:def:category_adjunction/d_triangle} it follows that the following diagram commutes:
  \begin{equation}\label{eq:rem:universal_mapping_property/f_tilde_uniquness}
    \begin{aligned}
      \includegraphics[page=3]{output/rem__universal_mapping_property.pdf}
    \end{aligned}
  \end{equation}

  Therefore,
  \begin{equation*}
    \widetilde{f} = \pi_X \bincirc F(f)
  \end{equation*}

  Taking into account that the functor \( F \) itself is unique up to a unique isomorphism, as per \fullref{thm:functor_adjoint_uniqueness}, we have proved the following statement:
  \begin{displayquote}
    For every object \( A \) in \( \cat{C} \), there exist unique up to a unique isomorphism object \( F(A) \) in \( \cat{D} \) and canonical coprojection map \( \iota_A: A \to [G \bincirc F](A) \) satisfying the following property, called a \term{universal mapping property}:
    \begin{displayquote}
      For every object \( X \) in \( \cat{D} \) and every map \( f: A \to G(X) \) in \( \cat{C} \), there exists a unique map \( \widetilde{f}: F(A) \to X \) in \( \cat{D} \) such that the diagram \eqref{eq:rem:universal_mapping_property/c_triangle} commutes.
    \end{displayquote}
  \end{displayquote}

  Intuitively, this universal mapping property states that any map (morphism) with domain \( A \) in \( \cat{C} \) can be transformed into a map with domain \( F(A) \) in \( \cat{D} \).

  The statement becomes more meaningful when we regard \( G: \cat{D} \to \cat{C} \) as a \hyperref[def:concrete_category]{forgetful functor}. In this case, every object of \( \cat{D} \) is regarded as an object of \( \cat{C} \), and we write \( X \) rather than \( G(X) \). The universal mapping property then becomes:
  \begin{displayquote}
    For every object \( A \) in \( \cat{C} \), there exist unique up to a unique isomorphism object \( F(A) \) in \( \cat{D} \) and canonical coprojection map \( \iota_A: A \to F(A) \) satisfying the following universal mapping property:
    \begin{displayquote}
      For every object \( X \) in \( \cat{D} \) and every map \( f: A \to X \) in \( \cat{C} \), there exists a unique map \( \widetilde{f}: F(A) \to X \) in \( \cat{D} \) such that the following diagram commutes:
      \begin{equation}\label{eq:rem:universal_mapping_property/c_triangle_forgetful}
        \begin{aligned}
          \includegraphics[page=4]{output/rem__universal_mapping_property.pdf}
        \end{aligned}
      \end{equation}
    \end{displayquote}
  \end{displayquote}

  In \fullref{def:concrete_category} we mentioned that we will call the left adjoint of a forgetful functor a free functor. Universal mapping properties allow characterizing certain \enquote{free constructions}, such as the free groups defined in \fullref{def:free_group}, without explicitly building a free functor and proving that it is left adjoint. Indeed, for every suitable object and map, we explicitly build the natural isomorphism \( \varphi \) of a hom-adjunction, and the commutative triangle \eqref{eq:rem:universal_mapping_property/c_triangle} ensures that this \( \varphi \) is a natural transformation.

  Universal mapping properties of this form are used for \hyperref[def:category_of_cones/colimit]{colimits} --- see \fullref{rem:limit_universal_mapping_property}.

  Of course, there is a \hyperref[thm:categorical_principle_of_duality]{dual} universal mapping property:
  \begin{displayquote}
    For every object \( X \) in \( \cat{D} \) there exist unique up to a unique isomorphism object \( G(X) \) in \( \cat{C} \) and canonical projection map \( \pi_X: [F \bincirc G](X) \to X \) satisfying the following property, called a \term{universal mapping property}:
    \begin{displayquote}
      For every object \( A \) in \( \cat{C} \) and every map \( g: F(A) \to X \) in \( \cat{D} \), there exists a unique map \( \widetilde{g}: A \to G(X) \) in \( \cat{C} \) such that the following diagram commutes:
      \begin{equation}\label{eq:rem:universal_mapping_property/d_triangle}
        \begin{aligned}
          \includegraphics[page=5]{output/rem__universal_mapping_property.pdf}
        \end{aligned}
      \end{equation}
    \end{displayquote}
  \end{displayquote}

  In this case, we can regard \( F \) as a forgetful functor and \( G \) as a free functor to obtain the following:
  \begin{displayquote}
    For every object \( X \) in \( \cat{D} \) there exist unique up to a unique isomorphism object \( G(X) \) in \( \cat{C} \) and canonical projection map \( \pi_X: G(X) \to X \) satisfying the following property, called a \term{universal mapping property}:
    \begin{displayquote}
      For every object \( A \) in \( \cat{C} \) and every map \( g: A \to X \) in \( \cat{D} \), there exists a unique map \( \widetilde{g}: A \to G(X) \) in \( \cat{C} \) such that the following diagram commutes:
      \begin{equation}\label{eq:rem:universal_mapping_property/d_triangle_forgetful}
        \begin{aligned}
          \includegraphics[page=6]{output/rem__universal_mapping_property.pdf}
        \end{aligned}
      \end{equation}
    \end{displayquote}
  \end{displayquote}

  Universal mapping properties of this form are used for \hyperref[def:category_of_cones/limit]{limits} --- see \fullref{rem:limit_universal_mapping_property}.
\end{remark}


\subsection{Computing inverses}
\label{ssec:computing-inverses}

In Example~\ref{exa:verifying-inverse}, we verified that a matrix $A$
had an inverse. But we did not actually compute the inverse: the
inverse $B$ was already given, and we merely checked that $AB=I$ and
$BA=I$. We now explore a method for finding the inverse when it is not
already known what it is.

\begin{example}{Finding the inverse of a matrix}{finding-inverse}
  Find the inverse of the matrix
  \begin{equation*}
    A=\begin{mymatrix}{rr}
      1 & -2 \\
      2 & -3
    \end{mymatrix}.
  \end{equation*}
\end{example}

\begin{solution}
  To find $A^{-1}$, we need to find a matrix $\begin{mymatrix}{rr}
    x & z \\
    y & w
  \end{mymatrix}$ such that
  \begin{equation*}
    \begin{mymatrix}{rr}
      1 & -2 \\
      2 & -3
    \end{mymatrix} \begin{mymatrix}{rr}
      x & z \\
      y & w
    \end{mymatrix} =\begin{mymatrix}{rr}
      1 & 0 \\
      0 & 1
    \end{mymatrix}.
  \end{equation*}
  We can multiply these two matrices, and see that in order for this
  equation to be true, we must solve the systems of equations
  \begin{equation*}
    \begin{array}{c}
      x  - 2y = 1, \\
      2x - 3y = 0,
    \end{array}
  \end{equation*}
  and
  \begin{equation*}
    \begin{array}{c}
      z  - 2w = 0, \\
      2z - 3w = 1.
    \end{array}
  \end{equation*}
  Writing the augmented matrix for these two systems gives
  \begin{equation*}
    \begin{mymatrix}{rr|r}
      1 & -2 & 1 \\
      2 & -3 & 0
    \end{mymatrix}
    % \label{inverse-1a}
  \end{equation*}
  for the first system and
  \begin{equation*}
    \begin{mymatrix}{rr|r}
      1 & -2 & 0 \\
      2 & -3 & 1
    \end{mymatrix}
  \end{equation*}
  for the second one. Note that both systems have $A$ as their coefficient
  matrix. Since both systems have the same coefficient matrix, they both
  require exactly the same row operations, and we can use the method of
  Example~\ref{exa:multiple-systems} to solve both systems at the same
  time.  To do so, we create a single augmented matrix containing both of the
  right-hand sides:
  \begin{equation*}
    \begin{mymatrix}{rr|rr}
      1 & -2 & 1 & 0 \\
      2 & -3 & 0 & 1
    \end{mymatrix}.
  \end{equation*}
  Then we perform row operations until the coefficient matrix is in
  {\rref}:
  \begin{equation}\label{eqn:finding-inverse}
    \begin{mymatrix}{rr|rr}
      1 & -2 & 1 & 0 \\
      2 & -3 & 0 & 1
    \end{mymatrix}
    \stackrel{R_2\rowop R_2-2R_1}{\roweq}
    \begin{mymatrix}{rr|rr}
      1 & -2 &  1 & 0 \\
      0 &  1 & -2 & 1
    \end{mymatrix}
    \stackrel{R_1\rowop R_1+2R_2}{\roweq}
    \begin{mymatrix}{rr|rr}
      1 & 0 & -3 & 2 \\
      0 & 1 & -2 & 1
    \end{mymatrix}.
  \end{equation}
  This corresponds to the following {\rref}s for the two original
  systems of equations:
  \begin{equation*}
    \begin{mymatrix}{rr|r}
      1 & 0 & -3 \\
      0 & 1 & -2
    \end{mymatrix}
    \quad\mbox{and}\quad
    \begin{mymatrix}{rr|rr}
      1 & 0 & 2 \\
      0 & 1 & 1
    \end{mymatrix}.
  \end{equation*}
  The solution of the first system is $x=-3$ and $y=-2$. The solution
  for the second system is $z=2$ and $w=1$. If we take the values
  found for $x$, $y$, $z$, and $w$ and put them into our inverse
  matrix, we see that the inverse is
  \begin{equation*}
    A^{-1} =
    \begin{mymatrix}{rr}
      x & z \\
      y & w
    \end{mymatrix}
    =
    \begin{mymatrix}{rr}
      -3 & 2 \\
      -2 & 1
    \end{mymatrix}.
  \end{equation*}
  Notice that this is exactly the right-hand side in the last
  augmented matrix of {\eqref{eqn:finding-inverse}}. In other words,
  all we really had to do to find the inverses were the row operations
  in {\eqref{eqn:finding-inverse}}. The inverse can be read off
  directly from the result.
\end{solution}

The example suggests a general method for finding the inverse of a
matrix, which we summarize in the following algorithm.

\begin{algorithm}{Finding the inverse of a matrix}{matrix-inversion-algorithm}
  Suppose $A$ is an $n\times n$-matrix. To find $A^{-1}$ if it exists%
  \index{matrix!finding the inverse}, form the augmented
  $n\times 2n$-matrix
  \begin{equation*}
    \mat{A\mid I}.
  \end{equation*}
  If possible, do row operations until you obtain an
  $n\times 2n$-matrix of the form
  \begin{equation*}
    \mat{I\mid B}.
  \end{equation*}
  If this can be done, then $A$ is invertible and $A^{-1}=B$. If it is
  not possible (i.e., if the {\rref} of $A$ has less than
  $n$ pivot entries), then $A$ is not invertible.
\end{algorithm}

This algorithm shows how to find the inverse if it exists. It also
tells us if $A$ does not have an inverse.

\begin{example}{Finding the inverse of a matrix}{finding-inverse2}
  Let $A=\begin{mymatrix}{rrr}
    1 & 2 & 2 \\
    1 & 0 & 2 \\
    3 & 1 & -1
  \end{mymatrix}$. Find $A^{-1}$ if it exists.
\end{example}

\begin{solution}
  We set up the augmented matrix and reduce it to {\rref}.
  \begin{eqnarray*}
    \mat{A\mid I} &=&
    \begin{mymatrix}{rrr|rrr}
      1 & 2 &  2 & 1 & 0 & 0 \\
      1 & 0 &  2 & 0 & 1 & 0 \\
      3 & 1 & -1 & 0 & 0 & 1
    \end{mymatrix}\\[1ex]
    &\stackrel{R_2\rowop R_2-R_1}{\stackrel{R_3\rowop R_3-3R_1}{\roweq}}&
    \begin{mymatrix}{rrr|rrr}
      1 &  2 &  2 &  1 & 0 & 0 \\
      0 & -2 &  0 & -1 & 1 & 0 \\
      0 & -5 & -7 & -3 & 0 & 1
    \end{mymatrix}\\[1ex]
    &\stackrel{R_1\rowop 7R_1}{\stackrel{R_3\rowop -2R_3}{\roweq}}&
    \begin{mymatrix}{rrr|rrr}
      7 & 14 & 14 &  7 & 0 &  0 \\
      0 & -2 &  0 & -1 & 1 &  0 \\
      0 & 10 & 14 &  6 & 0 & -2
    \end{mymatrix}\\[1ex]
    &\stackrel{R_1\rowop R_1+7R_2}{\stackrel{R_3\rowop R_3+5R_2}{\roweq}}&
    \begin{mymatrix}{rrr|rrr}
      7 &  0 & 14 &  0 & 7 &  0 \\
      0 & -2 &  0 & -1 & 1 &  0 \\
      0 &  0 & 14 &  1 & 5 & -2
    \end{mymatrix}\\[1ex]
    &\stackrel{R_1\rowop R_1-R_3}{\roweq}&
    \begin{mymatrix}{rrr|rrr}
      7 &  0 &  0 & -1 & 2 &  2 \\
      0 & -2 &  0 & -1 & 1 &  0 \\
      0 &  0 & 14 &  1 & 5 & -2
    \end{mymatrix}\\[-1ex]
    &\stackrel{R_1\rowop \frac{1}{7}R_1}{\stackrel{R_2\rowop -\frac{1}{2}R_2}{\stackrel{R_3\rowop \frac{1}{14}R_3}{\roweq}}}&
    \def\arraystretch{1.5}
    \begin{mymatrix}{rrr|rrr}
      1 & 0 & 0 & -\frac{1}{7} & \frac{2}{7} & \frac{2}{7} \\
      0 & 1 & 0 & \frac{1}{2} & -\frac{1}{2} & 0           \\
      0 & 0 & 1 & \frac{1}{14} & \frac{5}{14} & -\frac{1}{7}
    \end{mymatrix}.
  \end{eqnarray*}
  Notice that the last augmented matrix is of the form
  $\mat{I\mid B}$, where the left-hand side is the $3 \times 3$
  identity matrix.  Therefore, the inverse is the $3 \times 3$-matrix
  on the right-hand side, given by
  \begin{equation*}
    A^{-1} ~=~
    \def\arraystretch{1.5}
    \begin{mymatrix}{rrr}
      -\frac{1}{7} & \frac{2}{7} & \frac{2}{7} \\
      \frac{1}{2} & -\frac{1}{2} & 0 \\
      \frac{1}{14} & \frac{5}{14} & -\frac{1}{7}
    \end{mymatrix}.
  \end{equation*}
\end{solution}

When looking for the inverse of a matrix, it can happen that the
left-hand side cannot be row reduced to the identity matrix. The
following is an example of this situation.

\begin{example}{A non-invertible matrix}{matrix-no-inverse}
  Let $A=\begin{mymatrix}{rrr}
    1 & -2 & 2 \\
    1 &  0 & 2 \\
    2 & -2 & 4
  \end{mymatrix}$. Find $A^{-1}$ if it exists.%
  \index{matrix!inverse!does not exist}%
  \index{inverse!of a matrix!does not exist}
\end{example}

\begin{solution}
  We write the augmented matrix
  \begin{equation*}
    \mat{A\mid I}
    ~=~
    \begin{mymatrix}{rrr|rrr}
      1 & -2 & 2 & 1 & 0 & 0 \\
      1 &  0 & 2 & 0 & 1 & 0 \\
      2 & -2 & 4 & 0 & 0 & 1
    \end{mymatrix}
  \end{equation*}
  and proceed to do row operations attempting to obtain
  $\mat{I\mid A^{-1}}$. After a few row operations, we have
  \begin{equation*}
    \begin{mymatrix}{rrr|rrr}
      \circled{1} & -2 & 2 & 1 & 0 & 0 \\
      0 & \circled{2} & 0 & -1 & 1 & 0 \\
      0 & 0 & 0 & -1 & -1 & 1
    \end{mymatrix}.
  \end{equation*}
  At this point, we see that the coefficient matrix has rank $2$,
  i.e., there are only two pivot entries. This means there is no way
  to obtain $I$ on the left-hand side of this augmented matrix.
  Hence, there is no way to complete the algorithm, and the inverse of
  $A$ does not exist.
\end{solution}

If the algorithm provides an inverse, it is always possible to
double-check that your answer is correct.  To do so, use the method
demonstrated in Example~\ref{exa:verifying-inverse}. Check that the
products $AA^{-1}$ and $A^{-1}A$ both equal the identity
matrix. Through this method, you can always ensure that you have
calculated $A^{-1}$ properly.


\section{Solving For The Market Steady State}

\label{appx: Flux Sketch}
\subsection{Steady State Flow Equations}
\begin{itemize}
    \item Fix some strategies $s_m,s_w$ and let:

\begin{equation*}
    \rho_m(\mu,b)=\mathbb{E}_{\theta_w}\Big[s_m(\theta,\mu,b)\Big]= \iint\limits_{[0,1]^2} s_m(\theta,\mu,b)\,dG(\theta|\omega)\,dW(\omega;s),
\end{equation*}

    \item Let $R^m_b=\mathbb{P}(\mu \in(\mu',\mu''],b;s)$
    \begin{itemize}
        \item I.e. agents with pizzaz $\mu\in(\mu',\mu'']$ and budget $b$
        \item Eg. $R^m_b=M(\mu'',b;s)-M(\mu'',b-1;s)-M(\mu',b;s)+M(\mu',b-1;s)$
        \item and $R^m_1=M(\mu'',1)-M(\mu',1)$

    \end{itemize}

    \item Fix any $\mu',\mu''\in [0,1]$. For all $\mu\in(\mu',\mu'']$ the steady state male market must satisfy the following flow equations:
    \end{itemize}
    \begin{align}
        \underbrace{\frac{\lambda_m}{N_w}\Big(F_m(\mu'')-F_m(\mu')\Big)}_{\text{Enters platform}}&\;=\;\underbrace{(1-\delta)\sum^B_{b=1} R^m_b}_{\text{Exogenous death}}+\underbrace{\delta R^m_1 \int^{\mu''}_{\mu'}\rho_m(\mu,1)\,dM(\mu;s)}_{\text{Expended budget}} \label{flow1} \\[15pt]
        \underbrace{\delta R^m_{b+1} \int^{\mu''}_{\mu'}\rho_m(\mu,b+1)\,dM(\mu;s)}_{\text{Enters b}}&\;=\;\underbrace{(1-\delta) R^m_{b}+\delta R^m_{b} \int^{\mu''}_{\mu'}\rho_m(\mu,b)\,dM(\mu;s) }_{\text{Leaves b}} \label{flow2} \\[15pt]
        \underbrace{\frac{\lambda_m }{N_m}\Big(F_m(\mu'')-F_m(\mu')\Big)}_{\text{Enters platform}}&\;=\;\underbrace{(1-\delta)R^m_{B} + \delta R^m_{B} \int^{\mu''}_{\mu'}\rho_m(\mu,B)\,dM(\mu;s)}_{\text{Leaves @ B}} \label{flow3} \\[15pt]\nonumber
    \end{align}

\subsection{Solving for the Endogenous Type Distribution}
\begin{itemize}
    \item With an abuse of notation, let the probability of someone in $R^m_b$ swiping right be:
    \begin{equation*}
        \bar\rho_m(b)=\int^{\mu''}_{\mu'}\rho_m(u,b)\,dM(u;s)
    \end{equation*}
    \item Solve for $R^m_B$ from \eqref{flow3}
    \begin{equation*}
        R^m_B= \frac{\lambda_m \Big(F_m(\mu'')-F_m(\mu')\Big)}{N_m\Big((1-\delta)+\delta \bar\rho_m(B)\Big)}
    \end{equation*}
    \item Rearrange for $R^m_b$ using \eqref{flow2}
    \begin{equation*}
        R^m_b=\underbrace{\frac{\delta \bar\rho_m(b+1)}{\Big((1-\delta)+\delta \bar\rho_m(b)\Big)}}_{k_{b}}R^m_{b+1}
    \end{equation*}
    \item By the above recurrence relation:
    \begin{align*}
        R^m_{B-1}&= k_{B-1}R^m_{B}\\
        R^m_{B-2}&= k_{B-2}R^m_{B-1}\\
        &=k_{B-2}(k_{B-1}R^m_{B})\\
         &\;\vdots \\
         R^m_{b}&=R^m_{B}\prod^{B-b}_{i=1} k_{B-i}
    \end{align*}
    \item Let $\mu''=1$ and $\mu'=0$. Then $R^m_b = \mathbb{P}_m(b_m=b; s)$
    \item Given that $b$ is discrete and the above defines a PMF, we also have:
\end{itemize}

$$
\mathbb{P}_m(b_m=b;s)=R^m_{B}\prod^{B-b}_{i=1} k_{B-i}
$$

$$
\implies M_b(b;s)=R^m_{B}\sum^b_{j=1}\prod^{B-j}_{i=1} k_{B-i}
$$

- Let $\mu''=\mu$ and $\mu'=0$. Then:

$$
R^m_b=M(\theta,b;s)-M(\theta,b-1;s)=\mathbb{P}_m(\theta_m<\theta \,\cap \, b_m=b;s)
$$

- By substituting the extended form for the above two cases and rearranging:

$$
M_{\theta}(\theta|b_m=b;\mu,\omega)=\frac{\mathbb{P}_m(\theta_m<\theta \,\cap \, b_m=b;\mu,\omega)}{\mathbb{P}(b_m=b;\mu,\omega)}=F_m(\theta)
$$

- To solve for $M(\theta,b;\mu,\omega)$

$$
\begin{aligned}M(\theta,b;\mu,\omega)&=\sum^b_{j=1} M_{\theta}(\theta|b_m=j;\mu,\omega)\mathbb{P}_m(b_m=j;\mu,\omega)\\&=F_m(\theta)R^m_{B}\sum^b_{j=1}\prod^{B-j}_{i=1} k_{B-i}\\&=F_m(\theta)M_b(b;\mu,\omega)\end{aligned}
$$

- Letting $b=B$, we get the marginal distribution for $\theta_m$:

$$
M(\theta,B;\mu,\omega)=F_m(\theta)M_b(B;\mu,\omega)=F_m(\theta)=M_\theta(\theta;\mu,\omega)
$$

- Hence, we have:

$$
\begin{aligned} \mathbb{P}_m(b_m=b;\mu,\omega)&=\frac{\lambda_m  }{N_m\Big(1-\delta (1-\rho^m_B) \Big)}\prod^{B-b}_{i=1}\frac{\delta\rho^m_{B-i+1}}{\Big(1-\delta (1-\rho^m_{B-i}) \Big)}\\M_b(b;\mu,\omega)&=\sum^b_{i=1}\mathbb{P}_m(b_m=i;\mu,\omega)\\M_{\theta}(\theta;\mu,\omega)&=F_m(\theta)\\M(\theta,b;\mu,\omega)&=M_{\theta}(\theta;\mu,\omega)M_b(b;\mu,\omega)\end{aligned}
$$

 Tying up The Steady State

- Consider the above arguments for the analogous case for women
    - Since we know the marginal attractiveness distribution for women in the steady state is equal to $F_w(\theta)$ then the expected probability of a right-swipe for men $\rho^m_b$ is expressed as below, with an analogous expression for women

$$
\rho^m_b=\int_{\Theta_w} \mu(\theta',b)\,dW_\theta(\theta';\mu,\omega)=\int_{\Theta_w} \mu(\theta',b)\,dF_w(\theta')
$$

- Substitute into the first set of flow equations to solve for
- Furthermore, let:

$$
\begin{aligned} z^m_b &=\prod^{B-b}_{i=1}\frac{\delta\rho^m_{B-i+1}}{\Big(1-\delta (1-\rho^m_{B-i}) \Big)}, \quad \forall b=1,...,B_m-1\\z^w_b&=\prod^{B-b}_{i=1}\frac{\delta\rho^w_{B-i+1}}{\Big(1-\delta (1-\rho^w_{B-i}) \Big)} , \quad \forall b=1,...,B_w-1\\\\ z^m_B&=\Big(1-\delta (1-\rho^m_B) \Big) \\\\ z^w_B&=\Big(1-\delta (1-\rho^w_B) \Big) \end{aligned}
$$

- Then the steady state is given by:

$$
\begin{aligned}N_m(\mu,\omega)&=\lambda_m\left(\frac{z^m_B-\delta z^m_1\rho^m_1}{(1-\delta)z^m_B}\right)\\\\N_w(\mu,\omega)&=\lambda_w\left(\frac{z^w_B-\delta z^w_1\rho^w_1}{(1-\delta)z^w_B}\right)\\\\M(\theta,b;\mu,\omega)&=F_m(\theta) \left(\frac{(1-\delta)}{z^m_B-\delta z^m_1\rho^m_1}\right)\sum^b_{i=1} z^m_i\\\\W(\theta,b;\mu,\omega)&=F_w(\theta)\left(\frac{(1-\delta)}{z^w_B-\delta z^w_1\rho^w_1}\right)\sum^b_{i=1} z^w_i \end{aligned}
$$


%% !TeX root = main.tex

\chapter{Orthogonal Frequency-Division Multiplexing (OFDM) Project}
\glsresetall
\label{chapter:ofdm}

\section{Introduction}

In this project, you will learn the very basic idea behind an OFDM system, and implement a simple OFDM receiver in programmable logic.  The project is divided into three parts. The first provides an OFDM transmitter and receiver in Simulink. This gives you insight into the ideas behind OFDM. In the second part, you develop a basic OFDM receiver using HLS. The receiver consists of a \gls{fft} module and a QPSK symbol decoder. The final part is to integrate the receiver onto the  Zedboard using Xillybus to transmit data to the OFDM receiver, and receive the decoded data back from your hardware implementation in the programmable logic. You should use Gplot to show the transmitted and received data as you have done in previous projects.

\section{Part I: Simulink}

We provided a Simulink file with an OFDM transmitter, simulated channel, and receiver design. The goal of this part of the project is to gain an initial understanding of how a very simple OFDM system works. Furthermore, you will use the Simulink file to extract data as a testbench for Parts II and III. In this part, we walk you through a series of steps to familiarize you with Simulink and OFDM. This part is optional in the sense you do not have to turn anything. Though you will need to have at least a decent understand of the Simulink in order to complete the assignments from the next two parts of this project.

Because the HDL-compatible \gls{fft} block inherently bit-reverses, there are two different Simulink models.
\begin{itemize}
\item Version a: No bit reversal in TX, bit reversal in both HDL and behavioral/algorithmic RX, and thus would provide suitable incoming data for a non-bit-reversing Vivado \gls{fft} receiver.
\item Version b: Bit reversal in TX and in both RX  thus be used with a bit-reversing Vivado \gls{fft} receiver.
\end{itemize}

The simple OFDM transmitter encodes 2-bit data symbol (either values of 0 through 3 or random) onto a digital QPSK modulation pattern. 1024 of these symbols go through a 1024-point blockwise I\gls{fft} and are then converted to floating point and sent over a simulated AWGN channel. Two receiver architectures are provided in parallel: HDL-optimized \gls{fft} and block \gls{fft}. You can synthesize the HDL \gls{fft} into Verilog and then run that through Vivado (not HLS) to obtain FPGA resource use estimates.

\begin{figure}
\centering
\includegraphics[width=5.5in]{images/ofdm_1024a}
\caption{Simulink test bench for a simple OFDM transceiver. This is found in the Simulink file \texttt{hdlcoder\_ofdm\_fft\_eml\_1024b.slx}.}
\label{fig:ofdm_1024a}
\end{figure}

Figure \ref{fig:ofdm_1024a} shows the top level of the provided \texttt{hdlcoder\_ofdm\_fft\_eml\_1024b.slx} file. The 2-bit/symbol data source is at upper left, the transmitter (QPSK + I\gls{fft}) is top center, then the AWGN simulated channel and the OFDM A/D converter. We do everything except the channel math in fixed point, since we are trying to build real hardware. The channel, is not synthesizable into Verilog or hardware, is kept in floating point, in deference to the computational limits of Matlab, which needs to add Gaussian-distributed random numbers to what we transmit into the channel.

Run the simulation and note the resulting bit error rate and scope traces. Note that the transmitter input and the receiver output have been manually time-aligned for you. In a real system this function will be handled by the synchronization correlators (matched filters), such as those we studied in an earlier projects (e.g., Chapter \ref{chapter:phase_detector}). The z-2 block delays the \texttt{Behavioral\gls{fft}} output by two frames = 2048 sample times, to compensate for the 1589 delays through the HDL Optimized \gls{fft}, the 458 delays after it, and one delay for serializer in front of it. You can see from the scope that the two have been aligned by the external delays.

\begin{figure}
\centering
\includegraphics[width=5.5in]{images/ofdm_1024a_scope}
\caption{The first two plots shows signal outputs from two different \gls{fft} paths in \texttt{hdlcoder\_ofdm\_fft\_eml\_1024a}. The third scope plots the difference between these two outputs.}
\label{fig:ofdm_1024a_scope}
\end{figure}

The third scope channel is feed from subtractor that compares the two parallel receiver constructs (see Figure \ref{fig:ofdm_1024a_scope}). We did something like this in earlier labs, to provide convenient visual verification that two data streams matched. \textbf{Where is the 2\% error coming from?} Hint: try scoping the respective outputs of the Behavioral\gls{fft} and \gls{fft} HDL Optimized blocks -- if the \gls{fft}s match, then what is causing the disparity?

Click on \texttt{Analysis} at the top of your screen, then \texttt{Fixed Point Tool}, then make sure \texttt{hdlcoder\_ofdm\_fft\_eml\_1024a} is selected and change \texttt{Data type override:} to \texttt{[Floating Point] Double [precision]}. What happens to the bit error rate? What is likely going on here?

Important note: Since the hardware-optimized \gls{fft} generates results in bit-reversed order, we have set the block \gls{fft} to do the same. Thus, we compare the (bit-reversed) results from the two receivers, instead of comparing one receiver's output against the original data sequence that was transmitted. We need to add a bit reversal block to the design to do a proper TX-RX bit error rate comparison, but for the moment take the block \gls{fft} as your golden standard.

Now lump the \texttt{\gls{fft} HDL Optimized}, \texttt{458-clock delay}, and \texttt{OFDM Receiver Symbol Detection} blocks into a single subsystem (a series of left clicks, one per block, with Shift held down will do nicely), right click on it, and start HDL advisor.

Run the resulting Verilog code through Vivado and report projected FPGA resource usage. Do not worry yet about putting this into a Xillybus environment.

Now open \texttt{hdlcoder\_ofdm\_fft\_eml\_1024b.slx}. This is similar, except that we are now checking true symbol error rate of recovered data versus originally transmitted data. How were we able to do this, given that the two \gls{fft}s both output bit-reversed data? Also, why are the two error/difference traces on the scope so different? One runs as expected between -3 and +3, but the other has huge spikes of about 255.

Describe the two data sources, and try each one in turn by clicking on the \texttt{Manual Switch}. Feel free to invent your own data source generator and to swap it in.

Important points from this lab:

\begin{enumerate}
\item Simplified 1024-point OFDM system with data on every channel.
\item AWGN channel simulation available -- will inject Gaussian noise at a user-selected SNR.
\item Quantization -- we chose 12-bit precision for the receivers' input -- was this enough? What is our practical upper limit of bits?
\item Bit reversal -- the data emerge from the receiver in bit-reverse order, but we can compensate if we tell the transmitter its incoming data are also in bit-reverse order.
\end{enumerate}

\section{Part II: High Level Synthesis}
The major portion of the OFDM receiver is a 1024-point \gls{fft}. The \gls{fft} is a more efficient version of the Discrete Fourier Transform (DFT). The \gls{fft} utilizes symmetry in the DFT coefficients to provide a recursive implementation that reduces the runtime from O(N2) to O(N log N) where N is the number of samples in the input signal.

Your tasks for this part of the lab are:
\begin{enumerate}
\item Implement a working \gls{fft} module that passes the testbench in HLS.
\item Optimize the \gls{fft} module (create and explore multiple architectures)
\item Implement and optimize the QPSK decoder.
\item Integrate the \gls{fft} and decoder into a complete OFDM receiver.
\end{enumerate}

\subsection{Materials}

You are largely responsible for generating the testbenches for this project. This can be done by extracted data from the provided Simulink file. We do however provide you with testbenches for the \gls{fft}. This is the major part of the receiver.

You are given a zip file with three folders \texttt{0\_Initial}, \texttt{1\_Subcomponents}, and \texttt{2\_Skeleton\_Restructured}.  Folder \texttt{0\_Initial} contains the files corresponding to the ``software'' version of the \gls{fft}. Folder \texttt{2\_Skeleton\_Restructured} provides a framework for a more optimized \gls{fft} implementation. And folder \texttt{1\_Subcomponents} has a number of subfolders that allow you to create projects for individual functions that you will develop over the project. This is largely for your convenience for testing and development. All of the code developed here will eventually be placed in to \texttt{0\_Initial} and \texttt{2\_Skeleton\_Restructured}.
The structure of each of these folders is largely the same.
\begin{itemize}
\item \texttt{*.cpp}: The place where you write your synthesizable code.
\item \texttt{*.h} header file with various definitions that may be useful for developing your code.
\item \texttt{*\_test.cpp}: Testbench
\item \texttt{out.gold.dat}: ``Golden'' output. The testbench (\texttt{*\_test.cpp}) generates a sample input and calls the corresponding function in \texttt{*.cpp} with that sample input. This output of the function is compared to the expected output. This will indicate PASS or FAIL. If it fails, then the code in \texttt{*.cpp} is incorrect.
\item \texttt{script.tcl} and \texttt{directive.tcl}: These allow you to easily create a project. To do this, open the \VHLS Command Prompt tool (\texttt{Start} $\rightarrow$ \texttt{Xilinx Design Tools} $\rightarrow$ \texttt{Vivado HLS} $\rightarrow$ \texttt{Vivado HLS Command Prompt}) and go to the directory where source files and script files reside by using \texttt{cd} command. Then type \texttt{vivado\_hls script.tcl}. This will create a HLS project automatically, so you do not have to add source files, set the top function, select the target device, etc. This will create a folder called \texttt{hls} in that directory with the project. It will also synthesize the project.
\item There is a \texttt{README.txt} which contains a link to the project instructions (this file). \note{probably remove this.}
\end{itemize}

\subsection{Goals}
Part II of the project is divided into stages. The first part of the project is to perform the bit reversal of the input data. Then you optimize a ``software'' version of the code which we have given you (minus the bit reversal portion). After that, you will create a more hardware friendly \gls{fft} architecture. We have provided a testbenches for the individual functions in addition to the testbenches for the overall \gls{fft}. Finally, you must design and implement at QPSK decoder, and integrate it with the \gls{fft} to complete the receiver.

While the major goal of this project is create a functional core, you will also perform optimizations on the code. You should modify the code to create a number of different architectures that tradeoff between performance and area. You will create a report describing how you generated these different architectures (code restructuring, pragmas utilized, etc.). For each architecture you should provide its results including the resource utilization (BRAMs, DSP48, LUT, FF), and performance in terms of throughput (number of \gls{fft} operations/second), latency, clock cycles, clock frequency (which is fixed to 10 ns).

\subsection{\gls{fft} Bit Reversal}
The first step in most optimized \gls{fft} implementation is to reorder the input data by performing ``bit reversed'' swapping. This allows for in-place computation of the \gls{fft}, i.e., the resulting ``frequency domain'' data (as well as the intermediate results) can be stored into the same locations as the input ``time domain'' data. In addition, the output frequency domain data will be in the ``correct order'' at the end of the computation.

An example of the bit reversed data for an 8 point \gls{fft} is shown in Table \ref{tab:bit_reverse}.
\begin{table}[htbp]
\caption{The data for an \gls{fft} must be swapped in a ``bit reverse'' manner. The table shows the decimal value, corresponding binary value, and the reversed binary and decimal values for an 8-point \gls{fft}. }
\begin{center}
\begin{tabular}{|c|c|c|c|}
\hline
Input & Input  & Reversed  & Reversed  \\
Decimal & Binary & Binary & Decimal \\
Address & Address & Address & Address \\
\hline
0 & 000 & 000 & 0 \\
\hline
1	& 001 &	100	& 4 \\
\hline
2	& 010	& 010	& 2 \\
\hline
3	& 011	& 110	& 6 \\
\hline
4	& 100	& 001	& 1 \\
\hline
5	& 101	& 101	& 5 \\
\hline
6	& 110	& 011	& 3 \\
\hline
7	& 111	& 111	& 7 \\
\hline
\end{tabular}
\end{center}
\label{tab:bit_reverse}
\end{table}%

In other words, the input data that was initially stored in the array at location 1 is stored in location 4 after the bit reversal is completed. The input data stored in the array at location 4 will be put in array location 1. The input data stored in locations 0, 2, 5 and 7 stay in those locations. Note that this is only true for an 8 point \gls{fft}. Other sizes of \gls{fft} will have different reordering of the data though it is still based on the bit reversed pattern. For example, in a 16 point \gls{fft}, the input data stored in location 1 (binary 0001) will be relocated into location 8 (binary 1000).

You should create an architecture that, efficiently as possible, transforms the input data into a bit reversed order. Note that there are many ``software'' implementations of this that will not effectively map to ``hardware''. While the first goal is to get a working function, you should also consider the performance of the architecture.

We have given you a set of files that allows you to develop and test this bit reversal code in isolation. This includes a simple testbench that exercises this function directly. You should develop and optimized your bit reversed code here. You will later copy this code into the \gls{fft} code.

This code is in subfolder \texttt{1\_bit\_reverse} in the folder \texttt{1\_Subcomponents}. You should develop your code here to insure that it matches the expected result. Note that this testbench is exercising only one input/output result. In other words, even if it passes this, it may not pass all results. Feel free to add additional testbenches to insure your code is correct.

The bit reverse function has the following prototype: \texttt{void bit\_reverse(DTYPE X\_R[SIZE], DTYPE X\_I[SIZE])}

You should perform the swapping ``in place'' on the data in both of the real and imaginary portions of the data. That is the input data in both \texttt{X\_R} and \texttt{X\_I} will be reordered when the function completes.

Your report should describe your code and its performance and area results. Focus on how you modified your code in order to make it more ``hardware friendly''.

Hint: Logical operations map well to hardware. Calculating the indices of the arrays that should be swapped can be done with logical operations.

\subsection{Optimizing the ``Software'' Version of the \gls{fft}}
The next portion of this lab performs optimization on a typical software implementation of the \gls{fft}. You are given typical three nested loop implementation of the \gls{fft} in the folder \texttt{0\_Initial}. First, you should understand in detail what this code is doing. It is worth spending time on this now as you will have to rewrite the \gls{fft} in a more hardware friendly manner in the next steps. You can reuse some of this code in those steps.

You should optimize this code as much as possible and detail these optimizations and their performance area results in your report. The results of the code will be poor; it will likely have greater than 250 million cycles. The throughput here is likely much worse than running this in software on a microprocessor. This often happens when we put the initial software versions of an application into a high level synthesis tool. And it should not be all that surprising. The code is optimized to run quickly in software, which runs largely in a sequential model of computation. The code must typically be carefully optimized with the final hardware architecture in mind to get good results. This involves exploiting parallelism and pipelining.

You will also notice that the first loop has function calls to sine and cosine. This code will synthesize quickly with these function calls. However, you may wish to replace these function calls (which will synthesize into CORDIC cores), into table lookups. We have provided two tables in the \texttt{.h} file, \texttt{W\_real} and \texttt{W\_imag} which contain the precomputed twiddle factors for our 1024 \gls{fft}, i.e., \texttt{W\_real[i] = cos(2.0*pi*i/SIZE)} and \texttt{W\_imag[i] = sin(2.0*pi*i/SIZE)} where $i = [0,512)$.

Some potential optimizations include:
\begin{itemize}
\item Using the \texttt{W\_real} and \texttt{W\_imag} tables.
\item Pipelining
\item Loop unrolling
\item Memory partitioning
\end{itemize}

In the report, you should discuss the performance and area numbers of the various optimizations that you apply. This must describe the effect of these optimizations on the architecture, and not just state the optimization that you used.

\subsection{Hardware Friendly \gls{fft} Implementation}

A good architecture will selectively expose and take advantage of parallelism, and allow for pipelining. Your final \gls{fft} architecture will restructure the code such that each stage is computed in a separate function or module. There will be one module for bit reversal that you have already developed, and then $\log N$ stages (10 in our case) for the butterfly computations corresponding to the 2-point, 4-point, 8-point, 16-point, \dots \gls{fft} stages.

The skeleton code for this final \gls{fft} implementation can be found in the \texttt{2\_Skeleton\_Restructured} folder. This creates code connects a number of functions in a staged fashion with arrays acting as buffers between the stages. Figure \ref{fig:staged_fft} provides a graphical depiction of this process.

\begin{figure}
\centering
\includegraphics[width=5.5in]{images/staged_fft}
\caption{A staged implementation of a 1024 \gls{fft}. Bit reversal is followed by 10 stages of butterfly computations. This architecture is capable of pipeline both within the stages and across the stages.}
\label{fig:staged_fft}
\end{figure}

The first step in this process is to create code that computes the first and last stages of the \gls{fft}. The hope is that this will allow you to get a better understanding of exactly how memory accesses and the butterfly computations are performed in a general case. You can develop these two functions \texttt{fft\_stage\_first} and \texttt{fft\_stage\_last} in isolation. They both have subfolders in the \texttt{1\_Subcomponents} folder. Once these are working correctly, you can copy and paste the code directly in the same functions in the \texttt{2\_Skeleton\_Restructured} project.

The next task is to create code that can implement ``generic'' function, i.e., one that can compute any stage of the \gls{fft}. This is the function \texttt{fft\_stages} which also has its own project in the \texttt{1\_Subcomponents} folder. Note that this function prototype is similar to \texttt{fft\_stage\_first} and \texttt{fft\_stage\_last} with one major difference: it has a stage argument. This code will used to implement stages 2 through 9 in the \texttt{2\_Skeleton\_Restructured} project.

Hints:
\begin{enumerate}
\item These stages are performing the same calculation as one iteration of the outer for loop in the \texttt{0\_Initial} project.
\item The major difference between the stages is what data elements you are performing the butterfly functions on, i.e., in what order do you pull data from \texttt{X\_R} and \texttt{X\_I}.
\item Test each of the functions in isolation with the provided projects. Make sure that the code compiles and passes the testbench before attempting any optimizations.
\end{enumerate}

Once you have a correctly functioning set of functions, you should copy and paste them in the \texttt{2\_Skeleton\_Restructured} project and make sure that it passes the testbench. Since our testbenches perform one check, which is far from comprehensive, it is possible, though hopefully unlikely, that you have some error that the \texttt{2\_Skeleton\_Restructured} testbench exposes and was not exercised in the individual testbench. If your code passes the \texttt{2\_Skeleton\_Restructured} project you can assume it is correct (though again since it is only one test, it may be wrong; you should perform significantly more testing if you want this to be anywhere close to production quality).

Now on to the final part of the project, optimizing of this restructured code. You should perform the typical tricks here: pipelining, memory partitioning, unrolling, etc. Some of these may not make sense depending on how you wrote your code. This final architecture should be orders of magnitude better than the \texttt{0\_Initial} project. Highly optimized \gls{fft} architectures can easily have less than 10000 cycles.

You should describe in your report the baseline results and the effects of any optimizations that you performed. By this point, you should be starting to understand what optimizations will work and which will not work, and most importantly why. Describe these insights in your report.

\subsection{QPSK Decoder}
The decoder takes the 1024 I/Q outputs from the \gls{fft} and decodes them into the corresponding binary data. Essentially you have to reverse the encoding that was done in the transmitter. The encoder went from 0 and 1 to -1 and 1. Because you have a perfect channel, the output of your \gls{fft} will be -1 and 1. You must make those into 0 and 1. You can look at the Simulink file to determine the exact encoding. It used a Gray code, and the constellation taken directly from the Simulink file is shown below.

\begin{figure}
\centering
\includegraphics[width=5.5in]{images/qpsk_fft}
\caption{A QPSK constellation using a Gray mapping for translating into the I and Q values.}
\label{fig:qpsk_fft}
\end{figure}

The output of your encoder should be the exact data that was given to the OFDM receiver in the Simulink file. You can create your testbench to reflect this.

\subsection{Receiver Integration}
You should connect the \gls{fft} and the QPSK decoder together to form the complete OFDM receiver. The input to the receiver is the data from the channel. The output of the receiver should match the transmitted data.

\subsection{Optimization Hints and Report Guidelines}

\begin{itemize}
\item You should use a clock period of 10 ns. While varying the clock period can drastically change the results, this is not a focus of this project. Though feel free to modify this and observe the changes.
\item The output of the various architectures that you generate must match the golden output. We have broken down the project into subcomponents to allow you to develop and test them individually. You would be wise to do it in such a manner.
\item You should not change the data types as given to you. You do not need to perform bitwidth optimization of this project.
\item There are some variable defined in the \texttt{.h} files for you convenience. These include \texttt{SIZE = 1024}, \texttt{SIZE2 = 512}, and \texttt{M = 10} (i.e., $\log$ SIZE). Feel free to use these in your code. They are defined in every \texttt{.h} file across all of the different folders.
\item The major goal of this project is to get fully functional versions of all the code. You should focus more of your time on getting everything to work rather than getting some but not all of the components to work and optimizing them.
\item Your report should describe your code at a high level. Since each of you will likely write different code anyone that reads your report should be able to fully understand what each line of your code does. However, this does not mean that you need to explain each line of code in excruciating detail. It is possible to be succinct and thorough at the same time.
\item The software version has a nested for loop structure that does not allow Vivado HLS to provide an exact number of cycles. The \texttt{tripcount} directive can help with this. You should be able to understand the reported results. For example, while Vivado may give you a best, worst and average case numbers, your algorithm for a fixed size \gls{fft} should be a fixed number of cycles. You should report the exact number of cycles for your throughput numbers. You must describe in your report exactly how you derived your throughput results.
\item You must provide a comparison between the best architecture that you derived using the ``software'' version and the best one using the ``hardware friendly'' framework.
\item It is ok to rewrite the code if it helps you with optimizations. For example, you can change the function interfaces.
\item Your code should be written such that the hardware implementation is optimal. For example, there are many ways to do a bit reversal that are efficient in software but not necessarily efficient in hardware.
\item Comment your code.
\end{itemize}

\section{Part III: Zedboard Demo}
You must implement the entire OFDM receiver on the Zedboard in the programmable logic. You should use Xillybus to transmit data to the receiver, the receiver operates on the data, and you will use Xillybus to get the data off of the programmable logic and back onto the ARM core. You must use Gplot to show that transmitted and the received data.

You are responsible for extracting the transmitted data from the Simulink testbench. You can use ``To Workspace'' data from any signal in the Simulink file. This will then appear as a variable in the Matlab workspace. There are already several ``To Workspace'' blocks in your Simulink file that you can either use directly or modify to extract the necessary data. You only need to show one ``frame'', i.e., the data from the output of one 1024 \gls{fft}.

We provided the general framework for Gplot, Xillybus, etc. in previous labs. You should use that to create this demo. We will not be providing you with anything more than what was given in previous labs. You should provide a plot similar to Figure \ref{fig:ofdm_zedboard} in your report to prove your design is working.  Please plot the entire 1024-point output. Please also plot a zoomed-in version of the output. We would like to see the ``0 1 2 3 0 1 2 3 0 1 2 3 \dots'' sequence clearly.

\begin{figure}
\centering
\includegraphics[width=6in]{images/ofdm_zedboard}
\caption{An example plot showing the input and output values to the simple OFDM receiver.}
\label{fig:ofdm_zedboard}
\end{figure}


%%%% Revised contents of Manual/Tutorial/binomial.tex %%%%
\chapter{Example: the Binomial Theorem}\label{binomial}

The Binomial Theorem in \HOL{} is a medium sized worked example whose subject
matter is more widely known than any specific piece of hardware or software.
This chapter introduces the small amount of algebra and mathematical notation
needed to state and prove the Binomial Theorem, shows how this is rendered
in \HOL{}, and outlines the structure of the proof.

This chapter is also available as the self-contained case study \ml{binomial}
in the directory {\small\verb%Training/studies%}.

\def\self{chapter}
\def\path{{\tt Training/studies/binomial}}
\input{binomial/binomial}
\input{binomial/appendix}


\section{Fuzzy Prolog}

Prolog is based on First Order Logic, where the truth values are only
{\em true} and {\em false}. In Fuzzy Logic, there is a whole range of
truth values: any real from 0 (absolute falsity) to 1 (absolute
truth). Fuzzy Prolog is a logic programming language based on
this logic.

A (logic) concept can be seen as a set which includes the elements of
``universe'' to which the concept is applicable. A predicate then can
be associates with a {\em characteristic function} which determines if
the arguments given to the predicates are in the set defining the
predicate (satisfy the relation represented by the predicate) or not.
%
Given a relevant universal set $U$, a (classic) set $A$, associated to
a predicate, can be defined by a characteristic function
$A : U\rightarrow \{0,1\}$. If an element $x$ in $U$ belongs to $A$
then $A(x) = 1$, otherwise $A(x) = 0$.

Fuzzy sets, on the other hand, try to model imprecise concepts. An
element in the universal set belongs to a fuzzy sets in a certain
grade. For example, the youth of a person given his age. A person
which is 25 years old is certainly young, and if he is 50 then he is
not young, but if he is 36 years old he is young in some
grade. Therefore, a fuzzy set $A$ is defined by a characteristic
function $A : X \rightarrow [0,1]$. Figure \ref{fig:fuzzysetyoung}
shows the characteristic function for the fuzzy set for \texttt{young}.
The value $A(x)$ is the membership value of $x$ in the fuzzy set $A$,
if we consider $A$ as a predicate, this value is called the truth value.

\begin{figure}[htbp]
  \begin{center}
\setlength{\unitlength}{2547sp}%
%
\begingroup\makeatletter\ifx\SetFigFont\undefined%
\gdef\SetFigFont#1#2#3#4#5{%
  \reset@font\fontsize{#1}{#2pt}%
  \fontfamily{#3}\fontseries{#4}\fontshape{#5}%
  \selectfont}%
\fi\endgroup%
\begin{picture}(5175,2685)(1051,-3136)
\thinlines
{\color[rgb]{0,0,0}\put(1801,-2761){\vector( 0, 1){2250}}
\put(1801,-2761){\vector( 1, 0){4125}}
}%
{\color[rgb]{0,0,0}\put(2401,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(3601,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(3001,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(4801,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(5401,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(1801,-961){\line(-1, 0){150}}
}%
\thicklines
{\color[rgb]{0,0,0}\put(1801,-2761){\line( 1, 0){600}}
\put(2401,-2761){\line( 1, 2){900}}
\put(3301,-961){\line( 1, 0){600}}
\put(3901,-961){\line( 1,-2){900}}
\put(4801,-2761){\line( 1, 0){675}}
}%
\thinlines
{\color[rgb]{0,0,0}\put(4201,-2761){\line( 0,-1){150}}
}%
{\color[rgb]{0,0,0}\put(1801,-1861){\line(-1, 0){150}}
}%
\put(2326,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}10}%
}}}
\put(2926,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}20}%
}}}
\put(4726,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}50}%
}}}
\put(5326,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}60}%
}}}
\put(3526,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}30}%
}}}
\put(4126,-3136){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}40}%
}}}
\put(1501,-2836){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{16.8}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}0}%
}}}
\put(1501,-1036){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{16.8}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}1}%
}}}
\put(1276,-1936){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{16.8}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}0.5}%
}}}
\put(6226,-2986){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}Age}%
}}}
\put(1051,-586){\makebox(0,0)[lb]{\smash{\SetFigFont{8}{14.4}{\rmdefault}{\mddefault}{\updefault}{\color[rgb]{0,0,0}Youth}%
}}}
\end{picture}
    \caption{The fuzzy set \texttt{young}}
    \label{fig:fuzzysetyoung}
  \end{center}
\end{figure}

The package \texttt{fuzzy} allows Ciao to interpret fuzzy
predicates. Fuzzy predicates which correspond to fuzzy sets on a
universal set of numbers and with characteristic functions which are
polygonal can be defined by the operator
\texttt{:\# fuzzy\_predicate}. For example, the above fuzzy set
\texttt{young} is defined as:
\begin{quote}
\begin{verbatim}
:- use_package([...,fuzzy,...]).

young :# fuzzy_predicate [(0,0),(10,0),(25,1),(35,1),(50,0),(60,0)].
\end{verbatim}
\end{quote}
%
where each element in the list is a vertex in the polygonal function.
This sentence defines a fuzzy predicate \texttt{young/2}, where the
first argument is the age and the second argument represents the truth
value. Truth values are assigned to the variable in the last argument
as constraints (Section~\ref{sec:constr-logic-progr}) over real
numbers. For example,

\begin{verbatim}
?- young(30,M).

M = 1 ?

yes
?- young(38,M).

(M.=.0.8 ?

yes
?- young(45,M).

M.=.0.333333333333333313 ?

yes
?- young(50,M).

M = 0 ?
\end{verbatim}

More complex fuzzy predicates can be defined by fuzzy clauses. We use
\texttt{:{\tiny$^\sim$}} instead of \texttt{:-} as the neck of
fuzzy clauses to distinguish them from Prolog clauses. For example,
\begin{quote}
{\tt
\begin{tabbing}
young\_co\=uple(X,Y,Mu) :{\tiny$^\sim$} \\
\>        age(X,X1), \\
\>        age(Y,Y1),  \\
\>        young(X1,MuX), \\
\>        young(Y1,MuY). \\
\\
age(john,46). \\
age(rose,36).
\end{tabbing}
}
\end{quote}
%
defines a fuzzy predicate \texttt{young\_couple/3} that uses in its
definition a fuzzy predicate \texttt{young/2} and a Prolog predicate
\texttt{age/2}. The truth value of Prolog calls in the body of the
fuzzy clause is 1 is it succeeds and 0 otherwise. The truth value of
\texttt{young\_couple} is obtained by aggregating the truth values of
the calls in the body. By default the aggregation function is
\texttt{min}, i.e., the minimum from all body goals. In this example,

\begin{verbatim}
?- young_couple(john,rose,M).

M.=.0.26 ?
\end{verbatim}
%
because $0.26$ is the minimum of $\{1,1,0.93,0.26\}$ which are the
truth values of the calls \texttt{age(john,X1)},
\texttt{age(rose,Y1)}, \texttt{young(46,MuX)} and
\texttt{young(36,MuY)} respectively.

Aggregation functions are indicated after the operator
\texttt{:{\tiny$^\sim$}}. For example, if we want the truth value of
\texttt{young\_couple/3} to be the product of the truth values in its
definition then we write:
\begin{quote}
{\tt
\begin{tabbing}
young\_co\=uple(X,Y,Mu) :{\tiny$^\sim$} prod \\
\>        age(X,X1), \\
\>        age(Y,Y1),  \\
\>        young(X1,MuX), \\
\>        young(Y1,MuY).
\end{tabbing}
}
\end{quote}
%
so that now:

\begin{verbatim}
?- young_couple(john,rose,M).

M.=.0.23 ?
\end{verbatim}
%
since $0.23$ is the product of $\{1,1,0.93,0.26\}$.

Other {\em aggregations functions} are:
\begin{itemize}
\item \texttt{max}: the maximum truth value in the body of the
  clause. It is a ``disjunctive'' aggregation operation.
\item \texttt{luka}: the Lukasiewicz T-norm. It is a ``conjunctive''
  operator like \texttt{min} and \texttt{prod}. The Lukasiewicz T-norm
  of two values $x$ and $y$ is defined as $\max(0,x + y -1)$.
\item \texttt{dluka}: the Lukasiewicz T-conorm. It is defined as
  $\min(1,x + y)$.
\item \texttt{dprod} the product T-conorm. It is defined as $x + y -
  (x * y)$.
\end{itemize}
%
(T-conorms are disjunctive operators dual to the conjunctive operator
of the corresponding T-norm.)

The min-max fuzzy logic can be modeled using the operators \texttt{max} and
\texttt{min}. In the same way, using the operators \texttt{luka} and
\texttt{dluka} the lukasiewicz fuzzy logic can be modeled. Let us see
an example.

Suppose we want to measure which is the possibility that a couple
of values, obtained throwing two loaded dice, sum 5. Let us suppose we
only know that one die is loaded to obtain a small value and the other
is loaded to obtain a large value. The program to declare this is the
following:
\begin{quote}
{\tt
\begin{tabbing}
small :\# fuzzy\_predicate([(1,1),(2,1),(3,0.7),(4,0.3),(5,0),(6,0)]). \\
large :\# fuzzy\_predicate([(1,0),(2,0),(3,0.3),(4,0.7),(5,1),(6,1)]). \\
\ \\
die1(X,M)\= 123456789012345678901234567890\= two\_dice\=\kill
die1(X,M)\> :{\tiny$^\sim$}       \> two\_dice\=(X,Y,M) :{\tiny$^\sim$} min \\
\>       small(X,M).            \> \> die1(X,M1), \\
\>                              \> \> die2(Y,M2). \\
die2(X,M) :{\tiny$^\sim$} \\
\>        large(X,M).
\end{tabbing}
}
\end{quote}
%
where \texttt{two\_dice(X,Y,M)} gives the possibility that the first die
obtains the value \texttt{X} and the second the value \texttt{Y}.
Therefore in this clause we need a conjunctive operator as
\texttt{min}. Now we can define:
\begin{quote}
{\tt
\begin{tabbing}
sum(5,M)\= :{\tiny$^\sim$} max \\
\>        two\_dice(4,1,M1), \\
\>        two\_dice(1,4,M2), \\
\>        two\_dice(3,2,M3), \\
\>        two\_dice(2,3,M4).
\end{tabbing}
}
\end{quote}
%
for which we need a disjunctive operator as \texttt{max} which
aggregates the different ways of obtaining 5 for the sum. We will
get for example:

\begin{verbatim}
?- sum(5,M).

M.=.0.7 ?
\end{verbatim}

The package also gives the possibility of defining fuzzy predicates
which are the fuzzy negation of other fuzzy predicates. For example,
the fuzzy predicate \texttt{small} could be defined as:
\begin{quote}
\begin{verbatim}
small :# fnot large/2
\end{verbatim}
\end{quote}
%
so that the truth value \verb+M+ of \verb+small(X,M)+ is defined as
\verb+1-N+ where \verb+N+ is the truth value of \verb+large(X,N)+.

It is possible to ``fuzzify'' Prolog predicates. For
example to fuzzify \verb+age/2+ it is only necessary to write:
\begin{quote}
\begin{verbatim}
age_f :# fuzzy age/2
\end{verbatim}
\end{quote}
%
and the program is expanded with a new fuzzy predicate
\texttt{age\_f/3} (the last argument is the truth value) with truth
value equal to 0 if \texttt{age/2} fails and 1 otherwise.

Prolog calls
in bodies of fuzzy clauses are automatically fuzzified, except those
that are enclosed in \verb+{}+ brackets. This is useful if we want
truly prolog calls to define a fuzzy predicate, for example to set a
threshold for a fuzzy clause like in the following program:
\begin{quote}
{\tt
\begin{tabbing}
very\_goo\=d\_credit\_customer(X,Mu):{\tiny$^\sim$} min \\
\>        good\_credit\_customer(X,M), \\
\>        \{Mu .>=. 0.8\}.  \\
very\_good\_credit\_customer(X,Mu):{\tiny$^\sim$} min \\
\>        good\_credit\_customer(X,M), \\
\>        fail, \\
\>        \{Mu .<. 0.8\}.
\end{tabbing}
}
\end{quote}
%
which defines a very good credit customer as a good credit customer
with truth value greater than $0.8$. A  good credit customer is
defined, for example, as follows:
\begin{quote}
{\tt
\begin{tabbing}
good\_credit\_customer(john,0.8):{\tiny$^\sim$} . \\
good\_credit\_customer(mary,0.5):{\tiny$^\sim$} . \\
good\_credit\_customer(alan,0.9):{\tiny$^\sim$} .
\end{tabbing}
}
\end{quote}

Note how fuzzy facts do require the operator \texttt{:{\tiny$^\sim$}}
(with a space separating it from the final dot). Otherwise, they will
be deemed as normal Prolog clauses. Mixing fuzzy clauses and Prolog
clauses may cause unexpected behaviours. The compiler will signal
the problem with a warning message indicating discontiguous clauses for
the predicate.

In this case we obtain the following answers:

\begin{verbatim}
?- very_good_credit_customer(X,Mu).

X = john,
Mu.=.0.8 ? ;

X = alan,
Mu.=.0.9 ? ;

Mu = 0,
X = mary ? ;

no
?-
\end{verbatim}


\section{Scanning with Regular Languages \& Parsers with CFG}
\subsection*{Scanner}
Splits input in sub-strings and groups in lexical units. Feeds tokenized version of input to parser. \textbf{hand-built scanners:} Beyond regular languages; Easier to debug; More efficient.
\subsection*{Automata}
\textbf{NFA} ($Q,\Sigma,\delta,q_0,F$) $Q \times (\Sigma \cup \{\epsilon \}) \rightarrow 2^Q$ transition func. \textbf{DFA} NFA deterministic if $\delta (q,\epsilon )\ =\ \phi\ \forall\ q\ \in\ Q \wedge\ |\delta(q,a)|\ =\ 1\ \forall\ (q,a)\ \in\ Q\ \times\ \Sigma$. For DFAs, $\delta$ form $Q \times\ \Sigma\ \rightarrow\ Q$. Can detect word w, in $\mathcal{O}(|w|)$ from regex constructed in P-time.
\subsection*{Myhill-Nerode theorem}
\textbf{Equivalence classes:}We say x, y are equivalent with respect to L, written x \textasciitilde$_L$ y if xz $\in$ L $\iff$ yz $\forall\ z \in \Sigma^*$
p> \textbf{theorem:} Language L is regular iff $~_L$ has finite number of equivalence classes. Number of equivalence classes of $~_L$ is number of states of smallest DFA.
\subsection*{recognizing v scanning}
\textbf{Recognizing:} Given string, simulate DFA and get boolean answer: (not) lexeme recognized. \textbf{Scanning:} Given string, scanner returns sequence tokens. Token is longest match (maximal much).
\subsection*{Longest matches}
Find longest prefix of remaining string which is lexical unit. \textbf{2 or more matches:} 1. First will be chosen; 2. Disallow, DFAs cant accept same input. Doing: 1. DFAs ordered; 2. Language checking when generating scanner. For all pairs of EREs with $L_1,L_2$, we should check: $L_1 \cap L_2 = \phi$.
\subsection*{Grammar}
G = (V, T, P, S) P: $\alpha\rightarrow\beta$ with $\alpha \in (V \cup T)^*V(V\cup T)^*$ and $\beta \in (V \cup T)^*$. \textbf{Derivation} Let $\gamma \in (V \cup T)^*V(V \cup T)^*$ and $\delta \in (V \cup T)^*$. We say $\delta$ can be derived from $\gamma$ iff there are $\gamma_1,\gamma_2 \in (V \cup T)*$ and a rule $\alpha \rightarrow \beta \in P$ st $\gamma = \gamma_1 \cdot \alpha \cdot \gamma_2$ and $\delta = \gamma_1 \cdot \beta \cdot \gamma_2$.
\subsection*{Grammar classes}
For all rules $\alpha \rightarrow \beta$: \textit{class 0}: All grammars no restriction; \textit{class 1}: Context-sensitive grammars: either $\alpha = S$ and $\beta = \epsilon$ or $|\alpha| \leqslant |\beta|$ and S does not appear in $\beta$; \textit{class 2}: Context-free grammars: $\alpha \in V$; \textit{class 3}: $\alpha \in V$ and left-regular = $\beta \in T^* \cup (V \cdot T^*)$. right-regular = $\beta \in T^* \cup (T^* \cdot V)$. \textbf{Chomsky’s hierarchy:} Languages: $Reg \subset CFL \subset CSL \subset RE$.
\subsection*{Universality of CNF}
\textbf{CFG to CNF:} Eliminate: 1. Start symbol from RHS; 2. Rules with non-solitary terminals. 3. RHS with more than 2 nonterminals. 4. $\epsilon$ productions; 5. Unit rules. \textbf{splits:} For grammars in CNF, A can generate w if we can find a rule A -> BC and we can split w in two non-empty words w = u $\cdot$ v st: B -> u and C -> v. It does detect w in polynomial time $\mathcal{O}(|w|^3)$
\subsection*{Attributes (semantics)}
We associate to every nonterminal variable V of the grammar a finite set A(V) of attributes partitioned into synthesized attributes $A_s(V)$ and inherited attributes $A_i(V)$. I Each attribute $\alpha \in A(V)$ has a (potentially infinite) set of possible values. The actual value will be selected based on the appearance of V in the derivation tree. \textbf{Attribute mapping functions:} For each rule $\alpha \rightarrow \beta_1 ... \beta_k$ we have a semantic rule functions $f_{\alpha,j}$ mapping values of certain attributes of $\beta_1 ... \beta_k$ to values of $\alpha \in A(\beta_j)$. \textbf{welldefinedness:} Semantic rule should not be recursive. They are formulated in a way st all attributes are always defined at all nodes in all possible derivation trees. \textbf{synthesized/inherited:} synthesized if its value depends on the vaules of its children in some derivation tree, if not the inherited.
\subsection*{(Non)deterministic pushdown automata}
A is a tuple $(Q, \Sigma, \Gamma, \delta, q_0, Z_0, F)$ $\delta : Q \times (\Sigma \cup \{\epsilon\}) \times \Gamma \rightarrow 2^{Q\times\Gamma^*}$ transition func. \textbf{Deterministic:} 1. $\forall q \in Q$, all $a \in \Sigma \cup {\epsilon}$, and all $\gamma \in \Gamma$: $\delta(q,a,\gamma)$ has at most 1 element. 2. $\forall q \in Q$, and all $\gamma \in \Gamma$: if $\delta(q,\epsilon,\gamma) \neq \phi$ then $\delta(q,a,\gamma) = \phi$ for all $a \in \Sigma$, but does not accept CFL $L_{pal}$
\subsection*{Simplifying grammar}
\textbf{Factoring:} $A \rightarrow wB$ and $A \rightarrow wC$, split A into $A_1 \rightarrow wA_2$ and $A_2 \rightarrow B$, $A_2 \rightarrow C$. \textbf{Indirect left recursion:} $\forall$ pairs of rules $A \rightarrow Bw$ and $B \rightarrow \beta_1$ we replace the first rule by $A \rightarrow \beta_1 w$. Repeated. \textbf{Direct left recursion:} If we have rules $(V \rightarrow V \alpha_i)_{i\in I}$ and $(V \rightarrow \beta_j)_{j\in J}$, we can replace them by $(V' \rightarrow \alpha_i )_{i\in I}$, $(V \rightarrow \beta_j V')_{j\in J}$, and $V' \rightarrow \epsilon$. \textbf{unproductive:} A unproductive if there is no word w that can be derived from A. \textbf{unreachable:} $X \in T \cup V$ is unreachable if no sentential form contains X.