# A swipl command shell options to use pack zdd library to counting families of sets

**URL:** <https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655>\
**Category:** General\
**Created:** [August 1, 2024, 8:34am UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655 "2024-08-01T08:34:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 1, 2024, 8:34am UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/1 "2024-08-01T08:34:50Z")

</div>

Assuming pack pac 1.9.6 is installed by `pack_install/2` under `~/.local/share/swi-prolog`, query log below on counting family of sets expressed in zdd terms should be reproduced.

Nothing particular has been added to zdd library of mine for one year in my slow life, but only recently I am realizing usefulness swipl command line options (thanks to @jan), and this is first-step exercise to use it. As next exercise, I have in mind to try command line version which uses arguments. Advice on this are welcome.

In the below, test file “zdd-eval-count.pl” should be put under appropriate directory,  
and the path variable EVALCOUNT to be set in the shell script ‘count-zdd-samples-local’

```prolog
% count-zdd-samples-local
#(a)=1
#((a+b)*(a+c))=4
#((a+b)*(c+d))=4
#(a*b*c*a*b)=1
#(a*b+c)=2
#(a+b-(c+d))=2
#((a+b)/a)=1
#((a+b)//a)=1
#((a*c+b)//a)=1
#(*(numlist(1,5)))=1
#(*([1,2,3]))=1
#(+[0,1,2]* +[0,1,2])=6
#(+[1,b,1,1]* +[1,a])=4
#(+[1,2,3,4])=4
#(+numlist(1,100)* +numlist(1,100))=5050
#((a+b)*(a+c)+a*b)=4
#(pow([a,b])-(c+d))=4
#(pow([a,b])//(a+b))=3
#(pow([a,b])/(a+b))=2
#(pow(charlist(a,c)))=1
#(pow(append([1,2],[a,b])))=16
#(pow(subtract([1,2,3],[1,2,a])))=2
#(+atomlist($a(1,10)))=10
#(pow(atomlist($a(1,10))))=1024

```

```prolog
#! /usr/bin/env sh

ROOT="${HOME}/.local/share/swi-prolog/pack/pac/prolog"
PAC="${ROOT}/pac"
SETUPAUX="${ROOT}/setup-aux"
EVALCOUNT=${HOME}/devel/zdd/prolog/zdd/zdd-eval-count
COUNT='zdd_count:count_all'
swipl -q -l ${SETUPAUX} -l ${PAC} -l ${EVALCOUNT} -g ${COUNT} -t halt

```

```prolog
% cat zdd-eval-count.pl

:- module(count_zdd, [count_all/0]).

% ?- count_all.

:- use_module(zdd(zdd)).

count_all:- forall(zdd_term(E), (zmod:zdd, once(count_one(E)))).
%
count_one(E):-
	call_with_time_limit(10, (X<< E, card(X, C))),
	writeln(#(E)=C).

% examples of zdd terms.
zdd_term( a ).
zdd_term( (a+b)*(a+c)).
zdd_term( (a+b)*(c+d)).
zdd_term( a*b*c*a*b).
zdd_term( a*b + c).
zdd_term( (a+b)-(c+d)).
zdd_term( (a+b)/a).
zdd_term( (a+b)//a).
zdd_term( (a*c+b)//a).
zdd_term( *(numlist(1, 5))).
zdd_term( *([1,2,3])).
zdd_term( +[0, 1, 2]* (+[0, 1, 2])).
zdd_term( +[1,b,1,1] * (+[1,a])).
zdd_term( +[1,2,3,4]).
zdd_term( +(numlist(1,100)) * +(numlist(1,100))).
zdd_term( (a+b)*(a+c) +(a*b)).
zdd_term( pow([a,b])-(c+d)).
zdd_term( pow([a,b])//(a+b)).
zdd_term( pow([a,b])/(a+b)).
zdd_term( pow(charlist(a, c))).
zdd_term( pow(append([1,2],[a, b]))).
zdd_term( pow(subtract([1,2,3], [1,2,a]))).
zdd_term( +(atomlist($a(1,10)))).
zdd_term( pow(atomlist($a(1,10)))).

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 1, 2024, 9:17am UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/2 "2024-08-01T09:17:47Z")

</div>

You can make this a lot simpler these days by adding a directory `app` in your pack and a file zdd.pl. Now.

```
 swipl zdd ...

```

runs this zdd.pl, so you can use Prolog’s commandline argument processing to so whatever you want. See the apps in SWI-Prolog’s own `app` directory for inspiration.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 1, 2024, 12:31pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/3 "2024-08-01T12:31:41Z")

</div>

> [@jan](#):
>
> You can make this a lot simpler these days by adding a directory `app` in your pack and a file zdd.pl. Now.
> 
> ```prolog
> swipl zdd ...
> 
> ```

Thanks. I’m trying the modern way, but I got the following.

```prolog
% swipl zdd hello
ERROR: Prolog initialisation failed:
ERROR: file `zdd' does not exist

```

But I think I will fix this soon. BTW, I found the pac-1.9.6 has invited a wrong ‘use\_module’. I must update soon.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 1, 2024, 2:22pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/4 "2024-08-01T14:22:28Z")

</div>

> [@kuniaki.mukai](#):
>
> `ERROR: file `zdd’ does not exist`

My mistake. This does not yet work for packs. I’ll look into that.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 1, 2024, 3:37pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/5 "2024-08-01T15:37:59Z")

</div>

> [@jan](#):
>
> My mistake. This does not yet work for packs. I’ll look into that.

Take time. I’m not in hurry, though interested in the app functionality, which was new to me.

A simple test I have tried is this ( for pac-1.9.7 with the wrong use of use\_module fixed.)

```prolog
% cat ~/.local/share/swi-prolog/pack/pac/app/hello.pl
:-initialization(main, main).
main(A):- writeln(A).

% swipl hello world
ERROR: Prolog initialisation failed:

```

ERROR: file `hello’ does not exist

%

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 1, 2024, 11:42pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/6 "2024-08-01T23:42:17Z")

</div>

I have managed to write a swi-prolog script which counts the number of sets of a given family of sets in zdd term expression as argument of the script.  
It is in an obsolete way of passing argument, but I have no idea for now to improve to smarter one.

```prolog
#!/usr/bin/env swipl -q -t halt

% usage: testscript.pl -- "pow([1,2,3,4])"
% #(pow([1,2,3,4]))=16

:- initialization(main, main).
:- expand_file_name('~/.local/share/swi-prolog/pack/pac/prolog/setup-aux', [AUX|_]),
   use_module(AUX).
:- expand_file_name('~/.local/share/swi-prolog/pack/pac/prolog/pac', [PAC|_]),
   use_module(PAC).
:- use_module(zdd(zdd)).
:- expand_file_name('~/devel/zdd/prolog/zdd/zdd-eval-count', [EVALCOUNT|_]),
   use_module(EVALCOUNT).

main(Args) :- atomics_to_string(Args, ' ', S),
			  term_string(Exp, S),
			  count_zdd:eval_count_one(Exp).

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 2, 2024, 8:22am UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/7 "2024-08-02T08:22:30Z")

</div>

> [@kuniaki.mukai](#):
>
> ```prolog
> :- expand_file_name('~/.local/share/swi-prolog/pack/pac/prolog/setup-aux', [AUX|_]),
> use_module(AUX).
> 
> ```

You can load a file from a specific pack using

```
:- use_module(pack('pac/prolog/setup-aux')).

```

The search path `pack` refers to the parent directories of all packs. Not that it is not wise toput libraries with a general name in the `prolog` directory of a pack as you can also load the above using

```
:- use_module(library('setup-aux')).

```

unless some other pack uses the same name. My general advise is

- Put the user loadable modules in the `prolog` directory of the pack and give them a clear name that refers to the pack.

- Put all other files in a directory `private` below the `prolog` directory and load them from the public files using e.g.

- Make sure the module identifier of all module files is unique, for example, name all of them (in your case) `pac_<name>`, e.g, `pac_utils`.

Note that library(main) provides nice utilities for command line argument handling.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 2, 2024, 1:29pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/8 "2024-08-02T13:29:02Z")

</div>

> [@jan](#):
>
> You can load a file from a specific pack using
> 
> ```prolog
> :- use_module(pack('pac/prolog/setup-aux')).
> 
> ```

It works, and is much simpler, which seems enough for my current purpose.  
I would like to use the private directory under the pack in the future. Thank you for your help. There seems a lot of things remain for me to learn about pack management.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [August 2, 2024, 4:02pm UTC](https://swi-prolog.discourse.group/t/a-swipl-command-shell-options-to-use-pack-zdd-library-to-counting-families-of-sets/7655/9 "2024-08-02T16:02:35Z")

</div>

Finally I have reached to a swipl commnand line `zddcard` below to count the members of a family of sets using my zdd library of pack pac 1.9.7. There are many things for me to learn about details of modern SWI-Prolog’s pack structure, I have to take time for that. For example, I found that the extension .pl seems not always necessary, and also with “–”. However  
double quotes " around zdd term argument seems necessary. I am a little bit confusion about this.

```prolog
#! /usr/bin/env swipl -q -t halt

% usage: zddcard "pow([1,2,3,4])"
% #(pow([1,2,3,4]))=16

:- initialization(main, main).

:- use_module(pack('pac/prolog/setup-aux')).
:- use_module(pack('pac/prolog/pac')).
:- use_module(zdd(zdd)).

main(Args) :- atomics_to_string(Args, ' ', S),
		term_string(Exp, S),
		zmod:zdd,
		call_with_time_limit(10, zmod: (X<< Exp, card(X, C))),
		writeln(#(Exp)=C).

% sample zdd terms.
sample( a ).
sample( (a+b)*(a+c)).
sample( (a+b)*(c+d)).
sample( a*b*c*a*b).
sample( a*b + c).
sample( (a+b)-(c+d)).
sample( (a+b)/a).
sample( (a+b)//a).
sample( (a*c+b)//a).
sample( *(numlist(1, 5))).
sample( *([1,2,3])).
sample( +[0, 1, 2]* (+[0, 1, 2])).
sample( +[1,b,1,1] * (+[1,a])).
sample( +[1,2,3,4]).
sample( +(numlist(1,100)) * +(numlist(1,100))).
sample( (a+b)*(a+c) +(a*b)).
sample( pow([a,b])-(c+d)).
sample( pow([a,b])//(a+b)).
sample( pow([a,b])/(a+b)).
sample( pow(charlist(a, c))).
sample( pow(append([1,2],[a, b]))).
sample( pow(subtract([1,2,3], [1,2,a]))).
sample( +(atomlist($a(1,10)))).
sample( pow(atomlist($a(1,10)))).

```
