gpt4 book ai didi

c++ - 将 SWI-Prolog 连接到 C++ 的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:22:05 24 4
gpt4 key购买 nike

我想尽办法让 SWI-Prolog 与 C++ 配合得很好。现在,在我开始确切解释我的问题是什么之前,我想先说明我的项目是关于什么的,以及我选择了哪些工具来开发解决方案。

我的教授分配给我的任务是开发一个 GUI 程序作为 SWI-prolog 的前端,这个前端是用 C++ 开发的。我选择使用 Qt 来设计 GUI,并使用 C++ 作为后端将 SWI-Prolog 连接到应用程序。此应用程序的用户应该能够输入一些列表,然后通过 prolog 选择要应用于它们的操作,例如,如果我输入了一个数字列表,然后通过单击一个按钮,用户可以获得另一个列表此列表中成对的数字(如果有的话)。我正在基于 archlinux 和 manjaro 开发一个 unix 操作系统,更具体地说,是 netrunner 滚动发行版。

我做了一些研究,似乎为了连接 SWI-Prolog 最好的做法是使用 Volker Wysk 开发的头文件和源文件;作为引用,这里是包含这些文件的压缩文件的链接 http://www.volker-wysk.de/swiprolog-c++/index.html

现在这是我的问题:如果你访问了我刚刚给你的页面,你会发现这个 SWI-Prolog 接口(interface)的 C++ 实现已经很老了:上次使用它是在 2002 年。我不得不修改标题文件,这样我就可以摆脱一些错误,比如使用命名空间std或将#include ostream.h更改为#include ostream,所以我设法将错误计数变为只有两个我无法修复而且我认为我无法做到,因为有两个函数的实现我在任何地方都找不到:该函数已声明,但找不到在调用它们时应该运行的代码。

我现在将列出我认为最相关的文件的内容。我安装了最新版本的 SWI-Prolog,因此 SWI-Prolog.h header 是安装最新 prolog(版本 6.6.5)时附带的最新 header 。

#-------------------------------------------------
#
# Project created by QtCreator 2014-07-05T12:38:45
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = prologFrontend
TEMPLATE = app


SOURCES += main.cpp\
mainwindow.cpp \
../../../../../../../../usr/local/share/swiprolog-c++/prolog.cpp

LIBS += -L/usr/lib/swipl-6.6.5/lib/x86_64-linux -lswipl

HEADERS += mainwindow.h

FORMS += mainwindow.ui

prologFrontend.pro 文件(Qt 创建者项目文件)的内容
#include "mainwindow.h"
#include <QApplication>
#include <prolog.hpp>


int main(int argc, char *argv[])
{
try {
Prolog_impl::prolog_init(argc, argv);

} catch(Prolog_impl::PlError &error) {

}


QApplication prog(argc, argv);
MainWindow w;
w.show();

return prog.exec();
}

main.cpp 文件的内容

我会复制 Volker Wysk 制作的头文件和源文件的全部内容,但这里太长了,不适合。如果你从我已经发布的他的网站的链接下载它,你可以看看它们。接下来是我得到的错误以及它们在他制作的 .cpp 文件中发生的两个相应的代码片段:
// part of SWI-Prolog, but not exportet by header file
// /usr/local/src/swiprolog-4.0.9/src/pl-funcs.h

//NOTE: this function is declared here but it's even not to be found in the header file
//prolog.hpp. Its implementation can't be found anywhere using the function definition
//navigation capability of Qt so, basically, its a function that does nothing.
extern "C"{
unsigned long pl_atom_to_term(term_t in_atom,
term_t out_term,
term_t out_bindings);

}

bool Prolog_impl::atom_to_term(const char* text, Term* t, list<Term::Binding>* b)
{
Term in_atom = Atom(text);
Term out_term;
Term out_bindings;

if (!pl_atom_to_term(in_atom.lsi, out_term.lsi, out_bindings.lsi))
return false;

if (t) *t = out_term;
if (b) *b = out_bindings;
return true;
}

此代码抛出的错误: /usr/local/share/swiprolog-c++/prolog.cpp:45:错误:未定义对“pl_atom_to_term”的引用 .
//Note that this code has the same issues as the one above: no implementation to be found
extern "C"{
unsigned long pl_copy_term(term_t in, term_t out);
}

Term Prolog_impl::copy_term(Term t)
{
term_t t2 = PL_new_term_ref();
if (!pl_copy_term(t.lsi, t2))
throw LogicError("copy_term(Term)", "failure calling pl_copy_term()");
return Term(t2);
}

以及此代码引发的错误: /usr/local/share/swiprolog-c++/prolog.cpp:60:错误:未定义对“pl_copy_term”的引用 .

除了必须对我已经提到的头文件进行的更改之外,我还必须在头文件中修复这行代码:
#include <SWI-Prolog.h>

对此:
#include "/usr/lib/swipl-6.6.5/include/SWI-Prolog.h"

这是因为,否则编译器会提示找不到该头文件。

我的猜测是这些函数曾经存在于较旧的 SWI-Prolog 版本中。我对如何处理这项任务没有真正的线索,我尝试阅读使用 volker 实现的其他替代方案,但就像网上几乎没有关于如何将 Prolog 与 C++ 接口(interface)的好信息。

非常感谢您花时间阅读我的问题。如果您有可行的解决方案,请告诉我。它不必是 SWI-Prolog,它可以是任何其他与 C++ 很好地接口(interface)的 Prolog 环境,并且使用或多或少与 SWI-Prolog 使用的语法相同的语法,尽管我认为语法已经是标准的所有环境。

最佳答案

swipl-win是一个工作 SWI-Prolog/Qt 界面,可移植到 Linux、MacOS、Windows 上。我还有很多 here ,但这些现在仅限于在 Linux 上运行......

我想知道为什么,除了 Qt 特定的问题,当有一个“官方”接口(interface)时,你会选择一个旧的、未维护的 C++ 接口(interface)here .该接口(interface)运行良好,基于异常处理和自动类型转换提供参数验证。然后很容易添加到界面 - 例如,从PREDICATE.h

typedef PlTerm T;
#define LOOP__ { } operator bool() { return next_solution(); }
#define query0(P) struct P : PlQuery { P() : PlQuery(#P, V()) LOOP__ };
#define query1(P) struct P : PlQuery { P(T A) : PlQuery(#P, V(A)) LOOP__ };
...

允许
query1(current_predicate)

void Completion::initialize(QSet<QString> &strings, bool reload) {
Q_UNUSED(reload)
T PRED;
for (current_predicate cp(PRED); cp; ) {
QString p = t2w(PRED);
if (p[0].isLetter())
strings.insert(p);
}
qDebug() << "Completion::initialize loaded" << strings.count();
}

关于您的具体问题,可能这些功能已经过时,您应该坚持使用 C Api(也称为外语接口(interface))记录的 here .

关于c++ - 将 SWI-Prolog 连接到 C++ 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24602416/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com