Hello World

For the last couple of weeks, I’ve been working on something very basic: getting Alef to accept a command ( say hello ), and respond by… saying hello. This exercises all the basic layers of natural language processing. And having a mechanism to give commands supports bootstrapping and testing.

Yesterday, it finally worked. The goal throughout is to implement in the most minimal way possible, so naturally, a lot of it is hacked and will have to change.

The highlights of the current implementation are the parser, task management, and semantic-object mapping.

Parser

The parser is quite minimal as yet. It runs in several phases: tokenising the input (basic); building a phrase tree (hacked); building a semantic graph.

I’ve plugged in Wordnet (the JWI library from MIT). This is overkill (and possibly not helpful) but I like having the rich dictionary at hand. Wordnet synsets directly correspond to Alef concepts (expressed in RDF).

The parser must take the phrase tree (RDF) and convert it into a semantic graph (RDF). This is done using a pattern: an example RDF graph showing how a verb phrase relates to the required semantic graph.

The major problem is how to acquire these patterns, i.e: how they can be learned — since I don’t want to hard code them all, and I want Alef to be able to learn new constructions whenever they show up.

Task Management

The ‘Brain’ class in Alef is primarily a task manager. It has a single worker thread (more would be possible, but it complicates use of RDF and I don’t think multi-threading is of much help right now) and a list of tasks. Tasks can be long running, short running, or episodic — they stay in the list until they finish or are terminated.

The brain simply finds the first task in the list that has work to do, and calls its ‘work’ method. The Task is expected to do a small slice of work and then return, in order to give other Tasks a chance to do their stuff. It shouldn’t do anything that might hang, obviously.

Semantic Object Mapping

In order to actually do something — like say ‘hello’ — it’s necessary to jump from a semantic graph expressed in RDF (description of an action) to Java code that does the described action. And that Java code may need to interact with other Java objects which also correspond to conceptual objects in the semantic graph (for example, Files).

So we have a set of Java objects that are ‘live’ instances of RDF objects, and we need a way to instantiate them and to keep track of them while they’re in use.

To instantiate them, we introduce factory classes. Each module can plug in its own factory to handle its own areas of expertise.

The singleton SemanticObjectMapping is responsible for mapping from RDF objects to Java objects and calling factories to instantiate new objects as required. WeakReferences are used so Java objects can be discarded when they’re not in use.

Aspirationally, it would be neat if every Java object in the system had an RDF model, could be inflated and persisted to RDF, and interacted with via RDF.

Next Steps

Having done a lot of work on the core classes, the Bug and Mouse models are broken (well, they were broken before that, now they’re worse broken). I’d like to get the Bug running again, which will probably suggest some more refinement to the framework.

After that, I think it’ll be time to work on bootstrapping the NLP.

Published by Catherine Griffin

I write fantasy novels.

Leave a comment

Design a site like this with WordPress.com
Get started