Skip to main content

The programming model to integrate AI components

Project description

Combinator

The programming model to integrate AI components

Build Status

Combinator is a programming model to build integrative AI solutions. Programs can be generated in the form of graphs such that functions are represented by nodes and dataflow between them by edges. It loosly follows the functional style of programming with lazy evaluation. The features of the programming model can be enumerated as following.

  • Dynamical program generation - Can generate aribitrary subprograms at runtime
  • Modularity - Every part of the program is modular
  • Expressivity - Preloaded with required primitives to build complex logics
  • Abstraction - Can build arbitrary reusable components
  • Ease of integration - With a proper UI programs can be easily built by connection nodes with edges.
  • API integration - This packaged model contains a basic version of the environment object to make post calls to remote APIs

For more details please check this paper and this one.

Get started

The programming model is built on Python. You can install the package by running the following command

pip install combinator

Then load the package in Python by running the following command

import combinator as cb

Examples

Here are few program examples in combinator

Add two constant numbers
from combinator import creategraph, createnode, addlink, init_world, runp
operation = '+' # this example can be run by setting operation as '-' or '*' or '/' or '^' or '=' or '>'
graph = creategraph('TestGraph') # Takes graphname as argument
g1 = createnode(graph,'iW',init_world) # 1st argument should be the graph object, 2nd the node short name and 3rd argument should be specific parameters needed to create specific nodes. Except for initworld, constant, sensor and actuator 3rd argument is not needed. 
g2 = createnode(graph,'K',2);
g3 = createnode(graph,'K',3)
g4 = createnode(graph,operation)
addlink(graph,g1); 
addlink(graph,g2,g1); # first argument should be the graph object, 2nd the node which needs to be connect to its parents and rest of the arguments should be the parent nodes in sequence.
addlink(graph,g3,g1);
addlink(graph,g4,g3,g2);
output = runp(g4,graph) # The first argument should be the terminal node which needs to be run and 2nd the graph object
print (output[0])
Conjuction of two boolean values
from combinator import creategraph, createnode, addlink, init_world, runp
operation = '&' # this example can also be run by setting operation as '|'
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',True);
g3 = createnode(graph,'K',False)
g4 = createnode(graph,operation)
addlink(graph,g1);
addlink(graph,g2,g1);
addlink(graph,g3,g1);
addlink(graph,g4,g3,g2);
output = runp(g4,graph)
print (output[0])
Conditional execution
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',2)
g3 = createnode(graph,'K',3);
g4 = createnode(graph,'=')
g5 = createnode(graph,'if')
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1);addlink(graph,g4,g2,g3);addlink(graph,g5,g4,g1,g2);
output = runp(g5,graph)
print(output[0])
Square all elements of list with fmap
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',[3,4,5]);
g3 = createnode(graph,'*')
g4 = createnode(graph,'fm')
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1,g1);addlink(graph,g4,g3,g2);
output = runp(g4,graph)
print(output[0])
Zip two lists
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',[3,4,5]);
g3 = createnode(graph,'K',[14,12,4]);
g4 = createnode(graph,'zp')
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1);addlink(graph,g4,g3,g2);
output = runp(g4,graph)
print(output[0])
Run loop
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',2);
g3 = createnode(graph,'+')
g4 = createnode(graph,'lp')
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1,g1);addlink(graph,g4,g3,g2);
output = runp(g4,graph)
print(output[0])
Run Recurse
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',7);
g3 = createnode(graph,'K',1);
g4 = createnode(graph,'+');
g5 = createnode(graph,'K',100);
g6 = createnode(graph,'>');
g7 = createnode(graph,'lg')
g8 = createnode(graph,'lg')
g9 = createnode(graph,'rc')
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1);addlink(graph,g4,g3,g1);addlink(graph,g5,g1);addlink(graph,g6,g1,g5);addlink(graph,g7,g6);addlink(graph,g8,g4);addlink(graph,g9,g8,g7,g2);
output = runp(g9,graph)
print(output[0])
API POST call with actuator and sensor
from combinator import creategraph, createnode, addlink, init_world, runp
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',{'url':'https://httpbin.org/post','headers':{'Content-Type':'application/json'}})
g3 = createnode(graph,'K','');
g4 = createnode(graph,'ac','dict'); # the third argument in actuator or sensor node is the input type and output type respectively. If no argument is supplied the type is set as 'any'
g5 = createnode(graph,'sn','any');
g6 = createnode(graph,'ac','char');
g7 = createnode(graph,'sn','any');
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g4,g2);
addlink(graph,g5,g4);addlink(graph,g3,g5);addlink(graph,g6,g3);addlink(graph,g7,g6);
output = runp(g7,graph)
print(output[0])
Update the environment
from combinator import init_world
init_world.update_env(<environment object>) # check environment/apienv.py to find out how to build an environment object. It can serve as an template to build your own custom environment object
Get runtime errors
from combinator import creategraph, createnode, addlink, init_world, runp,combinatorruntimeerror
graph = creategraph()
g1 = createnode(graph,'iW',init_world)
g2 = createnode(graph,'K',2);
g3 = createnode(graph,'K','3')
g4 = createnode(graph,'-')
print(g1,g2,g2,g4)
addlink(graph,g1);addlink(graph,g2,g1);addlink(graph,g3,g1);addlink(graph,g4,g3,g2);
try:
  print(runp(g4,graph))
except integratorruntimeerror as e:
  print(e.error)

List of available primitives

Following are the list of available primitives in combinator:


Full Name short name Description
initWorld iW Initializes the environment
constant K Outputs a constant value as set during node creation
identity id Outputs the input value unchanged
add + Adds two input numbers. Joins two lists. Updates 2nd key-value pair in the 1st.
subtract - Subtracts the number in 2nd input port from the 1st
multiply * Multiplies two numbers
divide / Divides the number in 1st input port with respect to the 2nd
exponent ^ Raises the number in the 1st input port to the power of the 2nd
conjunction & Does logical AND operation between two inputs
disjunction | Does logical OR operation between two inputs
negate ! Inverts the input boolean value
greater > Outputs True if 1st input is greater than second else False
equal = Outputs True if 1st input is equal to second else False
emptylistordict nl Outputs empty key-value pair if input is 'keyvalue' else empty list
head hd Outputs 1st element of the list
tail tl Outputs rest of the list except the 1st element
pop pop Outputs the n th element from the list in the 2nd input port. The value n should be provided in the 1st input port. It fetches the value corresponding to the key k if 1st input is a key-value pair. In that case the 2nd input should provide the key k.
append cn Appends an element e to the list provided in the 2nd input, where the 1st input provides the element e
addkey ak Adds a key value pair to the key-value pairs provided in the 1st input. The 2nd input should provide the key and 3rd the value.
condition if Executes the parent graph connected to 2nd input port if 1st input is True else the parent graph of 3rd input port is executed.
lambdagraph lg Outputs the parent graph as subgraph. The iW node in the subgraph is replaced with an identity node. Any other initial nodes in the subgraph is connected to the newly created idenity node.
apply ap Outputs the parent graph as subgraph. The iW node in the subgraph is replaced with an identity node. Any other initial nodes in the subgraph is connected to the newly created idenity node.
fmap fm Converts the subgraph corresponding to parentnode1, a function and thereby applies it to each element of the list supplied in the input port 2. It outputs the new list.
zip zp Joins two list element wise. The two list should be provided in two input ports. It outputs a list of lists.
aggregator ag Aggregates the element of a list by an aggregator function. The aggregator function should be provided in input port 1 and the list in input port 2.
loop lp Converts the subgraph corresponding to parentnode1, a function and applies it n number of times to its output. The initial argument of the function will be n , where n is supplied as an integer to its input port 2.
recurse rc Takes 2 function and one data value of any type as input. The function supplied to input port 1 is applied recursively on the 3rd input until stopping condition is met. The function supplied to input port 2 is applied on 3rd input to evaluate the stopping condition.
sensor sn sends a read request to the environment and outputs the recieved data
actuator ac sends and write request to the environment and writes the input data

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

combinator-1.1.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

combinator-1.1-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

File details

Details for the file combinator-1.1.tar.gz.

File metadata

  • Download URL: combinator-1.1.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.9

File hashes

Hashes for combinator-1.1.tar.gz
Algorithm Hash digest
SHA256 e90d8b16c74b643a90407c1f0c8b810298ff398ee00180a117708267a90b782f
MD5 31c5964c779cec9d055d8ac2fd6b16d4
BLAKE2b-256 49d1080a3e70594cd9937695b81865ddda2c26c838f117f6bd2a21c6a63e07ad

See more details on using hashes here.

File details

Details for the file combinator-1.1-py3-none-any.whl.

File metadata

  • Download URL: combinator-1.1-py3-none-any.whl
  • Upload date:
  • Size: 24.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.9

File hashes

Hashes for combinator-1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d49df29d98b8870e6203e184b0d67e23179d3e7212ea70eaea9b3d1e7a8f220b
MD5 77bf4831af6fd1c6ebaf2de4618696c8
BLAKE2b-256 4485fe5b54e28045921bbb669ade65c6951eb8077ea4b3ce0f2f327924fc54ef

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page