我想写一个谓词convert / 2。 它应该像这样工作
DESCRIBE table Select * from risk.risk_basic
我知道,我必须首先找到列表的长度。 然后我必须对它进行排序,最后我必须合并重复的元素。
答案 0 :(得分:2)
因此,在不确切知道您的排序算法是什么的情况下,我创建了一个通用的示例来演示这个概念:
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]).
这会递归转换列表中的每个列表,然后使用内置排序删除重复项,然后应用自定义排序(基于朴素排序)。
我最初认为我破解了你的排序算法(按列表的深度排序(其中一个原子的深度为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]).
...但是你的第三个例子失败了,其中[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]).
答案 1 :(得分:0)
好的,但你可以用其他的替换内置函数'sort'吗?这是最重要的