New instances in the RHS

2 views
Skip to first unread message

Chris G.

unread,
Dec 22, 2008, 8:49:04 AM12/22/08
to fuxi-discussion
One of the things I'd like to be able to do is express an N3 rule
that, when true, posits a new instance. From what I've been able to
tell (I'm very new to the RDF world), a rule like this should create a
new instance of an "Inference" class:

{ ?det a m:Detection.
... other conditions ...
} => {
?det has m:inference [ a m:Inference; has m:inference_name ?
infName ].
}.

Or a rule like this:

{ ?det a m:Detection.
... other conditions ...
} => {
@forSome :inf.
:inf a m:Inference.
:inf has m:inference_name ?newInfName
}.

Both work fine when the rule only has to fire once. When it fires
more than once, instead of creating a new instance for each firing, it
continually appends clauses to the first instance, as though a rule
can only have one new instance associated with it ever. The N3
results look like:

[ a _3:Inference;
_3:inference_name "GroupADetection",
"GroupBDetection"].

When it should look like:

[ a _3:Inference;
_3:inference_name "GroupADetection"].
[ a _3:Inference;
_3:inference_name "GroupBDetection"].

Am I doing anything wrong here? Should FuXi be able to handle
something like this, or am I misinterpreting what the tool is for?

Here's my test code:

------------------------------
store = plugin.get('IOMemory',Store)()
store.open('')
ruleStore = N3RuleStore()
ruleGraph = Graph(ruleStore)
ruleGraph.parse(open('masf_rules.n3'),format='n3')
factGraph = Graph(store)
factGraph.parse(open('masf_facts.n3'),format='n3')

count = 0
while count < len(newFacts):
fact = newFacts[count]
factGraph.add(fact)
count = count + 1

deltaGraph = Graph(store)
network = ReteNetwork(ruleStore,
initialWorkingMemory=generateTokenSet
(factGraph),
inferredTarget = deltaGraph)

cg = network.closureGraph(factGraph, store=ruleStore)
print cg.serialize(format="n3")
-----------------------------

Note that "newFacts" is an array of RDF triples entered earlier
designed to fire the above rule twice.

Thanks for any assistance!

Chris G.

Chimezie

unread,
Dec 22, 2008, 10:38:38 PM12/22/08
to fuxi-discussion

On Dec 22, 8:49 am, "Chris G." <imagine...@gmail.com> wrote:
> One of the things I'd like to be able to do is express an N3 rule
> that, when true, posits a new instance.  From what I've been able to
> tell (I'm very new to the RDF world), a rule like this should create a
> new instance of an "Inference" class:
>
> { ?det a m:Detection.
>   ... other conditions ...} => {
>
>   ?det has m:inference [ a m:Inference; has m:inference_name ?
> infName ].
>
> }.
>
> Or a rule like this:
>
> { ?det a m:Detection.
>   ... other conditions ...} => {
>
>   @forSome :inf.
>   :inf a m:Inference.
>   :inf has m:inference_name ?newInfName
>
> }.

Yes, each time this rule is fired, it should assert a statement about
a new m:Inference instance.

> Both work fine when the rule only has to fire once.  When it fires
> more than once, instead of creating a new instance for each firing, it
> continually appends clauses to the first instance, as though a rule
> can only have one new instance associated with it ever.  The N3
> results look like:
>
> [ a _3:Inference;
>         _3:inference_name "GroupADetection",
>             "GroupBDetection"].
>
> When it should look like:
>
> [ a _3:Inference;
>         _3:inference_name "GroupADetection"].
> [ a _3:Inference;
>         _3:inference_name "GroupBDetection"].
>
> Am I doing anything wrong here?  Should FuXi be able to handle
> something like this, or am I misinterpreting what the tool is for?

It is supposed to be able to handle this. I.e., every time a rule
fires that has BNodes in its consequent, it is supposed to introduce a
new set of BNode labels. Can you create a stand-alone unit test that
replicates the problem (with the facts/rules embedded)? Something
like:

import unittest, os, time, sys
from cStringIO import StringIO
from rdflib import RDF
from FuXi.Rete import *
from FuXi.Rete.RuleStore import N3RuleStore
from FuXi.Rete.Util import renderNetwork,generateTokenSet
from FuXi.Horn.PositiveConditions import Uniterm,
BuildUnitermFromTuple
from FuXi.Horn.HornRules import HornFromN3

N3_PROGRAM=\
"""
@prefix m: <http://example.com/#>.
{ ?det a m:Detection; m:name ?infName }
=> { ?det has m:inference [ a m:Inference; m:inference_name ?
infName ].
}. """

N3_FACTS=\
"""
.....
"""

class ExistentialInHeadTest(unittest.TestCase):

def testExistentials(self):
store = plugin.get('IOMemory',Store)()
store.open('')
ruleStore = N3RuleStore()
ruleGraph = Graph(ruleStore)
ruleGraph.parse(StringIO(N3_PROGRAM),format='n3')
factGraph = Graph(store)
factGraph.parse(StringIO(N3_FACTS),format='n3')

.. setup factGraph .factGraph..

deltaGraph = Graph(store)
network = ReteNetwork(ruleStore,
initialWorkingMemory=generateTokenSet
(factGraph),
inferredTarget = deltaGraph)
self.failUnless(len(network.inferredFacts.subjects
(predicate=RDF.type,

object=URIRef('...#Inference')))>1,
'each rule firing should introduce a new
BNode!')
cg = network.closureGraph(factGraph, store=ruleStore)
print cg.serialize(format="n3")

if __name__ == "__main__":
unittest.main()


-- Chimezie

Chris G.

unread,
Dec 23, 2008, 10:07:11 AM12/23/08
to fuxi-discussion
Here is a stand-alone unit test. Hope that it's helpful :D

---------------------------------
import unittest, os, time, sys
from cStringIO import StringIO
from rdflib import RDF, URIRef
from FuXi.Rete import *
from FuXi.Rete.RuleStore import N3RuleStore
from FuXi.Rete.Util import renderNetwork, generateTokenSet
from FuXi.Horn.PositiveConditions import Uniterm,
BuildUnitermFromTuple
from FuXi.Horn.HornRules import HornFromN3
from rdflib import plugin
from rdflib.store import Store
from rdflib.Graph import Graph

N3_PROGRAM=\
"""
@prefix m: <http://example.com/#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

{ ?det a m:Detection.
?det has m:name ?infName.
} => {
?det has m:inference [ a m:Inference; m:inference_name ?infName ].
}.
"""

N3_FACTS=\
"""
@prefix m: <http://example.com/#>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

m:Detection a rdfs:Class.
m:Inference a rdfs:Class.

:det1 a m:Detection.
:det1 m:name "Inference1".

:det2 a m:Detection.
:det2 m:name "Inference2".
"""

class ExistentialInHeadTest(unittest.TestCase):

def testExistentials(self):
store = plugin.get('IOMemory',Store)()
store.open('')
ruleStore = N3RuleStore()
ruleGraph = Graph(ruleStore)
ruleGraph.parse(StringIO(N3_PROGRAM),format='n3')
factGraph = Graph(store)
factGraph.parse(StringIO(N3_FACTS),format='n3')

deltaGraph = Graph(store)
network = ReteNetwork(ruleStore,
initialWorkingMemory=generateTokenSet
(factGraph),
inferredTarget = deltaGraph)

inferenceCount = 0
for inferredFact in network.inferredFacts.subjects
(predicate=RDF.type,

object=URIRef('http://example.com/#Inference')):
inferenceCount = inferenceCount + 1

self.failUnless(inferenceCount > 1, 'Each rule firing should
introduce a new BNode!')

cg = network.closureGraph(factGraph, store=ruleStore)
print cg.serialize(format="n3")


if __name__ == "__main__":
unittest.main()


Chimezie

unread,
Dec 25, 2008, 3:41:46 PM12/25/08
to fuxi-discussion
BTW, I've committed this unit test as well as a fix for it. Thanks,
and happy holidays.

-- Chimezie
Reply all
Reply to author
Forward
0 new messages