Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximum recursion depth exceed for "learn.aiml" examples #2

Open
mertyildiran opened this issue May 1, 2016 · 22 comments
Open

Maximum recursion depth exceed for "learn.aiml" examples #2

mertyildiran opened this issue May 1, 2016 · 22 comments

Comments

@mertyildiran
Copy link

mertyildiran commented May 1, 2016

Hey @creatorrr , thanks for this great library!

I'm facing with a problem while trying to use these learn.aiml files with your library.
Mitsuku: http://www.square-bear.co.uk/aiml/learn.zip
ALICE: http://alicebot.wikidot.com/learn-aiml (WRONG/OUTDATED)

It's trapping in to an infinite loop, how can I solve that? This is the error.log from the beginning to KeyboardInterrupt.

stderr:

WARNING: maximum recursion depth exceeded (input='xlearnfact')WARNING: maximum recursion depth exceeded (input='XEDUCATE WHAT IS .........
........XSPLIT a language XSPLIT')WARNING: maximum recursion depth exceeded (input='xlearnfact')Traceback (most recent call last):
  File "main2.py", line 5, in <module>
    print kernel.respond("Learn the sun is hot")
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 329, in respond
    response = self._respond(s, sessionID)
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 394, in _respond
    response += self._processElement(elem, sessionID).strip()
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 425, in _processElement
    return handlerFunc(elem, sessionID)
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 928, in _processTemplate
    response += self._processElement(e, sessionID)
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 425, in _processElement
    return handlerFunc(elem, sessionID)
.
.
.
.
    return handlerFunc(elem, sessionID)
  File "/usr/local/lib/python2.7/dist-packages/aiml/Kernel.py", line 871, in _processStar
    response = self._brain.star("star", input, that, topic, index)
  File "/usr/local/lib/python2.7/dist-packages/aiml/PatternMgr.py", line 181, in star
    patMatch, template = self._match(input.split(), thatInput.split(), topicInput.split(), self._root)
  File "/usr/local/lib/python2.7/dist-packages/aiml/PatternMgr.py", line 325, in _match
    pattern, template = self._match(suf, thatWords, topicWords, root[self._STAR])
  File "/usr/local/lib/python2.7/dist-packages/aiml/PatternMgr.py", line 307, in _match
    pattern, template = self._match(suffix, thatWords, topicWords, root[first])
  File "/usr/local/lib/python2.7/dist-packages/aiml/PatternMgr.py", line 325, in _match
    pattern, template = self._match(suf, thatWords, topicWords, root[self._STAR])
  File "/usr/local/lib/python2.7/dist-packages/aiml/PatternMgr.py", line 320, in _match
    if root.has_key(self._STAR):
KeyboardInterrupt

With these usage attempts both of them has same problem:

import aiml

kernel = aiml.Kernel()
kernel.learn("learn.aiml")
print kernel.respond("Learn the sun is hot")
import aiml

kernel = aiml.Kernel()
sessionId = 12345
kernel.getSessionData(sessionId)
kernel.learn("learn.aiml")
print kernel.respond("Learn the sun is hot")
@cyberyu
Copy link

cyberyu commented Jan 22, 2017

I have the same issue. But on Pandorabots.com it seems okay. They use LISP AIML parser though.

@seth7743
Copy link

Also ran into the same issue, but fixed it by using a .brn file instead for learning, however that also means you start off in a clean file. If that's what you wanna do then it would be your best bet.

@mertyildiran
Copy link
Author

mertyildiran commented Jan 24, 2017

@cyberyu I never considered using AIML with LISP but it's seems a reasonable solution right now.

@seth7743 What do you mean with .brn file? could you explain a little bit?

By the way I believe @cdwfs is the creator and maintainer of the PyAIML: https://github.com/cdwfs/pyaiml

Proof: http://www.alicebot.org/downloads/programs.html

and this issue must be discussed under that page instead of this page: cdwfs/pyaiml#1

I'll do my best to investigate this issue when I have a chance, but at this point your guess may be as good as mine. - Cort Danger Stratton

@seth7743
Copy link

seth7743 commented Jan 24, 2017

Your .brn will act as the learn.aiml file, it stores and retrieves the bot's learned responses. At least this is what I think you wish to achieve so here's a simple code snippet:

You can use the kernel.setSessionData() and get as well on the .brn file

startup.txt

@mertyildiran
Copy link
Author

@seth7743 Could you provide the file assigned at this line: bot_brain = "aiml/bot_brain.brn"

Is that the file: https://github.com/cyface/pyaiml-test/blob/master/bot_brain.brn

Could you explain the process at startup.txt?

@cdwfs
Copy link

cdwfs commented Jan 24, 2017

By the way I believe @cdwfs is the creator and maintainer of the PyAIML: https://github.com/cdwfs/pyaiml
Proof: http://www.alicebot.org/downloads/programs.html

Yup, that's me! Glad to see the project is still alive and (allegedly) useful. Alas, I haven't written a non-trivial Python script in close to ten years, so I wouldn't expect too much active development in my fork of the repo.

@seth7743
Copy link

seth7743 commented Jan 25, 2017

@mertyildiran The file is automatically created by this line (29) "kernel.saveBrain(bot_brain)" if it does not exist.

The program is to initiate a chat, I'll start from line (13), the top is fairly simple I believe:
line(13) - Declaring the directory of the bot properties file, you can find this in your Pandorabots files
line(17) > line(23) - Loops through the properties in the above file and sets the bot predicate for there kernel, these are default bot properties for pyaiml, much like saving to .brn file
line(27) > line(33) - Checks if your bot already has a .brn file, if not, it'll create it with the name and directory specified in line(5)
line(35) > line(47) - Requests input from the user to interact with the bot
Typing "quit" exits
Typing "save" stores everything learnt to the brain
Typing "load aiml b" reloads aiml files if you made changes to them
Typing anything else chats with the bot and generates a response

I hope that's what you were hoping to achieve @mertyildiran

@cdwfs It is (supposedly) quiet useful. Thanks for developing it!

@mertyildiran
Copy link
Author

@seth7743 hmm, I understand thx!

@creatorrr
Copy link
Owner

Hey @mertyildiran, sorry for the late reply. I was travelling. Anyhow, were you able to get the file working? I tried testing the learn.aiml file and I ran into the following:

  • There were a few parse errors but the file seemed to load correctly in the end.

    PARSE ERROR: Unexpected tag (line 73, column 4)
    PARSE ERROR: Unexpected tag (line 81, column 6)
    PARSE ERROR: Unexpected tag (line 93, column 2)
    PARSE ERROR: Unexpected tag (line 94, column 0)
    Loading learn.aiml... done (0.02 seconds)

  • On trying k.respond("Learn the sun is hot"), the interpreter did get stuck in an infinite loop.

My initial thoughts are that the aiml file probably had errors which I need to investigate but if you were able to get it to work with another aiml implementation then I guess there's a bug in this one. Please let me know.

@mertyildiran
Copy link
Author

No @creatorrr. learn.aiml file is a legit AIML file.

Mitsuku is a Chatterbot created from AIML technology by Steve Worswick. Mitsuku won the 2013 and 2016 Loebner prize.

https://en.wikipedia.org/wiki/Mitsuku
http://www.mitsuku.com/

It's working perfectly well with Program-O though, maybe examining Program-O's algorithm can help to resolve the issue with pyAIML.

We are pretty sure that learn.aiml file is working well because in the university we made a virtual assistant that using it: https://github.com/mertyildiran/Dragonfire

Video as proof: https://youtu.be/ujmRtqf2nxQ

By the way don't irritate when you see "Teachable AI" term because it's the result of the stupidity of some academician. Replace "Teachable AI" with "AIML" term in your mind 😄

@cdwfs
Copy link

cdwfs commented Feb 5, 2017

Hi @mertyildiran -- I've just come out of PyAIML retirement long enough to investigate this bug report. I think I see the problem -- the learn.aiml file includes a <learn> tag whose child is a <category> to be learned. However, as specified in the AIML 1.0.1 spec, the contents of a <learn> tag are meant to evaluate to a URI to be loaded (e.g. a URL or filename); inline AIML tags would not be valid, according to this interpretation.

It looks like the specification of the <learn> tag was expanded in the AIML 2.0 working spec to allow inline AIML, and I agree that would certainly be an awesome feature. But PyAIML was very specifically written against the 1.0.1 spec. I don't have a wikidot account, but if I did I'd suggest an edit to the learn.aiml page to add a "version=2.0" to the <aiml> tag.

I haven't looked at Program O, but if it processes this file correctly, it must either be targeting the 2.0 spec, or a relaxed interpretation of the 1.0.1 spec. To emulate this behavior in a 1.0.1-compliant interpreter like PyAIML, you could probably replace the inline AIML inside in the <learn> tag with a <system> tag that writes the same inline AIML to a temporary file, and then returns the name of that file. Or something like that.

@mertyildiran
Copy link
Author

Hi @cdwfs. I'm glad you come back from the retirement. 😄

Adding version="2.0" to <aiml> tag <aiml version="2.0"> made no difference.

Unique feature of learn.aiml is being recursive and I believe AimlParser.py is not able to parse recursively. But I'm not capable to understand or fix the issue, I'm just guessing. You @cdwfs should fix it.

By the way this link of learn.aiml is WRONG and/or OUTDATED

Correct link is this: http://www.square-bear.co.uk/aiml/learn.zip

I forgot to mention that; on May 1st 2016, I reached out to Steve Worswick via email and this is the email dump:

Me:

When I try to use learn.aiml file with
https://pypi.python.org/pypi/aiml/0.8.6 I'm facing with maximum recursion
depth problem.

The only problematic file is learn.aiml. How can I solve this issue.

Steve Worswick:

Does your interpreter support and tags?
Even if it does, inputs like "Harry is taller than John but smaller than
Fred" will set up dozens of categories. You may need to increase your
recursion depth.

Me:

I'm using this Python library to get responses:
https://pypi.python.org/pypi/aiml/0.8.6
https://github.com/creatorrr/pyAIML

Do you think the issue is related with this library?

Also, please checkout the issue that I opened: #2
You can see more detailed explanation from this issue entry.

Steve Worswick:

Sorry but that’s not an interpreter I’ve ever used. My learn.aiml file is valid AIML used by hundreds of people and so I can only assume the problem lies with your interpreter.
Hopefully, the author will provide some support for you.

@mertyildiran
Copy link
Author

@cdwfs and @creatorrr I also forgot to mention that or this just newly happened to me;

When I try to load the learn.aiml file, it's giving me tons of PARSE ERROR:s

>>> import aiml
>>> kernel = aiml.Kernel()
>>> kernel.learn("learn.aiml")
PARSE ERROR: Unexpected <category> tag (line 172, column 1)
PARSE ERROR: Unexpected </learn> tag (line 180, column 3)
PARSE ERROR: Unexpected </template> tag (line 192, column 1)
PARSE ERROR: Unexpected </category> tag (line 193, column 0)
PARSE ERROR: Unexpected <category> tag (line 200, column 1)
PARSE ERROR: Unexpected </learn> tag (line 208, column 3)
PARSE ERROR: Unexpected </template> tag (line 210, column 1)
PARSE ERROR: Unexpected </category> tag (line 211, column 0)
PARSE ERROR: Unexpected <category> tag (line 218, column 1)
PARSE ERROR: Unexpected </learn> tag (line 226, column 3)
PARSE ERROR: Unexpected </template> tag (line 238, column 1)
PARSE ERROR: Unexpected </category> tag (line 239, column 0)
Loading learn.aiml... done (0.05 seconds)
>>>

@cdwfs
Copy link

cdwfs commented Feb 6, 2017

Adding version="2.0" to tag made no difference.

I wouldn't expect it to make a difference with PyAIML, which (as I said) does not support the AIML 2.0 spec. I don't even think there was a working 2.0 draft of the spec when I last worked on PyAIML. Adding the version attribute would just be a handy way to indicate that 2.0-level interpreter functionality is required to parse the file.

Unique feature of learn.aiml is being recursive and I believe AimlParser.py is not able to parse recursively.

I assure you that AimlParser.py can definitely parse recursively; several other tags rely on this functionality. I'm virtually certain the problem is what I described above. See the _processLearn() function in Kernel.py, which is called when a <learn> element is encountered: it evaluates the element, treats the result as a filename, and attempts to load and learn() the contents of that file. This the behavior dictated in the 1.0.1 AIML spec, and there's no way it could possibly handle inline AIML correctly. I can't explain why it's failing the way it is, but I don't think the problem is with PyAIML; the problem is feeding (valid) 2.0 AIML data into a (valid) 1.0.1-level interpreter.

But I'm not capable to understand or fix the issue, I'm just guessing. You @cdwfs should fix it.

While I truly appreciate the continued interest in PyAIML, the fact is that I haven't worked on it in nearly ten years; while nothing is certain, I wouldn't count on any further updates from my end. But consider this: it was the first non-trivial Python project I wrote. With a bit of effort, it wouldn't take you long at all to learn as much Python as I knew when I wrote PyAIML!

@mertyildiran
Copy link
Author

@cdwfs OK. I will try to upgrade PyAIML to AIML 2.0 in near future. It would be much easier for you to fix it but never mind I will try. If I will be successful I'll send Pull requests to both of yours and this repository. Thanks for your attention! 👍 😄

@cdwfs
Copy link

cdwfs commented Feb 13, 2017

It would be much easier for you to fix it

I think you're overestimating how much I remember about either Python, AIML, or PyAIML after ~10 years; I would effectively be approaching a completely unfamiliar codebase at this point. I don't think it would be terribly easy for either of us :)

Is the AIML 2.0 spec fairly stable and well-supported at this point? I'd hate for you (or anybody) to put a lot of work into supporting a draft specification, and end up subtly incompatible with other interpreters.

@athuldevin
Copy link

friends i have developed support for learn tag can i share here

@creatorrr
Copy link
Owner

creatorrr commented Jul 22, 2017 via email

@athuldevin
Copy link

athuldevin commented Jul 22, 2017

https://github.com/athuldevin/learn

the complete pyaiml files and learn.aiml is available here
i have made changes to parser and kernel from pyaiml 0.9.0
changes made

ability to save bot predicates which set dynamically and restore also
added learn tag
changed previous learn to load
added eval tag

problem
if bot learn something to brain there is a problem in debugging output, not in response

also developed support for javascript tag but not included in this kernel because it require one additional package , if you like i will share

@mertyildiran
Copy link
Author

mertyildiran commented Jul 26, 2017

@athuldevin after a while I realized that learn.aiml of Steve Worswick is a little bit overrated. So recently I wrote this script which has superior capabilities then the combination of an AIML interpreter and learn.aiml file.

In general, state-of-the-art NLP techniques (like spaCy) pretty much made AIML redundant.

@athuldevin
Copy link

@mertyildiran can you say where should i go for learn more about advanced stuff like this i am a student

@11sm11
Copy link

11sm11 commented Mar 15, 2018

An easy way for the pyaiml bot to "learn" is to create a separate py "file writing" script that you send through args the information you want your ai to learn. Then reload the aiml file it wrote to. Example:
<category> <pattern>* ARE *</pattern> <template> OK, I will remember that <star index="1"/> are <star index="2"/>. <system>scripts/are_learning.py "<get name="name"/>" "<star index="1"/>" "<star index="2"/>"</system> <learn>learned.aiml</learn> </template> </category>

a short example of my are_learning.py file:
` name = sys.argv[1:]
star1 = name[1].upper()
star2 = name[2].upper()
xml = []
xml.append('')
xml.append('%s ARE %s' % (star1, star2))
xml.append('')
xml.append('That is true, %s told me.' % name[0])
xml.append('')
xml.append('')
xml.append('')
xml.append('')
xml.append('')

str = join(xml,'\n')

filename = "./learned.aiml"
with open(filename, 'r') as f:
  text = f.read()
text = text.replace('</aiml>', str)
with open(filename, 'w') as f:
  f.write(text)`

I hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants