【问题标题】:Prolog - Creating a listProlog - 创建一个列表
【发布时间】:2017-12-07 01:52:26
【问题描述】:

需要帮助创建一个列表。我需要返回课程先决条件的所有可能组合,包括先决条件的先决条件。

这里有一些我需要使用的规则和事实,(一些提供,一些我已经创建)。

prereqFor(engg233, []).
prereqFor(encm339, [engg233]).
prereqFor(cpsc217, []).
prereqFor(cpsc219, [cpsc217]).
prereqFor(cpsc231, []).
prereqFor(cpsc233, [cpsc231]).
prereqFor(math271, [X]) :-
   member(X, [math211, math213]).
prereqFor(math273, []).
prereqFor(cpsc319, [C]) :- 
   member(C, [cpsc219, cpsc233, cpsc235, encm339]).
prereqFor(cpsc331, [M, C]) :- 
   member(M, [math271, math273]), 
   member(C, [cpsc219, cpsc233, cpsc235, encm339]).
prereqFor(cpsc335, [C]) :- 
   member(C, [cpsc319, cpsc331]).

现在我要完成这两个功能,其中一个是帮助器...而且我似乎无法使用 [H|T] 或附加来填充列表...我的当前尝试:

allPrereqFor(Course, Prerequisites) :-
   prereqFor(Course, Prerequisites),
   creatingList(Course, Prerequisites, []).

creatingList(Course, Prerequisites, OnGoingList) :-
   append(Course, Prerequisites, myList).

我也尝试过类似的方法:

allPrereqFor(Course, Prerequisites) :-
   prereqFor(Course, Prerequisites),
   creatingList(Prerequisites, []).

creatingList(Addition, OnGoingList) :-
   [Addition | OnGoingList].

在尝试递归案例之前,我什至无法获得最简单的输出。

我没有列出每个 prereqFor 函数,但示例输出如下:

| ?- allPrereqFor(cpsc331, X).
X = [cpsc217,cpsc219,math211,math271] ? ;
X = [cpsc231,cpsc233,math211,math271] ? ;
X = [consent235,cpsc235,math211,math271] ? ;
X = [encm339,engg233,math211,math271] ? ;

另一个解决方案的尝试...

allPrereqFor(Course,[],Result) :-   append([Course],[],Result).
allPrereqFor(Course, X,Result) :-   prereqFor(Course, Y),
                                    Y=[H|T],
                                    allPrereqFor(H,X,Result).

痕迹:

| ?- allPrereqFor(cpsc331,X).
  1    1  Call: allPrereqFor(cpsc331,_23) ? 
  1    1  Exit: allPrereqFor(cpsc331,[]) ? 

X = [] ? ;
  1    1  Redo: allPrereqFor(cpsc331,[]) ? 
  2    2  Call: prereqFor(cpsc331,_92) ? 
  3    3  Call: member(_78,[math271,math273]) ? 
  3    3  Exit: member(math271,[math271,math273]) ? 
  4    3  Call: member(_80,[cpsc219,cpsc233,cpsc235,encm339]) ? 
  4    3  Exit: member(cpsc219,[cpsc219,cpsc233,cpsc235,encm339]) ? 
  2    2  Exit: prereqFor(cpsc331,[math271,cpsc219]) ? 
  5    2  Call: allPrereqFor(math271,_23) ? 
  5    2  Exit: allPrereqFor(math271,[]) ? 
  1    1  Exit: allPrereqFor(cpsc331,[]) ? 

X = [] ? ;
  1    1  Redo: allPrereqFor(cpsc331,[]) ? 
  5    2  Redo: allPrereqFor(math271,[]) ?

当我跟踪时,我可以看到它递归地访问了所有正确的课程,但它只是不断输出:

X = [] ?;

【问题讨论】:

  • 作为作业,我认为您不应该自己添加事实,您可以发布原始事实吗?
  • 解释“先决条件组合”的另一种方式是“材料构建”。如果您搜索“Prolog 物料清单”,您将找到this。虽然不是一个确切的答案,但它会让你进入球场。 :)
  • 可以帮助您学习 Prolog 的其他方法是查看使用 Prolog 解决的非常简单的练习示例,但也可以使用另一种编程语言解决。见this
  • 它很接近,但这是我已经拥有的部分......一个类似的例子是如果你可以选择不同的轮胎并输出每个组合。即 (spoke, chain, dunlop) (spoke, chain, goodyear) (spoke, chain, yomoto),但每个部分都有不同的组合,所以如果有 3 种辐条,3 种链条,3 种轮胎,我需要输出 27 种不同的组合。这就是我卡住的地方。
  • @GuyCoder:快来回答吧!

标签: list prolog


【解决方案1】:

如果我正确理解您的问题,那么:

您正在寻找基于 andor 谓词的组合列表。

例如

要参加cpsc219,您需要参加
cpsc217cpsc219

要参加math271,您需要参加
math211math271
math213math271

link 中,该示例使用build of materials 表示自行车,实际问题的材料构建类似于您的先决条件。

此答案将使用DCG,因为您正在构建列表,并且在主要使用列表 DCG 时使用 Prolog 是首选。

对于自行车示例,DCG 规则仅显示 and DCG 规则,在看到您在评论中对我的问题的回答后,您还需要 or DCG 规则,但自行车示例中没有给出这些规则。

所以只是回顾一下: 在 Prolog 中,and 使用 , (,/2) 和 or 完成,这可以使用 ; (;/2) 完成,但更常见的是使用多个 DCG 规则完成。请注意,这里提到的,; 不是列表运算符,而是针对目标的运算符。

自行车and DCG 传动链规则示例。

drivechain --> crank, pedal, pedal, chain.

现在缺少使用多个 DCG 规则实现的 or DCG 规则示例

tire --> [dunlop].
tire --> [goodyear].
tire --> [yomoto].

或使用;实现

tire -->
    [dunlop]; [goodyear]; [yomoto].

and DCG 规则的工作示例:

?- drivechain(X,[]).
X = [crank, pedal, pedal, chain] ;
false.

or DCG 规则的工作示例:

?- tire(X,[]).
X = [dunlop] ;
X = [goodyear] ;
X = [yomoto] ;
false.

因此,对于 math271 需要 math211math213 的问题,DCG 规则将是:

math211 --> [math211].
math213 --> [math213].

math271 --> math211.
math271 --> math213.

?- math271(X,[]).
X = [math211] ;
X = [math213].

由于您指出这是原始帖子中的一项作业,因此我将其视为家庭作业,因此我不会对您的问题给出具体答案,而是使用自行车示例向您展示类似的内容。

bike --> frame, drivechain, wheel, wheel.    
wheel --> spokes, rim, hub, tire.

tire --> [dunlop].
tire --> [goodyear].
tire --> [yomoto].

drivechain --> crank, pedal, pedal, chain.

spokes --> [spokes].
crank --> [crank].
pedal --> [pedal].
chain --> [chain].
rim --> [rim].
hub --> [hub].
frame --> [frame].

?- bike(X,[]).
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear] ;
X = [frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto].

请注意,即使轮胎由三个品牌组成,也有 9 个答案,因为有两个轮子,每个轮子都有一个轮胎,每个轮胎可以是三个品牌之一,因此 3 * 3 是 9。

SWI-Prolog 特定:
由于其中一些答案会很长并且会被... 截断,请参阅此answer 以获取帮助以查看没有... 的完整答案。换句话说,将;false 附加到查询中,并在第一个答案后按w,然后按空格键以获得更多答案。

由于DCGsyntactic sugar 类似,因此要将脱糖DCG 规则(-->)视为谓词(:-),请使用listing/1,例如

?- listing(wheel).
wheel(A, E) :-
        spokes(A, B),
        rim(B, C),
        hub(C, D),
        tire(D, E).
true.

正如我在 cmets 中所指出的,我看到 @false 可能会回答这个问题。我向他学习,所以我完全期望他的答案比我的更好,但我发布我的答案是因为如果有人发现我的答案有问题并指出,那么我也会学习。

====================================

更精细的自行车示例,可以制作自行车或三轮车。

bike --> type.
type --> bicycle.
type --> tricycle.
bicycle --> bicycle_frame, bicycle_drivechain, wheel, wheel.
tricycle --> tricycle_frame, tricycle_drive, wheel, wheel, wheel.
wheel --> spokes, rim, hub, tire.
bicycle_drivechain --> crank, pedal, pedal, chain.
tricycle_drive --> crank, pedal, pedal.
bicycle_frame --> [bicycle_frame].
tricycle_frame --> [tricycle_frame].
tire --> [dunlop].
tire --> [goodyear].
tire --> [yomoto].
spokes --> [spokes].
crank --> [crank].
pedal --> [pedal].
chain --> [chain].
rim --> [rim].
hub --> [hub].

?- bike(X,[]);false.
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear] ;
X = [bicycle_frame, crank, pedal, pedal, chain, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear, spokes, rim, hub, yomoto] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto, spokes, rim, hub, dunlop] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto, spokes, rim, hub, goodyear] ;
X = [tricycle_frame, crank, pedal, pedal, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto, spokes, rim, hub, yomoto] ;
false.

【讨论】:

  • 我们从未见过 --> 但它似乎相当不言自明......不过,这似乎是一种相当手动的方法。我希望使用我在 A 部分中创建的所有谓词(这对赋值有意义)作为我递归的一部分,即遵循逻辑...
  • allPrereqFor(parentCourse, X) :- 以某种方式使用 prereqFor(parentCourse,X)... 创建所有直接 prereqs 的列表... 在父级的所有 prereqs 中递归(使用辅助函数?)当然,再次使用 prereqFor(1stprereq,X), prereqFor(2ndprereq,X)... 继续递归直到 [] 意味着这是一门没有 prereqs 的课程... 我们只剩下 X=[prereq, prereqs-prereq, prereq, prereq, prereq's-prereq's-prereq, prereq]?
  • 感谢cpsc331 的输出更新我现在看到我的答案没有按您的需要分组。我会努力的。
【解决方案2】:

可以递归地找到前置需求的前置需求。好吧,你应该使用findall/3flatten/2,它们是在 prolog 库中定义的。

pre(X,Y):-
    preRequirement(X,Y).


preRequirement(X,[(X-List)|Y]):-
    findall(Z,prereqFor(X,Z),Res),
    flatten(Res,List),
    findPreOfPre(List,Y).


findPreOfPre([],[]).
findPreOfPre([H|T],[(H-L)|Result]):-
    findall(P,prereqFor(H,P),N),
    flatten(N,L),
    findPreOfPre(T,Result).

【讨论】:

  • 不工作。仅输出直接先决条件。虽然它确实输出了 4 个 cpsc319 和 8 个 cpsc331,这说明它正在正确地递归......
  • 你能举例说明你想要什么吗?你说“先决条件的先决条件”这就是这段代码的作用。
  • 直接复制看看能不能用,我只得到了直接的先决条件。
  • @johnstamos 如果查询pre(cpsc319,X). 那么它将返回cpsc319 的先决条件列表以及cpsc219, cpsc233, cpsc235, encm339 的先决条件math319 的先决条件
  • 好的,我现在知道了。对不起。格式让我失望。我应该提供一个示例输出。我已经更新了问题...
猜你喜欢
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多