Entry level propositional logic simplification - boolean-logic

This is an entry level propositional logic question.
An exercise's final 2 statements are:
(A v B) v (B v C)
A v B v C
Is the last statement a distributive simplification? I can't figure out how the last statement was arrived at.
Appreciate any help.

So first use the associative property
(A v B) v (B v C)
can be written like this
A v (B v B) v C
because the associative property will hold.
The idempotent law states that B v B = B
So we end up with
A v B v C

Related

If A and B are two logical variables under what circumstances, or conditions on A and B, happens that: A B = A + B

If A and B are two logical variables under what circumstances, or conditions on A and B, happens
that:
A B = A + B
The easiest answer is gnasher729's, from the comments. Here is a truth table with columns for both expressions:
A B AB A+B
T T T T
T F F T
F T F T
F F F F
We see AB = A+B for the cases (A, B) in {(T, T), (F, F)}. A simpler way of saying this is that AB = A+B iff A = B.

Making unique values into duplicates in R

I am working with R and I have a table that look like this...
A
B
C
D
E
F
And I need the table to look like this...
A
A
A
A
A
B
B
B
B
B
C
C
C
C
C
D
D
D
D
D
E
E
E
E
E
F
F
F
F
F
So,I need the same values 5 times in order to match them with another column.
Any help would greatly appreciated.
Thanks!
Not sure if the table has associated data that also has to be duplicated. Looking at a vector or single data.frame column can use rep
data <- LETTERS[1:6]
rep(data, each = 5) # will repeat each position 5 times prior to going to next position
rep(data, times = 5) # will repeat entire array 5 times

Find the middle of a string after first space and before last in MySql

Given a Name Field with Contents "A B C D" how can I extract "B C"?
I can use:
substring_Index(Name,' ',1) to extract 'A'
substring_Index(Name,' ',-1) to extract 'D'
But am not sure how to combine those to get the middle string. One issue is that both 'A' and 'D' can be anywhere from 1 to 4 characters and there can also be 'A B D'. So basically looking to extract whatever is not the two substrings above.
Something like below:
select trim(replace(replace(col,concat(substring_Index(col,' ',1),' '),''),concat(' ',substring_Index(col,' ',-1)),'')) from foo;
Check sqlfiddle: http://sqlfiddle.com/#!9/57f88/8
After getting some good answers I tried my own approach which seems to automatically account for
However many words between 'A' and 'D'
However many letters in 'A' or 'D'
Whether or not 'A' starts with same letter as D
Sorry for not taking time to do sqlfiddle deep in middle of project but as you can see works on any pattern:
Original 'A B C D' pattern:
Select 'A B C D', substring('A B C D',(char_length(substring_Index('A B C D',' ',1))+2),(char_length('A B C D')-char_length(substring_Index('A B C D',' ',-1)))-(char_length(substring_Index('A B C D',' ',1))+2))
More words between 'A' and 'D':
Select 'A B C X D', substring('A B C X D',(char_length(substring_Index('A B C X D',' ',1))+2),(char_length('A B C X D')-char_length(substring_Index('A B C X D',' ',-1)))-(char_length(substring_Index('A B C X D',' ',1))+2))
Length of 'A' and 'D' greater than one letter:
Select 'AA B C DDDD', substring('AA B C DDDD',(char_length(substring_Index('AA B C DDDD',' ',1))+2),(char_length('AA B C DDDD')-char_length(substring_Index('AA B C DDDD',' ',-1)))-(char_length(substring_Index('AA B C DDDD',' ',1))+2))
'A' and 'D' start with same letter (issue in earlier answer):
Select 'A B C A', substring('A B C A',(char_length(substring_Index('A B C A',' ',1))+2),(char_length('A B C A')-char_length(substring_Index('A B C A',' ',-1)))-(char_length(substring_Index('A B C A',' ',1))+2))

how to calculate the negation of a selection predicate of a SQL query?

I have a sql query 'q' which is of the form :
Select attribute from table1, table2 where SC;
Here 'SC' is the conjunction of all the selection predicates in q
In my case : SC is balance <1000 and salary >=50000
Now i want to calculate "NSC" which is negation of SC in q and need some help.
Per your post you said i want to calculate "NSC" which is negation of SC and
SC is balance <1000 and salary >=50000
So, Negation of SC would simply be balance >= 1000 and salary < 50000
So, you can do like
Select attribute from table1 where balance >= 1000 and salary < 50000
(OR)
Select attribute from table1
where attribute not in
( select attribute from table1
where balance <1000 and salary >=50000 )
The general answer to your question is given by De Morgan's laws.
NOT(P AND Q) = NOT(P) OR NOT(Q)
and
NOT(P OR Q) = NOT(P) AND NOT(Q)
Your expression NOT(balance < 1000 AND salary >= 50000) becomes
balance >= 1000 OR salary < 50000
De Morgan's laws apply to Boolean algebra with a binary logic. If you have NULL values, things get more complicated. The way to go depends on the result you are expecting. A very useful function, in this respect, is the COALESCE function which returns the first non-null parameter passed to it.
COALESCE(balance, 0) >= 1000 OR COALESCE(salary, 0) < 50000
Take your pick of two methods.
Aside: null
I will assume there are no NULLs in tables or expressions. Because that complicates things. In particular, if we want to treat NULL as if it were a value in conditions then:
v = w is true in SQL when v = w AND v IS NOT NULL AND w IS NOT NULL
v != w is true in SQL when v != w AND v IS NOT NULL AND
Also SQL has lots of special behaviour when there are nulls. Also beware that nulls get generated by SQL in things like OUTER JOIN and IN of a subquery. See SQL and Relational Theory: How to Write Accurate SQL Code, 2nd Edition.
1. not ( expression )
SQL doesn't have a comparson-negating "not". You can build an expression that is the not of another expression by parsing from the top down:
not (c AND d) is (not (c) OR not (d))
not (c OR d) is (not (c) AND not(d))
not (e NOT NOTable-operator o) is (e NOTable-operator o)
not (e NOTable-operator o) is (e NOT NOTable-operator o)
not (e NOT NOTable-function(f)) is (e NOTable-function(f))
not (e notable-function(f)) is (e NOT NOTable-function(f))
not (e != f) is (e = f)
not (e = f) is (e != f)
not (v < w) is is (v >= w)
not NOT b is b -- boolean b
not b is (NOT (b)) -- boolean b
Now given SC you find expression not(SC) and you write:
SELECT ... FROM ... WHERE not(SC)
2. Not not ( expression )
In standard SQL you could write the preceding query as:
(SELECT ... FROM ...)
EXCEPT
(SELECT ... FROM ... WHERE SC)
(In Oracle it's MINUS.) But MySql doesn't have EXCEPT. But s EXCEPT t is
SELECT s.a,...
FROM s
LEFT JOIN t
ON s.a = t.a AND ...
WHERE t.a IS NULL
When s.a has no match in t, t.a IS NULL. So this returns only unmatched rows. So
SELECT ... FROM ... WHERE not(SC)
is:
SELECT s.a,...
FROM (SELECT ... FROM ...) s
LEFT JOIN (SELECT ... FROM ... WHERE SC) t
ON s.a = t.a AND ...
WHERE t.a IS NULL

Is there a shortcut to normalizing a table where the columns=rows?

Suppose you had the mySQL table describing if you can mix two substances
Product A B C
---------------------
A y n y
B n y y
C y y y
The first step would be to transform it like
P1 P2 ?
-----------
A A y
A B n
A C y
B A y
B B y
B C n
C A y
C B n
C C y
But then you have duplicate information. (eg. If A can mix with B, then B can mix with A), so, you can remove several rows to get
P1 P2 ?
-----------
A A y
A B n
A C y
B B y
B C n
C C y
While the last step was pretty easy with a small table, doing it manually would take forever on a larger table. How would one go about automating the removal of rows with duplicate MEANING, but not identical content?
Thanks, I hope my question makes sense as I am still learning databases
If it's safe to assume that you're starting with all relationships doubled up, e.g.
If A B is in the table, then B A is guaranteed to be in the table.
Then all you have to do is remove all rows where P2 < P1;
DELETE FROM `table_name` WHERE `P2` < `P1`;
If this isn't the case, you can make it the case by going through the table and inserting all the duplicate rows if they don't already exist, then running this.
I don't think it's necessary in your situation, but as an intellectual exercise, you could build on Jamie Wong's solution and prevent non-duplicated columns from being removed with an EXISTS clause. Something like this:
DELETE FROM `table_name` AS t1
WHERE `P2` < `P1`
AND EXISTS (SELECT NULL FROM `table_name` AS t2
WHERE t1.`P1` = t2.`P2` AND t1.`P2` = t2.`P1`);
It pretty much just makes sure that there's a duplicate before deleting anything.
(My MySQL syntax might be a little off; it's been a while.)
Step 1 (as you've already done): Transform to Table2
P1 P2 ?
-----------
A A y
A B n
A C y
B A y
B B y
B C n
C A y
C B n
C C y
Step 2: ReOrder Columns, Select Distinct
SELECT DISTINCT
IF P1<P2 THEN P1 ELSE P2 END as P1, -- this puts the smallest value in P1
IF P1>P2 THEN P1 ELSE P2 END as P2 -- this puts the largest value in P2
FROM Table2
WHERE NOT P1=P2 --(Assuming records like A, A, y are not interesting)
I'm not a mySQL guy, so you might need to check the if/then syntax, but this seems conceptually ok anyway.