Closed UWN closed 2 years ago
Related discussion: https://github.com/infradig/trealla/issues/233
@didoudiaz the current Logtalk git version includes an extended test set for the length/2
predicate, which you may find useful to help ensure that all type errors in the first argument are detected/reported.
A Prolog definition for the length/2
predicate that type-checks both arguments but makes no attempt to handle cyclic terms:
length(List, Length) :-
( var(Length) ->
length(List, List, 0, Length)
; \+ integer(Length) ->
throw(error(type_error(integer,Length), length/2))
; Length < 0 ->
throw(error(domain_error(not_less_than_zero,Length), length/2))
; make_list(Length, List, List)
).
make_list(N, Term, List) :-
( N =:= 0, Term = [] ->
true
; N < 0, var(Term) ->
fail
; M is N-1, Term = [_| Tail] ->
make_list(M, Tail, List)
; Term \= [],
Term \= [_|_],
throw(error(type_error(list,List), length/2))
).
length(Term, List, _, _) :-
Term \= [],
Term \= [_|_],
throw(error(type_error(list,List), length/2)).
length([], _, Length, Length).
length([_| Tail], List, Acc, Length) :-
Acc2 is Acc + 1,
length(Tail, List, Acc2, Length).
This definition passes all Logtalk bundled tests.
All tests now pass! 🎉🥳 Thanks for the fix. Making the behavior depending on the strict_iso
flag is a good idea.
length(List, Length)
now sometimes produces atype_error(list,_)
when there is no instance ofList
that is a list. In the past, length/2 uniformly failed in this case, as specified by the template and modelength(?term, ?integer)
.See #4 ff: