My favorites | Sign in
Project Logo
Project hosting will be READ-ONLY Wednesday at 8am PST due to brief network maintenance.
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
"""
This section defines Horn rules for RIF Phase 1. The syntax and semantics
incorporates RIF Positive Conditions defined in Section Positive Conditions
"""
from PositiveConditions import *
from rdflib import Variable, BNode, URIRef, Literal, Namespace,RDF,RDFS
from rdflib.Graph import Graph
def ExtractVariables(clause):
pass

Comment by chimezie, Dec 20, 2008:
Now horn clauses can be trivially created from N3 
def HornFromN3(n3Stream):
from FuXi.Rete.RuleStore import SetupRuleStore
store,graph=SetupRuleStore(n3Stream)
store._finalize()
return Ruleset(n3Rules=store.rules,nsMapping=store.nsMgr)

class Ruleset(object):
"""
Ruleset ::= RULE*
"""
def __init__(self,formulae=None,n3Rules=None,nsMapping=None):
from FuXi.Rete.RuleStore import N3Builtin
self.nsMapping = nsMapping and nsMapping or {}
self.formulae = formulae and formulae or []
if n3Rules:
#Convert a N3 abstract model (parsed from N3) into a RIF BLD
for lhs,rhs in n3Rules:
allVars = set()
for ruleCondition in [lhs,rhs]:
for stmt in ruleCondition:
if isinstance(stmt,N3Builtin):
ExternalFunction(stmt,newNss=self.nsMapping)
# print stmt;raise
allVars.update([term for term in stmt if isinstance(term,Variable)])
body = [isinstance(term,N3Builtin) and term or
Uniterm(list(term)[1],[list(term)[0],list(term)[-1]],
newNss=nsMapping) for term in lhs]
body = len(body) == 1 and body[0] or And(body)
head = [Uniterm(p,[s,o],newNss=nsMapping) for s,p,o in rhs]
head = len(head) == 1 and head[0] or And(head)
self.formulae.append(Rule(Clause(body,head),declare=allVars))

def __iter__(self):
for f in self.formulae:
yield f

class Rule(object):
"""
RULE ::= 'Forall' Var* CLAUSE

Example: {?C rdfs:subClassOf ?SC. ?M a ?C} => {?M a ?SC}.

>>> clause = Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> Rule(clause,[Variable('M'),Variable('SC'),Variable('C')])
Forall ?M ?SC ?C ( ?SC(?M) :- And( rdfs:subClassOf(?C ?SC) ?C(?M) ) )

"""
def __init__(self,clause,declare=None,nsMapping=None):
self.nsMapping = nsMapping and nsMapping or {}
self.formula = clause
self.declare = declare and declare or []

def n3(self):
"""
Render a rule as N3 (careful to use e:tuple (_: ?X) skolem functions for existentials in the head)

>>> clause = Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> Rule(clause,[Variable('M'),Variable('SC'),Variable('C')]).n3()
u'{ ?C rdfs:subClassOf ?SC .\\n ?M a ?C } => { ?M a ?SC }'

"""
return u'{ %s } => { %s }'%(self.formula.body.n3(),
self.formula.head.n3())
# "Forall %s ( %r )"%(' '.join([var.n3() for var in self.declare]),
# self.formula)

def __eq__(self,other):
return hash(self.formula)==hash(other.formula)

def __hash__(self):
"""
>>> a=Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> b=Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> d=set()
>>> d.add(a)
>>> b in d
True
>>> hash(a) == hash(b)
True

"""
return hash(self.formula)

def __repr__(self):
return "Forall %s ( %r )"%(' '.join([var.n3() for var in self.declare]),
self.formula)
class Clause(object):
"""
Facts are *not* modelled formally as rules with empty bodies

Implies ::= ATOMIC ':-' CONDITION

Use body / head instead of if/then (native language clash)

Example: {?C rdfs:subClassOf ?SC. ?M a ?C} => {?M a ?SC}.

>>> Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
?SC(?M) :- And( rdfs:subClassOf(?C ?SC) ?C(?M) )
"""
def __init__(self,body,head):
self.body = body
self.head = head
from FuXi.Rete.Network import HashablePatternList
antHash=HashablePatternList(
[term.toRDFTuple() for term in body],skipBNodes=True)
consHash=HashablePatternList(
[term.toRDFTuple() for term in head],skipBNodes=True)
self._hash = hash(antHash) ^ hash(consHash)

def __eq__(self,other):
return hash(self)==hash(other)

def __hash__(self):
"""
>>> a=Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> b=Clause(And([Uniterm(RDFS.subClassOf,[Variable('C'),Variable('SC')]),
... Uniterm(RDF.type,[Variable('M'),Variable('C')])]),
... Uniterm(RDF.type,[Variable('M'),Variable('SC')]))
>>> d=set()
>>> d.add(a)
>>> b in d
True
>>> hash(a) == hash(b)
True

>>> d={a:True}
>>> b in d
True
"""
return self._hash

def asTuple(self):
return (self.body,self.head)

def __repr__(self):
if isinstance(self.body,SetOperator) and not len(self.body):
return "%r :-"%self.head
return "%r :- %r"%(self.head,self.body)

def n3(self):
return u'{ %s } => { %s }'%(self.body.n3(),self.head.n3())

def test():
import doctest
doctest.testmod()

if __name__ == '__main__':
test()
Show details Hide details

Change log

r247 by chimezie on Dec 20, 2008   Diff
InfixOWL
- added extent descriptor for classes
(returns generator over class extension)
- added equivalence relation between
Restriction instances (useful for symbolic
manipulation)

HornRules
- added HornFromN3 method.  Takes a N3
stream and returns a corresponding Horn
ruleset
- added equivalence / fixed relation for
...
Go to: 
Sign in to write a code review

Older revisions

r242 by chimezie on Aug 18, 2008   Diff
- fixed OWL abstract syntax
serialization of recursive inverseOf
reference
- added n3Stream argument to
SetupRuleStore (first argument,
...
r238 by chimezie on Aug 08, 2008   Diff
- Added list prefix
(http://www.w3.org/2000/10/swap/list#)
to default namespace bindings
- Added
FuXi.Rete.N3RuleStore.SetupRuleStore
...
r217 by chimezie on Jul 17, 2008   Diff
Make Clauses hashable (useful for
identifying duplicates in a ruleset)
All revisions of this file

File info

Size: 6716 bytes, 172 lines
Hosted by Google Code