Isabelle_DOF/examples/technical_report/TR_my_commented_isabelle/document/prooftree.sty

348 lines
12 KiB
TeX
Executable File

\message{<Paul Taylor's Proof Trees, 2 August 1996>}
%% Build proof tree for Natural Deduction, Sequent Calculus, etc.
%% WITH SHORTENING OF PROOF RULES!
%% Paul Taylor, begun 10 Oct 1989
%% *** THIS IS ONLY A PRELIMINARY VERSION AND THINGS MAY CHANGE! ***
%%
%% 2 Aug 1996: fixed \mscount and \proofdotnumber
%%
%% \prooftree
%% hyp1 produces:
%% hyp2
%% hyp3 hyp1 hyp2 hyp3
%% \justifies -------------------- rulename
%% concl concl
%% \thickness=0.08em
%% \shiftright 2em
%% \using
%% rulename
%% \endprooftree
%%
%% where the hypotheses may be similar structures or just formulae.
%%
%% To get a vertical string of dots instead of the proof rule, do
%%
%% \prooftree which produces:
%% [hyp]
%% \using [hyp]
%% name .
%% \proofdotseparation=1.2ex .name
%% \proofdotnumber=4 .
%% \leadsto .
%% concl concl
%% \endprooftree
%%
%% Within a prooftree, \[ and \] may be used instead of \prooftree and
%% \endprooftree; this is not permitted at the outer level because it
%% conflicts with LaTeX. Also,
%% \Justifies
%% produces a double line. In LaTeX you can use \begin{prooftree} and
%% \end{prootree} at the outer level (however this will not work for the inner
%% levels, but in any case why would you want to be so verbose?).
%%
%% All of of the keywords except \prooftree and \endprooftree are optional
%% and may appear in any order. They may also be combined in \newcommand's
%% eg "\def\Cut{\using\sf cut\thickness.08em\justifies}" with the abbreviation
%% "\prooftree hyp1 hyp2 \Cut \concl \endprooftree". This is recommended and
%% some standard abbreviations will be found at the end of this file.
%%
%% \thickness specifies the breadth of the rule in any units, although
%% font-relative units such as "ex" or "em" are preferable.
%% It may optionally be followed by "=".
%% \proofrulebreadth=.08em or \setlength\proofrulebreadth{.08em} may also be
%% used either in place of \thickness or globally; the default is 0.04em.
%% \proofdotseparation and \proofdotnumber control the size of the
%% string of dots
%%
%% If proof trees and formulae are mixed, some explicit spacing is needed,
%% but don't put anything to the left of the left-most (or the right of
%% the right-most) hypothesis, or put it in braces, because this will cause
%% the indentation to be lost.
%%
%% By default the conclusion is centered wrt the left-most and right-most
%% immediate hypotheses (not their proofs); \shiftright or \shiftleft moves
%% it relative to this position. (Not sure about this specification or how
%% it should affect spreading of proof tree.)
%
% global assignments to dimensions seem to have the effect of stretching
% diagrams horizontally.
%
%%==========================================================================
\def\introrule{{\cal I}}\def\elimrule{{\cal E}}%%
\def\andintro{\using{\land}\introrule\justifies}%%
\def\impelim{\using{\Rightarrow}\elimrule\justifies}%%
\def\allintro{\using{\forall}\introrule\justifies}%%
\def\allelim{\using{\forall}\elimrule\justifies}%%
\def\falseelim{\using{\bot}\elimrule\justifies}%%
\def\existsintro{\using{\exists}\introrule\justifies}%%
%% #1 is meant to be 1 or 2 for the first or second formula
\def\andelim#1{\using{\land}#1\elimrule\justifies}%%
\def\orintro#1{\using{\lor}#1\introrule\justifies}%%
%% #1 is meant to be a label corresponding to the discharged hypothesis/es
\def\impintro#1{\using{\Rightarrow}\introrule_{#1}\justifies}%%
\def\orelim#1{\using{\lor}\elimrule_{#1}\justifies}%%
\def\existselim#1{\using{\exists}\elimrule_{#1}\justifies}
%%==========================================================================
\newdimen\proofrulebreadth \proofrulebreadth=.05em
\newdimen\proofdotseparation \proofdotseparation=1.25ex
\newdimen\proofrulebaseline \proofrulebaseline=2ex
\newcount\proofdotnumber \proofdotnumber=3
\let\then\relax
\def\hfi{\hskip0pt plus.0001fil}
\mathchardef\squigto="3A3B
%
% flag where we are
\newif\ifinsideprooftree\insideprooftreefalse
\newif\ifonleftofproofrule\onleftofproofrulefalse
\newif\ifproofdots\proofdotsfalse
\newif\ifdoubleproof\doubleprooffalse
\let\wereinproofbit\relax
%
% dimensions and boxes of bits
\newdimen\shortenproofleft
\newdimen\shortenproofright
\newdimen\proofbelowshift
\newbox\proofabove
\newbox\proofbelow
\newbox\proofrulename
%
% miscellaneous commands for setting values
\def\shiftproofbelow{\let\next\relax\afterassignment\setshiftproofbelow\dimen0 }
\def\shiftproofbelowneg{\def\next{\multiply\dimen0 by-1 }%
\afterassignment\setshiftproofbelow\dimen0 }
\def\setshiftproofbelow{\next\proofbelowshift=\dimen0 }
\def\setproofrulebreadth{\proofrulebreadth}
%=============================================================================
\def\prooftree{% NESTED ZERO (\ifonleftofproofrule)
%
% first find out whether we're at the left-hand end of a proof rule
\ifnum \lastpenalty=1
\then \unpenalty
\else \onleftofproofrulefalse
\fi
%
% some space on left (except if we're on left, and no infinity for outermost)
\ifonleftofproofrule
\else \ifinsideprooftree
\then \hskip.5em plus1fil
\fi
\fi
%
% begin our proof tree environment
\bgroup% NESTED ONE (\proofbelow, \proofrulename, \proofabove,
% \shortenproofleft, \shortenproofright, \proofrulebreadth)
\setbox\proofbelow=\hbox{}\setbox\proofrulename=\hbox{}%
\let\justifies\proofover\let\leadsto\proofoverdots\let\Justifies\proofoverdbl
\let\using\proofusing\let\[\prooftree
\ifinsideprooftree\let\]\endprooftree\fi
\proofdotsfalse\doubleprooffalse
\let\thickness\setproofrulebreadth
\let\shiftright\shiftproofbelow \let\shift\shiftproofbelow
\let\shiftleft\shiftproofbelowneg
\let\ifwasinsideprooftree\ifinsideprooftree
\insideprooftreetrue
%
% now begin to set the top of the rule (definitions local to it)
\setbox\proofabove=\hbox\bgroup$\displaystyle % NESTED TWO
\let\wereinproofbit\prooftree
%
% these local variables will be copied out:
\shortenproofleft=0pt \shortenproofright=0pt \proofbelowshift=0pt
%
% flags to enable inner proof tree to detect if on left:
\onleftofproofruletrue\penalty1
}
%=============================================================================
% end whatever box and copy crucial values out of it
\def\eproofbit{% NESTED TWO
%
% various hacks applicable to hypothesis list
\ifx \wereinproofbit\prooftree
\then \ifcase \lastpenalty
\then \shortenproofright=0pt % 0: some other object, no indentation
\or \unpenalty\hfil % 1: empty hypotheses, just glue
\or \unpenalty\unskip % 2: just had a tree, remove glue
\else \shortenproofright=0pt % eh?
\fi
\fi
%
% pass out crucial values from scope
\global\dimen0=\shortenproofleft
\global\dimen1=\shortenproofright
\global\dimen2=\proofrulebreadth
\global\dimen3=\proofbelowshift
\global\dimen4=\proofdotseparation
\global\count255=\proofdotnumber
%
% end the box
$\egroup % NESTED ONE
%
% restore the values
\shortenproofleft=\dimen0
\shortenproofright=\dimen1
\proofrulebreadth=\dimen2
\proofbelowshift=\dimen3
\proofdotseparation=\dimen4
\proofdotnumber=\count255
}
%=============================================================================
\def\proofover{% NESTED TWO
\eproofbit % NESTED ONE
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofover
$\displaystyle
}%
%
%=============================================================================
\def\proofoverdbl{% NESTED TWO
\eproofbit % NESTED ONE
\doubleprooftrue
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofoverdbl
$\displaystyle
}%
%
%=============================================================================
\def\proofoverdots{% NESTED TWO
\eproofbit % NESTED ONE
\proofdotstrue
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofoverdots
$\displaystyle
}%
%
%=============================================================================
\def\proofusing{% NESTED TWO
\eproofbit % NESTED ONE
\setbox\proofrulename=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofusing
\kern0.3em$
}
%=============================================================================
\def\endprooftree{% NESTED TWO
\eproofbit % NESTED ONE
% \dimen0 = length of proof rule
% \dimen1 = indentation of conclusion wrt rule
% \dimen2 = new \shortenproofleft, ie indentation of conclusion
% \dimen3 = new \shortenproofright, ie
% space on right of conclusion to end of tree
% \dimen4 = space on right of conclusion below rule
\dimen5 =0pt% spread of hypotheses
% \dimen6, \dimen7 = height & depth of rule
%
% length of rule needed by proof above
\dimen0=\wd\proofabove \advance\dimen0-\shortenproofleft
\advance\dimen0-\shortenproofright
%
% amount of spare space below
\dimen1=.5\dimen0 \advance\dimen1-.5\wd\proofbelow
\dimen4=\dimen1
\advance\dimen1\proofbelowshift \advance\dimen4-\proofbelowshift
%
% conclusion sticks out to left of immediate hypotheses
\ifdim \dimen1<0pt
\then \advance\shortenproofleft\dimen1
\advance\dimen0-\dimen1
\dimen1=0pt
% now it sticks out to left of tree!
\ifdim \shortenproofleft<0pt
\then \setbox\proofabove=\hbox{%
\kern-\shortenproofleft\unhbox\proofabove}%
\shortenproofleft=0pt
\fi
\fi
%
% and to the right
\ifdim \dimen4<0pt
\then \advance\shortenproofright\dimen4
\advance\dimen0-\dimen4
\dimen4=0pt
\fi
%
% make sure enough space for label
\ifdim \shortenproofright<\wd\proofrulename
\then \shortenproofright=\wd\proofrulename
\fi
%
% calculate new indentations
\dimen2=\shortenproofleft \advance\dimen2 by\dimen1
\dimen3=\shortenproofright\advance\dimen3 by\dimen4
%
% make the rule or dots, with name attached
\ifproofdots
\then
\dimen6=\shortenproofleft \advance\dimen6 .5\dimen0
\setbox1=\vbox to\proofdotseparation{\vss\hbox{$\cdot$}\vss}%
\setbox0=\hbox{%
\advance\dimen6-.5\wd1
\kern\dimen6
$\vcenter to\proofdotnumber\proofdotseparation
{\leaders\box1\vfill}$%
\unhbox\proofrulename}%
\else \dimen6=\fontdimen22\the\textfont2 % height of maths axis
\dimen7=\dimen6
\advance\dimen6by.5\proofrulebreadth
\advance\dimen7by-.5\proofrulebreadth
\setbox0=\hbox{%
\kern\shortenproofleft
\ifdoubleproof
\then \hbox to\dimen0{%
$\mathsurround0pt\mathord=\mkern-6mu%
\cleaders\hbox{$\mkern-2mu=\mkern-2mu$}\hfill
\mkern-6mu\mathord=$}%
\else \vrule height\dimen6 depth-\dimen7 width\dimen0
\fi
\unhbox\proofrulename}%
\ht0=\dimen6 \dp0=-\dimen7
\fi
%
% set up to centre outermost tree only
\let\doll\relax
\ifwasinsideprooftree
\then \let\VBOX\vbox
\else \ifmmode\else$\let\doll=$\fi
\let\VBOX\vcenter
\fi
% this \vbox or \vcenter is the actual output:
\VBOX {\baselineskip\proofrulebaseline \lineskip.2ex
\expandafter\lineskiplimit\ifproofdots0ex\else-0.6ex\fi
\hbox spread\dimen5 {\hfi\unhbox\proofabove\hfi}%
\hbox{\box0}%
\hbox {\kern\dimen2 \box\proofbelow}}\doll%
%
% pass new indentations out of scope
\global\dimen2=\dimen2
\global\dimen3=\dimen3
\egroup % NESTED ZERO
\ifonleftofproofrule
\then \shortenproofleft=\dimen2
\fi
\shortenproofright=\dimen3
%
% some space on right and flag we've just made a tree
\onleftofproofrulefalse
\ifinsideprooftree
\then \hskip.5em plus 1fil \penalty2
\fi
}
%==========================================================================
% IDEAS
% 1. Specification of \shiftright and how to spread trees.
% 2. Spacing command \m which causes 1em+1fil spacing, over-riding
% exisiting space on sides of trees and not affecting the
% detection of being on the left or right.
% 3. Hack using \@currenvir to detect LaTeX environment; have to
% use \aftergroup to pass \shortenproofleft/right out.
% 4. (Pie in the sky) detect how much trees can be "tucked in"
% 5. Discharged hypotheses (diagonal lines).