Sample queries in functional syntax on toplevel query

My pack pac was aimed at clojure in Prolog. The latest version is 1.7.4. I have noticed that functional syntax of the pac works also on toplevel query on terminal, though I don’t understand well why it works. Usually I use it while editing on Emacs (ediprolog.el). I hope you could reproduce the sample queries below on terminal. Unfortunately I could post only sample queries for now, without boring explanations.

At terminal
% swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.1.16-37-ga0900ca3d)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- use_module(library(pac)).
true.

?- module(pac).
true.

pac:  ?- append([1,2])@[3,4]@V.
V = [1, 2, 3, 4].

pac:  ?- append@X@Y@[1,2,3].
X = [],
Y = [1, 2, 3] ;
X = [1],
Y = [2, 3] ;
X = [1, 2],
Y = [3] ;
X = [1, 2, 3],
Y = [] ;
false.

pac:  ?- flip(is)@(1+2)@V.
V = 3.

pac:  ?- eval@(append@[1,2]@[3,4])@X.
X = append([1, 2], [3, 4]).

pac:  ?- eval@(:append@[1,2]@[3,4])@X.
X = [1, 2, 3, 4].

pac:  ?- eval(:append@[1,2]@[3,4], X).
X = [1, 2, 3, 4].

pac:  ?- call(append@[1,2]@[3,4]@X).
X = [1, 2, 3, 4].

pac:  ?- call@(append@[1,2]@[3,4]@X).
X = [1, 2, 3, 4].

pac:  ?- #(:flip@flip(is))@X@(1+2).
X = 3.
Emacs (ediprolog.el)
% ?- append@X@Y@[a,b].
%@ X = [],
%@ Y = [a, b] ;
%@ X = [a],
%@ Y = [b] ;
%@ X = [a, b],
%@ Y = [] ;
%@ false.

% ?- (=)@X@2.
%@ X = 2.

% ?- =(X)@2.
%@ X = 2.

% ?- flip(is)@(1+2+3)@X.
%@ X = 6.

% ?- eval(:flip(is)@(1+2+3), V).
%@ V = 6.

% ?- eval@(:flip(is)@(1+2+3))@V.
%@ V = 6.

% ?- #(:flip@(:flip@(flip(is))))@(1+2+3)@F.
%@ F = 6.

% ?- #(:flip@(flip(is)))@V@(1+2+3).
%@ V = 6.

% ?- #(:flip@(:flip@is))@V@(1+2+3).
%@ V = 6.

% ?- call(flip(is)@(1+2+3)@V).
%@ V = 6.

% ?- call@(flip(is)@(1+2+3)@V).
%@ V = 6.

% ?- flip(is)@(1+2+3)@V.

% ?- call(flip(is), (1+2+3), V).
%@ V = 6.

% ?- call(flip(is) @ (1+2+3), V).
%@ V = 6.

% ?- #(call @ flip(is) @ (1+2+3)) @ V.
%@ V = 6.

% ?- permutation([1,2,3], P), show(flip(P, append)), fail.
%@ pac:pac#54, where
%@ pac:pac#54(A,B,C):-pac:append(A,B,C)
%@ pac:pac#55, where
%@ pac:pac#55(A,B,C):-pac:append(A,C,B)
%@ pac:pac#56, where
%@ pac:pac#56(A,B,C):-pac:append(B,A,C)
%@ pac:pac#57, where
%@ pac:pac#57(A,B,C):-pac:append(B,C,A)
%@ pac:pac#58, where
%@ pac:pac#58(A,B,C):-pac:append(C,A,B)
%@ pac:pac#59, where
%@ pac:pac#59(A,B,C):-pac:append(C,B,A)
%@ false.

I’m sorry to say that something must be missing in pac.
On a (relatively) clean Windows machine, after a successul

:- pack_install(pac).

I get a broken system if I attempt to

:- use_module(library(pac)).
errors...
?- use_module(library(pac)).
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:42:
ERROR:    source_sink `'/users/a_user_name/.config/cgi-config'' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:42:
Warning:    Goal (directive) failed: '$pac$':(prolog_load_context(directory,_2198),setup_root_home_user(_2198),setup_cgi_config)
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:80:
ERROR:    source_sink `pac('expand-pac')' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:80:
Warning:    Goal (directive) failed: '$pac$':use_module(pac('expand-pac'))
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:81:
ERROR:    source_sink `util('env-dict')' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:81:
Warning:    Goal (directive) failed: '$pac$':use_module(util('env-dict'))
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:82:
ERROR:    source_sink `util(file)' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:82:
Warning:    Goal (directive) failed: '$pac$':use_module(util(file))
true.```

After that, I must quit, since the REPL gets broken:

?- ls.
ERROR: expand_query/4: Unknown procedure: pac:expand_query/3
ERROR:   However, there are definitions for:
ERROR:         expand_query/4

Maybe you should set the appropriate search paths for your pack, or are the source where cgi_eqns(Eqns) etc are defined really lost ?

It seems that I have uploaded a wrong version, which is for prolog cgi in some host machine. I will check soon later.
If my guess is the case, fixing may be easy. Otherwise, it may be serious.

Thanks for reporting, and I am sorry for your taking time for this trouble.

Edit
I have found another cofiguration mistake. Sorry.

I have updated the pack pac to 1.7.7, with hope it works.
If my guess is correct, pac 1.7.5 also works if you put
a dummy file ~/.config/cgi-config.pl
with this two lines.

:- module(config, [cgi_eqns/1]).
cgi_eqns([]).

Alas, it’s not working.

Seems the problem is not more related to cgi-config.pl, but your suggestion about ~/.config/cgi-config.pl make me think that you could have some implicit dependencies on *nix folders structure. Anyway, I created the ~/.config/cgi-config.pl file with the content, but the errors didn’t changed.

errors...
?- pack_list_installed.
Installed packages (2):

i pac@1.7.7                 - Anonymous predicates expansion utility
i scasp@0.10.0              - Goal directed ASP solver
true.

?- use_module(library(pac)).
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:45:
ERROR:    setup_cgi_config/0: Unknown procedure: '$pac$':file_exits/1
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:45:
Warning:    Goal (directive) failed: '$pac$':(prolog_load_context(directory,_47548),setup_root_home_user(_47548),setup_cgi_config)
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:83:
ERROR:    source_sink `pac('expand-pac')' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:83:
Warning:    Goal (directive) failed: '$pac$':use_module(pac('expand-pac'))
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:84:
ERROR:    source_sink `util('env-dict')' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:84:
Warning:    Goal (directive) failed: '$pac$':use_module(util('env-dict'))
ERROR: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:85:
ERROR:    source_sink `util(file)' does not exist
Warning: c:/users/a_user_name/appdata/local/swi-prolog/pack/pac/prolog/pac.pl:85:
Warning:    Goal (directive) failed: '$pac$':use_module(util(file))
true.
...
ERROR:    setup_cgi_config/0: Unknown procedure: '$pac$':file_exits/1
...

file_exits should be 'file_exist` Is this a typo ?

Yes. I have amended.
How many mistakes I am making !
Thanks.

I changed file_exits to exists_file/1 and it’s working…
So, now I’m just wondering what pac:flip is about :slight_smile: and how to cleanly quit the pac: prompt

Yes. In fact, assuming the “nix” folders structure, file_search_path
were generated from some module prefix skeletal tree with its root directory and the home directory, which could not work for non “nix” folders structure. I have no idea
for non “nix” folders structure.

Don’t worry, it works in Windows as well

A motivation of this post was my “rediscovery” that four primitives
call, eval(:), apply(@), and arguments scoping( #) works in harmony with
the prolog term structure for functional syntax in Prolog, and no other
primitives (pragma ?) seem necessary as far as my experiences concerned, which is, though, limited of course.

If remember correctly, once flip/1 was built-in in some Prolog system to swap arguments like this.

?- flip((1+2+3) is X ).
X = 6.

As I could not find such flip/1 builtin in swipl, I wrote it for my DCG form based snippet handler for example. The flip works for not only binary predicate call but also
for ones of any arity:

flip([j1, ..., jn], g(a1, ..., an))

is equivalent to

g(b1, ..., bn),

where bk = a(jk). For example, flip([2,1], is(1+2, X)) runs as X is 1+2. (n = 2)

I am not sure that the following is relevant to your second question, but
it might be better that @-operator should be declared in the user module
for writing queries in the functional syntax. I thought that user defined operators in a package should not be declared in the user module to avoid conflicts
against other packages, though I am not sure on this.

?- context_module(X).
X = user.

?- is @X @(1+2).
ERROR: Syntax error: Operator expected
ERROR: is
ERROR: ** here **
ERROR:  @X @(1+2) . 
?- @(@(is, X), 1+2).
X = 3.

?- pac:current_op(X, Y, @).
X = 10,
Y = fy ;
X = 200,
Y = yfx.

?- pac:current_op(X, yfx, @), user:op(X, yfx, @).
X = 200.

?- is @X @(1+2).
X = 3.

```

Perhaps again same problem. I thought I had changed so that
it also works without ~/.config/cgi-config file. Thanks for reporting.
I will fix and update to pac-1.8.6 with other bug fix and new stuff on ZDD.

If you have not a file ~/.config/cgi-config.pl then
replace the whole content of the pac.pl with the following lines.
I hope this fix the trouble.

Replace pac.pl by this
:- module('$pac$', []).
:- user:set_prolog_flag(encoding, utf8).
:- user:set_prolog_flag(optimise, true).
:- user:set_prolog_flag(qcompile, auto).
:- user:set_prolog_flag(editor, emacsclient).
:- user:set_prolog_flag(history, 0).
:- setenv('EDITOR', emacsclient).

:- use_module(library(macros)).

#define(local_cgi_config, '/.config/cgi-config').

:- dynamic user:file_search_path/2.
:- multifile user:file_search_path/2.

:- use_module('setup-aux').

pac_directories(
		[	(pac_root : []) -
			 [	test:test,
				:(prolog) -
					[	pac		: pac,
						util	: util,
						zdd		: zdd,
						tmp		: tmp,
						gb		: "util/grobner",
						other	: other
					]]]
			   ).

setup_root_home_user(Dir):-
	split_string(Dir, /, '',  [_, Root, User|_]),
	atomic_list_concat([/,Root,/,User], Home),
	setenv(home, Home),
	setenv(user, User),
	setenv(pac_root, Dir).

setup_cgi_config:-  getenv(home, H),
	atom_concat(H, #local_cgi_config, Mod),
	atom_concat(Mod, ".pl", Modpl),
	(	exists_file(Modpl) ->
		use_module(Mod),
		cgi_eqns(Eqns),
		maplist(setup_env, Eqns)
	;	true
	),
	pac_directories(DirStr),
	mk_file_search_path(DirStr).

:- prolog_load_context(directory, Dir),
	setup_root_home_user(Dir),
	setup_cgi_config.

% ?- getenv(user, U), getenv(home, H), getenv(host_user, HU).
% :- pac_directories(DirStr),
% 	mk_file_search_path(DirStr).

% :- set_prolog_flag(color_term, false).
% :- set_stream(user_input, tty(true)).
% :- set_prolog_flag(tty_control, false).

user: enable_pac_query	:- set_prolog_flag(pac, true).
user: disable_pac_query	:- set_prolog_flag(pac, false).
user: chk_pac_query	:- current_prolog_flag(pac, true).

user: enable_odict	:- set_prolog_flag(odict, true).
user: disable_odict	:- set_prolog_flag(odict, false).
user: chk_odict		:- current_prolog_flag(odict, true).

:- use_module([
		library(clpfd),
		library(dif),
		library(lists),
		library(sort),
		library(ordsets),
		library(url),
		library(ugraphs),
		library(readutil),
		library(apply),
   		library(apply_macros)
	      ]).
%
user: expand_query(X, Y, Z, Z) :- user:chk_pac_query, !,
	'$current_typein_module'(C),
	pac:expand_query(C, X, Y).
user: expand_query(X, X, Z, Z).

:- use_module(pac('expand-pac')).
:- use_module(util('env-dict')).
:- use_module(util(file)).

:- user:enable_pac_query.
:- user:enable_odict.