Return the Nth oldest child from a prolog query

Viewed 248
child(john, mary).
child(john, martinez).
child(john, maggie).

age(mary, 11).
age(martinez, 12).
age(maggie, 13).

What I would like to do is define a query that returns the Nth oldest child of a person, in this case John. E.G. 1st oldest, would be Maggie. 2nd oldest would be Martinez, and 3rd oldest would be Mary.

I'm new to prolog, and the tutorials provided on the website are written in some archaic flash-script that has long since been dead and unsupported so I'm kind of in the dark here. Thank you in advance for helping with this.

2 Answers

Compare the children's ages. P is unified with <, > or =

ch_compare(P, C1, C2) :- age(C1, A1), age(C2, A2), compare(P, A2, A1).

Collect all children, sort them and then pick the nth oldest.

nth_child_of(N, Parent, Child) :-
  findall(C, child(Parent, C), Children),
  predsort(ch_compare, Children, Sorted), 
  nth1(N, Sorted, Child).

I suggest you read up on the predicates findall/3, predsort/3.

EDIT: If you want the list of children ordered by age then you have

ch_compare(P, C1, C2) :- age(C1, A1), age(C2, A2), compare(P, A2, A1).
children(Parent, Children) :-
  findall(C, child(Parent, C), Unsorted),
  predsort(ch_compare, Unsorted, Children).
  1. make a QUERY that get's all children of the PERSON0 .
  2. form the result so that AGE comes first in the term .
  3. use setof for the query so that the results are sorted by AGE youngest to oldest .
  4. reverse the youngest to oldest list to get an oldest to youngest list .
  5. obtain the NTH element from the list of oldest to youngest .

nth__oldest__child(NTH0,PERSON0,NTH_CHILD,NTH_AGE)
:-
QUERY=(child(PERSON0,CHILD) , age(CHILD,AGE)) ,
FORM=(age___child(AGE,CHILD)) ,
prolog:setof(FORM,QUERY,YOUNGEST_TO_OLDESTs) ,
lists:reverse(YOUNGEST_TO_OLDESTs,OLDEST_TO_YOUNGESTs) ,
lists:nth1(NTH0,OLDEST_TO_YOUNGESTs,age___child(NTH_AGE,NTH_CHILD))
.

/*
?- nth__oldest__child(1,john,CHILD,AGE) .
CHILD = maggie,
AGE = 13.

?- nth__oldest__child(2,john,CHILD,AGE).
CHILD = martinez,
AGE = 12.

?- nth__oldest__child(3,john,CHILD,AGE).
CHILD = mary,
AGE = 11.

?- nth__oldest__child(4,john,CHILD,AGE).
false.

?-
*/

Related