Reputation: 343
I'm working on a solution using the SbsSW.SwiPlCs
dll for integration between a C# application and a prolog .pl
source file, however I'm facing a problem with the assert(atom)
command.
My prolog file is a set of airports and flights between airports, during my running time I assert new airports and flights like this:
internal void alta(Flight new)
{
try
{
PlEngine.Initialize(new string[] { "" });
//PlEngine.Initialize(param);
PlQuery.PlCall("consult(vuelos)");
//comando
//flight(v01,bra,ams,1000)
PlQuery q = new PlQuery("assert(fligth(" + new.id + "," + new.airportFrom.id + "," + new.airportTo.id + "," + new.price + "))");
}
catch (PlException e)
{
Console.WriteLine(e.MessagePl);
Console.WriteLine(e.Message);
}
finally
{
PlEngine.PlCleanup();
}
}
This runs fine, and I don't get any error message nor exceptions (I used to get one, but it was because my flight/4 and airport/2 statements were static, I changed both to dynamic at the beggining of my file and no errors were thrown).
My problem is when I try to consult something involving the new asserts I got at runtime.
internal List<string> directFlight(Airport from, Airport to)
{
List<string> list = new List<string>();
try
{
PlEngine.Initialize(new string[] { "" });
//PlEngine.Initialize(param);
PlQuery.PlCall("consult(vuelos)");
//comando
//una_escala(W,from,to)
using (PlQuery q = new PlQuery("directF(W," + from.id + "," + to.id + ")"))
{
foreach (PlQueryVariables v in q.SolutionVariables)
{
list.Add(v["W"].ToString());
}
}
}
catch (PlException e)
{
Console.WriteLine(e.MessagePl);
Console.WriteLine(e.Message);
}
finally
{
PlEngine.PlCleanup();
}
return list;
}
My List<string> list
variable should return the list of all the flight id's which go from from
to to
, and this works with pre-loaded flights (the ones on my vuelos.pl
which I call on PlQuery.PlCall("consult(vuelos)");
), but I doesn't take into account any of my new flights created at runtime and I can't figure out why.
Upvotes: 1
Views: 517
Reputation: 343
My error consisted on two malpractices. First, I cleaned my PlEngine everytime I executed a query
finally
{
PlEngine.PlCleanup();
}
What I did in order to fix this, is to just initialize my PlEngine
one time at my class constructor Class Prolog
, that way I can use the same PlEngine
for all my methods. I've looked around and seemingly another solution would be to use the ? tell('file.pl'), append(listing(atom)), told.
to save the file at runtime, but I'm not aware if it can corrupt my previous data, so I chose the PlEngine
workaround. It doesn't save volatile data, but works fine for one Prolog session. I still created a method to clean the engine, which I call when I terminate my program.
The other issue I found, is that I tried to execute the assert parameters like this:
PlQuery q = new PlQuery("assert(fligth(" + new.id + "," + new.airportFrom.id + "," + new.airportTo.id + "," + new.price + "))");
When I should have done:
PlQuery.PlCall("assert(fligth(" + new.id + "," + new.airportFrom.id + "," + new.airportTo.id + "," + new.price + "))");
PlQuery
is exclusive for requests who return variables from what I could grasp, while PlCall
is used for simple consults or instructions which return a true/false
.
Hope this helps anyone.
Upvotes: 0