s(CASP) 'denial' constraints don't work inside SWI prolog

If I run the ‘denials’ example from the s(CASP) 2021 tutorial paper inside SWI prolog :

:- use_module(library(scasp)).
:- style_check(-discontiguous).
:- style_check(-singleton).
:- set_prolog_flag(scasp_unknown, fail).

opera(D) :- not home(D).
home(D) :- not opera(D).
home(monday).

:- baby(D), opera(D).
	
baby(tuesday).

… I get:

?- ['/users/mac/workspace-prolog/law/BNA/test2.pl'].

ERROR: /Users/MAC/workspace-prolog/law/BNA/test2.pl:9:

ERROR: '<meta-call>'/1: Unknown procedure: baby/1

Warning: /Users/MAC/workspace-prolog/law/BNA/test2.pl:9:

Warning: Goal (directive) failed: user:(baby(_59506),opera(_59506))

true.

?- ?+- opera(D).

% s(CASP) model

{ not home(D), opera(D)

},

D ∉ [monday] .

… the denial is not recognized and disregarded, yielding the same result as if no such constraint was present.

If I run the same program through s(CASP) natively, from the command line, I get:

Erics-MBP-4:scasp MAC$ ./scasp -i /users/mac/workspace-prolog/law/BNA/test2.pl

casp 1 ?- opera(D).
% Query
?- opera(D).
% ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
%                         Answer 1 (0.001 sec)                          
% ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
% Model
{ not baby(_ | {_ ∉ [tuesday]}),         home(tuesday),
  baby(tuesday),                         opera(D | {D ∉ [monday,tuesday]}),
  not home(D | {D ∉ [monday,tuesday]}),  not opera(tuesday)
}
% Bindings
D = D | {D ∉ [monday,tuesday]} ? 


casp 2 ?- halt.

[ … after edit of test2.pl to comment out “:- baby(D), opera(D).”

Erics-MBP-4:scasp MAC$ ./scasp -i /users/mac/workspace-prolog/law/BNA/test2.pl

casp 1 ?- opera(D).
% Query
?- opera(D).
% ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
%                         Answer 1 (0.000 sec)                          
% ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
% Model
{ not home(D | {D ∉ [monday]}),  opera(D | {D ∉ [monday]})
}
% Bindings
D = D | {D ∉ [monday]} ?

The term I know them by is global constraints. And yes, they are different when using s(CASP) inside Prolog. You need to write this. There is not much choice as :- term. is used to define directives.

false :- baby(D), opera(D).

Note that it still works a bit different. The stand-alone version considers all global constraints. The embedded version only considers global constraints that have some overlap in their call tree with the given query. I.e., it expands the call tree of both the query and all global constraints and adds all global constraints whose call tree has at least one predicate in common with the call tree of the query. So, if you have a non-satisfied global constraint that is completely independent from the query, the stand-alone application will give no answer and the embedded version will.

Thank you.

Is there also an alternate way to specify “#show -p” in the embedded version? It allows “#show not p”, but gives an error on “#show -p” (Type error: atom' expected, found -p’ (a compound)).

Using #show '-p'. should work. From the code it seems this must be #show '-p'/0. though. Note that the embedded version normally uses :- show '-p'/0. Pushed a fix to avoid the need for quotes.