# Lecture 6: Symbols, Variables, and References¶

While Sage works with dynamic typing in a similar fashion as Python,
sometimes we must declare variables explicitly with `var`

as in `var('x')`

.

Every variable in Sage has a type. We distinguish between names of variables and the objects variables refer to. Putting quotes around a variable name prevents an evaluation and we see how this may be used to make connections between variables. We cover the (partial) evaluation of expressions as needed in the verification of the solutions of a general cubic equation.

## Expressions and Names¶

Sage export mathematical constants, such as `pi`

.
We can work with `pi`

as a variable and assign
any value to `pi`

. For example:

```
print(pi, type(pi))
pi = 3.14
print(pi, type(pi))
```

The first statement shows that `pi`

is an expression.
After the assignment, `pi`

refers to the value 3.14
which is of type `sage.rings.real_mpfr.RealLiteral`

.
Did we then loose the value of pi?

With `restore`

(we could also call the restore
the unassign operation)
we can get back the original value of `pi`

.

```
restore('pi')
print(pi, type(pi))
print(numerical_approx(pi, digits=30))
```

Mind the quotes in the argument of `restore`

,
without the quotes we would take the value `pi`

refers to.
After executing the `restore`

we see that `pi`

is again
an expression. And sure enough, we can see as many digits
of `pi`

as we like.

The quotes are of course a general construction from Python where everything put between quotes is a string. A value can be stored as a string and then later evaluated with eval.

```
x = 3.14
name = 'x'
print(x, name, eval(name))
```

## Verification of Solutions¶

By default, with we solve an equation with``solve`` we receive a list of expressions.

```
var('z')
equ = z**2 - 3 == 0
sols = solve(equ, z); print(sols)
print(type(sols[0]))
```

We have the option to return a list of dictionaries.

```
sols = solve(equ, z, solution_dict=True); print(sols)
```

Now we see `[{z: -sqrt(3)}, {z: sqrt(3)}]`

and `sols`

is a list
of dictionaries. As key for each dictionary
we have the variable name
and its corresponding value is the value of the solution of the equation.
For example, to select the value of the first solution, using as key
the variable name `z`

, we can proceed as follows

```
print(sols[0], type(sols[0]))
print(sols[0][z])
```

The last command prints the value `-sqrt(3)`

.
The dictionary is useful to
substitute the value of the variable
in the equation we solved, for
verification purposes.

```
equ.substitute(sols[0])
```

and we see `0 == 0`

.

Suppose we were to assign to `z`

.
Then we can no longer access the dictionary as directly as before,
because `z`

now refers to a value, but via `keys()`

we retrieve the
unevaluated variable with the corresponding value.
But the substitution still works.

```
z = 3; print('z = ', z)
print(sols[0].keys(), sols[0].values())
equ.substitute(sols[0])
```

Even though we have lost the use of `z`

as a general variable,
its former value as a solution is still contained in the dictionary
of solutions `sols`

.

How do we see the current value to which z refers to?

```
print(eval(str(sols[0].keys())))
```

This will show the list `[3]`

.
Recall that lists in Python allow to work with shared references.

## Evaluation of Expressions¶

We can express the roots of a polynomial of degree two with
symbolic coefficients.
Similar formulas exist for a polynomial of degree three.
To start over, we clear all the variables in our worksheet
with the `reset()`

.

```
reset()
var('x, a, b, c')
p = x^3 + a*x^2 + b*x + c
s = solve(p == 0, x, solution_dict=True)
print(s)
```

The formulas look complicated. Let us check a specific example. We want to verify the solution for specific values of the coefficients. An easy choice for the coefficients are the numbers 1.0, 2.0, 3.0 (of type float). Recall that Python allows for simultaneous or tuple assignment.

```
(a, b, c) = (1.0, 2.0, 3.0)
print(a, b, c)
print(p)
print(s[0])
```

The outcome is not what we wanted and expected.
Even as we see the specific values for `a`

, `b`

, and `c`

printed,
the polynomial still shows up in its original symbolic
form \(x^3 + a x^2 + b x + c\), and so does its solution.
If we were to retype the expression for the polynomial again,
then the coefficients would be evaluated, but this is tedious
and we do not want to retype the complicated expressions for
the solutions.

How to force the evaluation of the coefficients in p and the solution without retyping the polynomial p? We can evaluate an expression.

```
print(p(x=x,a=a,b=b,c=c))
s0 = s[0][x](a=a,b=b,c=c); print(s0)
```

Now we see the polynomial
`x^3 + x^2 + 2.00000000000000*x + 3.00000000000000`

and a numerical value for the solution.

We can then evaluate the expression `p`

at `s0`

.

```
print(p(x=s0,a=a,b=b,c=c))
```

To verify whether the value of the expression at the solution will evaluate to zero, we convert to the complex floating point type.

```
print(complex(p(x=s0,a=a,b=b,c=c)))
```

and we see that the value is close enough to the machine precision.

## Assignments¶

For variables

`a`

and`b`

consider the expression\[{\displaystyle \frac{1}{a + b \sqrt{2}}}\]We want to compute expressions for the coefficients of the inverse of \(a + b \sqrt{2}\), written in the same format, that is: as \(c + d \sqrt{2}\) for some variables

`c`

and`d`

.Set up the equations on the coefficients

`c`

and`d`

such that\[{\displaystyle \left( a + b \sqrt{2} \right) \left( c + d \sqrt{2} \right) = 1.}\]Apply

`solve`

to the equations to find expressions for`c`

and`d`

in function of the`a`

and`b`

of the original expression.Verify your solution by making the product \({\displaystyle \left(a + b \sqrt{2}\right)\left(c + d \sqrt{2}\right)}\) and check if the product equals 1 for the computed expressions for

`c`

and`d`

.

Execute the statements

`reset(); a, b = var('a, b'); b = a; a = 2`

and explain the relationships between the variables`a`

and`b`

. Give the Sage commands and their output to illustrate your explanation.Execute the statements

`reset(); a, b = var('a, b'); a = 3`

in a cell. What is the next statement so`print(a, b)`

shows`3, a`

as`b`

refers to`a`

, as`a`

refers to`3`

.