Home > database >  How to simplify this logical expression in a single return statement?
How to simplify this logical expression in a single return statement?

Time:03-02

I have been trying to simplify this function in a single return A ... B ... C statement but some cases always slip out. How could this checks be expressed in a logical way (with and, or, not, etc.)?

bool f(bool C, bool B, bool A)
{
if (A)
    return true;

if (B)
    return false;
   
if (C)
    return true;

return false;
}

CodePudding user response:

bool f(bool C, bool B, bool A)
{
if (A)
    return true;

if (B)
    return false;
   
if (C)
    return true;

return false;
}

is equivalent to

bool f(bool C, bool B, bool A)
{
if (A)
    return true;
else if (B)
    return false;
else if (C)
    return true;
else 
    return false;
}

is equivalent to:

bool f(bool C, bool B, bool A)
{
if (A)
    return true;
else if (!B)
{
    if (C)
        return true;
    else
        return false;
}
else
    return false;
}

is equivalent to:

bool f(bool C, bool B, bool A)
{
if (A)
    return true;
else if (!B and C)
    return true;
else
    return false;
}

is equivalent to:

bool f(bool C, bool B, bool A)
{
if (A or (!B and C))
    return true;
else
    return false;
}

is equivalent to:

bool f(bool C, bool B, bool A)
{
return (A or (!B and C));
}

CodePudding user response:

Make a truth table

  A    B     C     return
  1    0     0     1
  1    0     1     1
  1    1     0     1
  1    1     1     1
  0    0     0     0
  0    0     1     1
  0    1     0     0
  0    1     1     0

Then either you already see how it can be shortened or you just try something, for example:

bool f(bool C, bool B, bool A)
{
    return A || (C && not B);
}

Then write a test to see that it always returns the same. I wrote a "manual" test to see that the same truth table is produced:

void test(bool A, bool B, bool C){
    std::cout << A << " " << B << " " << C << " " << f(C,B,A) << "\n";
}

int main()
{
  for (int A = 1; A >= 0; --A){
      for (int B = 0; B<2;  B){
          for (int C = 0; C<2;  C){
              test(A,B,C);
          }
      }
  }
}

And indeed the enter image description here

static std::vector<bool> table{false, true, false, false, true, true, true, true};

which you can then extract the value with

table[4 * A   2 * B   C]

Taking this one step further, you could simplify to

242 & (A << 4   B << 2   C)

Both are branchless, which is nice.

CodePudding user response:

Alternative answer:

bool f(bool C, bool B, bool A)
{
if (A)
    return true;

if (B)
    return false;
   
if (C)
    return true;

return false;
}

You can create a boolean matrix for this:

A B C f(C, B, A)
f f f f
f f t t
f t f f
f t t f
t f f t
t f t t
t t f t
t t t t

The lower half evaluates to if(A) The remainding entries are these:

B C f(C, B, A)
f f f
f t t
t f f
t t f

There is only one true-case here: if(!B && C)

To combine these two statements you have to use or as only one of them needs to evaluate to true: if((A) || (!B && C))

CodePudding user response:

ya got ternary operators to your rescue ....

  • Related