Prolog - 一周中的几天

时间:2017-05-17 03:52:10

标签: arrays prolog next

我是prolog的新人,这让我头疼。你们能给我一个简单的例子,比如......一周的日子!我们说我有一个

day(mon, tue, wed, thu, fri).

我想知道我一周中的哪一天(假设一开始就把它设置为"星期一",我甚至都不知道怎么做呢,但我想我可以搞清楚),我想把变量设置为"明天",(如果......如果今天是星期一,我想知道明天是星期二)

我知道这听起来很愚蠢但是我和c和java一起使用这对我来说太难了......

谢谢!

6 个答案:

答案 0 :(得分:5)

如果你不介意使用库,你也可以这样做:

:- use_module(library(clpfd)).

ord_weekday(0, mon).
ord_weekday(1, tue).
ord_weekday(2, wed).
ord_weekday(3, thu).
ord_weekday(4, fri).
ord_weekday(5, sat).
ord_weekday(6, sun).

day_next(D, N) :-
    (X+1) mod 7 #= Y,
    ord_weekday(X, D),
    ord_weekday(Y, N).

首先我们将0映射到星期一,1映射到星期二,依此类推;然后,我们将0映射为1,1到2,...,6到0。

现在你可以这样查询:

?- day_next(mon, X).
X = tue.

?- day_next(X, mon).
X = sun.

重要的是,您可以将两个参数都保留为自由变量并枚举所有可能的组合:

?- day_next(D, N).
D = mon, N = tue ;
D = tue, N = wed ;
D = wed, N = thu ;
D = thu, N = fri ;
D = fri, N = sat ;
D = sat, N = sun ;
D = sun, N = mon.

这为this solution提供了完全相同的结果。我更喜欢这个特定问题的另一个解决方案(本周的第二天),但是可能还有其他一些东西要从这里的例子中学到。

答案 1 :(得分:2)

你可能想要像

这样的东西
day([mon,tue,wed,thu,fri,sat,sun]).

以便您有一个可以使用的列表。

然后星期一是mon,您可以使用

Tomorrow = mon

但是如果你想要第二天的一般规则,那么这不是最佳的。

所以也许最好有一个谓词day/2而不是day/1

day(mon,tue).
day(tue,wed).
day(wed,thu).
day(thu,fri).
day(fri,sat).
day(sat,sun).
day(sun,mon).

现在,您只需致电day(Tomorrow,DayAfterThat)即可获取tue

如果你想要所有日子的清单,你可以说

findall(X,day(X,_),Days)

您可以使用day/2assert/1修改规则(例如retract/1)。

答案 2 :(得分:2)

类似于所呈现的方法,但使用不同的方法确定"明天" ...

在Prolog中布置有效日期的最规范方式可能是个别事实:

% Valid days of the week, in order
day_of_week(mon).
day_of_week(tue).
day_of_week(wed).
day_of_week(thu).
day_of_week(fri).
day_of_week(sat).
day_of_week(sun).

然后,对于day_of_week(Day)中任何给定的有效日期,Day等查询都会成功。

要确定给定日期之后的日期,您可以使用通用循环后继谓词:

succ(X, [H|T], S) :-
    succ(X, H, [H|T], S).

succ(X, H, [X], H).
succ(X, _, [X,Y|_], Y).
succ(X, H, [_|T], S) :-
    succ(X, H, T, S).

因此确定第二天将是:

day_after(Day, NextDay) :-
    % List valid days of the week in order
    findall(DayOfWeek, day_of_week(DayOfWeek), DaysOfWeek),
    succ(Day, DaysOfWeek, NextDay).  % NextDay is successor to Day

答案 3 :(得分:1)

这可以帮助您入门:

days(mon,tue,wed,thu,fri,sat,sun).

tomorrow(X,Y) :- days(|Z), tomorrow(X,Y,Z).

tomorrow(X,Y,[X,Y|_]).
tomorrow(X,Y,[_|Z]) :- tomorrow(X,Y,Z).

?- tomorrow(X,tue), write(X), nl.

写出mon

答案 4 :(得分:1)

以下是基于append/3的规范答案:

today_tomorrow(T0, T1) :-
   Days = [mon,tue,wed,thu,fri,sat,sun,mon],
   append(_, [T0,T1|_], Days).

让我们问一个最普遍的查询

?- today_tomorrow(X, Y).
   X = mon, Y = tue
;  X = tue, Y = wed
;  X = wed, Y = thu
;  X = thu, Y = fri
;  X = fri, Y = sat
;  X = sat, Y = sun
;  X = sun, Y = mon
;  false.                   % no more solutions

答案 5 :(得分:-1)

程序

  ([user]) .

  %%%% database-style prolog program .
  %%% for day  , tomorrow , yesterday .

  day( day( sk( 10'7 ) , pk( 36'sun ) , nm( 'sunday' )      , next( 36'mon ) ) ) .
  day( day( sk( 10'6 ) , pk( 36'sat ) , nm( 'saturday' )    , next( 36'sun ) ) ) .
  day( day( sk( 10'5 ) , pk( 36'fri ) , nm( 'friday' )      , next( 36'sat ) ) ) .
  day( day( sk( 10'4 ) , pk( 36'thu ) , nm( 'thursday' )    , next( 36'fri ) ) ) .
  day( day( sk( 10'3 ) , pk( 36'wed ) , nm( 'wednesday' )   , next( 36'thu ) ) ) .
  day( day( sk( 10'2 ) , pk( 36'tue ) , nm( 'tuesday' )     , next( 36'wed ) ) ) .
  day( day( sk( 10'1 ) , pk( 36'mon ) , nm( 'monday' )      , next( 36'tue ) ) ) .

  tomorrow( tomorrow( day( _tomorrow_ ) )  , today( day( _today_ ) ) )
  :-
  (
     _today_ = ( day( sk( _ ) , pk( _ ) , nm( _ ) , next( _next_ ) ) ) ,
     _tomorrow_ = ( day( sk( _ ) , pk( _next_ ) , nm( _ ) , next( _ ) ) ) ,

     day( _today_ ) , 
     day( _tomorrow_ )
  ) .

  yesterday( yesterday( day( _yesterday_ ) )  , today( day( _today_ ) ) )
  :-
  (
     tomorrow( tomorrow( day( _today_ ) ) , today( day( _yesterday_ ) ) )
  ) .

  %%% legend

  %%    pk --- primary key
  %%    sk --- secondary (sort) key
  %%    nm --- name 
  %%    10'2 --- a number whereby each digit has 10 possibilities ( [0-9] )
  %%    16'ff --- a number whereby each digit has 16 possibilities ( [0-9,a-f] )
  %%    36'mon --- a number whereby each digit has 36 possibilities ( [0-9,a-z] )

示例用法

  %%%% example usage


  %% query for all day

  ?- day( DAY ) .

  %@ DAY = day(sk(7),pk(37391),nm(sunday),next(29399)) ? ;
  %@ DAY = day(sk(6),pk(36677),nm(saturday),next(37391)) ? ;
  %@ DAY = day(sk(5),pk(20430),nm(friday),next(36677)) ? ;
  %@ DAY = day(sk(4),pk(38226),nm(thursday),next(20430)) ? ;
  %@ DAY = day(sk(3),pk(41989),nm(wednesday),next(38226)) ? ;
  %@ DAY = day(sk(2),pk(38678),nm(tuesday),next(41989)) ? ;
  %@ DAY = day(sk(1),pk(29399),nm(monday),next(38678))

  %% query for all day , sorted

  ?- setof( _day_ , day( _day_ ) , VECTOR ) .

  %@ VECTOR =
  %@ [
  %@    day(sk(1),pk(29399),nm(monday),next(38678)) ,
  %@    day(sk(2),pk(38678),nm(tuesday),next(41989)) ,
  %@    day(sk(3),pk(41989),nm(wednesday),next(38226)) ,
  %@    day(sk(4),pk(38226),nm(thursday),next(20430)) ,
  %@    day(sk(5),pk(20430),nm(friday),next(36677)) ,
  %@    day(sk(6),pk(36677),nm(saturday),next(37391)) ,
  %@    day(sk(7),pk(37391),nm(sunday),next(29399))
  %@ ]

  %% query for all day , sorted

  ?- use_module( library( lists ) ) .   % for ``member`` .
  ?- setof( _day_ , day( _day_ ) , _vector_ ) , member( DAY , _vector_ ) .

  %@ DAY = day(sk(1),pk(29399),nm(monday),next(38678)) ? ;
  %@ DAY = day(sk(2),pk(38678),nm(tuesday),next(41989)) ? ;
  %@ DAY = day(sk(3),pk(41989),nm(wednesday),next(38226)) ? ;
  %@ DAY = day(sk(4),pk(38226),nm(thursday),next(20430)) ? ;
  %@ DAY = day(sk(5),pk(20430),nm(friday),next(36677)) ? ;
  %@ DAY = day(sk(6),pk(36677),nm(saturday),next(37391)) ? ;
  %@ DAY = day(sk(7),pk(37391),nm(sunday),next(29399)) ? ;

  %% query for all yesterday 

  ?-
  _query_ =
  (
     yesterday( yesterday( day( _yesterday_ ) ) , today( day( _today_ ) ) )
  )
  , 
  setof( [ _yesterday_ , _today_ ]  , _query_ , VECTOR )
  .

  %@ VECTOR =
  %@ [
  %@    [  day(sk(1),pk(29399),nm(monday),next(38678)) ,     day(sk(2),pk(38678),nm(tuesday),next(41989))  ] ,
  %@    [  day(sk(2),pk(38678),nm(tuesday),next(41989)) ,    day(sk(3),pk(41989),nm(wednesday),next(38226))] ,
  %@    [  day(sk(3),pk(41989),nm(wednesday),next(38226)) ,  day(sk(4),pk(38226),nm(thursday),next(20430)) ] ,
  %@    [  day(sk(4),pk(38226),nm(thursday),next(20430)) ,   day(sk(5),pk(20430),nm(friday),next(36677))   ] ,
  %@    [  day(sk(5),pk(20430),nm(friday),next(36677)) ,     day(sk(6),pk(36677),nm(saturday),next(37391)) ] ,
  %@    [  day(sk(6),pk(36677),nm(saturday),next(37391)) ,   day(sk(7),pk(37391),nm(sunday),next(29399))   ] ,
  %@    [  day(sk(7),pk(37391),nm(sunday),next(29399)) ,     day(sk(1),pk(29399),nm(monday),next(38678))   ]
  %@ ]


  %% query for all tomorrow  .
  % format results as a json-style map .

  ?-
  _query_ =
  (
     tomorrow( tomorrow( day( _tomorrow_ ) ) , today( day( _today_ ) ) )
     ,
     _tomorrow_ = day( _ , _ , nm( _nm_tomorrow_ ) , _ )
     ,
     _today_ = day( _ , _ , nm( _nm_today_ ) , _ )
  )
  ,
  _each_ =
  (
     { tommorrow: _nm_tomorrow_ , today: _nm_today_ }
  )
  ,
  setof( _each_ , _query_ , VECTOR )
  .

  %@ VECTOR = [{tommorrow:friday,today:thursday}] ? ;
  %@ VECTOR = [{tommorrow:monday,today:sunday}] ? ;
  %@ VECTOR = [{tommorrow:saturday,today:friday}] ? ;
  %@ VECTOR = [{tommorrow:sunday,today:saturday}] ? ;
  %@ VECTOR = [{tommorrow:thursday,today:wednesday}] ? ;
  %@ VECTOR = [{tommorrow:tuesday,today:monday}] ? ;
  %@ VECTOR = [{tommorrow:wednesday,today:tuesday}]

  %% query for the day named monday

  ?-
  _nm_ =  'monday'
  ,
  _day_ = day( sk( _sk_ ) , pk( _pk_ ) , nm( _nm_ ) , _etc_ )
  ,
  setof( _day_ , day( _day_ ) , VECTOR )
  .

  %@ VECTOR =
  %@ [
  %@    day(sk(1),pk(29399),nm(monday),next(38678))
  %@ ]

  %% query for the today of the tomorrow named monday

  ?-
  _today_ = day( _ , _ , nm( _nm_today_ ) , _ )
  ,
  _tomorrow_ = day( _ , _ , nm( _nm_tomorrow_ ) , _ )
  ,
  _nm_tomorrow_ = 'monday'
  ,
  _query_ = tomorrow( tomorrow( day( _tomorrow_ ) ) , today( day( _today_ ) ) )
  ,
  _each_ = { tomorrow: _nm_tomorrow_ , today: _nm_today_ }
  ,
  setof( _each_ , _query_ , VECTOR )
  .

  %@ VECTOR =
  %@ [
  %@    { tomorrow: monday , today: sunday }
  %@ ]