Search code examples
jsonprologswi-prolog

How to turn prolog predicates into JSON?


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!


Solution

  • 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.