prolog中的交换函数,无限循环
我试图在prolog中的交换函数,无限循环,prolog,swi-prolog,Prolog,Swi Prolog,我试图在prolog中创建一个swap函数,但我最终得到了一个无限循环,我尝试使用trace() 这个函数的一个例子是swap(4,3,[“You”,“Are”,“Awesome”,“thank”,“You”],“SwappedList”) 输出为 [“你”、“是”、“谢谢”、“棒极了”、“你”] 在跟踪输出中,显示问题在删除中,因为它是failure和redesthesplit /* Getting the nth element of the list*/ n_thelement(1, [
prolog
中创建一个swap函数,但我最终得到了一个无限循环
,我尝试使用trace()
这个函数的一个例子是swap(4,3,[“You”,“Are”,“Awesome”,“thank”,“You”],“SwappedList”)
输出为
[“你”、“是”、“谢谢”、“棒极了”、“你”]
在跟踪输出中,显示问题在删除中,因为它是failure
和redes
thesplit
/* Getting the nth element of the list*/
n_thelement(1, [Head|_], Head).
n_thelement(N, [_|Tail], Item):-
NewN is N-1,
n_thelement(NewN, Tail, Item).
/* Deleting the element of the desired Nth element*/
delete(X, [X|Tail], Tail).
delete(X, [Head|Tail], [Head|Item]):-
delete(X, Tail, Item).
/* Adding the deleted element to the beginning of the list*/
append([], Element, Element).
append([Head], Element, [Head|Element]).
swap(X, X, List, List).
swap(X, Y, List, NList):-
n_thelement(X, List, Num1),
n_thelement(Y, List, Num2),
split(X, List, B1, A1),
delete(Num1, A1, L1),
append([Num2], L1, NList1),
append(B1, NList1, NList2),
split(Y, NList2, B2, A2),
delete(Num2, A2, L2),
append([Num1], L2, NList3),
append(B2, NList3, NList).
split(1, [Head|Tail], Head, Tail).
split(N, [Old_List|New_List], Old_List, New_List):-
NewN is N -1,
split(NewN, _, Old_List, New_List).
如果我正确理解了你的问题陈述,给出了列表中的索引M和N,使得M
:列表的引入前缀。它的长度是米As
:要交换的第一项B
:列表的中间部分。其长度为N-(M+1)Cs
:要交换的第二项D
:列表的后缀/剩余部分。它是任意长度的Es
append/3
有助于列表的解构和重建,使实际交换变得容易。你有3个箱子
- 首先,两个指数相同的特殊情况,在这种情况下,没有工作要做:
swap( M, M, Ls, Ls ).
- 第二,指数无序的情况,在这种情况下,我们只是递归地交换它们以使它们有序:
swap( M, N, Ls, Rs ) :- M > N, swap(N,M,Ls,Rs).
- 第三,一般情况:
swap( M, N, Ls, Rs ) :- % if the 2 indices differ M < N, % - and are in order M >= 0, % - and M is greater than or equal to zero N >= 0, % - and N is greater than or equal to zero X is N - (M+1), % - compute the length of the middle segment length( As, M ), % - construct an empty, unbound list of length M, the length of the prefix length( Cs, X ), % - and construct an empty, unbound list of that length append( As, [B|T1], Ls), % - get the prefix (As) and the first item (B) to be swapped append( Cs, [D|Es], T1), % - get the middle segment (Cs), the second item (D) to be swapped, and the suffix (Es) append( As, [D|Cs], T2), % - concatenate As, D, and Cs, then... append( T2, [B|Es], Rs ) % - concatenate that with B and the suffix . % Easy!
swap(M,N,Ls,Rs):-%如果两个指数不同 M
=0,%-且M大于或等于零 N>=0,%-且N大于或等于零 X是N-(M+1),%-计算中间段的长度 长度(As,M),%-构造一个空的、未绑定的长度为M的列表,即前缀的长度 长度(Cs,X),%-并构造该长度的空的未绑定列表 追加(As[B | T1],Ls),%-获取前缀(As)和要交换的第一项(B) 追加(Cs,[D|Es],T1),%-获取中间段(Cs)、要交换的第二项(D)和后缀(Es) 追加(As[D | Cs],T2),%-连接As、D和Cs,然后。。。 附加(T2,[B|Es],Rs)%-将其与B和后缀连接起来 . % 容易的!
replace(Index, [Old|Rest], [New|Rest], Old, New) :- Index == 0, !.
replace(Index, [First|Rest], [First|NewRest], Old, New) :-
Index > 0,
Previous is Index - 1,
replace(Previous, Rest, NewRest, Old, New).
示例:
?- replace(1, [a,b,c,d,e], List1, Old1, x).
List1 = [a, x, c, d, e],
Old1 = b.
?- replace(1, [a,b,c,d,e], List1, Old1, New1).
List1 = [a, New1, c, d, e],
Old1 = b.
?- replace(4, [a,b,c,d,e], List2, Old2, New2).
List2 = [a, b, c, d, New2],
Old2 = e.
?- swap(3, 2, ["You", "Are", "Awesome", "thank", "You"], L).
L = ["You", "Are", "thank", "Awesome", "You"].
?- swap(1, 4, [a,b,c,d,e], L).
L = [a, e, c, d, b].
?- swap(0, 3, [a,b,c,d,e], L).
L = [d, b, c, a, e].
?- swap(1, 0, [a,b,c,d,e], L).
L = [b, a, c, d, e].
?- swap(2, 2, [a,b,c,d,e], L).
L = [a, b, c, d, e].
?- swap(3, 9, [a,b,c,d,e], L).
false.
然后,使用此谓词,您可以定义:
swap(I, J, OldList, NewList) :-
replace(I, OldList, List, X, Y),
replace(J, List, NewList, Y, X).
示例:
?- replace(1, [a,b,c,d,e], List1, Old1, x).
List1 = [a, x, c, d, e],
Old1 = b.
?- replace(1, [a,b,c,d,e], List1, Old1, New1).
List1 = [a, New1, c, d, e],
Old1 = b.
?- replace(4, [a,b,c,d,e], List2, Old2, New2).
List2 = [a, b, c, d, New2],
Old2 = e.
?- swap(3, 2, ["You", "Are", "Awesome", "thank", "You"], L).
L = ["You", "Are", "thank", "Awesome", "You"].
?- swap(1, 4, [a,b,c,d,e], L).
L = [a, e, c, d, b].
?- swap(0, 3, [a,b,c,d,e], L).
L = [d, b, c, a, e].
?- swap(1, 0, [a,b,c,d,e], L).
L = [b, a, c, d, e].
?- swap(2, 2, [a,b,c,d,e], L).
L = [a, b, c, d, e].
?- swap(3, 9, [a,b,c,d,e], L).
false.