首页 > 解决方案 > Prolog 相互递归谓词

问题描述

晚上好,

我是 Prolog 的新手,我有一个问题要解决。我试着自己做,但它对我不起作用。我搜索了我的 Prolog 书籍以寻求任何帮助,但也没有找到任何帮助。这个问题真的让我很困惑。

问题是:

我们需要计算每个任务的最早开始时间(必须首先完成它的先决条件,它可以开始的最早时间)。

• 任务的提前开始时间由其先决条件的最晚提前完成给出。

• 任何任务列表的最迟提前完成时间可以通过从零开始,依次取最大值和每个任务的提前完成时间来计算。

• 任务的提前完成时间是通过将其持续时间与其提前开始时间相加得出的。

在 Prolog 中为谓词 e_start、l_e_finish、e_finish 编写定义。这些谓词是相互递归的。

任务及其时间定义如下:

duration(Task, Time),
duration(b, 10),
duration(k,5),
duration(a,2).

先决条件定义如下:

prerequisites(Task, PreqTask),
prerequisites(k,[b]),
prerequisites(b,[]),
prerequisites(a,[k]).

我试图解决它,但我认为我需要更多解释如何正确地做到这一点,因为我无法做到正确。

我的解决方案是:

e_start(Task,Start):-
   prereqs(Task, X),
   l_e_finish(X,Start).

l_e_finish(Task,Finish) :-
    e_finish(Task,Finish),
    l_e_finish(Task,Finish1),
    duration(Task, Finish),
    max(Finish,Task,Finish1).

e_finish(Task,Finish):-
    duration(Task, Time),
    e_start(Task,Finish),
    Finish is Time+Finish.

任何帮助我都会非常感激。谢谢各位码农!

标签: recursionprolog

解决方案


让我们首先考虑没有先决条件的情况。在这种情况下,您最早的完成就是您的持续时间:

early_finish(T, Finish) :- 
    duration(T, Finish).

如果你有先决条件怎么办?然后你的早期完成是你的持续时间加上最新的,看起来像这样:

early_finish(T, Finish) :-
    prerequisites(T, Prerequisites),
    maplist(early_finish, Prerequisites, PrerequisiteFinishes),
    maxlist(PrerequisiteFinishes, LastFinish),
    duration(T, Duration),
    Finish is LastFinish + Duration.

我假设您在maxlist/2这里有一个谓词,可以为您提供列表中最大的项目。如果您定义maxlist/2为空列表提供 0 并且您保证所有任务都有prerequisite/2定义,那么您只需使用一个子句即可。如果没有,您将不得不找到一种方法来结合这两个子句的逻辑。


推荐阅读