You are right, it should not use

`x+y`

as a generator```
In [3]: Poly((x+y)**2+1)
Out[3]: Poly(x**2 + 2*x*y + y**2 + 1, x, y, domain='ZZ')
```

```
In [1]: Poly((x+sin(y))**2+1)
Out[1]: Poly(x**2 + 2*x*(sin(y)) + (sin(y))**2 + 1, x, sin(y), domain='ZZ')
```

i.e. no

`y`

@isuruf what should I use as a default generator if no generator is provided by the user? can I use the raw NULL pointer?

I mean,

`RCP<const UIntPoly> basic_to_uintpoly(const RCP<const Basic> &x, RCP<const Basic> gen = NULL)`

and then for eg, in the visitor I have,

```
void bvisit(const Integer &x)
{
if (gen != NULL)
res = UIntPoly::from_container(gen, std::move({{0, x.i}}));
else
throw runtime error;
}
```

You can have two methods. One taking a gen argument and another without. Function not taking the generator in can calculate the generators and use them

They will have separate visitors then?

That will be very redundant I feel, but actually

I would anyways have to check everytime if gen is null or not

so i guess ill make two visitors

One visitor to figure out the generators.

Another visitor to convert the polynomial

Another visitor to convert the polynomial

On a side note, why are we moving away from flint c++ api to our own wrappers?

Do you have any other genarators in mind apart from these (for the univariate case),

`Symbol`

eg. `x + 1`

, `Pow`

eg. `2**x + 1`

, `Function`

eg. `sin(x) + 1`

`Add`

and `Mul`

type Basics can't ever be generators, am I right?
I think the useful generators would be symbols and functions (including non-integer powers). SymPy seems to allow also more general expressions, but I suspect that they would not be of much practical use.

```
In [30]: tbt = Rational(3, 2)
In [31]: Poly(x**tbt + x + 1)
Out[31]: Poly(x + sqrt(x)**3 + 1, x, sqrt(x), domain='ZZ')
```

I expected `Out[31]: Poly(sqrt(x)**3 + x + 1, sqrt(x), domain='ZZ')`

Also, printing

`x**(1/2)`

instead of `sqrt(x)`

is alright?
We should change that in the string printer though

I had to change the printing a little bit, to incorporate

`Pow`

`var_`

s
Are these okay?

```
RCP<const Symbol> x = symbol("x");
RCP<const Basic> p = pow(integer(2), x);
RCP<const Basic> t = pow(x, rational(3,2));
RCP<const Basic> s = sqrt(x);
RCP<const Basic> sinx = sin(x);
RCP<const UIntPoly> a = UIntPoly::from_vec(p, {1_z, 2_z, 2_z});
RCP<const UIntPoly> b = UIntPoly::from_vec(s, {1_z, 2_z, 2_z});
RCP<const UIntPoly> c = UIntPoly::from_vec(sinx, {1_z, 2_z, 2_z});
RCP<const UIntPoly> d = UIntPoly::from_vec(t, {1_z, 2_z, 2_z});
REQUIRE(a->__str__() == "2*2**(2*x) + 2*2**x + 1");
REQUIRE(b->__str__() == "2*x + 2*x**(1/2) + 1");
REQUIRE(c->__str__() == "2*sin(x)**2 + 2*sin(x) + 1");
REQUIRE(d->__str__() == "2*x**3 + 2*x**(3/2) + 1");
```

@isuruf What exactly are galois fields, does it make sense for it to have an

`eval`

method. I was thinking of making it inherit from `UIntPolyBase`

instead of `UPolyBase`

. Some things can be made common I think.
I read about fields (very preliminarily), why does it inherit from uni polys?

Why does

Shouldn't say $x^2y^3$ be stored as

In this way

`Mul`

store a map from basic to basic?Shouldn't say $x^2y^3$ be stored as

`mul_set`

= `{Pow(x,2), Pow(y,3)}`

instead of `mul_map = {{x,2}, {y,3}}`

In this way

`Mul`

is interanlly representing `Pow`

s`Mul`

right now is basically an ordered set of `Pow`

. Why was it decided to keep it this way?
For example you want to multiply

`x^2*y^3`

by `x`

. What you can do is find `x`

in the dictionary in `O(log(n))`

time or if it is a vector in `O(n)`

time
Another implementation could be just adding

`x`

to the `set`

. But I see your point. Why not `std::set<Pow>`

?
Same can be achieved

Say I construct

And the constructed poly has

And another

How will

`poly a = UIntPoly::from_basic(x + sqrt(x) + 1)`

And the constructed poly has

`var = sqrt(x)`

and `dict = {{0,1}, {1,1}, {2,1}}`

And another

`poly b = UIntPoly::from_basic(x + 1)`

, with `var = x`

and `dict = {{0,1}, {1,1}}`

How will

`add_poly(a, b)`

be handled?
```
In [23]: a = Poly(sqrt(x) + 1)
Out[23]: Poly(sqrt(x) + 1, sqrt(x), domain='ZZ')
In [24]: b = Poly(x + 1)
Out[24]: Poly(x + 1, x, domain='ZZ')
In [26]: a + b
Out[26]: Poly(sqrt(x) + x + 2, sqrt(x), x, domain='ZZ')
```

Looks like sympy doesn't do it as well. Hmm
SymPy assumes that the generators are either equal or independent, which I think is a good assumption.

```
In [30]: Poly(x + x**Rational(1,3) + 1)
Out[30]: Poly(x + x**(1/3) + 1, x, x**(1/3), domain='ZZ')
```

Do we want these simplifications (not done by sympy)
I meant, sympy didn't do the simplification. It treats

`x`

and `x**(1/3)`

as separate generators
Also, did you have a look at the printing issue I raised in the sympy chat. I changed symengine code to give what I expected. Should I revert it, or it's fine?

@asmeurer has a point. It shows that

`x**(1/3)`

is a generator