12

I'm trying to replicate the following tree in LaTeX: enter image description here

I'm having problems, because (1) I never drew a tree diagram with 90º degrees branches, like this, and (2) I never drew a tree diagram together with numbered examples. I tried using tikz-qtree and forest, but I didn't get anywhere. So I tried using tabbing environment to solve the numbered exemples problem, but now I don't know what package to use to draw the lines. This is my current (and horribly written) code:

\documentclass[]{article}
\begin{document}
\begin{tabbing}
\hspace{0em} $(20)$ \= \hspace{2em} $n$ \= \hspace{1em} $s/(n)[n]$ \= 
\hspace{1em} $n/[s]$ \= \hspace{1em} $n$ \= \hspace{1em} $s/(n)$ \= 
\hspace{1em} $s/(n)//(s/(n))$ \= \hspace{1em} $s/(n)//(s/(n))[n]$ \= 
\hspace{1em} $n$ \= \hspace{1em} $n/(n)$\\~\\
\hspace{0em} $(21)$\= \hspace{37.5em} $n$\\~\\
\hspace{0em} $(22)$\= \hspace{17.5em} $s/(n)$\\~\\
\hspace{0em} $(23)$\= \hspace{30em} $s/(n)$\\~\\
\hspace{0em} $(24)$\= \hspace{20,5em} $s$\\~\\
\hspace{0em} $(25)$\= \hspace{14em} $n$\\~\\
\hspace{0em} $(26)$\= \hspace{6em} $s$\\
\end{tabbing}
\end{document}

Resulting in: enter image description here Can anyone give me some help on how to resolve this nightmare I'm having to replicate the tree diagram of the first image?

  • I wonder if you could use prooftrees for this .... – cfr May 30 '18 at 1:30
11

Here's a version using forest.

\documentclass{article}
\usepackage[edges]{forest}

\forestset{
declare count register=labelcount,
enumerate/.style={labelcount=#1,
for tree={content/.pgfmath=labelcount, labelcount-=1},
}
}

\begin{document}

\begin{forest}for tree={grow=north,forked edge,math content}
[
[s,no edge
    [n
        [s
            [s/(n)
                [n,tier=21
                    [n/(n), tier=top]
                    [n,tier=top]] 
                [{s/(n)//(s/(n))[n]},tier=top ]
                [s/(n)
                    [s/(n)//(s/(n))),tier=top ]
                    [s/(n),tier=top ]
                ]
            ]
            [n,tier=top]
         ]
        [{n/[s]},tier=top ]
    ]
    [{s/(n)[n]},tier=top ]
    [n,tier=top ]
]
[,for tree=no edge,delay={enumerate={26},for tree={content={(#1)}}}
    [[[[[,tier=21 [,tier=top ]]]]]]]
]
\end{forest}

\end{document}

output of code

Explanation of the code

  • We use the edges library from forest to make easy square branches.
  • We use grow=north to make the tree upside down.
  • The use of the tier key allows all the terminal nodes of the tree to be aligned at the top of the tree. It is also used to separate line (21) from (22) since in the tree they are at the same level of embedding, but in numbering they are not. By aligning the nodes in the tree with the nodes in the numbering we achieve the desired result.
  • The numbering is done with what is essentially a phantom root node that dominates both the tree and the numbers.
  • The numbers are calculated semi-automatically by giving the number for the root node using the enumerate=... key and counting down from there. Again, the tier key is used keep the alignment correct.
  • Interesting (+1, of course). It might be better not to rely on tempcounta, though. Why not use a new count for this, which is less likely to run into conflicts? I realise that's not very likely, but still .... – cfr May 28 '18 at 20:42
  • @cfr I was hoping you'd drop by with some comments. I just assumed that tempcounta was always local, and unlikely to interfere with other uses of it. What I'd really like to do is to number the nodes 'bottom up' (in the tree sense) from 20 instead of having to precalculate the last number and count down. Any ideas on how to do that? – Alan Munn May 28 '18 at 21:08
  • I was actually thinking that's how I'd do it. And I'd add the root and numbers automatically, if possible. tempcounta is local to the forest group, but not otherwise local. So it is unlikely to conflict, but might if, say, the OP tries to combine this code with code from another answer. (If they write additional code themselves, presumably, they know enough to avoid that, but I'm thinking more of an attempt to combine your answer with some other one.) – cfr May 28 '18 at 21:12
  • @cfr There was a comma missing in the label branch. I've updated and made a counter. – Alan Munn May 28 '18 at 21:34
  • I hope you don't mind: I've added an answer now my brain has started working again. – cfr May 30 '18 at 1:27
8
\documentclass[border = 5pt]{standalone}

\usepackage{tikz-qtree}

\begin{document}
\begin{tikzpicture}[grow' = up]
  \tikzset{
    edge from parent/.style = {draw,
      edge from parent path={(\tikzparentnode.north)
        -| (\tikzchildnode)}},
    frontier/.style = {distance from root = 180pt},
  }

  % tree
  \Tree [.s [n ]
            [s/(n)[n] ]
            [.n [n/[s] ]
                [.s [n ]
                    [.s/(n) [.s/(n) [s/(n) ] 
                                    [s/(n)//(s/(n)) ] ]
                            [s/(n)//(s/(n))[n] ]
                            [ [.n [.n ]
                                [.n/(n) ] ] ] ] ] ] ]

  % labels
  \foreach \y/\lbl in {0/26,30/25,60/24,90/23,120/22,150/21,180/20} {
    \node[xshift = -3cm, yshift = \y pt] at (0, 0){\small(\lbl)}; 
  }

\end{tikzpicture}

\end{document}

enter image description here

3

This is an adaption of Alan Munn's answer which is designed to be a bit more user-friendly. To produce the tree, simply add

enumerated,
enum'=<start line number>

where <start line number> is the number for the first line. The enumerated style will try to figure out how many lines are required, format the tree and number the lines. It is not necessary to add the phantom root or nodes for the numbers explicitly: these nodes will all be added automatically.

The only case where you need to help out are cases where extra lines are needed because two nodes which are at the same structural level should be placed on different lines.

The upshot of this is that

\begin{forest}
  enumerated,
  enum'=20,
  [S
      [n
          [s
              [s/(n)
                  [n,tier=21
                      [n/(n)]
                      [n]] 
                  [{s/(n)//(s/(n))[n]} ]
                  [s/(n),tier=22
                      [s/(n)//(s/(n))) ]
                      [s/(n) ]
                  ]
              ]
              [n]
          ]
          [{n/[s]} ]
      ]
      [{s/(n)[n]} ]
      [n ]
  ]
\end{forest}

produces

<code>enumerated</code> Forest style

Code:

\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}

\forestset{% addaswyd o gôd Alan Munn: https://tex.stackexchange.com/a/433753/
  declare count register=enum,
  enum'=100,
  declare toks register=enum tiers,
  enum tiers=,
  declare boolean register=enum toggle,
  not enum toggle,
  enumerated/.style={
    enum tiers=enum@tier@\foresteregister{enum},
    for tree={
      math content,
      grow=90,
    },
    forked edges,
    delay={
      tempcountc/.max={level}{tree},
      tempcountc'+=1,
      tempcountb/.register=enum,
      while={
        >R_> {tempcountc}{0}
      }{
        tempcountc'-=1,
        not enum toggle,
        where={
          > O R = {level} {tempcountc}
        }{
          if n children=0{
            tier/.process={Rw{enum}{enum@tier@##1}}
          }{
            if tier={}{
              tier/.process={Rw{tempcountb}{enum@tier@##1}},
              if={>R! RR=! & {enum toggle} {tempcountb}{enum} }{ +enum tiers/.process={Rw{tempcountb}{enum@tier@##1,}}, enum toggle } {}
            }{
              +enum tiers/.process={Ow{tier}{##1,}}
            }
          },
        }{},        
        tempcountb'+=1,
      },
    },
    before typesetting nodes={
      replace by={[, phantom, for tree={grow=90}, append, temptoksa/.option=name, split register={enum tiers}{,}{enum label}
        ]%
      },
    },
    before packing={
      delay={
        tempcounta/.register=enum,
        for nodewalk={reverse={fake=r,while nodewalk valid={l}{l}}}{content/.process={Rw{tempcounta}{(##1)}}, typeset node, tempcounta'+=1},
      }
    }
  },
  enum label/.style={
    prepend={[, grow=90, tier=#1, no edge, name=#1]},
    enum parent/.process={Rw{temptoksa}{{##1}{#1}}},
    temptoksa=#1,
  },
  enum parent/.style 2 args={
    before packing={
      for nodewalk={name=#1}{append=#2}
    },
  },
}

\begin{document}
\begin{forest}
  enumerated,
  enum'=20,
  [S
      [n
          [s
              [s/(n)
                  [n,tier=21
                      [n/(n)]
                      [n]] 
                  [{s/(n)//(s/(n))[n]} ]
                  [s/(n),tier=22
                      [s/(n)//(s/(n))) ]
                      [s/(n) ]
                  ]
              ]
              [n]
          ]
          [{n/[s]} ]
      ]
      [{s/(n)[n]} ]
      [n ]
  ]
\end{forest}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.