在序言中找到所有解决方案
Finding all solutions in 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).
该计划这部分的重点是将每个 class 与一位既有资格教授 class 并且在此期间没有空的老师配对。它应该给出一个列表。
?- 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]]
如果仔细观察,您会发现结尾没有句号,也没有 true/false 语句。这会使人相信它是无限循环的。然而,情况并非如此,因为 Bag 矩阵已完全形成,我可以简单地键入“.”。结束程序(而不是,你知道的,中止它)。
它只生成第一个有效的解决方案。为什么会这样?
您已经构建了 test
谓词,以便为 needs(N)
和 resources(R)
的每个实例组合调用 bagof/3
,因此它收集 [=] 的每个结果18=] 在它自己的 bagof/3
结果中:
ece3520 1 joel
Bag = [[ece3520, 1, tu, 11, 14, joel, _G4310]]
第一行是 make_bid
谓词中的 write
。第二行是一对 needs
/resources
对 make_bid
的单个查询的 Bag
结果。列表中的最后一个参数 _G4310
出现是因为您的谓词使用 _
并且它是匿名的(从不 used/instantiated)。
您当前的 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
的结构。
在序言中,我试图统一每一个有效的需求与资源配对
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).
该计划这部分的重点是将每个 class 与一位既有资格教授 class 并且在此期间没有空的老师配对。它应该给出一个列表。
?- 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]]
如果仔细观察,您会发现结尾没有句号,也没有 true/false 语句。这会使人相信它是无限循环的。然而,情况并非如此,因为 Bag 矩阵已完全形成,我可以简单地键入“.”。结束程序(而不是,你知道的,中止它)。
它只生成第一个有效的解决方案。为什么会这样?
您已经构建了 test
谓词,以便为 needs(N)
和 resources(R)
的每个实例组合调用 bagof/3
,因此它收集 [=] 的每个结果18=] 在它自己的 bagof/3
结果中:
ece3520 1 joel
Bag = [[ece3520, 1, tu, 11, 14, joel, _G4310]]
第一行是 make_bid
谓词中的 write
。第二行是一对 needs
/resources
对 make_bid
的单个查询的 Bag
结果。列表中的最后一个参数 _G4310
出现是因为您的谓词使用 _
并且它是匿名的(从不 used/instantiated)。
您当前的 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
的结构。