File: inference.html

package info (click to toggle)
semweb 1.05%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 4,000 kB
  • ctags: 2,832
  • sloc: cs: 14,483; makefile: 176; perl: 20; sh: 11; ansic: 7
file content (245 lines) | stat: -rw-r--r-- 10,402 bytes parent folder | download | duplicates (3)
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
<html>
	<head>
		<title>SemWeb: Querying</title>
		<link rel="stylesheet" type="text/css" href="stylesheet.css"/>
	</head>
	
	<body>

<p><a href="index.html">SemWeb Documentation</a></p>
<h1>Inferencing: RDFS and the Euler Proof Engine</h1>

<p>SemWeb provides two inferencing classes in the <tt>SemWeb.Inference</tt> namespace: <tt>RDFS</tt>, which implements a subset of RDFS reasoning, and <tt>Euler</tt> which implements general rule-based reasoning based on the <a href="http://www.agfa.com/w3c/euler/">Euler proof mechanism</a>.</p>

<p>The two reasoning engines work similarly.  They are initialized with axioms and then perform reasoning on an arbitrary target data model.  For the <tt>RDFS</tt> class, the axioms are an RDFS schema that contains subClassOf relations between classes and subPropertyOf relations between properties.  For the <tt>Euler</tt> class, the axioms are rules of entailment (and possibly some basic instance data).  The data model contains an arbitrarily large data set that the axioms are applied to in order to answer some question about the data.</p>

<p>The best way to use these <tt>Reasoner</tt> classes is to apply them to a <tt>Store</tt> with the <tt>AddReasoner</tt> method.  When this is done, the <tt>Contains</tt>, <tt>Select</tt>, and <tt>Query</tt> methods on the store will make use of the reasoner applied.</p>



<h2>RDFS Reasoning</h2>

<p>SemWeb's <tt>RDFS</tt> class provides limited RDFS reasoning over a data model.  See the API documentation for a complete list of what reasoning the class provides.</p>

<p>To use the class, create an instance of it and then load in RDF schemas.</p>

<pre class="code">
RDFS engine = new RDFS();
engine.LoadSchema(RdfReader.LoadFromUri(new Uri("http://xmlns.com/foaf/0.1/index.rdf")));
</pre>

<p>Besides passing it an <tt>RdfReader</tt>, you may also pass it any <tt>SelectableSource</tt> with RDFS schema statements, such as a <tt>MemoryStore</tt> that you might construct with your own schema.  You can call <tt>LoadSchema</tt> any number of times.</p>

<p>Then apply the <tt>RDFS</tt> instance to a <tt>Store</tt> object.</p>
		
<pre class="code">
dataModel.AddReasoner(engine);
</pre>

<p>The <tt>Contains</tt>, <tt>Select</tt>, and <tt>Query</tt> methods on the store will make use of the RDFS reasoner and will return anything entailed by the instance data in the data model and the schema.</p>

<p>For instance, if the dataModel contains the following:</p>

<pre class="code">
:me rdf:type foaf:Person .
:you rdf:type foaf:Person .
:me foaf:name "John Doe" .
:you foaf:name "Sam Smith" .
</pre>

<p>and you load in the FOAF schema, then the following will result</p>

<pre class="code">
dataModel.Contains(new Statement(me, rdfType, foafAgent)) => Returns True

dataModel.SelectSubjects(rdfType, foafAgent)) => Returns [ me , you ]
		
dataModel.Select(new Statement(null, rdfsLabel, null))
 => me rdfsLabel "John Doe"
 => you rdfsLabel "Sam Smith"
</pre>

<p>Note that when RDFS returns statements that were found by applying a subproperty closure, the returned statements do not show the subproperty actually in the instance data, but rather the property that was provided in the call to <tt>Select</tt>.  Think of it this way: Select does not return statements in the data model that are relavent to the template, but rather it returns <i>all</i> possible statements that are entailed by the data model and schema that <i>match the template</i>.</p>

<p>A complete example of using the <tt>RDFS</tt> class is below:</p>

<pre class="code" file="../examples/rdfs.cs">// This example demonstrates basic RDFS reasoning.

using System;
using System.IO;

using SemWeb;
using SemWeb.Inference;

public class EulerTest {

    public static void Main() {
        // Create the instance data
        
        MemoryStore dataModel = new MemoryStore();
        
        BNode me = new BNode("me");
        BNode you = new BNode("you");
        
        Entity rdfType = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
        Entity rdfsLabel= "http://www.w3.org/2000/01/rdf-schema#label";
        Entity foafPerson = "http://xmlns.com/foaf/0.1/Person";
        Entity foafAgent = "http://xmlns.com/foaf/0.1/Agent";
        Entity foafName = "http://xmlns.com/foaf/0.1/name";
        
        dataModel.Add(new Statement(me, rdfType, foafPerson));
        dataModel.Add(new Statement(you, rdfType, foafPerson));
        dataModel.Add(new Statement(me, foafName, (Literal)"John Doe"));
        dataModel.Add(new Statement(you, foafName, (Literal)"Sam Smith"));
        
        // Create the RDFS engine and apply it to the data model.
        
        RDFS engine = new RDFS();
        engine.LoadSchema(RdfReader.LoadFromUri(new Uri("http://xmlns.com/foaf/0.1/index.rdf")));
        
        dataModel.AddReasoner(engine);
        
        // Query the data model
        
        // Ask for who are typed as Agents.  Note that the people are
        // typed as foaf:Person, and the schema asserts that foaf:Person
        // is a subclass of foaf:Agent.
        Console.WriteLine("Who are Agents?");
        foreach (Entity r in dataModel.SelectSubjects(rdfType, foafAgent))
            Console.WriteLine("\t" + r);
        
        // Ask for the rdfs:labels of everyone.  Note that the data model
        // has foaf:names for the people, and the schema asserts that
        // foaf:name is a subproperty of rdfs:label.
        Console.WriteLine("People's labels:");
        foreach (Statement s in dataModel.Select(new Statement(null, rdfsLabel, null)))
            Console.WriteLine("\t" + s);
    }

}
</pre>

<h2>General reasoning with the Euler engine</h2>

<p>SemWeb has an adaptation of the <a href="http://www.agfa.com/w3c/euler/">Euler proof mechanism</a> by Jos De Roo in the class <tt>Euler</tt> in the namespace <tt>SemWeb.Inference</tt>.</p>  

<p>To use the class, create an instance of it and pass it a <tt>StatementSource</tt> with the rules of inference:</p>

<pre class="code">
string rules =
   "@prefix : <http://www.agfa.com/w3c/euler/graph.axiom#>. " +
   "{ ?a :oneway ?b } => { ?a :path ?b } . " +
   "{ ?a :path ?b . ?b :path ?c . } => { ?a :path ?c } . ";

Euler engine = new Euler(new N3Reader(new StringReader(rules)));
</pre>

<p>Then form the question to be proved in the form a statement:</p>

<pre class="code">
Statement question = new Statement(paris, path, nantes);
</pre>

<p>One way to ask the question is to have the Euler engine return an array of proofs.</p>

<pre class="code">
Proof[] proofs = engine.Prove(dataModel, new Statement[] { question });
foreach (Proof p in proofs)
   Console.WriteLine(p.ToString());
</pre>

<p>If it can't find a proof, a zero-length array is returned.</p>

<p>Alternatively, you may add the engine to a <tt>Store</tt> so that its <tt>Contains</tt>, <tt>Select</tt>, and <tt>Query</tt> methods make use of reasoning.  With reasoning, the <tt>Contains</tt> method returns not just whether the statement is directly in the data model, but also whether it can be proved to be entailed by the data model.</p>

<pre class="code">
dataModel.AddReasoner(engine);
Console.WriteLine("Euler Says the Question is: " + dataModel.Contains(question));
</pre>

<p>A complete example for using <tt>Euler</tt> is below:</p>

<pre class="code" file="../examples/euler.cs">// This example demonstrates general reasoning with
// the Euler engine based on Jos De Roo's Euler proof
// mechanism.  The example is based on the "graph"
// example from Euler.

using System;
using System.IO;

using SemWeb;
using SemWeb.Inference;

public class EulerTest {

    public static void Main() {
        // Create the instance data
        
        MemoryStore dataModel = new MemoryStore();
        
        BNode paris = new BNode("paris");
        BNode orleans = new BNode("orleans");
        BNode chartres = new BNode("chartres");
        BNode amiens = new BNode("amiens");
        BNode blois = new BNode("blois");
        BNode bourges = new BNode("bourges");
        BNode tours = new BNode("tours");
        BNode lemans = new BNode("lemans");
        BNode angers = new BNode("angers");
        BNode nantes = new BNode("nantes");
    
        Entity oneway = new Entity("http://www.agfa.com/w3c/euler/graph.axiom#oneway");
        Entity path = new Entity("http://www.agfa.com/w3c/euler/graph.axiom#path");
        
        dataModel.Add(new Statement(paris, oneway, orleans));
        dataModel.Add(new Statement(paris, oneway, chartres));
        dataModel.Add(new Statement(paris, oneway, amiens));
        dataModel.Add(new Statement(orleans, oneway, blois));
        dataModel.Add(new Statement(orleans, oneway, bourges));
        dataModel.Add(new Statement(blois, oneway, tours));
        dataModel.Add(new Statement(chartres, oneway, lemans));
        dataModel.Add(new Statement(lemans, oneway, angers));
        dataModel.Add(new Statement(lemans, oneway, tours));
        dataModel.Add(new Statement(angers, oneway, nantes));
        
        // Create the inference rules by reading them from a N3 string.
        
        string rules =
            "@prefix : &lt;http://www.agfa.com/w3c/euler/graph.axiom#&gt;.\n" +
            "\n" +
            "{ ?a :oneway ?b } =&gt; { ?a :path ?b } .\n" +
            "{ ?a :path ?b . ?b :path ?c . } =&gt; { ?a :path ?c } .\n";
        
        // Create our question in the form of a statement to test.
        
        Statement question = new Statement(paris, path, nantes);
        
        // Create the Euler engine
        
        Euler engine = new Euler(new N3Reader(new StringReader(rules)));
        
        // First Method of Inference:
        // Ask the engine whether there is a path from paris to nantes.
        // The Prove method will return a list of proofs, or an empty
        // array if it could not find a proof.
        
        foreach (Proof p in engine.Prove(dataModel, new Statement[] { question })) {
            Console.WriteLine(p.ToString());
        }
        
        // Second Method of Inference:
        // Apply the engine to the data model and then use the data
        // model's Contains method to see if the statement is "in"
        // the model + reasoning.
        
        dataModel.AddReasoner(engine);
        
        Console.WriteLine("Euler Says the Question is: " + dataModel.Contains(question));
        
    }

}
</pre>

	</body>
</html>