2
votes

I'm having a problem trying to call SWI-Prolog from C#, it gives me a message 'Precondition failed' in my PlTerm variable. The program is for a school project and I'm running out of time and ideas on how to solve this. It is supposed to show me all the available flights from one airport to another.

Let me show you my code for you to better understand what I'm trying to say:

aeropuerto(a).
aeropuerto(b).
aeropuerto(c).
aeropuerto(d).
aeropuerto(m).

vuelo(1,b,a,1000).
vuelo(2,a,b,900).
vuelo(3,c,a,1200).
vuelo(4,a,c,1400).
vuelo(5,d,c,500).
vuelo(6,b,d,800).
vuelo(7,d,m,600).
vuelo(8,m,d,700).

vDirecto(A,X,Y,B):-vuelo(A,X,Y,B).

vEscalaSimple([T,M],X,Y,Z):-vDirecto(T,X,C,B),vDirecto(M,C,Y,P),suma(B,P,Z),X\=Y.

suma(B,P,Z):-Z is B + P.

reversa(X,A,B):-vuelo(X,B,A,C).

vuelos([A|_],X,Y,B):-vDirecto(A,X,Y,B).
vuelos([A|T],X,Y,B):-vEscalaSimple([A|T],X,Y,B).
vuelos([A|T],X,Y,B):-vDirecto(A,X,Z,D),vEscalaSimple(T,Z,Y,C),suma(D,C,B),reversa(J,X,Z),X\=Y,not(member(A,T)),not(member(J,T)).

misVuelos([A|T],X,Y,B):-vuelos([A|T],X,Y,B).
misVuelos([A|T],X,Y,B):-vDirecto(A,X,Z,D),vuelos(T,Z,Y,C),suma(D,C,B),reversa(J,X,Z),X\=Y,not(member(A,T)),not(member(J,T)),not(length([A|T],3)).

So this is my code in SWI-Prolog. When I call for "misVuelos(A,B,C,D)" Prolog shows me all the available flights as a list. Everything works perfect, the problem comes when trying to retrieve the answer in C#.

Environment.SetEnvironmentVariable("SWI_HOME_DIR", @"C:\Program Files\swipl");
Environment.SetEnvironmentVariable("Path", @"C:\Program Files\swipl\bin");
            List<string[]> temp = new List<string[]>();
            string[] _params = { "-q", "-f", _path };
            if (!PlEngine.IsInitialized)
            {
                try
                {
                    PlEngine.Initialize(_params);

                    PlTerm t1 = new PlTerm("A"), t2 = new PlTerm("B"), t3 = new PlTerm("C"), t4 = new PlTerm("D");
                    PlTermV termV = new PlTermV(new PlTerm[] { t1, t2, t3, t4 });

                    using (PlQuery q = new PlQuery("misVuelos", termV))
                    {
                        foreach (PlQueryVariables v in q.SolutionVariables)
                        {
                            Console.WriteLine(t1.ToString());
                            /*temp.Add(new string[] {
                                v["A"].ToString(),
                                v["B"].ToString(),
                                v["C"].ToString(),
                                v["D"].ToString()
                            });*/
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    PlEngine.PlCleanup();
                }
            }
            return temp;

When trying to get the value of variable t1 and print it to the console it throws me an error saying (again) 'Precondition failed'. The other variables work well (t2, t3 and t4), it's just t1 that's giving me problems. I have read the documentation but no luck on finding the solution.

Someone care to explain why isn't working and how to solve this? What am I missing?

1
This question is related to this problem too! stackoverflow.com/questions/4110394/… - DMurguia08

1 Answers

0
votes

Solution was found 4 months ago

NVM, I found the solution. I still don't understand, I will read carefully later but for now, it works! ^^

Source:

http://www-users.york.ac.uk/~sjh1/courses/L334css/complete/complete2su6.html

Prolog code changes:

vuelos([A|[]],X,Y,B):-vDirecto(A,X,Y,B).
vuelos([A|[]],X,Y,B):-vEscalaSimple([A|[]],X,Y,B).
vuelos([A|T],X,Y,B):-vDirecto(A,X,Z,D),vEscalaSimple(T,Z,Y,C),suma(D,C,B),reversa(J,X,Z),X\=Y,not(member(A,T)),not(member(J,T)).

Now I can print the solutions to the C# console without problems.