Tuesday, 13 November 2012

An example of what can be done with Terms.

Terms is a production system. With it, you define words, and use the words to produce sentences and rules, that you add to the knowledge base. Terms extracts consecuences from those sentences and rules, and adds them to the knowledge base. Then you query the knowledge base. The knowledge base resides in a RDBMS.

I think the systax of Terms is intuitive enough that that I can give some code examples without going into much detail.

Almost everything in Terms are words. Words have types, and those types are themselves words. Facts are made out of words, and are themselves words. Only rules (and definitions of words) are not words. You can use Python in the rules, but I won’t touch on that here.

This means that we only need first order variables (ranging over words) to cover all Terms constructs with the exception of rules. I will give an example of this.

To start with, we define a word she of type thing:

she is a thing.

Then we define 2 verbs (2 words of type verb), wants and gets:

wants is exists, what a word.
gets is exists, what a word.

With these words, we can make facts shuch as (wants she, what <some word>).

Let’s make some more words, so that she can want/get things:

a fruit is a thing.
this-banana is a fruit.
eats is exists, what a fruit.

Now we can make a fact such as (eats she, what this-banana).

Now we introduce a rule that expresses that she always gets what she wants:

(wants she, what Word1)
->
(gets she, what Word1).

Now, if we say that she wants this banana:

(wants she, what this-banana).

We obtain that she gets it:

(gets she, what this-banana)?
true

And also if she wants a verb, or a noun, or a number, or a fact...:

(wants she, what fruit).
(gets she, what fruit)?
true

(wants she, what eats).
(gets she, what eats)?
true

(wants she, what number).
(gets she, what number)?
true

(gets she, what 42)?
false

(wants she, what 42).
(gets she, what 42)?
true

(wants she, what (eats she, what this-banana)).
(gets she, what (eats she, what this-banana))?
true

Then you can do something like:

(gets she, what (Exists1))
->
(Exists1).

To obtain that:

(eats she, what this-banana).

I don’t think that you can do that easily in other logic systems. Am I wrong?

Wednesday, 17 October 2012

Announcing Terms

This post is to announce the release of Terms, a knowledge store written in Python. Its main selling point would be the language it provides to express knowledge, that, in my opinion, is very simple and at the same time very powerful.

Wednesday, 15 December 2010

A social network with nl, part 1

This is meant to be the first of a series of posts in which I will develop the bussiness logic of a social networking application, implemented as an nl ontology. The application might be, for example, a social web site, though the user interface, and its bindings to the nl backend, (the views and the controllers, if we follow the MVC paradigm) will not be developed here.

In this application the users will correspond to objects in the knowledge base. They will be able to have different kinds of relationships among them, and with other kinds of things, and this relations will also be reflected in the knowledge base. They will as well be able to perform actions, which may have effects on their relationships, in ways determined by our ontology.

In this first part I will design the way the nl backend will interface with the controllers. This is to say, the way the users’ input will be translated into nl. In general, this will take three basic steps:

  • In the first step, the controller will translate the request from the user into an nl sentence with the form “such user wants to do such thing now”, and will enter this sentence into nl’s knowledge base.
  • In the second step, the knowledge base will be extended to all it’s logical consecuences.
  • And in the third step, the kb will be queried for a sentence with the form “such user does such thing now”. If it founds it there (i.e., if this second sentence was entailed by the one entered in the first step), the controller will trigger the action that the user requested.

So, lets code this. First we need to import a couple of classes from nl

>>> from nl import Thing, Exists, Fact

We now define two subclasses of Thing, whose instances will denote users and content items in the sentences that we will later put into the kb.

>>> class Person(Thing):
...     """ A person is a thing """
>>> class Content(Thing):
...     """ A content item is a thing """

The Content class may be further subclassed to provide for different types of content: images, articles, etc. Let’s just add images as an example:

>>> class Image(Content):
...     """ An image is a content item """

We now define a primitive verb Lives with the only constraint that sentences built with it need to have a Person instance as subject. We will then extend this verb to express any action or condition or relation that can affect people. Later on, this primitive verb will be useful to make statements about all those verbs as a whole.

>>> class Lives(Exists):
...     """ People can do things and relate to other things """
...     subject = Person

We might extend Lives to produce more specific verbs; for example, we might add a verb to the effect that people can view content items:

>>> class Views(Lives):
...     """ People can view content items """
...     mods = {'what': Content}

With what we have so far, we might be able to build sentences asserting that users do things. Let’s see an example of how would this be accomplished, in which we have a user John, a picture img1, and we say that John views img1:

>>> john = Person('john')
>>> img1 = Image('img1')
>>> f1 = Fact(john, Views(what=img1), 'now')

What we are doing with these instantiations is building sentences, that would be understood as “john is a person”, “img1 is an image”, and “John views img1 now”. Note that we are only building them, and not entering them into nl’s knowledge base (we will be doing that further down).

Finally, we need some kind of permission system. We want to express that certain people can (are allowed to) do certain things, and that people may want things to happen. For this purpose we define two verbs, that take a Person instance as subject and a Lives instance (i.e., a predicate) as a modifier:

>>> class Can(Lives):
...     """ People can do things """
...     mods = {'what': Lives}
>>> class Wants(Lives):
...     """ People want things to happen """
...     mods = {'to': Lives,
...             'who': Person}

With this, we may form sentences such as “John wants to view img1”, like This:

>>> f2 = Fact(john, Wants(who=john, to=Views(what=img1)), 'now')

With all this in place, we can add a rule to express that, if someone wants to do something at a certain time, and can do it, he simply does it.

>>> from nl import Rule, Instant, Duration, During
>>> r1 = Rule([
...   Fact(Person('P1'), Wants(who=Person('P1'), to=Lives('L1')), Instant('I1')),
...   Fact(Person('P1'), Can(what=Lives('L1')), Duration('D1')),
...   During('I1', 'D1'),
...   ],[
...   Fact(Person('P1'), Lives('L1'), Instant('I1'))])

As it is explained in nl’s documentation, an Instant denotes a point in time, A Duration denotes an interval of time, and During('I1', 'D1') states a condition that is True if the instant “I1” is within the bounds of the interval of time “D1”.

Now, we can enter into the system a sentence such as the above f2, and, if there is also a sentence (lets call it f3) asserting that he (John) can view img2, we will have a sentence such as the above f1 entailed by the other two (f2 and f3). We can imagine that f2 is entered into the knowledge base when the user identified as “John” clicks on a link that points to img1, and that f3 is in the knowledge base because the owner of img1 has wanted it to be there (as we shall develop in a later post). Let’s try it:

>>> f3 = Fact(john, Can(what=Views(what=img1)), Duration(start='now'))

We have to enter these sentences into the knowledge base:

>>> from nl import kb
>>> kb.tell(r1, john, img1, f2, f3)

To get entailments we need to extend the knowledge base. Without extending it, we only have what we have entered (note that we have not entered f1):

>>> kb.ask(Fact(john, Wants(who=john, to=Views(what=img1)), 'now'))
True
>>> kb.ask(Fact(john, Can(what=Views(what=img1)), Duration(start='now')))
True
>>> kb.ask(Fact(john, Views(what=img1), 'now'))
False

However, if we extend the knowledge base, we actually get that John views img1:

>>> kb.extend()
1
>>> kb.ask(Fact(john, Views(what=img1), 'now'))
True

Now, the reason that leads me to think that all this may be remarkable is that there is only a first order theory behind nl, but the “L1” logical variable in the “r1” rule has the “form” of (though it is not) a second order variable. We can, in fact, use variables that apparently have an arbitrarily high order, to say things like “thinks that wants to view”. I say it has the form of a secon order variable because we might use is like this: Lives('L1')(what=Content('C5'))

Thursday, 30 September 2010

nl, a python library for logic programming

I am in the proccess of releasing a first version of nl, an open source python library for logic programming. The software is in a fairly advanced state of development, perhaps to the point of being usable, and its documentation is in a state which I believe may allow interested readers to judge its value. So, the purpose of this post is to gather feedback from anyone who may care to visit the provided links.