将sw - prolog连接到c++的问题
Problems interfacing SWI-Prolog to C++
我在绞尽脑汁试图使sw - prolog与c++玩得很好。现在,在我开始解释我的问题是什么之前,我想首先说明我的项目是什么,以及我选择了什么工具来开发解决方案。
我的教授给我的任务是开发一个GUI程序作为SWI-prolog的前端,这个前端是用c++开发的。我选择使用Qt来设计GUI,并使用c++作为后端来桥接sw - prolog到应用程序。这个应用程序的用户应该能够输入一些列表,然后通过prolog选择要应用于它们的操作,例如,如果我输入一个数字列表,那么通过单击一个按钮,用户将获得该列表中所有成对数字的另一个列表(如果有的话)。我正在unix操作系统上开发,更具体地说,是基于archlinux和manjaro的netrunner滚动发行版。
我做了一些研究,似乎最好的行动方案是为了接口SWI-Prolog(我也可以提到,我的教授也建议这样做),是使用Volker Wysk开发的头文件和源文件;作为参考,这里是包含这些文件的压缩文件的链接http://www.volker-wysk.de/swiprolog-c++/index.html
现在这是我的问题:如果你访问了我刚刚给你的页面,你会发现这个c++实现的SWI-Prolog接口是相当旧的:最后一次工作是在2002年。我不得不修改头文件,这样我就可以摆脱一些错误,就像将使用名称空间性病或改变# # include ostream.h包括上ostream,所以我设法让错误数到只有两个,我不能设法解决,我想我不能,因为有两个函数的实现在任何地方我找不到:声明的函数,但它应该运行的代码当他们被称为不能被发现。
我现在将列出我认为最相关的文件内容。我已经安装了最新版本的wi - prolog,因此wi - prolog .h头文件是安装最新prolog(版本6.6.5)时附带的最新头文件。
#-------------------------------------------------
#
# 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的内容。
#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: error: undefined reference to ' 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: error: undefined reference to ' pl_copy_term'.
除了我必须对我已经提到的头文件进行的更改之外,我还必须修复头文件中的这行代码:
#include <SWI-Prolog.h>
:
#include "/usr/lib/swipl-6.6.5/include/SWI-Prolog.h"
这是因为,否则,编译器会抱怨找不到头文件。
我的猜测是这些函数曾经存在于较旧的SWI-Prolog版本中。关于如何处理这个任务,我没有真正的线索,我试着阅读使用volker的实现的其他替代方案,但就像在网上几乎没有关于如何将Prolog与c++接口的好信息。
非常感谢您花时间阅读我的问题。如果你有一个有效的解决方案,请告诉我。它不一定是SWI-Prolog,它可以是任何其他与c++接口良好的Prolog环境,并且使用或多或少与SWI-Prolog使用相同的语法,尽管我认为语法已经是所有环境的标准。Package swil -win是一个工作的SWI-Prolog/Qt接口,可移植到Linux,MacOS,Windows上。我在这里有很多其他的,但它们现在仅限于在Linux上运行…
我想知道为什么,除了Qt特定的问题,你选择了一个旧的,没有维护的c++接口,当这里有一个"官方"的。这个接口工作得很好,提供了基于异常处理和自动类型转换的参数验证。然后很容易添加到接口中—例如,从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(也称为外语接口)
查看swiprolog-c++-0.1.0
的Makefile
,看起来需要使用一个特殊的链接器,称为plld
。因此,您需要使用常用的编译器来生成目标文件,然后使用该链接器来创建可执行文件。
生成文件中的plld
行如下所示:
main : main.o prolog.o test.pl
plld -o $@ -ld $(CC) $^ -lstdc++
"recipe"行展开为:
plld -o main -ld gcc main.o prolog.o test.pl -lstdc++
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用mongocxx驱动程序时包含头文件问题