пролог - Генерация дат между датами - PullRequest
2 голосов
/ 21 февраля 2020

Мне нужно сгенерировать все даты между двумя указанными датами.

Мой предикат date_between (DateLow, DateHigh, X) работает правильно:

?- date_between(date(2020,2,15), date(2020,2,25), X).
X = date(2020, 2, 15) ;
X = date(2020, 2, 16) ;
....
X = date(2020, 2, 25) .

Но я думаю, что предикат слишком неуклюж. Есть ли другой способ сделать то же самое, но более элегантный?

Должен ли я переводить дату вперед и назад в секунды (штамп) и секунды в дату?

Мне нужно сравнивать даты посредством преобразования в секундах ?

Вы видите мой код:

date_between(DateLow, DateHigh, DateLow) :-
  datestd_stamp(DateLow, StampLow),
  datestd_stamp(DateHigh, StampHigh),
  StampLow =< StampHigh.

date_between(DateLow, DateHigh, X) :-
  datestd_stamp(DateLow, StampLow),
  datestd_stamp(DateHigh, StampHigh),
  StampLow < StampHigh,
  DateLow = date(Y,M,D),
  Dnxt is D + 1,
  date_time_stamp(date(Y,M,Dnxt,0,0,0,0,-,-), StampNext),
  stamp_date_time(StampNext, Dat, 0),
  date_time_value(date, Dat, DateNxt),
  date_between(DateNxt, DateHigh, X).

datestd_stamp(Data, Stamp) :-
  Data = date(Y,M,D),
  date_time_stamp(date(Y,M,D,0,0,0,0,-,-), StampTmp),
  round(StampTmp, Stamp).

1 Ответ

1 голос
/ 22 февраля 2020

Я пытался улучшить предикат. Время выполнения определенно было сокращено.

Предикат стал проще и быстрее.

Старая версия:

?- time((bagof(X, (date_between(date(2020,1,1), date(2100,12,31), X)), Ls))).
% 680,466 inferences, 0.149 CPU in 0.149 seconds (100% CPU, 4563901 Lips)
Ls = [date(2020, 1, 1), date(2020, 1, 2), date(2020, 1, 3), 

Новая версия:

?- time((bagof(X, (date_between2(date(2020,1,1), date(2100,12,31), X)), Ls))).
% 207,106 inferences, 0.066 CPU in 0.066 seconds (100% CPU, 3157900 Lips)
Ls = [date(2020, 1, 1), date(2020, 1, 2), date(2020, 1, 3), 

Вы можете увидеть новую версию предикат:

date_between2(DateLow, DateHigh, DateLow) :-
  DateLow @=< DateHigh.

date_between2(DateLow, DateHigh, X) :-
  DateLow @< DateHigh,
  DateLow = date(Y,M,D),
  Dnxt is D + 1,
  date_time_stamp(date(Y,M,Dnxt,0,0,0,0,-,-), StampNext),
  stamp_date_time(StampNext, Dat, 0),
  date_time_value(date, Dat, DateNxt),
  date_between2(DateNxt, DateHigh, X).
...