mthom / scryer-prolog

A modern Prolog implementation written mostly in Rust.
BSD 3-Clause "New" or "Revised" License
1.93k stars 116 forks source link

Adding clause to program breaks lambda maplist #2386

Closed dcnorris closed 2 months ago

dcnorris commented 2 months ago
% repro2.pl
% Investigating why lambdas suddenly stopped working with maplist/3

:- use_module(library(clpz)).
:- use_module(library(lists)).
:- use_module(library(debug)).
:- use_module(library(lambda)).

clpz:monotonic.

denom_tally(N, T/N) :- #N #>= 0, T in 0..N. % aids fair enumeration when D>1
tally(T/N) :- N in 0..6, indomain(N), denom_tally(N, T/N).

%?- tally(T/N).
%@    T = 0, N = 0
%@ ;  N = 1, clpz:(T in 0..1)
%@ ;  N = 2, clpz:(T in 0..2)
%@ ;  N = 3, clpz:(T in 0..3)
%@ ;  N = 4, clpz:(T in 0..4)
%@ ;  N = 5, clpz:(T in 0..5)
%@ ;  N = 6, clpz:(T in 0..6).

lez(T1/N1, T2/N2) :-
    tally(T2/N2),
    tally(T1/N1), 
    T1 #>= T2 + max(0, N1 - N2).

/* --- comment this clause to restore functioning of maplist(lambda,L1,L2) */
denom_le2(N, Q1, Q2) :-
    #N1 #>= 0,
    #N2 #>= 0,
    sum([N1, N2], #=, N),
    indomain(N1), length(Q1, D), maplist(denom_tally(N1), Q1),
    indomain(N2), length(Q2, D), maplist(denom_tally(N2), Q2).
    maplist(lez, Q1, Q2).
/* --- */

%?- maplist(\X^(X>3),[4,5,9]).
%@    true. % works as documented in lambda.pl

%?- maplist(\X^Y^(X=Y),[4,5,9],[4,5,9]).
%@    false. % why?

%?- maplist(\X^Y^(X>Y),[4,5,9],[0,0,0]).
%@    false. % why?

Commenting out the denom_le2/3 clause restores correct answers (true) in the last 2 queries.

triska commented 2 months ago

The program produces the following warning:

% Warning: singleton variables Q1, Q2 at line 31 of ediprologrQRUbd
% Warning: overwriting maplist/3 because the clauses are discontiguous
   true.

This is because you are (I think inadvertently) redefining maplist/3, because there is an accidental . (instead of ,) at the end of denom_le/3!

The most recent ediprolog version (2.3-PRE1) displays these warning as expected, but they are not visible with earlier ediprolog versions, because Scryer now shows warnings during compilation as comments (which I think fits the purpose of warnings). Please use the most recent ediprolog version to spot such mistakes more easily.

dcnorris commented 2 months ago

Many thanks, Markus! I ought to have tried from terminal as well, and also scrutinized every last character of the offending clause! (Incidentally, I've just installed your very latest ediprolog.el — verifying with M-x locate-library that it is indeed the one I'm using — but it still reports only "Buffer consulted" on the above repro. Meanwhile, I do see those Warnings when running Scryer in the terminal.)


Correction: doing C-h v ediprolog-version showed that I was in fact not using the latest version; but after doing M-x restart-server RET that variable updated, and all is well!