Recognizing if further expression execution can be skipped - compilation

I have such expression:
(a and b or c) and d
How would I recognize it's further execution doesn't make sense. For example when
a = 0, b = 1, c = 0, d = 1
it doesn't make sense to perform the outer most (...) and d becouse the whole expression will be false after the (a and b or c) return false.
So I'm trying to find a general rule that allows me to analyze expression and based on that, find those parts of expressions which execution is crucial for the whole expression and skip further execution if necessary. Below is hypothetical code of stack based virtual machine with the expression i'm starting from
ld a
ld b
and
ld c
or
ld d
and
with this what I would like to achieve:
ld a
ld b
and
ld c
or
jmpf outOfQuery ;;jump if false
ld d
and
outOfQuer:

The concept of not evaluating the right operand of Boolean operators when the result is already determined by the left operand, is known as short circuiting. It is usually implemented by compiling the and and or operators to the same code as conditional expressions:
a and b would be equivalent to a ? b : false (or a ? b : a)
a or b would be equivalent to a ? true : b (or a ? a : b)
So the generated byte- and/or machine code would not contain any and or or instructions, but just a conditional branch.

Related

Algorithm for enumerating all permutations of algebraic expressions

If I have a list of variables, such as {A, B, C} and a list of operators, such as {AND, OR}, how can I efficiently enumerate all permutations of valid expressions?
Given the above, I would want to see as output (assuming evaluation from left-to-right with no operator precedence):
A AND B AND C
A OR B OR C
A AND B OR C
A AND C OR B
B AND C OR A
A OR B AND C
A OR C AND B
B OR C AND A
I believe that is an exhaustive enumeration of all combinations of inputs. I don't want to be redundant, so for example, I wouldn't add "C OR B AND A" because that is the same as "B OR C AND A".
Any ideas of how I can come up with an algorithm to do this? I really have no idea where to even start.
Recursion is a simple option to go:
void AllPossibilities(variables, operators, index, currentExpression){
if(index == variables.size) {
print(currentExpression);
return;
}
foreach(v in variables){
foreach(op in operators){
AllPossibilities(variables, operators, index + 1, v + op);
}
}
}
This is not an easy problem. First, you need a notion of grouping, because
(A AND B) OR C != A AND (B OR C)
Second, you need to generate all expressions. This will mean iterating through every permutation of terms, and grouping of terms in the permutation.
Third, you have to actually parse every expression, bringing the parsed expressions into a canonical form (say, CNF. https://en.wikipedia.org/wiki/Binary_expression_tree#Construction_of_an_expression_tree)
Finally, you have to actually check equivalence of the expressions seen so far. This is checking equivalence of the AST formed by parsing.
It will look loosely like this.
INPUT: terms
0. unique_expressions = empty_set
1. for p_t in permutations of terms:
2. for p_o in permutations of operations:
3. e = merge_into_expression(p_t, p_o)
4. parsed_e = parse(e)
5. already_seen = False
6. for unique_e in unique_expressions:
7. if equivalent(parsed_e, unique_e)
8. already_seen = True
9. break
10. if not already_seen:
11. unique_expressions.add(parsed_e)
For more info, check out this post. How to check if two boolean expressions are equivalent

How do I store the result of a comparison in Prolog and use it later?

Say I want to write an (admittedly unnecessary, but it's an example) predicate that compares two values, and returns the result as a variable that can be referenced, something like this:
compare(Value1, Value2, Result) :-
Result is Value1 > Value2.
But in Swish I get an error:
src:2: Syntax error: Operator priority clash
compare/3: Domain error: `order' expected, found `'5''
After I have Result, how would I then use its value in another predicate? Would it be possible to say:
compare(5, 2, Result),
Result.
Or am I completely misunderstanding the philosophy of Prolog?
Superficially, it's a problem of operators' precedence: this compiles
compare(Value1, Value2, R) :- R is (Value1 > Value2).
but it doesn't run:
?- compare(1,3,X).
ERROR: compare/3: Type error: `atom' expected, found `1' (an integer)
You're going to clash with a builtin, see compare/3.
Better to avoid, although in SWI-Prolog redefine_system_predicate/1 directive could help.
is/2 is a predicate implementing a small (?) functional sublanguage, evaluating right side arithmetic expression, while >/2 implements the comparison after evaluating both sides. What I mean:
..., A > B, ...
it's either true or false, doesn't yields a number...
Maybe you want
my_compare(A,B,C) :- A > B -> C = 1 ; A < B -> C = -1 ; C = 0.
edit:
I think I should illustrate how to store the comparison value: just instance the result and call it later.
my_compare(A,B,C) :- A > B -> C = true ; C = false.
then
?- my_compare(1,3,R), (R -> writeln('comparison succeeded') ; writeln('comparison failed')).

swapping three numbers using xor in a single line

I read that three variables a,b, and c can be swapped using the single statement below:
c = a ^ b ^ c ^ (a=b) ^ (b=c)
Similarly, two variables a and b can be swapped as:
a = a ^ b ^ (b=a)
Can somebody please explain how does this work?
P.S. Here is the link saying so.
http://p--np.blogspot.ro/2011/04/reverse-linked-list-using-only-2.html
You only need to make in the original statement all assignments (except the one you want to change to) are countered:
a = a ^ b ^ c ^ (b=c) ^ (c=a);
You assign c=a, b=c. The return value of those is a and c respectevely, so, you want to "counter" a and c, and you use the fact that a^a == 0 and c^c == 0, and just add a,c at the beginning.
In addition, you add a b, to assign a to the value of b.
Here is a demo on ideone
Note that as discussed in comments, it is language dependent if the above is guaranteed to succeed or not. In Java, for example - it is: The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right., while in others, such as C, it is not.

how to construct truth table for not gate in 3-satisfiability circuit?

Having a lot of trouble understanding this relatively simple concept. So I'm proving that the 3-satisfiability problem is NP-Complete, and part of that involves transforming boolean gates (for example, the NOT gate) into conjunctive normal functions.
So if one gate is a "NOT" gate and takes input a, and returns b = NOT(a), apparently the right answer is that we can enforce the two clauses: a or b, and NOT(a) and NOT(b).
This can be done by a truth table, but I can't seem to figure out how this truth table works. If anyone can explain that would be VERY helpful.
Define a "consistency function" C taking 2 arguments a and b, which is True(1) if and only if the values of a and b are consistent with the definition of a NOT gate.
In your case,
C(0,0) = 0 (since a=0 b=0 is inconsistent with a=NOT(b) )
C(0,1) = 1
C(1,0) = 1
C(1,1) = 0
which is the desired truth table.
Now you can obtain expression for C = a.b + (a').(b') = (a + b).(a' + b')

complex logical operation

Given this logical operation :
(A AND B) OR (C AND D)
Is there a way to write a similar expression without using any parentheses and giving the same result ? Usage of logical operators AND, OR, NOT are allowed.
Yes:
A and B or C and D
In most programming languages, and is taken to have higher precedence than or (this stems from the equivalence of and and or to * and +, respectively).
Of course, if your original expression had been:
(A or B) and (C or D)
you couldn't simply remove the parentheses. In this instance, you'd have to "multiply out" the factors:
A and C or B and C or A and D or B and D
How about A AND B OR C AND D? It's the same because AND takes precedence over OR.
Just don't put any parentheses, it is the same...
It can be written in two ways
A & B | C & D
Type as it is mentioned in question just remove the parenthesis it will show the same result.
We can use & for AND to multiply and | for OR to divide. Also simply you can write them without any parenthesis

Resources