c# - SWI-prolog 到 C# 断言不工作

标签 c# prolog swi-prolog

我正在研究使用 SbsSW.SwiPlCs 的解决方案用于 C# 应用程序和序言之间集成的 dll .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();
        }
    }

这运行良好,我没有收到任何错误消息或异常(我曾经收到过一个,但那是因为我的 flight/4 和 airport/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 的所有航类 ID 的列表至 to ,这适用于预加载的航类(我在 vuelos.pl 上调用的航类 PlQuery.PlCall("consult(vuelos)"); ),但我没有考虑我在运行时创建的任何新航类,我无法弄清楚为什么.

最佳答案

我的错误在于两个不当行为。 首先,我每次执行查询时都会清理我的 PlEngine

        finally
    {
        PlEngine.PlCleanup();
    }

为了解决这个问题,我所做的就是在我的类构造函数 Class Prolog 中初始化我的 PlEngine 一次,这样我就可以使用相同的 PlEngine 我所有的方法。我环顾四周,似乎另一种解决方案是使用 ? tell('file.pl'), append(listing(atom)), told. 在运行时保存文件,但我不知道它是否会破坏我以前的数据,所以我选择了 PlEngine 解决方法。它不保存 volatile 数据,但对于一个 Prolog session 来说工作正常。我仍然创建了一个清理引擎的方法,我在终止程序时调用它。

我发现的另一个问题是,我尝试像这样执行断言参数:

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

希望这对任何人都有帮助。

关于c# - SWI-prolog 到 C# 断言不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29812529/

相关文章:

c# - 在路径中使用 "~"解析为 C :\

prolog - 在 Prolog 中,如何通过广度优先或深度优先搜索来解析汉诺塔?

string - SWI Prolog 转义引号

c# - Azure 持续部署 - Code First 迁移播种问题 (MVC 5)

c# - 保护 C# 程序集免受未经授权的调用者的攻击

prolog - 谓词返回假

prolog - 如何访问有向图中的每个点

prolog - 在 Prolog 中(从文件中)读取字符串

prolog - 最新的 Prolog 实现基准?

c# - 何时传递 ref 关键字