├── .DS_Store ├── LICENSE ├── README.md ├── github.png ├── samples ├── table.pdf └── table.tex ├── sheffer.html ├── truthtable.html └── truthtable.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrieppel/TruthTableGenerator/11a4df29062c1e3780fcbec35d8b932b6b55c193/.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Truth Table Generator 4 | 5 | Copyright (c) 2010-2024 Michael Rieppel 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Truth Table Generator 2 | ===================== 3 | 4 | This is a JavaScript program which will generate a truth tables for formulas of propositional logic. You can enter multiple formulas separated by commas to include more than one formula in a single table (e.g. to test for entailment). You can select which symbols to use for truth-values and connectives, the style of the table (full table, main connective only, plain text, or LaTeX output), and two-valued or different types of three-valued tables. 5 | 6 | The output characters used for the various connectives can be changed by modifying the `htmlchar()`, `txtchar()`, and `latexchar()` functions at the beginning of `truthtable.js`. 7 | 8 | A live version of the program is [here](http://mrieppel.net/prog/truthtable.html). 9 | 10 | (c) Michael Rieppel 2010-2024. Released under the MIT License. See LICENSE above for more information. 11 | -------------------------------------------------------------------------------- /github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrieppel/TruthTableGenerator/11a4df29062c1e3780fcbec35d8b932b6b55c193/github.png -------------------------------------------------------------------------------- /samples/table.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrieppel/TruthTableGenerator/11a4df29062c1e3780fcbec35d8b932b6b55c193/samples/table.pdf -------------------------------------------------------------------------------- /samples/table.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % - - - - - - - Formatting Etc. - - - - - - - 4 | 5 | \usepackage{amssymb,amsmath,color} 6 | \usepackage[top=1in, bottom=1in, left=1in, right=1in]{geometry} 7 | 8 | 9 | \begin{document} 10 | 11 | 12 | %NOTE: requires \usepackage{color} 13 | \begin{tabular}{ c c c | c c c c c c c c c c } 14 | A & B & C & ( & A & $\&$ & ( & $\sim$ & B & $\rightarrow$ & C & ) & )\\ 15 | \hline 16 | $\top$ & $\top$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & $\top$ & & \\ 17 | $\top$ & $\top$ & $\perp$ & & $\top$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & $\perp$ & & \\ 18 | $\top$ & $\perp$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & $\top$ & $\top$ & & \\ 19 | $\top$ & $\perp$ & $\perp$ & & $\top$ & \textcolor{red}{$\perp$} & & $\top$ & $\perp$ & $\perp$ & $\perp$ & & \\ 20 | $\perp$ & $\top$ & $\top$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & $\top$ & $\top$ & & \\ 21 | $\perp$ & $\top$ & $\perp$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & $\top$ & $\perp$ & & \\ 22 | $\perp$ & $\perp$ & $\top$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\top$ & $\perp$ & $\top$ & $\top$ & & \\ 23 | $\perp$ & $\perp$ & $\perp$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\top$ & $\perp$ & $\perp$ & $\perp$ & & \\ 24 | \end{tabular} 25 | 26 | 27 | 28 | \vspace{2em} 29 | 30 | 31 | \begin{tabular}{ c c c | c c c c c c c c c c } 32 | $\perp$ & A & B & ( & $\perp$ & $\rightarrow$ & ( & B & $\lor$ & $\sim$ & A & ) & )\\ 33 | \hline 34 | $\perp$ & $\top$ & $\top$ & & $\perp$ & \textcolor{red}{$\top$} & & $\top$ & $\top$ & $\perp$ & $\top$ & & \\ 35 | $\perp$ & $\top$ & $\perp$ & & $\perp$ & \textcolor{red}{$\top$} & & $\perp$ & $\perp$ & $\perp$ & $\top$ & & \\ 36 | $\perp$ & $\perp$ & $\top$ & & $\perp$ & \textcolor{red}{$\top$} & & $\top$ & $\top$ & $\top$ & $\perp$ & & \\ 37 | $\perp$ & $\perp$ & $\perp$ & & $\perp$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & $\perp$ & & \\ 38 | \end{tabular} 39 | 40 | \vspace{2em} 41 | 42 | %NOTE: requires \usepackage{color} 43 | \begin{tabular}{ c c c | c c c c c c c c c | c | c c c c c c } 44 | A & B & C & ( & A & $\leftrightarrow$ & ( & B & $\lor$ & C & ) & ) & A & ( & $\sim$ & B & $\rightarrow$ & C & )\\ 45 | \hline 46 | $\top$ & $\top$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\top$ & $\top$ & $\top$ & & & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & \textcolor{red}{$\top$} & $\top$ & \\ 47 | $\top$ & $\top$ & $\perp$ & & $\top$ & \textcolor{red}{$\top$} & & $\top$ & $\top$ & $\perp$ & & & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & \textcolor{red}{$\top$} & $\perp$ & \\ 48 | $\top$ & $\perp$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & & & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & \textcolor{red}{$\top$} & $\top$ & \\ 49 | $\top$ & $\perp$ & $\perp$ & & $\top$ & \textcolor{red}{$\perp$} & & $\perp$ & $\perp$ & $\perp$ & & & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & \textcolor{red}{$\perp$} & $\perp$ & \\ 50 | $\perp$ & $\top$ & $\top$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\top$ & $\top$ & $\top$ & & & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & \textcolor{red}{$\top$} & $\top$ & \\ 51 | $\perp$ & $\top$ & $\perp$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\top$ & $\top$ & $\perp$ & & & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & \textcolor{red}{$\top$} & $\perp$ & \\ 52 | $\perp$ & $\perp$ & $\top$ & & $\perp$ & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & $\top$ & & & \textcolor{red}{$\perp$} & & $\top$ & $\perp$ & \textcolor{red}{$\top$} & $\top$ & \\ 53 | $\perp$ & $\perp$ & $\perp$ & & $\perp$ & \textcolor{red}{$\top$} & & $\perp$ & $\perp$ & $\perp$ & & & \textcolor{red}{$\perp$} & & $\top$ & $\perp$ & \textcolor{red}{$\perp$} & $\perp$ & \\ 54 | \end{tabular} 55 | 56 | \vspace{2em} 57 | 58 | %NOTE: requires \usepackage{color} 59 | \begin{tabular}{ c c c | c c c c c c c c c c | c | c c c c c } 60 | P & Q & R & ( & P & $\rightarrow$ & ( & $\sim$ & Q & $\lor$ & R & ) & ) & P & ( & Q & $\rightarrow$ & R & )\\ 61 | \hline 62 | $\top$ & $\top$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & $\top$ & & & \textcolor{red}{$\top$} & & $\top$ & \textcolor{red}{$\top$} & $\top$ & \\ 63 | $\top$ & $\top$ & $\perp$ & & $\top$ & \textcolor{red}{$\perp$} & & $\perp$ & $\top$ & $\perp$ & $\perp$ & & & \textcolor{red}{$\top$} & & $\top$ & \textcolor{red}{$\perp$} & $\perp$ & \\ 64 | $\top$ & $\perp$ & $\top$ & & $\top$ & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & $\top$ & $\top$ & & & \textcolor{red}{$\top$} & & $\perp$ & \textcolor{red}{$\top$} & $\top$ & \\ 65 | $\top$ & $\perp$ & $\perp$ & & $\top$ & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & $\top$ & $\perp$ & & & \textcolor{red}{$\top$} & & $\perp$ & \textcolor{red}{$\top$} & $\perp$ & \\ 66 | $\perp$ & $\top$ & $\top$ & & $\perp$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\top$ & $\top$ & & & \textcolor{red}{$\perp$} & & $\top$ & \textcolor{red}{$\top$} & $\top$ & \\ 67 | $\perp$ & $\top$ & $\perp$ & & $\perp$ & \textcolor{red}{$\top$} & & $\perp$ & $\top$ & $\perp$ & $\perp$ & & & \textcolor{red}{$\perp$} & & $\top$ & \textcolor{red}{$\perp$} & $\perp$ & \\ 68 | $\perp$ & $\perp$ & $\top$ & & $\perp$ & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & $\top$ & $\top$ & & & \textcolor{red}{$\perp$} & & $\perp$ & \textcolor{red}{$\top$} & $\top$ & \\ 69 | $\perp$ & $\perp$ & $\perp$ & & $\perp$ & \textcolor{red}{$\top$} & & $\top$ & $\perp$ & $\top$ & $\perp$ & & & \textcolor{red}{$\perp$} & & $\perp$ & \textcolor{red}{$\top$} & $\perp$ & \\ 70 | \end{tabular} 71 | 72 | \vspace{2em} 73 | 74 | %NOTE: requires \usepackage{color} 75 | \begin{tabular}{ c c | c c | c c c c c | c c c c c | c c c c c | c c c c c } 76 | P & Q & $\sim$ & P & ( & P & $\&$ & Q & ) & ( & P & $\lor$ & Q & ) & ( & P & $\rightarrow$ & Q & ) & ( & P & $\leftrightarrow$ & Q & )\\ 77 | \hline 78 | $\top$ & $\top$ & \textcolor{red}{$\perp$} & $\top$ & & $\top$ & \textcolor{red}{$\top$} & $\top$ & & & $\top$ & \textcolor{red}{$\top$} & $\top$ & & & $\top$ & \textcolor{red}{$\top$} & $\top$ & & & $\top$ & \textcolor{red}{$\top$} & $\top$ & \\ 79 | $\top$ & $\perp$ & \textcolor{red}{$\perp$} & $\top$ & & $\top$ & \textcolor{red}{$\perp$} & $\perp$ & & & $\top$ & \textcolor{red}{$\top$} & $\perp$ & & & $\top$ & \textcolor{red}{$\perp$} & $\perp$ & & & $\top$ & \textcolor{red}{$\perp$} & $\perp$ & \\ 80 | $\perp$ & $\top$ & \textcolor{red}{$\top$} & $\perp$ & & $\perp$ & \textcolor{red}{$\perp$} & $\top$ & & & $\perp$ & \textcolor{red}{$\top$} & $\top$ & & & $\perp$ & \textcolor{red}{$\top$} & $\top$ & & & $\perp$ & \textcolor{red}{$\perp$} & $\top$ & \\ 81 | $\perp$ & $\perp$ & \textcolor{red}{$\top$} & $\perp$ & & $\perp$ & \textcolor{red}{$\perp$} & $\perp$ & & & $\perp$ & \textcolor{red}{$\perp$} & $\perp$ & & & $\perp$ & \textcolor{red}{$\top$} & $\perp$ & & & $\perp$ & \textcolor{red}{$\top$} & $\perp$ & \\ 82 | \end{tabular} 83 | 84 | 85 | 86 | 87 | 88 | 89 | \end{document} -------------------------------------------------------------------------------- /sheffer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sheffer Stroke Converter 7 | 8 | 9 | 10 | 11 | 12 | 101 | 102 | 200 | 201 | 202 | 203 | 204 | 205 | 206 |
207 | 208 |
Home > Etc > Truth Table Generator > Sheffer Stroke Converter
209 | 210 | 211 | 212 |
Sheffer Stroke Converter
213 | 214 |

This page contains a program that will convert a formula of truth-functional logic into an equivalent formula that uses only the Sheffer Stroke (representing the NAND operation). It won't generally be the shortest equivalent formula, though! Try out ~(A&B), for example. You can generate truth tables for the converted formulas here. See below for the keyboard symbols to use for the logical connectives.

215 | 216 |
217 | 218 | 219 |
220 | 221 |
222 | 223 |

Wittgenstein famously used the Sheffer stroke in the Tractatus, but there it represents the NOR operation (rather than NAND). So here is another converter, this time one that will output an equivalent formula using only a NOR-stroke (here represented using '!'). So (A!B) means ~(AvB) or, equivalently, (~A&~B) i.e. the joint denial of A and B. In the Tractatus Wittgenstein generalized this into his N operator, which forms the joint denial of any collection of propositions. You can read more about that here. 224 | 225 |

226 | 227 | 228 |
229 | 230 |
231 | 232 | 233 |

Symbols: use the following keyboard symbols in your input for the various logical connectives:

234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 |
~for negation
&for conjunction
vfor disjunction
>for the conditional
< >for the biconditional
#for absurdity
|for NAND (aka the Sheffer Stroke)
!for NOR (Wittgenstein's Sheffer Stroke)
246 | 247 |
248 |

Here are some examples of well-formed inputs the program will accept:

249 | 250 | 259 | 260 |

The source code is available on GitHub, just click the icon at the top right corner of the page. 261 | 262 |

263 | 264 |
265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | -------------------------------------------------------------------------------- /truthtable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Truth Table Generator 7 | 8 | 33 | 34 | 35 | 36 | 37 | 38 | 163 | 164 | 165 | 166 | 167 | 168 |
169 | 170 |
Home > Etc > Truth Table Generator
171 | 172 | 173 | 174 |
Truth Table Generator
175 | 176 |

This page contains a program that will generate truth tables for formulas of propositional logic. You can enter multiple formulas separated by commas to include more than one formula in a single table (e.g. to test for entailment). Below you can select which symbols to use for the truth-values and connectives, the style of the table (full table, main connective only, plain text, or LaTeX output), and (by special request!) two-valued or different types of three-valued tables.

177 | 178 |
179 | 180 | 181 |
182 | 183 |
184 | 185 |
186 | 187 |
188 |
Truth-Values:
189 |
190 |
191 |
192 |
193 | 194 |
195 |
Connectives:
196 |
197 |
198 |
199 |
200 | 201 |
202 |
Table Style:
203 |
204 |
205 |
208 | 209 |
210 |
Type:
211 |
212 |
213 |
216 | 217 |
218 |
219 | 220 | 221 |

Symbols: use the following keyboard symbols in your input for the various logical connectives:

222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
~for negation
&for conjunction
vfor disjunction
>for the conditional
< >for the biconditional
#for absurdity/falsum
|for NAND (aka the Sheffer Stroke)
!for NOR (Wittgenstein's Sheffer Stroke)
234 | 235 |
236 |

Here are some examples of well-formed inputs the program will accept:

237 | 238 | 246 | 247 |

The source code is available on GitHub, just click the icon at the top right corner of the page. 248 | 249 |

250 | 251 |
252 | 253 | 254 | 255 | 256 | 257 | 268 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /truthtable.js: -------------------------------------------------------------------------------- 1 | // Truth Table Generator 2 | // 3 | // The MIT License (MIT) 4 | // 5 | // Copyright (c) 2010-2024 Michael Rieppel 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | /*************************************************************************************/ 25 | 26 | function htmlchar(c,tv,cs) { 27 | switch(c) { 28 | case true : // return char based on selected truth value style 29 | switch(tv) { 30 | case 'tb': return '⊤'; 31 | case 'tf': return 'T'; 32 | case 'oz': return '1'; 33 | } 34 | case false : // return char based on selected truth value style 35 | switch(tv) { 36 | case 'tb': return '⊥'; 37 | case 'tf': return 'F'; 38 | case 'oz': return '0'; 39 | } 40 | case null : // return char based on selected truth value style (third truth value) 41 | switch(tv) { 42 | case 'tb': return 'N'; 43 | case 'tf': return 'N'; 44 | case 'oz': return 'N'; 45 | } 46 | case '~' : // return connective chars based on selected cset 47 | switch(cs) { 48 | case 'cs1': return '¬'; 49 | default : return '~'; 50 | } 51 | case '&' : 52 | switch(cs) { 53 | case 'cs1' : return '∧'; 54 | default : return '&'; 55 | } 56 | case 'v' : return '∨'; 57 | case '>' : 58 | switch(cs) { 59 | case 'cs3' : return '⊃'; 60 | default : return '→'; 61 | } 62 | case '<>' : 63 | switch(cs) { 64 | case 'cs3' : return '≡'; 65 | default : return '↔'; 66 | } 67 | case '|' : return '|'; 68 | case '#' : return '⊥' 69 | default : return c; 70 | } 71 | } 72 | 73 | function txtchar(c,tv,cs) { 74 | switch(c) { 75 | case true : // return char based on selected truth value style 76 | switch(tv) { 77 | case 'tb': return '\u22a4'; 78 | case 'tf': return 'T'; 79 | case 'oz': return '1'; 80 | } 81 | case false : // return char based on selected truth value style 82 | switch(tv) { 83 | case 'tb': return '\u22a5'; 84 | case 'tf': return 'F'; 85 | case 'oz': return '0'; 86 | } 87 | case null : // return char based on selected truth value style (third truth value) 88 | switch(tv) { 89 | case 'tb': return 'N'; 90 | case 'tf': return 'N'; 91 | case 'oz': return 'N'; 92 | } 93 | case '' : return ' '; 94 | default : return c; 95 | } 96 | } 97 | 98 | function latexchar(c,tv,cs) { 99 | switch(c) { 100 | case true : // return char based on selected truth value style 101 | switch(tv) { 102 | case 'tb': return '$\\top$'; 103 | case 'tf': return 'T'; 104 | case 'oz': return '1'; 105 | } 106 | case false : // return char based on selected truth value style 107 | switch(tv) { 108 | case 'tb': return '$\\bot$'; 109 | case 'tf': return 'F'; 110 | case 'oz': return '0'; 111 | } 112 | case null : // return char based on selected truth value style (third truth value) 113 | switch(tv) { 114 | case 'tb': return 'N'; 115 | case 'tf': return 'N'; 116 | case 'oz': return 'N'; 117 | } 118 | case '~' : // return connective chars based on selected cset 119 | switch(cs) { 120 | case 'cs1': return '$\\lnot$'; 121 | default : return '$\\sim$'; 122 | } 123 | case '&' : 124 | switch(cs) { 125 | case 'cs1' : return '$\\land$'; 126 | default : return '$\\&$'; 127 | } 128 | case 'v' : return '$\\lor$'; 129 | case '>' : 130 | switch(cs) { 131 | case 'cs3' : return '$\\supset$'; 132 | default : return '$\\rightarrow$'; 133 | } 134 | case '<>' : 135 | switch(cs) { 136 | case 'cs3' : return '$\\equiv$'; 137 | default : return '$\\leftrightarrow$'; 138 | } 139 | case '|' : return '$|$'; 140 | case '#' : return '$\\perp$'; 141 | default : return c; 142 | } 143 | } 144 | 145 | /*************************************************************************************/ 146 | 147 | // main construction function 148 | function construct() { 149 | var formulas = document.getElementById('in').value.replace(/ /g,'');// remove whitespace 150 | if(formulas=='') {return alert("You have to enter a formula.");}; 151 | var r = badchar(formulas); 152 | if(r>=0) {return alert("The string you entered contains the following unrecognized symbol: "+formulas[r]);}; 153 | 154 | var style = document.querySelector('input[name="style"]:checked').value; 155 | var tv = document.querySelector('input[name="tvstyle"]:checked').value; 156 | var cs = document.querySelector('input[name="cset"]:checked').value; 157 | 158 | formulas = formulas.split(','); // create an array of formulas 159 | var trees = formulas.map(parse); // create an array of parse trees 160 | for(var i=0;i0) { // checks if any formulas are still malformed 168 | return alert("One of the formulas you entered is not well formed"); 169 | } 170 | 171 | var table = mkTable(formulas,trees); 172 | if(style=='full' || style=='main') { 173 | var htmltable = htmlTable(table,trees,(style=='main'),tv,cs); 174 | document.getElementById('tt').innerHTML = htmltable; 175 | } 176 | else if(style=='text') { 177 | var texttable = textTable(table,tv,cs); 178 | document.getElementById('tt').innerHTML = '
'+texttable+'
'; 179 | } 180 | else if(style=='latex') { 181 | var latextable = latexTable(table,trees,tv,cs); 182 | document.getElementById('tt').innerHTML = '
'+latextable+'
'; 183 | } 184 | } 185 | 186 | // (Table,[Tree],Boolean) -> String 187 | // Takes a table (as output by mkTable), the trees it's a table of, and a boolean and 188 | // returns an HTML table. If the boolean is set to true, it only prints the column 189 | // under the main connective. 190 | function htmlTable(table,trees,flag,tv,cs) { 191 | var rownum = table[0].length; 192 | var mcs = []; // indices of the main connectives 193 | for(var i=0;i'; // return the html table 202 | 203 | function mkTHrow(tbl) { 204 | var rw = ''; 205 | for(var i=0;i'+''; 209 | } else { 210 | rw += ''+htmlchar(tbl[i][0][j],tv,cs)+''; 211 | } 212 | } 213 | } 214 | return rw+''; 215 | } 216 | 217 | function mkTDrow(tbl,r) { 218 | var rw = ''; 219 | for(var i=0;i'; 223 | } else if(flag && i>0) { 224 | rw += '' 225 | } else { 226 | rw += ''+htmlchar(tbl[i][r][j],tv,cs)+''; 227 | } 228 | if(j==tbl[i][r].length-1 && i!=tbl.length-1) { 229 | rw += '' 230 | } 231 | } 232 | } 233 | return rw+''; 234 | } 235 | } 236 | 237 | // Table -> String 238 | // Takes a table (as output by mkTable) and returns a text version of the table. 239 | function textTable(table,tv,cs) { 240 | var rownum = table[0].length; 241 | var bcind = []; // an array of arrays of ints, locations of biconditionals 242 | for(var i=0;i=0 && r!=0) {rw += ' ';} // add space for biconditional 259 | if(j==tbl[i][r].length-1 && i!=tbl.length-1) {rw += '| ';} // add segment separator 260 | } 261 | } 262 | return rw; 263 | } 264 | function bcInd(a) { 265 | var bc = []; 266 | a.map(function(e,i) {if(e=='<>') {bc.push(i);};}); 267 | return bc; 268 | } 269 | } 270 | 271 | 272 | // Table -> String 273 | // Takes a table (as output by mkTable) and the trees its a table of and returns a LaTex version of the table. 274 | function latexTable(table,trees,tv,cs) { 275 | var rownum = table[0].length; 276 | var mcs = []; // indices of the main connectives 277 | for(var i=0;i=0 && dividers.indexOf(i+1)>=0) { 293 | begintable += ' | c' 294 | } else if(dividers.indexOf(i)>=0) { 295 | begintable += parloc.indexOf(i)>=0 ? ' | c@{}' : ' | c@{ }'; 296 | } else if(dividers.indexOf(i+1)>=0) { 297 | begintable += parloc.indexOf(i)>=0 ? '@{}c@{ }' : '@{ }c'; 298 | } else { 299 | begintable += parloc.indexOf(i)>=0 ? '@{}c@{}' : '@{ }c@{ }'; 300 | } 301 | } 302 | 303 | return begintable+'}\r\n'+out+'\\end{tabular}'; 304 | 305 | function mkrow(tbl,r) { // makes a table row 306 | dividers = []; 307 | colnum = 0; 308 | 309 | var rw = ''; 310 | for(var i=0;i Int 329 | // Finds the index of the main connective in the tree 330 | function mcindex(t) { 331 | if(t.length == 2 || t.length==1) { 332 | return 0; 333 | } else { 334 | return countleaves(t[1])+1; 335 | } 336 | } 337 | 338 | // Tree -> Int 339 | // Takes a tree and returns the number of leaves (terminal nodes) in the tree 340 | function countleaves(t) { 341 | var out = 0; 342 | for(var i=0;i Table 351 | // Takes an array of formulas and their parse trees and returns a truth table as a 352 | // multidimensional array. For n formulas, the array contains n+1 elements. The first 353 | // element is the lhs of the table, and the succeeding elements are the table segments 354 | // for each passed formula. 355 | function mkTable(fs,ts) { 356 | var type = document.querySelector('input[name="type"]:checked').value; // get type of table, two-valued or otherwise 357 | var lhs = mklhs(fs,type); 358 | var rhs = []; 359 | for(var i=0;i LHSTable 366 | // Takes an array of strings and a table type, makes the left hand side of a table 367 | // (i.e. the rows with all the tv assignments) 368 | function mklhs(fs,type) { 369 | var atomic = []; 370 | var tvrows = []; 371 | var tvs = (type=='twoval') ? [[true],[false]] : [[true],[false],[null]]; // send two or three truth values to tvcfun? 372 | for(var i=0;i TableSegment 382 | // Takes a tree, the formula it's a tree of, a LHSTable, and table type, returns a 383 | // TableSegment for the formula 384 | function mktseg(f,t,lhs,type) { 385 | var tbrows=[]; 386 | for(var i=1;i [Char] 402 | // Takes a wff and returns an array with all the atomic sentences in the wff. The 403 | // array has duplicates removed and is sorted in alphabetical order. 404 | function getatomic(s) { 405 | var out = []; 406 | for(var i=0;i Int -> [[val]] 413 | // Piece de resistance, totally illegible ;-) Takes an array of singleton arrays and an 414 | // int n and returns the n-ary Cartesian power of the set of singleton values. In 415 | // practice: takes either [[true],[false]] or [[true], [false], [null]] and the number n 416 | // of atomic formulas and returns and array of all 2- or 3-valued assignments to those 417 | // atoms in a canonical order, i.e. the left side of the truth table 418 | function tvcfun(a,n) { 419 | if(n==0) {return [[]];} 420 | var prev = tvcfun(a,(n-1)); 421 | return a.reduce(foo,[]); 422 | function foo(ac,cv) { 423 | return ac.concat(prev.map((e) => cv.concat(e))); 424 | } 425 | } 426 | 427 | // ([Char], [Bool+]) -> Assignment 428 | // Takes an array of n Chars and an array of n Bools and returns a assignment that 429 | // assigns the nth Bool to the nth Char. 430 | function mkAss(s,b) { 431 | var a = new Object(); 432 | for(var i=0;i Array 439 | // Takes an evaluated tree and turns it into a one dimensional array 440 | function flatten(t) { 441 | if(t.length==5) { 442 | return [].concat(t[0]).concat(flatten(t[1])).concat(t[2]).concat(flatten(t[3])).concat(t[4]); 443 | } else if(t.length==2) { 444 | return [].concat(t[0]).concat(flatten(t[1])); 445 | } else if(t.length==1) { 446 | return [].concat(t[0]); 447 | } 448 | } 449 | 450 | // (Tree, Assignment, TType) -> Tree 451 | // Takes a tree and an assignment of booleans to atomic sentences and table type, returns 452 | //an evaluated tree (i.e. with all atomic sentences and connectives replaced by booleans). 453 | function evlTree(t,a,type) { 454 | if(t.length==5) { 455 | var t1 = evlTree(t[1],a,type); 456 | var t3 = evlTree(t[3],a,type); 457 | return ['',t1,gtTv([t[2],t1,t3],type),t3,''] 458 | } else if(t.length==2) { 459 | var t1 = evlTree(t[1],a,type); 460 | return [gtTv([t[0],t1],type),t1]; 461 | } else if(t.length==1) { 462 | return t[0]=='#' ? [false] : [a[t[0]]]; 463 | } 464 | } 465 | 466 | // Array -> Boolean+ 467 | // Takes an array, the first element of which is a connective, and the rest of which 468 | // are evaluated trees of the formulas it connects, and returns the truth value 469 | // associated with the connective 470 | function gtTv(arr,type) { 471 | switch(arr[0]) { 472 | case '~' : return fneg(tv(arr[1])); 473 | case '&' : return fcnj(tv(arr[1]),tv(arr[2]),type); 474 | case 'v' : return fdsj(tv(arr[1]),tv(arr[2]),type); 475 | case '>' : return fcnd(tv(arr[1]),tv(arr[2]),type); 476 | case '<>' : return fcnj( fcnd(tv(arr[1]),tv(arr[2]),type), fcnd(tv(arr[2]),tv(arr[1]),type), type ); 477 | case '|' : return fneg(fcnj(tv(arr[1]),tv(arr[2]),type)); 478 | case '!' : return fneg(fdsj(tv(arr[1]),tv(arr[2]),type)); 479 | } 480 | function tv(x) { 481 | switch(x.length) { 482 | case 5 : return x[2]; 483 | case 2 : return x[0]; 484 | case 1 : return x[0]; 485 | } 486 | } 487 | } 488 | 489 | // Boolean+ -> Boolean+ 490 | // Negation: takes one truth value, no table type needed since all agree on negation 491 | function fneg(v) { 492 | return v===null ? null : !v; 493 | } 494 | 495 | // (Boolean+, Boolean+, TType) -> Boolean+ 496 | // Conjunction: takes two truth values and a table type 497 | function fcnj(v1,v2,type) { 498 | if(type==='twoval' || type=='luka' || type=='skleen') { 499 | return (v1===null) ? ((v2==null) ? null : (v2 ? null : false)) : ((v2===null) ? (v1 ? null : false) : (v1 && v2)); 500 | } else if(type==='wkleen') { 501 | return (v1===null || v2===null) ? null : (v1 && v2); 502 | } 503 | } 504 | 505 | // (Boolean+, Boolean+, TType) -> Boolean+ 506 | // Disjunction: takes two truth values and a table type 507 | function fdsj(v1,v2,type) { 508 | if(type==='twoval' || type=='luka' || type=='skleen') { 509 | return (v1===null) ? ((v2==null) ? null : (v2 ? true : null)) : ((v2===null) ? (v1 ? true : null) : (v1 || v2)); 510 | } else if(type=='wkleen') { 511 | return (v1===null || v2===null) ? null : (v1 || v2); 512 | } 513 | } 514 | 515 | // (Boolean+, Boolean+, TType) -> Boolean+ 516 | // Conditional: takes two truth values and a table type 517 | function fcnd(v1,v2,type) { 518 | if(type==='twoval' || type=='luka') { 519 | return (v1===null) ? ((v2==null) ? true : (v2 ? true : null)) : ((v2===null) ? (v1 ? null : true) : (!v1 || v2)); 520 | } else if(type=='skleen') { 521 | return (v1===null) ? ((v2==null) ? null : (v2 ? true : null)) : ((v2===null) ? (v1 ? null : true) : (!v1 || v2)); 522 | } else if(type=='wkleen') { 523 | return (v1===null || v2===null) ? null : (!v1 || v2); 524 | } 525 | } 526 | 527 | // Remove duplicates from an array 528 | function rmDup(a) { 529 | return a.filter(function(el,pos) {return a.indexOf(el)==pos;}); 530 | } 531 | 532 | // [Char] -> [Char] 533 | // Takes an array of chars and returns the array sorted from smallest to largest 534 | function sorted(a) { 535 | var b = a.map(function(x) {return x.charCodeAt(0);}); 536 | b = b.sort(function(b,c) {return b-c;}); 537 | return b.map(function(x) {return String.fromCharCode(x);}); 538 | } 539 | 540 | 541 | // FORMULA PARSING CODE 542 | //==================== 543 | 544 | /* THE GRAMMAR 545 | S ::= U S | '(' S B S ')' | A 546 | U ::= '~' 547 | B ::= '&' | 'v' | '>' | '<>' | '|' | '!' 548 | A ::= '#' | 'A' | 'B' | 'C' | 'D' | ... | 'a' | 'b' | ... 549 | */ 550 | 551 | // String -> Tree 552 | // Takes a string and if it's a wff, returns a parse tree of the string, otherwise 553 | // returns an empty array. 554 | function parse(s) { 555 | if(s.length==0) {return [];} 556 | var s1 = []; 557 | var s2 = []; 558 | if(isU(s[0])) { 559 | s1 = parse(s.substring(1)); 560 | return s1.length ? [s[0],s1] : []; 561 | } 562 | if(s[0] =='(' && s[s.length-1]==')') { 563 | var a = gSub(s); 564 | if(a.indexOf(undefined)>=0 || a.indexOf('')>=0) { 565 | return []; 566 | } else { 567 | s1 = parse(a[0]); 568 | s2 = parse(a[2]); 569 | if(s1.length && s2.length) { 570 | return ['(',s1,a[1],s2,')']; 571 | } else {return [];} 572 | } 573 | } 574 | else {return isA(s) ? [s] : []} 575 | } 576 | 577 | // String -> Bool 578 | // Determines if s is an atomic wff 579 | function isA(s) { 580 | if(s.length!=1) {return false;} 581 | var pr = '#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuwxyz'; 582 | return pr.indexOf(s)>=0; 583 | } 584 | 585 | 586 | // String -> Bool 587 | // Determines if s begins with a unary connective 588 | function isU(s) { 589 | return s.indexOf('~')==0; 590 | } 591 | 592 | // String -> [String] 593 | // takes a string beginning with '(' and ending with ')', and determines if there is a 594 | // binary connective enclosed only by the outermost parentheses. If so, returns an array 595 | // with the string to the left and the string to the right of the binary connective; 596 | // otherwise returns an array of three undefined's. 597 | function gSub(s) { 598 | var stk = []; 599 | var l = 0; 600 | for(var i=0;i0) { 604 | stk.pop(); 605 | } else if(stk.length==1 && (l = isB(s.substring(i)))>0) { 606 | return [s.substring(1,i),s.substring(i,i+l),s.substring(i+l,s.length-1)]; 607 | } 608 | } 609 | return [undefined,undefined,undefined]; 610 | } 611 | 612 | // String -> Int 613 | // takes a string and determines if it begins with a binary connective. If so, returns 614 | // the length of the connective, otherwise returns 0. 615 | function isB(s) { 616 | var bc = ['&','v','>','<>','|','!']; 617 | for(var i=0;i Int 626 | // Checks if the string contains any inadmissible characters 627 | function badchar(s) { 628 | var x = ',()~v&<>|!#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuwxyz'; 629 | for(var i=0;i