我很機智地試圖讓SWI-Prolog在C++中表現出色。現在,在我開始準確解釋我的問題之前,我想首先說明我的項目是什麼以及我選擇哪些工具來開發解決方案。將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接口的C++實現相當老:上次是在2002年工作。我不得不修改頭文件,以便我可以擺脫一些錯誤,比如使用命名空間std或將#include ostream.h更改爲#include ostream,所以我設法得到的錯誤計數只有兩個,我無法設法解決,而我認爲我將無法執行,因爲有兩個函數的實現我找不到任何地方:函數聲明,但無法找到它被調用時運行的代碼。
我現在將列出我認爲最相關的文件的內容。我安裝了最新版本的SWI-Prolog,因此SWI-Prolog.h頭文件是安裝最新的prolog(6.6.5版)的最新版本。
的prologFrontend.pro文件#-------------------------------------------------
#
# 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
內容(Qt Creator的項目文件)中的main.cpp文件的
#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();
}
內容
我將複製的全部內容由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++接口的良好信息一樣。
非常感謝您花時間閱讀我的問題。如果您有解決方案,請告訴我。它不一定是SWI-Prolog,它可以是任何其他Prolog環境,它與C++很好地接口,並且或多或少地使用與SWI-Prolog使用的語法相同的語法,儘管我認爲語法對所有人來說都是標準的環境。
有些東西我不明白。如果你參考這個鏈接http://www.swi-prolog.org/FAQ/CppBinding.html,它說實際上有兩個C++綁定:一個包含在swi-prolog安裝中,由Jan Wielemaker(i假設這是你所指的那個),另一個是由Volker Wysk製作的。現在,引用Jan Wielemaker的話,他說:「如果事實證明,Volkers的工作正常並且更好,它很可能會取代我的版本。」除了SWI-Prolog.h之外,我需要在我的項目中包含哪些庫,才能使這一切工作正常?任何.so圖書館? – Greg
好吧,注意:**如果**證明Volkers的工作正常並且更好... Jan已經發展了C++接口,因爲我們在整合Qt的同時一起工作。 C++接口,它是'僅頭'組件,你不需要任何額外的庫。我會在您鏈接的頁面上發佈一條維基評論,指出您遇到的問題。 – CapelliC
我已在[該頁面](http://www.swi-prolog.org/FAQ/CppBinding.html)上發表評論。我想知道你認爲這是否合適。 – CapelliC