• The Ghosts in my Cabinet: Indexing

    From Mild Shock@21:1/5 to All on Thu Jul 10 12:45:32 2025
    I am currently doing a re-evaluation of an old
    Prolog system, checking what features I could adopt.
    This is unlike the current trend where people have
    turned their focus on GUIs, like XPCE,

    or a are stuck in an endless loop of parser
    problems, like in Trealla. But I would nevertheless
    share my finding. Take this simple example of
    a list append:

    app([], X, X).
    app([X|Y], Z, [X|T]) :- app(Y, Z, T).

    ECLiPSe Prolog gives me, only one redo question
    in the top-level:

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 2]: app(X,Y,[1]).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    In SWI-Prolog I find, two redo questions
    in the top.level:

    /* SWI-Prolog 9.3.25 */
    ?- app(X,Y,[1]).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    I know SWI-Prolog handles lists differently
    than other Prolog terms during indexing. Could
    this be the reason? Or maybe that the call is
    not “hot” enough, so it doesn’t get JIT-ed.

    ECLiPSe Prolog does it on the very first call,
    and I assume its due to a kind of index on
    the 3rd argument.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Fri Jul 11 09:38:00 2025
    Interestingly, DCG is also affect. Here a
    DCG take of an append app/3, it has the 2nd
    and 3rd argument swapped:

    ?- [user].
    app([]) --> [].
    app([X|Y]) --> [X], app(Y).
    ^D

    Looks like an append, taking the argument swap
    into account, the A=B is redundant, could
    be optimized away:

    /* SWI-Prolog 9.3.25 */
    ?- listing(app/3).
    app([], A, B) :-
    A=B.
    app([A|B], [A|C], D) :-
    app(B, C, D).

    And works like an append, again taking the
    argument swap into account:

    ?- app([1],X,[2,3]).
    X = [1, 2, 3].

    Now the multi-argument indexing test, still
    taking the argument swap into account;

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 3]: app(X, [1], Y).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    Versus:

    /* SWI-Prolog 9.3.25 */
    ?- app(X, [1], Y).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    Mild Shock schrieb:
    I am currently doing a re-evaluation of an old
    Prolog system, checking what features I could adopt.
    This is unlike the current trend where people have
    turned their focus on GUIs, like XPCE,

    or a are stuck in an endless loop of parser
    problems, like in Trealla. But I would nevertheless
    share my finding. Take this simple example of
    a list append:

    app([], X, X).
    app([X|Y], Z, [X|T]) :- app(Y, Z, T).

    ECLiPSe Prolog gives me, only one redo question
    in the top-level:

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 2]: app(X,Y,[1]).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    In SWI-Prolog I find, two redo questions
    in the top.level:

    /* SWI-Prolog 9.3.25 */
    ?- app(X,Y,[1]).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    I know SWI-Prolog handles lists differently
    than other Prolog terms during indexing. Could
    this be the reason? Or maybe that the call is
    not “hot” enough, so it doesn’t get JIT-ed.

    ECLiPSe Prolog does it on the very first call,
    and I assume its due to a kind of index on
    the 3rd argument.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Tue Jul 15 15:20:02 2025
    Hi,

    That false/0 and not fail/0 is now all over the place,
    I don't mean in person but for example here:

    ?- X=f(f(X), X), Y=f(Y, f(Y)), X = Y.
    false.

    Is a little didactical nightmare.

    Syntactic unification has mathematical axioms (1978),
    to fully formalize unifcation you would need to
    formalize both (=)/2 and (≠)/2 (sic!), otherwise you
    rely on some negation as failure concept.

    Keith L. Clark, Negation as Failure https://link.springer.com/chapter/10.1007/978-1-4684-3384-5_11

    You can realize a subset of a mixture of (=)/2
    and (≠)/2 in the form of a vanilla unify Prolog
    predicate using some of the meta programming
    facilities of Prolog, like var/1 and having some

    negation as failure reading:

    /* Vanilla Unify */
    unify(V, W) :- var(V), var(W), !, (V \== W -> V = W; true).
    unify(V, T) :- var(V), !, V = T.
    unify(S, W) :- var(W), !, W = S.
    unify(S, T) :- functor(S, F, N), functor(T, F, N),
    S =.. [F|L], T =.. [F|R], maplist(unify, L, R).

    I indeed get:

    ?- X=f(f(X), X), Y=f(Y, f(Y)), unify(X,Y).
    false.

    If the vanilla unify/2 already fails then unify
    with and without subject to occurs check, will also
    fail, and unify with and without ability to
    handle rational terms, will also fail:

    Bye

    Mild Shock schrieb:

    Interestingly, DCG is also affect. Here a
    DCG take of an append app/3, it has the 2nd
    and 3rd argument swapped:

    ?- [user].
    app([]) --> [].
    app([X|Y]) --> [X], app(Y).
    ^D

    Looks like an append, taking the argument swap
    into account, the A=B is redundant, could
    be optimized away:

    /* SWI-Prolog 9.3.25 */
    ?- listing(app/3).
    app([], A, B) :-
        A=B.
    app([A|B], [A|C], D) :-
        app(B, C, D).

    And works like an append, again taking the
    argument swap into account:

    ?- app([1],X,[2,3]).
    X = [1, 2, 3].

    Now the multi-argument indexing test, still
    taking the argument swap into account;

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 3]: app(X, [1], Y).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    Versus:

    /* SWI-Prolog 9.3.25 */
    ?- app(X, [1], Y).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    Mild Shock schrieb:
    I am currently doing a re-evaluation of an old
    Prolog system, checking what features I could adopt.
    This is unlike the current trend where people have
    turned their focus on GUIs, like XPCE,

    or a are stuck in an endless loop of parser
    problems, like in Trealla. But I would nevertheless
    share my finding. Take this simple example of
    a list append:

    app([], X, X).
    app([X|Y], Z, [X|T]) :- app(Y, Z, T).

    ECLiPSe Prolog gives me, only one redo question
    in the top-level:

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 2]: app(X,Y,[1]).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    In SWI-Prolog I find, two redo questions
    in the top.level:

    /* SWI-Prolog 9.3.25 */
    ?- app(X,Y,[1]).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    I know SWI-Prolog handles lists differently
    than other Prolog terms during indexing. Could
    this be the reason? Or maybe that the call is
    not “hot” enough, so it doesn’t get JIT-ed.

    ECLiPSe Prolog does it on the very first call,
    and I assume its due to a kind of index on
    the 3rd argument.



    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mild Shock@21:1/5 to Mild Shock on Tue Jul 15 15:24:07 2025
    Hi,

    Now somebody was so friendly to spear head
    a new Don Quixote attempt in fighting the
    windmills of compare/3. Interestingly my

    favorite counter example still goes through:

    ?- X = X-0-9-7-6-5-4-3-2-1, Y = Y-7-5-8-2-4-1,
    compare_with_stack(C, X, Y).
    X = X-0-9-7-6-5-4-3-2-1,
    Y = Y-7-5-8-2-4-1,
    C = (<).

    ?- H = H-9-7-6-5-4-3-2-1-0, Z = H-9-7-6-5-4-3-2-1, Y = Y-7-5-8-2-4-1,
    compare_with_stack(C, Z, Y).
    H = H-9-7-6-5-4-3-2-1-0,
    Z = H-9-7-6-5-4-3-2-1,
    Y = Y-7-5-8-2-4-1,
    C = (>).

    ?- H = H-9-7-6-5-4-3-2-1-0, Z = H-9-7-6-5-4-3-2-1, X =
    X-0-9-7-6-5-4-3-2-1,
    compare_with_stack(C, Z, X).
    H = H-9-7-6-5-4-3-2-1-0,
    Z = X, X = X-0-9-7-6-5-4-3-2-1,
    C = (=).

    I posted it here in March 2023:

    Careful with compare/3 and Brent algorithm https://swi-prolog.discourse.group/t/careful-with-compare-3-and-brent-algorithm/6413

    Its based that rational terms are indeed in
    some relation to rational numbers. The above
    terms are related to:

    10/81 = 0.(123456790) = 0.12345679(02345679)

    Bye

    Mild Shock schrieb:
    Hi,

    That false/0 and not fail/0 is now all over the place,
    I don't mean in person but for example here:

    ?- X=f(f(X), X), Y=f(Y, f(Y)), X = Y.
    false.

    Is a little didactical nightmare.

    Syntactic unification has mathematical axioms (1978),
    to fully formalize unifcation you would need to
    formalize both (=)/2 and (≠)/2 (sic!), otherwise you
    rely on some negation as failure concept.

    Keith L. Clark, Negation as Failure https://link.springer.com/chapter/10.1007/978-1-4684-3384-5_11

    You can realize a subset of a mixture of (=)/2
    and (≠)/2 in the form of a vanilla unify Prolog
    predicate using some of the meta programming
    facilities of Prolog, like var/1 and having some

    negation as failure reading:

    /* Vanilla Unify */
    unify(V, W) :- var(V), var(W), !, (V \== W -> V = W; true).
    unify(V, T) :- var(V), !, V = T.
    unify(S, W) :- var(W), !, W = S.
    unify(S, T) :- functor(S, F, N), functor(T, F, N),
         S =.. [F|L], T =.. [F|R], maplist(unify, L, R).

    I indeed get:

    ?- X=f(f(X), X), Y=f(Y, f(Y)), unify(X,Y).
    false.

    If the vanilla unify/2 already fails then unify
    with and without subject to occurs check, will also
    fail, and unify with and without ability to
    handle rational terms, will also fail:

    Bye

    Mild Shock schrieb:

    Interestingly, DCG is also affect. Here a
    DCG take of an append app/3, it has the 2nd
    and 3rd argument swapped:

    ?- [user].
    app([]) --> [].
    app([X|Y]) --> [X], app(Y).
    ^D

    Looks like an append, taking the argument swap
    into account, the A=B is redundant, could
    be optimized away:

    /* SWI-Prolog 9.3.25 */
    ?- listing(app/3).
    app([], A, B) :-
         A=B.
    app([A|B], [A|C], D) :-
         app(B, C, D).

    And works like an append, again taking the
    argument swap into account:

    ?- app([1],X,[2,3]).
    X = [1, 2, 3].

    Now the multi-argument indexing test, still
    taking the argument swap into account;

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 3]: app(X, [1], Y).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    Versus:

    /* SWI-Prolog 9.3.25 */
    ?- app(X, [1], Y).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    Mild Shock schrieb:
    I am currently doing a re-evaluation of an old
    Prolog system, checking what features I could adopt.
    This is unlike the current trend where people have
    turned their focus on GUIs, like XPCE,

    or a are stuck in an endless loop of parser
    problems, like in Trealla. But I would nevertheless
    share my finding. Take this simple example of
    a list append:

    app([], X, X).
    app([X|Y], Z, [X|T]) :- app(Y, Z, T).

    ECLiPSe Prolog gives me, only one redo question
    in the top-level:

    /* ECLiPSe Prolog 7.1beta #13 */
    [eclipse 2]: app(X,Y,[1]).

    X = []
    Y = [1]
    Yes (0.00s cpu, solution 1, maybe more) ? ;

    X = [1]
    Y = []
    Yes (0.00s cpu, solution 2)

    In SWI-Prolog I find, two redo questions
    in the top.level:

    /* SWI-Prolog 9.3.25 */
    ?- app(X,Y,[1]).
    X = [],
    Y = [1] ;
    X = [1],
    Y = [] ;
    false.

    I know SWI-Prolog handles lists differently
    than other Prolog terms during indexing. Could
    this be the reason? Or maybe that the call is
    not “hot” enough, so it doesn’t get JIT-ed.

    ECLiPSe Prolog does it on the very first call,
    and I assume its due to a kind of index on
    the 3rd argument.




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