Using repeat to sort a collection of facts in prolog

社会主义新天地 提交于 2019-12-13 03:18:11

问题


I have a set of facts set/2 where the first variable is the identifier for the set and the second is the value associated with the identifier.
For example:

set(a,2).
set(a,c).
set(a,1).
set(a,a).
set(a,3).
set(a,b).

I need to construct a predicate ordering/2 (using the repeat operator) which will output the values of a specific set in their lexicographic order. For example

?- ordering(a,Output).

Would result in

[1,2,3,a,b,c].

What I have made thus far is this code:

ordering(Input,Output):-    
    findall(X,set(Input,X),List),
    repeat,
    doSort(List)
    sort(List, OrderedList),
    Output = OrderedList. 

The idea here is that the predicate will find all values of the set associated with the specific Input and unify the List variable with them. Now we have the unsorted List. Here comes the part I'm not completely sure on. The predicate is supposed to keep using some sort of specific doSort on the List, then check the List with sort/2 and if it's lexicographically ordered, unify it with the Output.

Can anyone clarify if I'm on the correct path and if yes then how should the doSort be implemented?


回答1:


Alright, I tried a sort of answer for this using @Daniel lyon's help:

ordering(Input,Output):-    
   findall(X,set(Input,X),List),
    repeat,
    permutation(List,PermutationList),
    sort(PermutationList, SortedList),
    Output= SortedList , !. 

The general idea is the same, for the repeat cycle, the predicate will unify the List with PermutationList, try all variants of it and check for their correctness with sort/2 until it achieves the correct permutation, unifying it with SortedList, after that it will unify the Output with SortedList. The cut is there so I will only get the Output once.




回答2:


?- % 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.

now we can try to make these queries reusable:

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(_,_,[]).

To be correct, we need a cut somewhere. Can you spot the place ?



来源:https://stackoverflow.com/questions/47144989/using-repeat-to-sort-a-collection-of-facts-in-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!