ciao
ciao copied to clipboard
Feature request library(aggregate) from SICStus Prolog
I did a search in this repository about aggregate_all/3
. But
I didn't find it. Is this correct that Ciao Prolog has no
library(aggregate) from SICStus Prolog?
An Aggregation Operator for Data-Base-Style Queries https://sicstus.sics.se/sicstus/docs/4.6.0/html/sicstus/lib_002daggregate.html
I am somehow used to it since it also found its way into SWI-Prolog. Would it be possible to support the same in Ciao Prolog as well? Its not urgent, just a feature request.
Here is an example test case:
?- aggregate_all(count, (between(1,1000,N), N mod 13 =:= 0), C).
C = 76.
?- aggregate_all(sum(N), (between(1,1000,N), N mod 13 =:= 0), C).
C = 38038.
With Novacore and Liblets its not needed anymore.
Adding those predicates would still be an enhancement for Ciao. I reopen it.
Is there a ciao version where this is already available? Some library aggregate.? I now did for example this:
:- use_module(library(numlists)).
aggregate_all(sum(X), G, S) :-
findall(X, G, L),
sum_list(L, S).
But it doesn't work, when I call it with this here:
?- use_module(library(between)).
?- use_module(library(random)).
?- ['aggregate.p'].
?- E is (1<<100), M is (1<<101), K is (1<<20),
between(1,10,_), aggregate_all(sum(X),
(between(1,K,_), random(0,M,X)), S),
N is msb(abs(S-E*K))-20, write(N), nl, fail; true.
{ERROR: user:random/3 - existence error: procedure:user:random/3 does not exist}
Whats missing, a meta predicate declaration before aggregate_all?
Random number generation is in library(random): http://ciao-lang.org/ciao/build/doc/ciao.html/random.html
Calling random(0,M,X)
should give you what you need. You can also of course skip defining aggregate_all
, just put in the query findall(X, (between(1,K,_), random(0,M,X)), L), sum_list(L,S), ...
.
(I edited the previous comment)
random/3 was not part of my comment or ticket here, the code I
posted already calls random(0,M,_)
, no editing done.
This was on SWI-Prolog discourse. There I observed that your
random/3 generates in the interval [L,H] whereas SWI-Prolog
generates in the interval [L,H). Translated to SWI-Prolog you
need to call random(0,M+1,_)
. I didn't open any ticket or made
any comment about random/3 on Ciao Prolog GitHub issues. Should there be a discussion about random/3? I don't know, what are your plans? I don't know? Is there a road map? I don't
know. Does anybody care Ciao and SWI-Prolog compatibility? I don't know? Recenfly SWI-Prolog deprecated random/3 and introduced random_between/3 with a different protocoll.
Maybe this can point the way forward?
just put in the query
findall(X, (between(1,K,_), random(0,M,X)), L), sum_list(L,S), ...
.
Interestingly that was just what I defined:
aggregate_all(sum(X), G, S) :-
findall(X, G, L),
sum_list(L, S).
But why does it throw a random/3 existence error. Should I place a meta_predicate directive before aggregate_all/3? I imported random/3 already into user:
?- use_module(library(random)).
but the error messsage says:
{ERROR: user:random/3 - existence error: procedure:user:random/3 does not exist}
Will try with a meta predicate directive soon.
Humm, it works for me:
?- use_module(library(random)), use_module(library(numlists)).
yes
?- random(0,5,X).
X = 1 ?
Is this what you are doing?
Here is a screenshot of what I already copy pasted into the ticket here:
The scrambling of the input, the 3 blanks ' ' is an artefact of your Ciao Prolog readline routine somehow, when pasting a multi-line query. So the screenshot doesn't look that pretty. What I pasted into the ticket here
looks more pretty. It has also removed Note:, yes, yes, yes, aborted.
Ah, I understand now: make aggregate a module (just put :- module(_,_).
at the beginning) and include the meta-predicate declaration: :- meta_predicate( aggregate_all(_,goal,_)).
.
Now I could run it. The error in Ciao Prolog is much larger than in SWI-Prolog, i.e. the distance to the expected value. Was using this query, taking into account the different random/3 protocoll, and
the missing aggregate_all/3 and msb/1 evaluable function:
$ ciaosh
Ciao 1.22.0 (2022-09-28 21:20:35 +0200) [LINUXx86_64]
?- use_module(library(between)).
?- ['aggregate.p'].
?- E is (1<<100), M is (1<<101), K is (1<<20),
between(1,10,_), aggregate_all(sum(X),
(between(1,K,_), random(0,M,X)), S),
H is abs(S-E*K), msb(H,J), N is J-20, write(N), nl, fail; true.
100.0
100.0
100.0
100.0
100.0
100.0
100.0
100.0
100.0
100.0
And this helper code (file aggregate.p):
:- use_module(library(numlists)).
:- use_module(library(random)).
aggregate_all(sum(X), G, S) :-
findall(X, G, L),
sum_list(L, S).
msb(X, Y) :- Y is log(X)/log(2).
Also a little strange that it is exactly 100.0 in all runs? Have to dig deeper whats going on.