Esempio n. 1
0
    static void RunTest(Entity test, Store manifest)
    {
        Entity rdf_type = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
        Entity mf_PositiveSyntaxTest = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#PositiveSyntaxTest";
        Entity mf_NegativeSyntaxTest = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#NegativeSyntaxTest";
        Entity mf_QueryTest          = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#QueryEvaluationTest";
        Entity mf_action             = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action";
        Entity mf_result             = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#result";
        Entity qt_data  = "http://www.w3.org/2001/sw/DataAccess/tests/test-query#data";
        Entity qt_query = "http://www.w3.org/2001/sw/DataAccess/tests/test-query#query";

        Entity test_type = (Entity)manifest.SelectObjects(test, rdf_type)[0];
        Entity action    = (Entity)manifest.SelectObjects(test, mf_action)[0];

        if (test_type == mf_PositiveSyntaxTest || test_type == mf_NegativeSyntaxTest)
        {
            // The action is a query.

            // Load the action as a string.
            string q = ReadFile(action.Uri);

            // Run the action.
            try {
                new SparqlEngine(q);
            } catch (SemWeb.Query.QueryFormatException qfe) {
                // On a negative test: Good!
                if (test_type == mf_NegativeSyntaxTest)
                {
                    pass++;
                    return;
                }

                Console.WriteLine("Test Failed: " + action);
                Console.WriteLine(qfe.Message);
                Console.WriteLine(q);
                Console.WriteLine();
                fail++;
                return;
            }

            // On a positive test: Good!
            if (test_type == mf_PositiveSyntaxTest)
            {
                pass++;
                return;
            }

            Console.WriteLine("Test Failed: " + action);
            Console.WriteLine("Query is syntactically incorrect.");
            Console.WriteLine(q);
            Console.WriteLine();
            fail++;
        }
        else if (test_type == mf_QueryTest)
        {
            Entity data   = (Entity)manifest.SelectObjects(action, qt_data)[0];
            Entity query  = (Entity)manifest.SelectObjects(action, qt_query)[0];
            Entity result = (Entity)manifest.SelectObjects(test, mf_result)[0];

            MemoryStore data_store = new MemoryStore(new N3Reader(data.Uri));
            string      q          = ReadFile(query.Uri);

            if (q.IndexOf("ASK") >= 0)
            {
                Console.WriteLine("ASK Test Skipped: " + test);
                skip++;
                return;
            }

            string run_individual_test = "mono ../../bin/rdfquery.exe -type sparql n3:" + data.Uri + " < " + query.Uri;

            SparqlEngine sp;
            try {
                sp = new SparqlEngine(q);
            } catch (SemWeb.Query.QueryFormatException qfe) {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(qfe.Message);
                Console.WriteLine();
                fail++;
                return;
            }

            QueryResultBuffer results = new QueryResultBuffer();
            bool results_bool         = false;
            try {
                if (sp.Type != SparqlEngine.QueryType.Ask)
                {
                    sp.Run(data_store, results);
                }
                else
                {
                    results_bool = sp.Ask(data_store);
                }
            } catch (Exception e) {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(e);
                Console.WriteLine();
                fail++;
                return;
            }

            bool          failed = false;
            StringBuilder info   = new StringBuilder();

            if (result.Uri.EndsWith(".ttl") || result.Uri.EndsWith(".srx") || result.Uri.EndsWith(".rdf"))
            {
                bool sorted = false;
                QueryResultBuffer results2 = new QueryResultBuffer();

                if (result.Uri.EndsWith(".srx"))
                {
                    using (FileStream fs = new FileStream(result.Uri, FileMode.Open))
                        SemWeb.Remote.SparqlHttpSource.ParseSparqlResponse(fs, results2);
                }
                else if (result.Uri.EndsWith(".rdf") || result.Uri.EndsWith(".ttl"))
                {
                    RdfReader reader = null;
                    if (result.Uri.EndsWith(".rdf"))
                    {
                        reader = new RdfXmlReader(result.Uri);
                    }
                    else if (result.Uri.EndsWith(".ttl"))
                    {
                        reader = new N3Reader(result.Uri);
                    }
                    MemoryStore result_store = new MemoryStore(reader);

                    string rs               = "http://www.w3.org/2001/sw/DataAccess/tests/result-set#";
                    Entity rsResultSet      = rs + "ResultSet";
                    Entity rsresultVariable = rs + "resultVariable";
                    Entity rssolution       = rs + "solution";
                    Entity rsindex          = rs + "index";
                    Entity rsbinding        = rs + "binding";
                    Entity rsvariable       = rs + "variable";
                    Entity rsvalue          = rs + "value";

                    // get a list of variables in the query output
                    Entity    resultset = result_store.GetEntitiesOfType(rsResultSet)[0];
                    ArrayList vars      = new ArrayList();
                    foreach (Literal var in result_store.SelectObjects(resultset, rsresultVariable))
                    {
                        vars.Add(new Variable(var.Value));
                    }
                    Variable[] varsarray = (Variable[])vars.ToArray(typeof(Variable));

                    // try to order as best we can to our own output, so we sort the results the same way
                    for (int i = 0; i < results.Variables.Length; i++)
                    {
                        if (i >= varsarray.Length)
                        {
                            break;
                        }
                        for (int j = i; j < varsarray.Length; j++)
                        {
                            if (varsarray[j].LocalName == results.Variables[i].LocalName)
                            {
                                Variable temp = varsarray[i];
                                varsarray[i] = varsarray[j];
                                varsarray[j] = temp;
                                break;
                            }
                        }
                    }

                    Hashtable varmap = new Hashtable();
                    foreach (Variable v in varsarray)
                    {
                        varmap[v.LocalName] = varmap.Count;
                    }

                    results2.Init(varsarray);

                    Resource[] resultbindings = result_store.SelectObjects(resultset, rssolution);

                    // Try sorting by index
                    int[] indexes = new int[resultbindings.Length];
                    for (int i = 0; i < resultbindings.Length; i++)
                    {
                        Entity  binding = (Entity)resultbindings[i];
                        Literal index   = (Literal)result_store.SelectObjects(binding, rsindex)[0];
                        indexes[i] = (int)(Decimal)index.ParseValue();
                        sorted     = true;
                    }
                    Array.Sort(indexes, resultbindings);

                    // Add bindings into results2.
                    for (int i = 0; i < resultbindings.Length; i++)
                    {
                        Resource[] row     = new Resource[vars.Count];
                        Entity     binding = (Entity)resultbindings[i];
                        foreach (Entity var in result_store.SelectObjects(binding, rsbinding))
                        {
                            string   name = ((Literal)result_store.SelectObjects(var, rsvariable)[0]).Value;
                            Resource val  = result_store.SelectObjects(var, rsvalue)[0];
                            row[(int)varmap[name]] = val;
                        }
                        results2.Add(new VariableBindings(varsarray, row));
                    }
                }

                // Check variable list
                ArrayList vars1 = new ArrayList();
                foreach (Variable v in results.Variables)
                {
                    vars1.Add(v.LocalName);
                }
                ArrayList vars2 = new ArrayList();
                foreach (Variable v in results2.Variables)
                {
                    vars2.Add(v.LocalName);
                }
                failed |= !SetsSame(vars1, vars2, "Result Set Variables", info);

                // Checking bindings
                if (results.Bindings.Count != results2.Bindings.Count)
                {
                    info.Append("Solutions have different number of bindings.\n");
                    failed = true;
                }
                else
                {
                    // Now actually run comparison.

                    if (!sorted)
                    {
                        ((ArrayList)results.Bindings).Sort();
                        ((ArrayList)results2.Bindings).Sort();
                    }

                    for (int i = 0; i < results.Bindings.Count; i++)
                    {
                        VariableBindings b1 = (VariableBindings)results.Bindings[i];
                        VariableBindings b2 = (VariableBindings)results2.Bindings[i];
                        foreach (Variable var in results.Variables)
                        {
                            Resource val1 = b1[var.LocalName];
                            Resource val2 = b2[var.LocalName];
                            if (val1 != val2 && !(val1 is BNode) && !(val2 is BNode))                                       // TODO: Test bnodes are returned correctly
                            {
                                info.Append("Binding row " + i + " differ in value of " + var.LocalName + " variable: " + val2 + ", should be: " + val1 + "\n");
                                failed = true;
                            }
                        }
                    }
                }
            }
            else
            {
                skip++;
                Console.WriteLine(test + ": Unknown result type " + result.Uri);
            }

            if (failed)
            {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(info.ToString());
                Console.WriteLine();
                fail++;
            }
            else
            {
                pass++;
            }
        }
        else
        {
            skip++;
            Console.WriteLine(test + ": Unknown test type " + test_type);
            Console.WriteLine();
        }
    }
Esempio n. 2
0
    static void RunTest(Entity test, Store manifest)
    {
        Entity rdf_type = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
        Entity mf_PositiveSyntaxTest = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#PositiveSyntaxTest";
        Entity mf_NegativeSyntaxTest = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#NegativeSyntaxTest";
        Entity mf_QueryTest = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#QueryEvaluationTest";
        Entity mf_action = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#action";
        Entity mf_result = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#result";
        Entity qt_data = "http://www.w3.org/2001/sw/DataAccess/tests/test-query#data";
        Entity qt_query = "http://www.w3.org/2001/sw/DataAccess/tests/test-query#query";

        Entity test_type = (Entity)manifest.SelectObjects(test, rdf_type)[0];
        Entity action = (Entity)manifest.SelectObjects(test, mf_action)[0];

        if (test_type == mf_PositiveSyntaxTest || test_type == mf_NegativeSyntaxTest) {
            // The action is a query.

            // Load the action as a string.
            string q = ReadFile(action.Uri);

            // Run the action.
            try {
                new SparqlEngine(q);
            } catch (SemWeb.Query.QueryFormatException qfe) {
                // On a negative test: Good!
                if (test_type == mf_NegativeSyntaxTest) {
                    pass++;
                    return;
                }

                Console.WriteLine("Test Failed: " + action);
                Console.WriteLine(qfe.Message);
                Console.WriteLine(q);
                Console.WriteLine();
                fail++;
                return;
            }

            // On a positive test: Good!
            if (test_type == mf_PositiveSyntaxTest) {
                pass++;
                return;
            }

            Console.WriteLine("Test Failed: " + action);
            Console.WriteLine("Query is syntactically incorrect.");
            Console.WriteLine(q);
            Console.WriteLine();
            fail++;

        } else if (test_type == mf_QueryTest) {

            Entity data = (Entity)manifest.SelectObjects(action, qt_data)[0];
            Entity query = (Entity)manifest.SelectObjects(action, qt_query)[0];
            Entity result = (Entity)manifest.SelectObjects(test, mf_result)[0];

            MemoryStore data_store = new MemoryStore(new N3Reader(data.Uri));
            string q = ReadFile(query.Uri);

            if (q.IndexOf("ASK") >= 0) {
                Console.WriteLine("ASK Test Skipped: " + test);
                skip++;
                return;
            }

            string run_individual_test = "mono ../../bin/rdfquery.exe -type sparql n3:" + data.Uri + " < " + query.Uri;

            SparqlEngine sp;
            try {
                sp = new SparqlEngine(q);
            } catch (SemWeb.Query.QueryFormatException qfe) {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(qfe.Message);
                Console.WriteLine();
                fail++;
                return;
            }

            QueryResultBuffer results = new QueryResultBuffer();
            bool results_bool = false;
            try {
                if (sp.Type != SparqlEngine.QueryType.Ask)
                    sp.Run(data_store, results);
                else
                    results_bool = sp.Ask(data_store);
            } catch (Exception e) {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(e);
                Console.WriteLine();
                fail++;
                return;
            }

            bool failed = false;
            StringBuilder info = new StringBuilder();

            if (result.Uri.EndsWith(".ttl") || result.Uri.EndsWith(".srx") || result.Uri.EndsWith(".rdf")) {

                bool sorted = false;
                QueryResultBuffer results2 = new QueryResultBuffer();

                if (result.Uri.EndsWith(".srx")) {
                        using (FileStream fs = new FileStream(result.Uri, FileMode.Open))
                            SemWeb.Remote.SparqlHttpSource.ParseSparqlResponse(fs, results2);

                } else if (result.Uri.EndsWith(".rdf") || result.Uri.EndsWith(".ttl")) {
                    RdfReader reader = null;
                    if (result.Uri.EndsWith(".rdf"))
                        reader = new RdfXmlReader(result.Uri);
                    else if (result.Uri.EndsWith(".ttl"))
                        reader = new N3Reader(result.Uri);
                    MemoryStore result_store = new MemoryStore(reader);

                    string rs = "http://www.w3.org/2001/sw/DataAccess/tests/result-set#";
                    Entity rsResultSet = rs + "ResultSet";
                    Entity rsresultVariable = rs + "resultVariable";
                    Entity rssolution = rs + "solution";
                    Entity rsindex = rs + "index";
                    Entity rsbinding = rs + "binding";
                    Entity rsvariable = rs + "variable";
                    Entity rsvalue = rs + "value";

                    // get a list of variables in the query output
                    Entity resultset = result_store.GetEntitiesOfType(rsResultSet)[0];
                    ArrayList vars = new ArrayList();
                    foreach (Literal var in result_store.SelectObjects(resultset, rsresultVariable))
                        vars.Add(new Variable(var.Value));
                    Variable[] varsarray = (Variable[])vars.ToArray(typeof(Variable));

                    // try to order as best we can to our own output, so we sort the results the same way
                    for (int i = 0; i < results.Variables.Length; i++) {
                        if (i >= varsarray.Length) break;
                        for (int j = i; j < varsarray.Length; j++) {
                            if (varsarray[j].LocalName == results.Variables[i].LocalName) {
                                Variable temp = varsarray[i];
                                varsarray[i] = varsarray[j];
                                varsarray[j] = temp;
                                break;
                            }
                        }
                    }

                    Hashtable varmap = new Hashtable();
                    foreach (Variable v in varsarray)
                            varmap[v.LocalName] = varmap.Count;

                    results2.Init(varsarray);

                    Resource[] resultbindings = result_store.SelectObjects(resultset, rssolution);

                    // Try sorting by index
                    int[] indexes = new int[resultbindings.Length];
                    for (int i = 0; i < resultbindings.Length; i++) {
                        Entity binding = (Entity)resultbindings[i];
                        Literal index = (Literal)result_store.SelectObjects(binding, rsindex)[0];
                        indexes[i] = (int)(Decimal)index.ParseValue();
                        sorted = true;
                    }
                    Array.Sort(indexes, resultbindings);

                    // Add bindings into results2.
                    for (int i = 0; i < resultbindings.Length; i++) {
                        Resource[] row = new Resource[vars.Count];
                        Entity binding = (Entity)resultbindings[i];
                        foreach (Entity var in result_store.SelectObjects(binding, rsbinding)) {
                            string name = ((Literal)result_store.SelectObjects(var, rsvariable)[0]).Value;
                            Resource val = result_store.SelectObjects(var, rsvalue)[0];
                            row[(int)varmap[name]] = val;
                        }
                        results2.Add(new VariableBindings(varsarray, row));
                    }
                }

                // Check variable list
                ArrayList vars1 = new ArrayList();
                foreach (Variable v in results.Variables)
                    vars1.Add(v.LocalName);
                ArrayList vars2 = new ArrayList();
                foreach (Variable v in results2.Variables)
                    vars2.Add(v.LocalName);
                failed |= !SetsSame(vars1, vars2, "Result Set Variables", info);

                // Checking bindings
                if (results.Bindings.Count != results2.Bindings.Count) {
                    info.Append("Solutions have different number of bindings.\n");
                    failed = true;
                } else {
                    // Now actually run comparison.

                    if (!sorted) {
                        ((ArrayList)results.Bindings).Sort();
                        ((ArrayList)results2.Bindings).Sort();
                    }

                    for (int i = 0; i < results.Bindings.Count; i++) {
                            VariableBindings b1 = (VariableBindings)results.Bindings[i];
                            VariableBindings b2 = (VariableBindings)results2.Bindings[i];
                            foreach (Variable var in results.Variables) {
                                Resource val1 = b1[var.LocalName];
                                Resource val2 = b2[var.LocalName];
                                if (val1 != val2 && !(val1 is BNode) && !(val2 is BNode)) { // TODO: Test bnodes are returned correctly
                                    info.Append("Binding row " + i + " differ in value of " + var.LocalName + " variable: " + val2 + ", should be: " + val1 + "\n");
                                    failed = true;
                                }
                            }
                    }
                }

            } else {
                skip++;
                Console.WriteLine(test + ": Unknown result type " + result.Uri);
            }

            if (failed) {
                Console.WriteLine("Test Failed: " + test);
                Console.WriteLine(run_individual_test);
                Console.WriteLine(q);
                Console.WriteLine(info.ToString());
                Console.WriteLine();
                fail++;
            } else {
                pass++;
            }

        } else {
            skip++;
            Console.WriteLine(test + ": Unknown test type " + test_type);
            Console.WriteLine();
        }
    }
Esempio n. 3
0
        public static void MakeLean(Store store, SelectableSource relativeTo, StatementSink removed)
        {
            // Break the data source into MSGs.  Make each MSG
            // lean first (in isolation).  Then check each lean MSG
            // to see if it's already entailed by the whole store,
            // or by relativeTo if it's provided (not null).

            MSG.Graph[] msgs = MSG.FindMSGs(store, true);

            foreach (MSG.Graph msgg in msgs)
            {
                // Load the MSG into memory.
                MemoryStore msg = new MemoryStore(msgg);                 // unnecessary duplication...

                // Make this MSG lean.  The "right" thing to do is
                // to consider all of the 'connected' subgraphs of MSG
                // against the whole store, rather than the MSG in
                // isolation.  But that gets much too expensive.
                MemoryStore msgremoved = new MemoryStore();
                MakeLeanMSG(new Store(msg), msgg.GetBNodes(), msgremoved);

                // Whatever was removed from msg, remove it from the main graph.
                store.RemoveAll(msgremoved.ToArray());

                // And track what was removed.
                if (removed != null)
                {
                    msgremoved.Select(removed);
                }

                // If this MSG is now (somehow) empty (shouldn't happen,
                // but one never knows), don't test for entailment.
                if (msg.StatementCount == 0)
                {
                    continue;
                }

                // Remove this MSG if it is already entailed.

                // The GraphMatch will treat all blank nodes in
                // msg as variables.
                GraphMatch        match = new GraphMatch(msg);
                QueryResultBuffer sink  = new QueryResultBuffer();
                match.Run(new SubtractionSource(store, msg), sink);
                if (sink.Bindings.Count > 0)
                {
                    // This MSG can be removed.
                    store.RemoveAll(msg.ToArray());
                    if (removed != null)
                    {
                        msg.Select(removed);
                    }
                }
                else if (relativeTo != null)
                {
                    match.Run(relativeTo, sink);
                    if (sink.Bindings.Count > 0)
                    {
                        // This MSG can be removed.
                        store.RemoveAll(msg.ToArray());
                        if (removed != null)
                        {
                            msg.Select(removed);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
		public static void MakeLean(Store store, SelectableSource relativeTo, StatementSink removed) {
			// Break the data source into MSGs.  Make each MSG
			// lean first (in isolation).  Then check each lean MSG
			// to see if it's already entailed by the whole store,
			// or by relativeTo if it's provided (not null).
		
			MSG.Graph[] msgs = MSG.FindMSGs(store, true);
			
			foreach (MSG.Graph msgg in msgs) {
				// Load the MSG into memory.
				MemoryStore msg = new MemoryStore(msgg); // unnecessary duplication...

				// Make this MSG lean.  The "right" thing to do is
				// to consider all of the 'connected' subgraphs of MSG
				// against the whole store, rather than the MSG in
				// isolation.  But that gets much too expensive.
				MemoryStore msgremoved = new MemoryStore();
				MakeLeanMSG(new Store(msg), msgg.GetBNodes(), msgremoved);
				
				// Whatever was removed from msg, remove it from the main graph.
				store.RemoveAll(msgremoved.ToArray());
				
				// And track what was removed.
				if (removed != null) msgremoved.Select(removed);
				
				// If this MSG is now (somehow) empty (shouldn't happen,
				// but one never knows), don't test for entailment.
				if (msg.StatementCount == 0) continue;

				// Remove this MSG if it is already entailed.
				
				// The GraphMatch will treat all blank nodes in
				// msg as variables.
				GraphMatch match = new GraphMatch(msg);
				QueryResultBuffer sink = new QueryResultBuffer();
				match.Run(new SubtractionSource(store, msg), sink);
				if (sink.Bindings.Count > 0) {
					// This MSG can be removed.
					store.RemoveAll(msg.ToArray());
					if (removed != null) msg.Select(removed);
				} else if (relativeTo != null) {
					match.Run(relativeTo, sink);
					if (sink.Bindings.Count > 0) {
						// This MSG can be removed.
						store.RemoveAll(msg.ToArray());
						if (removed != null) msg.Select(removed);
					}
				}
			}
		}
Esempio n. 5
0
    public static void Main()
    {
        System.Net.ServicePointManager.Expect100Continue = false;         // don't send HTTP Expect: headers which confuse some servers

        string endpoint = "http://www.rdfabout.com/sparql";

        string ex1 = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n"
                     + "SELECT ?name \n"
                     + "WHERE { [] foaf:name ?name . }\n"
                     + "LIMIT 10 \n";

        string ex2 = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n"
                     + "ASK \n"
                     + "WHERE { [] foaf:name ?name . }\n";

        string ex3 = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n"
                     + "CONSTRUCT { ?person foaf:name2 ?name } \n"
                     + "WHERE { ?person foaf:name ?name . }\n"
                     + "LIMIT 10 \n";

        SparqlHttpSource source = new SparqlHttpSource(endpoint);

        Console.WriteLine("RunSparqlQuery(ex1, Console.Out):");
        source.RunSparqlQuery(ex1, Console.Out);
        Console.WriteLine();

        Console.WriteLine("RunSparqlQuery(ex1, SparqlXmlQuerySink):");
        source.RunSparqlQuery(ex1, new SparqlXmlQuerySink(Console.Out));
        Console.WriteLine();
        Console.WriteLine();

        Console.WriteLine("RunSparqlQuery(ex2, bool):");
        bool result;

        source.RunSparqlQuery(ex2, out result);
        Console.WriteLine(result);
        Console.WriteLine();

        Console.WriteLine("RunSparqlQuery(ex3, N3Writer):");
        using (N3Writer writer = new N3Writer(Console.Out))
            source.RunSparqlQuery(ex3, writer);
        Console.WriteLine();

        Console.WriteLine("Select(subject,__,__)");
        using (N3Writer writer = new N3Writer(Console.Out))
            source.Select(new Statement("http://www.rdfabout.com/rdf/usgov/congress/people/M000303", null, null), writer);
        Console.WriteLine();

        Console.WriteLine("Query(...) A");
        Variable     a  = new Variable("a");
        QueryOptions qo = new QueryOptions();

        qo.Limit = 10;
        source.Query(new Statement[] {
            new Statement(a, "http://xmlns.com/foaf/0.1/name", (Literal)"John McCain"),
            new Statement(a, new Variable("b"), new Variable("c")),
        }, qo, new SparqlXmlQuerySink(Console.Out));
        Console.WriteLine();
        Console.WriteLine();

        Console.WriteLine("Query(...) B");
        QueryResultBuffer qb = new QueryResultBuffer();

        source.Query(new Statement[] {
            new Statement(a, "http://xmlns.com/foaf/0.1/name", (Literal)"John McCain"),
            new Statement(a, new Variable("b"), new Variable("c")),
        }, qo, qb);
        foreach (VariableBindings b in qb)
        {
            Console.WriteLine("a => " + b["a"]);
            Console.WriteLine("b => " + b["b"]);
            Console.WriteLine();
        }
        Console.WriteLine();
    }