nemonik/Intellect

learn_policy swallows an AttributeError

Closed this issue · 3 comments

Calling learn_policy is throwing an Attribute error.

-> intel.learn_policy("./basic_rules.policy")
(Pdb) 
Exception AttributeError: "'NoneType' object has no attribute 'path'" in <function _remove at 0x10ad4d410> ignored

The offending code can be seen below:

import pdb
from intellect.Intellect import Intellect
from wobbit import ColoredWobbit

if __name__ == '__main__':
    print 'Running...'
    intel = Intellect()
    #pdb.set_trace()
    intel.learn_policy("./basic_rules.policy")

    blue_wobbit = ColoredWobbit(5, 'blue')
    print blue_wobbit.color

    intel.learn(blue_wobbit)
    intel.reason()

Commenting out the intel.learn_policy("./basic_rules.policy") causes the code to continue to run, meaning output is printed, etc.

All the code is here:
https://gist.github.com/2484156

I will keep mucking with it, as it might be something silly I am doing.

Updated the gist to fix a typo, wobbit code seems fine and should exercise the intellect as intended. At least at face value.

Try the following changes to your code and policy:

#!/usr/bin/env python

import pdb
from intellect.Intellect import Intellect
from wobbit import ColoredWobbit

if __name__ == '__main__':
    print 'Running...'
    intel = Intellect()

    #pdb.set_trace()

    # add a try-except block like this to catch the error
    try:
        intel.learn_policy("./basic_rules.policy")
    except Exception, err:
        print err

    blue_wobbit = ColoredWobbit(5, 'blue')
    print blue_wobbit.color

    intel.learn(blue_wobbit)
    intel.reason()

And then modify your policy like so:

from wobbit import BaseWobbit, ColoredWobbit

rule is_blue:
    when:
        $i := ColoredWobbit( color == 'blue')

    then:
        print('Found a blue wobbit')
        $i.construct()

rule is_wobbit:
    when:
        $i := BaseWobbit()

    then:
        print('Yes this is a wobbit')

And modify wobbit module like so:

#!/usr/bin/env python

class BaseWobbit(object):
    """
    Base class for a Wobbit
    """

    def __init__(self, size):
        print 'Instantiating a wobbit'
        self._size = size

    # Data descriptors
    @property
    def size(self):
        return self._size

    @size.setter
    def size(self, value):
        if isinstance(value, int):
            self._size = value

        else:
            raise TypeError('Size must be set to an integer')

    def construct(self):
        print "Building a house out of wobbits"

class ColoredWobbit(BaseWobbit):
    """
    This is an extended Wobbit that is colored
    """

    def __init__(self, size, color):
        print 'Instantiating a colored wobbit'
        self._color = color

        # Call the base class explicitly
        # or use 'super'
        BaseWobbit.__init__(self, size)

    # Data descriptors
    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, value):
        if isinstance(value, str):
            self._color = value

        else:
            raise TypeError('Color must be set to a string')

Without the try-exception around messaging intellect to learn... the exception thrown by the method just bails you right out of your code with no clue as to something is wrong... i am looking into whether Intellect is gobbling standard error as I'm redirecting stderr to return the content as the message of the exception as ANTLR3 parser writes to the error to stderr and throws an empty exception leaving you no clue as to what went wrong...

With a try-except block in place around the call to learn though will inform you of the exception being thrown, if you trap and print the exception to stdout...

Output will look like the following after these fixes:

Running...
Instantiating a colored wobbit
Instantiating a wobbit
blue
Found a blue wobbit

Building a house out of wobbits

Yes this is a wobbit

Cool. I figured it was being swallowed somewhere. I was going to offer to fork and fix, but you did it.