2015-06-15 28 views
0

я должен найти перестановки, которые имеют 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). 

Но во время выполнения:

Debug:

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) 

Что я делаю не так?

+0

'переставить (L, R)' возвращает список списков в 'r'. Затем вы вызываете 'isValid (R)' в список списков, что означает 'H' в выражении' abs (H - C) '- это список, который является недопустимым синтаксисом. Избавьтесь от 'findall' в вашем предикате' permute' и пусть он возвращает результаты по одному с помощью backtracking. Почему бы вам не использовать предикат 'перестановки/2' Prolog? – lurker

+0

Просили от меня сделать это так ... –

+1

OK. Вы не должны использовать 'findall' в своей реализации' permute/2'. – lurker

ответ

3

Этот диагноз заключается в том, что код имеет «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). 
+1

Все находки, которые не безопасно защищены от слишком общих целей, действительно должны быть запрещены. – false

Смежные вопросы