Cognitive Complexity - negation and parentheses in logical expressions

Hello!

I write a cognitive compelxity computing engine and need some clarifing about negations and parentheses.

Cognitive complexity whitepaper has this example (page 7):

if (a           // +1 for `if`
    &&          // +1
    !(b && c))  // +1

Why does the third increment trigger?
Cause of negation ! ? - other examples with single negation (before variable) doesn’t increment complexity counter.
Cause of second parentheses? - sonar-java skips parentheses in logical expressions during complexity compluting.
Maybe the ! AND parentheses make increment?

Thanks for any advice and examples.

1 Like

Hey @nixel2007,

Pretty cool to learn that you are implementing the Cognitive Complexity metric! Out of curiosity, what language are you targeting?

As far as I remember from implementation (and looking at our implementations handling binary expressions in our PHP, JavaScript, Java plugins), the idea is to flatten the chain of binary expressions (ignoring parentheses), and increase complexity every time it changes operator:

A && B     // +1
    && C   // +0
      && D // +0

A && B     // +1
    || C   // +1
      && D // +1   

In you case, however, I guess that the negation in the middle break the chain, introducing an extra +1. It also seems to me that logical complements are not taken into account in our computation. According to my tests on SonarJava, I can see that we are going to count your case like this:

if (   // +1
    A
      && // +1
         ! // +0
          ( // +0
           B
             && // +1 
                C
                 )
                  )

Good luck with your implementation!
I hope this helps!

Cheers,
Michael

1 Like

Hi, @Michael!

It’s 1C (BSL) - language of 1C:Enterprise. I’ve posted a NEW RELEASE announce some time ago - [NEW RELEASE] 1C (BSL) Community Plugin 1.0.1

You can find used cognitive complexity computer implemantation here (as it is a part of BSL Language Server) - https://github.com/1c-syntax/bsl-language-server/blob/develop/src/main/java/org/github/_1c_syntax/bsl/languageserver/context/computer/CognitiveComplexityComputer.java and resource file https://github.com/1c-syntax/bsl-language-server/blob/develop/src/test/resources/context/computer/CognitiveComplexityComputerTest.bsl

Hm, looks like it is the most difficult part of computing :slight_smile: I’ll try to implement it based on your test.

It would be cool, if this clarification will be placed at whitepaper.

Thanks! Cognitive complexity is a main feature for 1.1 sonar-community-plugin release (besides 9 new rules) :slight_smile:

3 Likes

Hi,

Just to followup on Michael’s excellent answers, it’s the negation of a group that start a new series. Specifically !(b && c) in the example from the whitepaper is a new series because the reader must mentally translate / understand that:
!(b && c) == !b || !c
so the whole sequence becomes:
a && (!b || !c).
When written out like that the trickiness lurking in !(b && c) is a bit more obvious. And trickiness is what we’re counting here. :slight_smile:

I’ll go back to the whitepaper and see if an expansion / clarification is in order.

 
Ann

3 Likes

Hi, one more small question :slight_smile:

What about operations after the negation of group?

if (a            // +1 for `if`
   &&            // +1
   !(b && c))    // +1
   && d          // ?

Does negation of group completely break the chain of &&? Should I increment complexity counter and threat it like new chain-start?

1 Like

Hi,

The negated group is a distinct sequence - distinct from what comes before and after. So yes:

if (             // +1 for `if`
   a &&          // +1
   !(b && c)     // +1
   && d)         // +1

And if it’s rearranged to the simpler, semantic equivalent:

if (             // +1 for `if`
   a && d &&     // +1
   !(b && c))    // +1

Because again, look at the mental translations you have to understand

if (             // +1 for `if`
   a &&          // +1
   (!b || !c)    // +1
   && d)         // +1
if (             // +1 for `if`
   a && d &&     // +1
   (!b || !c))   // +1

 
HTH,
Ann

2 Likes

Thanks a lot, Ann!

I’ll put your examples to tests