我認爲除了JB的建議之外,還有其他一些解決方法。一個俊俏的訣竅是加入了此信息查詢結束執行了ProductTypeN
排序:
ProductType1 @> ProductType2,
ProductType2 @> ProductType3.
這將讓你的三大產品類型中的一種排列,省去您所看到的組合爆炸。
更復雜的技術將是使用setof/3
來列舉解決方案。因爲它將所有的答案都作爲一個集合來產生,所以它必須對這些值進行排序,這樣就可以按照與俗氣的技巧基本相同的方式去除重複項。
more_than_two_product_types(Manufacturer) :-
setof(Manufacturer, T^manufacturer(T,Manufacturer), Manufacturers),
member(Manufacturer, Manufacturers),
setof(Type, Thing^(manufacturer(Thing, Manufacturer), store(Thing, Type)), [_,_,_|_]).
這很複雜,所以讓我們來分解它。首先,這種情況下產生的製造商的列表:
setof(Manufacturer, T^manufacturer(T,Manufacturer), Manufacturers),
的setof/3
元謂詞需要一個構造函數表達式,模板表達式,並返回結果列表。這一個將收集所有manufacturer(T, Manufacturer)
的解決方案,並將它們收集到一個列表中。我們只對製造商的名稱感興趣,所以模板參數只是Manufacturer
。 T^
語法告訴setof/3
T
是manufacturer(T, Manufacturer)
中的自由變量,因此我們不在乎它實例化的是什麼。這是必不可少的,否則本身會爲每種類型生成一個解決方案,這不是我們想要的。
此行迭代廠家的新名單:
member(Manufacturer, Manufacturers),
這種複雜的線路找到我們由製造商生產的所有類型的產品:
setof(Type, Thing^(manufacturer(Thing, Manufacturer), store(Thing, Type)), [_,_,_|_]).
目標表達這裏的序列(manufacturer(Thing, Manufacturer), store(Thing, Type))
。這就是說,找到這個製造商生產的Thing
,然後找到那個東西的Type
。同樣,Thing^
語法表示我們並不在意事情是什麼,所以立即獲得所有的解決方案。與其將這個綁定到我們要處理的列表中,模板[_,_,_|_]
與任何至少包含三個項目的列表相統一。我們並不在乎這些物品是什麼,所以它們都是空白的。測試在您的控制檯,看看它與統一:
?- [1,2,3] = [_,_,_|_].
true.
?- [1,2] = [_,_,_|_].
false.
?- [1,2,3,4] = [_,_,_|_].
true.
這將產生至少三種解決方案,然後扔掉成功,或者如果它產生較少的失敗。你可以看到,有不止一種方法可以用Prolog對一隻貓進行皮膚處理。 :)
這功課?!你有什麼其他未公開的限制?! –
那就是全部。對不清楚 – emanyalpsid
'maplist(store,[I,J,K],[T,R,S]),maplist(製造商,[I,J,K],[C,C,C]), = R,R'= S,T'= S'更短。 –