summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/truthtable/truthtable.sty
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/truthtable/truthtable.sty')
-rw-r--r--macros/luatex/latex/truthtable/truthtable.sty148
1 files changed, 148 insertions, 0 deletions
diff --git a/macros/luatex/latex/truthtable/truthtable.sty b/macros/luatex/latex/truthtable/truthtable.sty
new file mode 100644
index 0000000000..94403911ad
--- /dev/null
+++ b/macros/luatex/latex/truthtable/truthtable.sty
@@ -0,0 +1,148 @@
+% truthtable.sty
+%% Copyright 2021 D. Flück
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status “author-maintained”.
+%
+% The Current Maintainer of this work is D. Flück.
+%
+% This work consists of the file truthtable.sty.
+\NeedsTeXFormat{LaTeX2e}[1994/06/01]
+\ProvidesPackage{truthtable}[2021/10/01 0.0.1 Package for generating truth tables automatically using LuaTeX]
+
+\ProcessOptions\relax
+\@ifpackageloaded{luacode}{
+ \PackageWarningNoLine{truthtable}{Package luacode was already loaded}
+}{
+ \RequirePackage{luacode}
+}
+
+\begin{luacode*}
+
+function Impl(a,b)
+ return (not a or b);
+end
+
+function Equiv(a,b)
+ return ((a and b) or ((not a) and (not b)));
+end
+
+function ComputeRows(header)
+ return 2^header
+end
+
+function Split(s, delimiter)
+ local result = {};
+ for match in (s..delimiter):gmatch("(.-)"..delimiter) do
+ table.insert(result, match);
+ end
+ return result;
+end
+
+function EvaluateFormula(formula)
+ local parsedFormula = "function res() return( " .. string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(formula, " ", ""),">>","Impl"),"__","Equiv"),"!","not "),"&" ," and "),"|"," or "),";",",") .. " ) end";
+
+ chunk = load(parsedFormula);
+ chunk();
+ local result = res();
+ return result;
+end
+
+function toBits(num)
+ local t = "" -- will contain the bits
+ while num>0 do
+ local rest = math.fmod(num,2)
+ if (rest == 1) then
+ t = "1" .. t
+ else
+ t = "0" .. t
+ end
+
+ num=(num-rest)/2
+ end
+ return t;
+end
+
+function printTruthValue(expr, dTrue, dFalse)
+
+ local returnVal = ""
+
+ if (expr) then
+ returnVal = dTrue;
+ else
+ returnVal = dFalse;
+ end
+
+ return returnVal;
+end
+
+function parse(commaSepVariables, commaSepDisplayVariables, commaSepResultRows, commaSepResultDisplayRows, displayTrue, displayFalse)
+ local vrbls = Split(commaSepVariables, ",");
+ local numberOfColumns = #(vrbls);
+ local rows = ComputeRows(numberOfColumns);
+ local dVrbls = Split(commaSepDisplayVariables, ",");
+ local resRows = Split(commaSepResultRows, ",");
+ local dResRows = Split(commaSepResultDisplayRows, ",");
+
+ local dHeader = string.gsub(commaSepDisplayVariables, ",", " & ") .. " & " .. string.gsub(commaSepResultDisplayRows, ",", " & ") .. " \\\\ \\hline";
+
+ if (not (numberOfColumns == #(vrbls) and numberOfColumns == #(dVrbls))) then
+ return("error");
+ end
+
+ local tableContent = dHeader;
+
+ for i = (rows - 1),0,-1
+ do
+ local bitString = toBits(i);
+
+ while #bitString < numberOfColumns do
+ bitString = "0" .. bitString
+ end
+
+ local wVrbls = commaSepVariables;
+ local wCommaSepRows = commaSepResultRows
+ for ii = 1,numberOfColumns
+ do
+ wVrbls = string.gsub(wVrbls, vrbls[ii], (string.sub(bitString,ii,ii) == "1" ) and "+" or "-" )
+ wCommaSepRows = string.gsub(wCommaSepRows, vrbls[ii], (string.sub(bitString,ii,ii) == "1" ) and "+" or "-" )
+ end
+
+ local aWVrbls = Split(string.gsub(string.gsub(wVrbls, "+", "true"),"-", "false"), ",");
+
+ local aWCommaSepRows = Split(string.gsub(string.gsub(wCommaSepRows, "+", "true"),"-", "false"), ",");
+
+ local row = "";
+
+ for c = 1,#(aWVrbls)
+ do
+ row = row .. printTruthValue(EvaluateFormula(aWVrbls[c]), displayTrue, displayFalse) .. " & ";
+ end
+
+ for c = 1,#(aWCommaSepRows)
+ do
+ row = row .. printTruthValue(EvaluateFormula(aWCommaSepRows[c]), displayTrue, displayFalse) .. " & ";
+ end
+
+ row = string.sub(row, 1, #row - 2) .. "\\\\"
+
+ tableContent = tableContent .. "\n" .. row
+ end
+
+ tex.print(tableContent);
+end
+
+\end{luacode*}
+
+\newcommand{\truthtable}[6]{
+ \luadirect{parse("#1", "\luaescapestring{#2}", "\luaescapestring{#3}", "\luaescapestring{#4}", "\luaescapestring{#5}","\luaescapestring{#6}")}
+}
+
+\endinput \ No newline at end of file