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:

  1. Set the Path environment variable to the PL and and PL/bin directory
  2. Set the SWI_HOME_DIR environment variable to the PL directory
  3. 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:

  1. Initialize the SWI-Prolog engine if not done
  2. Read the number which we wish to compute the faculty of from the keyboard
  3. Consult the faculty program
  4. create a query, which retrieves the faculty of the number read in (2.)
  5. output the computed faculty
  6. 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 -

faculty

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.