All Projects → criticalhop → Poodle

criticalhop / Poodle

Licence: bsd-3-clause
Poodle - Python framework for AI Planning and automated programming

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Poodle

Wheels
Performance-optimized wheels for TensorFlow (SSE, AVX, FMA, XLA, MPI)
Stars: ✭ 891 (+1120.55%)
Mutual labels:  ai, optimization
Hyperparameter hunter
Easy hyperparameter optimization and automatic result saving across machine learning algorithms and libraries
Stars: ✭ 648 (+787.67%)
Mutual labels:  ai, optimization
Monkeys
A strongly-typed genetic programming framework for Python
Stars: ✭ 98 (+34.25%)
Mutual labels:  ai, optimization
Bfgs Neldermead Trustregion
Python implementation of some numerical (optimization) methods
Stars: ✭ 8 (-89.04%)
Mutual labels:  ai, optimization
Chinesechess
Chinese Chess(中国象棋) - A Free iOS App(C & Obj-C & Swift)
Stars: ✭ 68 (-6.85%)
Mutual labels:  ai
Ultimatemrz Sdk
Machine-readable zone/travel document (MRZ / MRTD) detector and recognizer using deep learning
Stars: ✭ 66 (-9.59%)
Mutual labels:  ai
Convai Bot 1337
NIPS Conversational Intelligence Challenge 2017 Winner System: Skill-based Conversational Agent with Supervised Dialog Manager
Stars: ✭ 65 (-10.96%)
Mutual labels:  ai
09 Zombierunner Original
First person shooter with Unity terrain and AI pathfinding (http://gdev.tv/cudgithub)
Stars: ✭ 64 (-12.33%)
Mutual labels:  ai
Serverless Plugin Webpack
Serverless Plugin Webpack
Stars: ✭ 72 (-1.37%)
Mutual labels:  optimization
Unity Plane Mesh Splitter
Unity Plane Mesh Splitter
Stars: ✭ 71 (-2.74%)
Mutual labels:  optimization
Surpriver
Find big moving stocks before they move using machine learning and anomaly detection
Stars: ✭ 1,152 (+1478.08%)
Mutual labels:  ai
Train Ai With Django Swagger Jwt
Train AI (Keras + Tensorflow) to defend apps with Django REST Framework + Celery + Swagger + JWT - deploys to Kubernetes and OpenShift Container Platform
Stars: ✭ 66 (-9.59%)
Mutual labels:  ai
Bytom
Official Go implementation of the Bytom protocol
Stars: ✭ 1,163 (+1493.15%)
Mutual labels:  ai
Pyribs
A bare-bones Python library for quality diversity optimization.
Stars: ✭ 66 (-9.59%)
Mutual labels:  optimization
Componentarrays.jl
Arrays with arbitrarily nested named components.
Stars: ✭ 72 (-1.37%)
Mutual labels:  optimization
Tiny Site
图片优化
Stars: ✭ 65 (-10.96%)
Mutual labels:  optimization
Frost Dev
Fast Robot Optimization and Simulation Toolkit (FROST)
Stars: ✭ 67 (-8.22%)
Mutual labels:  optimization
Picasso
Laravel Image Management and Optimization Package
Stars: ✭ 70 (-4.11%)
Mutual labels:  optimization
Spirit
Atomistic Spin Simulation Framework
Stars: ✭ 67 (-8.22%)
Mutual labels:  optimization
Powa Web
PoWA user interface
Stars: ✭ 66 (-9.59%)
Mutual labels:  optimization

Poodle - AI Planning in Python

PyPI - Status License PyPI version Build Status

Poodle is the Python-to-PDDL compiler and automated programming framework in an early stage of development.

Rationale

PDDL is a widely-used language to describe AI planning domains. The applications include various robotic planning problems, scheduling, logistics and manufacturing optimization, writing intelligent agents in computer games, real-time decision making, and even automated unix administration [1] [2]. AI planning, and specifically model-based planning, can be explained as a problem-solving method where the software developer describes (models) a problem, rather than codes the algorithm to solve the problem - which is radically different from how the conventional software development is practically-always done today. Not having to invent and code the algorithm has obvious benefits: developer productivity goes to extremes, you can write software with humanly-impossible complexity of algorithms, any tasks that require combining actions into meaningful chains can now be automated.

But despite these extreme gains, AI planning-based software is virtually nonexistent. And there are reasons why imperative programming is so popular and logic programming is not. Imperative programming has a much lower barrier of entry. Realistically, the majority of problems are much easier to code in a "usual" imperative way rather than modeling the full domain. The tooling, ecosystem, coding paradigms, and the language itself are much more polished and well-designed. Finally, many software libraries and components were written, and are readily available, in imperative programming languages.

Poodle aims to change that. The goal is to create a "native merge" of Python and model-based planning. This means that the developer will have an option to either write the algorithm or describe the problem and let the AI figure out the algorithm - with the result as usable in both options. The goal is to develop all the necessary tooling to enable full-scale production use of AI planning in real-world computing tasks - building on the top of a strong foundation created by the Python community.

Translating full Python programs into planning domain enables the use of efficient search methods to compose pre-built Python libraries into new algorithms. And a developer always gets an alternative to use the code imperatively - whenever she desires to switch.

Quickstart

$ pip install poodle # requires Python 3.7+

Let's say you have:

from poodle import Object, xschedule

class World(Object): 
    prepared: int
    said: bool 

def hello(world: World):
    assert world.said == False
    world.prepared += 1

def world(world: World):
    assert world.prepared > 0
    world.said = True
    return "Hello, world!"

w = World()
w.prepared = 0
w.said = False

Now you have two options:

  1. (obvious) execute natively, if you know the algorithm
hello(w)
print(world(w)) 
# -> "Hello, World!"
  1. if you don't know the parameters and/or sequence of execution - ask AI to figure out
print(xschedule(methods=[world, hello], space=[w], goal=lambda:w.said==True))
# -> "Hello, World!"

This will run the code on a hosted solver. To run a local solver, please scroll down to Installation section.

Overview

Introduction

Poodle is a Python module that enables construction of complex planning and constraint satisfaction problems using familiar Pythonic paradigms in production environments. It is still in the early stage of development, but is already powering kalc, our tool to optimize Kubernetes cluster.

Poodle introduces a pair of Python functions called xschedule and schedule that implement an automated planning mechanism, and a new base object Object:

xschedule(
    methods=[...],   # methods
    space=[...],     # objects
    goal=lambda: ... # condition for final object state
)

where methods is the list of methods that the planner should use to try to reach the goal state; space contains the list of Object objects that the planner will try to use as parameters for the methods, and goal is a simple end-state condition expressed as Python logical expression, usually a lambda function.

Object is a special object type that knows how to translate itself to PDDL.

To understand how to construct a problem, let's start with a classic "Hello, World" function:

from poodle import Object, xschedule

class World(Object): # a class that defines object that will hold final state
    said: bool       # declaration of a bollean variable (Python 3 type hints)

def hello(world: World): # annotated function that mutates the state of `world`
    assert world.said == False # hint for the planner when this call is valid
    print("Hello, World!")
    world.said = True    # mutate the state of the parameter object

w = World()          # create first object instance
w.said = False       # define the value for `said` attribute

# now execute this in an unfamiliar way ... 
xschedule(methods=[hello], space=[w], goal=lambda:w.said==True)

This program will immediately print "Hello, World!" to the console, which looks obvious at first. What actually happened is that Poodle compiled your Python method into PDDL domain + problem and used AI planner to find that the final state is achievable by simply executing the only method, and all asserts are satisfied with our hero object w.

It is important to note that the more precisely you describe your task, the easier it is for the AI planner to figure out the algorithm. That is why Poodle enforces fully statically typed interface for all objects and methods in search space as a minimum selectivity requirement. This also saves you from a lot of bugs in bigger projects.

Let's now jump to a more sophisticated example:

Monkey and Banana problem

We need to plan monkey actions to get the hanging banana: move the box, climb the box and grasp the bananas. We also need to take into account some basic laws of nature: like if the banana is on the tree, it's location is where the tree is.

from poodle import Object, schedule
from typing import Set

class Position(Object):
    def __str__(self):
        if not hasattr(self, "locname"): return "unknown"
        return self.locname
class HasHeight(Object):
    height: int
class HasPosition(Object):
    at: Position
class Monkey(HasHeight, HasPosition): pass
class PalmTree(HasHeight, HasPosition): 
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.height = 2
class Box(HasHeight, HasPosition): pass
class Banana(HasHeight, HasPosition): 
    owner: Monkey
    attached: PalmTree 
class World(Object):
    locations: Set[Position]


p1 = Position()
p1.locname = "Position A"
p2 = Position()
p2.locname = "Position B"
p3 = Position()
p3.locname = "Position C"

w = World()
w.locations.add(p1)
w.locations.add(p2)
w.locations.add(p3)

m = Monkey()
m.height = 0 # ground
m.at = p1

box = Box()
box.height = 2
box.at = p2

p = PalmTree()
p.at = p3

b = Banana()
b.attached = p

def go(monkey: Monkey, where: Position):
    assert where in w.locations
    assert monkey.height < 1, "Monkey can only move while on the ground"
    monkey.at = where
    return f"Monkey moved to {where}"

def push(monkey: Monkey, box: Box, where: Position):
    assert monkey.at == box.at
    assert where in w.locations
    assert monkey.height < 1, "Monkey can only move the box while on the ground"
    monkey.at = where
    box.at = where
    return f"Monkey moved box to {where}"

def climb_up(monkey: Monkey, box: Box):
    assert monkey.at == box.at
    monkey.height += box.height
    return "Monkey climbs the box"

def grasp(monkey: Monkey, banana: Banana):
    assert monkey.height == banana.height
    assert monkey.at == banana.at
    banana.owner = monkey
    return "Monkey takes the banana"

def infer_owner_at(palmtree: PalmTree, banana: Banana):
    assert banana.attached == palmtree
    banana.at = palmtree.at
    return "Remembered that if banana is on palm tree, its location is where palm tree is"

def infer_banana_height(palmtree: PalmTree, banana: Banana):
    assert banana.attached == palmtree
    banana.height = palmtree.height
    return "Remembered that if banana is on the tree, its height equals tree's height"

print('\n'.join(x() for x in schedule(
          [go, push, climb_up, grasp, infer_banana_height, infer_owner_at],
          [w,p1,p2,p3,m,box,p,b],
          goal=lambda: b.owner == m)))

this program solves the slightly modified "Monkey and banana" planning problem and produces the result:

$ pip install poodle
$ python ./monkey.py
Monkey moved to Position B
Remembered that if banana is on the tree, its height equals tree's height
Remembered that if banana is on palm tree, its location is where palm tree is
Monkey moved box to Position C
Monkey climbs the box
Monkey takes the banana

Kubernetes Configuration Problem

In this example, we are checking what are the consequences of configuration changes in a Kubernetes cluster. For example, the Kubernetes current state may be that once you load a new DaemonSet, important services will get evicted from the cluster in order to place your new microservice.

For a complete program, feel free to check out kalc source code.

Principles and Architecture

Poodle compiles Python into PDDL and uses fast-downward to run the search. As a typical real-world problem requires huge amounts of RAM, the whole solver bundle is running as an HTTP service in current architecture.

Composability

Support for nested xschedule is on the roadmap for planning code composability, although Python already provides excellent composability mechanisms.

Readability and Debuggability

Bad readability and debuggability have always plagued logic languages, and Poodle is not an exception: it is hard to tell what the result would be just by reading the code, as multiple methods can be executed concurrently and in any order. To address this problem, adding a visual debugger based on VOWL is planned. Although a combination of good code design and classical Python REPL allowed us to rapidly develop quite sophisticated AI planning-based software.

Debgging programs written with Poodle

  1. Unit test your methods
  2. Unit test sequences of methods - to make sure they actually play well together
  3. If something goes not according to plan:
    1. Create regression test and make sure that sequence of methods works if manually written and test passes
    2. Examine if Poodle can continue on its own from any step of your manually written sequence of methods
  4. Examine resulting plans with schedule() and POODLE_PERSIST=1 env variable

Poodle performance debugging

TBD

Documentation

There is no documentation at this point, but we promise to provide it as poodle evolves. If you would like to experiment with Poodle, the general recommendation is to start from reading the examples, unit tests and the kalc project source.

Developing

Poodle development is set up with tox and poetry. To run all tests locally

tox

To run tests using local web solver:

tox -e pytest_web

Environmet variables

POODLE_TEMPDIR - directory where poodle stores its files POODLE_PERSIST - should poodle keep its intermediate files it its POODLE_TEMPDIR

Contacts

Poodle is maintained by CriticalHop, a team of dedicated AI planning engineers. If you have any questions, feel free to open a github issue and chat with @grandrew and the team at ##poodle on freenode.

Poodle is a very large project and will not be possible without community support. Translating full Python into planning domain, and writing a fast solver that understands itself, is an absolutely wild idea that one day may become an important step towards the Artificial General Intelligence. So we are committed to Open Source and welcome any help.

If you are interested in joining the project, please write us at [email protected] or reach out directly to me at [email protected] or @Andrew_Gree on twitter.

-- Andrew Gree and the team

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].