Swi-cs-pl - A CSharp class library to connect .NET languages with SWI-Prolog
SbsSW.SwiPlCs Namespace
SwiPlCs interfaceSbsSW.SwiPlCs

The online documentation home is here.

This namespace SbsSW.SwiPlCs provides an .NET interface to SWI-Prolog

Overview

Prolog variables are dynamically typed and all information is passed around using the C-interface type term_t witch is an int. In C#, term_t is embedded in the lightweight struct PlTerm. Constructors and operator definitions provide flexible operations and integration with important C#-types (string, int and double).

The list below summarises the important classes / struct defined in the C# interface.

class / structShort description
PlEngine
A static class represents the prolog engine.
PlTerm
A struct representing prolog data.
PlTermV
A vector of PlTerm.
PlQuery
A class to query Prolog.
Types
All TypesClassesStructuresEnumerations
IconTypeDescription
PlEngine
This static class represents the prolog engine.

PlFrame

The class PlFrame provides an interface to discard unused term-references as well as rewinding unifications (data-backtracking). Reclaiming unused term-references is automatically performed after a call to a C#-defined predicate has finished and returns control to Prolog. In this scenario PlFrame is rarely of any use.

This class comes into play if the top level program is defined in C# and calls Prolog multiple times. Setting up arguments to a query requires term-references and using PlFrame is the only way to reclaim them.


PlQuery

This class allows queries to prolog.

A query can be created by a string or by constructing compound terms see Constructors for details.

All resources an terms created by a query are reclaimed by Dispose()()()(). It is recommended to build a query in a using scope.

There are four possible opportunities to query Prolog

Query typeDescription
A static call
To ask prolog for a proof. Return only true or false.
A PlCallQuery(String)
To get the first result of a goal
Construct a PlQuery object by a string.
The most convenient way.
Construct a PlQuery object by compound terms.
The most flexible and fast (runtime) way.

For examples see PlQuery(String) and PlQuery(String, PlTermV)


PlQuerySwitch
Flags that control for the foreign predicate parameters

SWI-Prolog Manual - 9.6.16 Querying Prolog.


PlQueryVar
Represents one variable of a Query result.

PlQueryVariables

Represents the set variables of a Query if it was created from a string.

This class is also used to represent the results of a PlQuery after ToList()()()() or SolutionVariables was called.


PlTerm

The PlTerm struct plays a central role in conversion and operating on Prolog data.

PlTerm implements IComparable to support ordering in [!:System.Linq] queries if PlTerm is a List.

Creating a PlTerm can be done by the Constructors or by the following static methods:

PlVar(), PlTail(), PlCompound, PlString(), PlCodeList(), PlCharList() (see remarks)


PlTermV
The struct PlTermv represents an array of term-references.

This type is used to pass the arguments to a foreign defined predicate (see DelegateParameterVarArgs), construct compound terms (see PlCompound(String, PlTermV) and to create queries (see PlQuery).

The only useful member function is the overloading of [], providing (0-based) access to the elements. Item[([( Int32])]) Range checking is performed and raises a ArgumentOutOfRangeException exception.


PlType
Obtain the type of a term, which should be a term returned by one of the other interface predicates or passed as an argument. The function returns the type of the Prolog term. The type identifiers are listed below.

Examples

Before going into a detailed description of the CSharp classes let me present a few examples illustrating the `feel' of the interface. The Assert class in the sample is from the test framework and has nothing to do with the interface. It shows only which return values are expected.

Creating terms

This very simple example shows the basic creation of a Prolog term and how a Prolog term is converted to C#-data:

 Copy imageCopy
PlTerm t1 = new PlTerm("x(A)"); 
PlTerm t2 = new PlTerm("x(1)"); 
Assert.IsTrue(t1.Unify(t2));
Assert.AreEqual("x(1)", t1.ToString());

Calling Prolog

This example shows how to make a simple call to prolog.

 Copy imageCopy
PlTerm l1 = new PlTerm("[a,b,c,d]");
Assert.IsTrue(PlQuery.PlCall("is_list", l1));

Getting the solutions of a query

This example shows how to obtain all solutions of a prolog query.

PlQuery takes the name of a predicate and the goal-argument vector as arguments. From this information it deduces the arity and locates the predicate. the member-function NextSolution() yields true if there was a solution and false otherwise. If the goal yielded a Prolog exception it is mapped into a C# exception.

 Copy imageCopy
PlQuery q = new PlQuery("member", new PlTermV(new PlTerm("A"), new PlTerm("[a,b,c]")));
while (q.NextSolution())
    Console.WriteLine(s[0].ToString());

There is an other constructor of PlQuery which simplify the sample above.

 Copy imageCopy
PlQuery q = new PlQuery("member(A, [a,b,c])");
foreach (PlTermV s in q.Solutions)
    Console.WriteLine(s[0].ToString());

An other way to get the results is to use SolutionVariables to iterate over PlQueryVariables.

 Copy imageCopy
PlQuery q = new PlQuery("member(A, [a,b,c])");
foreach (PlQueryVariables vars in q.SolutionVariables)
    Console.WriteLine(vars["A"].ToString());

It is also possible to get all solutions in a list by ToList()()()(). This could be used to work with LinQ to objects which is really nice. PlQuery and ToList()()()() for further samples.

 Copy imageCopy
var results = from n in new PlQuery("member(A, [a,b,c])").ToList() select new {A = n["A"].ToString()};
foreach (var s in results)
    Console.WriteLine(s.A);