Conditions with common logic: question of style, readability, efficiency, - coding-style

I have conditional logic that requires pre-processing that is common to each of the conditions (instantiating objects, database lookups etc). I can think of 3 possible ways to do this, but each has a flaw:
Option 1
if A
prepare processing
do A logic
else if B
prepare processing
do B logic
else if C
prepare processing
do C logic
// else do nothing
end
The flaw with option 1 is that the expensive code is redundant.
Option 2
prepare processing // not necessary unless A, B, or C
if A
do A logic
else if B
do B logic
else if C
do C logic
// else do nothing
end
The flaw with option 2 is that the expensive code runs even when neither A, B or C is true
Option 3
if (A, B, or C)
prepare processing
end
if A
do A logic
else if B
do B logic
else if C
do C logic
end
The flaw with option 3 is that the conditions for A, B, C are being evaluated twice. The evaluation is also costly.
Now that I think about it, there is a variant of option 3 that I call option 4:
Option 4
if (A, B, or C)
prepare processing
if A
set D
else if B
set E
else if C
set F
end
end
if D
do A logic
else if E
do B logic
else if F
do C logic
end
While this does address the costly evaluations of A, B, and C, it makes the whole thing more ugly and I don't like it.
How would you rank the options, and are there any others that I am not seeing?

Can't you do
if (A, B, or C)
prepare processing
if A
do A logic
else if B
do B logic
else if C
do C logic
end
? Maybe I misunderstood.
Edit: zzz, your edits messed me up. If you don't want it to evaluate A,B,C twice then do
x = func returnCase() //returns a,b, or c
if x != None
prepare processing
do Case

Doesn't this solve the redundancy:
if A
prepareprocessingfunction()
do A logic
else if B
prepareprocessingfunction()
do B logic
else if C
prepareprocessingfunction()
do C logic
// else do nothing
end
prepareprocessingfunction() {
prepare processing
}

Related

Basic Logic operators both AND and OR

Hi I have tree conditions
A, B and C
Now, I want to apply these conditions I such a way, that if any of these conditions is true, or a combination, the whole outcome is true.
If I do
A || B || C
then as soon as A is true, B and C are not evaluated
if I do
A && B && C
it's only true if ALL of them are true.
Is there a special notation for fulfilling my wishes?
Using the Or (||) operator will give you the correct answer because it does not need to evaluate the other conditions but if you want B and C to be evaluated even if A is True then you should nest the If statements such as:
if A == True
do something;
if B == True
do something;
if C == True
do something;
Or just do three separate If statements.
You have answered your own question.
You want a situation whereby if EITHER A OR B OR C is true, or if a combination such as A AND B are true then the whole expression will evaluate to true.
That is A || B || C. If you only care about requiring ANY of the conditions to be true, then there is no need to evaluate all the conditions because as long as ONE condition is true, then your whole expression or outcome is true.
If you care about the specific combinations being true TOGETHER then you can group them using parenthesis as such:
If I want A AND B to be true at the same time OR C: (A && B) || C
If I want A AND C to be true at the same time OR B: (A && C) || B

Cleaner way to represent languages accepted by DFAs?

I am given 2 DFAs. * denotes final states and -> denotes the initial state, defined over the alphabet {a, b}.
1) ->A with a goes to A. -> A with b goes to *B. *B with a goes to *B. *B with b goes to ->A.
The regular expression for this is clearly:
E = a* b(a* + (a* ba* ba*)*)
And the language that it accepts is L1= {w over {a,b} | w is b preceeded by any number of a's followed by any number of a's or w is b preceeded by any number of a's followed by any number of bb with any number of a's in middle of(middle of bb), end or beginning.}
2) ->* A with b goes to ->* A. ->*A with a goes to *B. B with b goes to -> A. *B with a goes to C. C with a goes to C. C with b goes to C.
Note: A is both final and initial state. B is final state.
Now the regular expression that I get for this is:
E = b* ((ab) * + a(b b* a)*)
Finally the language that this DFA accepts is:
L2 = {w over {a, b} | w is n 1's followed by either k 01's or a followed by m 11^r0' s where n,km,r >= 0}
Now the question is, is there a cleaner way to represent the languages L1 and L2 because it does seem ugly. Thanks in advance.
E = a* b(a* + (a* ba* ba*)*)
= a*ba* + a*b(a* ba* ba*)*
= a*ba* + a*b(a*ba*ba*)*a*
= a*b(a*ba*ba*)*a*
= a*b(a*ba*b)*a*
This is the language of all strings of a and b containing an odd number of bs. This might be most compactly denoted symbolically as {w in {a,b}* | #b(w) = 1 (mod 2)}.
For the second one: the only way to get to state B is to see an a in A, and the only way to get to C from outside C is to see an a in B. C is a dead state and the only way to get to it is to see aa starting in A. That is: if you ever see two as in a row, the string is not in the language; the language is the set of all strings over a and b not containing the substring aa. This might be most compactly denoted symbolically as {(a+b)*aa(a+b)*}^c where ^c means "complement".

Technical Term for this Rule Combination Pattern

I've been working on a program that takes a list of rules and tests combinations of them to operate a simple controller. The rules can only be true.
One rule would generate one controller:
A: If Cond1 Then True
If A then Activate
Two rules can generate 2 controllers:
A: If Cond1 Then True
B: If Cond2 Then True
If A and B then Activate
If A or B then Activate
Three rules generate 8 controllers:
A: If Cond1 Then True
B: If Cond2 Then True
C: If Cond3 Then True
A and B and C
A or B or C
(A and B) or C
A or (B and C)
(A and C) or B
(A and B) or (A and C)
(B and C) or (A and C)
(A and B) or (B and C)
Is there a formal name for this procedure? What field of study does this type of program fall under? All I've been able to find is that each controller might be described as using "fuzzy logic".
Truth tables exist for each of the controllers in the questions. The desired output could be obtained by filtering the output of a program that generated truth tables.
More about generating truth tables here:
Algorithm for generating all possible boolean functions of n variables

Is these algorithms equivalent?

E is a logic variable (T/F), P and Q are programs
(P)
If E then R
Else
S
(Q)
bool c = E
bool d = not E
While c do
Begin
R
c = d
End
While d do
Begin
S
d = c
End
We knew that, the same input mean the same output, so they are weak-equivalency, but what about the execute time numbers (R)? I am not sure R is for (R,S) or E?
As it is now, both variants are equivalent in the sense that R and S are fulfilled or not in both variants according to the same start conditions.
But the second variant also sets two variables c and d, and obviously they will be used somehow later, for otherwards there is no use in their setting inside while cycles. So, the second variant has additional and independent consequences (c and d are defined and set to false).
If the S and R can cancel the whole algorithm, that additional part becomes NOT independent.

How do you break out of parallel loops? ParallelBreak

in the following snippet, if you replace Do by ParallelDo, it will evaluate by a factor of 3 SLOWER, because now the loop will be broken in only ONE of the two kernels.
ParallelEvaluate[NN = 10070];
SetSharedVariable[res]
Module[{a, b, c},
Do[
c = NN - a - b;
If[a a + b b == c c, res = a b c; Break[]]
, {a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming
Calling ParallelAbort would solve the issue, but it's forbidden. What else is there?
You need to have a way for each iteration to tell
all other iterations that the answer has been found.
I modelled this with a "quit" flag, intially set
to false, that is set to true when any iteration
decides to finish. Each iteration likewise has
to check the exit condition.
My Mathematica is 15 years rusty, and I haven't
seen the Parallelxxx forms before, but a good guess
at how the loop should change is the following
variation on your code:
ParallelEvaluate[NN = 10070];
SetSharedVariable[res,quit]
Module[{a, b, c},
quit=false;
Do[ c = NN - a - b;
If[quit, Break[]];
If[ a a + b b == c c, quit=true; res = a b c; Break[]],
{a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming
The extra If slows down the loop somewhat, but thats the price of
synchronization.
I suspect that the amount
of work you are doing in each iteration is already pretty small
compared to the cost of executing each iteration in parallel,
so this loop is probably inefficient and you may not get
any real value from the Do Parallel.
If you dont, then you can make each Do iteration operate on several values
of a and b (e.g., use {a, 1, NN, 10} and similarly for b for each
iteration and handle the 10-wide subrange as a subloop inside
each parallel iteration).to keep the quit-test exit overhead small in comparison
to the work done in each loop body.
Recode exercise left for the reader.
Your code has another problem: there's a race condition in setting
res. Under ceratin circumstances, two iterations could both decide to set res.
If you don't care which answer is produced, and the store to res is "atomic",
this is fine. If res were a more complicated data structure, and updating
it took multiple Mathematica statements, you'd surely have a data race
and your loop would produce bad results once in a great while and it
would be very hard to debug. You ideally need some kind of atomic
test to protect the exit condition. I don't know what that is in MMa,
so you'll have to look it up, but I imagine an "atomic[...]" form
that insists its body is executged by only one of the many parallel threads.
(Perhaps MMa has a semaphore that you can use to implement atomic].
If so, your code should then look like this:
ParallelEvaluate[NN = 10070];
SetSharedVariable[res,quit]
Module[{a, b, c},
quit=false;
Do[ c = NN - a - b;
If[quit, Break[]];
If[ a a + b b == c c,
atomic[If[not[quit]; quit=true; res = a b c;]; Break[]],
{a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming

Resources