2016-12-13 5 views
1

Итак, я застрял в этой проблеме часами, и я не могу найти решение.
Мне нужно, учитывая текущую дату, и зная, что самолеты взлетают во вторник, в четверг и субботу в 6:00, подсчитывают дату и время следующего вылета. Я поставил эту информацию в виде фактов (второй аргумент представляет день недели, где 1 = понедельник):Пролог: Поиск следующей даты

departure(time(6,0,0), 2). 
departure(time(6,0,0), 4). 
departure(time(6,0,0), 6). 

Может кто-нибудь помочь мне? Спасибо.

ответ

0

Я предлагаю следующее решение, и я постараюсь esplain это

selNextDepH([], _, First, First). 

selNextDepH([Hd | _], Now, _, Hd) :- 
    Now @<= Hd. 

selNextDepH([Hd | Td], Now, First, NextDep) :- 
    Now @> Hd, 
    selNextDepH(Td, Now, First, NextDep). 

selNextDep([Hd | Td], Now, NextDep) :- 
    selNextDepH([Hd | Td], Now, Hd, NextDep). 

switchDep(dep(Day, Time), departure(Time, Day)). 

nextDep(DayNow, TimeNow, NextDeparture) :- 
    findall(dep(Day, Time), departure(Time, Day), List), 
    sort(List, ListS), 
    selNextDep(ListS, dep(DayNow, TimeNow), NextDep), 
    switchDep(NextDep, NextDeparture). 

Все начинают в nextDep/3 где findall/3 собрать все departure/2 но собирают они, как dep/2, в обратном порядке (dep(Day, Time) вместо departure(Time, Day)), потому что это проще заказать

findall(dep(Day, Time), departure(Time, Day), List), 

Далее мы сортируем список List из dep/2 структур с sort/2

sort(List, ListS), 

так в ListS (отсортированный) мы имеем отклонения (в dep/2 форме) упорядочено день в качестве первого ключа и время, как второй.

Далее мы называем selNextDep/3, чтобы найти следующий выезд в dep/2 форме (NextDep)

selNextDep(ListS, dep(DayNow, TimeNow), NextDep), 

и с switchDep/2, мы получаем следующий вылет в departure/2 форме

switchDep(NextDep, NextDeparture). 

swithcDep/2 тривиально, но selNextDep/3 нет (IMHO).

Идея, лежащая в основе selNextDep/3, - это возврат (в третьем аргументе) первого элемента sel/2 элемента сортированного списка (первого аргумента), который больше, чем второй аргумент (время). Если не найден более крупный элемент, идея возвращает первый элемент списка (первый выход на следующей неделе).

Итак, я разработал простой selNextDep/3, который вызывает только предложение хелпера (selNextDepH/4) с теми же аргументами и добавляет первый элемент списка (в случае отказа при поиске большего элемента); что

selNextDep([Hd | Td], Now, NextDep) :- 
    selNextDepH([Hd | Td], Now, Hd, NextDep). 

Для selNextDepH/4 терминал условие тривиально: если список пуст, вернуть (унифицировать с последним аргументом) первый элемент списка

selNextDepH([], _, First, First). 

Если список не является пусто, то есть 2 случая: (1) теперь времени меньше (или равно), чем первый элемент списка, поэтому мы возвращаемся (унифицировать последний аргумент) первый элемент списка

selNextDepH([Hd | _], Now, _, Hd) :- 
    Now @<= Hd. 

или (2) время теперь больше, чем первый аргумент списка, поэтому мы ищем более крупный отъезд в следующем списке

selNextDepH([Hd | Td], Now, First, NextDep) :- 
    Now @> Hd, 
    selNextDepH(Td, Now, First, NextDep). 
Смежные вопросы