EDIT-1
I think it is working better now. I have taken the liberty to change a few things that I will explain.
First define a utility function:
Clear[h];
h[expr_] := Module[{
rules = MapThread[Rule,
{CharacterRange["a", "h"],
CharacterRange["P", "W"]}],
logicStrings = {"!" -> "\[Not]", "&&" -> "\[And]", "||" -> "\[Or]"
(*,"Nor"\[Rule] "\[Nor]","Nand"\[Rule] "\[UpArrow]","Xor"\[Rule]
"\[CirclePlus]","Xnor"->"\[CircleDot]","Implies"\[Rule]
"\[Implies]"*)
}
},
StringReplace[ (expr // StandardForm // ToString),
Join[rules, logicStrings]]
]
Key change is the use of "StandardForm". You can test this with inputs in \[]
notation for variables or Xor[a,b]
form.
Test:
h[Xor[a, b, Or[c, d]] && Xor[b, c]]
For creating logic truth tables:
1- exprList
is the list of table entries; e.g.;
exprList = {a \[Implies] b, c, (a \[Implies] b) \[Implies] c,
d, ((a \[Implies] b) \[Implies] c) \[Implies] d};
2- From this, BooleanVariables
will be extracted. These will form the however many variable columns that go before the first vertical divider. For our example:
vars = (BooleanVariables /@ exprList ) // Flatten // Union
{a, b, c, d}
3- Now, table columns consist of the Boolean variables and the expressions, these are joined.
tableCols = vars~Join~exprList
{a, b, c, d,
a \[Implies] b, c, (a \[Implies] b) \[Implies]
c, d, ((a \[Implies] b) \[Implies] c) \[Implies] d}
4- Variable go before the divider placed after Length@vars
. Appropriate number of False values in a list will be spliced.
varDivs = ConstantArray[False, Length@vars]
{False, False, False, False}
5- hdr
is the utility function h
applied to tableCols
generating strings as required. 2^n rows are generated; and various dividers are put in place. A divider is placed at the end of the table. For standard logic courses "T T T" entries go first, (For circuits, usually "0 0 0" entries go first) so on line 3 Reverse@dta
accomplishes that. At the end, you can add a rule to change 1/0 to T/F if you want or remove the Boole
used in dta
.
dta = Reverse[Boole[BooleanTable[tableCols]]];
hdr = h /@ tableCols
Grid[Prepend[Reverse@dta, hdr]
, Dividers -> {
{Splice[varDivs], True},
{True, True}~Join~ConstantArray[False, 2^Length[vars] - 1]~
Join~{True}
}
, Spacings -> {1, 1/2}
, Alignment -> Center
, FrameStyle -> Gray
] /. {0 -> F, 1 -> T}
For your original example:
I hope this turns out to be more useful than the original attempt.
Original attempt
Too long for a comment, but here is an attempt:
f[v_] := Module[
{
k = List @@ v,
ch = Switch[v[[0]],
And, "\[And]",
Or, "\[Or]",
Nand, "\[Nand]",
Nor, "\[Nor]",
Xor, "\[Xor]",
Xnor, "\[Xnor]",
Implies, "\[Implies]"
],
rules = {
"a" -> "P"
, "b" -> "Q"
, "c" -> "R"
, "d" -> "S"
, "e" -> "T"
}
},
StringReplace[
"(" <>
StringJoin[Riffle[Riffle[ToString /@ k, ch], " "]] <>
")"
, rules
]
]
Usage: f
will return a string in standard logic notation for the args translated according to rules
.
{f[Or[a, b]], f[And[a, b, c]], f[Xor[a, b, c, d]], f[Implies[a, b]]}
$$\{\text{(P $\lor $ Q)},\text{(P $\land $ Q $\land $ R)},\text{(P $\veebar $ Q $\veebar $ R $\veebar $ S)},\text{(P $\Rightarrow $ Q)}\}$$
rules = {a -> P, b -> Q, c -> R, d -> S, e -> T};
and thenApply[Or, {a, b}] /. rules
? or further use// TraditionalForm
at the end? $\endgroup$