在prolog中寻找所有解

在prolog中寻找所有解,prolog,prolog-findall,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

在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]] 
如果你仔细观察,你会发现结尾没有句号,也没有对错的陈述。这会让人相信它是无限循环的。但事实并非如此,因为包矩阵已经完全成形,我可以简单地键入“.”来结束程序(而不是中止程序)


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

您已经构建了
测试
谓词,以便对
需求(N)
资源(R)
的每个实例组合调用
bagof/3
,因此它在自己的
bagof/3
结果中收集
投标的每个结果:

ece3520 1 joel
Bag = [[ece3520, 1, tu, 11, 14, joel, _G4310]]
第一行是
make\u bid
谓词中的
write
。第二行是针对一对
需求
/
资源
的单个查询的
结果。列表中的最后一个参数,
\u G4310
,之所以出现,是因为谓词使用了
\u
,并且它是匿名的(从未使用/实例化)

您当前的
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).
(注意:我不知道为什么在第三个list参数的末尾有
。它代表什么?)

如果要在一个列表中收集整个结果,则可以使用
findall/3

findall([Class, Sect, Name], (needs(N), resources(R), make_bid(N, R, [Class, Sect, _, _, _, Name, _]), Listings).
这将收集一个元素列表,看起来像,
[Class,Sect,Name]
。您可以在这里使用
bagof/3
,但是对于
make\u bid/3
调用中您不想绑定的变量,您需要一个存在量词

如果您想要完整的
列表
列表,那么:

findall(L, (needs(N), resources(R), make_bid(N, R, L)), Listings).

但是
Listings
的每个元素都是一个列表,其最后一个元素是一个匿名变量,因为
make\u bid/3
就是这样构造的。

如果老师上一节课,你不需要让他不在吗?我会选择bagof(N,needs(N),needs)
然后选择追索权,因为可用时间会改变。但我不能帮你回答这个问题。哦,事实上我知道:你的一个谓词正在生成一个开放的分支,这还没有被考虑。作为一个简单的例子,我能想到的最小的知识库是:
a。答:-失败。
。如果您查询
?-a.
,您将首先得到
true
,然后在请求更多后得到
false
。一些Prolog系统使用变量绑定(如果有的话)替换
true
。因此,为了更接近您的案例,请选择
a(1)。a(216;):-fail
和query
?-a(a)
。请尝试findall而不是bagofI。我有另一个问题。首先,谢谢你,这帮了大忙。我得到了我想要的矩阵。问题是,我不再需要矩阵了。我希望该计划产生一个bids变量,其结构与需求和资源相同,然后我可以从那里开始。你知道怎么做吗?我觉得这是一个简单的编辑,但我不知道在哪里可以找到这些信息。至于你的问题,为什么u在那里,这是一个代码片段,我正在试验。这个变量现在正好是垃圾。@PowerOfKaishin是的,这是一个简单的改变。你到底想让术语看起来像什么?呃,很抱歉这么紧张,但我决定放弃这个想法,至少现在是这样。我回到了绘图板,因为矩阵是在prolog中执行操作的最佳方式,但它们几乎使回溯不可能。