This
my $code = <<END_CODE;
owns(merlyn,gold).
owns(ovid,books).
owns(kudra,gold).
valuable(perl).
valuable(gold).
valuable(corinna).
query :-
owns(X,Y), valuable(Y),
writef('["%t", "%t"], ',[X,Y]).
main :-
writef('[ '),
bagof(_,query,_),
writef(']\n').
END_CODE
my $tmpfile = "deleteme.pro";
open(TMP,">$tmpfile"); print TMP $code; close(TMP);
my $result = `pl -q -f deleteme.pro -t main`;
unlink($tmpfile);
print $result;
yields this
[ ["merlyn", "gold"], ["kudra", "gold"], ]
using
SWI-Prolog.
Perl is great at generating code, handing it to an industrial-strength backtracking engine, and scraping the result (though there is also
Language::Prolog::Yaswi
et.al.).