• Goal reordering or advanced program transformation?

    From Mostowski Collapse@21:1/5 to All on Tue Aug 17 17:23:05 2021
    It is often said that compared to SQL, Prolog lacks
    goal reordering. But is it true that query planning boils
    down to goal reordering? I found an example

    which is more than goal reordering. You don't get anc2/2
    from anc/2 by simple goal reordering, even if both were
    formulated with edge/2. Take this example here (*):

    setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    Its the same transitive closure, only once computed from
    the left and the other time computed from the right:

    ?- time((between(1,1000,_), anc(0,1024), fail; true)).
    % 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips) true.

    ?- time((between(1,1000,_), anc2(0,1024), fail; true)).
    % 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips)
    true.

    (*) I am using edge/2 and edge2/2 so that the testing also works
    for a Prolog system that has only first argument indexing.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Aug 19 11:00:42 2021
    Woa! The JavaScript JIT compiler is quite impressive. I now
    ported Dogelog runtime to Python as well, so that I can compare
    JavaScript and Python, and tested without clause indexing:

    between(L,H,L) :- L =< H.
    between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).

    setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    :- setup.
    :- time((between(1,10,_), anc2(0,255), fail; true)).
    :- time((between(1,10,_), anc(0,255), fail; true)).

    The results are:

    /* Python 3.10.0rc1 */
    % Wall 188 ms, trim 0 ms
    % Wall 5537 ms, trim 0 ms

    /* JavaScript Chrome 92.0.4515.159 */
    % Wall 5 ms, trim 0 ms
    % Wall 147 ms, trim 0 ms

    Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
    It is often said that compared to SQL, Prolog lacks
    goal reordering. But is it true that query planning boils
    down to goal reordering? I found an example

    which is more than goal reordering. You don't get anc2/2
    from anc/2 by simple goal reordering, even if both were
    formulated with edge/2. Take this example here (*):

    setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    Its the same transitive closure, only once computed from
    the left and the other time computed from the right:

    ?- time((between(1,1000,_), anc(0,1024), fail; true)).
    % 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips) true.

    ?- time((between(1,1000,_), anc2(0,1024), fail; true)).
    % 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.

    (*) I am using edge/2 and edge2/2 so that the testing also works
    for a Prolog system that has only first argument indexing.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Aug 19 11:01:47 2021
    Thats a factor 37.8 faster! I tested the a variant of
    the Albufeira instructions Prolog VM aka ZIP, which
    was also the inspiration for SWI-Prolog.

    Open Source:

    The Python Version of the Dogelog Runtime https://github.com/jburse/dogelog-moon/tree/main/devel/runtimepy

    The Python Test Harness https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-test-py

    Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:00:43 UTC+2:
    Woa! The JavaScript JIT compiler is quite impressive. I now
    ported Dogelog runtime to Python as well, so that I can compare
    JavaScript and Python, and tested without clause indexing:

    between(L,H,L) :- L =< H.
    between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).

    setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
    :- setup.
    :- time((between(1,10,_), anc2(0,255), fail; true)).
    :- time((between(1,10,_), anc(0,255), fail; true)).

    The results are:

    /* Python 3.10.0rc1 */
    % Wall 188 ms, trim 0 ms
    % Wall 5537 ms, trim 0 ms

    /* JavaScript Chrome 92.0.4515.159 */
    % Wall 5 ms, trim 0 ms
    % Wall 147 ms, trim 0 ms
    Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
    It is often said that compared to SQL, Prolog lacks
    goal reordering. But is it true that query planning boils
    down to goal reordering? I found an example

    which is more than goal reordering. You don't get anc2/2
    from anc/2 by simple goal reordering, even if both were
    formulated with edge/2. Take this example here (*):

    setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    Its the same transitive closure, only once computed from
    the left and the other time computed from the right:

    ?- time((between(1,1000,_), anc(0,1024), fail; true)).
    % 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips) true.

    ?- time((between(1,1000,_), anc2(0,1024), fail; true)).
    % 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.

    (*) I am using edge/2 and edge2/2 so that the testing also works
    for a Prolog system that has only first argument indexing.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Aug 19 11:19:08 2021
    So this week , was coding Python as if there
    were no tomorrow, only to arrive at the conclusion:

    - Ha Ha Python is useless

    Lets see. Next I will try to bring first argument clause
    indexing also to the Python version and redo the

    Datalog-ish benchmark.

    Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:01:48 UTC+2:
    Thats a factor 37.8 faster! I tested the a variant of
    the Albufeira instructions Prolog VM aka ZIP, which
    was also the inspiration for SWI-Prolog.

    Open Source:

    The Python Version of the Dogelog Runtime https://github.com/jburse/dogelog-moon/tree/main/devel/runtimepy

    The Python Test Harness https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-test-py Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:00:43 UTC+2:
    Woa! The JavaScript JIT compiler is quite impressive. I now
    ported Dogelog runtime to Python as well, so that I can compare
    JavaScript and Python, and tested without clause indexing:

    between(L,H,L) :- L =< H.
    between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).

    setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
    :- setup.
    :- time((between(1,10,_), anc2(0,255), fail; true)).
    :- time((between(1,10,_), anc(0,255), fail; true)).

    The results are:

    /* Python 3.10.0rc1 */
    % Wall 188 ms, trim 0 ms
    % Wall 5537 ms, trim 0 ms

    /* JavaScript Chrome 92.0.4515.159 */
    % Wall 5 ms, trim 0 ms
    % Wall 147 ms, trim 0 ms
    Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
    It is often said that compared to SQL, Prolog lacks
    goal reordering. But is it true that query planning boils
    down to goal reordering? I found an example

    which is more than goal reordering. You don't get anc2/2
    from anc/2 by simple goal reordering, even if both were
    formulated with edge/2. Take this example here (*):

    setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    Its the same transitive closure, only once computed from
    the left and the other time computed from the right:

    ?- time((between(1,1000,_), anc(0,1024), fail; true)).
    % 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips)
    true.

    ?- time((between(1,1000,_), anc2(0,1024), fail; true)).
    % 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.

    (*) I am using edge/2 and edge2/2 so that the testing also works
    for a Prolog system that has only first argument indexing.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mostowski Collapse@21:1/5 to Mostowski Collapse on Thu Aug 19 14:54:51 2021
    Maybe Python has some niche like Julia, in that its
    possible to override or some such the basic operations
    (+)/2, etc.. and do some amazing autodiff stuff.

    uncertainties
    https://pythonhosted.org/uncertainties/user_guide.html

    And other niche might be, Python itself is a fairy tale:

    Learn Python through Nursery Rhymes & Fairy Tales https://www.kickstarter.com/projects/914595512/learn-python-through-nursery-rhymes-and-fairy-tales

    LoL

    P.S.: Didn't we do autodiff somewhere with Prolog? Isn't
    there a some years old thread on SWI-Prolog discourse
    about autodiff and how to do it in Prolog?

    Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:19:08 UTC+2:
    So this week , was coding Python as if there
    were no tomorrow, only to arrive at the conclusion:

    - Ha Ha Python is useless

    Lets see. Next I will try to bring first argument clause
    indexing also to the Python version and redo the

    Datalog-ish benchmark.
    Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:01:48 UTC+2:
    Thats a factor 37.8 faster! I tested the a variant of
    the Albufeira instructions Prolog VM aka ZIP, which
    was also the inspiration for SWI-Prolog.

    Open Source:

    The Python Version of the Dogelog Runtime https://github.com/jburse/dogelog-moon/tree/main/devel/runtimepy

    The Python Test Harness https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-test-py
    Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:00:43 UTC+2:
    Woa! The JavaScript JIT compiler is quite impressive. I now
    ported Dogelog runtime to Python as well, so that I can compare JavaScript and Python, and tested without clause indexing:

    between(L,H,L) :- L =< H.
    between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).

    setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
    :- setup.
    :- time((between(1,10,_), anc2(0,255), fail; true)).
    :- time((between(1,10,_), anc(0,255), fail; true)).

    The results are:

    /* Python 3.10.0rc1 */
    % Wall 188 ms, trim 0 ms
    % Wall 5537 ms, trim 0 ms

    /* JavaScript Chrome 92.0.4515.159 */
    % Wall 5 ms, trim 0 ms
    % Wall 147 ms, trim 0 ms
    Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
    It is often said that compared to SQL, Prolog lacks
    goal reordering. But is it true that query planning boils
    down to goal reordering? I found an example

    which is more than goal reordering. You don't get anc2/2
    from anc/2 by simple goal reordering, even if both were
    formulated with edge/2. Take this example here (*):

    setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
    setup :- edge(M,N), assertz(edge2(N,M)), fail.
    setup.

    anc(X,Y) :- edge(X, Y).
    anc(X,Y) :- edge(X, Z), anc(Z, Y).

    anc2(X,Y) :- edge2(Y, X).
    anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).

    Its the same transitive closure, only once computed from
    the left and the other time computed from the right:

    ?- time((between(1,1000,_), anc(0,1024), fail; true)).
    % 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips)
    true.

    ?- time((between(1,1000,_), anc2(0,1024), fail; true)).
    % 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips)
    true.

    (*) I am using edge/2 and edge2/2 so that the testing also works
    for a Prolog system that has only first argument indexing.

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