我想制作类似于下面的逻辑树的东西。我试过使用 tikz-qtree,但我不知道如何对树中的每一行进行编号。不过,我在 qtree 中找到了其他可行的方法。这是我的代码示例(请注意,它与下面的树不同)
\documentclass[a4paper, english, 12pt, reqno]{article}\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[norsk]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{mathtools}
\usepackage[shortlabels]{enumitem}
\usepackage{bm}
\usepackage{qtree}
\begin{document}
\maketitle{}
\section{}
\begin{center}
\begin{tabular}{c c c}
\Tree[.{1\\2\\ 3\\4} [.5 [.6 ] ] ] &
\Tree[.$A\supset B$\\$C\vee A$\\$\sim\sim C$\,\checkmark\\$C$ [.$C$ $s$ $s$ ][.$A$ $c$ $c$ ] ] &
\Tree[.SM\\SM\\SM\\3$\sim\sim$D [.3$\vee$D [.1$\supset$D ] ] ]
\end{tabular}
\end{center}
\end{document}
所以我有一些问题,希望能够帮助我更接近图中类似的树。
1)我的线条没有水平对齐,有什么办法可以解决这个问题吗?
2)如何删除连接数字的线以及表格环境右侧的符号?
3)这个问题不是我的代码的问题,但我以后会遇到这个问题。正如您在图片中的第 9 行看到的,有一个节点一直延伸到第 12 行,跳过了中间的行。我该怎么做?
我也愿意使用 tikz-qtree,但我可能错过了手册中的一些内容,所以我会尝试阅读更多内容,因为我对在 LaTeX 中使用 qtree 还很陌生。提前谢谢!
答案1
这是Ignasi 的回答。它使用基于 的新包forest
。其优点是可以自动对行进行编号,使用键将理由作为注释与其节点一起添加just
(无需单独的树),并且应该分组在一起的行之间的垂直间距(如列出假设时)会自动更正。另外,还提供了样式来将节点(move by
)移动到树中的较低行,而无需设置特殊tier
名称或输入空节点。在理由和闭包注释中提供了交叉引用支持(使用命名节点或相对节点名称),因此不需要硬编码行号。包文档中说明了更多选项和详细信息。
\documentclass[tikz,multi,border=10pt]{standalone}
\usepackage{prooftrees,amsmath,turnstile}
\newcommand*{\tnot}{\ensuremath{\mathord{\sim}}}
\begin{document}
\begin{prooftree} % uses Ignasi's code for the main tree (https://tex.stackexchange.com/a/233576/)
{
to prove={(\exists x)Fx \supset (\forall x)Fx \sststile{}{} (\forall x) (Fx \supset (\forall y) Fy)}
}
[(\exists x) Fx \supset (\forall x) Fx, checked, just=SM, name=pr
[\tnot (\forall x) (Fx \supset (\forall y) Fy), checked, grouped, just=SM
[(\exists x) \tnot (Fx \supset (\forall y) Fy), checked=a, just={$\tnot\forall$D:!u}
[\tnot (Fa \supset (\forall y) Fy), checked, just={$\exists$D:!u}
[Fa, just={$\tnot\supset$D:!u}, name=fa
[\tnot (\forall y) Fy, checked, grouped, just={$\tnot\supset$D:!uu}
[(\exists y) \tnot Fy, checked=b, just={$\tnot\forall$D:!u}
[\tnot Fb, just={$\exists$D:!u}, name=nofb
[\tnot (\exists x) Fx, checked, just={$\supset$D:pr}
[(\forall x) \tnot Fx, subs=a, just={$\tnot\exists$D:!u}
[\tnot Fa, close={:fa,!c}, just={$\forall$D:!u}
]
]
]
[(\forall x) Fx, subs=b
[Fb, close={:nofb,!c}, just={$\forall$D:!u}, move by=2
]
]
]
]
]
]
]
]
]
]
\end{prooftree}
\end{document}
答案2
这是一种方法。这有点像 hack,因为它需要手动调整才能获得正确的间距。
代码通过创建三棵树来工作 - 主树、行号和对齐。为了创建后两者而不需要行,我们暂时重新定义了用于分支的命令,利用 的qtree
功能!
。
最佳工作流程是先设置树本身。然后将该树复制到代码中,并将每个实例替换[.{single formula i.e. no line break}
为[.n
适当的行号 n。然后将替换[.{several formulae with line breaks}
为[.{n\\m\\...}
相关行号 n、m、...。现在编译并检查间距。根据需要添加间距。尽可能使行对齐。然后将行号树复制到主树的代码下方。只需用相关对齐替换行号即可。间距应该是正确的,因为您已经调整过了。
文档中实际上介绍了如何创建第十二行的长分支,qtree
其中解释了如何创建没有标签的节点。但是,它可能不适用于此处,因为示例涉及未标记的分支节点,而您的示例需要额外的非分支节点。
\documentclass[a4paper, english, 12pt, reqno]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[norsk]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{mathtools}
\usepackage[shortlabels]{enumitem}
\usepackage{bm}
\usepackage{qtree}
\usepackage{turnstile}
% set up a more semantically pleasing command for not
\newcommand*{\tnot}{\ensuremath{\mathord{\sim}}}
\makeatletter
\newcommand{\nounibranches}[1]{% One-branching only
\begin{picture}(0,1)
\put(0,0){\line(0,1){0}}
\end{picture}}%
\newcommand{\nobibranches}[1]{% Two-branching only
\begin{picture}(2,0.5)
\put(0,0){\line(2,1){0}}
\put(2,0){\line(-2,1){0}}
\end{picture}}%
\let\qdrawReal=\qdraw@branches
\def\dimbr#1{\ifcase#1\relax % zero case is unused
\or % One-branching
\let\qdraw@branches=\nounibranches
\or % Two-branching
\let\qdraw@branches=\nobibranches
\else \typeout{error --- Can't handle #1-way branching}
\fi}
\newcommand\breto{\let\qdraw@branches=\qdrawReal}
\makeatother
\begin{document}
\hspace*{-\parindent}
{$(\exists x)Fx \supset (\forall x)Fx \sststile{}{} (\forall x) (Fx \subset (\forall y) Fy)$}\bigskip\\
\Tree
[.{1\\2}
[.3
[.4
[.{5\\6}
[.7
[.{8\\[-.75em]\mbox{ }}
[.9
[.10
[.11
[.12
!{\dimbr1}
]
]
]
]
]
]
]
]
]
] {\breto}
\Tree
[.{$(\exists x) Fx \supset (\forall x) Fx\ \checkmark$\\
$\tnot (\forall x) (Fx \subset (\forall y) Fy)\ \checkmark$}
[.{$(\exists x) \tnot (Fx \subset (\forall y) Fy)\ \checkmark$}
[.{$\tnot (Fa \subset (\forall y) Fy)\ \checkmark$}
[.{$Fa$\\$\tnot (\forall y) Fy\ \checkmark$}
[.{$(\exists y) \tnot Fy\ \checkmark$}
[.{$\tnot Fb$}
[.{$\tnot (\exists x) Fx\ \checkmark$}
[.{$(\forall x) \tnot Fx\ \checkmark$}
[.{$\tnot Fa$\\$\otimes$}
]
]
]
[.{$(\forall x) Fx\ \checkmark$}
[
[
[
[
[
[.{$Fb$\\$\otimes$}
]
]
]
]
]
]
]
]
]
]
]
]
]
\Tree
[.{SM\\SM}
[.{2 $\tnot\forall$D}
[.{3 $\exists$E}
[.{4 $\tnot\supset$D\\4 $\tnot\supset$D}
[.{6 $\tnot\forall$D}
[.{7 $\exists$D}
[.{1 $\supset$D}
[.{9 $\tnot\exists$D}
[.{10 $\forall$D}
[.{9 $\forall$D}
!{\dimbr1}
]
]
]
]
]
]
]
]
]
] {\breto}
\end{document}
这将生成以下树:
答案3
如果你愿意接受不同的方法,我实际上会采用另一种方法\usetikzlibrary{matrix}
。我认为这个解决方案可能比@cfr 的解决方案,因为不需要手动调整此解决方案的间距。
也就是说,可以全局指定和matrix
的选项,以便获得所有行和列所需的默认间距。但与此同时,如果想要操纵column sep
row sep
一些的间距,可以通过例如使用可选参数来实现\\
,正如我在第 8 行中所做的那样,matrix
以便为“树”的分支部分提供更多的分离。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{amssymb}
\newcommand*{\tnot}{\ensuremath{\mathord{\sim}}} % following @cfr's suggestion
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of nodes, row sep=0.2em,
column sep=0.1em, text height=1.5ex, text depth=0.25ex]
{
1 & & $(\exists x) Fx \supset (\forall x) Fx\ \checkmark$ & & SM \\
2 & & $\tnot (\forall x) (Fx \subset (\forall y) Fy)\ \checkmark$ & & SM \\
3 & & $(\exists x) \tnot (Fx \subset (\forall y) Fy)\ \checkmark$ & & 2 $\tnot\forall$D \\
4 & & $\tnot (Fa \subset (\forall y) Fy)\ \checkmark$ & & 3 $\exists$E \\
5 & & $Fa$ & & 4 $\tnot\supset$D \\
6 & & $\tnot (\forall y) Fy\ \checkmark$ & & 4 $\tnot\supset$D \\
7 & & $(\exists y) \tnot Fy\ \checkmark$ & & 6 $\tnot\forall$D \\
8 & & $\tnot Fb$ & & 7 $\exists$D \\[2em] % here I've added some space so the tree can branch
9 & $\tnot (\exists x) Fx\ \checkmark$ & & $(\forall x) Fx\ \checkmark$ & 1 $\supset$D \\
10 & $(\forall x) \tnot Fx\ \checkmark$ & & & 9 $\tnot\exists$D \\
11 & $\tnot Fa$ & & & 10 $\forall$D \\
12 & $\otimes$ & & $Fb$ & 9 $\forall$D \\
& & & $\otimes$ & \\
};
\path[-] (m-8-3.south) edge (m-9-2.north)
(m-8-3.south) edge (m-9-4.north)
(m-9-4) edge (m-12-4);
\end{tikzpicture}
\end{document}
答案4
只是为了好玩,我想尝试一下forest
并且所有列都是来自同一棵树的分支。
主要问题是如何调整列之间的水平对齐。forest
文档提到(第 17 页)当文本包含 时parenthesis
,对齐看起来会很奇怪,因为这是一个非常特殊的情况。但是,像往常一样,它也提供了一种解决方案,即定义一个新的\forestStandardNode
。
因此,一个可能的解决方案forest
可能是:
\documentclass[tikz,border=2mm]{standalone}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[norsk]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{mathtools}
\usepackage{qtree}
\usepackage{forest}
\newcommand*{\tnot}{\ensuremath{\mathord{\sim}}} % following @cfr's suggestion
\begin{document}
\forestStandardNode[(dj)]
{%
\forestOve{\csname forest@id@of@standard node\endcsname}{content},%
\the\ht\strutbox,\the\pgflinewidth,%
\pgfkeysvalueof{/pgf/inner ysep},\pgfkeysvalueof{/pgf/outer ysep},%
\pgfkeysvalueof{/pgf/inner xsep},\pgfkeysvalueof{/pgf/outer xsep}%
}
{
l sep={\the\ht\strutbox+\pgfkeysvalueof{/pgf/inner ysep}},
l={l_sep()+abs(max_y()-min_y())+2*\pgfkeysvalueof{/pgf/outer ysep}},
s sep={2*\pgfkeysvalueof{/pgf/inner xsep}}
}
{l sep,l,s sep}
\begin{forest}
[,phantom, for descendants={no edge}
[1, [2[3[4[5[6[7[8[9[10[11[12]]]]]]]]]]]]
[$(\exists x) Fx \supset (\forall x) Fx\ \checkmark$
[$\tnot (\forall x) (Fx \subset (\forall y) Fy)\ \checkmark$
[$(\exists x) \tnot (Fx \subset (\forall y) Fy)\ \checkmark$
[$\tnot (Fa \subset (\forall y) Fy)\ \checkmark$
[$Fa$
[$\tnot (\forall y) Fy\ \checkmark$
[$(\exists y) \tnot Fy\ \checkmark$
[$\tnot Fb$
[$\tnot (\exists x) Fx\ \checkmark$, edge={draw}
[$(\forall x) \tnot Fx\ \checkmark$
[$\tnot Fa$
[$\otimes$, tier=otimes]]]]
[$(\forall x) Fx\ \checkmark$, edge={draw}
[$Fb$,tier=otimes, edge={draw}
[$\otimes$]]]]]]]]]]]
[SM [SM[2 $\tnot\forall$D[3 $\exists$E[4 $\tnot\supset$D[6 $\tnot\forall$D
[7 $\exists$D[1 $\supset$D[9 $\tnot\exists$D[10 $\forall$D
[9 $\forall$D]]]]]]]]]]]
]
\end{forest}
\end{document}