问题
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