Я пытаюсь обработать список номеров, которые я получаю из интерфейса GUI, созданного в Qt. В частности, я хочу вернуть пользователю, в ярлыке, список всех чисел, которые есть даже в его списке ввода. Благодаря пользователю CapelliC мне удалось включить все файлы и библиотеки, чтобы заставить SWI-Prolog работать изнутри C ++, и сейчас я пытаюсь разработать программу.
Требуется, чтобы я использовал интерфейс C ++ к Прологу таким образом, чтобы я получал список от пользователя через объект QLineEdit, отправлял список в механизм Пролога, а затем Пролог должен возвращать в программу C ++ результирующий список пар ,
Я уже сделал правило, которое извлекает пары из списка и возвращает его как другой список. Это содержимое моего файла manejoListas.pl, базы знаний SWI-Prolog для моей программы:
pares(Lista,ListaPares):-findall(Numero,(member(Numero,Lista),mod(Numero,2)=:=0),ListaPares).
Это работает правильно в SWI-Prolog. Теперь я хочу загрузить этот файл .pl в мою программу на C ++ и Qt, отправить список ввода в это правило и получить результирующий список, указанный аргументом ListaPares, в мой интерфейс C ++, чтобы я мог показать его пользователю.
Я прочитал документацию по интерфейсу иностранных языков и не смог найти то, что мне нужно для решения этого конкретного сценария. Это то, что я до сих пор слепо основывал на неполном «учебном пособии», которое я нашел у кого-то на YouTube, который не удосужился объяснить, что он делает для другой не связанной проблемы, главным образом, найти факториал числа, используя Qt, C ++ и Пролог.
void MainWindow::on_btnPares_clicked()
{
QString listaEntrada = ui->txtListaEntrada->text();
term_t listaEntrada, listaPares, term;
functor_t paresFunc;
listaEntrada = PL_new_term_ref();listaPares = PL_new_term_ref();
term = PL_new_term_ref();
PlCall("consult('manejoListas.pl')"); //I assume this opens my knowledgebase file so that i can work with it
paresFunc = PL_new_functor(PL_new_atom("pares"), 2);
PL_cons_functor(term, paresFunc, listaEntrada, listaPares);
if(PL_call(term, NULL)) {
PL_get_string()
}}
Я не могу продвинуться, я не знаю, как передать список в SWI-Prolog или как составить правильную консультацию, которую я должен отправить в Prolog, или как получить ответ. Эта программа должна вести себя точно так же, как если бы я запустил следующую консультацию в SWI-Prolog:
?- pares([2,4,8,9],X).
X = [2, 4, 8].
Заранее благодарю за любую помощь, которую вы можете оказать.
Лучше избегать смешивания интерфейса C — т. Е. Term_t, functor_t, PL_new_term_ref () и т. Д. — и C ++ — т. Е. PlCall () и т. Д.
Ваш код теперь явно не компилируется — может быть, вы немного разочарованы сложностью, но переведите дыхание и продолжайте изучать документацию …
Посмотреть класс PlTail На странице документации приведен простой пример кода, необходимого для построения списка. OTOH, если вы можете предположить, что список синтаксически правильный, некоторые встроенные функции более высокого уровня могут упростить вашу задачу. Например, этот фрагмент требует ввода списка в виде чисел, разделенных запятыми:
try {
QString numbers = QInputDialog::getText(0, "Input numbers separed by comma", "Numbers");
PlTerm SQLIST = PlAtom(qPrintable("[" + numbers + "]")), NUMLIST, _, SUM;
if (PlCall("atom_to_term", PlTermv(SQLIST, NUMLIST, _))) {
if (PlCall("sum_list", PlTermv(NUMLIST, SUM))) {
QMessageBox::information(0, "sum",
QString("as string: %1\nas number: %2").arg((const char*)SUM).arg((long)SUM));
}
}
}
catch(PlException ex) {
QMessageBox::critical(0, "exception", (const char*)ex);
}
а затем показывает, как вернуть значения — интерфейс C ++ использует определенный стиль для преобразования типов и извлечения значений. Благодаря такому стилю мы можем получить очень компактный код, даже при наличии большого «несоответствия непостоянства», существующего между Prolog и C ++ (но здесь я показал расширенный код без каких-либо ярлыков, которые я обычно использую).
Обратите внимание на блок try / catch: он избежит многих проблем, перехвата синтаксических и семантических ошибок — именно так, как вы получаете в интерактивной оболочке Prolog.
Последний совет: всегда проверяйте возвращение PlCall — иногда ваш код может потерпеть поражение без исключений …