Indra2 basic system

interactive.py contains some sample code on how to use the new Indra system. This notebook will illustrate its contents.

Right now we have three types of entity at play here:

  • Entity: the base "thingie" from which all else descends. Operations on entities act like vector operations.
  • Composite: an Entity that can hold other entities. Because it is itself an entity, we can nest composites. Operations on composites act like set operations.
  • Time: a Composite that loops over its members when acting, giving rise to "periods" of action.

Let's import interactive and see what we can do:


In [ ]:
from indra.interactive import *


---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-4bd57a1847c3> in <module>()
----> 1 from indra.interactive import *

~/desktop/indras_net/indra/interactive.py in <module>()
      9 
     10 from indra.tests.test_agent import *
---> 11 from tests.test_composite import *
     12 from env import *
     13 

ModuleNotFoundError: No module named 'tests.test_composite'

Now let's have a look at some of the things we get from that import:


In [2]:
newton


Out[2]:
{
    "name": "Newton",
    "duration": 30,
    "pos": null,
    "attrs": {
        "place": 0.0,
        "time": 1658.0,
        "achieve": 43.9
    },
    "groups": "NewtonLeibniz NewtonHardy ",
    "active": true,
    "type_sig": 3
}

newton is an Entity. The base Entity has a name, a lifespan (duration), and an arbitrary number of attributes.

hardy is another entity. Here's how easy it is to make a group out of two entities:


In [3]:
great_mathematicians = newton + hardy
great_mathematicians


Out[3]:
{
    "name": "NewtonHardy",
    "attrs": {},
    "members": {
        "Newton": {
            "name": "Newton",
            "duration": 30,
            "pos": null,
            "attrs": {
                "place": 0.0,
                "time": 1658.0,
                "achieve": 43.9
            },
            "groups": "NewtonLeibniz NewtonHardy ",
            "active": true,
            "type_sig": 3
        },
        "Hardy": {
            "name": "Hardy",
            "duration": 10,
            "pos": null,
            "attrs": {
                "age": 141.0
            },
            "groups": "NewtonHardy ",
            "active": true,
            "type_sig": 1
        }
    }
}

Oops, we forgot Leibniz and Ramanujan:


In [7]:
forgotten = leibniz + ramanujan
forgotten
great_mathematicians += forgotten
great_mathematicians


Out[7]:
{
    "name": "NewtonHardy",
    "attrs": {},
    "members": {
        "Newton": {
            "name": "Newton",
            "duration": 30,
            "attrs": {
                "place": 0.0,
                "time": 1658.0,
                "achieve": 43.9
            }
        },
        "Hardy": {
            "name": "Hardy",
            "duration": 10,
            "attrs": {
                "age": 141.0
            }
        },
        "Leibniz": {
            "name": "Leibniz",
            "duration": 20,
            "attrs": {
                "place": 0.0,
                "time": 1646.0
            }
        },
        "Ramanujan": {
            "name": "Ramanujan",
            "duration": 5,
            "attrs": {}
        }
    }
}

In [ ]:
We can also do set intersection:

In [8]:
great_mathematicians *= forgotten
great_mathematicians


Out[8]:
{
    "name": "NewtonHardy",
    "attrs": {},
    "members": {
        "Leibniz": {
            "name": "Leibniz",
            "duration": 20,
            "attrs": {
                "place": 0.0,
                "time": 1646.0
            }
        },
        "Ramanujan": {
            "name": "Ramanujan",
            "duration": 5,
            "attrs": {}
        }
    }
}

And take subsets, using a predicate:


In [4]:
calc_founders = newton + leibniz
just_l = calc.subset(max_duration, 25, name="Just Leibniz!")
just_l


Join group being called on Leibniz to join group: Just Leibniz!
Out[4]:
{
    "name": "Just Leibniz!",
    "attrs": {},
    "members": {
        "Leibniz": {
            "name": "Leibniz",
            "duration": 20,
            "attrs": {
                "place": 0.0,
                "time": 1646.0
            },
            "groups": "NewtonLeibniz Just Leibniz! "
        }
    }
}

In that particular case, our predicate selected just the set members with a duration of less than 25, and so we got only Leibniz. The function signature for subset is: def subset(self, predicate, *args, name=None): *args is a list of arguments to pass to the predicate function, so it can take an arbitrary number. The optional name parameter will name the new subset.


In [ ]:
calc_founder