我对Prolog很新,我正在尝试使用它来订购具有已定义约束的列表。
问题始于以下定义:
Item
是长度为3的列表:[Name, Type, Weight]
。Content
是项目[item_0,.....item_n]
。ContentList
是Content
例如:
使用以下项目:
item_1 = [chicken, meat, 1.0]
item_2 = [eggplant, vegetable, 0.5]
item_3 = [tomatoes, vegetable, 1.0]
item_4 = [bread, other, 0.2]
我们构建了两个内容:
contentA = [item_2, item_3]
contentB = [item_1, item_4]
contentC = [item_3, item_4]
现在,让我们说我们有一些内容定义:
hasItemType([_, XType, _], XType).
hasListItemType([H|T], Type) :-
hasItemType(H, Type);
hasListItemType(T, Type).
hasListOnlyItemType([H|T], Type) :-
hasItemType(H, Type),
hasListItemType(T, Type)
isVegetarian(Content) :- hasListOnlyItemType(Content, vegetable).
hasVegetables(Content) :- hasListItemType(Content, vegetable).
hasMeat(Content) :- hasListItemType(Content, meat).
目标是:
根据Content
列表,返回ContentList
,其中匹配定义的最佳订单:
例如(但因此我的问题是我不确定这是否是正确的做法。)
-> `order(A, B)` A is before B in the output list.
order(ContentA, ContentB) :-
isVegetarian(ContentA),
hasVegetables(ContentB).
order(ContentA, ContentB) :-
hasVegetables(ContentA),
hasMeat(ContentB).
理想情况下,我想要这样的事情:
solve([contentB, contentC, contentA])
将返回[contentA, contentB, contentC]
,因为: 订单(contentA,contentB),订单(contentA,contentC),订单(contentB,contentC)
所以我基本上有两个问题:
order
和约束后,编写解算器的方法是什么?我理解我的问题有点宽,所以我会接受任何建议,参考,想法;)
如果你读到这篇文章,请提前致谢!
答案 0 :(得分:1)
您需要的是排序功能,但不能使用标准比较函数 - 谓词(如=<
或>=
进行排序,而是使用您的订单谓词。因此,您需要在Prolog中实现排序算法,例如插入排序:
insertionSort([], []).
insertionSort([HEAD|TAIL], RESULT) :-
insertionSort(TAIL, LIST), insertInPlace(HEAD, LIST, RESULT).
insertInPlace(ELEMENT, [], [ELEMENT]).
insertInPlace(ELEMENT, [HEAD|TAIL], [ELEMENT|LIST]) :-
order(ELEMENT,HEAD), insertInPlace(HEAD, TAIL, LIST).
insertInPlace(ELEMENT, [HEAD|TAIL], [HEAD|LIST]) :-
\+order(ELEMENT ,HEAD), insertInPlace(ELEMENT, TAIL, LIST).
您还可以实现更高效的mergesort。由于我没有数据,我无法看到上述内容是否真的有效,或者是否有一些错误,所以我在等待评论......
我认为它有效我通过查询来测试它:
insertionSort([[[chicken, meat, 1.0],[beaf, meat, 1.0]],[[eggplant, vegetable, 0.5],[tomatoes, vegetable, 1.0]]],Result).
我给了一个列表[content1,cntent2]其中content1有类型的肉,而内容2有类型的蔬菜所以根据顺序谓词输出应该是[content2,content1]所以输出我认为是正确的:
?- insertionSort([[[chicken, meat, 1.0],[beaf, meat, 1.0]],[[eggplant, vegetable, 0.5],[tomatoes, vegetable, 1.0]]],Result).
Result = [[[eggplant, vegetable, 0.5], [tomatoes, vegetable, 1.0]], [[chicken, meat, 1.0], [beaf, meat, 1.0]]] ;
false.