查找符合条件的项目

br3nt

我有一个类似于的数据库:

item(coin, [gold, metal, round]).
....
item(ball, [sphere, bouncy, -red]).  % notice the negated property

我的目标是找到与给定属性匹配的项目。

问题的一个示例是:

?- findall(I, (item(I, P), properties_true(P, [gold], [], match)), Items).
Items = [coin, ball]

findall/3正在返回所有项目。在这种情况下,目标是仅取回黄金物品。

我怀疑这是因为item/2实际上返回了所有项目,因此将其添加到项目中。我的假设是,properties_true/4这是错误的ball,因此不会添加到中Items

有人能够指出我正确的方向吗?

以下是我使用的规则:

%% properties_true(Prop, True, False, SearchType)
%
%  Prop = the items to search
%  True = List of properties that must be in Prop
%  False = List of items that mustn't be in Prop
%  SearchType = match|solve
%    * solve = Return true if item has all of True and none of False
%    * match = Return true if item has 0 or more of true and none of False  
% 
% 
properties_true([-Property|Rest], True, False, SearchType) :-
    !, property_true(-Property, True, False, SearchType),
    properties_true(Rest, True, [Property|False], SearchType), !.
properties_true([Property|Rest], True, False, SearchType) :-
    property_true(Property, True, False, SearchType),
    properties_true(Rest, [Property|True], False, SearchType), !.

%% property_true/4
%
properties_true([], _, _, _) :- !.
property_true(-Property, _, False, solve) :-
    !, member(Property, False).
property_true(-Property, True, _, match) :-
    !, not(member(Property, True)).
property_true(Property, True, _, solve) :-
    !, member(Property, True).
property_true(Property, _, False, _) :-
    !, not(member(Property, False)).
property_true(_ , [], [], solve) :- !. % dont think i really need this

用法示例:

?- properties_true([sphere, bouncy, -red], [], [], match).
true.

?- properties_true([sphere, bouncy, -red], [], [], solve). % solve needs to match all     properties
false.

?- properties_true([sphere, bouncy, -red], [sphere, bouncy], [red], solve).
true.
用户名

首先建议:标准化您的数据。代替:

item(coin, [gold,metal,round]).
item(ball, [sphere, bouncy, -red]).

说:

item(coin).
item(ball).
item(chair).
item(keyboard).

item_property(coin, gold).
item_property(coin, metal).
item_property(coin, red).
item_property(ball, sphere).
item_property(ball, bouncy).
item_property(ball, -red).
item_property(chair, black).
item_property(chair, -bouncy).
item_property(keyboard, black).
item_property(keyboard, plastic).

现在,编写match_property/2谓词要容易得多

match_property(Property, Item) :-
    (   Property = -NegP
    ->  match_neg_property(NegP, Item)
    ;   item_property(Item, Property)
    ).

match_neg_property(NegP, Item) :-
    item(Item),
    once(neg_property(Item, NegP)).

neg_property(Item, NegP) :-
    item_property(Item, -NegP).
% whether you actually want this clause depends on how you model your world!
neg_property(Item, NegP) :-
    \+ item_property(Item, NegP).

match_property_list(PList, Item) :-
    foreach(
        member(P, PList),
        match_property(P, Item)
    ).

请注意,您不一定需要具有正负属性的两个“模式”。我不确定这是否适合您的一般想法(Prolog说“如果不是真的,那就一定是假的”;显式表示否定属性是不一样的,但是您的初始代码建议您仍然希望“否定就是失败”) 。

但是有了这些基本的构建基块,您现在可以轻松地说出:

?- match_property(-red, Item).
Item = ball ;
Item = chair ;
Item = keyboard.

?- match_property_list([-red, -plastic], Item).
Item = ball ;
Item = chair ;
false.

?- match_property_list([black, -bouncy], Item).
Item = chair ;
Item = keyboard.

我不确定这是否能回答您的问题,但这似乎是一种有效的方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章