(Prolog)如何递归地重新排列列表中的元素以给出答案的多个结果状态?

时间:2014-08-30 05:23:56

标签: list prolog definition

'找到一个列表,其中第一个tos()之后的第一个元素已经相互移动了tos()'。

我该如何转变:

[tos(a), 1, 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e)]

使用prolog进入这个列表?:

 [tos(a), 5, 12, tos(b),1, tos(c), tos(d), 2, 17, tos(e)]
 [tos(a), 5, 12, tos(b), tos(c),1, tos(d), 2, 17, tos(e)]
 [tos(a), 5, 12, tos(b), tos(c), tos(d),1, 2, 17, tos(e)]
 [tos(a), 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e),1]

又名,

neighbours([tos(a), 1, 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e)],X).

X=[[tos(a), 5, 12, tos(b),1, tos(c), tos(d), 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c),1, tos(d), 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c), tos(d),1, 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e),1]].

*编辑*感谢CapelliC澄清我的问题。

1 个答案:

答案 0 :(得分:0)

这是一种不规则的模式,那么你应该更清楚你想要什么。

当你明确它时,你会发现它很容易编程。我假设描述可能是

'找到一个列表,其中第一个元素()之后的第一个元素已经在彼此之后移动了()',即

neighbours(P, L) :-
    P = [tos(X),N|Ps],
    findall(Q, move_after(Ps, N, Q), Qs),
    L = [tos(X)|Qs].

move_after([tos(X)|R], N, [tos(X), N|R]).
move_after([E|R], N, [E|S]) :-
    move_after(R, N, S).

编辑,因为您显示的'示例'是无效的Prolog语法,我认为它类似于

X=[[tos(a), 5, 12, tos(b),1, tos(c), tos(d), 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c),1, tos(d), 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c), tos(d),1, 2, 17, tos(e)],
 [tos(a), 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e),1]].

记下列表清单。但更简单的定义允许以更清洁的方式解决:

neighbours([tos(X),N|Ps], [tos(X)|Qs]) :-
    move_after(Ps, N, Qs).

move_after / 3它与上面相同,但现在必须通过回溯来请求替代解决方案:

?- neighbours([tos(a), 1, 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(e)],L).
L = [tos(a), 5, 12, tos(b), 1, tos(c), tos(d), 2, 17|...] ;
L = [tos(a), 5, 12, tos(b), tos(c), 1, tos(d), 2, 17|...] ;
L = [tos(a), 5, 12, tos(b), tos(c), tos(d), 1, 2, 17|...] ;
L = [tos(a), 5, 12, tos(b), tos(c), tos(d), 2, 17, tos(...)|...] ;
false.
注意分号,强制回溯...