【问题标题】:How to get the result from Prolog, via the C++ FFI , into a C++ variable如何通过 C++ FFI 从 Prolog 获取结果到 C++ 变量中
【发布时间】:2019-05-02 15:24:12
【问题描述】:

我遇到的问题是如何从 Prolog(通过 SWI-Prolog 的接口)获取(变量 XY)并将其存储到 Visual Studio 中的变量(C++)中

简而言之:我将一个带有三角形瓷砖的拼图编码为 Prolog 表示。 Prolog 解决了这个难题。到目前为止,这有效。每个磁贴的可视化表示是在 Visual Studio 中完成的。这也有效。

现在我想通过接口调用 Prolog 引擎并获取解决方案和过程中的每个步骤(旋转瓷砖/哪个瓷砖/及其位置)(由 Prolog 中的write/1 完成)。到目前为止,我可以让 prolog 调用该函数并在控制台窗口中获取返回值。我还在控制台中显示每个write()。但仅在控制台中。

序言部分:
X 表示具有拼图块 ID 的列表。
Y 表示作为 prolog 的结果的图块旋转状态列表
在内部,瓷砖表示为:

teil(ID,side_a,side_b,side_c)。

teil(8, lsh, hbsh, gsv).

Prolog 调用:

?- puFlaeche(X,Y).
X = [2, 7, 3, 5, 9, 1, 4, 6, 8],
Y = [rechts, rechts, unten, rechts, rechts, unten, rechts, unten, rechts].

Visual Studio:

if( ! PL_initialise(1,av) ) {
    Console::Write("eeor with PL_initialise(1,av)");
} else {
    Console::Write("no error with PL_initialise(1,av)");
}

PlCall("consult('puzzle.pl')");
char rval2;
predicate_t pred2 = PL_predicate("puFlaeche",2,"user");
term_t h2 = PL_new_term_refs(2);
char * variable1 = "X";
char * variable2 = "Y";
//add some Variable to prolog
PL_put_variable(h2);
PL_put_variable(h2+1);
//produce console output
rval2 = PL_call_predicate(NULL,PL_Q_NORMAL,pred2,h2);

如果我打电话:

if (PL_call(h2, NULL)) {
    PL_get_list_chars(h2, &fact2,
        CVT_ATOM|REP_UTF8);
}

我在断点处的 VS 调试中看到 fact2 以某种方式存储了结果:

fact2   0x05699460 "\x2\a\x3\x5\t\x1\x4\x6\b"   char *

它也显示在控制台中......但带有示例输出:

ERROR: source_sink 2 does not exist
ERROR: source_sink 7 does not exist
ERROR: source_sink 3 does not exist
...

如果我打电话:

term_t tail = PL_copy_term_ref(h2);
term_t head = PL_new_term_ref();
int x;
while(PL_get_list(tail, head, tail))
{
    PL_get_integer(head, &x);
    Console::WriteLine("Ergebnis 2:---"+x+"---| ");
}

我确实得到了解决方案(来自 X),在控制台中没有错误:

"some debug text": 2 
"some debug text": 7
"some debug text": 3
...

我尝试了其他几种解决方案,但这是迄今为止我得到的最好结果...
再次长文提问后:
A) 如何从 Prolog 中获取 Y 变量内容 已解决

----编辑问题-----

B) 如何从控制台中显示的 prolog 中获取 write() 或任何其他方式以获取逐步输出,例如 prolog 中的“trace”

C) 如何将 A) 和 write() 语句存储到 c++ 中的变量或列表中

我可能会遇到错误的方法......所以你可以帮助我。 在此先感谢:)


编辑


A) 我通过调用函数 `PL_get_list` 获取 X 和 Y 列表的内容 X 代表 tilws 的 ID //也感谢 Jan
term_t tail = PL_copy_term_ref(h2);
term_t head = PL_new_term_ref();
int x;
while(PL_get_list(tail, head, tail))
{
    PL_get_integer(head, &x);
    PL_get_integer(head+1, &x);
    Console::WriteLine("Ergebnis X :---"+x+"---| ");
}

对于代表旋转状态的Y

term_t tail1 = PL_copy_term_ref(h2+1);
term_t head1 = PL_new_term_ref();
std::string extracted_state_array[10];
char* state_array[10];int count=0;

while(PL_get_list(tail1, head1, tail1)){
    std::string st;
    PL_get_chars(head1,&state_array[count],CVT_ALL | CVT_WRITE | BUF_RING);
    st.assign(state_array[count],strlen(state_array[count]));
    extracted_state_array[count]=st;

    std::cout<<"Ergebnis Y :---"+extracted_state_array[count]+"---| "<<  std::endl;
    count++;
}

【问题讨论】:

    标签: c++ visual-studio prolog ffi swi-prolog


    【解决方案1】:

    直到PL_call_predicate(),一切都很好。现在,h2 是两个术语引用的数组,h2+0 绑定到 [2, 7, 3, 5, 9, 1, 4, 6, 8]h2+1 绑定到 [rechts, rechts, unten, rechts, rechts, unten, rechts, unten, rechts]。然后你做了一些奇怪的事情:你打电话h2+0,基本上是打电话

    call([2, 7, 3, 5, 9, 1, 4, 6, 8])
    

    该列表是consult/1 的缩写,因此您尝试查阅(加载)名为1 等的文件。因此出现消息。

    您需要使用PlList 类中的列表迭代方法来枚举数组中的元素。然后你可以将每个翻译成一个数字或字符串(第二个)。

    当嵌入(在 C++ 中)时,您通常不会使用 Prolog 的 I/O。您可以使用 PL_get_chars() 和变体将单个术语转换为字符串。如果你真的想重新绑定 I/O,有标题SWI-Stream.h。不过,它的用法大多没有记录。您可以查看源代码以获取重新绑定 Prolog 的 I/O 以读取/写入 swipl-win.exe 控制台等的示例。我认为这不是您所追求的。

    【讨论】:

    • 非常感谢您的回答。你的权利。我也试过并行Pl_List。我更新我的问题还是我应该回答我的问题?对不起,这是我的第一篇文章:/我现在有一个 X 列表和一个 Y 列表。现在你可能对如何从 prolog 获取 write() 输出或“跟踪”有任何建议吗?为此,您建议 SWI-Stream.h 我对吗?还有其他方法吗?也许“PL_backtracec”?我不舒尔......我的计划是c ++将处理prolog(类似trace)传递的逐步输出并显示GUI元素中的更改
    • 您是否有任何提示让我将跟踪输出重定向到 c++ 中的变量?可能如何从 SWI-Stream.h 或其他方式开始。我打开了另一个question,尤其是最后一部分。我项目的所有其他部分都可以工作,除了这个。如果您能帮助我,我将不胜感激
    • 这是一个无关紧要的问题。您可以使用 SWI-Stream.h 重新定义 I/O。这在很大程度上是无证的。有关示例,请参阅源代码中的 src/pl-ntmain.c 和 packages/swipl-win。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多