I cannot rely on BOOLEAN logic when I use NOT together with AND and OR
I am trying to understand how boolean logic works when I use NOT. To give an example using awk
I have a text file containing
CORE
PORT
CORE
PORT
COREPORT
CORE
COREPORT
And I would like to remove all COREPORT lines. The way I thought I would do it was with (DO NOT CREATE) AND (NOT PORT) for example
awk '/!CORE/&&/!PORT/{print}'
But when I try to do this, I actually have to use OR instead of AND
awk '/!CORE/||/!PORT/{print}'
I would be very happy if someone could explain where my thinking is wrong and very happy if it could be visualized with a venn diagram or something like a boolean machine in kathyschrock
a source to share
I'll try to give a gut feel or your boolean expressions, for the math other posters have done this very well.
Your boolean expression must be true for the lines you want to store .
- ! PORT means the line does not contain PORT
- ! CORE means the line does not contain CORE
Hence, your boolean expression means that lines that at the same time do not contain PORT and do not contain CORE. Obviously your file doesn't have lines like this ...
You should use or
because what you really want to express is to store lines that do not contain both PORT and CORE, but as you can see there is only one in the above statement , you are trying to say something like: does the line do PORT, it also contains CORE, then I don't want that. And that !(/CORE/ && /PORT/)
, and using logical math, you can also write this /!CORE/||/!PORT/
as you saw yourself.
In general, negative statements are difficult to understand. I'm not the only one who said that. For example, Damian Conway at Perl Best Practice pointed this out and recommended using positive assertions whenever possible (and using unless
a Perl statement instead if
if you want to cancel a condition).
a source to share
A good way to visualize logic is a Karnot map .
Or, if you want to handle mathematical expressions, just remember that:
- not (a and b) matches (not a) or (not b)
- not (a or b) matches (not a) and (not b)
Actually, you don't want: (not CORE) and (not PORT), but: not (CORE and PORT), which is the same as: (not CORE) or (not PORT)
a source to share