次の問題があります。
a1 = ...、a2n+1 = 0 および |a(i+1) - ai| となる、長さ 2*n+1 のすべての部分文字列を生成します。1 <= i <= 2n ごとに = 1 または 2。これはスタック オーバーフローでここで見つけたものですが、ソリューションでは clpfd ライブラリが使用されており、どのような種類のライブラリも使用することは許可されていません。
change(0).
change(1).
change(-1).
%gets the last element from a list
lastE([X],X).
lastE([_|L],X) :-
last(L,X).
%checks if |N-M|=1 or 2
calc(N,M) :-
( 1 is abs(N-M)
; 2 is abs(N-M),
!
).
%generates all lists of length N with values -1,0,1
generate([],0) :-
!.
generate([H|T],N):-
change(H),
N1 is N-1,
generate(T,N1).
%validates a list to be correct (last element=0, |a(i+1) - ai| = 1 or 2)
valid(L) :-
valid(L,_,3).
valid([E],_,_) :-
lastE([E],0).
valid([H|[H1|T]],_,3) :-
valid([H1|T],H,H1).
valid([_|[H1|T]],N,M) :-
calc(N,M),
valid([H1|T],M,H1).
上記のコードはすべて正しく動作します (テスト済み)。しかし、genAll の次のコードでは、引数が十分にインスタンス化されていないというエラーが発生します。
genAll(N) :-
N1 is 2*N,
N2 is N1+1,
generate(L1,N2),
valid(L1),
write('['),
printl(L1).
printl([]) :-
write(']').
printl([0|T]) :-
write('0 '),
printl(T).
printl([1|T]) :-
write('1 '),
printl(T).
printl([-1|T]) :-
write('-1 '),
printl(T).
何が悪いのかわかりません。