SWI-prolog to C#断言不起作用

时间:2015-04-23 02:26:12

标签: c# prolog swi-prolog

我正在使用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变量应该返回从fromto的所有航班ID的列表,这适用于预先加载的航班(我{{1}上的航班我呼吁vuelos.pl),但我没有考虑在运行时创建的任何新航班,我无法弄清楚原因。

1 个答案:

答案 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的简单咨询或指令。

希望这有助于任何人。