Generate truth tables in Maxima - boolean-logic

I know Maxima can evaluate logical expressions, e.g.:
false and true or not true
will evaluate to
false
This is great, but how can I generate truth tables containing every interpretation of all variables?
For example, I'd want
A and B or not B
to generate a table such as this one:
| A | B | A and B or not B |
+-----+-----+--------------------+
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |

truth_table(A and B or not B);

Related

Automatically inserting additional columns in MySQL 8.0 [duplicate]

This question already has an answer here:
MySQL pivot row into dynamic number of columns
(1 answer)
Closed 3 years ago.
Say I have a table like so
+----+----------+------+
| id | name | type |
+----+----------+------+
| 1 | apple | F |
| 1 | pear | F |
| 1 | cucumber | V |
| 2 | orange | F |
| 2 | grass | NULL |
| 2 | broccoli | V |
| 3 | flower | NULL |
| 3 | tomato | NULL |
+----+----------+------+
I want to end up with a table that counts the number of elements for each type (including NULL types) AND for each id, like this:
+----+-----------------+--------------+--------------+
| id | type_NULL_count | type_F_count | type_V_count |
+----+-----------------+--------------+--------------+
| 1 | 0 | 2 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 2 | 0 | 0 |
+----+-----------------+--------------+--------------+
This is rather easy to do, but is there a way (a query I can write or something else) such that when I go back and edit one of the type fields in the first table, I end up with a properly updated count table?
For example, let's say I want to add a new type (type X) and change the type field for flower from NULL to X. Is there a way to end up with the following table without having to rewrite the query or add more statements?
+----+-----------------+--------------+--------------+--------------+
| id | type_NULL_count | type_F_count | type_V_count | type_X_count |
+----+-----------------+--------------+--------------+--------------+
| 1 | 0 | 2 | 1 | 0 |
| 2 | 1 | 1 | 1 | 0 |
| 3 | 1 | 0 | 0 | 1 |
+----+-----------------+--------------+--------------+--------------+
I'm not sure if this is the best way to do this, so I am open to suggestions
Having a secondary table which it's number of columns changes based on your first table is not a viable option.
Do you need to keep the result in a table or it will be displayed as a report?
I think a better way to do this is using the SQL below calculate counts by id plus type and display using your data display tool the way you like it.
select id, type, count(*) count
from d
group by 1,2
order by 1,2
The output would be
id type count
1 F 2
1 V 1
2 F 1
2 V 1
2 1
3 X 1
3 1

How to determine what's changed between database records

Presume first, that the following table exists in a MySQL Database
|----|-----|-----|----|----|-----------|--------------|----|
| id | rid | ver | n1 | n2 | s1 | s2 | b1 |
|----|-----|-----|----|----|-----------|--------------|----|
| 1 | 1 | 1 | 0 | 1 | Hello | World | 0 |
| 2 | 1 | 2 | 1 | 1 | Hello | World | 0 |
| 3 | 1 | 3 | 0 | 0 | Goodbye | Cruel World | 0 |
| 4 | 2 | 1 | 0 | 0 | Hello | Doctor | 1 |
| 5 | 2 | 2 | 0 | 0 | Hello | Nurse | 1 |
| 6 | 3 | 1 | 0 | 0 | Dippity | Doo-Dah | 1 |
|----|-----|-----|----|----|-----------|--------------|----|
Question
How do I write a query to determine whether for any given rid, what changed between the most recent version and the version immediately preceding it (if any) such that it produces something like this:
|-----|-----------------|-----------------|-----------------|
| rid | numbers_changed | strings_changed | boolean_changed |
|-----|-----------------|-----------------|-----------------|
| 1 | TRUE | TRUE | FALSE |
| 2 | FALSE | TRUE | FALSE |
| 3 | n/a | n/a | n/a |
|-----|-----------------|-----------------|-----------------|
I think that I should be able to do this by doing a cross-join between the table and itself but I can't resolve how to perform this join to get the desired output.
I need to generate this "report" for a table with 10's of columns and 1-10 versions of 100's of records (resulting in 1000's of rows). Note the particular design of the database is not my own and altering the structure of the database (at this time) is not an acceptable approach.
The actual format of the output isn't important - and if it simplifies the query getting a "full breakdown" of what changed for each "change set" would also be acceptable, for example
|-----|-----|-----|----|----|----|----|----|
| rid | old | new | n1 | n2 | s1 | s2 | b1 |
|-----|-----|-----|----|----|----|----|----|
| 1 | 1 | 2 | Y | N | N | N | N |
| 1 | 2 | 3 | Y | Y | Y | Y | N |
| 2 | 4 | 5 | N | N | N | Y | N |
|-----|-----|-----|----|----|----|----|----|
Note that it is also ok, in this case to omit rid records which only have a single version, as for the purposes of this report I only care about records that have changed and getting a separate list of records that haven't changed is an easy query
You can join every row with the following one with
select *
from history h1
join history h2
on h2.rid = h1.rid
and h2.id = (
select min(h.id)
from history h
where h.rid = h1.rid
and h.id > h1.id
);
Then you just need to compare every column from the two rows like h1.n1 <> h2.n1 as n1.
The full query would be:
select h1.rid, h1.id as old, h2.id as new
, h1.n1 <> h2.n1 as n1
, h1.n2 <> h2.n2 as n2
, h1.s1 <> h2.s1 as s1
, h1.s2 <> h2.s2 as s2
, h1.b1 <> h2.b1 as b1
from history h1
join history h2
on h2.rid = h1.rid
and h2.id = (
select min(h.id)
from history h
where h.rid = h1.rid
and h.id > h1.id
);
Result:
| rid | old | new | n1 | n2 | s1 | s2 | b1 |
|-----|-----|-----|----|----|----|----|----|
| 1 | 1 | 2 | 1 | 0 | 0 | 0 | 0 |
| 1 | 2 | 3 | 1 | 1 | 1 | 1 | 0 |
| 2 | 4 | 5 | 0 | 0 | 0 | 1 | 0 |
Demo: http://sqlfiddle.com/#!9/2e5d12/5
If the columns can contain NULLs, You might need something like NOT h1.n1 <=> h2.n1 as n1. <=> is a NULL-save equality check.
If the version within a rid group is guaranteed to be consecutive, you can simplify the JOIN to
from history h1
join history h2
on h2.rid = h1.rid
and h2.ver = h1.ver + 1
Demo: http://sqlfiddle.com/#!9/2e5d12/7

Mysql INNODB performance with redundant values in table

Please consider a big table with N cols of decimal and M rows.
N could be >50 and M could be > 1000000.
Many many rows will have all the same data, so there is heavy redundancy of tuples (except for id column).
This is the first simple solution
MAIN TABLE
+-----+------+------+-----+------+
| id | col1 | col2 | ... | colN |
+-----+------+------+-----+------+
| 1 | 0 | 0 | ... | 0 |
| 2 | 0 | 0 | ... | 0 |
| ... | ... | ... | ... | ... |
| M | 0 | 0 | ... | 0 |
+-----+------+------+-----+------+
The other solution with two tables could be:
MAIN TABLE
+-----+-------+
| id | refid |
+-----+-------+
| 1 | 1 |
| 2 | 1 |
| ... | ... |
| M | 2 |
+-----+-------+
REFERENCE TABLE (distinct tuples)
+-----+------+------+-----+------+
|refid| col1 | col2 | ... | colN |
+-----+------+------+-----+------+
| 1 | 0 | 0 | ... | 0 |
| 2 | 1 | 0 | ... | 1 |
| ... | ... | ... | ... | ... |
| P | 0 | 1 | ... | 1 |
+-----+------+------+-----+------+
Where REFERENCE TABLE will be joined to MAIN TABLE because it contains all distinct tuples of cols.
My question is: what is the best solution for high performance selecting and summing cols?
SELECT SUM(m.col1), SUM(m.col2) ... SUM(m.colN)
FROM maintable m
or with the other structure
SELECT SUM(r.col1), SUM(r.col2) ... SUM(r.colN)
FROM maintable m
JOIN referencetable r ON m.refid = r.refid
Please consider that the second structure may need a big index to find duplicates before insert new rows in REFERENCE TABLE

how can I calculate from two tables in mysql

I have 2 tables bellow
0 --> Pending
1 --> Success
2 --> Fail
table : mntnc
+-------+-------+-------+
| id | own | sts |
+-------+-------+-------+
| 1 | BN | 1 |
| 2 | BB | 2 |
| 3 | BN | 1 |
| 4 | BD | 1 |
| 5 | BD | 0 |
table : istlsi
+-------+-------+-------+
| id | own | sts |
+-------+-------+-------+
| 1 | BN | 1 |
| 2 | BB | 1 |
| 3 | BB | 1 |
| 4 | BC | 0 |
| 5 | BD | 2 |
of the two tables above, I want to add both of them to be the table below
+-------+-----------+-----------+-----------+
| own | success | fail | pending |
+-------+-----------+-----------+-----------+
| BN | 3 | 0 | 0 |
| BB | 2 | 1 | 0 |
| BD | 1 | 1 | 1 |
| BC | 0 | 0 | 1 |
The two key points here:
Union tables (I aliased result to B)
Use sum(case...) for each column.
First we union both tables together as an inline view.
We then use a case statement for each desired column and evaluate the status setting the value to 1 or 0 depending on sts value. and then sum those...
SELECT own
, sum(case when sts=1 then 1 else 0 end) as Success
, sum(case when sts=2 then 1 else 0 end) as Fail
, sum(case when sts=0 then 1 else 0 end) as Pending
FROM ( SELECT ID, own, sts
FROM mntnc
UNION ALL
SELECT id, own, sts
FROM istlsi
) B
GROUP BY own

how to query a database of a graph with sql to find paths of a given criteria for samples

If I have a database with two tables:
+---------+----+----+----+----+----+-------+
| samples | r1 | r2 | r3 | r4 | r5 | class |
+---------+----+----+----+----+----+-------+
| s1 | 1 | 0 | 1 | 0 | 1 | a |
| s2 | 0 | 1 | 1 | 1 | 0 | b |
| s3 | 1 | 0 | 1 | 0 | 1 | a |
| s4 | 0 | 1 | 0 | 1 | 0 | a |
+---------+----+----+----+----+----+-------+
+-------+------+----+
| edges | from | to |
+-------+------+----+
| e1 | r1 | r2 |
| e2 | r2 | r3 |
| e3 | r3 | r4 |
| e4 | r4 | r5 |
+-------+------+----+
How do I write an SQL query to find the samples that have a path of r's that have the value 1 of at least length two, and other queries that are similar? (e.g a path of value 1 of exactly length 2 or have a pattern 1,0,1)
The graph is more complicated in reality and has loops, so it needs to account for this.
Query : What samples have a chain of at least three r's that are one?
Result: s2
Query: What samples have a chain of 1,0,1?
s1,s3,s4
In prolog I could write something like :
sample_with_chain_at_least_3(S):-
edge(A,B),edge(B,C),r(S,A,1),r(S,B,1),r(S,C,1).
where we would have facts stored for each r(s1,r1,1) etc
But it has been a while since I have touched sql and I cant think how to do this simple query in sql..