在prolog中寻找所有解
在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
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中执行操作的最佳方式,但它们几乎使回溯不可能。