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')
```

However,

```
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`

Yes

@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

Updated above code

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

I see

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

It doesn't work with MSVC

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?
You can take a look at SymPy source code

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')`

That's a too extreme case IMO

Okay, I'll try to handle it though

Also, printing

`x**(1/2)`

instead of `sqrt(x)`

is alright?
yes

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");
```

Looks good to me

@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?

@nishnik, can you comment?

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

How do you find

`x`

in `std::set<Pow>`

?
Right

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)
Isn't that the output by SymPy?

Yes

I meant, sympy didn't do the simplification. It treats

`x`

and `x**(1/3)`

as separate generators
That's fine. We can revisit if a need arises

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