2017-02-19 32 views
0

Я не понимаю, почему мой код не работает.инверсная перестановка в прологе

An inverse permutation is a permutation in which each number and the number of the place which it occupies are exchanged. For example [3,8,5,10,9,4,6,1,7,2] -> [8,10,1,6,3,7,9,2,5,4]

inv_perm3(X,[F],length(X)):- 
    length([F]) == 1, 
    !, 
    nth0(F,X,length(X)). 
inv_perm3(X,[F|M],N):- 
    nth0(F,X,N),   %nth0(?Index, List, Elem) 
    F is F+1, 
    N1 is N+1, 
    inv_perm3(X,M,N1). 

inv_perm(A,B):- 
    inv_perm3(A,B,1). 

Я получаю ложна в каждом входе, я проверить это следующим образом: inv_perm ([2,3,1], X).

+2

У вас есть некоторые основные недоразумения в том, как работает Prolog. Предикаты, поскольку они называются, а не «функции», не «возвращают» значения. Они либо просто преуспевают, либо терпят неудачу (или не заканчиваются). Поэтому 'length ([F]) == 1' всегда будет терпеть неудачу, так как вы спрашивая Prolog, является ли термин 'length ([F])' идентичным '1', который невозможен. Prolog не вычисляет длину' [F] 'в этом контексте. В Prolog длина'/2' предикат, который преуспевает, если вторым аргументом является длина списка, заданного первым аргументом. – lurker

+2

'F is F + 1' всегда будет терпеть неудачу, так как' F' и 'F + 1' никогда не могут иметь одинаковое значение при одном и том же время. – lurker

ответ

1

это способ проще ... намек

?- X=[3,8,5,10,9,4,6,1,7,2],same_length(Y,X),nth1(I,X,V),nth1(V,Y,I). 
X = [3, 8, 5, 10, 9, 4, 6, 1, 7|...], 
Y = [_358, _364, 1, _376, _382, _388, _394, _400, _406|...], 
I = 1, 
V = 3 ; 
X = [3, 8, 5, 10, 9, 4, 6, 1, 7|...], 
Y = [_358, _364, _370, _376, _382, _388, _394, 2, _406|...], 
I = 2, 
V = 8 ; 
... 

в то время как я показал только 1 элемент в обоих списках, вы должны использовать FORALL/2, чтобы проверить все элементы, или FindAll/3, чтобы связать оба списка , Findall позволит генерировать инверсию, в то время как forall просто будет проверять правильность