Logical symbols learned in marriage (and implementation examples in Python)

Humble participants

You are working hard to get married. The annual income you want from the other party is over 8 million yen. I would like to attend a speed dating party, but I don't think it makes sense to attend unless ** at least one of the participants ** has an annual income of 8 million yen or more. Given a list of participants and their annual income, do not answer whether it makes sense to attend.

Logical symbol

Let's assume that the set of participants is $ M $ and the annual income is $ Y $ 10,000. The above condition uses logical symbols,

\exists M[Y\geq800]

Can be expressed as. $ \ exists $ means "there is". The point is ** "If even one person has an annual income of 8 million or more, it's OK immediately" **.

Program example

def main1(M):
    for Y in M:
        if Y >= 800:
            return "Attendance"
    return "Do not attend"

print(main1([800,900,1000,1100]))#Attendance
print(main1([500,600,700,800]))#Attendance
print(main1([400,500,600,700]))#Do not attend

You can look at the participants in order, and if you find a person of 8 million yen, you can stop the search there. It is the same no matter how many people there are after one.

Greedy participants

You have become more and more bullish after having many experiences of speed dating. I have come to think that there is no point in attending unless all of the participants ** have an annual income of 8 million yen or more.

Logical symbol

In this case,

\forall M[Y\geq800]

Can be expressed as. $ \ Forall $ means "about everything". However, if you try to implement this in the program as it is, it will be a little troublesome, so we will do a little logical conversion. The above proposition is

\lnot(\lnot \forall M[Y\geq800])

Is equivalent to. $ \ Lnot $ represents negation. For a two-choice question, ** "not'not A'" ** is equivalent to ** "is A" **. ** $ \ lnot $ can be moved to the right by swapping $ \ forall $ and $ \ exists $ **

\lnot(\lnot \forall M[Y\geq800])\\
\Leftrightarrow \lnot(\exists M\lnot[Y\geq800])\\
\Leftrightarrow \lnot(\exists M[Y<800])

The conversion is established. The point is ** "If even one person has an annual income of less than 800, he will be out immediately" **.

Program example

def main2(M):
    for Y in M:
        if Y < 800 :
            return "Do not attend"
    return "Attendance"

print(main2([800,900,1000,1100]))#Attendance
print(main2([500,600,700,800]))#Do not attend
print(main2([400,500,600,700]))#Do not attend

Judgment of attendance is also becoming strict.

Unmotivated planner

You who attended the marriage party too much turned to the planning side before you knew it. We decided to arrange multiple groups to meet the needs of the attendees. However, you are not motivated, so I thought it would be nice if there was ** at least one ** group with ** at least one ** participant with an annual income of 8 million yen or more. At worst, only one person is enough! What an unmotivated planner! Attendees are not a collection.

Let the set of groups be $ G $

\exists G \exists M[Y\geq800]

It will be. This implementation is easy, and there is no change in saying that even one person should have an annual income of 8 million or more.

def main3(G):
    for M in G:
        for Y in M:
            if Y >= 800:
                return "Pass"
    return "failure"   

print(main3([[400,500,600,700],[500,600,700,800]]))#Pass
print(main3([[400,500,600,800],[500,600,700,800]]))#Pass
print(main3([[300,400,500,600],[800,900,1000,1100]]))#Pass
print(main3([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass

Perfect planner

After receiving complaints about too much text, you decided to prepare a perfect lineup this time. ** All participants in all groups earn more than 8 million yen per year **.

\forall G \forall M[Y \geq 800]\\
\Leftrightarrow \lnot(\lnot \forall G \forall M[Y \geq 800])\\
\Leftrightarrow \lnot(\exists G \lnot(\forall M[Y \geq 800]))\\
\Leftrightarrow \lnot(\exists G \exists M[Y < 800])\\

If even one person has an annual income of less than 800, it will be out immediately. Implementation is just as easy.

def main4(G):
    for M in G:
        for Y in M:
            if Y < 800:
                return "failure"
    return "Pass"   

print(main4([[400,500,600,700],[500,600,700,800]]))#failure
print(main4([[400,500,600,800],[500,600,700,800]]))#failure
print(main4([[300,400,500,600],[800,900,1000,1100]]))#failure
print(main4([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass

Realistic planner 1

The perfect lineup was well received, but it was too difficult to get people together and soon reached its limit. This time I thought about such a plan.

"There is at least one ** dream team ** in the group with all members earning more than 8 million a year."

\exists G \forall M[Y \geq 800]\\
\Leftrightarrow \exists G \lnot(\lnot \forall M[Y \geq 800])\\
\Leftrightarrow \exists G \lnot(\exists M[Y < 800])\\

It's difficult to implement this in one loop like it used to be, but it can be implemented simply by splitting the function.

def main5(M):
    for Y in M:
        if Y < 800:
            return False
    return True

def main6(G):
    for M in G:
        if main5(M):
            return "Pass"
    return "failure"

print(main6([[400,500,600,700],[500,600,700,800]]))#failure
print(main6([[400,500,600,800],[500,600,700,800]]))#failure
print(main6([[300,400,500,600],[800,900,1000,1100]]))#Pass
print(main6([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass

Realistic planner part 2

With this dream team plan, the attendees who were drawn by Baba started to complain as a matter of course. So you came up with the next plan.

"We guarantee that each team has at least one person with an annual income of 8 million or more."

\forall G \exists M[Y \geq 800]\\
\Leftrightarrow \lnot ( \lnot \forall G \exists M[Y \geq 800])\\
\Leftrightarrow \lnot (\exists G \lnot(\exists M[Y \geq 800]))\\
def main7(M):
    for Y in M:
        if Y >= 800:
            return False
    return True

def main8(G):
    for M in G:
        if main7(M):
            return "failure"
    return "Pass"

print(main8([[400,500,600,700],[500,600,700,800]]))#failure
print(main8([[400,500,600,800],[500,600,700,800]]))#Pass
print(main8([[300,400,500,600],[800,900,1000,1100]]))#failure
print(main8([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass

With this, stable operation was finally possible. I'm happy.

bonus

If you want to complete the latter two cases in one function, you need to prepare a separate bool variable for the flag.

\exists G \forall M[Y \geq 800]\\
\Leftrightarrow \exists G \lnot(\lnot \forall M[Y \geq 800])\\
\Leftrightarrow \exists G \lnot(\exists M[Y < 800])\\
def main9(G):
    for M in G:
        fail_at_least = 0
        for Y in M:
            if Y < 800:
                fail_at_least = 1
        if not fail_at_least:
            return "Pass"
    return "failure" 
\forall G \exists M[Y \geq 800]\\
\Leftrightarrow \lnot ( \lnot \forall G \exists M[Y \geq 800])\\
\Leftrightarrow \lnot (\exists G \lnot ( \exists M[Y \geq 800]))\\
def main10(G):
    for M in G:
        success_at_least = 0
        for Y in M:
            if Y >= 800:
                success_at_least = 1
        if not success_at_least:
            return "failure"
    return "Pass" 

Since the flag condition is easy to get confused, I personally try to give a variable name such as fail_at_least (fail at least once) even if the name is long.

Recommended Posts

Logical symbols learned in marriage (and implementation examples in Python)
Sorting algorithm and implementation in Python
Implementation module "deque" in queue and Python
Deep Learning from scratch-Chapter 4 tips on deep learning theory and implementation learned in Python
Python variables and data types learned in chemoinformatics
Explanation of edit distance and implementation in Python
RNN implementation in python
ValueObject implementation in Python
SVM implementation in python
Merge sort implementation / complexity analysis and experiment in Python
Overview of generalized linear models and implementation in Python
Refactoring Learned in Python (Basic)
Python classes learned in chemoinformatics
Stack and Queue in Python
Neural network implementation in python
Unittest and CI in Python
Maxout description and implementation (Python)
Implementation of quicksort in Python
What I learned in Python
Character code learned in Python
Python functions learned in chemoinformatics
MIDI packages in Python midi and pretty_midi
Difference between == and is in python
View photos in Python and html
HMM parameter estimation implementation in python
Mixed normal distribution implementation in python
Manipulate files and folders in Python
About dtypes in Python and Cython
Implementation of life game in Python
Check and move directories in Python
Ciphertext in Python: IND-CCA2 and RSA-OAEP
Hashing data in R and Python
I learned about processes in Python
Function synthesis and application in Python
Elementary ITK usage learned in Python
Export and output files in Python
Implementation of original sorting in Python
Reverse Hiragana and Katakana in Python2.7
Reading and writing text in Python
[GUI in Python] PyQt5-Menu and Toolbar-
Create and read messagepacks in Python
Implementation of particle filters in Python and application to state space models
Overlapping regular expressions in Python and Java
Basic Linear Algebra Learned in Python (Part 1)
Differences in authenticity between Python and JavaScript
Modules and packages in Python are "namespaces"
Avoid nested loops in PHP and Python
AM modulation and demodulation in Python Part 2
difference between statements (statements) and expressions (expressions) in Python
Eigenvalues and eigenvectors: Linear algebra in Python <7>
Line graphs and scale lines in python
Implement FIR filters in Python and C
Differences in syntax between Python and Java
Check and receive Serial port in Python (Port check)
Search and play YouTube videos in Python
Difference between @classmethod and @staticmethod in Python
Python data structure and internal implementation ~ List ~
Difference between append and + = in Python list
Difference between nonlocal and global in Python
Write O_SYNC file in C and Python
Dealing with "years and months" in Python