TL; DR : La séquence que vous obtenez est triée — mais par un critère de tri auquel vous ne vous attendiez pas!
Lançons Ciao Prolog et essayons de reproduire le comportement bizarre observé par l'OP!
$ ciao
Ciao 1.14.2-13646: Mon Aug 15 10:15:33 CEST 2011
?- compile(dmy_vs_ymd).
{Reading /home/stefan/Prolog/dmy_vs_ymd.pl
WARNING: (lns 3-3) [I] - singleton variables in born/2
}
yes
?- by_date(S).
S = [fran,_,kate,marc,jess,michel,harry,ruth] ? ;
no
Il semble que chaque élément est mal placé — tout à fait une différence considérable :)
- prévu:
[kate,marc,I,michel,harry,jess,ruth,fran]
- observé:
[fran,_,kate,marc,jess,michel,harry,ruth]
Nous allons réorganiser les faits comme [fran,_,kate,marc,jess,michel,harry,ruth]
et examiner:
born(fran , date(4, 03, 1967)).
born(I , date(9, 03, 1962)).
born(kate , date(11, 02, 1960)).%\_______________________________________________
born(marc , date(11, 02, 1961)).%/ equal primary & secondary, different tertiary
born(jess , date(16, 01, 1965)).
born(michel, date(24, 04, 1963)).
born(harry , date(26, 05, 1964)).%\____________________________________
born(ruth , date(26, 09, 1966)).%/ equal primary, different secondary
% ^^ ^^ ^^^^
% || || ||||
% || || \+++------- tertiary sorting criterion
% || ||
% || \+------------ secondary sorting criterion
% ||
% \+------------------ primary sorting criterion
La clé? Commande standard des termes! Citant le relevant part du Ciao Prolog manual:
Compound terms, ordered first by arity, then by the name of the principal functor, then by the arguments in left-to-right order. Recall that lists are equivalent to compound terms with principal functor '.'/2
.
Tenir compte l'objectif findall(Date-Person, born(Person,Date), List)
dans la définition de by_date/1
. En mettant Date
avant Person
en Date-Person
en fait le critère principal. Pour la comparaison de deux termes composés date/3
, l'ordre standard est employé.
Pour déterminer la position relative des deux date/3
composés dans l'ordre standard des termes, Prolog utilise jusqu'à trois critères:
Day
: Si Day
est décisive, et Month
Year
sont tous les deux hors de propos.
Month
: Si Day
est indécise, mais Month
est décisive, alors Year
est hors de propos.
Year
: Seulement si Day
et Month
sont à la fois indécise, Year
est même regardé.
So, can we solve the "sort by decreasing age" problem? And how?
Oui! Suivez ISO 8601 et migrez de date(Day,Month,Year)
à date(Year,Month,Day)
!
born(fran ,date(1967,3, 4)).
born(I, date(1962,3, 9)).
born(kate ,date(1960,2,11)).
born(marc ,date(1961,2,11)).
born(jess ,date(1965,1,16)).
born(michel,date(1963,4,24)).
born(harry, date(1964,5,26)).
born(ruth, date(1966,9,26)).
Exemple de requête:
?- by_date(S).
S = [kate,marc,_,michel,harry,jess,ruth,fran].
Hmm ... Est-ce qu'on fait encore?
- attendu:
[kate,marc,I,michel,harry,jess,ruth,fran]
- observé:
[kate,marc,_,michel,harry,jess,ruth,fran]
Pas tout à fait 100% ... I
est une — variable que nous voulions en fait une constante; remplacez-le par l'atome i
. Cette variable incognito était la raison pour laquelle nous avons reçu l'avertissement "singleton variable" que nous avons reçu au début de notre session Ciao Prolog. HTH!
et la raison pour laquelle le downvote est ...? –