# GSoC 2015 Application Aaditya M Nair : Improve the assumptions system.

## Personal Background

I am a 2nd Year undergraduate pursuing Bachelor of Technology and MS (By Research) in Computer Science at International Institute of Information Technology, Hyderabad. During this time I have taken courses like

``````1. Mathematics-I   (Set Theory, Combinatorics, Introductory Graph Theory)
2. Mathematics-II  (Basic Matrices and Determinants, Jacobians, Gaussian Elimination)
3. Mathematics-III (Probability Theory, Complex Algebra)
``````

as well as other computer oriented courses like

``````1. Data Structures
2. Algorithms
3. Structured Software Analysis and Design
``````

## Programming Experience

I work on a Fedora 21 machine. I prefer using VIM as my primary text-editor due to availability of Keyboard based commands for almost everything and its general customizability and speed.

I have been programming for three years now. I began with C++/C and then moved on to NodeJS and Python. I switched to Python as my primary language due to its general ease of Programming and understandability. It also has a highly evolved documentation system that was very useful to me during the learning phase.

List / Dictionaries are my most favorite Python features. In SymPy, one of favorite features is transforms especially Fourier Transforms. As a student of Signal Analysis this semester, this feature helped me in a lot of analysis.

## Contributions to SymPy

I started tinkering with SymPy around January, 2015 and I made my first contribution at the end of that month. Since then I have been consistently contributing to and learning from the awesome community that is Sympy.

# The Project

## Brief Overview

This project aims to completely replace SymPy's old assumptions system and replace it with a completely new one. Aaron Meurer had already started some work on this direction. This project hopes to extend and probably complete this work.

In essence, the new assumptions system will separate the symbols from the assumptions associated with it.

#### Old Assumptions:

```>>> x=Symbols('x', positive=True)
>>> x.is_positive
True```

#### New Assumptions (Partially Implemented):

```>>> x = Symbol('x')
>>> y = Symbol('y')

>>> facts = Q.positive(x) & Q.positive(y)
True```

The present assumptions system creates a lot of bugs like #8873 which are fixed through non-desirable hacks. The new system will provide a better and elegant solutions to them

## Plan of Execution

1. Develop helper functions to facilitate further development.

• Add functions that convert a fact_name to corresponding property.

```>>> as_property('real')
Q.real
>>> as_not_property('positive')
~Q.positive ```
• Add `getter` functions in `Q` to facilitate the above.

2. Update `ManagedProperties` class to use the new style assumptions.

• This involves changing parts of code that used the old-style assumptions to new-style assumptions.

• For example:

This:

```for k, v in cls.default_assumptions.items():
setattr(cls, as_property(k), v)```

Becomes:

```for k, v in cls.default_assumptions.items():
if v == True:
global_assumptions &= as_property(k)(self)
else:
global_assumptions &= as_not_property(k)(self)```
3. Modify `ask()` to read the old-style assumptions. Change the `Symbol` class to use new-assumptions.

Presently:

```>>> ask(Q.real(Symbol('x', real=True)))
None```

After the project:

```>>> ask(Q.real(Symbol('x', real=True)))
True```
• This involves directly updating the `global_assumptions`. when new `Symbol` is created.

i.e. when the following symbol is created:

`>>> x = Symbol('x', real=True)`

the following call is made internally:

`global_assumptions &= Q.real(x)`
• All calls to `x.is_<attribute>` will be equivalent to `ask(Q.<attribute>(x), context=global_assumptions)`

4. Make a few core components ( `Add`, `Mul`, etc ) use the new assumptions system and test them.

Presently these classes use old assumptions:

```def _eval_is_imaginary(self):
rv = _fuzzy_group(a.is_imaginary for a in self.args)
if rv is False:
return rv
iargs = [a*S.ImaginaryUnit for a in self.args]
r = _fuzzy_group(a.is_real for a in iargs)
if r:
s = self.func(*iargs, evaluate=False)
return fuzzy_not(s.is_zero)```

These will be more like:

```def _eval_is_imaginary(self):
rv = _fuzzy_group(ask(Q.imaginary(a)) for a in self.args)
if rv is False:
return rv
iargs = [a*S.ImaginaryUnit for a in self.args]
r = _fuzzy_group(ask(Q.real(a)) for a in iargs)
if r:
s = self.func(*iargs, evaluate=False)
5. Once those functions are tested. Update to new assumptions on other core operations (`sub`, `mod`, etc.).

6. The assumptions system has, in many places, missing or incomplete documentation. Mostly, I believe that not enough examples are provided in the doc-strings. These examples could be added to make the code more easily understandable.

## Timeline

• Week-1

• Develop helper functions.
• Update `ManagedProperties` for new-style assumptions
• Week-2 -- Week-3

• Update `ask()` so that it reads the old-style assumptions from a `symbol`.
• Prepare `symbol` class to accept new assumptions. Test them.
• Week-4 -- Week-5

• Port some core functions ( `Add`, `Mul`, `Pow`, etc ) to use the new assumptions system.
• Week-6

• Extend `ask()` to accept expressions containing the above core functions.
• Week-7

• Catch-Up week.
• Week-8 -- Week-9

• Extend new assumptions to all core functions.
• Week-10

• Solve issues like #8873 caused due to old assumptions.
• Week-11 -- On-wards

• Documentation and various bug-fixes.

## Other Commitments (During GSoC)

I will have my semester finals till 7th of May. After that I am to start a research project for my course. This research is only intended as an introduction to the field and will only last at-most 8 weeks. Hence, during the research, I will be able to devote around 35 hours per week, after which I can contribute much more.