
Tengo que componer algunos cuadros semánticos en mi documento, similares al ejemplo siguiente.
Mi primera idea fue usarlo tikz
para esto, así que creé el siguiente monstruo:
\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 forest
o qtree
producir 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 forest
y perfeccionar su estilo tableaux
. Intenté hacerlo yo mismo durante los últimos dos días, pero comprender todas forest
las 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
\circ
separador debe reducirse, - los bordes deben estar alineados con el centro de los
\circ
separadores, ignorando los posibles subíndices, - Lo anterior también debería funcionar cuando no
\circ
se 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 tableaux
que podría usarse para este tipo de diagrama.
El problema con el uso label
es que no se tiene en cuenta al posicionar los nodos entre sí. tableaux
crea 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 phantom
nodo 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 environ
paquete se puede utilizar para esto con un nombre personalizado para el cuerpo del entorno).
La biblioteca de Forest edges
se utiliza para proporcionar el forked edges
estilo.
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}
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.5pt
y 3.5pt
para los subíndices y 7.5pt
y -7.5pt
para 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}
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 label
y 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 label
de tal manera que solo se permite una por nodo. Además,label
tambiénsobrescribe cualquier anotación anterior especificada usando tikz
o 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 tikz
anula 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 afterthought
para los números, lo que debería permitir el uso label
en el propio árbol. En ese caso, sin embargo, no podríamos especificar los números como TikZ label
sin reproducir esencialmente el código que usa Forest label
en primer lugar. Dado que no parece haber ninguna ventaja en hacer eso, es tentador redefinir label
agregando 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 label
los s se acumularán en lugar de sobrescribirse entre sí y/o cualquier uso anterior de pin
, tikz
o 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:
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 label
en 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
.