运行时出错

Error at runtime

我必须找到具有 2 个相差小于 3 的连续元素的排列。

cons2Less3(L,Rd):-
    findall(R, (permute(L,R),(isValid(R))), Rd).

isValid([H|T]):-
    listContainsConsecLess3(T,H).

listContainsConsecLess3([H|_],C):-
    4 > abs(H - C),!.
listContainsConsecLess3([H|T],_):-
    listContainsConsecLess3(T,H).

permute(L,Rd):-
      findall(R, (perm(L,R)), Rd).

perm([],[]).
perm([E|L],Z):-
    perm(L,Z1),
    elim(E,Z,Z1).

elim(E,[E|X],X).
elim(E,[A|X],[A|Y]):-
    elim(E,X,Y).

但在运行时:

调试:

  1 = [[6, 3, 6], [6, 6, 3], [3, 6, 6], [6, 3, 6], [6, 6, 3]]
  2 = [3, 6, 6]

控制台:

ERROR: >/2: Type error: `[]' expected, found `[3,6,6]' ("x" must hold one character)

我做错了什么?

这个诊断是代码有"findall-itis"。 :)

你从这个开始:

cons2Less3(L,Rd):-
    findall(R, (permute(L,R),(isValid(R))), Rd).

假设 permute/2 在回溯时单独生成 每个排列。但是,您的 permute/2 也调用 findall/3:

permute(L,Rd):-
      findall(R, (perm(L,R)), Rd).

所以 perm/2 在回溯时生成单独的排列,然后 permute/2 将它们收集到一个列表中。因此,您最终调用 isValid(R)R 是列表的列表,然后:

isValid([H|T]) :-    % Called with [H|T] a list of lists
    listContainsConsecLess3(T,H).   % Called with T a list of lists

listContainsConsecLess3([H|_],C):-  % Called with H a list
    4 > abs(H - C),!.               % H is not numeric, but a list!
...

导致数值表达式 abs(H - C) 具有 H 作为产生错误的列表。

快速解决方法是去掉 permute/2 并直接调用 perm/2

cons2Less3(L,Rd):-
    findall(R, (perm(L,R), isValid(R)), Rd).