1
$\begingroup$

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)"
   };
Grid[
 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

to

 "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

f[Or[a,b]]

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

Isn't this quite a challenge?

$\endgroup$
3
  • 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
    Commented 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$ Commented Dec 20, 2021 at 9:59
  • 1
    $\begingroup$ I have updated my answer. $\endgroup$
    – Syed
    Commented Dec 23, 2021 at 10:48

1 Answer 1

1
$\begingroup$

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]]

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]~
     Join~{True}
    }
  , 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"
     }
   },
  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)}\}$$

$\endgroup$
5
  • $\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$ Commented 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
    Commented Dec 21, 2021 at 12:56
  • $\begingroup$ Thank you !, I' am able to work on this again this afternoon. ( Europe ) $\endgroup$ Commented 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
    Commented 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$ Commented Dec 24, 2021 at 13:28

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