# Is !(p && q) exactly the same as !p || !q?

**URL:** <https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388>\
**Category:** Factual Questions\
**Created:** [December 13, 2017, 1:18pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388 "2017-12-13T13:18:23Z")\
**Posts on this page:** 20\
**Page:** 9

<div class="post-metadata">

**Author:** ![Francis\_Vaughan](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/francis_vaughan/32/3093_2.png) [@Francis\_Vaughan](https://boards.straightdope.com/u/Francis_Vaughan)\
**Post date:** [December 22, 2017, 5:10am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/161 "2017-12-22T05:10:40Z")

</div>

> [@Chronos](#):
>
> Whoa, really? I’ve contemplated something like this before, but always came to the conclusion that it’d be way too hard. How does it deal with trig functions, for instance? A small error in an angle can lead to an infinite error in a tangent (in fact, _any_ nonzero Gaussian error on an angle input leads to an infinite standard deviation of tangent’s output). It seems to me that, in order to be able to do this to any useful degree, you’d have to store not just summary information like standard deviations, but entire error distributions.

I’m not sure how they handle things like tan, but overall the theory seems pretty solid. It is however predicated on small changes in standard deviation which change in value - whihc is rather what you would expect would be needed.

You can read about it here: [Welcome to the uncertainties package — uncertainties Python package 3.0.1 documentation](https://pythonhosted.org/uncertainties/)

Where I think Python/Numpy is a bit of a game changer is that the paradigm for numpy is close enough to Matlab that Matlab users can feel at home, and transliteration of many codes is not difficult, and close to automatic. But the ability to augment the system in all sorts of neat ways, such as the uncertainly package get you a significant step further in utility. However, I do worry that there isn’t the rigour across this landscape of packages that you might hope from a commercially supported product. The scope for weird interactions and oddities means that the end user needs to be quite rigorous themselves about testing and analysis of results - which is no bad thing. There is a lot of bad science out there already from poor understanding and use of numerical tools.

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 2, 2018, 3:30am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/162 "2018-01-02T03:30:34Z")

</div>

I made a fucking pyramid out of bricks. It took me 7 hours and I used two separate logical operators (I might be using wrong terminology). I made it green, then I made the bricks 1/4 of the size but 4x as many, then I made it with green stripes - that was pretty exciting. I did accomplish my goal of not leaving the house though, that’s something. Just thought I’d share.

It’s the first program I’ve ever written BTW.

---

<div class="post-metadata">

**Author:** ![DPRK](https://avatars.discourse-cdn.com/v4/letter/d/4491bb/32.png) [@DPRK](https://boards.straightdope.com/u/DPRK)\
**Post date:** [January 2, 2018, 4:28am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/163 "2018-01-02T04:28:19Z")

</div>

> [@Francis\_Vaughan](#):
>
> HPC is indeed a very different beast. The trouble here is that there are no languages that really get you what you need, you absolutely have to know what the damned thing is going to compile down to, and have a very good idea of what the hardware is doing under the hood.
> 
> In this respect something like the C++11 template language is actually rather nice, as you can essentially write your own smarts into the templates and have some control over the paradigm. When you are worried about cache performance and pipeline stalls you are very much in a different world. Parallel is at least passably helped by things like OpenMP, but even here, if you don’t really know what is going on under the hood, you are not fully in control of the performance. Big parallel is still a bit in the stone age with things like MPI. Language level support for things like release consistency would not go astray. Or tagged memory, but that is something of a vain hope.
> 
> I’ve been in the position of coding my own coroutine kernel to slip in under C++ code for a discrete event simulator in order to claw back a pretty substantial amount of performance (about doubled the speed of the sim) and here every cycle was crafted, with a very careful eye on cache and pipeline performance, as well as such mundane things as instruction decode and I cache performance. You are way under the level of language definition, and right in the guts of language implementation.
> 
> I’m insane enough to still have Fortran2000 code with OpenMP, forall and where clauses in it. For the right platform and problem this is actually a pretty nice way of coding.

Why is this insane? What’s the right way to do it? (yes or no to Fortran, C++, OpenMP, assembly language?)

---

<div class="post-metadata">

**Author:** ![Francis\_Vaughan](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/francis_vaughan/32/3093_2.png) [@Francis\_Vaughan](https://boards.straightdope.com/u/Francis_Vaughan)\
**Post date:** [January 2, 2018, 4:41am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/164 "2018-01-02T04:41:32Z")

</div>

> [@DPRK](#):
>
> Why is this insane? What’s the right way to do it? (yes or no to Fortran, C++, OpenMP, assembly language?)

No, it isn’t insane. More a comment on the common perception of coding in Fortran.

Once you are working on getting the performance in serious code you use the right tool for the job. There are times when Fortran is very much the right tool for the job. Indeed if you look at a modern Fortran it makes some of the the supposedly modern languages look much quite stone age. (This most certainly includes C++. ) But you must have a very clear and detailed understanding of what is actually happening in the hardware. So no matter what level you are coding at, you need to be performing deep analysis of the code’s performance, and on the constant lookout for problems that rob you of performance.

The right answer comes from the problem you are trying to solve. The gamut of HPC problems is so large that until you have a pretty clear idea about the problem, from top to bottom, you can’t make a sensible choice about anything. These choices include languages, programming paradigms, and most assuredly, the hardware. They all interrelate, and you converge on a system design as you explore the options. For really big problems you need to run around the cycle a couple of times.

---

<div class="post-metadata">

**Author:** ![Dr.Strangelove](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/dr.strangelove/32/6613_2.png) [@Dr.Strangelove](https://boards.straightdope.com/u/Dr.Strangelove)\
**Post date:** [January 2, 2018, 4:49am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/165 "2018-01-02T04:49:25Z")

</div>

OpenMP is a bit of a weird beast. It’s handy if one has an “embarrassingly parallel” problem that can be chopped up at a high level and you don’t have a lot of time to spend on the parallelization. I’ve used it myself for a number of toy projects and it’s fine.

However, it’s no replacement for understanding the low-level OS synchronization and threading primitives. If you really need to squeeze every last bit out of a system, you don’t really have a choice.

In my experience, OpenMP also has some weird issues. Last I checked, on Windows it would slam every core to 100% utilization as soon as you used a parallel primitive. Apparently it used a spin loop (as opposed to a halt instruction or the like that would be more power efficient) to minimize latency. Horrible if you care about power at all, but the alternative is potentially worse–your app actually getting slower because it takes longer to spin up all the threads than any savings it would get.

---

<div class="post-metadata">

**Author:** ![Chronos](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/chronos/32/134_2.png) [@Chronos](https://boards.straightdope.com/u/Chronos)\
**Post date:** [January 2, 2018, 1:36pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/166 "2018-01-02T13:36:12Z")

</div>

**Mr. Nylock** , what do you mean about the pyramid? Did you write a program that draws a pyramid on the screen, or is that a metaphor for a long task that took a lot of work but is now completed?

**Francis Vaughan** , for some of us, the mere words “modern Fortran” are enough to elicit a giggle. Yes, I know that modern versions of it exist, but one is far more likely to encounter Fortran in the form of legacy code, which will be F77 at best. Using that monstrosity, any time you could possibly avoid doing so, is indeed insane.

---

<div class="post-metadata">

**Author:** ![DPRK](https://avatars.discourse-cdn.com/v4/letter/d/4491bb/32.png) [@DPRK](https://boards.straightdope.com/u/DPRK)\
**Post date:** [January 2, 2018, 2:16pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/167 "2018-01-02T14:16:04Z")

</div>

> [@Chronos](#):
>
> **Francis Vaughan** , for some of us, the mere words “modern Fortran” are enough to elicit a giggle. Yes, I know that modern versions of it exist, but one is far more likely to encounter Fortran in the form of legacy code, which will be F77 at best. Using that monstrosity, any time you could possibly avoid doing so, is indeed insane.

LAPACK uses Fortran 90 now.

ETA if there were some advantage to using, say, C++ for such a fundamental and critical piece of software, I’m sure they would, so the choice of language is telling.

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 2, 2018, 3:30pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/168 "2018-01-02T15:30:41Z")

</div>

> [@Chronos](#):
>
> **Mr. Nylock** , what do you mean about the pyramid? Did you write a program that draws a pyramid on the screen, or is that a metaphor for a long task that took a lot of work but is now completed?

I literally wrote a program that draws a pyramid on the screen. It took like 7 hours and was only about 14 lines or so. I used a while loop statement with 2 ifs, I think I might have been able to use a nested for loop; I’ll try that today. I’m very bad/at a very novice level at programming; but I’m still accomplishing my main goal of finding a way to occupy myself without spending any money.

---

<div class="post-metadata">

**Author:** ![Quartz](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/quartz/32/267_2.png) [@Quartz](https://boards.straightdope.com/u/Quartz)\
**Post date:** [January 2, 2018, 4:32pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/169 "2018-01-02T16:32:50Z")

</div>

It might help if you rewrote it using words. the left-hand side is NOT (P AND Q) and the right-hand side is NOT § OR NOT (Q)

People think they’re being neat and concise using symbols when all they’re doing is confusing themselves.

---

<div class="post-metadata">

**Author:** ![Dr.Strangelove](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/dr.strangelove/32/6613_2.png) [@Dr.Strangelove](https://boards.straightdope.com/u/Dr.Strangelove)\
**Post date:** [January 2, 2018, 6:45pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/170 "2018-01-02T18:45:43Z")

</div>

One problem with that approach is that English words don’t quite mean what they do in programming and logic. In particular, the English “or” is usually an exclusive or.

- I don’t have peanut butter and jelly.  
Isn’t the same as:
- I don’t have peanut butter or I don’t have jelly.  
Instead, it means:
- I don’t have peanut butter or I don’t have jelly or I have neither peanut butter nor jelly.

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 2, 2018, 7:00pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/171 "2018-01-02T19:00:10Z")

</div>

> [@Quartz](#):
>
> It might help if you rewrote it using words. the left-hand side is NOT (P AND Q) and the right-hand side is NOT (P) OR NOT (Q)
> 
> People think they’re being neat and concise using symbols when all they’re doing is confusing themselves.

I think you’re missing the point. Or maybe I’m missing the point. Or maybe I’m confusing myself or you’re confusing me or I’m confusing you or perhaps we’re confusing each other and everyone else. Is an eel a fish?

---

<div class="post-metadata">

**Author:** ![Corner\_Case](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/corner_case/32/234_2.png) [@Corner\_Case](https://boards.straightdope.com/u/Corner_Case)\
**Post date:** [January 2, 2018, 7:20pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/172 "2018-01-02T19:20:26Z")

</div>

> [@Chronos](#):
>
> \*\ ***Francis Vaughan** , for some of us, the mere words “modern Fortran” are enough to elicit a giggle. Yes, I know that modern versions of it exist, but one is far more likely to encounter Fortran in the form of legacy code, which will be F77 at best. Using that monstrosity, any time you could possibly avoid doing so, is indeed insane.

Decades ago, in my spare time, I wrote a communications program in Pascal on a VAX that let users talk to each other. Pretty simple. (Confession - the first version polled so much it brought the server to a crawl - but I fixed it quickly and it barely consumed any resources). So, in my real work writing Ada for the Air Force, they liked the little communications program, and wanted to use it. Woo hoo! They just wanted a translation (rubbing hands thinking about translating it to Ada). “Just translate it to Fortran 77”. Jaw drops - but okay. So I translated my Pascal program to Fortran 77!

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 21, 2018, 2:55pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/173 "2018-01-21T14:55:12Z")

</div>

> [@eschereal](#):
>
> Well, C, of course, because all other languages are evil: they are not-C.
> 
> **switch**

I was wondering if I could use switch in this program I wrote yesterday; the book and lectures don’t really spend much time talking about switch, but I think that using switch could make the code a little cleaner. My coding is ugly, but it works. Don’t worry, lives aren’t at stake, money isn’t on the line.

public class FindRange extends ConsoleProgram {

/\*\* Setinel value and min/max initialization. \*/   
double SENTINEL = 0;  
int min = 1;  
int max = 1;

```
public void run() {
	println("This program finds the largest and smallest numbers.");
	int question = readInt("? ");
	int firstInt = question;	

```

/\*\* For instances where the sentinel is first entry. _/   
if (question == SENTINEL){  
println(“You typed in sentinel dumbass.”);  
}   
/_\* For instances where the sentinel is second entry. _/  
if (question != SENTINEL){  
int question2 = readInt("? ");  
if (question2 == SENTINEL){  
println("Min. = " + question);  
println("Max. = " + firstInt);  
}  
/_\* Finds minimum and maximum of two or more numbers entered. \*/  
if (question2 != SENTINEL){  
int questionInfinity = readInt("? ");  
if (question2 \> question){  
min = question;  
max = question2;  
}  
else{  
min = question2;  
max = question;  
}  
while (true){  
if (questionInfinity != SENTINEL && questionInfinity \< min){  
min = questionInfinity;  
}  
if (questionInfinity != SENTINEL && questionInfinity \> max){  
max = questionInfinity;  
}  
if (questionInfinity == SENTINEL){  
println("Min. = "+ min);  
println("Max. = “+ max);  
break;  
}  
questionInfinity = readInt(”? ");  
}   
}  
}  
}  
}

I tried using code tags but it messed up the formatting. Even copy and pasting does not format the tabs a paragraphs correctly.

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [January 21, 2018, 4:55pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/174 "2018-01-21T16:55:02Z")

</div>

So I gather you type in a sequence of numbers with 0 as the terminating value and after the second number it starts telling you what the minimum and maximum numbers you entered were.

You don’t need switch. You need to clean up a bunch of things. What is ‘firstint’ for? It has the same value as ‘question’. In your loop you are repeating the condition ‘questionInfinity != SENTINEL’. You don’t need the && in those if conditions, you need to nest if-elses, and do your min/max logic in an inner if-else. You don’t need ‘questionInfinity == SENTINEL’ at all, it’s just the else condition for the first if.

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 21, 2018, 5:24pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/175 "2018-01-21T17:24:43Z")

</div>

> [@TriPolar](#):
>
> So I gather you type in a sequence of numbers with 0 as the terminating value and after the second number it starts telling you what the minimum and maximum numbers you entered were.
> 
> You don’t need switch. You need to clean up a bunch of things. What is ‘firstint’ for? It has the same value as ‘question’. In your loop you are repeating the condition ‘questionInfinity != SENTINEL’. You don’t need the && in those if conditions, you need to nest if-elses, and do your min/max logic in an inner if-else. You don’t need ‘questionInfinity == SENTINEL’ at all, it’s just the else condition for the first if.

Thank you for taking the time to look at my code (I have to figure out how to get the formatting right, so I know it’s a little bit more difficult to read than it should be - I can use a lot of advise as is apparent. The firstInt is something I forgot to erase I think. You pretty much have the right idea as far as the general way the program works (it is a fairly simple program) :

There are the three conditions that must be met :

1. If the sentinel is the first integer typed in, the message must appear and the program must be stopped.

2. If the sentinel is the second integer typed in, both the min. and max. must display the first integer and the program must be stopped.

3. If the sentinel is the third or any integer thereafter, the program must display the min. and max. and the program should stop.

I like your suggestions; I think I’ll work on the nesting ifs and elses. For some reason I’ve been trying not to nest too much, but think that I need to have more practice implementing if/else statements.

I’ll look at the code again in a day or two and see if I can make it cleaner. I’m writing a different program today so I might not have time to look at this one today.

BTW, why am I having so much formatting trouble copying code from eclipse?

---

<div class="post-metadata">

**Author:** ![TriPolar](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tripolar/32/3008_2.png) [@TriPolar](https://boards.straightdope.com/u/TriPolar)\
**Post date:** [January 21, 2018, 6:25pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/176 "2018-01-21T18:25:55Z")

</div>

I should have mentioned that you should use a return if you detect the 0 as the first or second entry. There’s no need to fail out of conditions all the way to the end of the code. Yes, I saw you were displaying the min and max after the 0, I didn’t exactly write it that way in my description.

Anyway, the thing to note is the repetition in the if conditions. That will tell you that you should be nesting ifs.

---

<div class="post-metadata">

**Author:** ![Chronos](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/chronos/32/134_2.png) [@Chronos](https://boards.straightdope.com/u/Chronos)\
**Post date:** [January 21, 2018, 6:53pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/177 "2018-01-21T18:53:36Z")

</div>

The code tags don’t work properly on the new message board skin, but they still work fine on the old skin. There’s a drop-down in the blue bar at the bottom of the page you can use to switch back, if you’d like. Meanwhile, a workaround is to use php tags instead of code tags, which are almost the same but with a little color-coding that won’t actually be relevant to non-PHP languages. Why the php tag works when code doesn’t, I don’t know, but there you go.

---

<div class="post-metadata">

**Author:** ![Mr.Nylock](https://avatars.discourse-cdn.com/v4/letter/m/77aa72/32.png) [@Mr.Nylock](https://boards.straightdope.com/u/Mr.Nylock)\
**Post date:** [January 21, 2018, 8:29pm UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/178 "2018-01-21T20:29:08Z")

</div>

> [@Chronos](#):
>
> The code tags don’t work properly on the new message board skin, but they still work fine on the old skin. There’s a drop-down in the blue bar at the bottom of the page you can use to switch back, if you’d like. Meanwhile, a workaround is to use php tags instead of code tags, which are almost the same but with a little color-coding that won’t actually be relevant to non-PHP languages. Why the php tag works when code doesn’t, I don’t know, but there you go.

I remember toggling between the two a few weeks ago and wondering if there was any practical difference for me posting. Well, now I guess I have the correct answer. 🙂

---

<div class="post-metadata">

**Author:** ![Francis\_Vaughan](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/francis_vaughan/32/3093_2.png) [@Francis\_Vaughan](https://boards.straightdope.com/u/Francis_Vaughan)\
**Post date:** [January 22, 2018, 12:46am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/179 "2018-01-22T00:46:21Z")

</div>

On a more general level of coding the question is useful.  
First up, you need to understand finite state automata. Understand the basic idea of any sort of input specification being expressible as a grammar, and that these grammars can be transformed into a finite sate automata. Now there is a lot of theory here, but unless you are writing a compiler, you can ignore most of it.  
What you do, in general, is construct your code so that it lives in a loop that is reading input “tokens”. Where a token is the basic unit of the grammar. Here you have two tokens. Integer and sentinal. The top of the loop reads the next token. The program has a “state” - basically a simple enumeration, that defines the current execution state of the automata. On he basis of the current state, and the token you receive, the internals of the loop take an action.  
A switch statement can be used here. You switch on the state value to decide on the action to take.

Structuring your code like this has a huge number of advantages. You can formally reason about the code. You can automatically create automata from other formal specifications. But most of all, this is the tactic that is most likely to get you error free and maintainable code.

For your problem the states are something like:  
initial  
one values read  
two values read

and the input tokens are integer, sentinal.

Your code looks a bit like like

```php
state = initial
while not done:
    input = read_integer()
    switch state
    initial: 
        if input = sentinal:
            barf
            done = true
        else
             calcualate stuff
             state = one_value_read
         endif
     one_value_read:
        ....
        state = two values_read
      two_values_read:
         ....
      end switch
end do

```

---

<div class="post-metadata">

**Author:** ![Francis\_Vaughan](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/francis_vaughan/32/3093_2.png) [@Francis\_Vaughan](https://boards.straightdope.com/u/Francis_Vaughan)\
**Post date:** [January 22, 2018, 12:54am UTC](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388/180 "2018-01-22T00:54:08Z")

</div>

Sorry, I accidentally hit the post button before I was done, and didn’t have time in the edit window to properly write the example. So the indenting is messed up and it could do with some more cleaning up generally, but there should be enough to get the overall idea. I can hack it some more if needed to get the idea across.

[Previous page](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388.md?page=8)

[Next page](https://boards.straightdope.com/t/is-p-q-exactly-the-same-as-p-q/804388.md?page=10)
