Limitations, optimizations and workarounds

This framework is still under development. At the current stage there are a few technical limitations regarding the Wisdom class

  1. It is not appropriate to use one single Wisdom object to parse a text longer than ~20 MB. There is however no limit on the number of Wisdoms that can be created (except from the total amount of RAM). The amount of text that can be fed to a Wisdom will be further increased in the next versions.
  2. Limitations about matching sentences.
  3. Retrieving information can be slow if the text has been parsed incorrectly or the question requires a lengthy inference to be answered.

Asking the same question to multiple Wisdoms

A text can be split into multiple wisdoms. Consider for example the text:

David goes to the cinema to see a movie. Anna travels to Germany for
business.

This text can be read by two different Wisdoms, and then the answers can be joined together using join_answers():

from NLUlite import ServerProxy, Wisdom, join_answers

server = ServerProxy()
wisdom1 = Wisdom(server)
wisdom2 = Wisdom(server)

wisdom1.add('David goes to the cinema to see a movie')
wisdom2.add('Anna travels to Germany for business')

question = 'who goes where'

# Ask the question
answers1 = wisdom1.ask(question)
answers2 = wisdom2.ask(question)
answers = join_answers([answers1, answers2])
print answers.comment()
for item in answers.elements() :
    print item.comment()

The joined answer is automatically sorted according to the answer.weight, and the output is:

the answer is a list

person: David
where: the cinema
David goes to the cinema to see a movie.

person: Anna
where: Germany
Anna travels to Germany for business.

The only limitations of this approach are the following:

  1. Questions that require the intersection of two answers (‘who is tall and likes pizza’) will be answered only if both the answers are in the same Wisdom. While answers can be joined, the knowledge in each Wisdom class is separated.

    This is a limiting issue of version 0.1.0 and it will be corrected from version 0.2.0.

  2. A Horn clause ‘if A and B then C’ will only work if A and B are in the same Wisdom

Tenses and modal verbs

While tenses and modal verbs are parsed and saved along with the rest of the elements, they have no role when answering a question. Therefore, in the example:

from NLUlite import ServerProxy, Wisdom, join_answers

server = ServerProxy()
wisdom = Wisdom(server)

wisdom.add('David might go to a pub. Tim already went there.')
answer=wisdom.ask('who will go to a pub')
print answer.comment()
for item in answer.elements():
    print item.comment()

the answer will be:

the answer is a list

person: David
David might go to a pub.

person: Tim
Tim already went there.

The reason for this behavior is twofold:

  1. NLUlite is a database system, its job is to give the largest possible list of results that matches the question.
  2. The time at which a sentence takes place is not a simple function of the tense. Modal verbs are even harder to implement.

Optional tense management will be implemented from version 0.2.0.

Set Timeout

The class WisdomParameters allows a finer tuning for the Wisdom class. For example, it is possible to set a timeout for the Wisdom.ask() method:

from NLUlite import ServerProxy, Wisdom, WisdomParameters

server = ServerProxy()
wisdom = Wisdom(server)

wp = WisdomParameters()
wp.set_timeout('5')        # Number of seconds for the timeout

wisdom.set_wisdom_parameters(wp)

With this configuration, the Wisdom.ask() method will try to search for an answer after 5 seconds. The default configuration for the timeout is 10 seconds.

Notice that - even with this configuration - the answer can take slightly longer than 5 seconds.

Saving memory

A Wisdom object spends additional memory for storing the values of the parsed sentences. These values are only important when saving to a file.

If you want a wisdom just for loading files and answering questions, you can disable storing these additional values:

from NLUlite import ServerProxy, Wisdom, WisdomParameters

server = ServerProxy()
wisdom = Wisdom(server)

wp = WisdomParameters()
wp.set_add_data('false')  # Additional data is not stored for being
                          # saved into a new file, saving some memory

wisdom.set_wisdom_parameters(wp)

This configuration results in saving about 25% of memory. On the other hand, all the files you save with this configuration will be empty.

Skip inference

Inference can take time. If you want just a “factual” database, you can disable it

from NLUlite import ServerProxy, Wisdom, WisdomParameters

server = ServerProxy()
wisdom = Wisdom(server)

wp = WisdomParameters()
wp.set_skip_solver('true')
wisdom.set_wisdom_parameters(wp)

This configuration results in a faster reply, but all the inference rules you submit will be ignored.

Compulsory inference

The standard configuration of the system searches for a direct answer to your question before using the inference rules. If this answer is found, inference is skipped altogether.

One example can be:

from NLUlite import ServerProxy, Wisdom

server = ServerProxy()
wisdom = Wisdom(server)

wisdom.add('Socrates is a man. If someone is a man he is mortal.')

answers = wisdom.ask("is socrates a mortal")
answer_comment = answers.comment()
item_comment   = ""
for item in answers.elements():
    item_comment += item.comment()

print answers.comment()
for item in answers.elements() :
    print item.comment()

and the output would be:

Yes

Socrates is a man.

The answer is correct but inference was not used. The correct answer is barely a coincidence of “man” and “mortal” being synonyms: The database finds an answer and inference is skipped.

If you wish to implement inference anyway you must use the WisdomParameters.do_solver() method as in the following:

from NLUlite import ServerProxy, Wisdom, WisdomParameters

server = ServerProxy()
wisdom = Wisdom(server)

wp= WisdomParameters()
wp.set_do_solver('true') # Rules are always applied
wisdom.set_wisdom_parameters(wp)

wisdom.add('Socrates is a man. If someone is a man he is mortal.')

answers = wisdom.ask("is socrates a mortal")
answer_comment = answers.comment()
item_comment   = ""
for item in answers.elements():
    item_comment += item.comment()

print answers.comment()
for item in answers.elements() :
    print item.comment()

which gives the correct output as a second answer:

Yes

Socrates is a man.

Socrates is a man.+ If someone is a man he is mortal.