I wonder if there's a way to return a JSON object in SWI-Prolog, such that the predicate names become the keys, and the instantiated variables become the values. For example:
get_fruit(JS_out):-
apple(A),
pear(P),
to_json(..., JS_out). # How to write this part?
apple("Gala").
pear("Bartlett").
I'm expecting JS_out
to be:
JS_out = {"apple": "Gala", "pear": "Bartlett"}.
I couldn't figure out how to achieve this by using prolog_to_json/3
or other built-in functions. While there are lost of posts on reading Json into Prolog, I can't find many for the other way around. Any help is appreciated!
Given hard coded facts as shown, the simple solution is:
get_fruit(JS_out) :- apple(A), pear(P), JS_out = {"apple" : A, "pear": B}.
However, in Prolog, you don't need the extra variable. You can write this as:
get_fruit({"apple" : A, "pear": B}) :- apple(A), pear(P).
You could generalize this somewhat based upon two fruits of any kind:
get_fruit(Fruit1, Fruit2, {Fruit1 : A, Fruit2 : B}) :-
call(Fruit1, A),
call(Fruit2, B).
With a bit more work, it could be generalized to any number of fruits.
As an aside, it is a common beginner's mistake to think that is/2
is some kind of general assignment operator, but it is not. It is strictly for arithmetic expression evaluation and assumes that the second argument is a fully instantiated and evaluable arithmetic expression using arithmetic operators supported by Prolog. The first argument is a variable or a numeric value. Anything not meeting these criteria will always fail or generate an error.