Skip to content

Reasoning for the Semantic Web with CLIPS

There is a pressing need in the Semantic Web community of exploiting data semantics coming from different hub contexts (e.g. geographic information, personal profiles, place and time) and to put that knowledge to work for ad hoc functionalities and services. The ontological content presents in data silos such as http://data.gov.uk, or http://ordnancesurvey.co.uk shall be firstly aligned to a common schema that can be then used to design functionalities and further knowledge bases that contains more personalised concepts such as: good locations for a meal, interesting news for me, or time schedule I need to know.

In classic AI rules based systems are a natural way to express operative knowledge about a domain (even an applicative one) and extend in expressive power classical representational frameworks such as DL ontologies. Reasoning with RDF instances that are distributed can be taunting and the integration of present tools can be tricky. An efficient tool for reasoning with rules that benefits of years of experience and a very efficient RETE implementation is CLIPS. Integrating a CLIPS engine with an existing application is quite easy. Java has its own implementation of CLIPS called Jess, while for the other languages a bridging is provided.

For python application a module called pyclips provides access to a CLIPS engine along with a two/way interaction python/CLIPS. It is possible to load and create rules and facts from python, run a CLIPS program and allow CLIPS to call python functions as well. The installation of pyclips is fairly painless (donwload the installing script, configure it and run it; it will automatically download the right version of CLIPS and will install the python module for you).

In order to use the CLIPS engine from python we need to import the clips module and reset it:

import clips
clips.Reset()

Then we can assert new facts in the environment:

clips.Assert('(contains A B)')

and new rules:

clips.BuildRule('subclass , '(subclass ?a ?b) (subclass ?b ?c)', 'assert((subclass ?a ?c))', 'RDFS subclass transitivity rule')

CLIPS has also the capability to define functions and classes. Functions can be called in order to make complex calculations or to create a side effect on the engine with the assertion and retraction of facts.:

clips.BuildFunction( 'log', '?message' , '(open "error.log" logdata "a") (printout logdata ?message) (close)' , 'log error message on a log file')

And finally we can register python functions to the CLIPS engine and call them from CLIPS rules:

def log(message):
log.debug(message)

clips.RegisterPythonFunction(log)
clips.Eval('(python-call log \'error message'\)')

Within EnAKTing such a solution has been used for reasoning over topologies, creating a knowledge base of rules that encoded the topology and then letting the engine to simplify it to a canonical form.

The problem to solve was to simplify the alignment between two topologies. The topologies we work on are peculiar ones, they are in fact hierarchical partition of a territory (in this case the UK). This particular condition allows us to assume that a particular region is equal to the union of all of the subregions it contains (i.e. A = B1 U B2 U ..U Bn). The alignment between the NUTS topology and the ONS topology provides three issues:

  1. The alignment is not 1:1, that means that sometimes bigger statistical regions are spatially equivalents, sometimes they are not
  2. The alignments available from the European statistical website are provided for the smallest subregions only (i.e. NUTS level 3), whereas nothing is said about spatial equivalence of upper regions
  3. An alignment between the leafs of this topology leaves eventual containments between regions hard to find

Using pyclips the two topologies are extracted from the triplestore via SPARQL:

SELECT ?super ?sub WHERE {
?super os:contains ?sub
}

and then the structure is reorganised in order to collect for each region (top) all of its subregions (bottoms). For example, the NUTS region UKH32 (Thurrock) has twenty subregions within the ONS hierarchy:

  • 00KGMX Aveley and Uplands
  • 00KGMY Belhus
  • 00KGMZ Chadwell St Mary
  • 00KGNA Chafford and North Stifford
  • 00KGNB Corringham and Fobbing
  • 00KGNC East Tilbury
  • 00KGND Grays Riverside
  • 00KGNE Grays Thurrock
  • 00KGNF Little Thurrock Blackshots
  • 00KGNG Little Thurrock Rectory
  • 00KGNH Ockendon
  • 00KGNJ Orsett
  • 00KGNK South Chafford
  • 00KGNL Stanford East and Corringham Town
  • 00KGNM Stanford-le-Hope West
  • 00KGNN Stifford Clays
  • 00KGNP The Homesteads
  • 00KGNQ Tilbury Riverside and Thurrock Park
  • 00KGNR Tilbury St Chads
  • 00KGNS West Thurrock and South Stifford

and a rule in CLIPS is created in order to simplify eventual topology expressions including the above listed ONS regions. The code in pyclips is the following:
for top , bottoms in structure.iteritems():
for b in bottoms:
f = clips.Assert('(contains %s %s)'%(top,b))
r = clips.BuildRule('reduce_%s'%ri , ''.join(['(contains ?t&~%s %s)'%(top,b) for b in bottoms]),
'(assert (contains ?t %s)) (python-call acontains ?t %s)'%(top,top),
'reducing rule')

and the rule generated for the above case is the following:

(defrule MAIN::reduce_769 "reducing rule"
(contains ?t&~UKH32 00KGNL)
(contains ?t&~UKH32 00KGNR)
(contains ?t&~UKH32 00KGNM)
(contains ?t&~UKH32 00KGNK)
(contains ?t&~UKH32 00KGNF)
(contains ?t&~UKH32 00KGNG)
(contains ?t&~UKH32 00KGNE)
(contains ?t&~UKH32 00KGNA)
(contains ?t&~UKH32 00KGMZ)
(contains ?t&~UKH32 00KGNN)
(contains ?t&~UKH32 00KGNP)
(contains ?t&~UKH32 00KGNJ)
(contains ?t&~UKH32 00KGNH)
(contains ?t&~UKH32 00KGNC)
(contains ?t&~UKH32 00KGND)
(contains ?t&~UKH32 00KGNB)
(contains ?t&~UKH32 00KGMY)
(contains ?t&~UKH32 00KGMX)
(contains ?t&~UKH32 00KGNQ)
(contains ?t&~UKH32 00KGNS)
=>
(assert (contains ?t UKH32))
(python-call acontains ?t UKH32))

This rule will match a region that contains all the subregions that UKH32 contains (but not UK32 itself). If so it will assert a new relation in the knowledge base saying that such region contains UKH32 as well.
A further rule will cover the scenario where two regions contains the same subregions and only those. In fact, in this case  the engine will infer that A contains B AND B contains A:
clips.RegisterPythonFunction(aequals)
clips.RegisterPythonFunction(acontains)

clips.BuildRule('symmetry',
'?f1 <- (contains ?a ?b) ?f2<-(contains ?b ?a)' ,
'(retract ?f1) (retract ?f2) (assert (spatially_equal ?a ?b) (spatially_equal ?b ?a)) (python-call aequals ?a ?b)',
'symetry reducing rule')

Once the topology has been converted to a CLIPS program the only thing to do is to run the program and the CLIPS engine will call the callback functions aequals and acontains every time it simplify an expression in accordance with the rules.

clips.Run()

Gianluca Correndo

Research fellow at ECS, University of Southampton

The author can be contacted at mailto:gc3 < at > ecs.soton.ac.uk

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*