Dear Hans,

I am sorry that I miss 
“context(func(set,u) and “1” or “0”)
In your code.

Correcting it, it works perfectly.

By changing the logic function, we can draw truth tables upto 3 variables.

After making a truth table, I draw Karnaugh Map of that table.
I made a short MetaFun code for drawing Karnaugh map for the class material. 
In that code, it calculate the truth value using MetaFun function again.
 
Recently, I read about “How to bring the data made by Lua into MetaFun.”  
So, my next try is to  bring the truth value which is made in Lua.
Then I omit the truth-value-calculation part from the MetaFun code.

If there is a way to draw a diagonal in the \starttabulate ..., then we may use Lua code to do the job. 
In the wiki, there is an example of diagonal rule.

https://wiki.contextgarden.net/TABLE#Diagonal_rules

I tried it in \starttabulate … \stoptabulate, but it is not working.
And the shape drawn using MetaFun is much better.

Anyway, I’ll try it.

Thank you again.

Best wishes,

Dalyoung


PS: Here is my code which produces the truth table and its Karnaugh Map. The code for the truth table is cleaned up by Hans, but the MetaFun part will be changed.

\startMPdefinitions
numeric tVal[][],rlSkip[],rlNum[],uk, wd, ht;
string val[],code[],subcode;
uk := LineHeight;
wd := 1.5uk;
ht := uk+5pt;

vardef funcOr(expr a,b) =
if a + b = 0:
out := 0;
else:
out := 1;
fi;
out
enddef;
vardef funcAnd(expr a,b) =
if a + b > 1:
out := 1;
else:
out := 0;
fi;
out
enddef;
vardef funcNot(expr a) =
if a = 0: out:=1; else: out:=0 fi;
out
enddef;

def KmapFrame(expr first,second) =
val[0]:=first;
val[1]:=second;
for k=0,1:
rlSkip[k] := length val[k];
rlNum[k] := 2*rlSkip[k];
if rlSkip[k] = 1:
code[k] := "01";
else:
code[k] :="00011110";
fi;
endfor;
label.top(textext("$" & first & "$"), (-.7wd,0));
label.top(textext("$" & second & "$"), (-.3wd,.5ht));
% drawing lines
draw (-1.2wd,0) -- origin -- ((rlNum[1]+1)*wd,0);
draw (0, 1.1ht) -- origin -- (0,-(rlNum[0]+.2)*ht);
draw (-wd,ht) --origin;
for i=0 upto rlNum[0]-1:
subcode := substring (i*rlSkip[0],(i+1)*rlSkip[0]) of code[0];
label.top(textext(subcode), ((-.7wd, -(i+1)*ht)));
endfor;
for i=0 upto rlNum[1]-1:
subcode := substring (i*rlSkip[1],(i+1)*rlSkip[1]) of code[1];
label.top(textext(subcode), ((i+1)*wd,.3ht));
endfor;
setbounds currentpicture to boundingbox currentpicture enlarged 2mm;
draw boundingbox currentpicture;
enddef;
\stopMPdefinitions

\startbuffer[Kmap_xyz]
KmapFrame("x", "yz");

vardef logicFunc(expr a,b,c) =
result := funcAnd(funcNot(b), funcOr(a,c));
result
enddef;

for i=0,1:
for j=0 upto rlNum[1]-1:
b := scantokens(substring (j*rlSkip[1],j*rlSkip[1]+1) of code[1]);
c := scantokens(substring (j*rlSkip[1]+1,j*rlSkip[1]+2) of code[1]);

tVal[i][j] := logicFunc(i,b,c);
label.top(tVal[i][j], ((j+1)*wd,-(i+1)*ht));
endfor;
endfor;
draw unitsquare xyscaled (1wd,2ht) shifted (1.5wd,-2.1ht) withpen pencircle scaled 2pt withcolor .625blue ;
draw unitsquare xyscaled (1.8wd,1ht) shifted (.6wd,-2.1ht) withpen pencircle scaled 2pt withcolor .625red ;
\stopbuffer

\starttext

\startluacode
function document.MakeHead(p,a)
if not a then
local t = p
p = string.rep("|mcw(1cm)",#p-1) .. "|mcw(2cm)|"
a = t
end
context.starttabulate { p }
context.FL()
for i=1,#a do
context.NC() context(a[i])
end
context.NC() context.NR()
context.LL()
end
function document.MakeFooter()
context.HL()
context.stoptabulate()
end

local tf = { true, false }

function document.truthTable(a,func)
document.MakeHead(a)
for i,s in ipairs(tf) do
for j,t in ipairs(tf) do
for k,u in ipairs(tf) do
context.NC()
context(s and "1" or "0")
context.NC()
context(t and "1" or "0")
context.NC()
if #a == 3 then
break
end
context(u and "1" or "0")
context.NC()
context(func(s,t,u) and "1" or "0")
context.NC()
context.AR()
end
if #a == 3 then
context(func(s,t) and "1" or "0")
context.NC()
context.AR()
end
end
end
document.MakeFooter()
end
\stopluacode

\startluacode
--statistics.starttiming()
local function logicF(p,q,r)
return (p or r) and (not q)
end

document.truthTable({ "x", "y","z","f(x,y,x)"},logicF)
\stopluacode

\processMPbuffer[Kmap_xyz]

\stoptext