在prolog中找到所有解决方案

时间:2015-01-29 23:21:33

标签: prolog prolog-findall

在prolog中,我试图将每个有效的需求配对与资源统一起来

needs([ece2090,1,m,13,16]).
needs([ece3520,1,tu,11,14]).
needs([ece4420,1,w,13,16]).

resources([joel, [ece2090,ece2010,ece3520,ece4420],[[m,13,16]]]).
resources([sam, [ece2010,ece4420],[]]).
resources([pete, [ece3520],[[w,13,16]]]).

使用此公式

make_bid([Class,Sect,Day,Ts,Te],[Name,Cap,Unavail],[Class,Sect,Day,Ts,Te,Name,_]) :-
no_conflict_all_unavailable(Day,Ts,Te,Unavail),
course_capable(Class,Cap),
writef('%w %w %w\n',[Class,Sect,Name]),
fail.

并运行此测试。

test(Listing) :- needs(N), resources(R), make_bid(N,R,Listing).

该计划的这一部分的目的是将每个班级与教师配对,这两个班级都具有教授班级的资格,并且在此期间不可用。它应该给出一个清单。

?- test(Listing).
ece3520 1 joel
ece3520 1 pete
ece4420 1 joel
ece4420 1 sam
false.

运行时,会生成以上内容。这是正确的,但它的格式对我来说是无用的,因为我需要将它作为自己的变量来进行进一步的计算。然后解决方案是使用bagof或findall,对吧?

所以我从程序的主要部分删除了fail子句,然后将测试更改为

test(Bag) :- needs(N), resources(R), bagof(Listing,make_bid(N,R,Listing),Bag).

但它会生成此

ece3520 1 joel
Bag = [[ece3520, 1, tu, 11, 14, joel, _G4310]] 

如果你仔细观察,你会发现最后没有句号,也没有真/假的陈述。这将导致人们相信它是无限循环的。然而,情况并非如此,因为Bag矩阵已完全形成,我只需键入"。"结束程序(而不是,你知道,中止它)。

它只生成第一个有效的解决方案。为什么会这样?

1 个答案:

答案 0 :(得分:0)

您已构建了test谓词,以便为bagof/3needs(N)的每个实例组合调用resources(R),因此它会收集make_bid的每个结果在它自己的bagof/3结果中:

ece3520 1 joel
Bag = [[ece3520, 1, tu, 11, 14, joel, _G4310]]

第一行是write谓词中的make_bid。对于Bag / make_bid对,needs的单个查询的resources结果为_G4310。列表中的最后一个参数_发生是因为您的谓词使用make_bid并且它是匿名的(从未使用/实例化)。

您当前的make_bid([Class, Sect, Day, Ts, Te], [Name, Cap, Unavail], [Class, Sect, Day, Ts, Te, Name, _]) :- no_conflict_all_unavailable(Day, Ts, Te, Unavail), course_capable(Class, Cap). 旨在将结果写入循环,而不是在多个回溯中实例化它们。所以这可以改为:

_

(注意:我不确定你为什么在第3个列表参数的末尾有findall/3。它代表什么?)

如果您想在一个列表中收集整个结果,那么您可以使用findall([Class, Sect, Name], (needs(N), resources(R), make_bid(N, R, [Class, Sect, _, _, _, Name, _]), Listings).

[Class, Sect, Name]

这将收集一个看起来像bagof/3的元素列表。你可以在这里使用make_bid/3,但是你需要一个存在量词,用于Listing调用中你不想绑定的变量。

如果您想要整个findall(L, (needs(N), resources(R), make_bid(N, R, L)), Listings). 列表,那么:

Listings

make_bid/3的每个元素都是一个列表,其最后一个元素是一个匿名变量,因为这就是{{1}}的结构。