questions about llvm plugin:expression expand, - llvm

expression expand
does llvm have some interface to solve the expression expand problem?
for example:
b = a + 1
c = b + 1
d = b * c
after expression expand, we can know that:
c = a + 1 + 1
d = (a + 1 + 1) * (a + 1)
i think Reverse Polish notation is useful for this, but i didn't find related description in llvm.
Any help would be appreciated~

Related

Sympy: simplification of elementary expression fails

I don't understand why the expression a * (... + 1) - a is not being removed while simplification. The example below shows the bug:
import sympy as sy
a,b,c = sy.symbols('a b c')
expr = a * (b - c + 1) - a + (b - c) * (a - b)
print expr # printed: a*(b - c + 1) - a + (a - b)*(b - c)
print expr.simplify() # printed: a*(b - c + 1) - a + (a - b)*(b - c)
On the other side, if I change the expression by
expr = a * (b - c + 1) - a
and call simplify(), I will obtain the expected result a * (b - c).
Sympy version is 1.1rc1.
simplify usually can only do a limited amount of magic. It could be arguably more in this case, but if you want that, you need to make a feature request. In any case it’s better to tell SymPy what specific kind of modifications you want to make.
Here, the following will probably satisfy you:
print(expr.factor()) # (2*a - b)*(b - c)

general expression substitution in sympy

I have two univariate functions, f(x) and g(x), and I'd like to substitute g(x) = y to rewrite f(x) as some f2(y).
Here is a simple example that works:
In [240]: x = Symbol('x')
In [241]: y = Symbol('y')
In [242]: f = abs(x)**2 + 6*abs(x) + 5
In [243]: g = abs(x)
In [244]: f.subs({g: y})
Out[244]: y**2 + 6*y + 5
But now, if I try a slightly more complex example, it fails:
In [245]: h = abs(x) + 1
In [246]: f.subs({h: y})
Out[246]: Abs(x)**2 + 6*Abs(x) + 5
Is there a general approach that works for this problem?
The expression abs(x)**2 + 6*abs(x) + 5 does not actually contain abs(x) + 1 anywhere, so there is nothing to substitute for.
One can imagine changing it to abs(x)**2 + 5*(abs(x) + 1) + abs(x), with the substitution result being abs(x)**2 + 5*y + abs(x). Or maybe changing it to abs(x)**2 + 6*(abs(x) + 1) - 1, with the result being abs(x)**2 + 6*y - 1. There are other choices too. What should the result be?
There is no general approach to this task because it's not a well-defined task to begin with.
In contrast, the substitution f.subs(abs(x), y-1) is a clear instruction to replace all occurrences of abs(x) in the expression tree with y-1. It returns 6*y + (y - 1)**2 - 1.
The substitution above of abs(x) + 1 in abs(x)**2 + 6*abs(x) + 5 is a clear instruction too: to find exact occurrences of the expression abs(x) + 1 in the syntax tree of the expression abs(x)**2 + 6*abs(x) + 5, and replace those subtrees with the syntax tree of the expression abs(x) + 1. There is a caveat about heuristics though.
Aside: in addition to subs SymPy has a method .replace which supports wildcards, but I don't expect it to help here. In my experience, it is overeager to replace:
>>> a = Wild('a')
>>> b = Wild('b')
>>> f.replace(a*(abs(x) + 1) + b, a*y + b)
5*y/(Abs(x) + 1) + 6*y*Abs(x*y)/(Abs(x) + 1)**2 + (Abs(x*y)/(Abs(x) + 1))**(2*y/(Abs(x) + 1))
Eliminate a variable
There is no "eliminate" in SymPy. One can attempt to emulate it with solve by introducing another variable, e.g.,
fn = Symbol('fn')
solve([Eq(fn, f), Eq(abs(x) + 1, y)], [fn, x])
which attempts to solve for "fn" and "x", and therefore the solution for "fn" is an expression without x. If this works
In fact, it does not work with abs(); solving for something that sits inside an absolute value is not implemented in SymPy. Here is a workaround.
fn, ax = symbols('fn ax')
solve([Eq(fn, f.subs(abs(x), ax)), Eq(ax + 1, y)], [fn, ax])
This outputs [(y*(y + 4), y - 1)] where the first term is what you want; a solution for fn.

I need some help shortening this regular expression

I currently try to get into regular expressions for school and have to work on the task to shorten this regular expression:
r = 0(e + 0 + 1)* + (e + 1)(1 + 0)* + e
with e being the empty word epsilon.
So far I got to this:
r = 0(0 + 1)* + 1(1 + 0)* + e
considering the rule
r* = (e + r)*
However, I don't really know how to continue. If it wasn't for the kleene star operators, I could use the distributive law, but that won't apply here. I can't really figure out a suitable law to continue on with this regex.
Any helpful tips?
Edit:
I think I got one step further by forming r to
r = 0(1 + 0)* + 1(1 + 0)* + e
and then being able to combine it to
r = (0 + 1)(0 + 1)* + e
Is that correct?
Also, we could then say
r = (0+1)*
which should be the final form
I'd say that your own deduction is correct except for one thing. Taking your original
r = 0(e + 0 + 1)* + (e + 1)(1 + 0)* + e
removing e which according to you is empty, leaves
r = 0(0 + 1)* + 1(1 + 0)*
or in plain words 0 followed by any number of 0 or 1 or 1 followed by any number of 1 or 0.
So the left side states that there has to be at least a 0 and the right side that there has to be a 1. That means that there must be at least a 0 or a 1. Now, your flavor of regex is one I've never seen so I don't know how to express one or more in your flavor (it's normally a +) so I'll express it in regular regex, which would be
r = [01]+
which simply means at least one0 or 1 repeated any number of times.
Regards.

Expression involving modular exponentiations in C++

I am wanting to evaluate the expression, (an + bn + cn) % 1000000003 , in C++. I a getting overflow errors when n is very large. Can someone help me with this ? More specifically a = q + 1, b = - 2 * q and c = q - 1. I have been following the function outlined in this
Can I break (an + bn + cn) % 1000000003 into (an) % 1000000003 + (bn) % 100000003 + (cn) % 1000000003 or something similar ?
Also I cannot use anything more than unsigned long long int
You can distribute your modulo. Mathematically, this will be sound:
( ((a^n)%1000000003) + ((b^n)%100000003) + ((c^n)%1000000003) ) % 1000000003;
This will prevent you from having to compute numbers that are out of bounds, allowing you to choose larger values for n.
Proof.
Just be sure to use pow in the math.h module:
( ((pow(a, n))%1000000003)
+ ((pow(b, n))%100000003)
+ ((pow(c, n))%1000000003) ) % 1000000003;

Moving out before brackets with XOR

If I had the sum of products like z*a + z*b + z*c + ... + z*y, it would be possible to move the z factor, which is the same, out before brackets: z(a + b + c + ... y).
I'd like to know how it is possible (if it is) to do the same trick if bitwise XOR is used instead of multiplication.
z^a + z^b + ... z^y -> z^(a + b + ... + y)
Perhaps a, b, c ... should be preprocessed, such as logically negated or something else, before adding? z could change, so preprocessing, if it's needed, shouldn't depend on particular z value.
From Wikipedia:
Distributivity: with no binary function, not even with itself
So, no, unfortunately, you can't do anything like that with XOR.
To prove that a general formula does not hold you only need to prove a contradiction in a limited case.
We can reduce it to show that this does not hold:
(a^b) * c = (a^c) * (b^c)
It is trivial to show that one base case fails as such:
a = 3
b = 1
c = 1
(a^b) * c = (3^1) * 1 = 2
(a^c) * (b^c) = 2 * 0 = 0
Using the same case you can show that (a*b) ^ c = (a^c) * (b^c) and (a + b) ^ c = (a^c) + (b^c) do not hold either.
Hence, equality does not hold in a general case.
Equality can hold in special cases though, which is an entirely different subject.