如何在prolog中编写谓词convert/2?

如何在prolog中编写谓词convert/2?,prolog,Prolog,我想写一个谓词转换/2。 应该是这样的 ? - convert([a,[a,a],[a,b],[b,a],[[a,b]],[d],c],X). X = [a,c,[a],[d],[a,b],[[a,b]]] yes ? - convert([[a,[a,b]],[a,[c,b]],[[a,b],a]], X). X = [[a,[a,b]],[a,[b,c]]] yes ? - convert([[a,b],[a,[a]],[a,b,c]],X). X = [[a,b],[a,[a]],[a

我想写一个谓词转换/2。 应该是这样的

? - convert([a,[a,a],[a,b],[b,a],[[a,b]],[d],c],X).
X = [a,c,[a],[d],[a,b],[[a,b]]]
yes

? - convert([[a,[a,b]],[a,[c,b]],[[a,b],a]], X).
X = [[a,[a,b]],[a,[b,c]]]
yes

? - convert([[a,b],[a,[a]],[a,b,c]],X).
X = [[a,b],[a,[a]],[a,b,c]]
yes
我知道,我必须先找到列表的长度。
然后我必须对其进行排序,最后我必须合并重复的元素。

因此,在不确切了解排序算法的情况下,我创建了一个稍微通用的示例来演示这个概念:

convert(X, X) :- \+is_list(X).
convert([],[]).
convert([InHead|InTail], OutList) :-
    convert(InHead, OutHead),
    convert(InTail, OutTail),
    append([OutHead], OutTail, UnsortedList),
    sort(UnsortedList, DeduplicatedList),
    custom_sort(DeduplicatedList, OutList).

custom_sort(List,Sorted) :-
    permutation(List,Sorted),
    is_sorted(Sorted).

is_sorted([]).
is_sorted([_]).
is_sorted([X,Y|T]) :- 
    % perform any number of tests on X and Y here
    % default is:
    X @=< Y,
    is_sorted([Y|T]).
convert(X,X):-\+is\u列表(X)。
转换([],[])。
转换([InHead | InTail],OutList):-
转化(吸入、排出),
转换(内部、外部),
追加([OutHead]、OutTail、UnsortedList),
排序(未排序列表、重复数据消除列表),
自定义排序(重复数据消除列表、大纲视图)。
自定义排序(列表,已排序):-
排列(列表、排序),
已排序(已排序)。
已排序([])。
已排序([[uu])。
是否按u排序([X,Y | T]):
%在此处对X和Y执行任意数量的测试
%默认值为:
X@=
这将递归地转换列表中的每个列表,然后使用内置排序删除重复项,然后应用自定义排序(基于朴素排序构建)

我最初认为我破解了您的排序算法(按列表深度排序(原子深度为0),然后按列表长度排序(原子长度为0),然后按列表元素排序),并得出以下结论:

list_length(X, 0) :- 
    \+is_list(X).
list_length(X, Y) :- 
    is_list(X), length(X, Y).

list_depth(X, 0) :- \+is_list(X).
list_depth([], 0).
list_depth([Head|Tail], Y) :-
    list_depth(Head, YH),
    list_depth(Tail, YTP),
    YT is YTP - 1,
    Y is max(YH, YT) + 1.

is_sorted([X,Y|T]) :- 
    list_length(X, XL), 
    list_length(Y, YL),
    list_depth(X, XD),
    list_depth(Y, YD),
    ( XD < YD ; 
      ( XD = YD,
        ( XL < YL ; 
          ( XL = YL, 
            X @=< Y) 
        )
      )
    ),
    is_sorted([Y|T]).
列表长度(X,0):-
\+是_列表(X)。
列表长度(X,Y):-
是列表(X),长度(X,Y)。
列表深度(X,0):-\+是列表(X)。
列表深度([],0)。
列表深度([Head | Tail],Y):-
列表深度(水头、YH),
列表深度(尾部,YTP),
YT是YTP-1,
Y是最大值(YH,YT)+1。
是否按u排序([X,Y | T]):
列表长度(X,XL),
列表长度(Y,YL),
列表深度(X,XD),
列表深度(Y,YD),
(XD
。。。但是对于第三个例子来说,这是失败的,其中[a,[a]],[a,b,c]有深度2,然后是深度1,所以我将上面的代码呈现给您,让您更感兴趣

编辑: Boris的评论足以让我意识到,按展平长度排序然后按深度排序适用于所有示例,如下所示:

list_length(X, 0) :- 
    \+is_list(X).
list_length(X, Y) :- 
    is_list(X), 
    flatten(X, Z), 
    length(Z, Y).

list_depth(X, 0) :- \+is_list(X).
list_depth([], 0).
list_depth([Head|Tail], Y) :-
    list_depth(Head, YH),
    list_depth(Tail, YTP),
    YT is YTP - 1,
    Y is max(YH, YT) + 1.

is_sorted([X,Y|T]) :- 
    list_length(X, XL), 
    list_length(Y, YL),
    list_depth(X, XD),
    list_depth(Y, YD),
    ( XL < YL ; 
      ( XL = YL,
        ( XD < YD ; 
          ( XD = YD, 
            X @=< Y) 
        )
      )
    ),
    is_sorted([Y|T]).
列表长度(X,0):-
\+是_列表(X)。
列表长度(X,Y):-
is_列表(X),
展平(X,Z),
长度(Z,Y)。
列表深度(X,0):-\+是列表(X)。
列表深度([],0)。
列表深度([Head | Tail],Y):-
列表深度(水头、YH),
列表深度(尾部,YTP),
YT是YTP-1,
Y是最大值(YH,YT)+1。
是否按u排序([X,Y | T]):
列表长度(X,XL),
列表长度(Y,YL),
列表深度(X,XD),
列表深度(Y,YD),
(XL
好的,但是您能用其他函数替换内置函数“sort”吗?这在这里是最重要的

例子很好;尝试定义一个算法也很好;它仍然有助于明确定义
convert/2
实际上在做什么我很难理解一个细节:为什么
[a,b]
出现在
[[a,b]]]
之前。查询
convert([[a[b,c]],[a,b,c]],X)
的结果会是什么?简单解释一下:在第一个示例中,
[a,b]
[[a,b]]
之前排序,可能是因为第二个是“更深的”。但是,在最后一个示例中,
[a[a]
排序在
[a,b,c]
之前,可能是因为它“较短”。那么,当一件“更深”而另一件“更长”时,你如何对两件事进行分类?好的,我解决了。我使用了:插入(X,[],[X])。插入(X[Y|Tail],[Y|L1]):-Y@=