Good morning everyone,
Here's what I'm working on today, and the issue I'm running in to:
--A
data Row = A | B | C | D | E | F | G | H | I | J deriving (Enum, Ord, Show, Bounded, Eq, Read)
data Column = One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum, Ord, Show, Bounded, Eq, Read)
--B
data Address = Address Row Column deriving (Show, Read, Eq)
Then a few lines later I get to the problem child:
toAddress r c = Address(toEnum r, toEnum c)
I need to feed Address a Row and Column, but I need to turn r and c into Row and Column (not Ints)
Obviously toAddress is not structured correctly to carry out this task. The requirement is as follows:
Write a function toAddress that takes in a row and column, each in [0
− 9]. Construct an Address and return it. Use toEnum to index into
your Row and Column enums lists.
Does anyone have any suggestions on how to accomplish what I'm going for here?
Thank you!
You got the syntax wrong.
A function application of a function f :: A -> B -> C in haskell looks like this f a b and not f(a,b). f(a,b) still is correct syntax but not what you want: it passes only one parameter to the function (i.e. the tuple consisting of a and b).
So the correct implementation of toAddress looks like this:
toAddress r c = Address (toEnum r) (toEnum c)
Related
Problem
Given a user query Q on a webpage, I am attempting to compute the following somewhat complex function for each entity p in my database:
(D is also dependent upon the user query Q) There are roughly 440,000 p entities in my database, and each has an average of ~50 associated w_{d,p} weights and ~400 associated u_{p, c} weights. Right now, these weights are stored across three tables, and there is an additional table that defines the relationship between d and c:
table columns indices
----- ------- ----
w weights: p | d | w_pd primary key (p, d), index on d
u weights: p | c | u_pc primary key (p, c), index on c
v weights: c | v_c primary key c
d/c relationship: d | c primary key (d, c), index on c
The IDs p, d and c are all varchars ranging in size from 10-16. w_dp, u_pc, and v_c are floats.
My current approach to computing the above equation involves multiple joins, subqueries, group by statements, etc. Depending on the Q, we may be able to trim the set of p entities we are interested in down to a more manageable number, and the computation may only take a few seconds. But some values of Q result in a computation that takes multiple minutes.
Example computation
Suppose we have the following four tables:
d/c relationship w weights u weights v weights
d | c p | d | w_dp p | c | u_pc c | v_c
d1 | c1 p1 | d1 | 1 p1 | c1 | 6 c1 | 12
d1 | c2 p1 | d2 | 3 p1 | c2 | 8 c2 | 16
d2 | c2 p2 | d1 | 2 p2 | c1 | 11 c3 | 15
d3 | c3 p3 | d2 | 4 p3 | c2 | 7
p3 | d3 | 5 p3 | c3 | 9
p4 | d3 | 10 p4 | c1 | 13
The query Q is actually a set of c IDs, that restricts the set D that the sum is over. So let's say Q = {c1, c2}. Using the d/c relationship table, our sum is then over d1 and d2. Computing the sum for p1, we have:
d1: 1 * max(6, 8) * [v_c : c = argmax_c (u_11=6, u_12=8)] = 1 * 8 * 16 = 128
d2: 3 * max(8) * [v_c : c = argmax_c (u_12=8)] = 3 * 8 * 16 = 384
So the score for p1 is 128 + 384 = 512. We would do a similar computation for p2 and p3. p4 is only associated with d3, and d3 has no relation with Q = {c1, c2}, so we have nothing to sum for p4.
Question
Is there any sensible way to compute the above function quickly? In particular,
Using the existing db schema? My understanding is that using aggregate functions over joined tables like I am currently doing is quite slow, so I'm guessing the answer to this question is "no".
Using an alternative table structure? My only current idea is to join the w/u/v weights into one massive, ~700m row table, and use that table for the query. I'm not sure how helpful this will be, but maybe if properly indexed could be faster.
Should I do something else entirely? Is there an alternative data storage/processing tool I should be considering?
Because I am very much a novice when it comes to SQL, I was hoping to get a clearer sense of direction before I waste too much time on a dead end.
Update
I know this didn't get much traction, but for future viewers: the way I solved this was by doing all computations ahead of time. There are about 5000 possible queries q, and a maximum of ~500,000 entities p. This would result in a table of size 2.5 billion rows, where (p, q) is the primary key. In reality, for each query q, only roughly 75k entities are assigned scores, on average, resulting in a slightly more manageable table size of 75000*5000 = 375,000,000. Now at query time, all I need to do to get the relevant list of scores is filter on q, which is much simpler than doing this crazy summation.
That said, if anyone sees this and has input, I'd still like to hear the opinion of any SQL/MySQL experts out there.
Suppose I have a database that contains two different types of information about certain unique objects, say their 'State' and 'Condition' to give a name to their classifiers. The State can take the values A, B, C or D, the condition the values X or Y. Depending on where I am sourcing data from, sometimes this database lacks entries for a particular pair.
From this data, I'd like to make a crosstab query that shows the count of data with a given State and Condition combination, but to have it still yield a row even when a given row is a 0. For example, I'd like the following table:
Unit | State | Condition
1 | A | X
2 | B | Y
3 | C | X
4 | B | Y
5 | B | X
6 | B | Y
7 | C | X
To produce the following crosstab:
Count | X | Y
A | 1 | 0
B | 1 | 3
C | 2 | 0
D | 0 | 0
Any help that would leave blanks instead of zeroes is fit for purpose as well, these are being pasted into a template Excel document that requires each crosstab to have an exact dimension.
What I've Tried:
The standard crosstab SQL
TRANSFORM Count(Unit)
SELECT Condition
FROM Sheet
GROUP BY Count(Unit)
PIVOT State;
obviously doesn't work as it doesn't raise the possibility of a D occurring. PIVOTing by a nested IIf that explicitly names D as a possible value does nothing either, nor does combining it with an Nz() around the TRANSFORM clause variable.
TRANSFORM Count(sheet.unit) AS CountOfunit
SELECT AllStates.state
FROM AllStates LEFT JOIN sheet ON AllStates.state = sheet.state
GROUP BY AllStates.state
PIVOT sheet.condition;
This uses a table "AllStates" that has a row for each state you want to force into the result. It will produce an extra column for entries that are neither Condition X nor Condition Y - that's where the forced entry for state D ends up, even though the count is 0.
If you have a relatively small number of conditions, you can use this instead:
SELECT AllStates.state, Sum(IIf([condition]="x",1,0)) AS X, Sum(IIf([condition]="Y",1,0)) AS Y
FROM AllStates LEFT JOIN sheet ON AllStates.state = sheet.state
GROUP BY AllStates.state;
Unlike a crosstab, though, this won't automatically add new columns when new condition codes are added to the data. It can also be cumbersome if you have many condition codes.
I'm trying to figured out how to use insert statement in a stored procedure.
I want to put data into a table
like this (concept, a, b, c, d, e, f, g)
but i want to get the result like this:
concept a b
concept c d
concept d e
concept f g
I think i need a string for this?
how can i create the string?
The Question is Kinda Vague but this should work you just need to insert multiple values in your table, to indicate a new row.
Sample:
INSERT INTO example
(Concept, element1, Element2)
VALUES
(Concept,a,b),
(Concept,c,d),
(Concept,e,f),
(Concept,g,h);
output:
Concept | Element1 | Element2 // table headers
concept | a | b
concept | C | D
concept | e | f //table elements
concept | g | h
or look Here for more :)
I need to detect a commutative pattern in one of my functions. I thought that writing the following will do the work:
let my_fun a b = match a,b with
(*...*)
| a,b
| b,a when is_valid b -> process b (***)
(*...*)
This doesn't work and Ocaml complains with this sub-pattern is unused
warning for the line marked with (***).
1) Can someone explain to me what this warning try to say and why this doesn't work?
2) How can I actually write this elegantly without using if then else given the fact that I want to now which argument is_valid?
2) Is it possible to get the intended functionality using only pattern matching and without repeating when is_valid b -> process b as it happens bellow?
let my_fun a b = match a,b with
(*...*)
| a,b when is_valid b -> process b
| b,a when is_valid b -> process b
(*...*)
Edit:
In my concrete example a and b are pairs. The function is a bit more complicated but the following will illustrate the case:
let f a b = match a,b with
| (a1,a2),(b1,b2)
| (b1,b2),(a1,a2) when b1 = b2 -> a1 + a2
Calling f (1,1) (1,2) will yield pattern match failed. I know understand why (thanks to the answers bellow) and I understand how I can make it work if I have different constructors for each element (as in Ashish Agarwal's answer). Can you suggest a way to make it work in my case?
The matching works by first matching the pattern, and if that succeedes, then by evaluating the condition with the attached environment from that pattern match. Since a,b will always bind, this is the only case used, and the compiler is correctly reporting that b,a is never used. You'll have to repeat that line,
let my_fun a b = match a,b with
| a,b when is_valid b -> process b
| b,a when is_valid b -> process b
Your method could work if you didn't perform the match with variables but to some variant, for example,
let my_fun a b = match a,b with
| a, `Int b
| `Int b, a when is_valid b -> process b
Edit: Think of the multiple patterns using one guard as a subexpression,
let my_fun a b = match a,b with
| ((a,b) | (b,a)) when is_valid b -> process b
You'll see this exemplified in the definition for patterns. It's really one pattern, composed of patterns, being matched.
For your first question, the thing to realize is you only have one pattern ((a,b) | (b,a)), which happens to be an "or" pattern. Matching proceeds from left to right in an "or" pattern. Since (a,b) will match anything, the second part will never be used.
For your second question, I don't see the problem, but it depends on the types of a and b. Here's an example:
type t = A of int | B of float
let my_fun a b = match a,b with
| A a, B b
| B b, A a when b > 0. -> (float_of_int a) +. b
| … -> (* other cases *)
It would also work for simpler types:
let my_fun a b = match a,b with
| 1,b
| b,1 when b > 0 -> b + 1
| … -> (* other cases *)
If you still can't get this to work in your case, let us know the types of a and b you are working with.
Could you please explain the De Morgan's rules as simply as possible (e.g. to someone with only a secondary school mathematics background)?
Overview of boolean algebra
We have two values: T and F.
We can combine these values in three ways: NOT, AND, and OR.
NOT
NOT is the simplest:
NOT T = F
NOT F = T
We can write this as a truth table:
when given.. | results in...
============================
T | F
F | T
For conciseness
x | NOT x
=========
T | F
F | T
Think of NOT as the complement, that is, it turns one value into the other.
AND
AND works on two values:
x y | x AND y
=============
T T | T
T F | F
F T | F
F F | F
AND is T only when both its arguments (the values of x and y in the truth table) are T — and F otherwise.
OR
OR is T when at least one of its arguments is T:
x y | x OR y
=============
T T | T
T F | T
F T | T
F F | F
Combining
We can define more complex combinations. For example, we can write a truth table for x AND (y OR z), and the first row is below.
x y z | x AND (y OR z)
======================
T T T | ?
Once we know how to evaluate x AND (y OR z), we can fill in the rest of the table.
To evaluate the combination, evaluate the pieces and work up from there. The parentheses show which parts to evaluate first. What you know from ordinary arithmetic will help you work it out. Say you have 10 - (3 + 5). First you evaluate the part in parentheses to get
10 - 8
and evaluate that as usual to get the answer, 2.
Evaluating these expressions works similarly. We know how OR works from above, so we can expand our table a little:
x y z | y OR z | x AND (y OR z)
===============================
T T T | T | ?
Now it's almost like we're back to the x AND y table. We simply substitute the value of y OR z and evaluate. In the first row, we have
T AND (T OR T)
which is the same as
T AND T
which is simply T.
We repeat the same process for all 8 possible values of x, y, and z (2 possible values of x times 2 possible values of y times 2 possible values of z) to get
x y z | y OR z | x AND (y OR z)
===============================
T T T | T | T
T T F | T | T
T F T | T | T
T F F | F | F
F T T | T | F
F T F | T | F
F F T | T | F
F F F | F | F
Some expressions may be more complex than they need to be. For example,
x | NOT (NOT x)
===============
T | T
F | F
In other words, NOT (NOT x) is equivalent to just x.
DeMorgan's rules
DeMorgan's rules are handy tricks that let us convert between equivalent expressions that fit certain patterns:
NOT (x AND y) = (NOT x) OR (NOT y)
NOT (x OR y) = (NOT x) AND (NOT y)
(You might think of this as how NOT distributes through simple AND and OR expressions.)
Your common sense probably already understands these rules! For example, think of the bit of folk wisdom that "you can't be in two places at once." We could make it fit the first part of the first rule:
NOT (here AND there)
Applying the rule, that's another way of saying "you're not here or you're not there."
Exercise: How might you express the second rule in plain English?
For the first rule, let's look at the truth table for the expression on the left side of the equals sign.
x y | x AND y | NOT (x AND y)
=============================
T T | T | F
T F | F | T
F T | F | T
F F | F | T
Now the righthand side:
x y | NOT X | NOT Y | (NOT x) or (NOT y)
========================================
T T | F | F | F
T F | F | T | T
F T | T | F | T
F F | T | T | T
The final values are the same in both tables. This proves that the expressions are equivalent.
Exercise: Prove that the expressions NOT (x OR y) and (NOT x) AND (NOT y) are equivalent.
Looking over some of the answers, I think I can explain it better by using conditions that are actually related to each other.
DeMorgan's Law refers to the fact that there are two identical ways to write any combination of two conditions - specifically, the AND combination (both conditions must be true), and the OR combination (either one can be true). Examples are:
Part 1 of DeMorgan's Law
Statement: Alice has a sibling.
Conditions: Alice has a brother OR Alice has a sister.
Opposite: Alice is an only child (does NOT have a sibling).
Conditions: Alice does NOT have a brother, AND she does NOT have a sister.
In other words: NOT [A OR B] = [NOT A] AND [NOT B]
Part 2 of DeMorgan's Law
Statement: Bob is a car driver.
Conditions: Bob has a car AND Bob has a license.
Opposite: Bob is NOT a car driver.
Conditions: Bob does NOT have a car, OR Bob does NOT have a license.
In other words: NOT [A AND B] = [NOT A] OR [NOT B].
I think this would be a little less confusing to a 12-year-old. It's certainly less confusing than all this nonsense about truth tables (even I'm getting confused looking at all of those).
It is just a way to restate truth statements, which can provide simpler ways of writing conditionals to do the same thing.
In plain English:
When something is not This or That, it is also not this and not that.
When something is not this and that, it is also not this or not that.
Note: Given the imprecision of the English language on the word 'or' I am using it to mean a non-exclusive or in the preceding example.
For example the following pseudo-code is equivalent:
If NOT(A OR B)...
IF (NOT A) AND (NOT B)....
IF NOT(A AND B)...
IF NOT(A) OR NOT(B)...
If you're a police officer looking for underage drinkers, you can do one of the following, and De Morgan's law says they amount to the same thing:
FORMULATION 1 (A AND B)
If they're under the age
limit AND drinking an alcoholic
beverage, arrest them.
FORMULATION 2 (NOT(NOT A OR NOT B))
If they're over
the age limit OR drinking a
non-alcoholic beverage, let them go.
This, by the way, isn't my example. As far as I know, it was part of a scientific experiment where the same rule was expressed in different ways to find out how much of a difference it made in peoples' ability to understand them.
"He doesn't have either a car or a bus." means the same thing as "He doesn't have a car, and he doesn't have a bus."
"He doesn't have a car and a bus." means the same thing as "He either doesn't have a car, or doesn't have a bus, I'm not sure which, maybe he has neither."
Of course, in plain english "He doesn't have a car and a bus." has a strong implication that he has at least one of those two things. But, strictly speaking, from a logic standpoint the statement is also true if he doesn't have either of them.
Formally:
not (car or bus) = (not car) and (not bus)
not (car and bus) = (not car) or (not bus)
In english, 'or' tends to mean a choice, that you don't have both things. In logic, 'or' always means the same as 'and/or' in English.
Here's a truth table that shows how this works:
First case: not (cor or bus) = (not car) and (not bus)
c | b || c or b | not (c or b) || (not c) | (not b) | (not c) and (not b)
---+---++--------+--------------++---------+---------+--------------------
T | T || T | F || F | F | F
---+---++--------+--------------++---------+---------+--------------------
T | F || T | F || F | T | F
---+---++--------+--------------++---------+---------+--------------------
F | T || T | F || T | F | F
---+---++--------+--------------++---------+---------+--------------------
F | F || F | T || T | T | T
---+---++--------+--------------++---------+---------+--------------------
Second case: not (car and bus) = (not car) or (not bus)
c | b || c and b | not (c and b) || (not c) | (not b) | (not c) or (not b)
---+---++---------+---------------++---------+---------+--------------------
T | T || T | F || F | F | F
---+---++---------+---------------++---------+---------+--------------------
T | F || F | T || F | T | T
---+---++---------+---------------++---------+---------+--------------------
F | T || F | T || T | F | T
---+---++---------+---------------++---------+---------+--------------------
F | F || F | T || T | T | T
---+---++---------+---------------++---------+---------+--------------------
Draw a simple Venn diagram, two intersecting circles. Put A in the left and B in the right. Now (A and B) is obviously the intersecting bit. So NOT(A and B) is everything that's not in the intersecting bit, the rest of both circles. Colour that in.
Draw another two circles like before, A and B, intersecting. Now NOT(A) is everything that's in the right circle (B), but not the intersection, because that's obviously A as well as B. Colour this in. Similarly NOT(B) is everything in the left circle but not the intersection, because that's B as well as A. Colour this in.
Two drawings look the same. You've proved that NOT(A and B) = NOT(A) or NOT(B). T'other case is left as an exercise for the student.
DeMorgan's Law allows you to state a string of logical operations in different ways. It applies to logic and set theory, where in set theory you use complement for not, intersection for and, and union for or.
DeMorgan's Law allows you to simplify a logical expression, performing an operation that is rather similar to the distributive property of multiplication.
So, if you have the following in a C-like language
if !(x || y || z) { /* do something */ }
It is logically equivalent to:
if (!x && !y && !z)
It also works like so:
if !(x && !y && z)
turns into
if (!x || y || !z)
And you can, of course, go in reverse.
The equivalence of these statements is easy to see using something called a truth table. In a truth table, you simply lay out your variables (x, y, z) and list all the combinations of inputs for these variables. You then have columns for each predicate, or logical expression, and you determine for the given inputs, the value of the expression. Any university curriculum for computer science, computer engineering, or electrical engineering will likely drive you bonkers with the number and size of truth tables you must construct.
So why learn them? I think the biggest reason in computing is that it can improve readability of larger logical expressions. Some people don't like using logical not ! in front of expressions, as they think it can confuse someone if they miss it. The impact of using DeMorgan's Law on the gate level of chips is useful, however, because certain gate types are faster, cheaper, or you're already using a whole integrated circuit for them so you can reduce the number of chip packages required for the outcome.
Not sure why I've retained this all these years, but it has proven useful on a number of occasions. Thanks to Mr Bailey, my grade 10 math teacher. He called it deMorgan's Theorem.
!(A || B) <==> (!A && !B)
!(A && B) <==> (!A || !B)
When you move the negation in or out of the brackets, the logical operator (AND, OR) changes.