如何在prolog中编写谓词convert/2?
我想写一个谓词转换/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
? - 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@=