Algorithm 在Prolog中反转列表的一部分

Algorithm 在Prolog中反转列表的一部分,algorithm,prolog,Algorithm,Prolog,我对这个Prolog函数的目标如下: 给定两个列表x和y,如果y可以通过反转列表x的连续部分由x构成,则返回true 例如,如果输入是x=[1,3,2,4],y=[1,2,3,4],那么结果应该是“true”,因为我们可以反转x的第二和第三个元素来得到y 我真的不知道,我需要一些帮助 从算法上讲,您可以从索引0中比较两者,找出它们的不同之处(称此索引为“a”),并从n中向后比较,直到它们不同为止(称此索引为“b”) 然后在一个列表中从索引“a”反向到索引“b”,并比较列表(或子列表,无所谓),看

我对这个Prolog函数的目标如下:

给定两个列表x和y,如果y可以通过反转列表x的连续部分由x构成,则返回true

例如,如果输入是x=[1,3,2,4],y=[1,2,3,4],那么结果应该是“true”,因为我们可以反转x的第二和第三个元素来得到y


我真的不知道,我需要一些帮助

从算法上讲,您可以从索引0中比较两者,找出它们的不同之处(称此索引为“a”),并从n中向后比较,直到它们不同为止(称此索引为“b”)

然后在一个列表中从索引“a”反向到索引“b”,并比较列表(或子列表,无所谓),看看它们是否相同。如果是,则为真,否则为假

当两个列表相同时,将出现一种极端情况。这可以定义为true或false,具体取决于空集是否算作列表的连续部分

Search forward for mismatch:
[1,2,3,4]
[1,3,2,4]
   ^-------a

Search backward for mismatch:
[1,2,3,4]
[1,3,2,4]
     ^-----b

Reverse sub-list from a to b in either list:
[1,3,2,4]  <-- Reversed sub-list indexed from 1-2
[1,3,2,4]

If equal, then true.
向前搜索不匹配项:
[1,2,3,4]
[1,3,2,4]
^-------a
向后搜索不匹配项:
[1,2,3,4]
[1,3,2,4]
^-----b
将任一列表中的子列表从a反转为b:

[1,3,2,4]这是一个开场白,你可以这样做:

rev(X,Y) :- 
   append(X1,X2,X3),
   append(X3,X4,X),
   reverse(X2,X5),
   append(X1,X5,X6),
   append(X6,X4,Y),
   !.
示例:

?- rev([1,3,2,4],[1,2,3,4]).
true.

?- rev([1,4,3,2],[1,2,3,4]).
true.

下面是使用SICStus Prolog 4.3.1的直接实现:

:- use_module(library(lists)).

list_singlePartReversed(Xs,Ys) :-
    same_length(Xs,Ys),              % Xs and Ys are lists w/the same length
    dif(Xs,Ys),                      % Xs and Ys are not equal
    append(Prefix  ,Xs0   ,Xs),      % Xs and Ys have common prefix
    append(Prefix  ,Ys0   ,Ys),
    append(Part    ,Suffix,Xs0),     % Xs and Ys have common suffix
    append(Reversed,Suffix,Ys0),
    reverse(Part,Reversed).          % the rest of Xs is reversed in Ys
现在来看一些示例查询。。。首先,您在问题中发布的原始查询:

?- list_singlePartReversed([1,3,2,4], [1,2,3,4]).
yes
接下来是一个我们预计失败的简单案例:

?- list_singlePartReversed([1,4,3,2],[]).
no
那么所有可能的反转方法呢

?- list_singlePartReversed([1,2,3,4], Xs).
Xs = [2,1,3,4] ? ;
Xs = [3,2,1,4] ? ;
Xs = [4,3,2,1] ? ;
Xs = [1,3,2,4] ? ;
Xs = [1,4,3,2] ? ;
Xs = [1,2,4,3] ? ;
no
如果第一个参数没有实例化,但第二个参数是实例化的,该怎么办

?- list_singlePartReversed(Xs, [1,2,3,4]).
Xs = [2,1,3,4] ? ;
Xs = [3,2,1,4] ? ;
Xs = [4,3,2,1] ? ;
Xs = [1,3,2,4] ? ;
Xs = [1,4,3,2] ? ;
Xs = [1,2,4,3] ? ;
no
那么最一般的问题呢?我们得到无限解集的一个公平枚举吗

?- list_singlePartReversed(Xs,Ys).
Xs = [_A,_B],       Ys = [_B,_A],       prolog:dif([_A,_B],[_B,_A])             ? ;
Xs = [_A,_B,_C],    Ys = [_B,_A,_C],    prolog:dif([_A,_B,_C],[_B,_A,_C])       ? ;
Xs = [_A,_B,_C],    Ys = [_C,_B,_A],    prolog:dif([_A,_B,_C],[_C,_B,_A])       ? ;
Xs = [_A,_B,_C],    Ys = [_A,_C,_B],    prolog:dif([_A,_B,_C],[_A,_C,_B])       ? ;
Xs = [_A,_B,_C,_D], Ys = [_B,_A,_C,_D], prolog:dif([_A,_B,_C,_D],[_B,_A,_C,_D]) ? ...

出于好奇,您是否需要担心变量是无界的?比如,它应该返回规则([1,3,2,4],X)的所有正确答案。例如?
?-rev([1,4,3,2],])。
不会终止。列表如何
[1,1]
?难道不可能逆转吗?