• Deephaven inspired me to name a predicate [first_by/2]

    From Mild Shock@21:1/5 to All on Mon Feb 10 18:44:56 2025
    Hi,

    Suddently I got an allergy to name a predicate
    distinct/2. It is not so obvious that distinct/1 and
    distinct/2 are related. There is no constant C such that:

    distinct(X) :- distinct(C, X).

    Just joking, but for some consistency with the introduction
    of group_by/4 and aggregate_by/4 I went for the
    name first_by/2. The name is more intuitive:

    ?- [user].
    p(1,a).
    p(1,b).
    p(2,c).
    p(2,d).
    p(2,e).
    ^Z
    true.

    Now some queries:

    ?- p(X,Y), write(X-Y), nl, fail; true.
    1-a
    1-b
    2-c
    2-d
    2-e
    true.

    ?- first_by(X, p(X,Y)), write(X-Y), nl, fail; true.
    1-a
    2-c
    true.

    Cool! The name is also used here with the same semantics:

    https://deephaven.io/core/docs/reference/table-operations/group-and-aggregate/firstBy/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Mon Feb 10 21:17:22 2025
    Hi,

    India & France had their AI Bikini Moment.
    Facinating behavior:

    Macron Says He And PM Modi Will Push https://www.youtube.com/watch?v=LwCK8yAnlkA

    But don't be fooled, things are possibly
    more connected:

    Synthesia: France's 109-billion-euro AI investment https://www.youtube.com/watch?v=_uyo4RG0Q6I

    Bye


    Mild Shock schrieb:
    Hi,

    Suddently I got an allergy to name a predicate
    distinct/2. It is not so obvious that distinct/1 and
    distinct/2 are related. There is no constant C such that:

    distinct(X) :- distinct(C, X).

    Just joking, but for some consistency with the introduction
    of group_by/4 and aggregate_by/4 I went for the
    name first_by/2. The name is more intuitive:

    ?- [user].
    p(1,a).
    p(1,b).
    p(2,c).
    p(2,d).
    p(2,e).
    ^Z
    true.

    Now some queries:

    ?- p(X,Y), write(X-Y), nl, fail; true.
    1-a
    1-b
    2-c
    2-d
    2-e
    true.

    ?- first_by(X, p(X,Y)), write(X-Y), nl, fail; true.
    1-a
    2-c
    true.

    Cool! The name is also used here with the same semantics:

    https://deephaven.io/core/docs/reference/table-operations/group-and-aggregate/firstBy/



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Sun Feb 16 12:24:13 2025
    Just noticed that group_by/4 calculates variables
    and then delegates to bagof/3. But the later predicate
    calculates also varables, so I suspect quite an overhead:

    /* SWI-Prolog 9.3.19 */
    group_by(By, Template, Goal, Bag) :-
    ordered_term_variables(Goal, GVars),
    ordered_term_variables(By+Template, UVars),
    ord_subtract(GVars, UVars, ExVars),
    bagof(Template, ExVars^Goal, Bag).

    I went with another soluton. First I provided a variant
    of aggregate/3 by the name aggregate_by/4 where one can
    offload the internal term_variables/2 calculation.
    Then use this bootstrapping:

    /* Dogelog Player 1.3.0 */
    group_by(Witness, Template, Goal, List) :-
    aggregate_by(Witness, bag(Template), Goal, List).

    Here is some testing:

    /* SWI-Prolog 9.3.19 */
    ?- length(_H,4000), time((between(1,2000,_),
    group_by(X,Y,(nonvar(_H),between(1,10,Y),between(1,10,X)),L),
    fail; true)).
    % 1,153,998 inferences, 0.562 CPU in 0.568 seconds (99% CPU, 2051552 Lips) true.
    ?- length(_H,8000), time((between(1,2000,_),
    group_by(X,Y,(nonvar(_H),between(1,10,Y),between(1,10,X)),L),
    fail; true)).
    % 1,153,998 inferences, 1.047 CPU in 1.060 seconds (99% CPU, 1102326 Lips) true.

    /* Dogelog Player 1.3.0 */
    ?- length(_H,4000), time((between(1,2000,_),
    group_by(X,Y,(nonvar(_H),between(1,10,Y),between(1,10,X)),L),
    fail; true)).
    % Zeit 399 ms, GC 0 ms, Lips 16987636, Uhr 10.02.2025 10:49
    true.
    ?- length(_H,8000), time((between(1,2000,_),
    group_by(X,Y,(nonvar(_H),between(1,10,Y),between(1,10,X)),L),
    fail; true)).
    % Zeit 400 ms, GC 1 ms, Lips 16945167, Uhr 10.02.2025 10:50
    true.

    The old version suffers from some term_variables/2
    dependency whereas the new version is totally immune
    on the size of the given goal, since any internal
    term_variables/2 has been offloaded.

    I couldn’t name aggregate_by/4 as aggregate/4, since
    the later already exists in SWI-Prolog and SICStus Prolog
    and has a different semantics, it is not the analog of
    distinct/2, where one can specify Witnesses.

    Mild Shock schrieb:
    Hi,

    India & France had their AI Bikini Moment.
    Facinating behavior:

    Macron Says He And PM Modi Will Push https://www.youtube.com/watch?v=LwCK8yAnlkA

    But don't be fooled, things are possibly
    more connected:

    Synthesia: France's 109-billion-euro AI investment https://www.youtube.com/watch?v=_uyo4RG0Q6I

    Bye


    Mild Shock schrieb:
    Hi,

    Suddently I got an allergy to name a predicate
    distinct/2. It is not so obvious that distinct/1 and
    distinct/2 are related. There is no constant C such that:

    distinct(X) :- distinct(C, X).

    Just joking, but for some consistency with the introduction
    of group_by/4 and aggregate_by/4 I went for the
    name first_by/2. The name is more intuitive:

    ?- [user].
    p(1,a).
    p(1,b).
    p(2,c).
    p(2,d).
    p(2,e).
    ^Z
    true.

    Now some queries:

    ?- p(X,Y), write(X-Y), nl, fail; true.
    1-a
    1-b
    2-c
    2-d
    2-e
    true.

    ?- first_by(X, p(X,Y)), write(X-Y), nl, fail; true.
    1-a
    2-c
    true.

    Cool! The name is also used here with the same semantics:

    https://deephaven.io/core/docs/reference/table-operations/group-and-aggregate/firstBy/




    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)