SWI-CS-PL – A First Glimpse
My exploration of Prolog and .NET led me to the C# interface to SWI-Prolog developed by Uwe Lesta. In the following I will present my first steps, i.e. the reproduction of the faculty Prolog program from C#. Before interoperating with SWI Prolog make sure you have correctly setup the following:
- Set the Path environment variable to the PL and and PL/bin directory
- Set the SWI_HOME_DIR environment variable to the PL directory
- include the SwiPlCs.dll assembly in your project
After having met these preconditions, I added the previously created faculty Prolog program (fac.pl) to the project’s directory.
Now, everything is set and we can delve into C# coding …
I created a C#-based console application. The code needs to account for the following:
- Initialize the SWI-Prolog engine if not done
- Read the number which we wish to compute the faculty of from the keyboard
- Consult the faculty program
- create a query, which retrieves the faculty of the number read in (2.)
- output the computed faculty
- clean up any bound resources
From this high level walk-through one may derive the following C# code.
1: using System;
2: using System.Collections.Generic;
3: using SbsSW.SwiPlCs;
4:
5: namespace PrologCSharp
6: {
7: class Program
8: {
9: static void Main(string[] args)
10: {
11: Console.WriteLine("First Prolog-CSharp");
12:
13: Console.WriteLine("compute the faculty of: ");
14: string facNumberStr = Console.ReadLine();
15:
16: int facNo = -1;
17:
18: /*
19: * read number
20: */
21: if (Int32.TryParse(facNumberStr, out facNo) == false)
22: {
23: Console.WriteLine("Entered string is not a number!");
24: return;
25: }
26:
27: /*
28: * Initialize the Prolog Engine if needed
29: */
30: if (!PlEngine.IsInitialized)
31: {
32: try
33: {
34: SbsSW.SwiPlCs.PlEngine.Initialize(new string[] { "" });
35: }
36: catch (System.Exception ex)
37: {
38: Console.WriteLine("Failure initializing Prolog: " + ex.Message);
39: return;
40: }
41: }
42:
43: /*
44: * Consult the faculty program
45: */
46: PlQuery.PlCall("consult(fac)");
47:
48: /*
49: * Construct the query to retrieve the faculty of the previously input number
50: * the query looks like fac(facNo, _GXYZ).
51: */
52: using (PlQuery facultyQuery = new PlQuery("fac", new PlTermV(new PlTerm(facNo), PlTerm.PlVar())))
53: {
54: /*
55: * there will only be one solution due to the cut
56: * this solution has two entries:
57: * entry 1 is the faculty to compute
58: * entry 2 is the bound variable, i.e. the solution
59: */
60: foreach (PlTermV v in facultyQuery.Solutions)
61: {
62: Console.WriteLine(string.Format("the faculty of {0} is {1}", v[0].ToString(), v[1].ToString()));
63: }
64: }
65:
66: /*
67: * cleanup everything
68: */
69: PlEngine.PlCleanup();
70:
71: Console.WriteLine("Press <key> to exit");
72: Console.ReadLine();
73: }
74: }
75: }
Now started, the Prolog will provide us with the faculty of 100 -
Not so bad – due to SWI Prolog’s built-in support for large numbers we did not have to do anything :). So happy interfacing and read you soon.