我有一组事实集/2,其中第一个变量是集合的标识符,第二个变量是与标识符关联的值。
例如:
set(a,2).
set(a,c).
set(a,1).
set(a,a).
set(a,3).
set(a,b).我需要构造一个谓词排序/2(使用重复运算符),它将输出特定集的值,并按其字典顺序排列。例如
?- ordering(a,Output).会导致
[1,2,3,a,b,c].到目前为止,我所做的是这样的代码:
ordering(Input,Output):-
findall(X,set(Input,X),List),
repeat,
doSort(List)
sort(List, OrderedList),
Output = OrderedList. 这里的思想是,谓词将找到与特定输入相关联的集合的所有值,并将List变量与它们统一。现在我们有了未排序的列表。这是我不太确定的部分。谓词应该继续在列表中使用某种特定的doSort,然后使用排序/2检查列表,如果它按字典顺序排列,则将它与输出统一起来。
有人能澄清我是否在正确的路径上,如果是,那么doSort应该如何实现?
发布于 2017-11-07 11:38:33
好吧,我试着用丹尼尔·里昂的帮助来回答这个问题:
ordering(Input,Output):-
findall(X,set(Input,X),List),
repeat,
permutation(List,PermutationList),
sort(PermutationList, SortedList),
Output= SortedList , !. 一般的思路是相同的,对于重复循环,谓词将列表与PermutationList统一,尝试其所有变体,并使用排序/2检查它们的正确性,直到达到正确的排列,并与SortedList统一,然后将输出与SortedList统一。裁剪在那里,所以我只能得到一次输出。
发布于 2017-11-08 08:21:05
?- % init test DB
| maplist([X]>>assert(set(a,X)), [c,b,a,1,2,3]).
true.
?- % find first
| set(a,X), \+ (set(a,Y), Y @< X).
X = 1 ;
false.
?- % find next, given - hardcoded here as 1 - previous
| set(a,X), X @> 1, \+ (set(a,Y), Y @> 1, Y @< X).
X = 2 ;
false.现在,我们可以尝试使这些查询可重用:
ordering(S,[H|T]) :- first(S,H), ordering(S,H,T).
first(S,X) :- set(S,X), \+ (set(S,Y), Y @< X).
next(S,P,X) :- set(S,X), X @> P, \+ (set(S,Y), Y @> P, Y @< X).
ordering(S,P,[X|T]) :- next(S,P,X), ordering(S,X,T).
ordering(_,_,[]).要想正确,我们需要在某个地方划个洞。你能看到那个地方吗?
https://stackoverflow.com/questions/47144989
复制相似问题