1. lostagain
  2. Untitled project
  3. SuperSimpleSemantics

Overview

HTTPS SSH

SuperSimpleSemantics

Note; Please excuse the mess, we have just transferred from google code so our wikis and layout is a little messy/incomplete!

SuperSimpleSemantics is a system making it dead simple for anyone to host cross reference-able data.

To host SSS files, all you need to do is put some static text files on your server, as well as a static index file.

Or, for offline use, you can supply the file lists in a text file locally.

Or, data can be added straight in your code without relying on any external sources.

Once data is loaded, basic semantic queries can be run on it.

On a more technical level: SSS is a simple transitional n3-like system, only with the whole database folded so that endpoints arnt needed for cross referencing. Static text files and indexs are enough for anyones data to be accessible by any client.

This is the companion project to "The GreenFruitEngine". which is a web based GUI front end for this.

https://code.google.com/p/green-fruit-engine/

Requirements

  • Guava jar (at least version r09)
  • If you wish to use it with gwt, then also the gwt version of Guava
  • If used with GWT, GWT 2.6 is expected - early versions might still work, but you will need to manually comment out any code with a "@GwtIncompatible" annotation.

Note; For early versions of Android you might need to use the backport of Guava: http://mvnrepository.com/artifact/com.google.guava/guava-jdk5/16.0-rc1 (place this in your lib folder instead of the current main version)

Note; Currently the project as been tested to work both online (GWT or LibGDX) and with Desktop Java within "Processing". Android has not been tested, but should work. Feedback very welcome.

Principles

1 - Properties construct the object

Super Simple Semantics' basic principle is that properties essentially make the object. Take an apple. We recognise an apple as an apple due to its shape, the way it grows, the texture of its flesh, the taste, the colour, the smell. In other words: through its properties. We don't recognise an apple because we're born with an inherited knowledge of the concept of apple, and apples just happen to have these properties.

This is a little different from many other semantic systems where the object itself is central and all the properties of this specific object are stored together.

In SSS, this means that we don't specify the properties that an apple has, we say that 'all these things are coloured green' and 'all these things are fruit' and apple would be in both of these lists. SSS runs a query, and because it finds apple in both of these lists, it knows it's a green fruit.

This seems like a small difference, but it makes it far easier to cross reference objects when all the information you have, are some of its properties. We're now using a fruit example, but in the future it should make it much easier to find a specific construction material or anything else with a desired property.

And it does this all by simply by:

looking through the lists of queried properties (in this case, 'color=green' and 'fruit')

see which objects are in these lists

look if any of the objects appear on both lists.

2 - Many properties are inherited

Let's look back at the example of the 'Green fruit' query. It returned 'apple' there.

However, not all apples are green. Only Granny Smiths and Golden Delicious are. So the list of green coloured things does not contain 'apple' but 'Granny Smith' and 'Golden Delicious'.

Why doesn't it just return 'apple'? Because logically speaking, you're looking for green fruits. And it will tell you exactly which fruits are green. Not which fruits could be green. After all, if you painted things, everything could be green. As such, in this stage, we only want to return absolute results.

The SSS however does still know that Golden Delicious are apples, and thus fruits, because otherwise it would not be able to display Golden Delicious in its results.

3 - Anyone can contribute data

We want everyone to be able to contribute their knowledge to this system.

If you can upload a text-file to a website; you can contribute. Your server does not need to run any code, you don't need a special environment, any passive file hosting is good enough.

As such, the formatting of the list-files themselves are incredibly simple.

Future plans

The current system cannot deal yet with source reliability, factual and philosophical disagreements in properties and fuzzy definitions.

We have ideas for how to handle this, but that's not applicable in this stage.

Source reliability can be assured by giving people the option to choose the sources of their query (say, only .edu websites).

For factual disagreements we're thinking of adding a weighted value system, so the more sources agree with a specific object-property link, the clearer it is to the end-user.

Likewise with fuzzy definitions. We're using 'color=green' at the moment, but in the future we want the SSS to understand that 'color=green' is a color between wavelength 520 and 570 nm. This would be formatted as a text file stating 'Things between wavelength 520 and 570nm' and only containing 'green'.

example code

Using semantics purely in code;

                SuperSimpleSemantics.setup();
            String baseURI = "examples/DefaultOntology.n3#";

                //create a few nodes manually
                //(these would more normally be loaded from a *.ntlist file)
                //
                final SSSNode green = SSSNode.createSSSNode("green", "green",baseURI);
        final SSSNode color = SSSNode.createSSSNode("color",  "color",baseURI);
                final SSSNode grannysmith = SSSNode.createSSSNode("granny smith",  "granny smith",baseURI);
        final SSSNode fruit = SSSNode.createSSSNode("fruit",  "fruit",baseURI);
        final SSSNode apple = SSSNode.createSSSNode("apple",  "apple",baseURI);
        final SSSNode orange = SSSNode.createSSSNode("orange",  "orange",baseURI);

                //give the nodes some parent class's
        grannysmith.addParentClasses(apple);
        apple.addParentClasses(fruit);
        orange.addParentClasses(fruit);

        //refresh caches
        SSSNode.refreshAllCaches();

                //an example of how a triplet query would be done
                //Note; Triplet associations like "Color=Green" can be loaded from files, but isnt yet supported using the manual add method seen above
        //HashSet<SSSNode>  testresult = QueryEngine.getNodesWithProperty(color, green);

        //return all the nodes which are fruit 
                //Note; this will include "grannysmith" as that is a type of apple, and         apple is a type of fruit
        HashSet<SSSNode>  testresult = QueryEngine.getNodesWhichAre(fruit);

                //loop over to display the results in the log       
        Iterator<SSSNode> tri = testresult.iterator();

        while (tri.hasNext()) {

            SSSNode sssNode = (SSSNode) tri.next();

            Log.info("***_____PLabel: "+sssNode.getPURI());

        }

Loading from remote files;

      { 
                //straight away we set up the super simple semantics
             SuperSimpleSemantics.setup();

        //assign the file manager and other callbacks.
                //In this case, the callbacks will be GWT specific things for a webclient.
                //The FileManager is just an interface you supply that can "getText" from a specified location. This, naturally would be done in different ways depending on where this code is used.
                //
        //other then the file manager, these are optional callbacks to monitor progress as the semantic databases load or are searched
        SuperSimpleSemantics.setFileManager(new SpiffyFileManager());
        SuperSimpleSemantics.setGenericWaitFor( new GWTWaitForBrowserToUpdate());
        SuperSimpleSemantics.setGenericWaitForRepeating(new GWTWaitForRepeating());

        SuperSimpleSemantics.setLoadedRunnable(new Runnable() {         
            @Override
            public void run() {
                                //when the remote files are all loaded, trigger this
                postLoadActions();

            }
        });

                 //define a list of database's to load
                 ArrayList<String> trustedIndexs = new ArrayList<String>();
                 trustedIndexs.add("demo.ntlist");
                 trustedIndexs.add("DrWhosWho.ntlist");

                //Start some databases loading
                 SuperSimpleSemantics.loadIndexsAt(trustedIndexs);

        ...
       }

       protected void postLoadActions() {

        // the database is now all loads and you can query it as you wish
                // (see other example for how to do basic querys)


    }

A more complex example taken from [http://www.fanficmaker.com] which uses SSS to pick correct objects of various sorts that fit a given era.

For example, "weapon" with era "future" might give you a "ray gun" which it will use to generate its (very bad) stories.

      { 

//An example of creating and running a query based on an input string
//This is where most of the power can be expressed, 
//as you can use subquerys, ANDS and ORS as well as negatives.
//More examples of the types of words it currently understands are on
//The GreenFruitEngine project site.

String objecttype = "weapon"
String CURRENTERA = "future"

//Construct a query that returns all the objects of a given type which
//are either not era specific, or belong to the specified era.
String querystring =  "("+objecttype+" !(EraSpecific))  || ( "+objecttype+" UsedIn="+CURRENTERA+" )";

        //Create a queery object from the given string
    Query realQuery = Query.createQuerySafely(queryString);

        Log.info("realQuery-"+realQuery.getAsString());

        if (!realQuery.hasNoErrors()){
            Log.info("Query Had Errors!");
            runnable.run("Query Had Errors!");
        }


                //Run the query
                //It gets the result nodes and gives them to the "RunWhenDone"
                //which is a type of runnable you can define that takes SSSNodes

        QueryEngine.processQuery(realQuery, false, null, RunWhenDone);

      }