编辑

编辑

我想知道如何画这些树:

在此处输入图片描述

我真的不知道。我看过了,但没有找到任何可以帮助我的东西(特别是画这些树)。所以我希望你能帮助我。

\documentclass[a4paper]{article}
\usepackage{amsmath}

\begin{document}

\end{document}

答案1

例如,这是使用强大forest包的第二棵树的示意图。

\documentclass[tikz, border=5pt]{standalone}
\usepackage{forest}

\begin{document}
  \begin{forest}
    for tree={
      shape=circle,
      fill=black,
      minimum width=5pt,
      inner sep=1pt,
      parent anchor=south,
      child anchor=north,
      anchor=center,
      line width=1pt
    }
    [, label={right:some label A}
      [, label={right:some label B}
        [, label={right:some label C}
          [, label={below:F}]
          [, label={right:some label D}
            [, label={below:E}]
          ]
        ]
      ]
    ]
  \end{forest}
\end{document}

图解森林

编辑

这里有两棵树及其公式。

如果您正在学习在逻辑中使用证明树,请不要将其用作示例。

这些不是逻辑证明中使用的标准树!

不合逻辑的树 1 不合逻辑的树

\documentclass[tikz, border=5pt, multi, varwidth]{standalone}
\usepackage{forest}
\standaloneenv{forest}
\begin{document}
  \forestset{
    my tree/.style={
      for tree={
        shape=circle,
        fill=black,
        minimum width=5pt,
        inner sep=1pt,
        anchor=center,
        line width=1pt,
        s sep+=25pt,
      },
    },
  }
  \begin{forest}
    my tree
    [, label={right:$(p_1 \rightarrow (\bot \vee (\lnot p_3)))$}
      [, label={below:$p_1$}]
      [, label={right:$(\bot \vee (\lnot p_3))$}
        [, label={below:$\bot$}]
        [, label={right:$(\lnot p_3)$}
          [, label={below:$p_3$}]
        ]
      ]
    ]
  \end{forest}

  \begin{forest}
    my tree
    [, label={right:$(\lnot(\lnot(p_1 \wedge (\lnot p_1))))$}
      [, label={right:$(\lnot(p_1 \wedge (\lnot p_1)))$}
        [, label={right:$(p_1 \wedge (\lnot p_1))$}
          [, label={below:$p_1$}]
          [, label={right:$(\lnot p_1)$}
            [, label={below:$p_1$}]
          ]
        ]
      ]
    ]
  \end{forest}
\end{document}

答案2

pst-tree这两棵树的路径如下:

\documentclass[12pt, a4paper, pdf]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{fourier}
\usepackage{pst-node, pst-tree}

\renewcommand\psedge{\ncline[arrows =-]}

\begin{document}
\psset{levelsep=1.5cm, treesep=3cm, dotsize =5pt}

\pstree
{\Tdot[dotsize =5pt] \nput{45}{\pssucc}{$ (p_1\to(\bot ∨ (\neg p_3)))$}}%
{%
    \Tdot\nput{-90}{\pssucc}{$p_1$}
    \pstree{\Tdot\nput{45}{\pssucc}{$(\bot ∨ (\neg p_3)) $}}%
    {\Tdot\nput{-90}{\pssucc}{$\bot $}%
        \pstree{\Tdot\nput{45}{\pssucc}{$(\neg p_3)$}}
        {\Tdot\nput{-90}{\pssucc}{$p_3$}}
    }
}
\hfill
\raisebox{-1.5cm}{%
    \pstree%
    {\Tdot[dotsize =5pt] \nput{45}{\pssucc}{$ (\neg(\neg(p_1 ∧ (\neg p_1))))$}}%
    {\pstree%
        {\Tdot \nput{45}{\pssucc}{$ (\neg(p_1 ∧ (\neg p_1)))$}}%
        {\pstree%
            {\Tdot \nput{45}{\pssucc}{$ (p_1 ∧ (\neg p_1)) $}}%
            {\Tdot\nput{-90}{\pssucc}{$p_1$}%
                \pstree%
                {\Tdot \nput{45}{\pssucc}{$(\neg p_1)$}}%
                {\Tdot\nput{-90}{\pssucc}{$p_1$}}
            }
        }
    }
}%
\end{document} 

在此处输入图片描述

答案3

也可以使用 MetaPost 来完成,例如借助元对象包裹。

树是 MetaObj 处理的“对象”之一,并且以递归方式定义,就像本程序中的树一样:

t := _T(TCs)(TCs, _T(TCs)(TCs, _T(TCs)(TCs)));
...
t := _T(TCs)(_T(TCs)(_T(TCs)(TCs, _T(TCs)(TCs))));

_Tnew_Tree是创建(子)树的命令的快捷方式,也是TCs在当前节点放置实心圆的另一个快捷方式。

\documentclass{article}
\usepackage{luamplib}
  \everymplib{verbatimtex \leavevmode etex; 
    input metaobj
      setCurveDefaultOption("arrows")("draw");
      setObjectDefaultOption("Tree")("treenodehsize")(0);
      setObjectDefaultOption("Tree")("hbsep")(1.6cm);
      setObjectDefaultOption("Tree")("vsep")(.7cm);
      labeloffset := 2bp;
    beginfig(1);}
  \everyendmplib{endfig;}
\begin{document}
  \emph{Examples.}
  \begin{minipage}[t]{0.36\linewidth}
    \centering
    $T\big((p_1 \to (\perp \vee \neg (p_3)))\big)$;
    \par\bigskip
    \begin{mplibcode}
      t := _T(TCs)(TCs, _T(TCs)(TCs, _T(TCs)(TCs)));
      Obj(t).n = origin;
      ObjLabel.treeroot(Obj(t))(1)(btex $p_1$ etex) "labdir(bot)";
      ObjLabel.treeroot(Obj(t))(2,1)(btex $\perp$ etex) "labdir(bot)";
      ObjLabel.treeroot(Obj(t))(2,2,1)(btex $p_3$ etex) "labdir(bot)";
      ObjLabel.treeroot(Obj(t))(2,2)(btex $(\neg p_3)$ etex) "labdir(urt)";
      ObjLabel.treeroot(Obj(t))(2)(btex $(\perp \vee (\neg p_3))$ etex) "labdir(urt)";
      label.urt(btex $(p_1 \to (\perp \vee (\neg p_3)))$ etex, origin);
      draw_Obj(t);
    \end{mplibcode}
  \end{minipage}
  %
  \begin{minipage}[t]{0.36\linewidth}
    \centering
    $T\big(\neg(\neg(p_1 \wedge (\neg p_1))) \big)$
    \par\bigskip
    \begin{mplibcode}
      t := _T(TCs)(_T(TCs)(_T(TCs)(TCs, _T(TCs)(TCs))));
      Obj(t).n = origin shifted (5cm, 0);
      label.urt(btex $(\neg(\neg(p_1 \wedge (\neg p_1))))$ etex, Obj(t).n);
      ObjLabel.treeroot(Obj(t))(1)(btex $(\neg(p_1 \wedge (\neg p_1)))$ etex) "labdir(urt)";
      ObjLabel.treeroot(Obj(t))(1,1)(btex $(p_1 \wedge (\neg p_1))$ etex) "labdir(urt)";
      ObjLabel.treeroot(Obj(t))(1,1,1)(btex $p_1$ etex) "labdir(bot)";
      ObjLabel.treeroot(Obj(t))(1,1,2)(btex $(\neg p_1)$ etex) "labdir(urt)";
      ObjLabel.treeroot(Obj(t))(1,1,2,1)(btex $p_1$ etex) "labdir(bot)";
      draw_Obj(t);
    \end{mplibcode}
  \end{minipage}
\end{document}

使用 LuaLaTeX 排版。输出:

在此处输入图片描述

答案4

这是原始MWEAsymptote

在此处输入图片描述

这些树看起来像某种逻辑表达式的句法树,其中运算符 $\to$、$\vee$、$\wedge$、$\neg$ 和操作数 $p_1$、$p_3$ 和 $\perp$。

在示例文件中,testoptree.asy 树是通过手动分析表达式和分离运算符(作为字符串)及其左子表达式和右子表达式(子树)来递归定义的。非终端节点处的字符串标签是自动形成的。

//
// testoptree.asy 
//
import optree;
real w=9cm, h=0.618w; size(w,h);
string p1="p_1", p3="p_3", to="\to", perp="\perp", vee="\vee", neg="\neg", wedge="\wedge";

opTree T1=
opTree(
  opTree(p1),to,
  opTree(
    opTree(perp), vee,
    opTree(
      neg, opTree(p3)
    )
  )
);

opTree T2=
opTree(
  neg,
  opTree(
  neg,
    opTree(
      opTree(p1), wedge,
      opTree(
        neg, opTree(p1)
      )         
    ) 
  ) 
);

void drawNode(pair c){
  fill(circle(c,0.07),white);
  fill(circle(c,0.06),orange);
}

draw(T1,darkblue+1.2bp,drawNode);
draw(shift(4,0)*T2,darkblue+1.2bp,drawNode);

MWE使用下面显示的模块optree.asy

struct opTree{
  string sr;
  opTree left, right;
  pair root;
  void operator init(opTree left=null, string sr, opTree right=null){
    this.left=left;
    this.sr=sr;
    this.right=right;
  }
}

string operator cast(opTree T){
  if(T==null)return "";
  if(T.left==null && T.right==null){
    return " "+T.sr+" ";
  }else{  
    return "("+T.left+T.sr+T.right+")";
  }
}

opTree operator*(transform t,opTree T){
  if(T!=null){
    T.root=t*T.root;
    T.left=t*T.left;
    T.right=t*T.right;
  }
  return T;
}

typedef void DrawFunc(pair);

void draw(opTree T,pen linepen=currentpen, DrawFunc drawNode=null){
  real dx=0.5, dy=sqrt(3)/2;
  if(T!=null){
    if(T.left!=null && T.right!=null){ 
      T.left.root =T.root+(-dx,-dy); 
      T.right.root=T.root+( dx,-dy);
      draw(T.right.root--T.root--T.left.root,linepen);
    }
    if(T.left==null && T.right!=null ){ 
      T.right.root=T.root+(0,-dy);
      draw(T.root--T.right.root,linepen);
    }
    if(T.left!=null && T.right==null ){ 
      T.left.root =T.root+(0,-dy); 
      draw(T.root--T.left.root,linepen);
    }

    if(drawNode!=null) drawNode(T.root);

    if(T.left==null && T.right==null){
      label("$"+T.sr+"$",T.root,plain.S);
    }else{
      label("$"+T+"$",T.root,plain.NE);      
    }
    draw(T.left ,linepen,drawNode);
    draw(T.right,linepen,drawNode);
  }
}

要获取独立的testoptree.pdf,请运行:

asy -f pdf testoptree.asy

只要它在同一个文件夹中(或者是正在寻找文件的optree.asy一些标准文件夹)。asy

相关内容