Scasp/2: How to retrieve arithmetic constraints?

I’m using: SWI-Prolog version 9.2.9

I want the code to: save s(CASP) models to a file, but including arithmetic constraints like {Value=<50}. When I use SWISH or the “?- ?” shorthand, where the s(CASP) results are printed to the UI, every model is accompanied by the respective arithmetic constraints. E.g., you take this program (SWISH -- SWI-Prolog for SHaring) and run “? test(Value).” you’ll receive “{Value=<50}” above the s(CASP) model.

But what I’m getting is: if I use “scasp(goal, model(Model))” instead and print Model to a file, the “{Value=<50}” string is not included in the file.

My code looks like this:

:- use_module(library(filesex)).      % for ensure_directory/1
:- use_module(library(lists)).        % (optional, but often loaded anyway)

%!  save_models(+Goal) is det.
%
%   Run s(CASP) on Goal and save every Model returned
%   to   a   file   ../temp/<Goal>.txt.   Each  model  is
%   written on its own line as a Prolog term.
%
%   Examples:
%       ?- save_models(some_goal).
%       ?- save_models(parent(alice, Bob)).
%
save_models(Goal) :-
    % Convert the (possibly compound) Goal to an atom for the filename
    term_to_atom(Goal, GoalAtom),
    % Build target directory and file name
    atomic_list_concat(['../temp/', GoalAtom, '.txt'], FilePath),
    % Make sure the directory exists
    file_directory_name(FilePath, Dir),
    ensure_directory(Dir),
    % Open the file and ensure it is closed afterwards
    setup_call_cleanup(
        open(FilePath, write, Out),
        forall(
            scasp(Goal, [model(Model)]),
            (   write_term(Out, Model,
                           [ quoted(true)
                           , numbervars(true)
                           ]),
                nl(Out)
            )
        ),
        close(Out)
    ).

The constraints are in attributed variables, which are by default ignored by write_term/3. The trick is to use copy_term/3 to extract the constraints in their human-readable form.

P.s. You need to add fullstop(true) to the options if you want to read it back :grinning_face: