how to get the result (two prolog lists ) from prolog, given via “c++ Interface to SWI-Prolog” , and store them in a variable in c++

瘦欲@ 提交于 2019-12-11 02:12:44

问题


Hello to everyone :)
The Problem i have is how to get and store(Variable X and Y) from Prolog (via interface from swi-prolog) into a variable (c++) in visual studio

In short: I transfered a Puzzle with triangular puzzle parts into Prolog representation. This puzzle is solved by prolog. This works so far. The visual representation with each puzzle tile is done in visual studion. This is working also.

Now i want to call via Interface the prolog engine and this will return the Solution and each step(turn puzzle tile/which puzzle tile/ and where it is) during the process(done by write() in prolog). So far i can instantiate prolog call the function and get return value in console window. Also i get displayed each write() in console. BUT only in console.

Prolog Part:
X represent a List with IDs of puzzle parts
Y represent a List of rotatestates from the puzzle parts as a result of prolog
internally puzzle parts represented as:

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 i call:

if (PL_call(h2, NULL))
{
    PL_get_list_chars(h2, &fact2,CVT_ATOM|REP_UTF8);
}

I see in debug from VS at brakpoint that fact2 somehow store the result:

fact2   0x05699460 "\x2\a\x3\x5\t\x1\x4\x6\b"   char *

And its also displayed in console...but with example output:

ERROR: source_sink 2 does not exist
ERROR: source_sink 7 does not exist
ERROR: source_sink 3 does not exist
...

and if i call:

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+"---| ");
}

i get indeed the solution (from X)somehow without error in the console:

"some debug text": 2 
"some debug text": 7
"some debug text": 3
...

I tryed several other solutions but this is so far the best result i have so far...
After long Text questions again:
A) how to get Y variable content from Prolog SOLVED Below

----EDIT QUESTION------

B) how to get the write() from prolog which is displayed in console or anny other way to get a step by step output like "trace" in prolog

C) how to store A) and the write() statements into a variable or list in c++

May i run into wrong way...so you can help me out :D Thanks in advance :)


EDIT


A) i get the content of the X and Y list by calling the function "PL_get_list" For X which represents the IDs of the puzzle parts //thanks also to 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+"---| ");
    }

And for Y which represent the rotate state

    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:


Up to PL_call_predicate(), all is fine. Now, h2 is an array of two term references, h2+0 bound to [2, 7, 3, 5, 9, 1, 4, 6, 8] and h2+1 to [rechts, rechts, unten, rechts, rechts, unten, rechts, unten, rechts]. Then you do something strange: you call h2+0, basically calling

call([2, 7, 3, 5, 9, 1, 4, 6, 8])

The list is an abbreviation for consult/1, so you try to consult (load) files named 1, etc. Hence the messages.

You need to use the list iteration methods from PlList class to enumerate the elements in the array. Then you can translate each to a number or string (for the second).

When embedding (in C++) you will normally not use Prolog's I/O. You can translate individual terms to a string using PL_get_chars() and variations. If you really want to rebind I/O, there is the header SWI-Stream.h. Its usage is mostly undocumented though. You can look through the source code for examples re-binding Prolog's I/O to read/write to the swipl-win.exe console, etc. I do not think that is what you are after though.



来源:https://stackoverflow.com/questions/55955656/how-to-get-the-result-two-prolog-lists-from-prolog-given-via-c-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!