我正在使用SbsSW.SwiPlCs
dll解决方案,以便在C#应用程序和prolog .pl
源文件之间进行集成,但是我遇到了assert(atom)
命令的问题
我的prolog文件是一组机场和机场之间的航班,在我的运行时间我声称新机场和这样的航班:
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();
}
}
这样运行正常,我没有得到任何错误信息或例外(我曾经得到一个,但这是因为我的航班/ 4和机场/ 2声明是静态的,我在开始时将两者都改为动态我的文件并没有抛出任何错误。)
我的问题是当我尝试查询涉及我在运行时获得的新断言的内容时。
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;
}
我的List<string> list
变量应该返回从from
到to
的所有航班ID的列表,这适用于预先加载的航班(我{{1}上的航班我呼吁vuelos.pl
),但我没有考虑在运行时创建的任何新航班,我无法弄清楚原因。
答案 0 :(得分:0)
我的错误包括两个不法行为。 首先,我每次执行查询时都清理了我的PlEngine
finally
{
PlEngine.PlCleanup();
}
我为解决这个问题所做的只是在我的类构造函数PlEngine
中初始化Class Prolog
一次,这样我就可以对我的所有方法使用相同的PlEngine
。我环顾四周,似乎另一种解决方案是使用? tell('file.pl'), append(listing(atom)), told.
在运行时保存文件,但我不知道它是否会破坏我以前的数据,所以我选择了PlEngine
解决方法。它不保存易失性数据,但适用于一个Prolog会话。我仍然创建了一种清理引擎的方法,我在终止程序时调用它。
我发现的另一个问题是我尝试执行这样的断言参数:
PlQuery q = new PlQuery("assert(fligth(" + new.id + "," + new.airportFrom.id + "," + new.airportTo.id + "," + new.price + "))");
当我应该做的时候:
PlQuery.PlCall("assert(fligth(" + new.id + "," + new.airportFrom.id + "," + new.airportTo.id + "," + new.price + "))");
PlQuery
仅适用于从我能掌握的内容中返回变量的请求,而PlCall
用于返回true/false
的简单咨询或指令。
希望这有助于任何人。