C++/ Prolog

I want to put the result of thid operation in a Variable. This code just Print the result but i want to get it and put into a variable

while (PL_next_solution(query)){
}

You might use this as a starting point:

example.cpp

#include <SWI-cpp2.h>
#include <stdio.h>

int main(int argc, char **argv)
{ PlEngine e(argc, argv);

  PlTermv Args(2);
  if(!Args[0].unify_string("123"))
  {
    printf("Something is broken.\n");
    return -1;
  }

  PlQuery q("member", Args);
  if(!q.next_solution())
  {
    printf("Query failed.\n");
    return -1;
  }
  printf("%s\n", Args[1].as_string().c_str());

  if(!q.next_solution())
  {
    printf("Query failed.\n");
    return -1;
  }
  printf("%s\n", Args[1].as_string().c_str());

  return 0;
}

Compile with swipl-ld example.cpp, run with ./a.out -q. The -q just suppresses the Welcome message.

I find the docs for the class PlQuery rather user friendly.

Moreover, the example for PlQuery::cut() is interesting.
Here is the snippet, modified by me to explain the caveat, note the comment about ~PlQuery (the destructor)

PREDICATE(list_modules, 0)
{ PlTermv av(1);

  // assume we want just the first 10...
  int counter = 0;
  PlQuery q("current_module", av);
  while( q.next_solution() ) {
    cout << av[0].as_string() << endl;
    if (++counter == 10)
      break;
  }
  return true;
  // ~PlQuery (the destructor) will cut here the eventual choice point we could have left...
}

Because this is C++, you can use iostream instead of stdio.h (BTW, this should be cstdio), and that allows cout << Args[1].as_string() << endl;.

Also, for debugging inside an extension written in C++, I suggest using Sdprintf() instead of printf().

1 Like

I don’t think we have an <iostream> abstraction of Prolog’s streams for C++, do we?

I admit that my “starting” point has some room for improvement, but I hope it is good enough from a pedagogical point of view. Do I understand correctly that Sdprintf does not apply in this particular example, since swipl is embedded (as compared to an extension).

No, there is no iostream abstraction in the C++ API and I have no plans to do it (for one thing, I’d have to resurrect memories from decades ago about how to do it). If you want to use iostream, one way is to use <sstream> and then use Sdprintf() to output the resulting string (using c_str(), of course).

Sdprintf() simply outputs to the Prolog streams (which typically then output to standard C files). So, in most cases, you won’t notice a difference between using fprintf(stderr, ...) and Sdprintf(), but if the Prolog code (including its foreign code) does output, then interleaving of output could be different.

1 Like