
Eu tenho que digitar alguns quadros semânticos em meu documento, parecidos com o exemplo abaixo.
Minha primeira ideia foi usar tikz
para isso, então criei o seguinte monstro:
\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}
É claro que este não é o resultado desejado. As bordas devem começar abaixo e terminar acima do \circ
s, e devem ter ângulos retos, de modo que o diagrama possa ser um pouco comprimido.
Desenhar esse tipo de diagrama é completamente novo para mim, então você pode me dar algumas orientações úteis? Você tem alguma dica ou truque para produzir esses quadros semânticos em geral? As embalagens semelhantes forest
ou qtree
produzidas são mais fáceis de usar para esse tipo de árvore?
Editar: A resposta de @cfr abaixo é promissora, então gostaria de trabalhar forest
e ajustar seu estilo tableaux
. Eu tentei fazer isso sozinho nos últimos dois dias, mas entender todas forest
as opções avançadas da documentação acabou sendo impossível para um iniciante como eu. Portanto, gostaria de conceder uma recompensa à pessoa que puder fazer o ajuste fino para mim. Que significa
- o espaço entre os wffs e o
\circ
separador deve ser diminuído, - as bordas devem estar alinhadas com o centro dos
\circ
separadores, ignorando os possíveis subscritos, - o procedimento acima também deve funcionar quando nenhum subscrito para o
\circ
separador for fornecido.
Responder1
Esta resposta usa uma abordagem completamente diferente, pois infelizmente o código da versão original da pergunta foi perdido. Pode ser menos útil, pois não é baseado nesse código, mas vou deixá-lo aqui, pois pode ser útil para alguém em algum momento.
Aqui está um estilo Forest básico, tableaux
que pode ser usado para esse tipo de diagrama.
O problema de usar label
é que ele não é levado em consideração ao posicionar os nós em relação uns aos outros. tableaux
cria nós adicionais para este conteúdo, que são especificados junto com o nó 'principal'. Isto torna possível alinhar as coisas corretamente com o círculo “principal”, deixando espaço suficiente para as wffs.
A única desvantagem real disso é que é necessário criar um phantom
nó raiz adicional, caso contrário, teríamos 2 ou 3 raízes (o nó principal no nível superior e wffs em cada lado). Isso não é possível. Daí o nó raiz fantasma.
Se você estiver fazendo muitas dessas coisas, é possível evitar ter que adicionar a raiz fantasma criando um novo ambiente que faça isso automaticamente. (O environ
pacote pode ser usado para isso com um nome personalizado para o corpo do ambiente.)
A biblioteca de Forest edges
é usada para fornecer o forked edges
estilo.
O ajuste fino fica como exercício para o leitor. Por exemplo, pode parecer melhor ajustar as distâncias entre irmãos para aproximar os 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
Isso aborda os 3 desejos adicionados à questão. Evitamos o efeito dos subscritos no alinhamento, renderizando-os como rótulos em vez de parte dos nós. Ajustamos a distância aos wffs antes de desenhar a árvore, pois não queremos reduzir as distâncias entre irmãos em geral, mas apenas a distância entre os círculos e os wffs associados. Tudo bem com e sem os subscritos.
Dependendo do seu uso real, família e tamanho da fonte, etc., você pode querer ajustar as dimensões específicas usadas nos ajustes. Estes são -3.5pt
e 3.5pt
para os subscritos e 7.5pt
e -7.5pt
para as wffs no MWE abaixo.
\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
Conforme apontado em um comentário, minha edição fez com que os fechamentos desaparecessem. Isso ocorre porque eles são criados usando label
e os números no canto superior direito dos nós também foram adicionados usando label
. Embora os rótulos sejam solicitados em locais diferentes e seriam adequados no código TikZ usual, Forest define label
de forma que apenas um seja permitido por nó. Além disso,label
tambémsubstitui quaisquer anotações anteriores especificadas usando tikz
ou 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 chamada tikz
substitui qualquer configuração anterior. Conseqüentemente, o código não se acumula, mas substitui o código existente.
Não tenho certeza do motivo que o autor teve para essa escolha, por isso não tenho certeza da melhor forma de abordá-la. Uma opção seria usar afterthought
para os números, o que deveria permitir o uso label
na própria árvore. Nesse caso, entretanto, não poderíamos especificar os números como TikZ label
s sem essencialmente reproduzir o código que Forest usa label
em primeiro lugar. Como não parece haver nenhuma vantagem em fazer isso, é tentador redefinir label
adicionando o seguinte código ao preâmbulo do documento:
\forestset{% Sašo Živanović won't like this ...
label/.style={%
tikz+={%
\path[late options={%
name=\forestoption{name},label={#1}}
];
}
},
}
O +
aqui é o que faz a diferença. Agora label
s serão acumulados em vez de se sobrescreverem e/ou quaisquer usos anteriores de pin
, tikz
ou tikz+
. Conforme indicado, não consigo imaginar que esse seja o tipo de coisa que devo fazer, por isso não estou recomendando, embora funcione:
Uma alternativa mais complexa é usar isto:
\forestset{%
my label/.style={%
tikz+={%
\path[late options={%
name=\forestoption{name},label={#1}}
];
}
}
}
Então a colocação dos números simplesmente é usada my label
no lugar de label
. Configuração 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},
}{}
},
}
}
que produz o mesmo resultado acima sem redefinir label
o estilo de Forest.