EDITAR

EDITAR

Tengo que componer algunos cuadros semánticos en mi documento, similares al ejemplo siguiente.

Cuadro semántico

Mi primera idea fue usarlo tikzpara esto, así que creé el siguiente monstruo:

árbol feo

\documentclass[convert]{standalone}
\usepackage{tikz,amssymb}
\usetikzlibrary{positioning}
\newcommand{\lnec}{\Box}
\begin{document}
  \begin{tikzpicture}[scale=2]
    \node[label=right:$(\lnec p\to\lnec q)\to\lnec(p\to q)$] (n1) {$\circ_1$};
    \node[label=left:$\lnec p\to\lnec q$, label=right:$\lnec(p\to q)$, below=of n1] (n2) {$\circ_1$};
    \node[label=left:$\lnec q$, label=right:$\lnec(p\to q)$, below left=of n2] (n3) {$\circ_1$};
    \node[label=right:{$\lnec p, \lnec(p\to q)$}, below right=of n2] (n4) {$\circ_1$};
    \node[label=left:$q$, label=right:$\lnec(p\to q)$, below=of n3] (n5) {$\circ_2$};
    \node[label=right:$p$, below left=of n4] (n6) {$\circ_3$};
    \node[label=right:$p\to q$, below right=of n4] (n7) {$\circ_4$};
    \node[label=left:$p$, label=right:$q$, below=of n7] (n8) {$\circ_4$};

    \draw[-] (n1) to (n2);
    \draw[-] (n2) to (n3);
    \draw[-] (n2) to (n4);
    \draw[-, dotted] (n3) to (n5);
    \draw[-, dotted] (n4) to (n6);
    \draw[-, dotted] (n4) to (n7);
    \draw[-] (n7) to (n8); 
  \end{tikzpicture}
\end{document}

Está claro que éste no es el resultado deseado. Los bordes deben comenzar debajo y terminar encima del\circ s, y deben tener ángulos rectos, de modo que el diagrama se pueda comprimir un poco.

Dibujar este tipo de diagramas es completamente nuevo para mí, entonces, ¿puedes darme algunas pautas útiles? ¿Tiene algún consejo o truco para producir estos cuadros semánticos en general? ¿Los paquetes como foresto qtreeproducir son más fáciles de usar para este tipo de árbol?


Editar: La respuesta de @cfr a continuación es prometedora, por lo que me gustaría trabajar foresty perfeccionar su estilo tableaux. Intenté hacerlo yo mismo durante los últimos dos días, pero comprender todas forestlas opciones avanzadas de la documentación resultó imposible para un principiante como yo. Por lo tanto, me gustaría otorgar una recompensa a la persona que pueda hacer los ajustes por mí. Eso significa

  • el espacio entre los wffs y el \circseparador debe reducirse,
  • los bordes deben estar alineados con el centro de los \circseparadores, ignorando los posibles subíndices,
  • Lo anterior también debería funcionar cuando no \circse proporciona ningún subíndice para el separador.

Respuesta1

Esta respuesta utiliza un enfoque completamente diferente ya que lamentablemente el código se perdió de la versión original de la pregunta. Puede que sea menos útil ya que no está basado en ese código, pero lo dejaré aquí ya que puede serle útil a alguien en algún momento.

A continuación se muestra un estilo de bosque básico tableauxque podría usarse para este tipo de diagrama.

El problema con el uso labeles que no se tiene en cuenta al posicionar los nodos entre sí. tableauxcrea nodos adicionales para este contenido que se especifican junto con el nodo 'principal'. Esto hace posible alinear las cosas correctamente con el círculo "principal" dejando suficiente espacio para los wffs.

La única desventaja real de esto es que es necesario crear un phantomnodo raíz adicional ya que de lo contrario terminaríamos con 2 o 3 raíces (el nodo principal en el nivel superior y wffs en cada lado). Eso no es posible. De ahí el nodo raíz fantasma.

Si está haciendo muchas de estas cosas, es posible evitar tener que agregar la raíz fantasma creando un nuevo entorno que lo haga automáticamente. (El environpaquete se puede utilizar para esto con un nombre personalizado para el cuerpo del entorno).

La biblioteca de Forest edgesse utiliza para proporcionar el forked edgesestilo.

El ajuste se deja como ejercicio para el lector. Por ejemplo, podría parecer mejor ajustar las distancias entre hermanos para acercar a los wffs.

\documentclass[tikz,multi,border=10pt]{standalone}
\usepackage[edges]{forest}
\usepackage{amssymb}
\begin{document}
\forestset{%
  declare toks={F}{},
  declare toks={T}{},
  tableaux/.style={%
    forked edges,
    for tree={
      math content,
      parent anchor=children,
      child anchor=parent,
    },
    where level=0{%
      for children={no edge},
      phantom,
    }{%
      delay={%
        content/.wrap value={\circ_{##1}},
        insert before/.wrap pgfmath arg={%
          [{##1}, no edge, math content]
        }{T()},
        insert after/.wrap pgfmath arg={%
          [{##1}, no edge, math content]
        }{F()},
      },
      if={n_children("!u")==1}{%
        before packing={calign with current edge},
      }{}
    },
  }
}
\newcommand*{\necc}{\ensuremath{\mathbin{\Box}}}
\newcommand*{\lif}{\ensuremath{\mathbin{\rightarrow}}}
\begin{forest}
  tableaux
  [
    [1, F=(\necc p \lif \necc q) \lif \necc (p \lif q)
      [1, T=\necc p \lif \necc q, F=\necc (p \lif q)
        [1, T=\necc q, F=\necc (p \lif q)
          [2, T=q, F=p \lif q, edge=densely dotted
            [2, T={p, q}, F=q, label=below:$\otimes$]
          ]
        ]
        [1, F={\necc p, \necc(p \lif q)}
          [3, F=p, edge=densely dotted]
          [4, F=p \lif q, edge=densely dotted
            [4, F=q, T=p]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

cuadros

EDITAR

Esto aborda los 3 desiderata agregados a la pregunta. Evitamos el efecto de los subíndices en la alineación representándolos como etiquetas en lugar de como parte de los nodos. Ajustamos la distancia a los wffs antes de dibujar el árbol, ya que no queremos reducir las distancias entre hermanos en general, sino solo la distancia entre los círculos y los wffs asociados. Esta bien con y sin los subíndices.

Dependiendo de su uso real, familia de fuentes y tamaño, etc., es posible que desee ajustar las dimensiones particulares utilizadas en los ajustes. Estos son -3.5pty 3.5ptpara los subíndices y 7.5pty -7.5ptpara los wffs en el MWE a continuación.

\documentclass[tikz,multi,border=10pt]{standalone}
\usepackage[edges]{forest}
\usepackage{amssymb}
\begin{document}
\forestset{%
  declare toks={T}{},
  declare toks={F}{},
  tableaux/.style={%
    forked edges,
    for tree={
      math content,
      parent anchor=children,
      child anchor=parent,
    },
    where level=0{%
      for children={no edge},
      phantom,
    }{%
      before typesetting nodes={%
        content/.wrap value={\circ},
      },
      delay={%
        my label/.wrap pgfmath arg={{[inner sep=0pt, xshift=-3.5pt, yshift=3.5pt, anchor=north west, font=\scriptsize]-45:$##1$}}{content()},
        insert before/.wrap pgfmath arg={%
          [{##1}, no edge, math content, before drawing tree={x'+=7.5pt}]
        }{T()},
        insert after/.wrap pgfmath arg={%
          [{##1}, no edge, math content, before drawing tree={x'-=7.5pt}]
        }{F()},
      },
      if={n_children("!u")==1}{%
        before packing={calign with current edge},
      }{}
    },
  }
}
\newcommand*{\necc}{\ensuremath{\mathbin{\Box}}}
\newcommand*{\lif}{\ensuremath{\mathbin{\rightarrow}}}
\begin{forest}
  tableaux
  [
    [1, F=(\necc p \lif \necc q) \lif \necc (p \lif q)
      [1, T=\necc p \lif \necc q, F=\necc (p \lif q)
        [1, T=\necc q, F=\necc (p \lif q)
          [2, T=q, F=p \lif q, edge=densely dotted
            [2, T={p, q}, F=q, label=below:$\otimes$]
          ]
        ]
        [1, F={\necc p, \necc(p \lif q)}
          [3, F=p, edge=densely dotted]
          [4, F=p \lif q, edge=densely dotted
            [4, F=q, T=p
              [99, F=X!, T=XX!!
                [, F=XXX!!!, T=XXXX!!!!]
              ]
            ]
          ]
        ]
      ]
    ]
  ]
\end{forest}
\end{document}

versión modificada

EDITAR EDITAR

Como se señaló en un comentario, mi Edición provocó que los cierres desaparecieran. Esto se debe a que se crean usando labely los números en la parte superior derecha de los nodos también se agregaron usando label. Aunque las etiquetas se solicitan en diferentes lugares y estarían bien en el código TikZ habitual, Forest las define labelde tal manera que solo se permite una por nodo. Además,label tambiénsobrescribe cualquier anotación anterior especificada usando tikzo pin. De forest.sty:

 label/.style={tikz={\path[late options={%
        name=\forestoption{name},label={#1}}];}},
 pin/.style={tikz={\path[late options={%
        name=\forestoption{name},pin={#1}}];}},

Cada llamada a tikzanula cualquier configuración anterior. Por lo tanto, el código no se acumula, sino que reemplaza el código existente.

No estoy seguro de qué motivo tuvo el autor para esta elección, por lo que no estoy del todo seguro de cuál es la mejor manera de abordarlo. Una opción sería usar afterthoughtpara los números, lo que debería permitir el uso labelen el propio árbol. En ese caso, sin embargo, no podríamos especificar los números como TikZ labelsin reproducir esencialmente el código que usa Forest labelen primer lugar. Dado que no parece haber ninguna ventaja en hacer eso, es tentador redefinir labelagregando el siguiente código al preámbulo del documento:

\forestset{% Sašo Živanović won't like this ...
  label/.style={%
    tikz+={%
      \path[late options={%
        name=\forestoption{name},label={#1}}
      ];
    }
  },
}

Esto +es lo que marca la diferencia. Ahora labellos s se acumularán en lugar de sobrescribirse entre sí y/o cualquier uso anterior de pin, tikzo tikz+. Como se indicó, no puedo imaginar que este sea el tipo de cosas que debo hacer, por lo que no lo recomiendo, aunque funciona:

restaurar cierres con hack

Una alternativa más compleja es utilizar esto:

\forestset{%
  my label/.style={%
    tikz+={%
      \path[late options={%
        name=\forestoption{name},label={#1}}
      ];
    }
  }
}

Luego, la ubicación de los números simplemente usa my labelen lugar de label. Configuración completa:

\forestset{%
  declare toks={T}{},
  declare toks={F}{},
  my label/.style={%
    tikz+={%
      \path[late options={%
        name=\forestoption{name},label={#1}}
      ];
    }
  },
  tableaux/.style={%
    forked edges,
    for tree={
      math content,
      parent anchor=children,
      child anchor=parent,
    },
    where level=0{%
      for children={no edge},
      phantom,
    }{%
      before typesetting nodes={%
        content/.wrap value={\circ},
      },
      delay={%
        my label/.wrap pgfmath arg={{[inner sep=0pt, xshift=-3.5pt, yshift=3.5pt, anchor=north west, font=\scriptsize]-45:$##1$}}{content()},
        insert before/.wrap pgfmath arg={%
          [{##1}, no edge, math content, before drawing tree={x'+=7.5pt}]
        }{T()},
        insert after/.wrap pgfmath arg={%
          [{##1}, no edge, math content, before drawing tree={x'-=7.5pt}]
        }{F()},
      },
      if={n_children("!u")==1}{%
        before packing={calign with current edge},
      }{}
    },
  }
}

lo que produce el mismo resultado que el anterior sin redefinir el estilo de Forest label.

información relacionada