I am working on a function of which the core will consist of something like:

dta = Reverse[Boole[BooleanTable[{a, b,
      Or[a, b],
      Not[And[Not[a], Not[b]]]
hdr = {
   "P", "Q", "(P \[Or] Q)", "\[Not](\[Not]P \[And] \[Not]Q)"
 Prepend[dta, hdr],
 Dividers -> {{False, False, True}, {True, True}}, 
 Spacings -> {1, 1/2},
 Alignment -> Center, FrameStyle -> Gray]

If you run this you'll get an idea of what I am working with. At the end of the day this might be helpful for students to self-investigate propositional logic.

My current issue is the following: I would like to translate, convert, ( or whatever it is called ), an expression like

  a, b,
  Or[a, b],
  Not[And[Not[a], Not[b]]]

which will act as an argument in the function


 "P", "Q", "(P \[Or] Q)", "\[Not](\[Not]P \[And] \[Not]Q)"

Let me explain:

letters a,b to P,Q or a,b,c to P,Q,R or a,b,c,d to P,Q,R,S 
Or[a,b] to "(P \[Or] Q)", and so on... including And, Nor, Nand, Not, Implies

Would this be, at all, possible? If so, can you give a hint as to how start analyzing the argument? What properties should the function have, and so on?

What have I tried so far?

SetAttributes[f, HoldFirst]
f[v_] := Module[{},
  HoldForm[v]] /. {a :> P, b :> Q}

As you can see I am in trouble with


I don't know how to handle the Or and how to continue from here.

Isn't this quite a challenge?

  • 1
    $\begingroup$ rules = {a -> P, b -> Q, c -> R, d -> S, e -> T}; and then Apply[Or, {a, b}] /. rules ? or further use // TraditionalForm at the end? $\endgroup$
    – Syed
    Dec 19, 2021 at 11:48
  • $\begingroup$ Thank you. Forget the R,S,T for now. Can you add the Apply to the function f, in some way? That would possibly bring us a step further ? - The intermediate result must be: "(P [Or] Q)" including double quotes and brackets. $\endgroup$ Dec 20, 2021 at 9:59
  • 1
    $\begingroup$ I have updated my answer. $\endgroup$
    – Syed
    Dec 23, 2021 at 10:48

1 Answer 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:

h[expr_] := Module[{
   rules = MapThread[Rule,
     {CharacterRange["a", "h"],
      CharacterRange["P", "W"]}],
   logicStrings = {"!" -> "\[Not]", "&&" -> "\[And]", "||" -> "\[Or]"
     (*,"Nor"\[Rule] "\[Nor]","Nand"\[Rule] "\[UpArrow]","Xor"\[Rule] 
  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.


h[Xor[a, b, Or[c, d]] && Xor[b, c]]

enter image description here

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]~
  , Spacings -> {1, 1/2}
  , Alignment -> Center
  , FrameStyle -> Gray
  ] /. {0 -> F, 1 -> T}

enter image description here

For your original example:

enter image description here

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"
   "(" <>
    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)}\}$$

  • $\begingroup$ Thank you, @Syed. - I will try to use this as a replacement for the hdr in the primary code: hdr = { "P", "Q", "(P [Or] Q)", "[Not]([Not]P [And] [Not]Q)" }; I could not have imagined that this would be such a complicated function. $\endgroup$ Dec 21, 2021 at 12:20
  • 1
    $\begingroup$ I was so caught up in writing this, I didn't pay attention to the hdr above. Try: expr1 = Not[And[Not[a], Not[b]]] and then StringReplace[ ToString[expr1 /. {a -> "P", b -> "Q"}], {"a" -> "P", "b" -> "Q", "&&" -> "\[And]", "!" -> "\[Not]"}]. If it works, I will edit this into the answer. $\endgroup$
    – Syed
    Dec 21, 2021 at 12:56
  • $\begingroup$ Thank you !, I' am able to work on this again this afternoon. ( Europe ) $\endgroup$ Dec 22, 2021 at 10:45
  • $\begingroup$ It should be possible to convert a general Boolean expression to a "standard logic expression" somehow in Mathematica; but as I have discovered, I need to learn a lot more. For multilevel expressions, I still don't have a solution as it requires (perhaps) a recursive approach that I cannot quite pin down. $\endgroup$
    – Syed
    Dec 22, 2021 at 11:11
  • $\begingroup$ Thank you so very, very much @Syed. - Due to Christmas "pressures" I haven't been able to work much on any of my ( pet ) projects. Will come back to this. $\endgroup$ Dec 24, 2021 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.