Prolog - 创建列表

时间:2017-12-07 01:52:26

标签: list prolog

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

以下是我需要使用的一些规则和事实,(有些提供,有些是我创建的)。

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 = [] ?;

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,那么:

您希望根据以及谓词构建一个组合列表。

例如

采取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.

正如我在评论中所指出的,我看到@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.

答案 1 :(得分:0)

可以递归地完成预先要求的预先要求。那么,你应该使用在prolog库中定义的findall/3flatten/2

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