├── .gitignore ├── README.md ├── fitch.hacker.txt ├── fitch.sty ├── fitchdoc-dimen.fig ├── fitchdoc-dimen.pdf ├── fitchdoc-dimen.svg ├── fitchdoc.tex └── fitchexample.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Core latex/pdflatex auxiliary files: 2 | *.aux 3 | *.lof 4 | *.log 5 | *.lot 6 | *.fls 7 | *.out 8 | *.toc 9 | *.fmt 10 | *.fot 11 | *.cb 12 | *.cb2 13 | .*.lb 14 | 15 | ## Intermediate documents: 16 | *.dvi 17 | *.xdv 18 | *-converted-to.* 19 | # these rules might exclude image files for figures etc. 20 | # *.ps 21 | # *.eps 22 | # *.pdf 23 | 24 | ## Generated if empty string is given at "Please type another file name for output:" 25 | .pdf 26 | 27 | ## Bibliography auxiliary files (bibtex/biblatex/biber): 28 | *.bbl 29 | *.bcf 30 | *.blg 31 | *-blx.aux 32 | *-blx.bib 33 | *.run.xml 34 | 35 | ## Build tool auxiliary files: 36 | *.fdb_latexmk 37 | *.synctex 38 | *.synctex(busy) 39 | *.synctex.gz 40 | *.synctex.gz(busy) 41 | *.pdfsync 42 | 43 | ## Build tool directories for auxiliary files 44 | # latexrun 45 | latex.out/ 46 | 47 | ## Auxiliary and intermediate files from other packages: 48 | # algorithms 49 | *.alg 50 | *.loa 51 | 52 | # achemso 53 | acs-*.bib 54 | 55 | # amsthm 56 | *.thm 57 | 58 | # beamer 59 | *.nav 60 | *.pre 61 | *.snm 62 | *.vrb 63 | 64 | # changes 65 | *.soc 66 | 67 | # comment 68 | *.cut 69 | 70 | # cprotect 71 | *.cpt 72 | 73 | # elsarticle (documentclass of Elsevier journals) 74 | *.spl 75 | 76 | # endnotes 77 | *.ent 78 | 79 | # fixme 80 | *.lox 81 | 82 | # feynmf/feynmp 83 | *.mf 84 | *.mp 85 | *.t[1-9] 86 | *.t[1-9][0-9] 87 | *.tfm 88 | 89 | #(r)(e)ledmac/(r)(e)ledpar 90 | *.end 91 | *.?end 92 | *.[1-9] 93 | *.[1-9][0-9] 94 | *.[1-9][0-9][0-9] 95 | *.[1-9]R 96 | *.[1-9][0-9]R 97 | *.[1-9][0-9][0-9]R 98 | *.eledsec[1-9] 99 | *.eledsec[1-9]R 100 | *.eledsec[1-9][0-9] 101 | *.eledsec[1-9][0-9]R 102 | *.eledsec[1-9][0-9][0-9] 103 | *.eledsec[1-9][0-9][0-9]R 104 | 105 | # glossaries 106 | *.acn 107 | *.acr 108 | *.glg 109 | *.glo 110 | *.gls 111 | *.glsdefs 112 | *.lzo 113 | *.lzs 114 | *.slg 115 | *.slo 116 | *.sls 117 | 118 | # uncomment this for glossaries-extra (will ignore makeindex's style files!) 119 | # *.ist 120 | 121 | # gnuplot 122 | *.gnuplot 123 | *.table 124 | 125 | # gnuplottex 126 | *-gnuplottex-* 127 | 128 | # gregoriotex 129 | *.gaux 130 | *.glog 131 | *.gtex 132 | 133 | # htlatex 134 | *.4ct 135 | *.4tc 136 | *.idv 137 | *.lg 138 | *.trc 139 | *.xref 140 | 141 | # hyperref 142 | *.brf 143 | 144 | # knitr 145 | *-concordance.tex 146 | # TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files 147 | # *.tikz 148 | *-tikzDictionary 149 | 150 | # listings 151 | *.lol 152 | 153 | # luatexja-ruby 154 | *.ltjruby 155 | 156 | # makeidx 157 | *.idx 158 | *.ilg 159 | *.ind 160 | 161 | # minitoc 162 | *.maf 163 | *.mlf 164 | *.mlt 165 | *.mtc[0-9]* 166 | *.slf[0-9]* 167 | *.slt[0-9]* 168 | *.stc[0-9]* 169 | 170 | # minted 171 | _minted* 172 | *.pyg 173 | 174 | # morewrites 175 | *.mw 176 | 177 | # newpax 178 | *.newpax 179 | 180 | # nomencl 181 | *.nlg 182 | *.nlo 183 | *.nls 184 | 185 | # pax 186 | *.pax 187 | 188 | # pdfpcnotes 189 | *.pdfpc 190 | 191 | # sagetex 192 | *.sagetex.sage 193 | *.sagetex.py 194 | *.sagetex.scmd 195 | 196 | # scrwfile 197 | *.wrt 198 | 199 | # svg 200 | svg-inkscape/ 201 | 202 | # sympy 203 | *.sout 204 | *.sympy 205 | sympy-plots-for-*.tex/ 206 | 207 | # pdfcomment 208 | *.upa 209 | *.upb 210 | 211 | # pythontex 212 | *.pytxcode 213 | pythontex-files-*/ 214 | 215 | # tcolorbox 216 | *.listing 217 | 218 | # thmtools 219 | *.loe 220 | 221 | # TikZ & PGF 222 | *.dpth 223 | *.md5 224 | *.auxlock 225 | 226 | # titletoc 227 | *.ptc 228 | 229 | # todonotes 230 | *.tdo 231 | 232 | # vhistory 233 | *.hst 234 | *.ver 235 | 236 | # easy-todo 237 | *.lod 238 | 239 | # xcolor 240 | *.xcp 241 | 242 | # xmpincl 243 | *.xmpi 244 | 245 | # xindy 246 | *.xdy 247 | 248 | # xypic precompiled matrices and outlines 249 | *.xyc 250 | *.xyd 251 | 252 | # endfloat 253 | *.ttt 254 | *.fff 255 | 256 | # Latexian 257 | TSWLatexianTemp* 258 | 259 | ## Editors: 260 | # WinEdt 261 | *.bak 262 | *.sav 263 | 264 | # Texpad 265 | .texpadtmp 266 | 267 | # LyX 268 | *.lyx~ 269 | 270 | # Kile 271 | *.backup 272 | 273 | # gummi 274 | .*.swp 275 | 276 | # KBibTeX 277 | *~[0-9]* 278 | 279 | # TeXnicCenter 280 | *.tps 281 | 282 | # auto folder when using emacs and auctex 283 | ./auto/* 284 | *.el 285 | 286 | # expex forward references with \gathertags 287 | *-tags.tex 288 | 289 | # standalone packages 290 | *.sta 291 | 292 | # Makeindex log files 293 | *.lpz 294 | 295 | # xwatermark package 296 | *.xwm 297 | 298 | # REVTeX puts footnotes in the bibliography by default, unless the nofootinbib 299 | # option is specified. Footnotes are the stored in a file with suffix Notes.bib. 300 | # Uncomment the next line to have this generated file ignored. 301 | #*Notes.bib 302 | 303 | *.pdf 304 | *.ps -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fitch.sty 2 | 3 | LaTeX macros for Fitch style natural deduction 4 | 5 | ## Usage 6 | 7 | Fitch-style natural deduction is a system for writing proofs in 8 | propositional logic and predicate logic. This is a set of easy-to-use 9 | LaTeX macros originally written by Peter Selinger. It is used, e.g., 10 | in the various versions of _forall x_ by PD Magnus (e.g., the 11 | [original](https://www.fecundity.com/logic/download.html), 12 | [Cambridge](http://www.homepages.ucl.ac.uk/~uctytbu/OERs.html), and 13 | [Calgary](https://forallx.openlogicproject.org) versions) 14 | 15 | With these macros, one can typeset natural deduction proofs in Fitch 16 | style, as in the following example: 17 | 18 | ![](fitchexample.png) 19 | 20 | ``` 21 | \begin{nd} 22 | \hypo {1} {\forall y \neg P(y)} 23 | \open 24 | \hypo {2} {\exists x P(x)} 25 | \open[u] 26 | \hypo {3} {P(u)} 27 | \have {4}{\forall y \neg P(y)} \r{1} 28 | \have {5} {\neg P(u)} \Ae{4} 29 | \have {6} {\bot} \ne{3,5} 30 | \close 31 | \have {6a} {\bot} \Ee{2,3-6} 32 | \close 33 | \have {7} {\neg \exists x P(x)} \ni{2-6a} 34 | \end{nd} 35 | ``` 36 | 37 | The output is shown above, and the corresponding LaTeX code below. 38 | 39 | ## Changes 40 | 41 | **v1.0-beta, October 15, 2023** Adds `outerline` option; improves 42 | `\by`; fixes spacing when using `tabular` 43 | 44 | **v1.0-alpha, Sept 30, 2023** This is an alpha release that adds key-value 45 | options to the package and commands for customization. It is not fully 46 | compatible with the 0.x versions (see documentation). Please report 47 | any issues or suggestions. 48 | 49 | **v0.6, Sept 4, 2023.** Updated the documentation and license (from 50 | GPL to LPPL). The code is essentially unchanged. 51 | 52 | **v0.5, Feb 8, 2005.** The ability to handle multi-line formulas 53 | was added. 54 | 55 | ## Download 56 | 57 | The package is available on CTAN as 58 | [`fitch`](https://ctan.org/pkg/fitch). 59 | 60 | The code is [maintained on Github](https://github.com/OpenLogicProject/fitch/). 61 | 62 | ## Related packages 63 | 64 | - [`logicproof`](https://ctan.org/pkg/logicproof): natural deduction 65 | with boxed subproofs in the style of Huth and Ryan's _Logic in 66 | Computer Science_. 67 | - [`lplfitch`](https://ctan.org/pkg/lplfitch): Fitch-style proofs in 68 | the format used in Barwise & Etchemendy's textbook _Language, Proof, 69 | and Logic_. 70 | - [`natded`](https://ctan.org/pkg/natded): natural deduction proofs 71 | in the style of Jaśkowski, or that of Kalish and Montague. 72 | - [`synproof`](https://ctan.org/pkg/synproof): natural deduction 73 | proofs in the style of Gamut's _Logic, 74 | Language, and Meaning_. 75 | 76 | 77 | Additional packages for proofs, including Johan Klüwer's, are 78 | available at a [page maintained by Alex Kocurek](https://www.actual.world/latex/) 79 | 80 | ## People 81 | 82 | Peter Selinger, Dalhousie University, is the original author. 83 | 84 | Richard Zach, University of Calgary, it the current maintainer. 85 | 86 | ## License 87 | 88 | Copyright (C) 2002-2023 Peter Selinger 89 | 90 | This work may be distributed and/or modified under the conditions of 91 | the LaTeX Project Public License, either version 1.3 of this license 92 | or (at your option) any later version. The latest version of this 93 | license is in 94 | 95 | https://www.latex-project.org/lppl.txt 96 | 97 | and version 1.3c or later is part of all distributions of LaTeX 98 | version 2008 or later. -------------------------------------------------------------------------------- /fitch.hacker.txt: -------------------------------------------------------------------------------- 1 | This file describes the internals of the macros in fitch.sty. It is 2 | intended for programmers who might want to hack this package. For 3 | information on how to use the package, please see the user guide, 4 | which is provided in the file fitchdoc.tex. 5 | 6 | GENERAL 7 | 8 | Global identifiers defined by this package start with '\nd@'. The only 9 | exceptions are \ndref, \nddim, \ndindent, and the "nd" and "ndresume" 10 | latex environments. 11 | 12 | The macros provided by this package mix TeX and LaTeX primitives. 13 | LaTeX is used for \rule, \settowidth, \addtolength, \hspace... All 14 | macros are assumed to be called in math mode. 15 | 16 | Translation proceeds through several layers of macros. Each layer 17 | consist of macros which expand into macros of the previous layer. Each 18 | layer may have some global state and initialization functions. Only 19 | the topmost layer (layer D) is directly user-accessible. 20 | 21 | REFERENCES 22 | 23 | We start with some macros to facilitate automatic line numbering, and 24 | for referencing of lines by labels. The macros defined here are: 25 | \nd@reset to reset the line number count. \nd@num{x}, to generate the 26 | next line number and store it in reference x; \nd@ref{x} to print the 27 | line number referenced by x, \ndref{xxx} to parse a list of 28 | references, separated by commas, periods, and hyphens, and translate 29 | all references to line numbers. Note: \ndref ignores spaces in its 30 | argument, but puts a space after each comma or period in the 31 | output. Also note: \nd@ref can be useful outside a natded environment, 32 | and thus it has a user accessible name. Most general ``line numbers'' 33 | actually consist of a name (such as ``n'') and a number (such as 34 | ``2''), to produce output such as $n+2$. \nd@set{n}{m} is called to 35 | set the letter to n and the number to m. As special cases, if the 36 | second argument is empty, it is not set, and if the first argument is 37 | \relax, it is not set. 38 | 39 | Example for references: 40 | 41 | \nd@reset \nd@num{x}; \nd@num{y}; \nd@numopt{n+1}{z}; \nd@num{zz}; 42 | \nd@ref{y}; \ndref{x, y-zz, z} 43 | will produce: 1; 2; n+1; 3; 2; 1, 2-3, n+1 44 | 45 | LAYER A 46 | 47 | Layer A provides primitive picture elements which can be combined into 48 | natural deduction derivations. These are: \nd@t to make a topmost 49 | vertical line segment; \nd@v to make a continuation vertical line 50 | segment, \nd@i to produce the indentation for a subproof, \nd@s to 51 | produce the horizontal space between a vertical line and a formula, 52 | \nd@u{x} to underline x with appropriate spacing for a 53 | hypothesis. \nd@f{x} typesets the formula x with the appropriate 54 | vertical spacing. \nd@g{x} is like \nd@i, except it puts a guard in 55 | the space it creates. These elements are spaced so that they are 56 | appropriate as left-aligned array entries. Line numberings and 57 | justifications must be provided manually in this layer. All explicit 58 | spacing information is contained in this layer; higher layers 59 | manipulate only layer A primitives. 60 | 61 | Example of a derivation using layer A syntax: 62 | 63 | \[ 64 | \begin{array}{lll} 65 | 1 & \nd@t\nd@s\nd@f {P\vee Q} \\ 66 | 2 & \nd@v\nd@s\nd@u {\neg Q} \\ 67 | 3 & \nd@v\nd@i\nd@t\nd@s\nd@u {P} \\ 68 | 4 & \nd@v\nd@i\nd@v\nd@s\nd@f {P} & \mbox{by 3} \\ 69 | 5 & \nd@v\nd@i\nd@t\nd@s\nd@u {Q} \\ 70 | 6 & \nd@v\nd@i\nd@v\nd@s\nd@f {\neg Q} & \mbox{by 2} \\ 71 | 7 & \nd@v\nd@i\nd@v\nd@s\nd@f {\bot} & \mbox{by 5, 6} \\ 72 | 8 & \nd@v\nd@i\nd@v\nd@s\nd@f {P} & \mbox{by 7} \\ 73 | 9 & \nd@v\nd@s\nd@f {P} & \mbox{by 1, 3-4, 5-8} \\ 74 | \end{array} 75 | \] 76 | 77 | LISTS 78 | 79 | This is a bit of a hack. We implement linked lists as follows: a list 80 | is either \nd@nil, or \nd@cons{T}{H}, where T is another list, and H 81 | is some arbitrary code. Note that lists grow to the right. The 82 | following macros operate on a list that is stored in a macro \list. 83 | 84 | \nd@push\list{item} pushes the item onto the list 85 | \nd@pop\list{item} pops and discards the last item from the list 86 | \nd@item\list{command} applies command to each element of the list 87 | \nd@modify\list\n{elt} modifies the \n-th element of the 88 | list, if there is such an element. Here \n is a counter. Elements 89 | are counted from the right, starting from 1. 90 | 91 | We use lists of items of the forms \nd@t, \nd@v, \nd@i, and \nd@g{...} 92 | to represent the current indentation level and format (see Layer A, 93 | above). The function \nd@cont computes the indentation for the 94 | following line by replacing all items of the form \nd@t by \nd@v and 95 | \nd@g{...} by \nd@i. 96 | 97 | With the list syntax, a derivation can be expressed like this: 98 | 99 | \[ 100 | \begin{array}{lll} 101 | \gdef\stack{\nd@nil} 102 | \newcount\n 103 | \nd@push\stack{\nd@t} 104 | 1 & \nd@iter\stack\relax\nd@s\nd@u {\neg\exists xP(x)} \\ 105 | \nd@cont\stack 106 | \nd@push\stack{\nd@i} 107 | \nd@push\stack{\nd@t} 108 | \nd@n=2\nd@modify\stack\n{\nd@g{u}} 109 | \nd@push\stack{\nd@i} 110 | \nd@push\stack{\nd@t} 111 | 2 & \nd@iter\stack\relax\nd@s\nd@u {P(u)} \\ 112 | \nd@cont\stack 113 | 3 & \nd@iter\stack\relax\nd@s\nd@f {\exists xP(x)} \\ 114 | \nd@cont\stack 115 | 4 & \nd@iter\stack\relax\nd@s\nd@f {\neg\exists xP(x)} \\ 116 | \nd@cont\stack 117 | 5 & \nd@iter\stack\relax\nd@s\nd@f {\bot} \\ 118 | \nd@cont\stack 119 | \nd@pop\stack 120 | \nd@pop\stack 121 | 6 & \nd@iter\stack\relax\nd@s\nd@f {\neg P(u)} \\ 122 | \nd@cont\stack 123 | \nd@pop\stack 124 | \nd@pop\stack 125 | 7 & \nd@iter\stack\relax\nd@s\nd@f {\forall y\neg P(y)} \\ 126 | \nd@cont\stack 127 | \end{array} 128 | \] 129 | 130 | LAYER B 131 | 132 | Layer B is simply a wrapper around layer A. It provides commands 133 | \nd@beginb, \nd@resumeb, \nd@endb, \nd@openb, \nd@closeb, \nd@guardb, 134 | \nd@hypob, and \nd@haveb which abstract from the layer A 135 | primitives. This includes automatic line numbering, and automatic 136 | indentation. \nd@hypocontb and \nd@havecontb are like \nd@hypob and 137 | \nd@haveb, except that they introduce continuation lines that are 138 | slightly indented and have no line number/label. \nd@beginb and 139 | \nd@endb enclose a natural deduction in layer B syntax. \nd@resumeb is 140 | like \nd@beginb, except that it resumes a deduction in progress (for 141 | instance, after a manual page break). \nd@openb and \nd@closeb open, 142 | respectively close, a subproof. \nd@guardb{n}{g} adds the guard g to 143 | the nth enclosing subderivation (counted from 1 from the 144 | inside). \nd@hypob introduces a hypothesis, and \nd@haveb introduces a 145 | non-hypothesis line in a proof. Line numbering is integrated, but 146 | justifications must still be given manually. Also, proof lines must 147 | still be terminated by '\\'. An idiosyncracy of this layer is that in 148 | a list of several hypotheses, all but the last one must be called with 149 | \nd@haveb, not \nd@hypob, to avoid drawing a horizontal line under 150 | each of them. 151 | 152 | Example of a derivation using layer B syntax. Note that the "line 153 | numbers" are really labels, which will be replaced by consecutive line 154 | numbers in the output. 155 | 156 | \[ 157 | \nd@beginb 158 | \nd@haveb {1}{P\vee Q} \\ 159 | \nd@hypob {2}{\neg Q} \\ 160 | \nd@openb 161 | \nd@hypob {3}{P} \\ 162 | \nd@haveb {4}{P} \mbox{by \ndref{3}} \\ 163 | \nd@closeb 164 | \nd@openb 165 | \nd@hypob {5}{Q} \\ 166 | \nd@haveb {6}{\neg Q} \mbox{by \ndref{2}} \\ 167 | \nd@haveb {6a}{\bot} \mbox{by \ndref{5,6}} \\ 168 | \nd@haveb {6b}{P} \mbox{by \ndref{6a}} \\ 169 | \nd@closeb 170 | \nd@haveb {8}{P} \mbox{by \ndref{1,3-4,5-6b}} \\ 171 | \nd@endb 172 | \] 173 | 174 | Here is another example, using a guard. 175 | 176 | \[ 177 | \nd@beginb 178 | \nd@hypob {1}{\neg\exists xP(x)} \\ 179 | \nd@openb 180 | \nd@guardb {1}{u} 181 | \nd@openb 182 | \nd@hypob {2}{P(u)} \\ 183 | \nd@haveb {3}{\exists xP(x)} \mbox{by \ndref{2}} \\ 184 | \nd@haveb {4}{\neg\exists xP(x)} \mbox{by \ndref{1}} \\ 185 | \nd@haveb {5}{\bot} \mbox{by \ndref{3,4}}\\ 186 | \nd@closeb 187 | \nd@haveb {6}{\neg P(u)} \mbox{by \ndref{2-5}}\\ 188 | \nd@closeb 189 | \nd@haveb {7}{\forall y\neg P(y)} \mbox{by \ndref{2-6}}\\ 190 | \nd@endb 191 | \] 192 | 193 | LAYER C 194 | 195 | Layer C is a wrapper around layer B. It takes care of buffering 196 | information and putting it correctly into an array. Specifically, in 197 | layer C, it is no more necessary to explicitly give '\\', and all 198 | hypotheses are denoted \hypo. Layer C also provides a convenient 199 | syntax for writing justification labels. Further, layer C provides 200 | ``multi-line'' commands, thus e.g. \nd@mhypoc{a}{x\\y\\z} is an 201 | abbreviation for \nd@hypoc{a}{x}\nd@hypocontc{y}\nd@hypocontc{z}. In 202 | addition there is a \nd@by command for writing justification labels, 203 | in the style of \nd@by{$\vee$E}{1,2-4,5-6}. 204 | 205 | Commands exported by layer C are: \nd@hypoc, \nd@havec, \nd@hypocontc, 206 | \nd@havecontc, \nd@mhypoc, \nd@mhavec, \nd@mhypocontc, \nd@mhavecontc, 207 | \nd@by, \nd@beginc, \nd@resumec, \nd@endc, \nd@openc, \nd@closec, 208 | \nd@guardc. 209 | 210 | The layer C macros work by storing each line in a data structure 211 | \ppp,\nd@typ,\nd@byt. The line is ejected when the beginning of the 212 | next line is read, and once at the very end. In this way, we can put 213 | in the correct line breaks (whether or not the line carries a 214 | justification), and a hypothesis does not get typeset until we know 215 | whether it is followed by another hypothesis. \nd@sto stores a new 216 | line, \nd@clr clears the current line, \nd@cmd outputs the current 217 | line. 218 | 219 | Example of layer C syntax: 220 | 221 | \[ 222 | \nd@beginc 223 | \nd@hypoc {1}{\neg\exists xP(x)} 224 | \nd@openc 225 | \nd@guardc {1}{u} 226 | \nd@openc 227 | \nd@hypoc {2}{P(u)} 228 | \nd@havec {3}{\exists xP(x)} \nd@by{$\exists$I}{2} 229 | \nd@havec {4}{\neg\exists xP(x)} \nd@by{R}{1} 230 | \nd@havec {5}{\bot} \nd@by{$\neg$E}{3,4} 231 | \nd@closec 232 | \nd@havec {6}{\neg P(u)} \nd@by{$\neg$I}{2-5} 233 | \nd@closec 234 | \nd@havec {7}{\forall y\neg P(y)} \nd@by{$\forall$I}{2-6} 235 | \nd@endc 236 | \] 237 | 238 | LAYER D 239 | 240 | Layer D is the syntax used by the end user. It is implemented as a 241 | wrapper around layer C, providing three additional conveniences: (1) a 242 | latex environment, (2) guard as optional argument to \have, \hypo, or 243 | \open, (3) optional relabeling arguments. The user level commands are 244 | similar to those of layer C: they are called \begin{nd}, \end{nd}, 245 | \open, \close, \hypo, \have, \guard, \by. For convenience, a number 246 | of abbreviations are also provided for writing justifications. For 247 | instance \ie for \by{$\Rightarrow$E} etc. These commands are only 248 | visible inside an nd-environment; thus they do not interfere with the 249 | global name space. There is also an environment ndresume which is like 250 | nd, except that it continues a proof in progress (with continuous 251 | nesting and labeling). 252 | 253 | The macros \nd@hypod, \nd@haved, \nd@opend, \nd@guardd are essentially 254 | the user-level macros, but with all optional argument spelled-out. The 255 | versions without the final "d" allow the optional arguments to be 256 | omitted. 257 | 258 | The functions \nd@optarg and \nd@optargg are used to handle optional 259 | arguments. Usage: \nd@optarg{default}{continuation}xxx - reads an 260 | optional argument, supplies default if necessary, then continues with 261 | continuation. Continuation expects optional argument between 262 | [...]. I.e., \nd@optarg{d}{c}[xxx] => c[xxx], and \nd@optarg{d}{c}x => 263 | c[d]x if x != '['. Behavior is undefined if x is {[...}. \nd@optargg 264 | is similar except it takes two continuations: first one for optional 265 | argument present, second for not present. It takes no default value. 266 | 267 | The function \nd@five{\a} reads five, partly optional arguments of the 268 | shape [][]{}[]{}, then call \a with these arguments. 269 | 270 | Finally, \nd@init puts all the commands which are visible inside an 271 | nd-environment in the current name space. 272 | 273 | Example of a derivation using layer D syntax. As before, the "line 274 | numbers" are really labels, which will be replaced by consecutive line 275 | numbers in the output. 276 | 277 | \[ 278 | \begin{nd} 279 | \hypo{1} {P\vee Q} 280 | \hypo{2} {\neg Q} 281 | \open 282 | \hypo{3a} {P} 283 | \have{3b} {P} \r{3a} 284 | \close 285 | \open 286 | \hypo{4a} {Q} 287 | \have{4b} {\neg Q} \r{2} 288 | \have{4c} {\bot} \ne{4a,4b} 289 | \have{4d} {P} \be{4c} 290 | \close 291 | \have{5} {P} \oe{1,3a-3b,4a-4d} 292 | \end{nd} 293 | \] 294 | 295 | Another example of layer D syntax, using guards and relabelings: 296 | 297 | \[ 298 | \begin{nd} 299 | \hypo {1} {P\vee Q} 300 | \open[u] 301 | \hypo {2} {P} 302 | \have [\vdots] {3} {\vdots} 303 | \have [n][-1] {4} {A\wedge B} 304 | \close 305 | \open 306 | \hypo {5} {Q} 307 | \have [\vdots] {6} {\vdots} 308 | \have [m] {7} {A\wedge B} 309 | \close 310 | \have {8} {A\wedge B} \oe{1,2-(4),5-7} 311 | \have [\vdots] {9} {\vdots} 312 | \have [][100] {10} {A} \ae{8} 313 | \end{nd} 314 | \] 315 | -------------------------------------------------------------------------------- /fitch.sty: -------------------------------------------------------------------------------- 1 | %% fitch.sty 2 | %% Macros for Fitch-style natural deduction 3 | %% Copyright 2002-2023 Peter Selinger 4 | % 5 | % This work may be distributed and/or modified under the 6 | % conditions of the LaTeX Project Public License, either version 1.3 7 | % of this license or (at your option) any later version. 8 | % The latest version of this license is in 9 | % https://www.latex-project.org/lppl.txt 10 | % and version 1.3c or later is part of all distributions of LaTeX 11 | % version 2008 or later. 12 | % 13 | % This work has the LPPL maintenance status `maintained'. 14 | % 15 | % The Current Maintainer of this work is Richard Zach 16 | % 17 | % This work consists of the files fitch.sty and fitchdoc.tex. 18 | 19 | % Original Author: Peter Selinger, Dalhousie University 20 | % Created: Jan 14, 2002 21 | % Modified: December 17, 2023 22 | % Version: 1.0 23 | % Copyright: (C) 2002-2005 Peter Selinger, Richard Zach 24 | % Filename: fitch.sty 25 | % Documentation: fitchdoc.tex 26 | % https://github.com/OpenLogicProject/fitch/ 27 | 28 | % USAGE EXAMPLE: 29 | % 30 | % The following is a simple example illustrating the usage of this 31 | % package. For detailed instructions and additional functionality, see 32 | % the user guide, which can be found in the file fitchdoc.tex. 33 | % 34 | % \[ 35 | % \begin{nd} 36 | % \hypo{1} {P\vee Q} 37 | % \hypo{2} {\neg Q} 38 | % \open 39 | % \hypo{3a} {P} 40 | % \have{3b} {P} \r{3a} 41 | % \close 42 | % \open 43 | % \hypo{4a} {Q} 44 | % \have{4b} {\neg Q} \r{2} 45 | % \have{4c} {\bot} \ne{4a,4b} 46 | % \have{4d} {P} \be{4c} 47 | % \close 48 | % \have{5} {P} \oe{1,3a-3b,4a-4d} 49 | % \end{nd} 50 | % \] 51 | 52 | \NeedsTeXFormat{LaTeX2e} 53 | \ProvidesPackage{fitch}[2023-12-17 v1.0 Macros for Fitch-style natural deduction] 54 | 55 | % Define keyval options 56 | 57 | \RequirePackage{kvoptions} 58 | 59 | \SetupKeyvalOptions{ 60 | family = fitch, 61 | prefix = nd@ % prefix with nd@ for compatibility with old code 62 | } 63 | 64 | \DeclareStringOption[ndrules]{rules} 65 | \DeclareStringOption[array]{arrayenv} 66 | \DeclareStringOption[ndjustformat]{justformat} 67 | \DeclareStringOption[ndrefformat]{refformat} 68 | 69 | \DeclareStringOption[4.5ex]{height}[4.5ex] 70 | \DeclareStringOption[3.5ex]{topheight}[3.5ex] 71 | \DeclareStringOption[1.5ex]{depth}[1.5ex] 72 | \DeclareStringOption[1em]{labelsep}[1em] 73 | \DeclareStringOption[1.6em]{indent}[1.6em] 74 | \DeclareStringOption[1.5ex]{hsep}[1.5ex] 75 | \DeclareStringOption[2.5em]{justsep}[2.5em] 76 | \DeclareStringOption[.2mm]{linethickness}[.2mm] 77 | \DeclareStringOption[1em]{cindent}[1em] 78 | \DeclareBoolOption[true]{outerline} 79 | 80 | % user command to redefine dimensions 81 | \def\nddim#1#2#3#4#5#6#7#8{ 82 | \setkeys{fitch}{ 83 | height=#1, 84 | topheight=#2, 85 | depth=#3, 86 | labelsep=#4, 87 | indent=#5, 88 | hsep=#6, 89 | justsep=#7, 90 | linethickness=#8 91 | } 92 | } 93 | 94 | \DeclareLocalOptions{ 95 | rules, 96 | arrayenv, 97 | justformat, 98 | refformat, 99 | height, 100 | topheight, 101 | depth, 102 | labelsep, 103 | indent, 104 | hsep, 105 | justsep, 106 | linethickness, 107 | cindent, 108 | outerline 109 | } 110 | 111 | \ProcessLocalKeyvalOptions{fitch} 112 | 113 | % Actual fitch.sty code 114 | 115 | \newlength{\nd@dim} 116 | 117 | % References 118 | 119 | \newcount\nd@ctr 120 | \def\nd@render{\expandafter\ifx\expandafter\nd@x\nd@base\nd@x\the\nd@ctr\else\nd@base\ifnum\nd@ctr<0\the\nd@ctr\else\ifnum\nd@ctr>0+\the\nd@ctr\fi\fi\fi} 121 | \expandafter\def\csname nd@-\endcsname{} 122 | 123 | \def\nd@num#1{\nd@numo{\nd@render}{#1}\global\advance\nd@ctr1} 124 | \def\nd@numopt#1#2{\nd@numo{$#1$}{#2}} 125 | \def\nd@numo#1#2{\edef\x{#1}\mbox{$\x$}\expandafter\global\expandafter\let\csname nd@-#2\endcsname\x} 126 | \def\nd@ref#1{\expandafter\let\expandafter\x\csname nd@-#1\endcsname\ifx\x\relax% 127 | \PackageWarning{fitch}{Undefined line reference: #1}\mbox{\textbf{??}}\else\csname\nd@refformat\endcsname{\mbox{$\x$}}\fi} 128 | \def\nd@noop{} 129 | \def\nd@set#1#2{\ifx\relax#1\nd@noop\else\global\def\nd@base{#1}\fi\ifx\relax#2\relax\else\global\nd@ctr=#2\fi} 130 | \def\nd@reset{\nd@set{}{1}} 131 | \def\nd@refa#1{\nd@ref{#1}} 132 | \def\nd@aux#1#2{\ifx#2-\nd@refa{#1}--\def\nd@c{\nd@aux{}}% 133 | \else\ifx#2,\nd@refa{#1}, \def\nd@c{\nd@aux{}}% 134 | \else\ifx#2;\nd@refa{#1}; \def\nd@c{\nd@aux{}}% 135 | \else\ifx#2.\nd@refa{#1}. \def\nd@c{\nd@aux{}}% 136 | \else\ifx#2)\nd@refa{#1})\def\nd@c{\nd@aux{}}% 137 | \else\ifx#2(\nd@refa{#1}(\def\nd@c{\nd@aux{}}% 138 | \else\ifx#2\nd@end\nd@refa{#1}\def\nd@c{}% 139 | \else\def\nd@c{\nd@aux{#1#2}}% 140 | \fi\fi\fi\fi\fi\fi\fi\nd@c} 141 | \def\ndref#1{\nd@aux{}#1\nd@end} 142 | 143 | % Layer A 144 | 145 | % set initial dimensions 146 | %\nddim{4.5ex}{3.5ex}{1.5ex}{1em}{1.6em}{.5em}{2.5em}{.2mm} 147 | 148 | \def\nd@v{\rule[-\nd@depth]{\nd@linethickness}{\nd@height}} 149 | \def\nd@h{\rule[-\nd@depth]{0mm}{\nd@height}} % strut 150 | \def\nd@t{\rule[-\nd@depth]{\nd@linethickness}{\nd@topheight}} 151 | \def\nd@i{\hspace{\nd@indent}} 152 | \def\nd@s{\hspace{\nd@hsep}} 153 | \def\nd@g#1{\nd@f{\makebox[\nd@indent][c]{$#1$}}} 154 | \def\nd@f#1{\raisebox{0pt}[0pt][0pt]{$#1$}} 155 | \def\nd@u#1{\makebox[0pt][l]{\settowidth{\nd@dim}{\nd@f{#1}}% 156 | \addtolength{\nd@dim}{\nd@hsep}\addtolength{\nd@dim}{\nd@hsep}% 157 | \hspace{-\nd@hsep}\rule[-\nd@depth]{\nd@dim}{\nd@linethickness}}\nd@f{#1}} 158 | 159 | % Lists 160 | 161 | \def\nd@push#1#2{\expandafter\gdef\expandafter#1\expandafter% 162 | {\expandafter\nd@cons\expandafter{#1}{#2}}} 163 | \def\nd@pop#1{{\def\nd@nil{\gdef#1{\nd@nil}}\def\nd@cons##1##2% 164 | {\gdef#1{##1}}#1}} 165 | \def\nd@iter#1#2{{\def\nd@nil{}\def\nd@cons##1##2{##1#2{##2}}#1}} 166 | \def\nd@modify#1#2#3{{\def\nd@nil{\gdef#1{\nd@nil}}\def\nd@cons##1##2% 167 | {\advance#2-1 ##1\advance#2 1 \ifnum#2=1\nd@push#1{#3}\else% 168 | \nd@push#1{##2}\fi}#1}} 169 | 170 | \def\nd@cont#1{{\def\nd@t{\nd@v}\def\nd@v{\nd@v}\def\nd@g##1{\nd@i}% 171 | \def\nd@i{\nd@i}\def\nd@nil{\gdef#1{\nd@nil}}\def\nd@cons##1##2% 172 | {##1\expandafter\nd@push\expandafter#1\expandafter{##2}}#1}} 173 | 174 | % Layer B 175 | 176 | \newcount\nd@n 177 | \def\nd@beginb{% 178 | \begingroup 179 | \nd@reset 180 | \gdef\nd@stack{\nd@nil}% 181 | \nd@push\nd@stack{\nd@h}% 182 | \ifnd@outerline 183 | \nd@push\nd@stack{\nd@t}\fi 184 | \begin{\nd@arrayenv}{l@{\hspace{\nd@labelsep}}l@{\hspace{\nd@justsep}}l}} 185 | \def\nd@resumeb{% 186 | \begingroup 187 | \begin{\nd@arrayenv}{l@{\hspace{\nd@labelsep}}l@{\hspace{\nd@justsep}}l}} 188 | \def\nd@endb{\end{\nd@arrayenv}\endgroup} 189 | \def\nd@hypob#1#2{\nd@f{\nd@num{#1}}&\nd@iter\nd@stack\relax\nd@cont\nd@stack\nd@s\nd@u{#2}&} 190 | \def\nd@haveb#1#2{\nd@f{\nd@num{#1}}&\nd@iter\nd@stack\relax\nd@cont\nd@stack\nd@s\nd@f{#2}&} 191 | \def\nd@havecontb#1#2{&\nd@iter\nd@stack\relax\nd@cont\nd@stack\nd@s\nd@f{\hspace{\nd@cindent}#2}&} 192 | \def\nd@hypocontb#1#2{&\nd@iter\nd@stack\relax\nd@cont\nd@stack\nd@s\nd@u{\hspace{\nd@cindent}#2}&} 193 | 194 | \def\nd@openb{\nd@push\nd@stack{\nd@i}\nd@push\nd@stack{\nd@t}} 195 | \def\nd@closeb{\nd@pop\nd@stack\nd@pop\nd@stack} 196 | \def\nd@guardb#1#2{\nd@n=#1\multiply\nd@n by 2 \nd@modify\nd@stack\nd@n{\nd@g{#2}}} 197 | 198 | % Layer C 199 | 200 | \def\nd@clr{\gdef\nd@cmd{}\gdef\nd@typ{\relax}} 201 | \def\nd@sto#1#2#3{\gdef\nd@typ{#1}\gdef\nd@byt{}% 202 | \gdef\nd@cmd{\nd@typ{#2}{#3}\nd@byt\\}} 203 | \def\nd@chtyp{\expandafter\ifx\nd@typ\nd@hypocontb\def\nd@typ{\nd@havecontb}\else\def\nd@typ{\nd@haveb}\fi} 204 | \def\nd@hypoc#1#2{\nd@chtyp\nd@cmd\nd@sto{\nd@hypob}{#1}{#2}} 205 | \def\nd@havec#1#2{\nd@cmd\nd@sto{\nd@haveb}{#1}{#2}} 206 | \def\nd@hypocontc#1{\nd@chtyp\nd@cmd\nd@sto{\nd@hypocontb}{}{#1}} 207 | \def\nd@havecontc#1{\nd@cmd\nd@sto{\nd@havecontb}{}{#1}} 208 | \def\nd@by#1#2{\ifx\nd@x#2\nd@x\gdef\nd@byt{\mbox{#1}}\else\ifx\nd@x#1\nd@x\gdef\nd@byt{\mbox{\ndref{#2}}}\else\gdef\nd@byt{\mbox{\csname\nd@justformat\endcsname{#1}{\ndref{#2}}}}\fi\fi\ignorespaces} 209 | 210 | % multi-line macros 211 | \def\nd@mhypoc#1#2{\nd@mhypocA{#1}#2\\\nd@stop\\} 212 | \def\nd@mhypocA#1#2\\{\nd@hypoc{#1}{#2}\nd@mhypocB} 213 | \def\nd@mhypocB#1\\{\ifx\nd@stop#1\else\nd@hypocontc{#1}\expandafter\nd@mhypocB\fi} 214 | \def\nd@mhavec#1#2{\nd@mhavecA{#1}#2\\\nd@stop\\} 215 | \def\nd@mhavecA#1#2\\{\nd@havec{#1}{#2}\nd@mhavecB} 216 | \def\nd@mhavecB#1\\{\ifx\nd@stop#1\else\nd@havecontc{#1}\expandafter\nd@mhavecB\fi} 217 | \def\nd@mhypocontc#1{\nd@mhypocB#1\\\nd@stop\\} 218 | \def\nd@mhavecontc#1{\nd@mhavecB#1\\\nd@stop\\} 219 | 220 | \def\nd@beginc{\nd@beginb\nd@clr} 221 | \def\nd@resumec{\nd@resumeb\nd@clr} 222 | \def\nd@endc{\nd@cmd\nd@endb} 223 | \def\nd@openc{\nd@cmd\nd@clr\nd@openb} 224 | \def\nd@closec{\nd@cmd\nd@clr\nd@closeb} 225 | \let\nd@guardc\nd@guardb 226 | 227 | % Layer D 228 | 229 | % macros with optional arguments spelled-out 230 | \def\nd@hypod[#1][#2]#3[#4]#5{\ifx\relax#4\relax\else\nd@guardb{1}{#4}\fi\nd@mhypoc{#3}{#5}\nd@set{#1}{#2}\ignorespaces} 231 | \def\nd@haved[#1][#2]#3[#4]#5{\ifx\relax#4\relax\else\nd@guardb{1}{#4}\fi\nd@mhavec{#3}{#5}\nd@set{#1}{#2}\ignorespaces} 232 | \def\nd@havecont#1{\nd@mhavecontc{#1}} 233 | \def\nd@hypocont#1{\nd@mhypocontc{#1}} 234 | \def\nd@base{undefined} 235 | \def\nd@opend[#1]#2{\nd@cmd\nd@clr\nd@openb\nd@guard{#1}#2} 236 | \def\nd@close{\nd@cmd\nd@clr\nd@closeb} 237 | \def\nd@guardd[#1]#2{\nd@guardb{#1}{#2}} 238 | 239 | % Handling of optional arguments. 240 | 241 | \def\nd@optarg#1#2#3{\ifx[#3\def\nd@c{#2#3}\else\def\nd@c{#2[#1]{#3}}\fi\nd@c} 242 | \def\nd@optargg#1#2#3{\ifx[#3\def\nd@c{#1#3}\else\def\nd@c{#2{#3}}\fi\nd@c} 243 | 244 | \def\nd@five#1{\nd@optargg{\nd@four{#1}}{\nd@two{#1}}} 245 | \def\nd@four#1[#2]{\nd@optarg{0}{\nd@three{#1}[#2]}} 246 | \def\nd@three#1[#2][#3]#4{\nd@optarg{}{#1[#2][#3]{#4}}} 247 | \def\nd@two#1{\nd@three{#1}[\relax][]} 248 | 249 | \def\nd@have{\nd@five{\nd@haved}} 250 | \def\nd@hypo{\nd@five{\nd@hypod}} 251 | \def\nd@open{\nd@optarg{}{\nd@opend}} 252 | \def\nd@guard{\nd@optarg{1}{\nd@guardd}} 253 | 254 | \def\nd@init{% 255 | \let\open\nd@open% 256 | \let\close\nd@close% 257 | \let\hypo\nd@hypo% 258 | \let\have\nd@have% 259 | \let\hypocont\nd@hypocont% 260 | \let\havecont\nd@havecont% 261 | \let\by\nd@by% 262 | \let\guard\nd@guard% 263 | \csname\nd@rules\endcsname 264 | } 265 | 266 | % Define default rule names 267 | 268 | \def\ndrules{% 269 | \def\ii{\by{$\Rightarrow$I}}% 270 | \def\ie{\by{$\Rightarrow$E}}% 271 | \def\Ai{\by{$\forall$I}}% 272 | \def\Ae{\by{$\forall$E}}% 273 | \def\Ei{\by{$\exists$I}}% 274 | \def\Ee{\by{$\exists$E}}% 275 | \def\ai{\by{$\wedge$I}}% 276 | \def\ae{\by{$\wedge$E}}% 277 | \def\ai{\by{$\wedge$I}}% 278 | \def\ae{\by{$\wedge$E}}% 279 | \def\oi{\by{$\vee$I}}% 280 | \def\oe{\by{$\vee$E}}% 281 | \def\ni{\by{$\neg$I}}% 282 | \def\ne{\by{$\neg$E}}% 283 | \def\be{\by{$\bot$E}}% 284 | \def\nne{\by{$\neg\neg$E}}% 285 | \def\r{\by{R}}} 286 | 287 | % default justification format 288 | 289 | \newcommand{\ndjustformat}[2]{#1, #2} 290 | 291 | % default line number format 292 | 293 | \newcommand{\ndrefformat}[1]{#1} 294 | 295 | % User-level commands for proofs 296 | 297 | \newenvironment{nd}[1][] 298 | {\begingroup 299 | \setkeys{fitch}{#1}% 300 | \nd@init\nd@beginc\ignorespaces} 301 | {\nd@endc\endgroup} 302 | \newenvironment{ndresume}[1][] 303 | {\begingroup 304 | \setkeys{fitch}{#1}% 305 | \nd@init\nd@resumec\ignorespaces} 306 | {\nd@endc\endgroup} 307 | \newenvironment{fitchproof}[1][] 308 | {\begin{list}{}{\setlength{\leftmargin}{0pt}}\item\begin{nd}[#1]} 309 | {\end{nd}\end{list}} 310 | \newenvironment{fitchproof*}[1][] 311 | {\begin{list}{}{\setlength{\leftmargin}{0pt}}\item\begin{ndresume}[#1]} 312 | {\end{ndresume}\end{list}} 313 | 314 | % End of file fitch.sty 315 | 316 | -------------------------------------------------------------------------------- /fitchdoc-dimen.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 2 | Landscape 3 | Center 4 | Inches 5 | Letter 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 11 | 3750 1650 2250 1650 12 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 13 | 3750 2100 2250 2100 14 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 15 | 4500 2100 6600 2100 16 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 17 | 5175 2700 6600 2700 18 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 19 | 3750 1650 3750 1050 20 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 21 | 4350 2250 4350 1050 22 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 23 | 4650 2700 4650 1050 24 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 25 | 4875 2700 4875 1050 26 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 27 | 5175 3300 5175 1050 28 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 29 | 3300 3300 3300 1050 30 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 31 | 6075 3300 6075 1050 32 | 2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2 33 | 4050 1950 6600 1950 34 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 35 | 1 1 1.00 45.00 30.00 36 | 1 1 1.00 45.00 30.00 37 | 2550 1650 2550 2100 38 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 39 | 1 1 1.00 45.00 30.00 40 | 1 1 1.00 45.00 30.00 41 | 6300 2100 6300 2700 42 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 43 | 1 1 1.00 45.00 30.00 44 | 1 1 1.00 45.00 30.00 45 | 6300 1950 6300 2100 46 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 47 | 1 1 1.00 45.00 30.00 48 | 1 1 1.00 45.00 30.00 49 | 5175 1350 6075 1350 50 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 51 | 1 1 1.00 45.00 30.00 52 | 1 1 1.00 45.00 30.00 53 | 4875 1350 5175 1350 54 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 55 | 1 1 1.00 45.00 30.00 56 | 1 1 1.00 45.00 30.00 57 | 4350 1350 4650 1350 58 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 59 | 1 1 1.00 45.00 30.00 60 | 1 1 1.00 45.00 30.00 61 | 3750 1350 4350 1350 62 | 2 1 0 1 0 7 50 0 -1 3.000 0 0 -1 1 1 2 63 | 1 1 1.00 45.00 30.00 64 | 1 1 1.00 45.00 30.00 65 | 3300 1350 3750 1350 66 | 2 1 0 3 0 7 50 0 -1 6.000 0 0 7 0 0 2 67 | 3750 1650 3750 3300 68 | 2 1 0 3 0 7 50 0 -1 6.000 0 0 7 0 0 2 69 | 3750 2100 4500 2100 70 | 2 1 0 3 0 7 50 0 -1 6.000 0 0 7 0 0 2 71 | 4350 2250 4350 3300 72 | 2 1 0 3 0 7 50 0 -1 6.000 0 0 7 0 0 2 73 | 4350 2700 5175 2700 74 | 4 0 0 50 0 1 24 0.0000 4 255 225 4050 1950 P\001 75 | 4 0 0 50 0 1 24 0.0000 4 330 270 4650 2550 Q\001 76 | 4 0 0 50 0 1 24 0.0000 4 255 225 4650 3150 R\001 77 | 4 0 0 50 0 1 24 0.0000 4 255 180 3150 1950 1\001 78 | 4 0 0 50 0 1 24 0.0000 4 255 645 6075 3150 Rule\001 79 | 4 0 0 50 0 1 24 0.0000 4 255 180 3150 2550 2\001 80 | 4 0 0 50 0 1 24 0.0000 4 255 180 3150 3150 3\001 81 | 4 0 0 50 0 1 10 1.5708 4 150 525 3600 1275 labelsep\001 82 | 4 0 0 50 0 1 10 1.5708 4 105 390 4125 1275 indent\001 83 | 4 0 0 50 0 1 10 1.5708 4 150 285 4575 1275 hsep\001 84 | 4 0 0 50 0 1 10 1.5708 4 150 285 5100 1275 hsep\001 85 | 4 0 0 50 0 1 10 1.5708 4 150 435 5700 1275 justsep\001 86 | 4 0 0 50 0 1 10 0.0000 4 150 345 6450 2100 depth\001 87 | 4 0 0 50 0 1 10 0.0000 4 150 375 6450 2475 height\001 88 | 4 0 0 50 0 1 10 0.0000 4 150 570 1875 1950 topheight\001 89 | -------------------------------------------------------------------------------- /fitchdoc-dimen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLogicProject/fitch/a23fbfe84a06e48728abe08d57b2c75ab80c054e/fitchdoc-dimen.pdf -------------------------------------------------------------------------------- /fitchdoc-dimen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 13 | 14 | 16 | 17 | 19 | 20 | 22 | 23 | 25 | 26 | 28 | 29 | 31 | 32 | 34 | 35 | 37 | 38 | 40 | 41 | 43 | 44 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 56 | 57 | 59 | 60 | 62 | 63 | 64 | 65 | 68 | 69 | 70 | 72 | 73 | 75 | 76 | 78 | 79 | 80 | 81 | 84 | 85 | 86 | 88 | 89 | 91 | 92 | 94 | 95 | 96 | 97 | 100 | 101 | 102 | 104 | 105 | 107 | 108 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | 120 | 121 | 123 | 124 | 126 | 127 | 128 | 129 | 132 | 133 | 134 | 136 | 137 | 139 | 140 | 142 | 143 | 144 | 145 | 148 | 149 | 150 | 152 | 153 | 155 | 156 | 158 | 159 | 160 | 161 | 164 | 165 | 166 | 168 | 169 | 171 | 172 | 174 | 175 | 177 | 178 | 180 | 181 | 183 | 184 | 186 | 187 | P 188 | 189 | Q 190 | 191 | R 192 | 193 | 1 194 | 195 | Rule 196 | 197 | 2 198 | 199 | 3 200 | 201 | 202 | labelsep 203 | 204 | 205 | indent 206 | 207 | 208 | hsep 209 | 210 | 211 | hsep 212 | 213 | 214 | justsep 215 | 216 | depth 217 | 218 | height 219 | 220 | topheight 221 | 222 | 223 | -------------------------------------------------------------------------------- /fitchdoc.tex: -------------------------------------------------------------------------------- 1 | %% fitchdoc.tex 2 | %% Macros for Fitch-style natural deduction (documentation) 3 | %% Copyright 2002-2023 Peter Selinger 4 | % 5 | % This work may be distributed and/or modified under the 6 | % conditions of the LaTeX Project Public License, either version 1.3 7 | % of this license or (at your option) any later version. 8 | % The latest version of this license is in 9 | % https://www.latex-project.org/lppl.txt 10 | % and version 1.3c or later is part of all distributions of LaTeX 11 | % version 2008 or later. 12 | % 13 | % This work has the LPPL maintenance status `maintained'. 14 | % 15 | % The Current Maintainer of this work is Richard Zach 16 | % 17 | % This work consists of the files fitch.sty and fitchdoc.tex. 18 | 19 | % Original Author: Peter Selinger, Dalhousie University 20 | % Created: Jan 14, 2002 21 | % Modified: Dec 17, 2023 22 | % Version: 1.0 23 | % Copyright: (C) 2002-2023 Peter Selinger, Richard Zach 24 | % Filename: fitch.sty 25 | % Documentation: fitchdoc.tex 26 | % https://github.com/OpenLogicProject/fitch/ 27 | 28 | \documentclass{ltxdoc} 29 | 30 | \usepackage{fitch,graphicx,showexpl} 31 | 32 | \lstset{% 33 | basicstyle=\ttfamily\small, 34 | commentstyle=\itshape\ttfamily\small, 35 | showspaces=false, 36 | showstringspaces=false, 37 | breaklines=true, 38 | breakautoindent=true, 39 | captionpos=t 40 | } 41 | 42 | \addtolength{\oddsidemargin}{-1cm} 43 | \addtolength{\textwidth}{2cm} 44 | 45 | \newcommand\NewIn[1]{\leavevmode 46 | \marginpar{\hfill\fbox{\fbox{New in #1}}\hspace*{1em}}\ignorespaces} 47 | 48 | \title{\texttt{fitch.sty}: Fitch-style natural deduction macros} 49 | 50 | \author{Peter Selinger\\Dalhousie University \and Richard 51 | Zach\\University of Calgary\thanks{The current maintainer of this 52 | package is \href{https://richardzach.org}{Richard Zach}. The package 53 | repository is at \url{https://github.com/OpenLogicProject/fitch/}, 54 | where you can also report any 55 | \href{https://github.com/OpenLogicProject/fitch/issues}{issues} with 56 | it.}} 57 | 58 | \date{Version 1.0\\ December 17, 2023} 59 | 60 | \begin{document} 61 | \maketitle 62 | 63 | \section{Overview} 64 | 65 | This document describes how to use the {\tt fitch.sty} macros for 66 | typesetting Fitch-style natural deduction derivations. To load the 67 | macros, simply put |\usepackage{fitch}| into the preamble of your 68 | {\LaTeX} file. 69 | 70 | Here is a natural deduction derivation, together with the code that 71 | produced it: 72 | 73 | \begin{LTXexample} 74 | $\begin{nd} 75 | \hypo {1} {P\vee Q} 76 | \hypo {2} {\neg Q} 77 | \open 78 | \hypo {3} {P} 79 | \have {4} {P} \r{3} 80 | \close 81 | \open 82 | \hypo {aa} {Q} 83 | \have {6} {\neg Q} \r{2} 84 | \have {7} {\bot} \ne{aa,6} 85 | \have {8} {P} \be{7} 86 | \close 87 | \have {9} {P} \oe{1,3-4,aa-8} 88 | \end{nd}$ 89 | \end{LTXexample} 90 | 91 | A derivation consists of \emph{lines}, and each line contains a {\em 92 | line label} and a \emph{formula}. Some lines also carry a {\em 93 | justification}. Moreover, each line is either a \emph{hypothesis} or a 94 | \emph{derived formula}. Usually, derived formulas carry a 95 | justification, whereas hypotheses do not; however, the macros do not 96 | enforce this. 97 | 98 | Proofs set using |fitch.sty| will have lines numbered automatically in 99 | the output. It is possible to override the automatic numbering (see 100 | Section~\ref{subsec-customline}). You can refer to line numbers in the 101 | text using |\ndref| (see Section~\ref{subsec-ndref}). Various 102 | dimensions, formatting of justifications and line references, and the 103 | shorthand macros used to produce rule names can be customized (see 104 | Section~\ref{sec-customization}). 105 | 106 | \NewIn{1.0} Several new commands and customization options have been 107 | introduced in v1.0. It is mostly backwards compatible with earlier 108 | versions, but see section~\ref{compat}. In particular, if you 109 | redefined any internal |fitch| commands, you will have to change |nd*| 110 | to |nd@|. 111 | 112 | \section{Usage}\label{sec-usage} 113 | 114 | \DescribeEnv{nd}\DescribeEnv{nd} Derivations are typeset 115 | inside the |nd| environment. By default, the standard |array| 116 | environment is used to do this, so the |nd| environment must must be 117 | used in math mode, i.e., it should be surrounded by |$...$| or 118 | |\[...\]|. 119 | 120 | \NewIn{1.0} The environment |fitchproof| typesets the proof on its own 121 | in text, not math mode. Proofs will be set flush left, with the 122 | default |\partopsep| spacing surrounding lists added. You do not have 123 | to insert |$| to switch to math mode for |fitchproof|---by default. 124 | However, it only works if you generate proofs using the |tabular| 125 | environment, e.g., by loading |fitch| with the |arrayenv=tabular| 126 | option. 127 | 128 | \DescribeMacro{\hypo}\DescribeMacro{\have} 129 | The commands |\hypo| and |\have| are used 130 | to typeset one line of the derivation; |\hypo| is used for 131 | hypotheses, and |\have| for derived formulas. Both commands take 132 | a label and a formula as an argument. Note that the labels used to 133 | identify lines in the derivation need not be actual line numbers; for 134 | instance, in the above example, we used the label $aa$ instead of $5$. 135 | In the output, lines are automatically numbered consecutively. Labels 136 | may not contain any punctuation characters or spaces. 137 | 138 | \DescribeMacro{\open}\DescribeMacro{\close} 139 | Subderivations are opened and closed with the commands |\open| and 140 | |\close|. Finally, the following commands are provided for 141 | annotating lines with justifications: 142 | \begin{center} 143 | \begin{tabular}[t]{@{}ll@{}} 144 | |\r| & reiteration \\ 145 | |\ii| & implication introduction \\ 146 | |\ie| & implication elimination \\ 147 | |\ai| & and introduction \\ 148 | |\ae| & and elimination \\ 149 | |\oi| & or introduction \\ 150 | |\oe| & or elimination 151 | \end{tabular} 152 | \qquad 153 | \begin{tabular}[t]{ll} 154 | |\ni| & not introduction \\ 155 | |\ne| & not elimination \\ 156 | |\be| & bottom elimination \\ 157 | |\nne| & double negation elimination \\ 158 | |\Ai| & forall introduction \\ 159 | |\Ae| & forall elimination \\ 160 | |\Ei| & exists introduction \\ 161 | |\Ee| & exists elimination \\ 162 | \end{tabular} 163 | \end{center} 164 | \NewIn{1.0} These commands and what they produce can be customized, 165 | see Section~\ref{sec-customization}. 166 | 167 | Each such command takes a \emph{reference list} as an argument. A 168 | reference list is a string made from labels, commas, and hyphens, for 169 | instance |1,3a-3b,4a-4d|. 170 | 171 | \section{Details} 172 | 173 | \subsection{Guards} 174 | 175 | Some natural deduction derivations with quantifiers use \emph{guards}, as in 176 | the following example: 177 | 178 | \begin{LTXexample} 179 | $ 180 | \begin{nd} 181 | \hypo {1} {\exists x\forall y.P(x,y)} 182 | \open[v] 183 | \open[u] 184 | \hypo {2} {\forall y.P(u,y)} 185 | \have {3} {P(u,v)} \Ae{2} 186 | \have {4} {\exists x.P(x,v)} \Ei{3} 187 | \close 188 | \have {5} {\exists x.P(x,v)} \Ee{1,2-5} 189 | \close 190 | \have {6} {\forall y\exists x.P(x,y)} \Ai{2-5} 191 | \end{nd} 192 | $ 193 | \end{LTXexample} 194 | 195 | The guards $v$ and $u$ in line 2 were typeset by giving optional 196 | arguments to the |\open| commands of the respective 197 | subderivations. 198 | 199 | \DescribeMacro{\guard} 200 | For most purposes, the above way of specifying guards is sufficient. 201 | However, there is another method, which allows a more flexible 202 | placement of guards: before any line, you can give the command 203 | |\guard{u}| to add a guard $u$ to the top-level subderivation at 204 | that line, or |\guard[n]{u}| to add a guard to the $n$th 205 | enclosing subderivation at that line. Thus, the above example could 206 | have also been typeset by inserting the two commands |\guard{u}| and 207 | |\guard[2]{v}| just after the second |\open| statement. 208 | 209 | % For backward compatibility, there is a third way of specifying guards 210 | % by giving an optional second argument to the |\hypo| and 211 | % |\have| commands. The use of this feature is discouraged. 212 | 213 | \subsection{Label and reference list details}\label{subsec-ndref} 214 | 215 | Labels for lines given to the |\have| and |\hypo| commands need not be 216 | numeric, although the package will \emph{output} them as consecutive 217 | numbers (see Section~\ref{subsec-customline} for how to adjust the 218 | numbering). Labels, however, may not contain commas, periods, 219 | semicolons, hyphens, parentheses, or spaces. In a reference list, 220 | spaces are ignored (even within a label!), whereas commas, periods, 221 | semicolons, parentheses, and hyphens are copied to the output. All 222 | other characters are interpreted as part of a label. Attempting to 223 | reference a label which has not been previously defined by any |\hypo| 224 | or |\have| command produces a \NewIn{0.6} warning message of the form: 225 | \begin{verbatim} 226 | ! Package fitch Warning: Undefined line reference: lab17. 227 | \end{verbatim} 228 | (In earlier versions, this resulted in an error, not a warning.) 229 | 230 | \DescribeMacro{\ndref} 231 | Labels defined in an |nd| environment can be referenced in the 232 | text with the |\ndref| command. This command takes a reference 233 | list as an argument, and produces the corresponding output. However, 234 | it is only possible to reference labels \emph{after} the corresponding 235 | derivation has been typeset. There is currently no convenient way of 236 | defining forward references. Also, if a label is used more than once, 237 | |\ndref| will always refer to the most recent time it was used. 238 | 239 | \subsection{Generic justifications} 240 | 241 | \DescribeMacro{\by} 242 | Non-standard justifications can be created with the |\by| 243 | command. This command takes two arguments: a name and a reference 244 | list. For instance, the command |\by{De Morgan}{lab3,lab4}| might 245 | produce the output ``\mbox{De Morgan, 3, 4}''. Note that the justification 246 | is typeset in text mode. 247 | 248 | In the default justification format, a comma is automatically inserted 249 | between the name and the reference list, unless the reference list is 250 | empty. The formatting of justifications can be changed, see 251 | Section~\ref{sec-customization}. If the second argument (the reference 252 | list) is empty, only the first argument (without formatting or 253 | punctuation) is printed. \NewIn{1.0} If the first argument is empty, 254 | only the reference list is printed. 255 | 256 | Since the |\by| command outputs its first argument without additional 257 | formatting when the second argument is empty, you can use |\by{...}{}| 258 | to produce arbitrary text in the justification. You can use the 259 | |\ndref| command here. 260 | \begin{LTXexample} 261 | $ 262 | \begin{nd} 263 | \hypo {a} {A \Rightarrow B} 264 | \by{Premise}{} 265 | \hypo {b} {A} \by{Premise}{} 266 | \have {c} {B} 267 | \by{\ndref{a,b} 268 | (but \emph{how?})}{} 269 | \have {d} {A \wedge B} \by{}{b,c} 270 | \end{nd} 271 | $ 272 | \end{LTXexample} 273 | 274 | \subsection{Scope} 275 | 276 | The commands |\hypo|, |\have|, |\open|, |\close|, |\by|, |\r|, |\ii|, and so 277 | forth are only available inside an |nd| environment. These commands 278 | may have a different meaning elsewhere in the same document. The only 279 | commands provided by the |fitch.sty| package which are visible 280 | outside an |nd| environment are the command |\ndref| described in 281 | Section~\ref{subsec-ndref}, the commands |\ndrules|, |\ndjustformat|, 282 | |\ndrefformat|, and |\nddim|, and the dimension |\ndindent| described 283 | in Section~\ref{sec-customization}. 284 | 285 | \subsection{Breaking it across pages}\label{subsec-break} 286 | 287 | \DescribeEnv{ndresume} 288 | \DescribeEnv{fitchproof*} 289 | The |nd| environment is derived from the {\LaTeX} |array| 290 | environment, and thus it does not break across pages automatically. 291 | However, if a derivation is too long to fit on a single page, it is 292 | possible to split it manually into physically independent, but 293 | logically consecutive subparts. For this purpose, the |ndresume| 294 | environment is provided to continue a previously interrupted 295 | derivation. 296 | \NewIn{1.0} The environment |fitchproof*| works the same way, except typesets the 297 | proof just like the |fitchproof| environment (no need for math mode, 298 | flush left, spacing before and after). However, like |fitchproof|, it 299 | requires the |arrayenv=tabular| option. Here is an example: 300 | 301 | \begin{LTXexample} 302 | \begin{fitchproof}[arrayenv=tabular] 303 | \hypo {1} {P\vee Q} 304 | \hypo {2} {\neg Q} 305 | \open 306 | \hypo {3} {P} 307 | \have {4} {P} \r{3} 308 | \close 309 | \open 310 | \hypo {aa} {Q} 311 | \have {6} {\neg Q} \r{2} 312 | \end{fitchproof} 313 | Derivations can be interrupted and 314 | resumed at any point. 315 | \begin{fitchproof*}[arrayenv=tabular] 316 | \have {7} {\bot} \ne{aa,6} 317 | \have {8} {P} \be{7} 318 | \close 319 | \have {9} {P} \oe{1,3-4,aa-8} 320 | \end{fitchproof*} 321 | \end{LTXexample} 322 | 323 | \NewIn{1.0} You can also have derivations break across pages 324 | automatically. In order to do this, you have to load the 325 | \href{https://ctan.org/pkg/longtable}{|longtable|} package, and load 326 | |fitch| with the |arrayenv=longtable| option. Since the |longtable| 327 | environment works in text (not math) mode, you should then only use 328 | |fitchproof|, or the |nd| environment but \emph{not} in text mode. 329 | Note that the |longtable| package does not work in 2-column mode or 330 | inside a |multicolumn| environment. You can always produce a proof 331 | inside a |multicolumn| environment by passing |arrayenv=tabular| as an 332 | option to the |nd| or |fitchproof| environment. 333 | 334 | 335 | \subsection{Custom line numbers}\label{subsec-customline} 336 | 337 | One often needs to write derivation schemas, rather than derivations. 338 | This often requires the use of symbolic constants such as $n$, $n+1$, 339 | etc, instead of actual line numbers. The |\have| and |\hypo| 340 | commands have an optional first argument which is a symbolic constant. 341 | For instance, |\have[n]| will cause the current line to be 342 | numbered with the symbolic constant $n$. Subsequent lines are 343 | automatically numbered $n+1$ etc. An initial offset can be given as a 344 | second optional argument, as in |\have[n][-1]|, which will cause 345 | the current line to be numbered $n-1$, the following line $n$, etc. In 346 | an explicit offset is given, the symbolic constant can also be absent: 347 | for instance, the command |\have[][7]| resets the current line 348 | number to $7$. The following example illustrates this behavior: 349 | 350 | \begin{LTXexample} 351 | $ 352 | \begin{nd}[justsep=1em] 353 | \hypo {1} {P\vee Q} 354 | \open 355 | \hypo {2} {P} 356 | \have [\vdots] {3} {\vdots} 357 | \have [n][-1] {4} {A\wedge B} 358 | \close 359 | \open 360 | \hypo {5} {Q} 361 | \have [\vdots] {6} {\vdots} 362 | \have [m] {7} {A\wedge B} 363 | \close 364 | \have {8} {A\wedge B} 365 | \oe{1,2-(4),5-7} 366 | \have [\vdots] {9} {\vdots} 367 | \have [][100] {10} {A} \ae{8} 368 | \end{nd} 369 | $ 370 | \end{LTXexample} 371 | 372 | Note that in the justification for line $m+1$, parentheses had to be 373 | put around the label $4$. There is currently no way of doing this 374 | automatically. 375 | 376 | {\bf Exercise.} How does one typeset an empty line number? 377 | 378 | {\bf Solution.} Since |\have[]| has a special meaning as explained 379 | above, we need to use |\have[~]| instead. 380 | 381 | \subsection{Continuation lines}\label{subsec-continuation} 382 | 383 | Sometimes one has to typeset a very long formula that does not fit on 384 | a single line. As of version 0.5 of the {\tt fitch.sty} macros, it is 385 | possible to break a formula into several lines using |\\| as a 386 | line separator. Continuation lines are automatically indented, as 387 | shown in the following example. 388 | 389 | \begin{LTXexample} 390 | $ 391 | \begin{nd} 392 | \hypo{1} {A\wedge B} 393 | \hypo{2} {A\wedge B\Rightarrow{} \\ 394 | C\wedge D} 395 | \have{3} {C\wedge D} \ie{1,2} 396 | \have{4} {A\wedge B\wedge{} \\ 397 | C\wedge D} \ai{1,3} 398 | \end{nd} 399 | $ 400 | \end{LTXexample} 401 | 402 | \DescribeMacro{\hypocont} 403 | \DescribeMacro{\havecont} 404 | Alternatively, the |\havecont| and |\hypocont| commands can 405 | be used to specify each continuation line separately, as the following 406 | example illustrates. 407 | 408 | \begin{LTXexample} 409 | $ 410 | \begin{nd} 411 | \hypo{1} {A\wedge B} 412 | \hypo{2} {A\wedge B\Rightarrow{}} 413 | \hypocont {C\wedge D} 414 | \have{3} {C\wedge D} \ie{1,2} 415 | \have{4} {A\wedge B\wedge{}} \ai{1,3} 416 | \havecont {C\wedge D} 417 | \end{nd} 418 | $ 419 | \end{LTXexample} 420 | 421 | This latter style gives slightly more flexibility in the placement of 422 | justifications, since each line and continuation line can have its own 423 | justification and its own guard (via the |\guard| command). It 424 | also allows a derivation to be interrupted between a line and its 425 | continuation, as discussed in Section~\ref{subsec-break}. 426 | 427 | \section{Customization}\label{sec-customization} 428 | 429 | The relative sizes of the various elements of a natural deduction 430 | proof are preset to reasonable values depending on the size of the 431 | currently selected font. However, it will sometimes be necessary to 432 | customize these dimensions. The customizable dimensions are given in 433 | the following diagram. 434 | \begin{center} 435 | \includegraphics{fitchdoc-dimen} 436 | \end{center} 437 | In addition, \meta{linethickness} determines the thickness of scope 438 | lines, and \meta{cindent} the extra indentation of continuation lines 439 | (as discussed in Section~\ref{subsec-continuation}). The default 440 | dimensions are: 441 | \begin{center} 442 | \begin{tabular}{ll@{\qquad}ll} 443 | \meta{height} & 4.5ex & 444 | \meta{topheight} & 3.5ex\\ 445 | \meta{depth} & 1.5ex & 446 | \meta{labelsep} & 1em\\ 447 | \meta{indent} & 1.6em & 448 | \meta{hsep} & .5em\\ 449 | \meta{justsep} & 2.5em & 450 | \meta{linethickness} & .2mm\\ 451 | \meta{cindent} & 1em 452 | \end{tabular} 453 | \end{center} 454 | 455 | \NewIn{1.0} To change these default dimensions, pass a list of 456 | key-value pairs as package options, as optional arguments to the 457 | |nd| or |fitchproof| environment, or use the |\setkeys| 458 | command: 459 | \begin{verbatim} 460 | \usepackage[justsep=1em]{fitch} 461 | \begin{nd}[rules=myrules] 462 | \begin{fitchproof}[linethickness=1pt] 463 | \setkeys{fitch}{hsep=1em,indent=1em}\end{verbatim} 464 | 465 | In addition, the macros used to generate the table containing the 466 | proof, to format justifications, format line number references, and to 467 | initialize macros to produce justifications in the proof can be 468 | customized: 469 | \begin{center} 470 | \begin{tabular}{ll} 471 | option & default\\\hline 472 | |rules=|\meta{macroname} & |ndrules|\\ 473 | |justformat=|\meta{macroname} & |ndjustformat|\\ 474 | |refformat=|\meta{macroname} & |ndrefformat|\\ 475 | |arrayenv=|\meta{envname} & |array| 476 | \end{tabular} 477 | \end{center} 478 | For compatibility with earlier versions of |fitch.sty|, the default 479 | for \meta{arrayenv} is |array|, i.e., the table containing the proof 480 | is generated using an |array| environment, and must therefore occur 481 | inside math mode. The |fitchproof| and |fitchproof*| environments 482 | assume that you use a text table command instead, such as |tabular|. 483 | Hence, you should \emph{not} use |fitchproof| in math mode, and you 484 | must use the option |arrayenv=tabular| (when loading |fitch|, as an 485 | optional argument to |fitchproof|, or using 486 | |\setkeys{fitch}{arrayenv=tabular}|. Any other table environment that 487 | takes the same table format argument as |array| and |tabular| can be 488 | used here, e.g., the |longtable| environment from the |longtable| 489 | package (which must be loaded separately). 490 | 491 | The package defines the macros 492 | \DescribeMacro{\ndrules}\cmd{\ndrules}, which defines the rule 493 | macros given at the end of Section~\ref{sec-usage}, using 494 | \begin{verbatim} 495 | \def\ndrules{% 496 | \def\ii{\by{$\Rightarrow$I}}% 497 | \def\ie{\by{$\Rightarrow$E}}% 498 | \def\Ai{\by{$\forall$I}}% 499 | \def\Ae{\by{$\forall$E}}% 500 | \def\Ei{\by{$\exists$I}}% 501 | \def\Ee{\by{$\exists$E}}% 502 | \def\ai{\by{$\wedge$I}}% 503 | \def\ae{\by{$\wedge$E}}% 504 | \def\ai{\by{$\wedge$I}}% 505 | \def\ae{\by{$\wedge$E}}% 506 | \def\oi{\by{$\vee$I}}% 507 | \def\oe{\by{$\vee$E}}% 508 | \def\ni{\by{$\neg$I}}% 509 | \def\ne{\by{$\neg$E}}% 510 | \def\be{\by{$\bot$E}}% 511 | \def\nne{\by{$\neg\neg$E}}% 512 | \def\r{\by{R}}} 513 | \end{verbatim} 514 | \DescribeMacro{\ndjustformat} 515 | The macro \cmd{\ndjustformat} is defined as 516 | \begin{verbatim} 517 | \newcommand{\ndjustformat}[2]{#1, #2} 518 | \end{verbatim} 519 | The first argument takes the rule name, the second the reference list. 520 | It is used to typeset the justification. 521 | 522 | \DescribeMacro{\ndrefformat} 523 | The macro \cmd{\ndrefformat} is defined as 524 | \begin{verbatim} 525 | \newcommand{\ndrefformat}[1]{#1} 526 | \end{verbatim} 527 | It is used to typeset the line numbers in justifications. 528 | 529 | \cmd{\ndrules}, \cmd{\ndjustformat}, and \cmd{\ndrefformat} can 530 | be redefined using \cmd{\renewcommand}, or you can define your own 531 | commands to provide the rule names, the justification format, and line 532 | number format, and pass the names (without initial |\|) as an option 533 | to the \cmd{\usepackage} or individual \cmd{\nd} or \cmd{\fitchproof} 534 | commands. 535 | \begin{LTXexample} 536 | \newcommand{\myjust}[2] 537 | {#2 by \textsf{#1}} 538 | \newcommand{\myrules}{ 539 | \ndrules % include standard rules 540 | \def\ds{\by{DS}}} 541 | \renewcommand{\ndrefformat}[1]{(#1)} 542 | $ 543 | \begin{nd}[rules=myrules, 544 | justformat=myjust, 545 | indent=1.5cm, 546 | linethickness=1.5pt, 547 | justsep=1cm] 548 | \hypo {1} {A\vee B} 549 | \hypo {2} {\neg B} 550 | \open 551 | \hypo {a} {B} 552 | \have {3} {A} \ds{1,2} 553 | \have {b} {A \wedge B} \ai{a,3} 554 | \end{nd} 555 | $ 556 | \end{LTXexample} 557 | 558 | The boolean option |outerline| can be set to false to suppress the 559 | leftmost scope line. This may be useful when printing inference rules, 560 | e.g., 561 | \begin{LTXexample} 562 | $ 563 | \begin{nd}[outerline=false, 564 | labelsep=0pt] 565 | \open 566 | \hypo [n]{1} {A} 567 | \have [~]{2} {\raisebox{-1ex}{\vdots}} 568 | \have [m]{3} {B} 569 | \close 570 | \have [~]{b} {A \Rightarrow B} \ii{1-3} 571 | \end{nd} 572 | $ 573 | \end{LTXexample} 574 | 575 | \section{Obsolete commands and backwards compatibility}\label{compat} 576 | 577 | \DescribeMacro{\nddim} 578 | The dimensions can also be changed with the 579 | |\nddim| command. The syntax of the command is as follows: 580 | \begin{center} 581 | \cmd{\nddim}\marg{height}\marg{topheight}\marg{depth}\marg{labelsep} 582 | \marg{indent}\marg{hsep}\marg{justsep}\marg{linethickness}, 583 | \end{center} 584 | where each of the eight parameters is a dimension. This still works, 585 | but using the key-value pair options is the preferred method. 586 | 587 | \NewIn{1.0}\DescribeMacro{\ndindent} In versions before v1.0, the recommended way 588 | to change the extra indentation used on continuation lines was to 589 | change dimension |\ndindent| directly using |\setlength|. As of v1.0, 590 | you should use the |cindent| option instead. 591 | 592 | The original code ``hid'' the internal macros by naming 593 | them |\nd*...|. In v1.0 this has been changed to the standard 594 | |\nd@...|. Any low-level redefinition of |fitch| internals that uses 595 | |*| will break in v1.0. 596 | 597 | \section{Other comments} 598 | 599 | The goal was to design a flexible package which would not impose any 600 | constraints on the form of derivations, while making typesetting easy. 601 | With this package, it is in fact possible to typeset incomplete, 602 | ill-formed, or invalid derivations. Sometimes it is pedagogically necessary 603 | to do so. 604 | 605 | There are no arbitrary limits on the size or nesting depth of a derivation, 606 | except for the obvious requirement of fitting horizontally on the 607 | printed page. 608 | 609 | \section{Copyright and license} 610 | 611 | This document and the accompanying |fitch.sty| macros are {\copyright} 612 | 2002--2023 by Peter Selinger and Richard Zach and distributed under 613 | the terms of the \href{https://www.latex-project.org/lppl/}{LPPL}. 614 | 615 | \end{document} 616 | -------------------------------------------------------------------------------- /fitchexample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLogicProject/fitch/a23fbfe84a06e48728abe08d57b2c75ab80c054e/fitchexample.png --------------------------------------------------------------------------------