%% memorygraphs.tex
%% Copyright 2018-2019 C. Staps
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%
http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status “maintained”.
%
% The Current Maintainer of this work is C. Staps.
%
% This work consists of the files memorygraphs.sty and the documentation in
% memorygraphs.tex and example-fibonacci.tex.
\documentclass[a4paper]{article}
\usepackage{geometry}
\usepackage[hidelinks]{hyperref}
\usepackage{csquotes}
\usepackage{cleveref}
\usepackage[nonewpage]{imakeidx}
\makeindex[intoc]
\usepackage{latexgit}
\usepackage{fancyvrb}
\usepackage{listings}
\usepackage{color}
\definecolor{codebg}{rgb}{0.8,0.8,1}
\lstset{backgroundcolor=\color{codebg},
frame=single,
framerule=0pt,
basicstyle=\ttfamily\footnotesize,
columns=fullflexible}
\usepackage{memorygraphs}
\newcommand{\memorygraphs}{\textsf{memorygraphs}}
\newcommand{\TikZ}{Ti\textit{k}Z}
\title{The \memorygraphs{} package}
\author{Camil Staps\thanks{
[email protected]}}
\date{\gitcommitdate[formatDate]}
\newif\ifexamplehorizontal
\newenvironment{example}{%
\medskip%
\VerbatimOut{\jobname.tmp}}
{\endVerbatimOut%
\ifexamplehorizontal%
\noindent\begin{minipage}{\linewidth}
\centering
\input{\jobname.tmp}
\end{minipage}
\par\bigskip
\noindent\begin{minipage}{\linewidth}
\lstinputlisting{\jobname.tmp}
\end{minipage}
\else%
\hfill%
\noindent\begin{minipage}{.4\linewidth}
\centering
\input{\jobname.tmp}
\end{minipage}%
\noindent\begin{minipage}{.6\linewidth}
\lstinputlisting{\jobname.tmp}
\end{minipage}
\fi%
}
\makeatletter
\definecolor{keyheading}{rgb}{0.75,0,0}
\newcommand{\keyheading}[2][\pgfutil@empty]{%
\index{#2@\texttt{#2} key}%
\edef\pgf@test{#1}%
\item\texttt{{\color{keyheading}{/tikz/#2}}\ifx\pgf@test\pgfutil@empty\else\,=\,#1\fi}\par}
\newenvironment{keydescription}[2][\pgfutil@empty]{%
\list{}{\leftmargin=2em\itemindent-\leftmargin}
\itemsep=0pt
\parskip=0pt
\topsep=0pt
\keyheading[#1]{#2}
}{\endlist}
\newenvironment{macrodescription}[2][\pgfutil@empty]{%
\index{#2@\texttt{\textbackslash{}#2}}%
\list{}{\leftmargin=2em\itemindent-\leftmargin}
\itemsep=0pt
\parskip=0pt
\topsep=0pt
\item\texttt{{\color{keyheading}{\textbackslash#2}}\,#1}
\par\parskip3pt
}{\endlist}
\newcommand{\marg}[1]{\texttt{\textbraceleft}$#1$\texttt{\textbraceright}}
\makeatother
\newcommand{\opt}[1]{$\langle#1\rangle$}
\begin{document}
\maketitle
\begin{center}
\input{example-fibonacci}
\end{center}
\tableofcontents
\section{Introduction}
This is the documentation of the \LaTeX{} package \memorygraphs{}.
It defines some \TikZ{} styles and adds anchors to existing styles that ease the declaration of \enquote{memory graphs}.
It is intended for graphs that represent the memory of a computer program during its execution.
\section{Functionality}
\begin{keydescription}{memory graph}
The \verb$memory graph$ style is to be used on \verb$tikzpicture$.
It sets a different node distance that the author finds suitable for this kind of graphs.
\begin{example}
\begin{tikzpicture}[memory graph]
\node[draw] (x) {37};
\node[draw,right=of x] {42};
\end{tikzpicture}
\end{example}
\end{keydescription}
\subsection{Nodes}
The following styles can be used to typeset memory blocks:
\begin{keydescription}{block}
This is the most basic style to define a memory block.
By default, this shape is a rectangle with borders:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[block] {37};
\end{tikzpicture}
\end{example}
\end{keydescription}
\begin{keydescription}[\opt{n}]{arity}
The \verb$arity$ style can be used to create a node with arguments.
This implies \verb$block$:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[arity=2] {Cons};
\end{tikzpicture}
\end{example}
\end{keydescription}
\begin{macrodescription}[\marg{i}]{arg}
Because blocks with \verb$arity$ are multipart rectangles,
one can use \TikZ{}'s \verb$\nodepart$ to put contents in the arguments.
However, it can be confusing that \verb$\nodepart{two}$ refers to the \emph{first} argument,
so we redefine \verb$\arg$ in \verb$block$s to identify arguments of the memory block:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[arity=2] {Cons \arg{1} 37 \arg{2} \dots};
\end{tikzpicture}
\end{example}
Should one want to use math mode's \verb$\arg$ in a memory block, they can first rename it:
\begin{example}
\let\matharg\arg
\begin{tikzpicture}[memory graph]
\node[block] {$\matharg(1)$};
\end{tikzpicture}
\end{example}
\end{macrodescription}
\subsection{Markings}
It is possible to mark the head of memory blocks using triangles in the north east and south east corners.
\begin{keydescription}[\opt{style}]{block mark north east}
\keyheading[\opt{style}]{block mark north west}
\keyheading[\opt{style}]{block mark south east}
\keyheading[\opt{style}]{block mark south west}
With this key, triangular marks can be added to the corners of the head of a node:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[arity=2,block mark north east] {Cons};
\end{tikzpicture}
\end{example}
It is optional to add a style:
\begin{example}
\begin{tikzpicture}
[memory graph,every node/.style={block}]
\node[block mark north east={fill,red}] at (1,1) {1};
\node[block mark north west={blue}] at (0,1) {2};
\node[block mark south west={fill,green}] at (0,0) {3};
\node[block mark south east={brown}] at (1,0) {4};
\end{tikzpicture}
\end{example}
The key is long to avoid clashes with other packages,
and because it depends on the context what nodes should be marked for.
It is of course possible to define a shorthand in your own document.
One application is to mark nodes that are in head normal form (HNF),
for which one may define the key \verb$hnf$:
\begin{example}
\tikzset{every block/.style={block mark south east}}
\tikzset{hnf/.style={block mark south east=fill}}
\begin{tikzpicture}[memory graph]
\node[arity=2,hnf]
{Cons \arg{1}$\dots$ \arg{2}$\dots$};
\node[arity=2] at (0,-1)
{map \arg{1}$\dots$ \arg{2}$\dots$};
\end{tikzpicture}
\end{example}
The size of the rectangles is defined by \verb$\memorygraphs@marklength$,
which can of course be changed.
The default is \makeatletter\the\memorygraphs@marklength\makeatother.
\begin{example}
\makeatletter
\memorygraphs@marklength=7pt
\makeatother
\begin{tikzpicture}[memory graph]
\node[arity=2,block mark north west=fill]
{Cons \arg{1}$\dots$ \arg{2}$\dots$};
\end{tikzpicture}
\end{example}
\end{keydescription}
\subsection{Anchors}
\index{anchors}
Because blocks with \verb$arity$ are multipart rectangles,
one can use anchors like \verb$two south$ to refer to the south of the second part of a node.
These are aliased as \texttt{arg $i$ south} (and similar for other anchors on multipart nodes),
where \verb$arg 1$ stands for \verb$two$.
The first block of a node is aliased as \verb$head$ instead of \verb$arg 0$,
so one can use \verb$head south$.
For \verb$head$, anchors for the corners (\verb$head north east$, etc.) are defined as well.
The parts of multipart rectangles do not normally have a \verb$center$ anchor, but \memorygraphs{} defines these.
One can use both \verb$two center$ and \verb$arg 1 center$ to refer to the center of the first argument of a node.
The additional anchors are shown below.
See the \TikZ{} manual for the predefined anchors.
{\examplehorizontaltrue
\begin{example}
\Large
\begin{tikzpicture}
\node
[arity=2,
line width=.25cm,inner xsep=1.25cm,inner ysep=.75cm,
color=black!30,fill=yellow!30]
(v) {Head \arg{1} 1 \arg{2} 2};
\foreach \anchor/\placement in
{head north/above,head south/below,head center/below,
head north east/below,head south east/above,head north west/left,head south west/left,
arg 1 north/above,arg 1 south/below,arg 1 center/below,
arg 2 north/above,arg 2 south/below,arg 2 center/below}
\draw[shift=(v.\anchor)] plot[mark=x] coordinates{(0,0)}
node[\placement] {\scriptsize\texttt{v.\anchor}};
\end{tikzpicture}
\end{example}
}
\subsection{References}
\begin{keydescription}{ref}
This is a simple style for arrows with a circle at the start and slightly rounded corners:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[arity=2] (hd) {Cons};
\node
[arity=2,below=of hd.arg 2 center,anchor=head north]
(tl) {Cons};
\draw[ref] (hd.arg 2 center)
-- (tl.head north);
\draw[ref] (tl.arg 2 center)
|- ($(hd.head north)+(0,.4)$)
-- (hd.head north);
\end{tikzpicture}
\end{example}
\end{keydescription}
\section{Examples}
\examplehorizontaltrue
\begin{itemize}
\item
The linked list of Fibonacci numbers on the title page was generated with:
\noindent\begin{minipage}{\linewidth}
\centering
\input{example-fibonacci.tex}
\end{minipage}
\par\bigskip
\noindent\begin{minipage}{\linewidth}
\lstinputlisting{example-fibonacci.tex}
\end{minipage}
\item
A cyclical linked list, with unboxed integers:
\begin{example}
\begin{tikzpicture}[memory graph]
\node[block,arity=2] (xs) {Cons \arg{1} 1};
\node[block,arity=2,right=of xs.arg 2 east] (xsb) {Cons \arg{1} 2};
\draw[ref] (xs.arg 2 center) -- (xsb);
\node[block,arity=2,right=of xsb.arg 2 east] (xsc) {Cons \arg{1} 3};
\draw[ref] (xsb.arg 2 center) -- (xsc);
\draw[ref] (xsc.arg 2 center) -- +(0,.6) -| (xs.head north);
\end{tikzpicture}
\end{example}
\end{itemize}
\printindex
\end{document}