Inheritance 定义依赖于条件的谓词

Inheritance 定义依赖于条件的谓词,inheritance,prolog,Inheritance,Prolog,我需要定义一个谓词eats/3(Eater,Food,Time),它根据时间来检查食客是否会吃食物 我有以下语义框架描述其组成部分之间的生物关系: is_a(animal, living_being). is_a(plant, living_being). is_a(herbivore, animal). is_a(carnivore, animal). is_a(omnivore, animal). is_a(flowering_plant, plant). is_a(nonflowering

我需要定义一个谓词eats/3(Eater,Food,Time),它根据时间来检查食客是否会吃食物

我有以下语义框架描述其组成部分之间的生物关系:

is_a(animal, living_being).
is_a(plant, living_being).
is_a(herbivore, animal).
is_a(carnivore, animal).
is_a(omnivore, animal).
is_a(flowering_plant, plant).
is_a(nonflowering_plant, plant).
is_a(fox, carnivore).
is_a(cow, herbivore).
is_a(hen, omnivore).
is_a(bessie, cow).
is_a(hawke, fox).
is_a(coco, hen).
is_a(cabbage, nonflowering_plant).
is_a(rose, flowering_plant).
我还有eats/2谓词:

eats(carnivore, animal).
eats(herbivore, plant).
eats(omnivore, animal).
eats(omnivore, plant).  
有两个谓词:动物食物/1和植物食物/1:

animal_food(animal).
plant_food(plant).
条件是动物食物只能在时间-s 22:00-06.00之间食用,植物食物只能在时间-s 06:01-21:59之间食用

例如:

?- eats(fox, hen, 02.00).
?- eats(bessie, cabbage, 14.00).
如果狐狸是食肉动物或杂食动物,母鸡是动物食物,并且食肉动物/杂食动物根据夜间食用的动物食物在夜间进食,则返回true

另一个例子:

?- eats(fox, hen, 02.00).
?- eats(bessie, cabbage, 14.00).
如果贝西是食草动物,卷心菜是植物性食物,食草动物根据白天吃的植物性食物在白天吃,则返回true

此外,食客不能与食物属于同一类(例如,狐狸不能吃狐狸)

到目前为止,我所做的是:

subclass(Who,Whose):-
    is_a(Who,Whose).
subclass(Who,Whose):-
    is_a(Who,Intermediary),
    subclass(Intermediary,Whose).  
这个谓词子类/2将检查它是否最终会找到两个类之间的关系

有了这个,我做了一个谓词/2:

eats(Who,Whom):-subclass(Who, Eater), subclass(Whom,Food), eats(Eater,Food), Who \= Food.  
我还做了一个谓词animal_food/1和plant_food/1,以便我可以检查,例如,母鸡是否属于animal_food类型,卷心菜是否属于plant_food类型:

animal_food(Who):-subclass(Who,Whose), animal_food(Whose), Who \= Whose.
plant_food(Who):-subclass(Who,Whose), plant_food(Whose), Who \= Whose.  
有了这些,如果我问的话,我就能实现

eats(fox,hen) 

但我遇到的问题是 1) eats/3的时间条件

我对检查时间条件的伪代码有点想法:

21.59 -> 21*60 + 59 = 1298. (minutes)  
06.01 -> 6*60 + 1 = 361. (minutes)  
(Time >= 361, Time=< 1298) -> daytime  
Otherwise -> nighttime 
例如,我假设主要检查狐狸:

% this is pseudocode  
eats(fox,hen,05.59):- Term1 =.. [subclass,fox,X], Term1, (animal_food(hen);plant_food(hen)), Number is 5*60 + 59, (Number>= 361, Number=< 1298) % if the Food is plant food; (!(Number>= 361, Number=< 1298)) %if the Food is animal_food  
%这是伪代码
吃(狐狸,母鸡,05.59):-Term1=。。[狐狸亚纲,X],术语1,(动物食物(母鸡);植物食物(母鸡)),数字为5*60+59,(数字>=361,数字=<1298%);(!(数字>=361,数字=<1298))%如果食品是动物性食品
任何帮助都将不胜感激

  • 但我不太确定如何解析15.30之类的内容,以便进行检查。列一个清单,然后分别对数字进行乘法运算

  • 让我们回顾一下您的情况:

    条件是动物食物只能在时间-s 22:00-06.00之间食用,植物食物只能在时间-s 06:01-21:59之间食用

    我可能不会将时间编码为十进制数,但假设你这样做了;我认为如果你用自然的方式表达,谓词会很好用:

    daytime(Num) :- 6.01 =< Num, Num =< 21.59.
    nighttime(Num) :- (22 =< Num, Num =< 24); (0 =< Num, Num =< 6).
    
    我认为你实际上已经拥有了你所需要的所有其他部分。这行吗

  • 编辑:有效时间
  • 据我所知,你的任务实际上并不依赖于任何算术或时间转换。所以,我们所要做的就是为有效时间进行测试,并确保测试正在进行中

    valid(HH:MM) :- between(0, 24, HH), between(0, 60, MM).
    
    此谓词确认时间值的有效性。如果传入一个无效的时间值,它将失败。试试看。现在,让我们将其插入其他时间谓词:

    daytime(Time) :- 
        valid(Time), 6:01 @=< Time, Time @=< 21:59.
    nighttime(Time) :- 
        valid(Time), 
        ((22:00 @=< Time, Time @=< 24:00) ; 
         (0 @=< Time, Time @=< 6:00)).
    
    白天(时间):-
    有效(时间),6:01@=

    这应该是你需要做的唯一改变。

    对,非常感谢@daniel lyons的帮助。关于谓词的名称和事实,我有一些冲突。最后我用eats\u rule/2代替eats/2,用植物食物/1加动物食物/1代替植物食物/1加动物食物/1。我唯一更改的是谓词的名称

    答案是:

    eats(Who,Whom):-subclass(Who, Eater), subclass(Whom,Food), eats(Eater,Food), Who \= Food.
    time_to_minutes(TimeAsNumber, TimeAsMinutes):-
        Hours is floor(TimeAsNumber),
        Minutes is integer(100*(TimeAsNumber-Hours)),
        between(0,23,Hours), between(0,59,Minutes), 
        TimeAsMinutes is ((Hours *60) + Minutes).
    daytime(Time):- time_to_minutes(Time,TimeResult), (TimeResult>=361, TimeResult=< 1319) .
    nighttime(Time) :- time_to_minutes(Time,TimeResult), ((TimeResult>= 1320 , TimeResult=< 1439) ; 
         (TimeResult>= 0, TimeResult=< 360)).
    eats(Who,Whom,Time):- eats_rule(Who,Whom), animal_food_rule(Whom), nighttime(Time).
    eats(Who,Whom,Time):- eats_rule(Who,Whom), plant_food_rule(Whom), daytime(Time).
    
    eats(Who,Who):-子类(Who,Eater),子类(Who,Food),eats(Eater,Food),Who\=Food。
    时间到分钟(TimeAsNumber,TimeAsMinutes):-
    小时为楼层(时间编号),
    分钟是整数(100*(TimeAsNumber小时)),
    在(0,23,小时)和(0,59,分钟)之间,
    TimeAsMinutes是((小时*60)+分钟)。
    白天(时间):-时间到分钟(时间,时间结果),(时间结果>=361,时间结果=<1319)。
    夜间(时间):-时间到分钟(时间,时间结果),((时间结果>=1320,时间结果=<1439);
    (TimeResult>=0,TimeResult=<360))。
    吃(谁,谁,时间):-吃(谁,谁),动物食物(谁),夜间(时间)。
    吃(谁,谁,时间):-吃(谁,谁),种植(谁),白天(时间)。
    
    感谢您迄今为止的帮助,您的解决方案适用于示例,但我认为该任务确实需要时间分别不超过23小时和59分钟。我该怎么做呢?@T44v1看看我添加了什么来解决这个问题。帮助?最后一件事是时间的格式是HH.MM而不是HH:MM。是简单地将“:”-s替换为“.”-s帮助,还是这里有什么不正确的地方?@T44v1如果这样做,您就是在生成浮点数,并且无法将这些片段进行模式匹配。但是你可以做我正在做的同样的事情,通过做一些算术来得到分数部分和整数部分。好吧,我基本上设法让它与“--s”一起工作,但问题似乎是,如果我试着问eats(fox,chicken,03.59),如果我使用;关于结果。我想问题是我应该只得到一次。也许我的条件太宽松了?
    daytime(Time) :- 
        valid(Time), 6:01 @=< Time, Time @=< 21:59.
    nighttime(Time) :- 
        valid(Time), 
        ((22:00 @=< Time, Time @=< 24:00) ; 
         (0 @=< Time, Time @=< 6:00)).
    
    eats(Who,Whom):-subclass(Who, Eater), subclass(Whom,Food), eats(Eater,Food), Who \= Food.
    time_to_minutes(TimeAsNumber, TimeAsMinutes):-
        Hours is floor(TimeAsNumber),
        Minutes is integer(100*(TimeAsNumber-Hours)),
        between(0,23,Hours), between(0,59,Minutes), 
        TimeAsMinutes is ((Hours *60) + Minutes).
    daytime(Time):- time_to_minutes(Time,TimeResult), (TimeResult>=361, TimeResult=< 1319) .
    nighttime(Time) :- time_to_minutes(Time,TimeResult), ((TimeResult>= 1320 , TimeResult=< 1439) ; 
         (TimeResult>= 0, TimeResult=< 360)).
    eats(Who,Whom,Time):- eats_rule(Who,Whom), animal_food_rule(Whom), nighttime(Time).
    eats(Who,Whom,Time):- eats_rule(Who,Whom), plant_food_rule(Whom), daytime(Time).