Sitemap

Using De Morgans Laws in your code

3 min readJan 2, 2023

--

As I progress through the end of my BSCS coursework, I am in the middle of ( whispers ) discrete mathematics.
A lot of this so far, s learning how to read and write logical expressions without the use of ! , && , or ||

In the context of this post, I will explain how they should look but will provide the rub equivalent as well.

I came across De Morgans Laws and found them to be interesting. In short, these laws describe how to distribute a negation symbol.

¬( p ^ q)

The ^ means “and,” so in Rubyist terms && , also known as a conjunction

In the context here v mean “or,” or || respectively, also known as a disjunction

The above would read, in English, “not p and q.”

# in ruby
p = true
q = true

!(p && q) # ¬( p ^ q)

De Morgan’s laws are a set of logical equivalences that allow us to manipulate boolean expressions involving negations, conjunctions, and disjunctions. Named after the mathematician Augustus De Morgan, these laws provide a set of rules for distributing negations inside parenthesized expressions.

Get RJ Robinson’s stories in your inbox

Join Medium for free to get updates from this writer.

The first De Morgan’s law states that the negation of a disjunction is equivalent to the conjunction of the negations of the individual terms. In other words, if we have an expression of the form !(p || q), we can rewrite it as (!p && !q). This is useful because it allows us to negate complex expressions by breaking them down into simpler parts and negating each part individually.

The second De Morgan’s law is the converse of the first law and states that the negation of a conjunction is equivalent to the disjunction of the negations of the individual terms. In other words, if we have an expression of the form !(p && q), we can rewrite it as (!p || !q). Like the first law, this allows us to negate complex expressions by breaking them down into simpler parts and negating each part individually.

In the Ruby programming language, we can use these laws to manipulate boolean expressions in our code.

For example, consider the following code:

# De Morgan's First Law

p = "the person is at least 18 years old"
q = "they will be admitted to the party"

p && q # The person is 18 and admitted into the party
!(p && q) # the person is either not 18, or not allowed in the party.

# now we can flip this using de morgans 1st law

(!p || !q) # the person is either not 18, or not allowed in the party.

#so... you can see that these are logically the same thing.
!(p && q) === (!p || !q)

Let's look at it the other way.

p = "The person has a job"
q = "The person has a trust fund"

(p || q) # reads "The person has a job or a trust fund

!(p || q) # reads "The person does not have a trust fund, or does not have a job

# lets flip this.

(!p && !q) # The person does not have a job, and does not have a trust fund.

#logically speaking
(!p && !q) === !(p || q) # these are the same.

This is equivalent to the original expression and will behave similarly when executed. Understanding De Morgan’s laws allow us to write more concise and easily readable code that involves complex boolean expressions.

--

--

RJ Robinson
RJ Robinson

Written by RJ Robinson

A Sr. Engineer and aspiring blogger. Passionate coder by day, meme creator by night. Expect tech talk & dad jokes on his blog.