diff options
author | Karl Berry <karl@freefriends.org> | 2014-12-02 00:55:36 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-12-02 00:55:36 +0000 |
commit | ab4c97bb1913e7167819b3e3c2688a0e5200f011 (patch) | |
tree | 3a92d1b788fa89ea4c49b249e57e80162208cb55 | |
parent | 5a51ac01bebab92f1bb7e8f4091a423e5ac6905d (diff) |
prftree (1dec14)
git-svn-id: svn://tug.org/texlive/trunk@35712 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/prftree/README | 9 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/prftree/prftreedoc.pdf | bin | 0 -> 267456 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/prftree/prftreedoc.tex | 1721 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/prftree/prftree.sty | 1046 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 2 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/prftree.tlpsrc | 0 |
7 files changed, 2778 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/prftree/README b/Master/texmf-dist/doc/latex/prftree/README new file mode 100644 index 00000000000..5c6a8ef263c --- /dev/null +++ b/Master/texmf-dist/doc/latex/prftree/README @@ -0,0 +1,9 @@ +The prftree package provides a package to write proof trees for +natural deduction calculi, sequent-like calculi, and similar. + +The package is composed by the filed +- prftree.sty: containing the LaTeX engine to typeset proof trees; +- prftreedoc.pdf: the human readable documentation for the package; +- prftreedoc.tex: the source code for the documentation. + +The package is distributed under the GNU General Public License. diff --git a/Master/texmf-dist/doc/latex/prftree/prftreedoc.pdf b/Master/texmf-dist/doc/latex/prftree/prftreedoc.pdf Binary files differnew file mode 100644 index 00000000000..ce700a53cce --- /dev/null +++ b/Master/texmf-dist/doc/latex/prftree/prftreedoc.pdf diff --git a/Master/texmf-dist/doc/latex/prftree/prftreedoc.tex b/Master/texmf-dist/doc/latex/prftree/prftreedoc.tex new file mode 100644 index 00000000000..8af679ea760 --- /dev/null +++ b/Master/texmf-dist/doc/latex/prftree/prftreedoc.tex @@ -0,0 +1,1721 @@ +\documentclass{amsart} +\usepackage[ND,SEQ]{prftree} +\usepackage{url} + +\setlength{\fboxsep}{0pt} + +\begin{document} +\title{Proof Trees in \LaTeX} +\date{} +\author{Marco Benini} +\address{Dipartimento di Scienza e Alta Tecnologia\\ + Universit\`a degli Studi dell'Insubria\\ + via Valleggio 11, I-22100 Como, Italy} +\email{marco.benini@uninsubria.it} +\urladdr{http://marcobenini.wordpress.com} +\maketitle + +% -------------------------- + +\section{Introduction}\label{sec:introduction} +Writing proofs in natural deduction or in similar, tree-like calculi, +is always a challenge: from the typographical point of view, these +proofs are complex objects that cannot be simply typeset using the +standard \LaTeX{} commands. Thus, many packages have been developed: +Sam Buss's \texttt{bussproofs.sty}, +\url{http://math.ucsd.edu/~sbuss/ResearchWeb/bussproofs/}; Makoto +Tatsuta's \texttt{proof.sty}, +\url{http://research.nii.ac.jp/~tatsuta/proof-sty.html}; and +\texttt{prooftree.sty} by Paul Taylor, +\url{http://mirror.ctan.org/macros/generic/proofs/taylor}. + +All these packages have their merits and weaknesses. For example, +Buss's package is extremely flexible but inference rules with more +than five assumptions cannot be directly typeset. On the other hand, +Tatsuta's package provides a very simple set of commands doing a +fine job, but customisation is very limited. Taylor's package provides +a natural syntax for writing proofs, but customisation is limited, and +the package has an expire date. + +The package presented in the following provides most of the features +which are already present in Buss's package, coupled with some new +ones. This package uses a syntax which is closer to Tatsuta's one, but +almost all the typesetting process is parametric, so that each bit of +a proof can be customised at will. + +The graphical appearance of a proof is similar to the one obtained +using Taylor's package, but the additional features allow to set up +the graphical output to follow the style of some of the standard +textbooks, e.g., A.S.~Troelstra and H.~Schwichtenberg, \textit{Basic + Proof Theory}, Cambridge University Press (2000). + +% -------------------------- +\clearpage +\section{Basic Commands}\label{sec:basic_commands} +The package is invoked by putting \verb|\usepackage{prfree.sty}| in +the preamble of the document, and installation reduces to put the file +\texttt{prftree.sty} somewhere in the \LaTeX{} search +path.\vspace{2ex} + +A proof tree constructs a box with the following internal structure: +\begin{center} + {\setlength{\unitlength}{1em} + \begin{picture}(31,6) + \put(7,4){\framebox(17,2){$\mbox{assumption}_1 \cdots + \mbox{assumption}_n$}} + \put(6,3){\line(1,0){19}} + \put(26,2){\framebox(5,2){rule name}} + \put(0,2){\framebox(5,2){label}} + \put(10,0){\framebox(11,2){conclusion}} + \end{picture}} +\end{center} +In turn, each assumption is typeset as a box which has usually the +shape of another proof tree, while the rule name and the label are +typeset in a text box, and the conclusion in a math box. The aspect of +the proof line is controlled by suitable options, as is the presence +of the rule name and of the label. Options cover other aspects of the +graphical rendering of a proof tree, as it will be explained +later. The basic command to build a proof tree is \verb|\prftree|. + +For example, the proof of $A \supset \neg\neg A$ in natural deduction +is: +\begin{displaymath} + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{displaymath} +This proof is generated by the following \LaTeX{} code: +\begin{verbatim} + \begin{displaymath} + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} + \end{displaymath} +\end{verbatim} + +In general, the syntax of the \verb|\prftree| command is: +\begin{displaymath} + \verb|\prftree|[\mbox{options}] \cdots + [\mbox{options}]\{\mbox{assumption}_1\} \cdots + \{\mbox{assumption}_n\}\{\mbox{conclusion}\} +\end{displaymath} +Assumptions are optional and there may be any number of them. Each +assumption may contain a proof tree, which is typeset +independently. The conclusion is mandatory, and it is supposed to be a +formula. Assumptions and the conclusion are typeset in a display style +math environment. Options control the way the proof is generated: in +the example, the \verb|r| option has been used to signal that the +first argument of \verb|\prftree| is the name of the inference rule. + +The available options are: +\begin{itemize} +\item\ [\textbf{r}], [\textbf{rule}], [\textbf{by rule}], + [\textbf{by}], [\textbf{right}]: the first argument after the + options is the rule name, which is typeset in text mode; +\item\ [\textbf{l}], [\textbf{left}], [\textbf{label}]: the first + argument after the options is the label of the rule, which is + typeset in text mode. If a rule name is present, the first argument + is the rule name, and the second one is the label; +\item\ [\textbf{straight}], [\textbf{straight line}], + [\textbf{straightline}]: makes the proof line solid; +\item\ [\textbf{dotted}], [\textbf{dotted line}], + [\textbf{dottedline}]: makes the proof line dotted; +\item\ [\textbf{dashed}], [\textbf{dashed line}], + [\textbf{dashedline}]: makes the proof line dashed; +\item\ [\textbf{f}], [\textbf{fancy}], [\textbf{fancy line}], + [\textbf{fancyline}]: the proof line will be fancy; +\item\ [\textbf{s}], [\textbf{single}], [\textbf{single line}], + [\textbf{singleline}]: makes the proof line single; +\item\ [\textbf{d}], [\textbf{double}], [\textbf{double line}], + [\textbf{doubleline}]: makes the proof line double; +\item\ [\textbf{noline}]: suppresses the proof line (prevails over all + other line options); +\item\ [\textbf{summary}]: renders the proof line as the summary + symbol (prevails over all other line options except \textbf{noline}). +\end{itemize} +By default the proof line is straight and single. Options may be +written in sequence, as in \verb|[r,f,d]|, which means that the proof +tree will have a rule name, and the proof line will be fancy and +double, or separately, as in \verb|[r][f][d]|, or even as a +combination, like \verb|[r][f,d]|. Options are evaluated +left-to-right, so \verb|[d,s]| is the same as \verb|[s]|, while +\verb|[noline,straight,d]| is the same as \verb|[noline]|. + +The conjunction introduction rule illustrates the various line +options\footnote{The reader is invited to look at the source code of + the documentation to see how these examples have been implemented.}: +\begin{displaymath} + \begin{array}{lcc@{\qquad}l} + \mbox{default (single straight)} & + \prftree{A}{B}{A \wedge B} & + \prftree[r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[straight]} \\ + \mbox{double straight} & + \prftree[d]{A}{B}{A \wedge B} & + \prftree[d,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[double,straight]} \\ + \mbox{single dotted} & + \prftree[dotted]{A}{B}{A \wedge B} & + \prftree[dotted,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[dotted]} \\ + \mbox{double dotted} & + \prftree[dotted,d]{A}{B}{A \wedge B} & + \prftree[dotted,d,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[double,dotted]} \\ + \mbox{single dashed} & + \prftree[dashed]{A}{B}{A \wedge B} & + \prftree[dashed,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[dashed]} \\ + \mbox{double dashed} & + \prftree[dashed,d]{A}{B}{A \wedge B} & + \prftree[dashed,d,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[double,dashed]} \\ + \mbox{single fancy} & + \prftree[f]{A}{B}{A \wedge B} & + \prftree[f,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[fancy]} \\ + \mbox{double fancy} & + \prftree[f,d]{A}{B}{A \wedge B} & + \prftree[f,d,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[double,fancy]} \\ + \mbox{noline} & + \prftree[noline]{A}{B}{A \wedge B} & + \prftree[noline,r]{$\wedge$I}{A}{B}{A \wedge B} & + \texttt{[noline]} + \end{array} +\end{displaymath}\vspace{1ex} + +An assumption is a special proof tree, built by the command: +\begin{displaymath} + \verb|\prfassumption|\{\text{formula}\} +\end{displaymath} +Similarly, a bounded assumption is produced by the command: +\begin{displaymath} + \verb|\prfboundedassumption|\{\text{formula}\} +\end{displaymath} +as in the previous example. + +Although it is possible to type assumptions directly as argument of +\verb|\prftree|, it is better to use the commands above: as explained +later, since a proof tree is a box with an internal structure, the +assumption commands take care of building this structure +appropriately, while the direct typing does not, which may produce +unexpected results.\vspace{2ex} + +Similarly, axioms are produced by the commands +\begin{displaymath} + \verb|\prfaxiom|\{\mbox{axiom}\} +\end{displaymath} +and +\begin{displaymath} + \verb|\prfbyaxiom|\{\mbox{name}\}\{\mbox{axiom}\} +\end{displaymath} +For example, the axiom stating that equality is reflexive, is +\begin{displaymath} + \begin{array}{cc} + \prfaxiom{\forall x\, x = x} & + \prfbyaxiom{refl}{\forall x\, x = x} + \end{array} +\end{displaymath} +and they are generated by the \LaTeX{} code +\begin{displaymath} + \begin{array}{cc} + \verb|\prfaxiom{\forall x\, x = x}|& + \verb|\prfbyaxiom{refl}{\forall x\, x = x}| + \end{array} +\end{displaymath}\vspace{-.2ex} + +Finally, a proof summary is used to summarise a proof. The +corresponding command is: +\begin{displaymath} + \verb|\prfsummary|[\mbox{name}]\{\mbox{assumption}_1\} \cdots + \{\mbox{assumption}_n\}\{\mbox{conclusion}\} +\end{displaymath} +The name of the proof is optional, while the assumptions and the +conclusion are treated as in \verb|\prftree|. When present, the proof +name is typeset in text mode. + +For example, \verb|\prfsummary{\forall x\, x = x}| produces +\begin{displaymath} + \prfsummary{\forall x\, x = x} +\end{displaymath} +while \verb|\prfsummary[name]{A(x)}{B(y)}{B(y) \wedge A(x)}| gives +\begin{displaymath} + \prfsummary[name]{A(x)}{B(y)}{B(y) \wedge A(x)} +\end{displaymath}\vspace{-.2ex} + +In general, a proof tree is a \TeX{} box containing all the pieces of +the tree, with strict bounds: for example, +\begin{displaymath} + \fbox{\prfsummary[name]{A(x)}{B(y)}{B(y) \wedge A(x)}} +\end{displaymath} + +% -------------------------- +\clearpage +\section{Parameters}\label{sec:parameters} +A number of parameters may be used to control the typesetting of proof +trees. They may be changed globally or locally, following the usual +scoping rules of \TeX{}. In this respect, remember that each +assumption is typeset independently, so parameters may be changed on a +sub-proof basis, as will be done in most examples.\vspace{2ex} + +There are various \TeX{} dimensions that influence how proofs are +constructed: +\begin{itemize} +\item\ \verb|\prflinepad| (default 0.3ex): the space between the + bottom line of assumptions and the proof line, and also the space + between the proof line and the top of the conclusion; +\item\ \verb|\prflineextra| (default 0.3em): the length which extends + on the left and on the right the proof line so that it is slightly + longer than the largest between the conclusion and the list of + (direct) assumptions; +\item\ \verb|\prflinethickness| (default 0.2pt): the thickness of the + proof line; +\item\ \verb|\prfemptylinethickness| (default 4 times the line + thickness): in the rare case when the line is empty, but there are + assumptions, this is the distance between the assumptions and the + conclusion; +\item\ \verb|\prfrulenameskip| (default 0.2em): the space between the + proof line and the rule name; +\item\ \verb|\prflabelskip| (default 0.2em): the space between the + proof label and the proof line; +\item\ \verb|\prfinterspace| (default .6em): the space between two + subsequent assumptions in the assumption list; +\item\ \verb|\prfdoublelineinterspace| (default 1.2pt): the space + between the two lines of a double line. +\end{itemize} + +For example, +\begin{displaymath} + \prflinepad=.7ex + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{displaymath} +is typeset by +\begin{verbatim} + \prflinepad=.7ex + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{verbatim} + +Similarly, \verb|\prflineextra=-.4em| and \verb|\prfrulenameskip=.8em| +produce: +\begin{displaymath} + {\prflineextra=-.4em + \prfrulenameskip=.8em + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A}} +\end{displaymath} + +Also, \verb|\prflinethickness=3pt| and +\verb|\prfdoublelineinterspace=2pt| in the upper sub-proof generate: +\begin{displaymath} + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prflinethickness=3pt + \prfdoublelineinterspace=2pt + \prftree[r,d]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{displaymath} +The corresponding code is +\begin{verbatim} + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prflinethickness=3pt + \prfdoublelineinterspace=2pt + \prftree[r,d]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{verbatim} + +Line thickness does not affect dashed, dotted, and fancy lines, but +interline space does: in the example, +\verb|\prfdoublelineinterspace=4pt| on a fancy line produces +\begin{displaymath} + \prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prfdoublelineinterspace=4pt + \prftree[r,d,f]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{displaymath}\vspace{.2ex} + +Fancy lines are drawn by the \verb|\prffancyline| command. This can be +redefined: as a guideline, the package defines it as +\begin{verbatim} + \def\prffancyline{\cleaders\hbox to .63em% + {\hss\raisebox{-.5ex}[.2ex][0pt]{$\sim$}\hss}\hfill} +\end{verbatim}\vspace{2ex} + +Label spacing works exactly as rule name spacing. Actually, it is +possible to have a proof with both a label and a rule name: +\begin{displaymath} + \prftree[r]{$\supset$I} + {\prflabelskip=.7em + \prftree[r,l]{$\supset$I} + {[\textsl{$\bot\mathrm{E}$ will not work here!}]} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{displaymath} +which has been typeset by +\begin{verbatim} + \prftree[r]{$\supset$I} + {\prflabelskip=.7em + \prftree[r,l]{$\supset$I} + {[\textsl{$\bot\mathrm{E}$ will not work here!}]} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} +\end{verbatim}\vspace{2ex} + +The \verb|\prfinterspace| controls the distance between +assumptions. Specifically, this is the space between the \emph{boxes} +containing two assumptions. + +Consider the following example +\begin{displaymath} + \prftree + {\prftree + {\prftree + {\prftree + {\prftree + {\prfboundedassumption{A \rightarrow (B \rightarrow C)}} + {\prfboundedassumption{A}} + {B \rightarrow C}} + {\prftree + {\prfboundedassumption{A \rightarrow B}} + {\prfboundedassumption{A}} + {B}} + {C}} + {A \rightarrow C}} + {(A \rightarrow B) \rightarrow (A \rightarrow C)}} + {(A \rightarrow (B \rightarrow C)) \rightarrow ((A \rightarrow B) + \rightarrow (A \rightarrow C))} +\end{displaymath} +Although the assumptions in the top line are well spaced, the two +sub-proofs on the top are too close. This can be corrected in two +different ways: by putting an explicit space, via \verb|\hspace|, in +front of the second sub-proof, or after the first +sub-proof---remember, they are just boxes +\begin{displaymath} + \prftree + {\prftree + {\prftree + {\prftree + {\prftree + {\prfboundedassumption{A \rightarrow (B \rightarrow C)}} + {\prfboundedassumption{A}} + {B \rightarrow C}\hspace{1.5em}} + {\prftree + {\prfboundedassumption{A \rightarrow B}} + {\prfboundedassumption{A}} + {B}} + {C}} + {A \rightarrow C}} + {(A \rightarrow B) \rightarrow (A \rightarrow C)}} + {(A \rightarrow (B \rightarrow C)) \rightarrow ((A \rightarrow B) + \rightarrow (A \rightarrow C))} +\end{displaymath} +otherwise, putting $\verb|\prfinterspace|=1.5\mathrm{em}$ before the +sub-proof whose conclusion is $C$, one obtains the more pleasant +\begin{displaymath} + \prftree + {\prftree + {\prftree + {\prfinterspace=1.5em + \prftree + {\prftree + {\prfboundedassumption{A \rightarrow (B \rightarrow C)}} + {\prfboundedassumption{A}} + {B \rightarrow C}} + {\prftree + {\prfboundedassumption{A \rightarrow B}} + {\prfboundedassumption{A}} + {B}} + {C}} + {A \rightarrow C}} + {(A \rightarrow B) \rightarrow (A \rightarrow C)}} + {(A \rightarrow (B \rightarrow C)) \rightarrow ((A \rightarrow B) + \rightarrow (A \rightarrow C))} +\end{displaymath}\vspace{.2ex} + +The rendering of bounded assumptions is modified by +\verb|\prfboundedstyle|. When $\verb|\prfboundedstyle| = 0$, the +format of the assumption is $[\mbox{formula}]$, which is the default +behaviour; with $\verb|\prfboundedstyle| = 1$, the formula is +cancelled by a horizontal line; with $\verb|\prfboundedstyle| > 1$, +the custom \verb|\prfdiscargedassumption| command is invoked: +\begin{displaymath} + \begin{array}{c@{\qquad}c@{\qquad}c} + \prfboundedassumption{A(x)} & + {\prfboundedstyle=1\prfboundedassumption{A(x)}} & + {\prfboundedstyle=2\prfboundedassumption{A(x)}} + \end{array} +\end{displaymath} + +The \verb|\prfdiscargedassumption| can be freely redefined. The +package provides a reference implementation: +\begin{verbatim} + \def\prfdiscargedassumption#1{\left\langle{#1}\right\rangle} +\end{verbatim}\vspace{2ex} + +Proof summaries are drawn according to \verb|\prfsummarystyle|. The +default value is $0$, which produces a vertical dotted line. Setting +$\verb|\prfsummarystyle| = 1$ produces a huge $\Pi$, while +$\verb|\prfsummarystyle| = 2$ produces a $\prod$. The value $3$ uses a +$\mathcal{D}$ as the derivation symbol. Values greater than $3$ force +the summary to be rendered by the \verb|\prffancysummarybox| command. +\begin{displaymath} + \begin{array}{@{}c@{\quad}c@{\qquad}c@{\qquad}c@{}} + \verb|\prfsummarystyle| = 0 & + {\prfsummary{\forall x.\, x = x}} & + {\prfsummary{B(x)}{A(x)}} & + {\prfsummary[name]{A(y)}{D(x)}{B(x) \wedge C(x)}} \\[2ex] + \verb|\prfsummarystyle| = 1 & + {\prfsummarystyle1\prfsummary{\forall x.\, x = x}} & + {\prfsummarystyle1\prfsummary{B(x)}{A(x)}} & + {\prfsummarystyle1\prfsummary[name]{A(y)}{D(x)}{B(x) \wedge + C(x)}} \\[1ex] + \verb|\prfsummarystyle| = 2 & + {\prfsummarystyle2\prfsummary{\forall x.\, x = x}} & + {\prfsummarystyle2\prfsummary{B(x)}{A(x)}} & + {\prfsummarystyle2\prfsummary[name]{A(y)}{D(x)}{B(x) \wedge + C(x)}} \\[1ex] + \verb|\prfsummarystyle| = 3 & + {\prfsummarystyle3\prfsummary{\forall x.\, x = x}} & + {\prfsummarystyle3\prfsummary{B(x)}{A(x)}} & + {\prfsummarystyle3\prfsummary[name]{A(y)}{D(x)}{B(x) \wedge C(x)}} + \\[1ex] + \verb|\prfsummarystyle| = 4 & + {\prfsummarystyle4\prfsummary{\forall x.\, x = x}} & + {\prfsummarystyle4\prfsummary{B(x)}{A(x)}} & + {\prfsummarystyle4\prfsummary[name]{A(y)}{D(x)}{B(x) \wedge C(x)}} + \end{array} +\end{displaymath} + +The fancy summary box is composed by the \verb|\prffancysummarybox| +command. This can be modified at will. The package defines it as +\begin{verbatim} + \newbox\prf@@fancysummarybox\newdimen\prf@@fancysymmarylen + \def\prffancysummarybox{% + \sbox{\prf@@fancysummarybox}{\Huge$\bigtriangledown$}% + \prf@@fancysymmarylen\ht\prf@@fancysummarybox% + \advance\prf@@fancysymmarylen\dp\prf@@fancysummarybox% + \sbox{\prf@@fancysummarybox}{% + \raisebox{.25\prf@@fancysymmarylen}[.8\prf@@fancysymmarylen]% + [0pt]{\usebox{\prf@@fancysummarybox}}}% + \prf@@fancysymmarylen\wd\prf@summary@label% + \ifdim\prf@@fancysymmarylen>\z@\relax% + \prf@@fancysymmarylen\wd\prf@@fancysummarybox% + \wd\prf@summary@label.4em% + \hbox to\prf@@fancysymmarylen{% + \usebox\prf@@fancysummarybox}\kern-.4em% + \box\prf@summary@label% + \else\usebox\prf@@fancysummarybox\fi} +\end{verbatim}\vspace{2ex} + +The assumptions, conclusions, labels, and rule names are drawn using +the following commands, which may be redefined: +\begin{verbatim} + \def\prfConclusionBox#1{\hbox% + {$\displaystyle\begingroup#1\endgroup\mathstrut$}} + \def\prfAssumptionBox#1{\hbox% + {$\displaystyle\begingroup#1\endgroup\mathstrut$}} + \def\prfRuleNameBox#1{\hbox{\begingroup#1\endgroup\strut}} + \def\prfLabelBox#1{\hbox{\begingroup#1\endgroup\strut}} +\end{verbatim} +It is not advisable to change these commands in a radical way, unless +one understands how the graphical engine works. + +% ------------------------------------- +\clearpage +\section{Labels and References}\label{sec:references} +As discharged assumptions are often hard to track in a proof, the +package provides a mechanism to label them and to reference them +inside a proof tree. A reference is made up of three pieces: the +\emph{label}, which is the name to denote the reference inside the +text, the \emph{reference value}, which is the value denoted by the +label, and the \emph{anchor}, which is the graphical rendering of the +value aside the labelled point of the proof. + +For example, +\begin{displaymath} + \begin{prooftree} + \prftree[r]{$\supset\mathrm{I}_{\prfref<assum:A>}$} + {\prftree[r]{$\supset\mathrm{I}_{\prfref<assum:not_A>}$} + {\prftree[r]{$\supset$E} + {\prfboundedassumption<assum:A>{A}} + {\prfboundedassumption<assum:not_A>{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} + \end{prooftree} +\end{displaymath} +is generated by the following code +\begin{verbatim} + \begin{prooftree} + \prftree[r]{$\supset\mathrm{I}_{\prfref<assum:A>}$} + {\prftree[r]{$\supset\mathrm{I}_{\prfref<assum:not_A>}$} + {\prftree[r]{$\supset$E} + {\prfboundedassumption<assum:A>{A}} + {\prfboundedassumption<assum:not_A>{\neg A}} + {\bot}} + {\neg\neg A}} + {A \supset \neg\neg A} + \end{prooftree} +\end{verbatim} +The labels are \verb|assum:A| and \verb|assum:not_A|, the reference +values are $1$ and $2$, respectively, and the anchors are these values +on the discharged assumptions on the top of the proof. The references +to these labels are the values in the rule names.\vspace{2ex} + +The \verb|prooftree| environment delimits the scope of labels: the +\verb|\end{prooftree}| declaration makes the labels still available +for reference, but numbering of new labels will restart from +$1$. Enclosing a proof tree in a \verb|prooftree| environment is not +mandatory: in such case, labels will be global to the +document.\vspace{2ex} + +Sometimes, labels require two compilation steps to be correctly +generated: in fact, as \LaTeX{} labels, forward references may be +undefined in the first compilation step. The package issues a warning +in this case, and display a \verb|??| for the invalid reference. Also, +notice how the assumption reference mechanism is analogous to \LaTeX{} +labels, but it is independent from it.\vspace{2ex} + +A reference to a label is made by the +$\verb|\prfref|\langle\mathrm{label}\rangle$ command: its argument is +a label, i.e., a string of text following the same rules as the +argument of the \LaTeX{} \verb|\label| command. As in the \verb|\ref| +command, the resulting value has no formatting.\vspace{2ex} + +A labelled assumption is generated by the following commands: +\begin{displaymath} + \begin{array}{l} + \verb|\prfassumption|\langle[\mathrm{option}]\mathrm{label}\rangle + \{\mathrm{assumption}\} + \\ + \verb|\prfboundedassumption|\langle[\mathrm{option}] + \mathrm{label}\rangle\{\mathrm{assumption}\} + \end{array} +\end{displaymath} +The first one acts as \verb|\prfassumption| but also declares the +assumption label and decorates the assumption text with the +anchor. The second one does the same on bounded assumptions. + +The generation of labels is controlled by the option value: +\begin{itemize} +\item \textbf{n}, \textbf{number}, \textbf{arabic}: generates a number + (default); +\item \textbf{r}, \textbf{roman}: generates a lowercase roman number; +\item \textbf{R}, \textbf{Roman}: generates an uppercase + roman number; +\item \textbf{a}, \textbf{alph}, \textbf{alpha}, \textbf{alphabetic}: + produces a lowercase letter; +\item \textbf{A}, \textbf{Alph}, \textbf{Alpha}, \textbf{Alphabetic}: + produces an uppercase letter; +\item \textbf{f}, \textbf{s}, \textbf{function}, \textbf{symbol}, + \textbf{function symbol}: produces a footnote symbol, as in + Section~C.8.4 of Lamport's, \textit{\LaTeX: A document preparation + system}; +\item \textbf{l}, \textbf{label}: tells that the label has not to be + defined. This is used to generate a labelled assumption sharing the + label with another one, which declares the value and the format. +\end{itemize} +Except for \textbf{l} and \textbf{label}, all the options are used to +format the anchor following the standard \LaTeX{} way available for +counters. No multiple options are allowed. + +For example, the disjunction elimination rule is a perfect way to +illustrate the reason behind the \textbf{label} option, i.e., the need +to discharge a pair of assumptions: +\begin{displaymath} + \begin{prooftree} + \prfinterspace=1.2em + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orE>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<assum:orE>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orE>{B}}{C}}{C} + \end{prooftree} +\end{displaymath} +\begin{verbatim} + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orE>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<assum:orE>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orE>{B}}{C}}{C} +\end{verbatim} + +If a label is declared more than once, a warning is issued when the +\textbf{label} option is not used: although this is not a mistake, it +may indicate that a label is reused when it should not. + +The same example can be used to show how the other options work: +\begin{displaymath} + \begin{array}{ccc} + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEn>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[n]assum:orEn>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEn>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEr>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[r]assum:orEr>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEr>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orER>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[R]assum:orER>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orER>{B}}{C}} + {C} + \end{prooftree} \\ + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEa>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[a]assum:orEa>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEa>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEA>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[A]assum:orEA>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEA>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEf>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[f]assum:orEf>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEf>{B}}{C}} + {C} + \end{prooftree} + \end{array} +\end{displaymath} + +Also, as the \verb|\prfboundedstyle| varies, the resulting proof trees +are: +\begin{displaymath} + \begin{array}{ccc} + \begin{prooftree} + \prfboundedstyle=0 + \prfsummarystyle=4 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:AorE>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<assum:AorE>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:AorE>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfboundedstyle=1 + \prfsummarystyle=4 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:BorE>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<assum:BorE>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:BorE>{B}}{C}} + {C} + \end{prooftree} & + \begin{prooftree} + \prfboundedstyle=2 + \prfsummarystyle=4 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:CorE>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<assum:CorE>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:CorE>{B}}{C}} + {C} + \end{prooftree} + \end{array} +\end{displaymath}\vspace{.2ex} + +The \verb|prfassumptioncounter| is the \LaTeX{} counter used to +generate the assumption values. It contains the last used value, and +initially, it is set to $0$. By modifying its value, e.g., to +\verb|\setcounter{prfassumptioncounter}{1}|, +\begin{displaymath} + \begin{prooftree} + \setcounter{prfassumptioncounter}{1} + \prfsummarystyle=2 + \prftree[r]{$\vee\mathrm{E}_{\prfref<assum:orEff>}$} + {\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, + \prfboundedassumption<[f]assum:orEff>{A}}{C}} + {\prfsummary{\Gamma, + \prfboundedassumption<[l]assum:orEff>{B}}{C}} + {C} + \end{prooftree} +\end{displaymath}\vspace{.2ex} + +A labelled assumption box is graphically constructed by the package +command \verb|\prflabelledassumptionbox| which can be redefined if +needed. It takes two arguments: the assumption and the anchor. Its +standard definition is +\begin{verbatim} + \def\prflabelledassumptionbox#1#2{% + \setbox\prf@fancybox\hbox{${#1}$}% + \prf@tmp\wd\prf@fancybox% + \setbox\prf@fancybox\hbox{$\box\prf@fancybox^{#2}$}% + \wd\prf@fancybox\prf@tmp% + \prf@assumption{\box\prf@fancybox}} +\end{verbatim} + +Moreover, also a labelled and bounded assumption is graphically +rendered by the same command. There is just one exception: when +$\verb|\prfboundedstyle| > 1$. In fact, since that style is +controlled by a command that can be redefined, the same must hold for +references in that style. The command which is called in this case is +\verb|\prflabelleddiscargedassumption| which can be redefined if +needed; its standard definition in the package is +\begin{verbatim} + \def\prflabelleddiscargedassumption#1#2{% + \prflabelledassumptionbox{\left\langle{#1}\right\rangle}{#2}} +\end{verbatim}\vspace{2ex} + +Also proof summaries can be labelled and referenced. The syntax +extends the \verb|\prfsummary| command: +\begin{displaymath} + \verb|\prfsummary|\langle[\mathrm{option}]\mathrm{label}\rangle + [\mathrm{name}]\{\mathrm{assumption}1\} \cdots + \{\mathrm{assumption}_n\}\{\mathrm{conclusion}\} +\end{displaymath} +The reference argument works in the same way as the corresponding one +for assumptions, and the options are the same. + +\begin{displaymath} + \setcounter{prfsummarycounter}{0} + \begin{array}{c@{\qquad}c@{\qquad}c@{\qquad}c@{\qquad}c} + {\prfsummarystyle=0 + \prfsummary<proof:a0>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<proof:a1>{A}{B}{A \wedge B}} & + {\prfsummarystyle=2 + \prfsummary<proof:a2>{A}{B}{A \wedge B}} & + {\prfsummarystyle=3 + \prfsummary<proof:a3>{A}{B}{A \wedge B}} & + {\prfsummarystyle=4 + \prfsummary<proof:a4>{A}{B}{A \wedge B}} + \end{array} +\end{displaymath} + +These examples have been generated by the following code snippet: +\begin{verbatim} + {\prfsummarystyle=X + \prfsummary<proof:aX>{A}{B}{A \wedge B}} +\end{verbatim} + +The \verb|[option]| part of the label specification is optional, and +it works exactly as the option field of labelled assumptions. This is +best illustrated by an example: +\begin{displaymath} + \setcounter{prfsummarycounter}{0} + \begin{array}{cccc} + {\prfsummarystyle=1 + \prfsummary<[r]proof:b1>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[R]proof:b2>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[f]proof:b3>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[a]proof:b4>{A}{B}{A \wedge B}} \\ & + {\prfsummarystyle=1 + \prfsummary<[A]proof:b5>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b3>{A}{B}{A \wedge B}} & + \end{array} +\end{displaymath} + +These examples have been generated by the following code snippet: +\begin{verbatim} + {\prfsummarystyle=1 + \prfsummary<[r]proof:bX>{A}{B}{A \wedge B}} +\end{verbatim} +and the last line uses the \verb|label| option.\vspace{2ex} + +The value of the summary labelling is controlled by the +\verb|prfsummarycounter| counter, which is initially $0$ and contains +the last used value. + +% ------------------------------------- +\clearpage +\section{Simplified Commands}\label{sec:simplified_commands} +The basic commands illustrated so far allow to control proof trees in +all aspects, but they tend to be verbose in practise. Thus, a number +of abbreviations are provided to make handier the writing of proofs. + +Since they may collide with other packages, these macros are activated +by suitable options. By loading the package as +\verb|\usepackage[ND]{prftree.sty}|, the following abbreviations are +available, which correspond to the inference rule of natural deduction +calculi: +\begin{itemize} +\item \verb|\NDA|: assumption; +\item \verb|\NDAL|: labelled assumption; +\item \verb|\NDD|: bounded assumption; +\item \verb|\NDDL|: labelled bounded assumption; +\item \verb|\NDP|: generic proof tree; +\item \verb|\NDANDI|: conjunction introduction; +\item \verb|\NDANDER|: conjunction elimination, right; +\item \verb|\NDANDEL|: conjunction elimination, left; +\item \verb|\NDANDE|: conjunction elimination, unspecified; +\item \verb|\NDIMPI|: implication introduction; +\item \verb|\NDIMPIL|: implication introduction with the label of the + discharged assumption; +\item \verb|\NDIMPE|: implication elimination; +\item \verb|\NDORIR|: disjunction introduction, right; +\item \verb|\NDORIL|: disjunction introduction, left; +\item \verb|\NDORI|: disjunction introduction, unspecified; +\item \verb|\NDORE|: disjunction elimination; +\item \verb|\NDOREL|: disjunction elimination with the label of the + discharged assumptions; +\item \verb|\NDALLI|: universal quantifier introduction; +\item \verb|\NDALLE|: universal quantifier elimination; +\item \verb|\NDEXI|: existential quantifier introduction; +\item \verb|\NDEXE|: existential quantifier elimination; +\item \verb|\NDEXE|: existential quantifier elimination with the label + of the discharged assumption; +\item \verb|\NDTI|: truth introduction; +\item \verb|\NDFE|: falsity elimination; +\item \verb|\NDLEM|: Law of Excluded Middle. +\end{itemize} + +For example, the proof +\begin{displaymath} + \begin{prooftree} + \NDOREL{simp:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]simp:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{simp:notnotA} + {\NDFE{\NDIMPE{\NDDL{simp:notnotA}{\neg\neg A}} + {\NDDL{simp:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} + \end{prooftree} +\end{displaymath} +is typeset in abbreviated form by the following code +\begin{verbatim} + \NDOREL{simp:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]simp:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{simp:notnotA} + {\NDFE{\NDIMPE{\NDDL{simp:notnotA}{\neg\neg A}} + {\NDDL{simp:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{verbatim}\vspace{2ex} + +Similarly, by loading the package as +\verb|\usepackage[SEQ]{prooftree.sty}|, the following abbreviations +are available, which roughly correspond to the inference rule of +sequent calculi: +\begin{itemize} +\item \verb|\SEQA|: assumption; +\item \verb|\SEQD|: bounded assumption; +\item \verb|\SEQP|: generic proof; +\item \verb|\SEQAX|: axiom rule; +\item \verb|\SEQLF|: left falsity; +\item \verb|\SEQLW|: left weakening; +\item \verb|\SEQRW|: right weakening; +\item \verb|\SEQLC|: left contraction; +\item \verb|\SEQRC|: right contraction; +\item \verb|\SEQLAND|: left conjunction; +\item \verb|\SEQRAND|: right conjunction; +\item \verb|\SEQLOR|: left disjunction; +\item \verb|\SEQROR|: right disjunction; +\item \verb|\SEQLIMP|: left implication; +\item \verb|\SEQRIMP|: right implication; +\item \verb|\SEQLALL|: left universal quantification; +\item \verb|\SEQRALL|: right universal quantification; +\item \verb|\SEQLEX|: left existential quantification; +\item \verb|\SEQREX|: right existential quantification; +\item \verb|\SEQCUT|: cut rule. +\end{itemize} + +One can load the package with both options at the same +time.\vspace{2ex} + +Since the implication symbol is usually represented either as +$\rightarrow$ or as $\supset$, the package allows to choose which +representation to use. By default, implication is $\rightarrow$, but +loading the package with the \verb|[IMP]| option switches to +$\supset$. The same effect is obtained by the commands +\verb|\prfIMPOptiontrue| (implication is $\supset$) and +\verb|prfIMPOptionfalse| (implication is $\rightarrow$). + +Of course, the reader is encouraged to develop her own abbreviations +starting from the provided ones. + +% ------------------------------------- +\clearpage +\section{Hints and Tricks}\label{sec:hints_and_tricks} +This section shows a few hints and tricks to use the package at its +best.\vspace{2ex} + +Consider the proof: +\begin{displaymath} + \begin{prooftree} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{a:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} + \end{prooftree} +\end{displaymath} +the space between the axiom and the sub-proof of the positive case is +visually much less than the space between the positive and the +negative cases. Looking at boxes, the space is exactly the same, but +the perception is that spacing is wrong. + +We can correct this perception in two distinct ways: by adding space +between the axiom and the positive case; or, conversely, by moving the +negative case closer to the positive one. + +The first strategy yields: +\begin{displaymath} + \begin{prooftree} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}\hspace{.8em}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} + \end{prooftree} +\end{displaymath} +and this effect is given by adding an appropriate \verb|\hspace| after +the axiom, as in +\begin{verbatim} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}\hspace{.4em}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{verbatim} + +Adding the same space in front of the positive case is equivalent. + +The second strategy yields: +\begin{displaymath} + \begin{prooftree} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\hspace{-.4em}\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} + \end{prooftree} +\end{displaymath} +Again, this is obtained by adding a negative \verb|hspace| after the +positive case, or, equivalently, before the negative one: +\begin{verbatim} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\hspace{-.8em}\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{verbatim} + +In general, to make a wide proof \emph{compact}, one can appropriately +add negative spaces in front of sub-proofs so to make them closer and +letting them to overlap as boxes, but not visually, thus \emph{tiling} +the space.\vspace{2ex} + +Since proof trees are boxes, it is easy to align them on need. For +example the following proof tree, with the bounding box put in +evidence +\begin{displaymath} + \fbox{\prfsummarystyle=1 + \prfsummary{A}{B}{A \wedge B}} +\end{displaymath} +can be used wherever a box may appear. In the flow of text, it will +look like \fbox{\prfsummarystyle=1\prfsummary{A}{B}{A \wedge B}}, so +that the conclusion is aligned with the baseline. This makes easier to +align proof trees, as in +\begin{center} + \fbox{\prfsummarystyle=1 + \prfsummary{f}{g}{f \wedge g}}\qquad + \fbox{$\begin{prooftree} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\hspace{-.4em}\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} + \end{prooftree}$} +\end{center} +since this is the natural way to put proofs side by side: +\begin{verbatim} + \fbox{\prfsummarystyle=1 + \prfsummary{f}{g}{f \wedge g}}\qquad + \fbox{$ + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\hspace{-.4em}\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A}$} +\end{verbatim} + +But, if really one has to include a proof tree in the flow of text, it +is slightly better to vertically centre the box, as in +\fbox{$\vcenter{\prfsummary{A}{B}{A \wedge B}}$}. This is obtained by +\begin{verbatim} + $\vcenter{\prfsummary{A}{B}{A \wedge B}}$ +\end{verbatim} + +Of course, the result is not pleasant, because rows are far apart, +which is unavoidable because of the height of the proof tree. The +same principle applies also to arrays of proof trees: +\begin{displaymath} + \begin{array}{lcccc} + \text{some text} & + \setcounter{prfsummarycounter}{0} + \setcounter{prfassumptioncounter}{0} + {\prfsummarystyle=1 + \prfsummary<[l]proof:b1>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b2>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b3>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b4>{A}{B}{A \wedge B}} + \end{array} +\end{displaymath} +\begin{verbatim} + \begin{array}{lcccc} + \text{some text} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b1>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b2>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b3>{A}{B}{A \wedge B}} & + {\prfsummarystyle=1 + \prfsummary<[l]proof:b4>{A}{B}{A \wedge B}} + \end{array} +\end{verbatim} +vertically aligns the cells to their baselines. + +On the contrary +\begin{displaymath} + \begin{array}{lcccc} + \text{some text} & + \setcounter{prfsummarycounter}{0} + \setcounter{prfassumptioncounter}{0} + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b1>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b2>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b3>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b4>{A}{B}{A \wedge B}} + \end{array} +\end{displaymath} +is much better, and it is obtained by +\begin{verbatim} + \begin{array}{lcccc} + \text{some text} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b1>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b2>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b3>{A}{B}{A \wedge B}} & + \vcenter{\prfsummarystyle=1 + \prfsummary<[l]proof:b4>{A}{B}{A \wedge B}} + \end{array} +\end{verbatim}\vspace{2ex} + +The labelling of proof summaries is useful when a proof is very large +and there is the need to split it. The strategy is to select some +sub-proofs and to show them as summaries: instead of writing +\begin{displaymath} + \setcounter{prfsummarycounter}{0} + \setcounter{prfassumptioncounter}{0} + \NDOREL{a:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]a:notA}{A}}{\neg\neg A \supset A}} + {\NDIMPIL{a:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]a:notnotA}{\neg\neg A}} + {\NDDL{[l]a:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{displaymath} +we may consider to define +\begin{displaymath} + \setcounter{prfsummarycounter}{0} + \setcounter{prfassumptioncounter}{0} + \mbox{Let } + \vcenter{\vbox{\prfsummary<s:abbrev> + {\NDDL{s:notnotA}{\neg\neg A}} + {\NDAL{s:notA}{\neg A}} + {\neg\neg A \supset A}}} + \equiv + \vcenter{\hbox{$\NDIMPIL{s:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]s:notnotA}{\neg\neg A}} + {\NDAL{[l]s:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}$}} +\end{displaymath} +allowing to abbreviate the whole proof as +\begin{displaymath} + \NDOREL{s:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]s:notA}{A}}{\neg\neg A \supset A}} + {\prfsummary<s:abbrev> + {\NDDL{[l]s:notnotA}{\neg\neg A}} + {\NDDL{[l]s:notA}{\neg A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{displaymath} + +The corresponding \LaTeX{} code is +\begin{verbatim} + \setcounter{prfsummarycounter}{0} + \setcounter{prfassumptioncounter}{0} + \mbox{Let } + \vcenter{\vbox{\prfsummary<s:abbrev> + {\NDDL{s:notnotA}{\neg\neg A}} + {\NDAL{s:notA}{\neg A}} + {\neg\neg A \supset A}}} + \equiv + \vcenter{\hbox{$\NDIMPIL{s:notnotA} + {\NDFE{\NDIMPE{\NDDL{[l]s:notnotA}{\neg\neg A}} + {\NDAL{[l]s:notA}{\neg A}}{\bot}}{A}} + {\neg\neg A \supset A}$}} +\end{verbatim} +for the definition of the proof summary, and +\begin{verbatim} + \NDOREL{s:notA}{\NDLEM{A \vee \neg A}} + {\NDIMPI{\NDDL{[l]s:notA}{A}}{\neg\neg A \supset A}} + {\prfsummary<s:abbrev> + {\NDDL{[l]s:notnotA}{\neg\neg A}} + {\NDDL{[l]s:notA}{\neg A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{verbatim} +for its use. + +% ------------------------------------- +\clearpage +\section{More Examples}\label{sec:examples} +This section shows a number of examples illustrating the package. See +the previous sections for the description of the features.\vspace{2ex} + +The disjunction elimination rule, with various line options: +\begin{displaymath} + \begin{array}{@{}ccc@{}} + {\prfsummarystyle=1 + \prftree{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[d]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r][d]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l][d]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[dotted]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r,dotted]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l,dotted]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[d,dotted]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r,d,dotted]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l,d,dotted]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[dashed]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r,dashed]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l,dashed]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[d,dashed]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[d,r,dashed]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[d,l,dashed]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[f]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[r,f]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[l,f]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} \\ + {\prfsummarystyle=1 + \prftree[noline]{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[noline][r]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} & + {\prfsummarystyle=1 + \prftree[noline][l]{$\vee$E}{\prfsummary{\Gamma}{A \vee B}} + {\prfsummary{\Gamma, \prfboundedassumption{A}}{C}} + {\prfsummary{\Gamma, \prfboundedassumption{B}}{C}} + {C}} + \end{array} +\end{displaymath} + +Proof that the Law of Excluded middle implies $\neg\neg A \supset A$: +\begin{displaymath} + \prftree[r]{$\vee$E} + {\prfbyaxiom{LEM} + {A \vee \neg A}\hspace{.4em}} + {\prftree[r]{$\supset$I} + {\prfboundedassumption{A}} + {\neg\neg A \supset A}} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\bot$E} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{\neg\neg A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{displaymath} + +Proof that the Law of Excluded middle implies $\neg\neg A \supset A$ +with labels instead of rule names, except on axioms: +\begin{displaymath} + \prftree[l]{$\vee$E} + {\prfbyaxiom{LEM} + {A \vee \neg A}\hspace{.6em}} + {\prftree[l]{$\supset$I} + {\prfboundedassumption{A}} + {\neg\neg A \supset A}} + {\prftree[l]{$\supset$I} + {\prftree[l]{$\bot$E} + {\prftree[l]{$\supset$E} + {\prfboundedassumption{\neg\neg A}} + {\prfboundedassumption{\neg A}} + {\bot}} + {A}} + {\neg\neg A \supset A}} + {\neg\neg A \supset A} +\end{displaymath} + +Another simple proof in natural deduction: +\begin{displaymath} + \prftree + {\prftree + {\prftree + {\prftree + {\prftree + {\prfboundedassumption{A \rightarrow (B \rightarrow C)}} + {\prfboundedassumption{A}} + {B \rightarrow C}\hspace{2em}} + {\prftree + {\prfboundedassumption{A \rightarrow B}} + {\prfboundedassumption{A}} + {B}} + {C}} + {A \rightarrow C}} + {(A \rightarrow B) \rightarrow (A \rightarrow C)}} + {(A \rightarrow (B \rightarrow C)) \rightarrow ((A \rightarrow B) + \rightarrow (A \rightarrow C))} +\end{displaymath} + +The same proof, under the proposition-as-types interpretation: +\begin{displaymath} + \prftree + {\prftree + {\prftree + {\prftree + {\prftree + {\prfassumption{u\colon A \rightarrow (B \rightarrow C)}} + {\prfassumption{w\colon A}} + {u w\colon B \rightarrow C}\hspace{2em}} + {\prftree + {\prfassumption{v\colon A \rightarrow B}} + {\prfassumption{w\colon A}} + {v w\colon B}} + {u w(v w)\colon C}} + {\lambda w.\, u w(v w)\colon A \rightarrow C}} + {\lambda v w.\, u w(v w)\colon (A \rightarrow B) \rightarrow (A + \rightarrow C)}} + {\lambda u v w.\, u w(v w)\colon (A \rightarrow (B \rightarrow C)) + \rightarrow ((A \rightarrow B) \rightarrow (A \rightarrow C))} +\end{displaymath} + +A deduction in a sequent calculus: +\begin{displaymath} + \prfinterspace=1.2em + \prftree + {\prftree + {\prftree + {\prftree + {\prfassumption{A \Rightarrow A}} + {\prftree + {\prfassumption{A \Rightarrow A}} + {\prftree + {B \Rightarrow B} + {C \Rightarrow C} + {B, B \rightarrow C \Rightarrow C}} + {A, A \rightarrow B, B \rightarrow C \Rightarrow C}} + {A, A \rightarrow B, A \rightarrow (B \rightarrow C) + \Rightarrow C}} + {A \rightarrow B, A \rightarrow (B \rightarrow C) \Rightarrow A + \rightarrow C}} + {A \rightarrow (B \rightarrow C) \Rightarrow (A \rightarrow B) + \rightarrow (A \rightarrow C)}} + {\Rightarrow (A \rightarrow (B \rightarrow C)) \rightarrow ((A + \rightarrow B) \rightarrow (A \rightarrow C))} +\end{displaymath} + +% ------------------------------------- +\clearpage +\section{Internals}\label{sec:internals} +A proof tree is typeset as a \TeX{} box in horizontal mode. This means +that wherever a character can stay, so does a proof: in principle, +there is no need to put the proof in a math environment. Also, the +width of a proof is exactly the width of the box; the height of the +proof is the height of the conclusion plus the total height of all the +matter above it; the depth of the proof is the depth of the +conclusion. The proof is aligned so that the current baseline is the +baseline of the conclusion. + +For example, the proof of $g \supset \neg\neg g$ in natural deduction +is: +\begin{displaymath} + \mbox{proof} \equiv + \fbox{\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$I} + {\prftree[r]{$\supset$E} + {\prfboundedassumption{g}} + {\prfboundedassumption{\neg g}} + {\bot}} + {\neg\neg g}} + {g \supset \neg\neg g}} +\end{displaymath} +The proof has been surrounded by a framebox to make evident its +bounds. Also, since the letter $g$ has a depth, the example shows how +depth in the conclusion influences the alignment of the proof with +respect to the preceding text.\vspace{2ex} + +Actually, the fundamental command in the package is \verb|\prftree|: +the commands to construct assumptions (\verb|\prfassumption| and +\verb|\prfboundedassumption|), those to generate axioms +(\verb|\prfaxiom| and \verb|\prfbyaxiom|), and \verb|\prfsummary| are +just appropriate instances.\vspace{2ex} + +The \verb|\prftree| command is composed by a parser, which takes care +of reading the various options and parameters, and by a graphical +engine, \verb|\prf@draw|, which calculates and draw the box containing +the proof tree. + +It may be useful to understand how the graphical engine works. In the +first place, each proof tree is a box with a structure: +\begin{center} + {\setlength{\unitlength}{1em} + \begin{picture}(27,6) + \put(0.8,0){\framebox(26.2,6){}} + \put(5,4){\framebox(18,1.8){$\cdots$}} + \put(5.2,4.2){\framebox(6,1.4){$\mbox{assumption}_1$}} + \put(16.8,4.2){\framebox(6,1.4){$\mbox{assumption}_n$}} + \put(7,3){\line(1,0){14}} + \put(22,2.3){\framebox(4.8,1.4){rule name}} + \put(1,2.3){\framebox(4.8,1.4){label}} + \put(8.5,0.2){\framebox(11,1.8){conclusion}} + \end{picture}} +\end{center} + +The conclusion, the proof line, and the \emph{assumption line} are +centred. The assumption line is the line whose first element is the +conclusion of the first assumption, and whose last element is the +conclusion of the last assumption, properly spaced so that all the +assumptions fit in between. The width of the proof line is calculated +as the maximum of the width of the assumption line and the conclusion, +with the rule name and the label, if present, hanging on the right and +the left, respectively. + +To calculate the assumption line, the engine keeps track of the +position of the conclusion within a proof tree, which reduces to +remember how far is the conclusion from the left margin +(\verb|Lassum|), and how far it is from the right margin +(\verb|Rassum|). So, the assumption line starts from the value of +\verb|Lassum| of the first assumption, and finishes at \verb|Rassum| +of the last assumption. + +Thus, with these values it is not difficult to figure out the +mathematics to place the various boxes around, so to combine them into +a proof tree. This is exactly what the graphical engine does. + +Unfortunately, when one writes assumptions as simple formulae, without +the \verb|\prfassumption| command, the corresponding \verb|Lassum| and +\verb|Rassum| are not set to $0$, which is the right value. In fact, +the recursive expansion of the \verb|\prf@draw| macro follows the +\emph{natural} order in the construction of the proof box, which is +extremely useful because it allows to locally modify parameters in +sub-proofs; but this order conflicts with proper rendering of +assumptions which are not proof trees. + +Also, the hints on how to put space between assumptions, see +Section~\ref{sec:hints_and_tricks}, may have strange effects: if space +is added in front of the first assumption or behind the last one, this +space makes invalid the values of \verb|Lassum| and \verb|Rassum|, +respectively, yielding hard to predict results. + +It is worth remarking that the mathematics of the graphical engine is +sound, which means that zero or negative values for the various +dimensions specified as parameters, or using \emph{bizarre} boxes in +the fancy commands, yields the expected results, as far as boxes do +not have parts which extends beyond the bounds.\vspace{2ex} + +The implementation of references mimics the implementation of +\verb|\label| and \verb|\ref| in \LaTeX. Whenever a reference is +defined, through a command with the $\langle \mathrm{label}\rangle$ as +the first argument, the reference value is created according to the +options, and it gets stored in the \texttt{.aux} file, by writing +$\verb|\prfauxvalue|\{\mathrm{label}\}\{\mathrm{value}\}$ in the +file. Then, when the source code will be recompiled, and the +\texttt{.aux} file read, this command will be executed before any +occurrence of a reference, which can be resolved. + +Most difficulties in the implementation of references lie in the way +to construct the boxes to be used in the proof tree. But, the tricky +part is the interaction with the \LaTeX{} and \TeX{} kernel for error +reporting. Actually, it is in this part that the bugs signalled in the +next section have their origin. + +% ------------------------------------- +\clearpage +\section{Future Features and Bugs}\label{sec:future_features} +Essentially, all the features of Buss's package have been implemented +but one: alignment of proofs according to the $\vdash$ (or equivalent) +sign. While this feature is occasionally useful in the writing of +sequent proofs, it requires some trickery in the graphical engine, so +it has been postponed for the moment.\vspace{2ex} + +Moreover, automatic compact proofs have been analysed, but not +implemented. A compact proof minimises the amount of space between +subsequent assumptions, eventually making the upper trees to overlap +as boxes, but not as typed text. + +The algorithm to obtain this result is not immediate: one should keep +track of the left and right \emph{skylines} of a proof. Comparing the +left skyline of an assumption with the right skyline of the next one, +one can calculate what is the distance between the boxes so that the +distance between the closest points in the skylines is exactly +\verb|\prfinterspace|. + +It is not simple to code such an algorithm in \TeX{}, but the real +difficulty is how to represent skylines and how to store them, since +\TeX{} provides no abstract data structures. Hence, the implementation +of this feature has been postponed to a remote future, or to the will +of a real \TeX{} magician.\vspace{2ex} + +There are three bugs in the packages. + +The first one is that \verb|\mathrm| and similar may break a proof +tree when used in the rule name. I have not been able to track down +why this happens. The effect is that the proof tree is correctly +constructed but it cannot be used as a box, e.g., it cannot be put +inside a \verb|\fbox| or used in normal text. Although disappointing +this bug can be easily circumvented by typesetting the proof tree in a +math environment, e.g., by putting it into a math display or by +enclosing it in a pair of dollar signs.\vspace{2ex} + +The second bug is minimal and in a future version it could be +solved. If one considers the following proof: +\begin{displaymath} + \begin{prooftree} + \fbox{% + \prflineextra=0pt + \prftree + {\prftree + {\prftree + {\prfboundedassumption{\neg\neg A}} + {\prfboundedassumption<bug:1>{\neg A}} + {\bot}} + {A}} + {\neg\neg A \supset A}} + \end{prooftree} +\end{displaymath} +the anchor of assumption (\prfref<bug:1>) is out of the bounding +box. Usually, this is not a problem and, in case, it can be manually +corrected +\begin{displaymath} + \begin{prooftree} + \fbox{% + \prflineextra=0pt + \hbox{\prftree + {\prftree + {\prftree + {\prfboundedassumption{\neg\neg A}} + {\prfboundedassumption<[l]bug:1>{\neg A}} + {\bot}} + {A}} + {\neg\neg A \supset A}\hspace{.34em}}} + \end{prooftree} +\end{displaymath} +as in the following code: +\begin{verbatim} + \prfassumption{\prftree{\prftree{\prftree + {\prfboundedassumption{\neg\neg A}} + {\prfboundedassumption<bug:1>{\neg A}}{\bot}} + {A}}{\neg\neg A \supset A}\hspace{.34em}}} +\end{verbatim}\vspace{2ex} + +The third bug happens the first time a reference is created: if it is +referred by \verb|\prfref| in the rule name, a strange ``immediate'' +follows it. This is not a problem, since the code has to be recompiled +anyway to complete the definition of references, and this is enough to +make the problem to disappear. Since it is a transient problem, I have +not investigated any further. + +\vfill + +\end{document} diff --git a/Master/texmf-dist/tex/latex/prftree/prftree.sty b/Master/texmf-dist/tex/latex/prftree/prftree.sty new file mode 100644 index 00000000000..8396b7b9cf5 --- /dev/null +++ b/Master/texmf-dist/tex/latex/prftree/prftree.sty @@ -0,0 +1,1046 @@ +% +% prftree.sty +% by Marco Benini - 30th November 2014 +% +% A package to typeset natural deduction proofs, or sequent proofs, or +% tableau proofs +% +% This package is distributed under the GNU General Public License +% + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{prftree}[2014/11/30 Natural Deduction Proofs] + +% Package options +\newif\ifprf@NDOption\prf@NDOptionfalse +\newif\ifprf@SEQOption\prf@SEQOptionfalse +\newif\ifprfIMPOption\prfIMPOptionfalse + +\DeclareOption{ND}{\prf@NDOptiontrue} +\DeclareOption{SEQ}{\prf@SEQOptiontrue} +\DeclareOption{IMP}{\prf@IMPOptiontrue} +\ProcessOptions\relax + +%-------------------------------------------------------------------- +% A proof tree is composed by a generic cell: +% A1 A2 A3 +% ---------- R +% C +% We call A1, A2, A3. ... assumptions, C the conclusion and R the rule +% name. The line dividing the assumptions from the conclusion is +% called the proof line. A proof tree with no assumptions is an axiom. +% An assumption which is not a proof tree is a pure assumption. +% +% A proof tree is typeset by +% \prftree[<options>]...[<options>] +% {<assumption1>}...{<assumptionN>} +% {<conclusion>} +% The possible options are: +% r : the first argument after the options is the rule +% name, typeset in text mode +% rule : synonym for 'r' +% by rule : synonym for 'r' +% by : synonym for 'r' +% right : synonym for 'r' +% l : the first argument after the options is the rule +% label, typeset in text mode; if there is also a +% rule name, the label is the second argument +% label : synonym for 'l' +% left : synonym for 'l' +% straight : the proof line will be a solid line (default) +% straight line : synonym for 'l' +% straightline : synonym for 'l' +% dotted : the proof line will be a dotted line +% dotted line : synonym for 'dotted' +% dottedline : synonym for 'dotted' +% dashed : the proof line will be a dashed line +% dashed line : synonym for 'dashed' +% dashedline : synonym for 'dashed' +% f : the proof line will be fancy +% fancy : synonym for 'f' +% fancy line : synonym for 'f' +% fancyline : synonym for 'f' +% s : the proof line will be single, not double (default) +% single : synonym for 's' +% single line : synonym for 's' +% singleline : synonym for 's' +% d : the proof line will be double, not single +% double : synonym for 'd' +% double line : synonym for 'd' +% doubleline : synonym for 'd' +% noline : suppresses the proof line (prevails over all other +% line options) +% summary : renders the proof line as the summary symbol +% (prevails over all other line options except +% noline) +% +% The format of options is [<opt1>,...,<optM>]; it is correct to have +% empty options. Options are parsed left-to-right: in case of +% conflicting options, the latest prevails. +% +% If present, the rule name is typeset in text style, while the +% conclusion and the assumptions are typeset in display math mode. +% The result is a box with the correct height and width, whose +% conclusion is aligned with the current baseline. +% +% Notice that the conclusion must be present, while the assumptions +% may be absent. +% +% If there are no assumptions, i.e., if the proof tree represents an +% axiom, you may use the following commands: +% \prfaxiom{<axiom>} +% \prfbyaxiom{<label>}{<axiom>} +% the latter includes also the axiom name. +% +% A pure assumption is just a proof tree composed by the conclusion +% only. It uses an option to suppress the drawing of the proof line. +% The commands are: +% \prfassumption<reference>{<formula>} +% \prfboundedassumption<reference>{<formula>} +% the second command discharges the assumption. +% +% A proof summary is just a proof tree whose proof line is bizarre. It +% uses an option to specify the type of summary. +% The command is: +% \prfsummary<reference>[<label>] +% {<assumption1>}...{<assumptionN>} +% {<conclusion>} +% The label is optional. The shape of the summary is controlled by the +% global option \prfsummarystyle. +% +% The <reference> field above is used for labelling and +% referencing, as explained in the documentation. +%-------------------------------------------------------------------- + +%-------------------------------------------------------------------- +% Parameters +% These values can be safely used to configure the behaviour of the +% macros in the package. Beware to modify them only outside a proof +% tree as the order in which a proof tree is typeset may vary in +% future version of the package. +%-------------------------------------------------------------------- + +% \prflinepad default 0.3ex +% the space between the baseline of assumptions and the proof line and +% also the space between the proof line and the top of the conclusion +\newdimen\prflinepad\prflinepad.3ex + +% \prflineextra default 0.3em +% the length which extends on the left and on the right the proof line +% so that it is slightly longer than the largest between the +% conclusion and the list of (direct) assumptions +\newdimen\prflineextra\prflineextra.3em + +% \prflinethickness default 0.2pt +% the thickness of the proof line +\newdimen\prflinethickness\prflinethickness.2pt + +% \prfemptylinethickness default 4 times the linethickness +% the thickness of the proof line which has to be drawn but it is empty +\newdimen\prfemptylinethickness\prfemptylinethickness4\prflinethickness + +% \prfrulenameskip default 0.2em +% the space between the proof line and the rule name +\newdimen\prfrulenameskip\prfrulenameskip.2em + +% \prflabelskip default 0.2em +% the space between the label and the proof line +\newdimen\prflabelskip\prflabelskip.2em + +% \prfinterspace default .6em +% the space between two subsequent assumptions +\newdimen\prfinterspace\prfinterspace.6em + +% \prfdoublelineinterspace default 1.2pt +% the space between a double line +\newdimen\prfdoublelineinterspace\prfdoublelineinterspace1.2pt + +% \prfboundedstyle default 0 +% defines the style of bounded (discharged) assumptions: +% 0 = [<formula>] +% 1 = <formula> cancelled by a horizontal line +% >1 = uses the custom \prfdiscargedassumption command +\newcount\prfboundedstyle\prfboundedstyle0 + +% \prfsummarystyle default 0 +% defines the style for the summary box. The argument takes the +% following values +% 0 = a vertical dotted line (default) +% 1 = a huge \Pi +% 2 = \prod +% 3 = a calligraphic D +% >3 = uses the custom \prffancysummarybox command +\newcount\prfsummarystyle\prfsummarystyle0 + +% \prffancyline +% the command to draw "fancy" lines +\def\prffancyline{\cleaders\hbox to .63em% + {\hss\raisebox{-.5ex}[.2ex][0pt]{$\sim$}\hss}\hfill} + +% \prfConclusionBox +% the command to draw the conclusion box +\def\prfConclusionBox#1{% + \hbox{$\displaystyle\begingroup#1\endgroup\mathstrut$}} + +% \prfAssumptionBox +% the command to draw the assumption box +\def\prfAssumptionBox#1{% + \hbox{$\displaystyle\begingroup#1\endgroup\mathstrut$}} + +% \prfRuleNameBox +% the command to draw the rule name box. +\def\prfRuleNameBox#1{\hbox{\begingroup#1\endgroup\strut}} + +% \prfLabelBox +% the command to draw the label box. +\def\prfLabelBox#1{\hbox{\begingroup#1\endgroup\strut}} + +% \prfdiscargedassumption +% the command to draw a discharged assumption in a custom way. +% Users may consider the cancel.sty package +\def\prfdiscargedassumption#1{\left\langle{#1}\right\rangle} + +% \prffancysummarybox +% the command to draw the body of a custom summary +\newbox\prf@@fancysummarybox +\newdimen\prf@@fancysymmarylen +\def\prffancysummarybox{% + \sbox{\prf@@fancysummarybox}{\Huge$\bigtriangledown$}% + \prf@@fancysymmarylen\ht\prf@@fancysummarybox% + \advance\prf@@fancysymmarylen\dp\prf@@fancysummarybox% + \sbox{\prf@@fancysummarybox}{% + \raisebox{.25\prf@@fancysymmarylen}[.8\prf@@fancysymmarylen]% + [0pt]{\usebox{\prf@@fancysummarybox}}}% + \prf@@fancysymmarylen\wd\prf@summary@label% + \ifdim\prf@@fancysymmarylen>\z@\relax% + \prf@@fancysymmarylen\wd\prf@@fancysummarybox% + \wd\prf@summary@label.4em% + \hbox to\prf@@fancysymmarylen{% + \usebox\prf@@fancysummarybox}\kern-.4em% + \box\prf@summary@label% + \else\usebox\prf@@fancysummarybox\fi} + +%==================================================================== + +%-------------------------------------------------------------------- +% What follows is intended for internal use of the package. +% It shouldn't be used in documents and may vary in future versions. +% +% Notice that we use temporary registers shared with TeX & LaTeX, and +% that some registers are shared also inside the drawing procedure! +%-------------------------------------------------------------------- + +% Lengths +\newskip\prf@Lassum% space between the left border of the + % assumption box and the left border of the + % conclusion of the first assumption; +\newskip\prf@Rassum% space between the right border of the + % assumption box and the right border of the + % conclusion of the last assumption +\skipdef\prf@assumline1% +\skipdef\prf@concline3% +\skipdef\prf@linewd5% +\skipdef\prf@lineht3% +\skipdef\prf@linedp1% +\skipdef\prf@temp7% +\skipdef\prf@tmp7% +\skipdef\prf@Aval9% + +% Boxes +\newbox\prf@assumptionsbox% Assumptions +\newbox\prf@conclusionbox% Conclusion +\newbox\prf@rulenamebox% Rule name +\newbox\prf@labelbox% Label +\newbox\prf@linebox% Proof line +\newbox\prf@summarybox% Summary +\newbox\prf@fancybox% To compute the fancy line + +%-------------------------------------------------------------------- +% Stack implementation +%-------------------------------------------------------------------- +%% End-of-stack, wrapper and stack declaration +\def\prf@eos{\noexpand\prf@eos} +\def\prf@cons{\noexpand\prf@cons} +\let\prf@stack\prf@eos + +%% Pushing a value puts the (decorated) value in front +%% of the stack list +\def\prf@push#1{\expandafter\edef\expandafter\prf@stack% + {\prf@cons{#1}\prf@stack}} + +%% Top retrieves the topmost value in the stack +\def\prf@@top\prf@cons#1#2\prf@eos{#1} +\def\prf@top{\expandafter\prf@@top\prf@stack} + +%% Pop discard the topmost value in the stack +\def\prf@@pop\prf@cons#1#2\prf@eos{% + \expandafter\edef\expandafter\prf@stack{#2\prf@eos}} +\def\prf@pop{\expandafter\prf@@pop\prf@stack} + +%-------------------------------------------------------------------- +% Checks whether two strings are equal +% \prf@streq{A}{B} if A = B then the boolean value \ifprf@same is +% true otherwise false +% +% There is also \prf@strlisteq{A}{L} which checks whether A is equal +% to any element in the comma-separated list L of strings +%-------------------------------------------------------------------- +\newif\ifprf@same + +\newcommand{\prf@streq}[2]{% + \global\prf@samefalse\begingroup\def\1{#1}\def\2{#2}% + \ifx\1\2\global\prf@sametrue\fi\endgroup} + +\def\prf@strlisteq#1#2{\prf@@strlisteq{#1}#2,@} +\def\prf@@strlisteq#1#2,{\prf@streq{#1}{#2}% + \ifprf@same\expandafter\prf@@strlistignore% + \else\expandafter\prf@@@strlisteq\fi{#1}} +\def\prf@@strlistignore#1@{\relax} +\def\prf@@@strlisteq#1#2{% + \begingroup\def\1{@}\def\2{#2}% + \ifx\1\2\prf@@@strlistignore\else\prf@hop\fi\endgroup{#1}#2} +\def\prf@hop\fi\endgroup#1#2{\fi\endgroup\prf@@strlisteq{#1}#2} +\def\prf@@@strlistignore\else\prf@hop\fi\endgroup#1@{\fi\endgroup} + +% ------------------------------------------------------------------- +% Labelling and referencing +% The following commands implement the reference mechanism to allow to +% label and then refer to assumptions and summaries of proofs +% ------------------------------------------------------------------- + +% The counter to keep track of assumptions +\newcounter{prfassumptioncounter} +\setcounter{prfassumptioncounter}{0} + +% The counter to keep track of summaries +\newcounter{prfsummarycounter} +\setcounter{prfsummarycounter}{0} + +% To keep track of the options +\newif\ifprf@lbl@arabic\prf@lbl@arabictrue +\newif\ifprf@lbl@roman\prf@lbl@romanfalse +\newif\ifprf@lbl@Roman\prf@lbl@Romanfalse +\newif\ifprf@lbl@alph\prf@lbl@alphfalse +\newif\ifprf@lbl@Alph\prf@lbl@Alphfalse +\newif\ifprf@lbl@fnsymbol\prf@lbl@fnsymbolfalse +\newif\ifprf@lbl@label\prf@lbl@labelfalse + +% The prooftree environment is used to define the scope of the +% assumption references +\newenvironment{prooftree}% + {\setcounter{prfassumptioncounter}{0}}% + {\setcounter{prfassumptioncounter}{0}} + +% Test whether a reference is defined +\def\ifprf@undefref<#1>{% + \expandafter\ifx\csname prf@ref@@#1\endcsname\relax} + +% Test whether a reference has been written in the .aux file +\def\ifprf@unwrittenref<#1>{% + \expandafter\ifx\csname prf@w@ref@#1\endcsname\relax} + +% Write a reference +\def\prfref<#1>{% + \ifprf@undefref<#1>{??}% + \PackageWarningNoLine{prooftree}{Undefined reference <#1>}% + \else\csname prf@ref@@#1\endcsname\relax\fi} + +% Create the anchor from what stored in the .aux file +\def\prfauxlabel#1#2{% + \ifprf@undefref<#1>% + \expandafter\gdef\csname prf@ref@@#1\endcsname{{#2}}\fi} + +% Write the newly created label in the .aux file +\def\prf@auxwrite<#1>#2{% + \ifprf@unwrittenref<#1>% + \protected@write\@auxout{}{\string\prfauxlabel{#1}{#2}}% + \expandafter\gdef\csname prf@w@ref@#1\endcsname{0}\fi} + +% Generate an assumption label +\def\prf@assum@lbl<#1>{\prf@generic@lbl<#1>{prfassumptioncounter}} + +% Generate a summary label +\def\prf@summary@lbl<#1>{\prf@generic@lbl<#1>{prfsummarycounter}} + +% Generate a label on a given counter +\def\prf@generic@lbl<#1>#2{% + \prf@warningtrue\stepcounter{#2}% + \ifprf@lbl@arabic\prf@warningfalse% + \prf@auxwrite<#1>{\arabic{#2}}\fi% + \ifprf@lbl@roman\prf@warningfalse% + \prf@auxwrite<#1>{\roman{#2}}\fi% + \ifprf@lbl@Roman\prf@warningfalse% + \prf@auxwrite<#1>{\Roman{#2}}\fi% + \ifprf@lbl@alph\prf@warningfalse% + \prf@auxwrite<#1>{\alph{#2}}\fi% + \ifprf@lbl@Alph\prf@warningfalse% + \prf@auxwrite<#1>{\Alph{#2}}\fi% + \ifprf@lbl@fnsymbol\prf@warningfalse% + \prf@auxwrite<#1>{\fnsymbol{#2}}\fi% + \ifprf@warning\prf@auxwrite<#1>{\arabic{#2}}\fi} + +% Parsing of the labelled assumption options +\def\prf@lblopt#1{% + \prf@warningtrue% + \global\prf@lbl@arabicfalse% + \global\prf@lbl@romanfalse% + \global\prf@lbl@Romanfalse% + \global\prf@lbl@alphfalse% + \global\prf@lbl@Alphfalse% + \global\prf@lbl@fnsymbolfalse% + \global\prf@lbl@labelfalse% + \prf@strlisteq{#1}{n,number,arabic}% + \ifprf@same\prf@warningfalse\global\prf@lbl@arabictrue\fi% + \prf@strlisteq{#1}{r,roman}% + \ifprf@same\prf@warningfalse\global\prf@lbl@romantrue\fi% + \prf@strlisteq{#1}{R,Roman}% + \ifprf@same\prf@warningfalse\global\prf@lbl@Romantrue\fi% + \prf@strlisteq{#1}{a,alph,alpha,alphabetic}% + \ifprf@same\prf@warningfalse\global\prf@lbl@alphtrue\fi% + \prf@strlisteq{#1}{A,Alph,Alpha,Alphabetic}% + \ifprf@same\prf@warningfalse\global\prf@lbl@Alphtrue\fi + \prf@strlisteq{#1}{f,s,function,symbol,function symbol}% + \ifprf@same\prf@warningfalse\global\prf@lbl@fnsymboltrue\fi% + \prf@strlisteq{#1}{l,label}% + \ifprf@same\prf@warningfalse\global\prf@lbl@labeltrue\fi% + \ifprf@warning% + \PackageWarning{prftree}{Unrecognised option #1}\fi} + +% How a labelled assumption is graphically rendered +\def\prflabelledassumptionbox#1#2{% + \setbox\prf@fancybox\hbox{${#1}$}% + \prf@tmp\wd\prf@fancybox% + \setbox\prf@fancybox\hbox{$\box\prf@fancybox^{#2}$}% + \wd\prf@fancybox\prf@tmp% + \prf@assumption{\box\prf@fancybox}} + +% How a discharged fancy labelled assumption is graphically rendered +\def\prflabelleddiscargedassumption#1#2{% + \prflabelledassumptionbox{\left\langle{#1}\right\rangle}{#2}} + +%-------------------------------------------------------------------- +% \prfassumption{<formula>} +% \prfboundedassumption{<formula>} +% +% Commands to draw a pure assumption: the former draws a pure +% assumption, while the latter draws a pure assumption which is +% discharged. The way to mark discharging is controlled by the global +% option \prfboundedstyle +%-------------------------------------------------------------------- +\def\prfassumption{\@ifnextchar<{\prf@assum@one}{\prf@assumption}} +\def\prf@assum@one<#1>{\global\prf@lbl@labelfalse\prf@assum@two#1>} +\def\prf@assum@two{\@ifnextchar[{\prf@assum@three}{\prf@assum@four}} +\def\prf@assum@three[#1]{\prf@lblopt{#1}\prf@assum@four} +\def\prf@assum@four#1>#2{% + \ifprf@unwrittenref<#1>\relax% + \else\ifprf@lbl@label\relax\else% + \global\prf@lbl@labeltrue% + \PackageWarningNoLine{prftree}{Label <#1> is [label]!}\fi\fi% + \ifprf@lbl@label\relax\else\prf@assum@lbl<#1>\fi% + \prflabelledassumptionbox{#2}{\prfref<#1>}} +\def\prf@assumption#1{\prftree[noline]{#1}\relax} + +\def\prfboundedassumption{% + \@ifnextchar<{\prf@bassum@one}{\prf@boundedassumption}} +\def\prf@bassum@one<#1>{\global\prf@lbl@labelfalse\prf@bassum@two#1>} +\def\prf@bassum@two{\@ifnextchar[{\prf@bassum@three}{\prf@bassum@four}} +\def\prf@bassum@three[#1]{\prf@lblopt{#1}\prf@bassum@four} +\def\prf@bassum@four#1>#2{% + \ifprf@unwrittenref<#1>\relax% + \else\ifprf@lbl@label\relax\else% + \global\prf@lbl@labeltrue% + \PackageWarningNoLine{prftree}{Label <#1> is [label]!}\fi\fi% + \ifprf@lbl@label\relax\else\prf@assum@lbl<#1>\fi% + \prftree[noline]{\prf@labelledbounded{#2}{#1}}\relax} +\def\prf@boundedassumption#1{\prftree[noline]{\prf@bounded{#1}}\relax} +\def\prf@bounded#1{% + \ifnum\prfboundedstyle=0\left[{#1}\right]% + \else\ifnum\prfboundedstyle=1% + \setbox\prf@conclusionbox\prfConclusionBox{#1}% + \prf@tmp\wd\prf@conclusionbox% + \prf@linedp.5\ht\prf@conclusionbox% + \advance\prf@linedp-.5\dp\prf@conclusionbox% + \prf@lineht\prf@linedp\advance\prf@lineht\prflinethickness% + \edef\prf@cancel{\hskip-\prf@tmp% + \vrule width\prf@tmp height\prf@lineht depth-\prf@linedp}% + {#1}\prf@cancel% + \else\prfdiscargedassumption{#1}\fi\fi} +\def\prf@labelledbounded#1#2{% + \ifnum\prfboundedstyle=0% + \prflabelledassumptionbox{\left[{#1}\right]}{\prfref<#2>}% + \else\ifnum\prfboundedstyle=1% + \setbox\prf@conclusionbox\prfConclusionBox{#1}% + \prf@tmp\wd\prf@conclusionbox% + \prf@linedp.5\ht\prf@conclusionbox% + \advance\prf@linedp-.5\dp\prf@conclusionbox% + \prf@lineht\prf@linedp\advance\prf@lineht\prflinethickness% + \edef\prf@cancel{\hskip-\prf@tmp% + \vrule width\prf@tmp height\prf@lineht depth-\prf@linedp}% + \prflabelledassumptionbox{{#1}\prf@cancel}{\prfref<#2>}% + \else\prflabelleddiscargedassumption{#1}{\prfref<#2>}\fi\fi} + +%-------------------------------------------------------------------- +% \prfaxiom{<axiom>} +% \prfbyaxiom{<label>}{<axiom>} +% +% Commands to draw an axiom: the former draws the axiom, while the +% latter includes also a rule name for the axiom. +%-------------------------------------------------------------------- +\def\prfaxiom#1{\prftree[single,straight]{#1}\relax} +\def\prfbyaxiom#1#2{\prftree[single,straight,rule]{#1}{#2}\relax} + +%-------------------------------------------------------------------- +% \prfsummary[<label>] +% {<assumption1>}...{<assumptionN>} +% {<conclusion>} +% +% Command to draw a proof summary, i.e., a structure with assumptions +% 1 to N and a conclusion which stands for a complex proof not +% explicited. The label is optional. +% The shape of the summary is controlled by the global option +% \prfsummarystyle +%-------------------------------------------------------------------- +\def\prfsummary{\@ifnextchar<{\prf@summary@one}{\prf@summary}} +\def\prf@summary@one<#1>{% + \global\prf@lbl@labelfalse\prf@summary@four#1>} +\def\prf@summary@four{% + \@ifnextchar[{\prf@summary@five}{\prf@summary@six}} +\def\prf@summary@five[#1]#2>{% + \prf@lblopt{#1}% + \ifprf@unwrittenref<#2>\relax% + \else\ifprf@lbl@label\relax\else% + \global\prf@lbl@labeltrue% + \PackageWarningNoLine{prftree}{Label <#2> is [label]!}\fi\fi% + \ifprf@lbl@label\relax\else\prf@summary@lbl<#2>\fi% + \setbox\prf@summary@label\hbox{\scriptsize\prfref<#2>}% + \prf@summary} +\def\prf@summary@six#1>{% + \ifprf@lbl@label\relax\else\prf@summary@lbl<#1>\fi% + \setbox\prf@summary@label\hbox{\scriptsize\prfref<#1>}% + \prf@summary} +\def\prf@summary{\@ifnextchar[{\prf@summary@two}{\prf@summary@three}} +\def\prf@summary@two[#1]{\prftree[summary,rule]{#1}} +\def\prf@summary@three{\prftree[summary]} + +\newbox\prf@summary@label +\def\prf@@summarystyle{% + \ifnum3=\prfsummarystyle\relax% + \setbox\prf@summarybox\hbox{$\mathcal{D}$}% + \prf@tmp\wd\prf@summarybox% + \setbox\prf@summarybox\hbox{$\mathcal{D}% + \hbox{\box\prf@summary@label}\mathstrut$}% + \wd\prf@summarybox\prf@tmp% + \else\ifnum2=\prfsummarystyle\relax% + \setbox\prf@summarybox\hbox{$\prod$}% + \prf@tmp\wd\prf@summarybox% + \setbox\prf@summarybox\hbox{$\prod\hbox{\box\prf@summary@label}$}% + \wd\prf@summarybox\prf@tmp% + \else\ifnum1=\prfsummarystyle\relax% + \setbox\prf@summarybox\hbox{\hbox{\Huge$\Pi$}}% + \prf@tmp\wd\prf@summarybox% + \setbox\prf@summarybox\hbox{\hbox{\Huge$\Pi$}% + \hbox{\box\prf@summary@label}}% + \wd\prf@summarybox\prf@tmp% + \else\ifnum0=\prfsummarystyle\relax% + \setbox\prf@summarybox\hbox{$\cdot$}% + \prf@tmp\wd\prf@summarybox% + \setbox\prf@summarybox% + \vbox to5.2ex{\cleaders\hbox{$\cdot$}\vfill}% + \setbox\prf@summarybox\hbox{\usebox{\prf@summarybox}% + \hbox{\ \box\prf@summary@label}}% + \wd\prf@summarybox\prf@tmp% + \else\setbox\prf@summarybox\hbox{\prffancysummarybox}\fi\fi\fi\fi% + \prf@tmp.5\ht\prf@summarybox% + \advance\prf@tmp-.5\dp\prf@summarybox% + \setbox\prf@summarybox% + \hbox{\lower\prf@tmp\hbox{\box\prf@summarybox}}}% + +%-------------------------------------------------------------------- +% \prftree[<options>]...[<options>] +% {<assumption1>}...{<assumptionN>} +% {<conclusion>} +% +% The format of options is [<opt1>,...,<optM>]; it is correct to have +% empty options. Options are parsed left-to-right: in case of +% conflicting options, the latest prevails. See the documentation for +% their description. +% +% If present, the rule name is typesetted in text style, while the +% conclusion and the assumptions are typesetted in math mode. +% The result is a box with the correct height and width, whose +% conclusion is aligned with the current baseline. +% +% Notice that the conclusion must be present, while the assumptions +% may be absent. +% +% Options and the way things are drawn can be modified via the global +% settings of the package (see above). Notice that changing these +% settings inside a proof tree may lead to impredictable results, as +% the typesetting may proceed in an arbitrary order. +%-------------------------------------------------------------------- +\newif\ifprf@rule% +\newif\ifprf@label% +\newif\ifprf@noline% +\newif\ifprf@doubleline% +\newif\ifprf@straightline% +\newif\ifprf@dottedline% +\newif\ifprf@dashedline% +\newif\ifprf@fancyline% +\newif\ifprf@summary% +\newif\ifprf@first% +\newif\ifprf@warning% +\newif\ifprf@assum + +% The real parsing command is \prf@Ntree; the external command sets +% the right values for the various switches controlling the options +\def\prftree{\prf@init\prf@Ntree} +\def\prf@init{% + \global\prf@rulefalse% + \global\prf@labelfalse% + \global\prf@nolinefalse% + \global\prf@doublelinefalse% + \global\prf@straightlinetrue% + \global\prf@dottedlinefalse% + \global\prf@dashedlinefalse% + \global\prf@fancylinefalse% + \global\prf@summaryfalse} + +% If there are options then parse them, eventually setting the +% booleans to their appropriate values. Then, expand \prf@@tree +\def\prf@Ntree{\@ifnextchar[{\prf@options}{\prf@@tree}} + +% Parses a block [<opt>,...,<opt>] of options one by one, left to +% right +\def\prf@options[#1]{\prf@opts#1,]\prf@Ntree} +\def\prf@opts#1,{\prf@opt#1,\@ifnextchar]{\prf@optsskip}{\prf@opts}} +\def\prf@optsskip]{\relax} % to consume the final ] + +% Parses a single option eventually setting the appropriate flag +\def\prf@opt#1,{\prf@warningtrue% + \prf@strlisteq{#1}{r,by rule,rule,by,right}% + \ifprf@same\prf@warningfalse\global\prf@ruletrue\fi% + \prf@strlisteq{#1}{l,label,left}% + \ifprf@same\prf@warningfalse\global\prf@labeltrue\fi% + \prf@strlisteq{#1}{s,single line,single,singleline}% + \ifprf@same\prf@warningfalse\global\prf@doublelinefalse\fi% + \prf@strlisteq{#1}{d,double line,double,doubleline}% + \ifprf@same\prf@warningfalse\global\prf@doublelinetrue\fi% + \prf@strlisteq{#1}{straight,straight line,straightline}% + \ifprf@same\prf@warningfalse% + \global\prf@straightlinetrue\global\prf@dottedlinefalse% + \global\prf@dashedlinefalse\global\prf@fancylinefalse\fi% + \prf@strlisteq{#1}{dotted,dotted line,dottedline}% + \ifprf@same\prf@warningfalse% + \global\prf@straightlinefalse\global\prf@dottedlinetrue% + \global\prf@dashedlinefalse\global\prf@fancylinefalse\fi% + \prf@strlisteq{#1}{dashed,dashed line,dashedline}% + \ifprf@same\prf@warningfalse% + \global\prf@straightlinefalse\global\prf@dottedlinefalse% + \global\prf@dashedlinetrue\global\prf@fancylinefalse\fi% + \prf@strlisteq{#1}{f,fancy line,fancy,fancyline}% + \ifprf@same\prf@warningfalse% + \global\prf@straightlinefalse\global\prf@dottedlinefalse% + \global\prf@dashedlinefalse\global\prf@fancylinetrue\fi% + \prf@strlisteq{#1}{noline}% + \ifprf@same\prf@warningfalse\global\prf@nolinetrue\fi% + \prf@strlisteq{#1}{summary}% + \ifprf@same\prf@warningfalse\global\prf@summarytrue\fi% + \ifprf@warning\PackageWarning{prftree}% + {Unrecognised option #1}\fi}% + +% At this point, options have been parsed. So, we process them +% preparing the right parameters for the drawing procedure. +% We start from the proof line options: +% 0 = single straight line +% 1 = double straight line +% 2 = single dotted line +% 3 = double dotted line +% 4 = single dashed line +% 5 = double dashed line +% 6 = single fancy line +% 7 = double fancy line +% 8 = no line +% 9 = summary +\def\prf@@tree{% + \countdef\prf@linetype1\prf@linetype0% + \ifprf@dottedline\prf@linetype2\fi% + \ifprf@dashedline\prf@linetype4\fi% + \ifprf@fancyline\prf@linetype6\fi% + \ifprf@doubleline\advance\prf@linetype1\fi% + \ifprf@noline\prf@linetype8\fi% + \ifprf@summary\prf@linetype9\fi\relax% + \expandafter\prf@@Ntree\the\prf@linetype} + +% If there is no rule name, we put an empty one in place +% #1 the line options +\def\prf@@Ntree#1{% + \edef\prf@choice{\ifprf@rule{#1}\else{#1}{}\fi}% + \expandafter\prf@@NNtree\prf@choice} + +% If there is no label, we put an empty one in place +% #1 the line options +% #2 the rule name +\def\prf@@NNtree#1#2{% + \edef\prf@choice{\ifprf@label{#1}{#2}\else{#1}{#2}{}\fi}% + \expandafter\prf@tree\prf@choice} + +% We collect the first assumption, if any, or the conclusion otherwise +% and we look if there is another argument. If not, we draw the proof. +% #1 the line options' value +% #2 the rule name +% #3 the label +% #4 the conclusion or the first assumption +\def\prf@tree#1#2#3#4{\@ifnextchar\bgroup% + {\prf@assumptions{#1}{#2}{#3}{\prf@preprf{#4}}}% + {\prf@draw{#1}{#2}{#3}{#4}{\prf@preprf}{}}} + +% We examine assumptions from left to right. If we hit the last +% argument, it is the conclusion and the proof is ready to be drawn. +% #1 the line options' value +% #2 the rule name +% #3 the label +% #4 the first assumptions +% #5 the current argument +\def\prf@assumptions#1#2#3#4#5{\@ifnextchar\bgroup% + {\prf@assumenext{#1}{#2}{#3}{#4}{\prf@interprf{#5}}}% + {\prf@draw{#1}{#2}{#3}{#5}{#4}{}}} + +% An intermediate assumption is added to the assumptions' box, until +% the last assumption has been collected. Then the proof is drawn. +% #1 the line options' value +% #2 the rule name +% #3 the label +% #4 the first assumption +% #5 the complete list of assumptions +% #6 the new argument +\def\prf@assumenext#1#2#3#4#5#6{\@ifnextchar\bgroup% + {\prf@assumenext{#1}{#2}{#3}{#4}{{#5}\prf@interprf{#6}}}% + {\prf@draw{#1}{#2}{#3}{#6}{#4}{#5}}} + +% We need to reset some internal variables during the generation of +% the assumptions +\def\prf@preprf{\global\prf@Lassum\z@\global\prf@Rassum\z@} + +% We need to put some space between assumptions when generating them +\def\prf@interprf{\hskip\prfinterspace} + +%-------------------------------------------------------------------- +% The drawing procedure, i.e., the "core" of the package +% #1 the line options' value +% #2 the rule name +% #3 the label +% #4 the conclusion +% #5 the first assumption +% #6 the list of assumptions +%-------------------------------------------------------------------- + +\def\prf@draw#1#2#3#4#5#6{% + % We construct the boxes which will constitute the proof + \ifprf@first\prf@push{1}\else\prf@push{0}\fi% + \global\prf@firsttrue% + \setbox\prf@assumptionsbox\prfAssumptionBox{#5}% + \prf@push{\the\prf@Lassum}% + \global\prf@firstfalse% + \ifdim\wd\prf@assumptionsbox>\z@\relax\prf@assumtrue% + \setbox\prf@assumptionsbox% + \hbox{\box\prf@assumptionsbox\prfAssumptionBox{#6}}% + \else\prf@assumfalse% + \setbox\prf@assumptionsbox\hbox{}\fi% + \prf@push{\the\prf@Rassum}% + \setbox\prf@conclusionbox\prfConclusionBox{#4}% + \setbox\prf@rulenamebox\prfRuleNameBox{#2}% + \setbox\prf@labelbox\prfLabelBox{#3}% + % We set up the flags needed to format the proof tree box + \prf@nolinefalse\prf@doublelinefalse\prf@straightlinetrue% + \prf@dottedlinefalse\prf@dashedlinefalse\prf@fancylinefalse% + \prf@summaryfalse\prf@rulefalse\prf@labelfalse% + \ifcase#1\relax\or% + \prf@doublelinetrue\or% + \prf@dottedlinetrue\prf@straightlinefalse\or% + \prf@doublelinetrue\prf@dottedlinetrue\prf@straightlinefalse\or% + \prf@dashedlinetrue\prf@straightlinefalse\or% + \prf@doublelinetrue\prf@dashedlinetrue\prf@straightlinefalse\or% + \prf@fancylinetrue\prf@straightlinefalse\or% + \prf@doublelinetrue\prf@fancylinetrue\prf@straightlinefalse\or% + \prf@nolinetrue\prf@straightlinefalse\or% + \prf@summarytrue\prf@straightlinefalse\fi% + \ifdim\wd\prf@rulenamebox>\z@\relax\prf@ruletrue% + \else\prf@rulefalse\fi% + \ifdim\wd\prf@labelbox>\z@\relax\prf@labeltrue% + \else\prf@labelfalse\fi% + \ifdim\wd\prf@assumptionsbox>\z@\relax\prf@assumtrue% + \else\prf@assumfalse\fi% + % Now, we retrieve the right values for Lassum and Rassum + % since box construction may have overwritten them. Also, we need to + % know if this proof is the first of a list of assumptions + \edef\prf@tok{\prf@top}\prf@pop\global\prf@Rassum\prf@tok% + \edef\prf@tok{\prf@top}\prf@pop\global\prf@Lassum\prf@tok% + \edef\prf@tok{\prf@top}\prf@pop\global\prf@firstfalse% + \ifnum\prf@tok=1\global\prf@firsttrue\fi% + % The assumptions' box has the following shape + % -------------------------------- + % |<---------------------wd------->| + % | ----------- ------------ | + % ||<--> | | <---->|| + % || Lassum | ... | Rassum || + % || | | | | || + % || V | | V || + % | ----------- ------------ | + % -------------------------------- + % The assumptions' line is composed by the conclusions of the + % proofs which are the antecedents of the application of the + % inference rule + % The final box will be something like + % -------------------------------- + % |<---------------------wd------->| + % | ----------- ------------ | + % ||<--> | | <---->|| + % || Lassum | ... | Rassum || + % || | | | | || + % || V | | V || + % | ----------- ------------ | + % -------------------------------- + % ======================== rule name + % conclusion + % <--Lassum--> <-----Rassum-----> + % + % We calculate the length of the assumptions' line: + % assumline = assumptionsbox - Lassum - Rassum + % if there are no assumption, assumline = 0 + % (for efficiency reasons, we actually calculate 1/2assumline) + \ifprf@assum\prf@assumline.5\wd\prf@assumptionsbox% + \advance\prf@assumline-.5\prf@Lassum% + \advance\prf@assumline-.5\prf@Rassum% + \else\prf@assumline\z@\fi% + % The length of the conclusionbox + % (for efficiency reasons, we actually calculate 1/2concline) + \prf@concline.5\wd\prf@conclusionbox% + % The length of the proof line is + % linewd = if summary then width of summary box else + % max(concline,assumline) + % if there is a line, we add 2extra + % (for efficiency reasons, we actually calculate 1/2linewd) + \ifprf@summary\prf@@summarystyle\prf@linewd.5\wd\prf@summarybox% + \else\prf@linewd\prf@assumline% + \ifdim\prf@assumline<\prf@concline\prf@linewd\prf@concline\fi% + \ifprf@noline\relax\else\advance\prf@linewd\prflineextra\fi\fi% + % We calculate the proofline without label and rule name. + \ifprf@noline\setbox\prf@fancybox\hbox{\hskip2\prf@linewd}% + \else\ifprf@summary\setbox\prf@fancybox\copy\prf@summarybox% + \else\ifprf@fancyline% + \setbox\prf@fancybox\hbox to2\prf@linewd{\prffancyline}\else% + \ifprf@dashedline% + \setbox\prf@fancybox% + \hbox to2\prf@linewd{\cleaders\hbox to.5em{\hss\_\hss}\hfill}\else% + \ifprf@dottedline% + \setbox\prf@fancybox% + \hbox to2\prf@linewd{\cleaders\hbox to.33em{\hss.\hss}\hfill}\else% + % it must be a straight line! + \setbox\prf@fancybox\hbox{\vrule width2\prf@linewd% + height\prflinethickness}\fi\fi\fi% + % If the line is double, we draw it twice with enough + % (doublelineinterspace) space between the two copies. + \ifprf@doubleline% + \setbox\prf@fancybox\hbox{\vbox{\copy\prf@fancybox% + \nointerlineskip\vskip\prfdoublelineinterspace\nointerlineskip% + \box\prf@fancybox}}\fi\fi\fi% + \prf@tmp\dp\prf@fancybox% + \setbox\prf@fancybox\hbox{\raise\prf@tmp\box\prf@fancybox}% + % Let A = max(1/2assumline + Lassum, 1/2conclusionbox, 1/2linewd + + % delta), where delta is 0 if there is no label, and it is the width + % of the label box plus prflabelskip otherwise. + % Then + % Assumptions shift = A - (1/2assumline + Lassum) + % Rule line shift = A - (1/2linewd + delta) + % Lassum = Conclusion shift = A - 1/2conclusionbox + % And, so, we can prepare the assumptions box and the conclusion box + \prf@Aval\prf@assumline\advance\prf@Aval\prf@Lassum% + \prf@tmp\prf@linewd\relax% + \ifprf@label\advance\prf@tmp\wd\prf@labelbox% + \advance\prf@tmp\prflabelskip\fi% + \ifdim\prf@Aval<\prf@tmp\prf@Aval\prf@tmp\fi% + \ifdim\prf@Aval<\prf@concline\prf@Aval\prf@concline\fi% + \prf@temp\prf@Aval\advance\prf@temp-\prf@assumline% + \advance\prf@temp-\prf@Lassum% + \setbox\prf@assumptionsbox% + \hbox{\hskip\prf@temp\box\prf@assumptionsbox}% + \prf@temp\prf@Aval\advance\prf@temp-\prf@concline% + \setbox\prf@conclusionbox% + \hbox{\hskip\prf@temp\box\prf@conclusionbox}% + \global\prf@Lassum\prf@temp% + % Rassum will be the width of the composition of all boxes (but we + % still have to cope with heigths...) minus (concline + conclusion + % shift) + \global\prf@Rassum-2\prf@concline% + \global\advance\prf@Rassum-\prf@temp% + % Then, if there is a rule name, the line is raised to align with + % the centre of the rule name and the rule box gets attached to the + % proof line box. + \prf@linedp\z@% + \ifprf@noline\setbox\prf@fancybox\hbox to2\prf@linewd{}\fi% + \ifprf@rule\advance\prf@linedp.5\ht\prf@fancybox% + \advance\prf@linedp-.5\ht\prf@rulenamebox% + \advance\prf@linedp.5\dp\prf@rulenamebox% + \setbox\prf@linebox% + \hbox{\copy\prf@fancybox\hskip\prfrulenameskip% + \raise\prf@linedp\box\prf@rulenamebox}% + \else\setbox\prf@linebox\copy\prf@fancybox\fi% + \setbox\prf@linebox\hbox{\raise\dp\prf@linebox\box\prf@linebox}% + % Then, if there is a label, the line is raised to align with + % the centre of the label and the label box gets attached to the + % proof line box. + \prf@linedp\z@% + \prf@temp\prf@Aval\advance\prf@temp-\prf@linewd% + \ifprf@label\advance\prf@linedp.5\ht\prf@linebox% + \advance\prf@linedp-.5\ht\prf@labelbox% + \advance\prf@linedp.5\dp\prf@labelbox% + \advance\prf@temp-\prflabelskip% + \advance\prf@temp-\wd\prf@labelbox% + \setbox\prf@linebox% + \hbox{\raise\prf@linedp\box\prf@labelbox% + \hskip\prflabelskip\box\prf@linebox}\fi% + \setbox\prf@linebox% + \hbox{\hskip\prf@temp\raise\dp\prf@linebox\box\prf@linebox}% + % We need to calculate the distance between the assumptions and the + % proofline: if there are no assumptions, it is zero; if there are + % assumptions but no rule name, it is \prflinepad; otherwise it is + % \linepad plus half of the "real" line's height + \prf@tmp\z@% + \ifprf@assum% + \ifprf@rule\prf@tmp-.5\ht\prf@linebox% + \advance\prf@tmp.5\ht\prf@fancybox% + \advance\prf@tmp.5\dp\prf@fancybox\fi\relax% + \ifprf@label\ifprf@rule\relax\else% + \prf@tmp-.5\ht\prf@linebox% + \advance\prf@tmp.5\ht\prf@fancybox% + \advance\prf@tmp.5\dp\prf@fancybox\fi\fi% + \advance\prf@tmp\prflinepad% + \setbox\prf@assumptionsbox% + \vbox{\box\prf@assumptionsbox\nointerlineskip\vskip\prf@tmp}\fi% + % We need to calculate the distance between the proofline and the + % conclusion: it is slightly complex to explain... try to draw the + % whole thing to make it clear!! + \prf@temp\prflinepad% + \ifprf@noline% + \ifprf@assum% + \advance\prf@temp\prfemptylinethickness\fi% + \advance\prf@temp-\prflinepad\fi% + \ifprf@rule% + \advance\prf@temp-.5\ht\prf@linebox% + \advance\prf@temp.5\ht\prf@fancybox% + \advance\prf@temp.5\dp\prf@fancybox\fi% + \ifprf@label\ifprf@rule\relax\else% + \advance\prf@temp-.5\ht\prf@linebox% + \advance\prf@temp.5\ht\prf@fancybox% + \advance\prf@temp.5\dp\prf@fancybox\fi\fi% + \setbox\prf@conclusionbox% + \vbox{\vskip\prf@temp\box\prf@conclusionbox}% + % And, finally, at the very end, we can prepare the proof box and we + % can calculate the right value from Rassum. At the very end, we can + % output the result (!!) + \setbox\prf@rulenamebox% + \vbox{\box\prf@assumptionsbox\nointerlineskip% + \box\prf@linebox\nointerlineskip% + \box\prf@conclusionbox\nointerlineskip}% + \global\advance\prf@Rassum\wd\prf@rulenamebox% + \hbox{$\box\prf@rulenamebox$}} + +% ------------------------------------------------------------------- +% The following macros are used to simplify the writing of proofs in +% natural deduction, and they roughly follow the format of proofs as +% in Troelstra, Schwichtenberg "Basic Proof Theory". +% +% Since they may conflict with other packages, they are controlled by +% options in the package. +% ------------------------------------------------------------------- + +% ------------------------------------------------------------------- +% Natural deduction systems +% +% Package option [ND] +% ------------------------------------------------------------------- + +\newbox\prf@charbox +\def\prfscript#1{\setbox\prf@charbox% + \hbox{$\scriptstyle\mathrm{#1}$}\copy\prf@charbox} +\ifprf@NDOption% + \def\NDA{\prfassumption} + \def\NDD{\prfboundedassumption} + \def\NDAL#1{\prfassumption<#1>} + \def\NDDL#1{\prfboundedassumption<#1>} + \def\NDP{\prftree} + \def\NDANDI{\prftree[by]{$\scriptstyle\wedge\prfscript{I}$}} + \def\NDANDER{\prftree[by]{% + $\scriptstyle\wedge\prfscript{E}_{\prfscript{R}}$}} + \def\NDANDEL{\prftree[by]{% + $\scriptstyle\wedge\prfscript{E}_{\prfscript{L}}$}} + \def\NDANDE{\prftree[by]{$\scriptstyle\wedge\prfscript{E}$}} + \ifprfIMPOption + \def\NDIMPI{\prftree[by]{$\scriptstyle\supset\prfscript{I}$}} + \def\NDIMPE{\prftree[by]{$\scriptstyle\supset\prfscript{E}$}} + \def\NDIMPIL#1{\prftree[by]{$\scriptstyle\supset% + \prfscript{I}_{\prfref<#1>}$}} + \else + \def\NDIMPI{\prftree[by]{$\scriptstyle\rightarrow% + \prfscript{I}$}} + \def\NDIMPE{\prftree[by]{$\scriptstyle\rightarrow% + \prfscript{E}$}} + \def\NDIMPIL#1{% + \prftree[by]{$\scriptstyle\rightarrow% + \prfscript{I}_{\prfref<#1>}$}}\fi + \def\NDORIR{\prftree[by]{$\scriptstyle\vee% + \prfscript{I}_{\prfscript{R}}$}} + \def\NDORIL{\prftree[by]{$\scriptstyle\vee% + \prfscript{I}_{\prfscript{L}}$}} + \def\NDORI{\prftree[by]{$\scriptstyle\vee\prfscript{I}$}} + \def\NDORE{\prftree[by]{$\scriptstyle\vee\prfscript{E}$}} + \def\NDOREL#1{\prftree[by]{$\scriptstyle\vee% + \prfscript{I}_{\prfref<#1>}$}} + \def\NDALLI{\prftree[by]{$\scriptstyle\forall\prfscript{I}$}} + \def\NDALLE{\prftree[by]{$\scriptstyle\forall\prfscript{E}$}} + \def\NDEXI{\prftree[by]{$\scriptstyle\exists\prfscript{I}$}} + \def\NDEXE{\prftree[by]{$\scriptstyle\exists\prfscript{E}$}} + \def\NDEXEL#1{% + \prftree[by]{$\scriptstyle\exists\prfscript{E}_{\prfref<#1>}$}} + \def\NDTI{\prftree[by]{$\scriptstyle\top\prfscript{I}$}} + \def\NDFE{\prftree[by]{$\scriptstyle\bot\prfscript{E}$}} + \def\NDLEM{\prftree[by]{$\scriptstyle\prfscript{lem}$}} +\fi + +% ------------------------------------------------------------------- +% Sequent systems +% +% Package option [SEQ] +% ------------------------------------------------------------------- + +\ifprf@SEQOption% + \def\SEQA{\prfassumption} + \def\SEQD{\prfboundedassumption} + \def\SEQP{\prftree} + \def\SEQAX{\prftree[by]{$\scriptstyle\prfscript{Ax}$}} + \def\SEQLF{\prftree[by]{$\scriptstyle\prfscript{L}\bot$}} + \def\SEQLW{\prftree[by]{$\scriptstyle\prfscript{LW}$}} + \def\SEQRW{\prftree[by]{$\scriptstyle\prfscript{RW}$}} + \def\SEQLC{\prftree[by]{$\scriptstyle\prfscript{LC}$}} + \def\SEQRC{\prftree[by]{$\scriptstyle\prfscript{RC}$}} + \def\SEQLAND{\prftree[by]{$\scriptstyle\prfscript{L}\wedge$}} + \def\SEQRAND{\prftree[by]{$\scriptstyle\prfscript{R}\wedge$}} + \def\SEQLOR{\prftree[by]{$\scriptstyle\prfscript{L}\vee$}} + \def\SEQROR{\prftree[by]{$\scriptstyle\prfscript{R}\vee$}} + \ifprfIMPOption + \def\SEQLIMP{\prftree[by]{$\scriptstyle\prfscript{L}\supset$}} + \def\SEQRIMP{\prftree[by]{$\scriptstyle\prfscript{R}\supset$}} + \else + \def\SEQLIMP{\prftree[by]{$\scriptstyle\prfscript{L}% + \rightarrow$}} + \def\SEQRIMP{\prftree[by]{$\scriptstyle\prfscript{R}% + \rightarrow$}} + \fi + \def\SEQLALL{\prftree[by]{$\scriptstyle\prfscript{L}\forall$}} + \def\SEQRALL{\prftree[by]{$\scriptstyle\prfscript{R}\forall$}} + \def\SEQLEX{\prftree[by]{$\scriptstyle\prfscript{L}\exists$}} + \def\SEQREX{\prftree[by]{$\scriptstyle\prfscript{R}\exists$}} + \def\SEQCUT{\prftree[by]{$\scriptstyle\prfscript{Cut}$}} +\fi + +% ------------------------------------------------------------------- diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 9a9eb72c952..d3b9855e0e8 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -394,7 +394,7 @@ my @TLP_working = qw( polyglossia polynom polynomial polytable postcards poster-mac powerdot powerdot-FUBerlin ppr-prv pracjourn preprint prerex present presentations presentations-en - pressrelease prettyref preview printlen proba probsoln procIAGssymp + pressrelease prettyref preview prftree printlen proba probsoln procIAGssymp prodint productbox program progress progressbar proposal properties prosper protex protocol przechlewski-book diff --git a/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc index 4608c02b8ee..c2670198b42 100644 --- a/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc @@ -37,6 +37,7 @@ depend nath depend ot-tableau depend oubraces depend perfectcut +depend prftree depend proba depend rec-thy depend ribbonproofs diff --git a/Master/tlpkg/tlpsrc/prftree.tlpsrc b/Master/tlpkg/tlpsrc/prftree.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/prftree.tlpsrc |