How to Set Up a Knowledge Base

Summary

A Knowledge Base is a collection of compiled rules and other knowledge definitions. It servers as the origin for Knowledge Sessions, where Facts meet Knowledge during the reasoning process.

Knowledge Package
A Knowledge Package incorporates knowledge definitions, most importantly rules but also rule flows. Constituents may come from several source types, processed by a Package Builder.
Knowledge Builder
A Knowledge Builder object accepts a selection of resources and produces a Collection of Knowledge Packages.
Knowledge Builder Configuration
An object of this class serves as a control panel for a Knowledge Builder, e.g., for setting the Java compiler or for adding operators.
Knowledge Base
A Knowledge Base is a repository of rules, processes and other ingredients of Knowledge Packages.
Knowledge Base Configuration
This acts as a control panel for a Knowledge Base, e.g., for selecting the assert behaviour or the event processing mode.
Setting up of a Knowledge Base begins with the creation (with or without a configuration) of a Knowledge Builder into which resources defining knowledge are fed for compilation. Then the Knowledge Base is created and receives the Knowledge Packages obtained from the Knowledge Builder.

Serializing Knowledge

Compiling knowledge resources into Knowledge Packages and the creation and charging of a Knowledge Base may be time-consuming. Therefore, serializing either Knowledge Packages or a finished Knowledge Base may be used to speed up a session start.

Source Code

Build and Execute

The following code snippet demonstrates the simple case of setting up a Knowledge Base from a single DRL file.

    // Compile a DRL file
    KnowledgeBuilder kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kBuilder.add( ResourceFactory.newFileResource( drlPath ), ResourceType.DRL );

    // Check for errors
    if( kBuilder.hasErrors() ){
        for( KnowledgeBuilderError err: kBuilder.getErrors() ){
	    System.err.println( err.toString() );
        }
        throw new IllegalStateException( "DRL errors" );
    }

    // Create the Knowledge Base
    KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();

    // Transfer compiled Knowledge Packages
    kBase.addKnowledgePackages( kBuilder.getKnowledgePackages() );
You can now create (stateful or stateless) Knowledge Sessions from the Knowledge Base.

Build and Serialize Knowledge Packages

Compiling resources into one or more Knowledge Packages which are then writted to a file is one way to fast-track a rule engine's start. The following method illustrates this with a single DRL file. For more than one file, simply add the all to the Knowledge Builder before you fetch the collective results.

    private void compilePackage( String drlPath, String pkgPath ) throws Exception {
        KnowledgeBuilder kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kBuilder.add( ResourceFactory.newFileResource( drlPath ), ResourceType.DRL );
        if( kBuilder.hasErrors() ){
            for( KnowledgeBuilderError err: kBuilder.getErrors() ){
                System.err.println( err.toString() );
            }
            throw new IllegalStateException( "DRL errors" );
        }
        OutputStream os = new FileOutputStream( pkgPath );
        ObjectOutputStream oos = new ObjectOutputStream( os );
        oos.writeObject( kBuilder.getKnowledgePackages() );
        oos.close();
    }

Create a Knowledge Base from Serialized Knowledge Packages

We'll now look at the creation of a Knowledge Base from the package file written in the previous section.

    public KnowledgeBase execPackage( String pkgPath ) throws Exception {
        KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(); 
        InputStream is = new FileInputStream( pkgPath );
        ObjectInputStream ois = new ObjectInputStream( is );
        @SuppressWarnings("unchecked")
        Collection kpkgs =
            (Collection) ois.readObject();
        ois.close();
        kBase.addKnowledgePackages( kpkgs );
        return kBase;
    }

You may want to include the package file in the application jar. In this case, the Input Stream for reading the package data might be set up like this:

    InputStream is =
        this.getClass().getResourceAsStream( pkgPathInJar );

Build and Serialize a Knowledge Base

Serializing a complete Knowledge Base is just a simple.

    private void compileRuleBase( String drlPath, String rbPath ) throws Exception {
        KnowledgeBuilder kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kBuilder.add( ResourceFactory.newFileResource( drlPath ), ResourceType.DRL );
        if( kBuilder.hasErrors() ){
            for( KnowledgeBuilderError err: kBuilder.getErrors() ){
                System.err.println( err.toString() );
            }
            throw new IllegalStateException( "DRL errors" );
        }
        KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(); 
        kBase.addKnowledgePackages( kBuilder.getKnowledgePackages() );
        OutputStream os = new FileOutputStream( rbPath );
        ObjectOutputStream oos = new ObjectOutputStream( os );
        oos.writeObject( kBase );
        oos.close();
    }

Compilation Errors

Always check for errors resulting from the knowledge build process. If you omit this check, an exception will be thrown during a later step, but you will not know what went wrong.

Errors are detected by the Drools parser and by the Java compiler as it precesses the Java code generated by the parser. For the latters, it might be necessary to inspect the generated Java source code to see what went wrong, and where. You can tell the Knowledge Builder to write generated code to disk, and the following code snippet shows how you do it.

    File tmpDir = new File( "/tmp/drools-build" );
    SingleValueKnowledgeBuilderOption ddOption = DumpDirOption.get( tmpDir );
    KnowledgeBuilderConfiguration kbConfig =
        KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
    kbConfig.setOption( ddOption );
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder( kbConfig );