как получить результат (два списка прологов) из пролога, передаваемого через «c ++ Interface to SWI-Prolog», и сохранить их в переменной в c ++ - PullRequest
2 голосов
/ 02 мая 2019

Привет всем :)
Проблема, которую я имею, состоит в том, как получить и сохранить (переменные X и Y) из Prolog (через интерфейс из swi-prolog) в переменную (c ++) в visual studio

Короче говоря: я перевел Пазл с треугольными частями головоломки в представление Пролога. Эта загадка решена прологом. Это работает до сих пор. Визуальное представление с каждой плиткой головоломки сделано в визуальном исследовании. Это тоже работает.

Теперь я хочу вызвать через интерфейс механизм пролога, и он будет возвращать Решение и каждый шаг (переворачивать мозаику головоломки / какую мозаику головоломки / и где она находится) во время процесса (выполняется write () в прологе). Пока что я могу создать пролог, вызвать функцию и получить возвращаемое значение в окне консоли. Также я отображаю каждую запись () в консоли. НО только в консоли.

Часть пролога:
X представляет список с идентификаторами частей головоломки
Y представляет список вращающихся состояний из частей головоломки в результате пролога
детали внутренней головоломки, представленные в виде:

teil (ID, side_a, side_b, side_c).

teil(8,lsh,hbsh,gsv).
prolog call:
?- puFlaeche(X,Y).
Result:
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 на brakpoint, что 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) как получить содержимое переменной Y из Prolog решено ниже

---- РЕДАКТИРОВАТЬ ВОПРОС ------

B) как получить write () из пролога, который отображается в консоли, или любой другой способ получить пошаговый вывод, например «trace» в прологе

C) как сохранить операторы A) и write () в переменной или списке в c ++

Могу ли я столкнуться с неправильным путем ... так что вы можете мне помочь: D Заранее спасибо:)


EDIT


А) Я получаю содержимое списка X и Y, вызывая функцию "PL_get_list" Для X, который представляет идентификаторы частей головоломки // спасибо также 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++;
        }

1 Ответ

2 голосов
/ 05 мая 2019

До 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. Вы можете перевести отдельные термины в строку, используя PL_get_chars() и варианты. Если вы действительно хотите перепривязать ввод / вывод, есть заголовок SWI-Stream.h. Его использование в основном недокументировано, хотя. Вы можете просмотреть исходный код для примеров повторной привязки ввода / вывода Prolog для чтения / записи на консоль swipl-win.exe и т. Д. Однако я не думаю, что это то, что вам нужно.

...