【问题标题】:Prolog integer comparisonProlog 整数比较
【发布时间】:2014-03-19 15:39:37
【问题描述】:

您好,我在 Prolog 中有一个简单的时钟,它以 5 分钟的间隔测量时间

nextTime(Hrs:Mins1, Hrs:Mins2) :- nextMins(Mins1, Mins2).
nextTime(Hrs1:'55', Hrs2:'00') :- nextHrs(Hrs1, Hrs2).

nextHrs('12', '13').
nextHrs('13', '14').
nextHrs('14', '15').
nextHrs('15', '16'). // and so on 

nextMins('00', '05').
nextMins('05', '10').
nextMins('10', '15').
nextMins('15', '20'). // and so on 

现在我想写一个谓词,它可以让我说出时间 t2 是晚于还是早于时间 t1,这听起来很简单,但我不知道如何比较一个谓词中的两个整数。

我尝试过喜欢的东西:

after(H1:M1, H2:M2) :- (H1 < H2).

arithmetic(X,Y) :- (X<Y).
after(H1:M1, H2:M2) :- arithmetic(H1,H2).

我对 Prolog 真的很陌生,所以上面的内容对某些人来说可能看起来很愚蠢。 所以我的实际问题是如何比较 Prolog 中谓词定义中的两个整数。

【问题讨论】:

  • 您是否有理由使用字符串来表示数字而不仅仅是数字?如果您使用整数,@CapelliC 显示的解决方案将按需要工作。

标签: prolog logic


【解决方案1】:

一个有用的 Prolog 功能是“Standard Order of Terms”。然后你可以写

after(T1, T2) :- T1 @< T2.

【讨论】:

  • 只要时间是HH:MM,这将很有效,其中HHMM 是整数而不是字符串。所以'3:30' @&lt; '13:40'. 是假的,但3:30 @&lt; 13:40. 是真的。
  • @mbratch:也许 OP 已经意识到了这个问题,因为他发布了带有前导零的原子......
  • 是的,这很好。如果在字符串格式中使用前导零,那么这将正常工作。这很有意义。
【解决方案2】:

你没有任何整数:你有原子atom '9' 比较大于 atom 12

只要您的原子始终是 2 个十进制数字('09' 而不是 '9'),您就可以使用 compare/3

after(H1:M1,H2,M2) :- compare( '>' , H1:M1 , H2:M2 ) .

on_or_after(H1:M1,H2:M2) :- compare( '>' , H1:M1 , H2:M2 ) .
on_or_after(H1:M1,H2:M2) :- compare( '=' , H1:M1 , H2:M2 ) .

等等

如果您将谓词更改为使用 整数 而不是原子

nextHrs(12, 13).
nextHrs(13, 14).
nextHrs(14, 15).
nextHrs(15, 16). // and so on  

nextMins(00, 05).
nextMins(05, 10).
nextMins(10, 15).
nextMins(15, 20). // and so on 

您可以使用arithmetic comparison operators 并简单地编写如下内容:

compare_time( H1:M1 , H2:M2 , '<' ) :- H1 < H2 .
compare_time( H1:M1 , H1,M2 , '<' ) :- M1 < M2 .
compare_time( HH:MM , HH:MM , '=' ) .
compare_time( H1:M1 , H2:M2 , '>' ) :- H1 > H2 .
compare_time( H1:M1 , H1:M2 , '>' ) :- M1 > M2 .

如果您始终将原子保持为 2 位文本值,您仍然可以执行相同的操作,但您必须使用 the standard order of terms operators 而不是算术比较运算符。

compare_time( H1:M1 , H2:M2 , '<' ) :- H1 @< H2 .
compare_time( H1:M1 , H1,M2 , '<' ) :- M1 @< M2 .
compare_time( HH:MM , HH:MM , '=' ) .
compare_time( H1:M1 , H2:M2 , '>' ) :- H1 @> H2 .
compare_time( H1:M1 , H1:M2 , '>' ) :- M1 @> M2 .

【讨论】:

  • 如果您使用@&lt; 等,正如@CapelliC 指出的那样,您不需要分别检查小时和分钟,因为如果小时和分钟是整数,Prolog 会做“正确的”比较时的东西,例如,3:25 @&lt; 13:20(它将是“真”)。所以你的compare_time(..., '&lt;') 只需要一个子句:compare_time(T1, T2, '&lt;') :- T1 @&lt; T2。但那时谓词是多余的。
  • Nicholas,作为我声明的附录,OP 可以使用字符串表示小时和分钟,然后使用 T1 @&lt; T2,只要小时和分钟总是左零填充到两位数(即我敢肯定这是他们的意图)。比较,'03':'25' @&lt; '13':'20' 将“做正确的事”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多