简体   繁体   中英

How to write a Prolog predicate that will return a list of successor facts, sorted by value

So I have a predicate called get_order_successors(L) and I'm trying to get it to return a list of successor facts, sorted / ordered by ascending value.

An example of this list might look like:

 h(a,12).
 h(b,8).
 h(c,4).
 h(d,3).
 h(f,5).
 h(e,5).
 h(g,0).

So far this is what I've tried. Setting up a list like [[a,12],[b,8],[c,4],etc..] and running a list search clause like so:

on(Item,[Item|Rest]).  

on(Item,[DisregardHead|Tail]):-
          on(Item,Tail).

thats purpose is to go through the list, piece by piece, and add the value of that list to a new list, putting it at the start or the front, depending on its value.. but to be honest I feel a little too in over my head with it as I'm quite new to the language and I'm not even certain that that solution will work?

I'm sure there's a simple solution to this problem that I'm just not seeing at the moment. Anybody that thinks they can help would be majorly appreciated. :)

Assuming that you have a predicate that sets up a list like [[a,12],[b,8],[c,4],etc..] as you described you need to sort the list of lists based on the second element of every inner list. So you need to implement a sorting algorithm (bubblesort,mergesort...) or use the built in sort predicates like sort/2 :

The problem is that sort/2 could sort a list of lists but based on the 1st element of every inner list, for example:

?- sort([[b,2],[a,3]],L).
L = [[a, 3], [b, 2]].

so it doesn't give the desired result: L = [[b, 2], [a, 3]] .

How to fix it?

Just write the predicate that set up the list like:

set_up(L):- findall([X,Y], h(Y,X), L).

and then:

get_order_successors(L):- set_up(L1),sort(L1,L).

example:

?-get_order_successors(L).
L = [[0, g], [3, d], [4, c], [5, e], [5, f], [8, b], [12, a]].

In order to reverse the inner list just write a predicate like:

rev([],[]).
rev([[Number, Letter]|T], [[Letter, Number]|T1]):-rev(T,T1).

and add it like:

get_order_successors(L):- set_up(L1),sort(L1,L2),rev(L2,L).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM