定义一个取决于条件

时间:2017-10-16 13:27:03

标签: inheritance prolog

我需要定义一个谓词吃/ 3(食者,食物,时间)来检查食者是否会吃掉食物,这取决于它的时间。

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

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).

我也有吃/ 2谓词:

eats(carnivore, animal).
eats(herbivore, plant).
eats(omnivore, animal).
eats(omnivore, plant).  

有谓词animal_food / 1和plant_food / 1:

animal_food(animal).
plant_food(plant).

条件是animal_food只能在时间22:00-06.00之间食用,而plant_food只能在Time-s 06:01-21:59之间食用。

例如:

?- eats(fox, hen, 02.00).
如果狐狸是食肉动物或杂食动物,

将返回真实,母鸡是动物食物,食肉动物/杂食动物在夜间吃,基于晚上吃的动物食物。

另一个例子:

?- eats(bessie, cabbage, 14.00).
如果bessie是草食动物,

将返回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) 

eats(cow,cabbage)  

但我遇到问题的地方是 1)吃的时间条件/ 3。

我在伪代码中有一个用于检查时间条件的想法:

21.59 -> 21*60 + 59 = 1298. (minutes)  
06.01 -> 6*60 + 1 = 361. (minutes)  
(Time >= 361, Time=< 1298) -> daytime  
Otherwise -> nighttime 

但我不太确定如何解析像15.30这样的东西,以便我可以进行检查。把它作为一个列表,然后分别对数字进行乘法运算?

2)构建谓词以便检查所有条件(Eater是食肉动物/杂食动物/食草动物,食物是植物食物或动物食物和时间适合食物)。 我做了检查空变量的简单检查

eats([],Food,Time):- fail.
eats(Eater,[],Time):- fail.
eats(Eater,Food,[]):- fail.  

我假设主检查例如是狐狸:

% 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  

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

  1.   

    但我不太确定如何解析像15.30这样的东西,以便我可以进行检查。把它作为一个列表,然后分别对数字进行乘法运算?

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

      

    条件是animal_food只能在时间22:00-06.00之间食用,而plant_food只能在Time-s 06:01-21:59之间食用。

    我可能不会将时间编码为十进制数,但是让我们说你做了;我认为,如果你以自然的方式表达谓语,它就会正常工作:

    daytime(Num) :- 6.01 =< Num, Num =< 21.59.
    nighttime(Num) :- (22 =< Num, Num =< 24); (0 =< Num, Num =< 6).
    

    这有效;问题是它也适用于疯狂的时代(6.79)并且在这种表示中按时算术并不能正常工作。但是,说实话,每个表示都有缺点,这个表示实际上可能足以解决你所描述的问题,所以我可能会容忍它。但我非常宽容。

    在Prolog中,您可以获得使用标准运算符或定义新运算符(如果它适合您的问题)的好处。冒号往往是有问题的,但似乎我可以做这样的事情:

    daytime(Time) :- 6:01 @=< Time, Time @=< 21:59.
    nighttime(Time) :- (22:00 @=< Time, Time @=< 24:00) ; (0 @=< Time, Time @=< 6:00).
    

    原子比较继续允许无效时间,但没有特别的理由在你给出的问题描述中解决它。

    1.   

      构建谓词,以便检查所有条件(Eater是食肉动物/杂食动物/食草动物,食物是植物食物或动物食物和时间适合食物)。

    2. 我会删除你的失败案件; Prolog通常不需要任何帮助来确定事情在不完整时会失败。你只能假设它们在那里而使用它们,如果它们不存在,它就会失败。

      你有一个自然语言定义你想要它做什么,所以从那里开始:

      eats(Eater, Food, Time) :-
          eats(Eater, Food),
          animal_food(Food),
          nighttime(Time).
      eats(Eater, Food, Time) :-
          eats(Eater, Food),
          plant_food(Food),
          daytime(Time).
      

      我认为你实际上拥有了你需要的所有其他部分。这有用吗?

      1. 修改:有效时间
      2. 据我所知,您的任务实际上并不依赖于任何算术或转换。所以我们要担心有效时间就是测试它,并确保测试正在进行中。

        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)).
        

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

答案 1 :(得分:1)

对,非常感谢@ daniel-lyons的帮助。关于谓词的名称和事实我有一些冲突。我最后用eats_rule / 2替换了eats / 2,用plant_food_rule / 1加上animal_food_rule / 1替换了plant_food / 1加上animal_food / 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).