I'm in a situation where I have
if A and B and C then
X
end
Which if I understood it correctly, means it will only execute X if all three conditions (A,B,and C) are met.
That's fine by itself, But, I need/want it to at the same time also check something that's like an "or if" statement, that is.
if A and B and C [or if] A and D [or if] A and E then
X
End
Meaning I want it to execute X when A and B and C are met, or if A and D are met, or if A and E are met. How do I go about doing that?
Simple:
if (A and B and C) or (A and D) or (A and E) then
X
end
Related
I'm trying to find an operation that can take a regular language and "unconcatenate" it with another. For example:
a*L - a* = L | where L is a regular language
I know that difference (subtraction) isn't the operation I want. But I believe I'm getting my point across.
Another way to look at it is if there have a set L that is logically equal to (A ∪ B), but we do not have access to A. So if we can only use L, B, and derivations of such, can we somehow derive A. Basically:
L - B = A | L = (A ∪ B)
I have put plenty of thought into this problem, using many variations of compliment, intersection, and other closure properties of regular languages, but I simply can't figure it out.
The best I've managed to come up with is:
A = ((L - B) ∪ (A ∩ B) | L = (A ∪ B)
However this requires A on the right side.
If L = A U B, define an operator - such that L - B = A.
The problem with this is that the operator - is not well-defined: Given L and B, there are potentially several languages which satisfy L = A U B. In particular, if A is a subset of L and any (possibly improper) superset of L \ B, then A is a solution; that is, if A = (L \ B) U C, where C is a (possibly improper) subset of B, then L - B might as well be equal to that set.
Now, you could define - to mean the set of all such A, and in that case, you could make this workable using set difference, union and power set operators. Then, L - B = Q where Q = {(L \ B) U {}, (L \ B) U {B[0]}, ..., (L \ B) U B = L}.
You can make this well-defined if you specify - always returns the "smallest" element of Q (for finite sets, the one with the fewest elements; for infinite sets, the one which is a subset of all other sets) in which case you recover simply L \ B.
If L = B.A, define an operator - such that L - B = A.
A similar problem exists here: there may be several languages which, when appended to B, give L. For example, consider B = a*, and two choices for A: a* and {e}, the language containing only the empty set. You can show without much effort that a* a* = a* e, so L is the same either way, B is the same, and L - B must now produce two different values: either a* or {e}.
I'm trying to write a simple Ocaml function but im getting this error:
Error: This expression has type unit
but an expression was expected of type int
let rec euclid a b =
if a = b then a
else if a < b then 1
else if a > b then 2
To fix the immediate problem, you need else clauses in your function:
let rec euclid a b =
if a = b then a
else if a < b then 1
else 2 (* You know a > b is the only possible alternative *)
You may realize this, but this function is not recursive, nor, I think, is it doing what you want it to do.
However, there is an error in the way you're conceptualizing how a function works in Ocaml. The way you've written the function is imperative in nature; it is a series of if/then statements which are acted upon sequentially. Rather, the return value of euclid should be simply the result of one broad if/then statement (an integer value). Nesting, as I have done above, can be acceptable, but the essential thing to take away is that a function is just a single expression which is evaluated, not a series of imperative actions.
EDIT for updated question:
All OCaml if/then statements should have else clauses. Your very last nested if/then statement has no else clause. If OCaml detects an if/then statement with no else clause, an else clause is assumed returning () (unit). Essentially, if a > b is false, what should OCaml return? It assumes nothing, but returning () conflicts with the supposed type of your function (an integer).
Of course, that a > b is false is impossible in your function, since if not a = b and not a < b, the only other choice is a > b. Thus, you don't need another if statement at the end of your function; at that point, you know without a doubt that a > b, so you can simply say else 2.
We all know that the DO loop is more powerful than the FORALL statement in Fortran. That is, you can always substitute a FORALL by a DO, but not vice versa.
What about the WHERE statement and block?
Can I always substitute the IF by a WHERE? Is it always possible to code the conditionals and bifurcations with a WHERE, thus avoiding the IF?
WHERE statements are reserved for arrays assignments and nothing else, e.g.:
INTEGER, DIMENSION(100,100) :: a, b
... define a ...
WHERE(a < 0)
b = 1
ELSEWHERE
b = 0
ENDWHERE
If you tried adding in something, say a WRITE statement, inside the WHERE block, you would see something like the following compiling error (compiler dependent):
Error: Unexpected WRITE statement in WHERE block at (1)
EDIT
Note that nested WHERE blocks are legal:
WHERE(a < 0)
WHERE( ABS(a) > 2)
b = 2
ELSEWHERE
b = 1
ENDWHERE
ELSEWHERE
b = 0
ENDWHERE
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I couldn't think of any good examples other than the "how to count words in a long text with MapReduce" task. I found this wasn't the best example to give others an impression of how powerful this tool can be.
I'm not looking for code-snippets, really just "textual" examples.
Map reduce is a framework that was developed to process massive amounts of data efficiently.
For example, if we have 1 million records in a dataset, and it is stored in a relational representation - it is very expensive to derive values and perform any sort of transformations on these.
For Example In SQL, Given the Date of Birth, to find out How many people are of age > 30 for a million records would take a while, and this would only increase in order of magnitute when the complexity of the query increases.
Map Reduce provides a cluster based implementation where data is processed in a distributed manner
Here is a wikipedia article explaining what map-reduce is all about
Another good example is Finding Friends via map reduce can be a powerful example to understand the concept, and
a well used use-case.
Personally, found this link quite useful to understand the concept
Copying the explanation provided in the blog (In case the link goes stale)
Finding Friends
MapReduce is a framework originally developed at Google that allows
for easy large scale distributed computing across a number of domains.
Apache Hadoop is an open source implementation.
I'll gloss over the details, but it comes down to defining two
functions: a map function and a reduce function. The map function
takes a value and outputs key:value pairs. For instance, if we define
a map function that takes a string and outputs the length of the word
as the key and the word itself as the value then map(steve) would
return 5:steve and map(savannah) would return 8:savannah. You may have
noticed that the map function is stateless and only requires the input
value to compute it's output value. This allows us to run the map
function against values in parallel and provides a huge advantage.
Before we get to the reduce function, the mapreduce framework groups
all of the values together by key, so if the map functions output the
following key:value pairs:
3 : the
3 : and
3 : you
4 : then
4 : what
4 : when
5 : steve
5 : where
8 : savannah
8 : research
They get grouped as:
3 : [the, and, you]
4 : [then, what, when]
5 : [steve, where]
8 : [savannah, research]
Each of these lines would then be passed as an argument to the reduce
function, which accepts a key and a list of values. In this instance,
we might be trying to figure out how many words of certain lengths
exist, so our reduce function will just count the number of items in
the list and output the key with the size of the list, like:
3 : 3
4 : 3
5 : 2
8 : 2
The reductions can also be done in parallel, again providing a huge
advantage. We can then look at these final results and see that there
were only two words of length 5 in our corpus, etc...
The most common example of mapreduce is for counting the number of
times words occur in a corpus. Suppose you had a copy of the internet
(I've been fortunate enough to have worked in such a situation), and
you wanted a list of every word on the internet as well as how many
times it occurred.
The way you would approach this would be to tokenize the documents you
have (break it into words), and pass each word to a mapper. The mapper
would then spit the word back out along with a value of 1. The
grouping phase will take all the keys (in this case words), and make a
list of 1's. The reduce phase then takes a key (the word) and a list
(a list of 1's for every time the key appeared on the internet), and
sums the list. The reducer then outputs the word, along with it's
count. When all is said and done you'll have a list of every word on
the internet, along with how many times it appeared.
Easy, right? If you've ever read about mapreduce, the above scenario
isn't anything new... it's the "Hello, World" of mapreduce. So here is
a real world use case (Facebook may or may not actually do the
following, it's just an example):
Facebook has a list of friends (note that friends are a bi-directional
thing on Facebook. If I'm your friend, you're mine). They also have
lots of disk space and they serve hundreds of millions of requests
everyday. They've decided to pre-compute calculations when they can to
reduce the processing time of requests. One common processing request
is the "You and Joe have 230 friends in common" feature. When you
visit someone's profile, you see a list of friends that you have in
common. This list doesn't change frequently so it'd be wasteful to
recalculate it every time you visited the profile (sure you could use
a decent caching strategy, but then I wouldn't be able to continue
writing about mapreduce for this problem). We're going to use
mapreduce so that we can calculate everyone's common friends once a
day and store those results. Later on it's just a quick lookup. We've
got lots of disk, it's cheap.
Assume the friends are stored as Person->[List of Friends], our
friends list is then:
A -> B C D
B -> A C D E
C -> A B D E
D -> A B C E
E -> B C D
Each line will be an argument to a mapper. For every friend in the
list of friends, the mapper will output a key-value pair. The key will
be a friend along with the person. The value will be the list of
friends. The key will be sorted so that the friends are in order,
causing all pairs of friends to go to the same reducer. This is hard
to explain with text, so let's just do it and see if you can see the
pattern. After all the mappers are done running, you'll have a list
like this:
For map(A -> B C D) :
(A B) -> B C D
(A C) -> B C D
(A D) -> B C D
For map(B -> A C D E) : (Note that A comes before B in the key)
(A B) -> A C D E
(B C) -> A C D E
(B D) -> A C D E
(B E) -> A C D E
For map(C -> A B D E) :
(A C) -> A B D E
(B C) -> A B D E
(C D) -> A B D E
(C E) -> A B D E
For map(D -> A B C E) :
(A D) -> A B C E
(B D) -> A B C E
(C D) -> A B C E
(D E) -> A B C E
And finally for map(E -> B C D):
(B E) -> B C D
(C E) -> B C D
(D E) -> B C D
Before we send these key-value pairs to the reducers, we group them by their keys and get:
(A B) -> (A C D E) (B C D)
(A C) -> (A B D E) (B C D)
(A D) -> (A B C E) (B C D)
(B C) -> (A B D E) (A C D E)
(B D) -> (A B C E) (A C D E)
(B E) -> (A C D E) (B C D)
(C D) -> (A B C E) (A B D E)
(C E) -> (A B D E) (B C D)
(D E) -> (A B C E) (B C D)
Each line will be passed as an argument to a reducer. The reduce
function will simply intersect the lists of values and output the same
key with the result of the intersection. For example, reduce((A B) ->
(A C D E) (B C D)) will output (A B) : (C D) and means that friends A
and B have C and D as common friends.
The result after reduction is:
(A B) -> (C D)
(A C) -> (B D)
(A D) -> (B C)
(B C) -> (A D E)
(B D) -> (A C E)
(B E) -> (C D)
(C D) -> (A B E)
(C E) -> (B D)
(D E) -> (B C)
Now when D visits B's profile, we can quickly look up (B D) and see
that they have three friends in common, (A C E).
One of the best examples of Hadoop-like MapReduce implementation.
Keep in mind though that they are limited to key-value based implementations of the MapReduce idea (so they are limiting in applicability).
One set of familiar operations that you can do in MapReduce is the set of normal SQL operations: SELECT, SELECT WHERE, GROUP BY, ect.
Another good example is matrix multiply, where you pass one row of M and the entire vector x and compute one element of M * x.
From time to time I present MR concepts to people. I find processing tasks familiar to people and then map them to the MR paradigm.
Usually I take two things:
Group By / Aggregations. Here the advantage of the shuffling stage is clear. An explanation that shuffling is also distributed sort + an explanation of distributed sort algorithm also helps.
Join of two tables. People working with DB are familiar with the concept and its scalability problem. Show how it can be done in MR.
I have a universe of elements organized into n non-disjoint sets. I have m expressions built using these sets, using union/intersection/difference operators. So given an element, I need to evaluate these m expressions, to find out which of the "derived" sets contain the element. I do not want to compute the "derived" set because it will be very time and space inefficient. Is there a way to say whether an element will lie in one of the derived sets just by looking at its expression? For e.g. if the expression is C = A U B and the element lies in set A, then i can say that it will lie in set C. Are there any C libraries to perform computations of this nature?
if im not mistake,
let e = the element
replace each set A, B with true if e is in the set, false if its not. Then, convert the set operators to their logical equivalents, and evaluate the expression as boolean. It should all map well to boolean operators, even xor and stuff.
for example, if e is in both A B, but not D
C = (A U B) xor D
it would be in C because
C = (true or true) xor false
-> (true) xor false
-> true
That could be pretty fast if you can quickly find if an element is in a set