Json in Prolog

% Prolog offers built-in support for JSON encoding and decoding,
% including to and from built-in and custom data types.

:- use_module(library(http/json)).

% We'll use these two compound terms to demonstrate encoding and
% decoding of custom types below.
response1(response1(Page, Fruits)) :-
    integer(Page),
    is_list(Fruits).

response2(response2(Page, Fruits)) :-
    integer(Page),
    is_list(Fruits).

main :-
    % First we'll look at encoding basic data types to
    % JSON strings. Here are some examples for atomic
    % values.
    atom_json_term(BolJSON, true, []),
    writeln(BolJSON),

    atom_json_term(IntJSON, 1, []),
    writeln(IntJSON),

    atom_json_term(FltJSON, 2.34, []),
    writeln(FltJSON),

    atom_json_term(StrJSON, "gopher", []),
    writeln(StrJSON),

    % And here are some for lists and dicts, which encode
    % to JSON arrays and objects as you'd expect.
    SlcD = ["apple", "peach", "pear"],
    atom_json_term(SlcJSON, SlcD, []),
    writeln(SlcJSON),

    MapD = json([apple=5, lettuce=7]),
    atom_json_term(MapJSON, MapD, []),
    writeln(MapJSON),

    % The JSON package can automatically encode your
    % custom data types. It will include all arguments
    % in the encoded output.
    Res1D = response1(1, ["apple", "peach", "pear"]),
    atom_json_term(Res1JSON, Res1D, []),
    writeln(Res1JSON),

    % You can use options to customize the encoded JSON.
    % Check the documentation of atom_json_term for more details.
    Res2D = response2(1, ["apple", "peach", "pear"]),
    atom_json_term(Res2JSON, Res2D, []),
    writeln(Res2JSON),

    % Now let's look at decoding JSON data into Prolog
    % terms. Here's an example for a generic data
    % structure.
    Byt = '{"num":6.13,"strs":["a","b"]}',
    atom_json_term(Byt, Dat, []),
    writeln(Dat),

    % In order to use the values in the decoded term,
    % we can access them directly.
    Num = Dat.num,
    writeln(Num),

    % Accessing nested data is straightforward in Prolog.
    [Str1|_] = Dat.strs,
    writeln(Str1),

    % We can also decode JSON into custom data types.
    % This has the advantage of adding additional
    % type-safety to our programs.
    Str = '{"page": 1, "fruits": ["apple", "peach"]}',
    atom_json_term(Str, Res, []),
    writeln(Res),
    [Fruit|_] = Res.fruits,
    writeln(Fruit),

    % In Prolog, we can directly write JSON to the standard output.
    D = json([apple=5, lettuce=7]),
    json_write(current_output, D, []).

% To run this program, save it as json_example.pl and use:
% swipl -q -t main -s json_example.pl

This Prolog code demonstrates JSON encoding and decoding using the library(http/json) module, which is commonly available in Prolog implementations like SWI-Prolog.

The program shows how to:

  1. Encode basic Prolog terms to JSON
  2. Encode lists and dicts to JSON arrays and objects
  3. Encode custom compound terms to JSON
  4. Decode JSON strings into Prolog terms
  5. Access data in decoded JSON terms
  6. Decode JSON into custom compound terms
  7. Write JSON directly to the standard output

Note that Prolog’s approach to JSON is somewhat different from Go’s. Prolog uses its built-in term structure to represent JSON, which makes working with JSON data very natural in Prolog programs. The atom_json_term/3 predicate is used for both encoding and decoding, with the direction determined by which arguments are instantiated.

To run this program, you would save it as json_example.pl and use the command:

swipl -q -t main -s json_example.pl

This will execute the main/0 predicate, which demonstrates all the JSON operations.