TL; DR: Последовательность, которую вы получаете , сортируется , но по критерию сортировки, которого вы не ожидали!
Давайте запустим CiaoПролог и попытайтесь воспроизвести странное поведение, которое наблюдал ОП!
$ 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
Похоже, что каждый отдельный элемент неуместен - довольно существенная разница:)
- ожидается:
[kate,marc,I,michel,harry,jess,ruth,fran]
- наблюдается:
[fran,_,kate,marc,jess,michel,harry,ruth]
Давайте изменим порядок, например [fran,_,kate,marc,jess,michel,harry,ruth]
, и рассмотрим:
born(fran , date(<b> 4</b>, 03, 1967)).
born(I , date(<b> 9</b>, 03, 1962)).
born(kate , date(<b>11</b>, 02, 1960)).%\_______________________________________________
born(marc , date(<b>11</b>, 02, 1961)).%/ equal primary & secondary, different tertiary
born(jess , date(<b>16</b>, 01, 1965)).
born(michel, date(<b>24</b>, 04, 1963)).
born(harry , date(<b>26</b>, 05, 1964)).%\____________________________________
born(ruth , date(<b>26</b>, 09, 1966)).%/ equal primary, different secondary
% ^^ ^^ ^^^^
% || || ||||
% || || \+++------- tertiary sorting criterion
% || ||
% || \+------------ secondary sorting criterion
% ||
% \+------------------ primary sorting criterion
ключ? Стандартный порядок терминов! Цитирование соответствующей части руководства Ciao Prolog :
Составные термины, упорядоченные сначала по arity,затем по имени главного функтора затем по аргументам в порядке слева направо .Напомним, что списки эквивалентны составным терминам с главным функтором '.'/2
.
Рассмотрим цель findall(<b>Date</b>-Person, born(Person,Date), List)
в определении by_date/1
.Помещение Date
перед Person
в Date-Person
делает его основным критерием.Для сравнения двух date/3
составных терминов используется стандартный порядок.
Чтобы определить относительное положение двух date/3
соединений в стандартном порядке терминов, Prolog использует до трех критериев:
Day
: Если Day
имеет решающее значение, Month
и Year
не имеют значения.
Month
: если Day
не имеет решающего значения, но Month
является решающим, то Year
не имеет значения.
Year
: Только если Day
и Month
оба нерешительны, Year
даже рассматривается.
Итак, можем ли мы решитьпроблема "сортировки по возрасту"?И как?
Да! Следуйте ISO 8601 и переходите с date(<b>Day</b>,Month,<i>Year</i>)
на date(<b>Year</b>,Month,<i>Day</i>)
!
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)).
Образецзапрос:
?- by_date(S).
S = [kate,marc,_,michel,harry,jess,ruth,fran].
Хм ... Мы уже закончили?
- Ожидается:
[kate,marc,<b>I</b>,michel,harry,jess,ruth,fran]
- наблюдается:
[kate,marc,<b>_</b>,michel,harry,jess,ruth,fran]
Не совсем на 100% ... I
- это переменная - мы на самом деле хотели постоянную;замените его атомом i
.Эта переменная инкогнито была причиной получения предупреждения «синглтон-переменная», которое мы получили в начале нашего сеанса Ciao Prolog.НТН!