triska / clpz

Constraint Logic Programming over Integers
https://www.metalevel.at/prolog/clpz
184 stars 15 forks source link

Domain error after some level of backtracking with clpz: error(domain_error(clpz_expression,[]),unknown([])-1) #16

Closed david-sitsky closed 2 years ago

david-sitsky commented 2 years ago

I am sure this is completely my fault, but it is not entirely clear to me what this error means. Am I mixing clpz expressions in some non-compatible way?

I have a very "naive" implementation of the following predicate to detect what numeric position (0-based) an element is within a list which I have run using scryer prolog and clpz:

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

member_at_position(L, [L|_], 0).
member_at_position(L, [_|Ls], N) :-
    N #> 0,
    length(Ls, Length),
    Limit #= Length + 1,
    N #< Limit,
    member_at_position(L, Ls, M),
    N #= M+1.

Here is some interaction with the console which shows this issue:

?- member_at_position(a, [a,b,c,a,d], P).
   P = 0
;  caught: error(domain_error(clpz_expression,[]),unknown([])-1)
?- member_at_position(a, L, P).
   L = [a|_A], P = 0
;  L = [_A,a], P = 1
;  L = [_A,a,_B], P = 1
;  L = [_A,_B,a], P = 2
;  L = [_A,a,_B,_C], P = 1
;  caught: error(domain_error(clpz_expression,[]),unknown([])-1)
?- member_at_position(E, L, P).
   L = [E|_A], P = 0
;  L = [_A,E], P = 1
;  L = [_A,E,_B], P = 1
;  L = [_A,_B,E], P = 2
;  L = [_A,E,_B,_C], P = 1
;  caught: error(domain_error(clpz_expression,[]),unknown([])-1)

I am sure I am at fault here, but could you explain what is wrong please?

UWN commented 2 years ago

You are not at fault for this particular error. Very good find! (It's hard to narrow it down any further, because then also some other issues arise...) That said, there are probably better ways to express what you intend.

UWN commented 2 years ago

Here is a smaller 'version' of your program.

:- use_module(library(clpz)).

:- dynamic(member_at_position/0).
member_at_position :-
    ( M = 0 ; false ),
    N in 1..2,
    N #= M+1.

:- initialization(( member_at_position, false )).

which gives:

ulrich@TU-Wien:~/scryer$ /opt/gupu/scryer-prolog/target/release/scryer-prolog -f item16_b.pl
caught: error(existence_error(procedure,[]/0),[]/0) % unexpected

which is just as unexpected, as your error. This really seems to be an issue in Scryer.

UWN commented 2 years ago

At least that last error occurs also when using freeze/2 in the remaining fragment of your program.

david-sitsky commented 2 years ago

As a point of comparison, I tried the same code but using module clpfd with SWI and it seemed to work fine. I realise clpfd is not the same as clpz though.

Is this the right place to mention this issue, or should I report it on Scryer's Github?

edit: ah I see you have reported an issue there.

UWN commented 2 years ago

(it seems you are reading this here by e-mail. If you are reading it via the web-interface you see any mentioning in other places directly.)

UWN commented 2 years ago

I realise clpfd is not the same as clpz though.

clpfd in SWI is the predecessor to clpz with about 2 (CPU-)centuries of testing. Unfortunately, SWI got non-conforming and also had a lot of instability in the unification interface which rendered all the testing less useful than it could have been.

It seems that the issue you found is not directly related to clpz and expect it to be fixed soon.

UWN commented 2 years ago

@david-sitsky : Seems to be fixed since some time


?- member_at_position(a, [a,b,c,a,d], P).
   P = 0
;  P = 3
;  false.
?- member_at_position(a, L, P).
   L = [a|_A], P = 0
;  L = [_A,a], P = 1
;  L = [_A,a,_B], P = 1
;  L = [_A,_B,a], P = 2
;  L = [_A,a,_B,_C], P = 1
;  L = [_A,_B,a,_C], P = 2
;  L = [_A,_B,_C,a], P = 3
;  L = [_A,a,_B,_C,_D], P = 1
;  L = [_A,_B,a,_C,_D], P = 2
;  L = [_A,_B,_C,a,_D], P = 3
;  L = [_A,_B,_C,_D,a], P = 4
;  L = [_A,a,_B,_C,_D,_E], P = 1
;  L = [_A,_B,a,_C,_D,_E], P = 2
;  L = [_A,_B,_C,a,_D,_E], P = 3
;  L = [_A,_B,_C,_D,a,_E], P = 4
;  ... .
?- member_at_position(E, L, P).
   L = [E|_A], P = 0
;  L = [_A,E], P = 1
;  L = [_A,E,_B], P = 1
;  L = [_A,_B,E], P = 2
;  L = [_A,E,_B,_C], P = 1
;  L = [_A,_B,E,_C], P = 2
;  L = [_A,_B,_C,E], P = 3
;  L = [_A,E,_B,_C,_D], P = 1
;  L = [_A,_B,E,_C,_D], P = 2
;  L = [_A,_B,_C,E,_D], P = 3
;  L = [_A,_B,_C,_D,E], P = 4
;  L = [_A,E,_B,_C,_D,_E], P = 1
;  L = [_A,_B,E,_C,_D,_E], P = 2
;  L = [_A,_B,_C,E,_D,_E], P = 3
;  L = [_A,_B,_C,_D,E,_E], P = 4
;  L = [_A,_B,_C,_D,_E,E], P = 5
;  ... .
?- 
david-sitsky commented 2 years ago

@UWN - excellent - thanks for letting me know.

UWN commented 2 years ago

In case there is nothing left, would you mind closing the isse?