2017-02-19 16 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]'的長度。如果第二個參數是由第一個參數給出的列表的長度,則判斷成功 – lurker

+2

由於F和F + 1永遠不會有相同的值,所以'F是F + 1'將總是失敗時間。 – lurker

回答

1

,這更簡單...而我已經展示了兩份名單的只有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 ; 
... 

,你應該使用FORALL/2,檢查所有元素,或的findAll/3涉及兩個列表。 Findall會允許生成相反的結果,而Forall只會檢查其正確性