我正在使用一个 Prolog 数据库,该数据库包含一组具有属性和值的实体。我想输出每个实体及其每个属性和值。
我对 Prolog 很陌生,我有一些东西可以为我提供所需的信息,但它不可读,而且效率也可能相当低。
主要是,我想知道如何更好地显示信息,但任何明显的提高效率的方法也会非常有帮助。
这是我的数据库的玩具版本:
% example objects
instanceOf(ball_1, physicalObject).
instanceOf(ball_2, physicalObject).
instanceOf(block_1, physicalObject).
% example properties
propertyOf(color_ball_1, ball_1).
propertyOf(size_ball_1, ball_1).
propertyOf(color_ball_2, ball_2).
propertyOf(size_ball_2, ball_2).
propertyOf(color_block_1, block_1).
propertyOf(size_block_1, block_1).
% example property values
hasValue(color_ball_1, red).
hasValue(size_ball_1, big).
hasValue(color_ball_2, blue).
hasValue(size_ball_2, small).
hasValue(color_block_1, red).
hasValue(size_block_1, small).
(旁注:我不喜欢这种存储方式,我有
color_ball_1
和 color_ball_2
感觉很笨重,而不是任何只有 physicalObject
的 color
,但我不不知道如何在 Prolog 中正确执行此操作。)
这是我的函子,用于获取所有对象及其属性和值:
% find all properties and values for one object
findEveryPropertyWithValue(Object, Properties) :-
% get one object ...
instanceOf(Object, physicalObject),
% find every property of every object
findall((Property, Value), (propertyOf(Property, Object), hasValue(Property, Value)), Properties).
% find all objects with properties and values
findAllObjects(Objects_and_Properties) :-
% find every physicalObject with its Properties and Values
findall((Obj, Properties), (instanceOf(Obj, physicalObject), findEveryPropertyWithValue(Obj, Properties)), Objects_and_Properties).
如果我只是运行
findEveryPropertyWithValue
那么我会得到一个不错的格式,但它可以更好地显示以在其自己的行或其他内容上显示每个属性:
?- findEveryPropertyWithValue(Obj, Props).
Obj = ball_1,
Props = [(color_ball_1, red), (size_ball_1, big)] ;
Obj = ball_2,
Props = [(color_ball_2, blue), (size_ball_2, small)] ;
Obj = block_1,
Props = [(color_block_1, red), (size_block_1, small)].
但是我需要让 Prolog 继续手动查找解决方案,并且我希望一次性找到所有解决方案,这就是
findAllObjects
的用途,但输出的可读性更差:
?- findAllObjects(Objs).
Objs = [(ball_1, [(color_ball_1, red), (size_ball_1, big)]), (ball_2, [(color_ball_2, blue), (size_ball_2, small)]), (block_1, [(color_block_1, red), (size_block_1, small)])].
如何获得更具可读性的输出,同时仍能在一次调用中获得所有解决方案?
(非常欢迎任何关于如何使整体实施更好的注释!)
您的数据结构可能只是例如:
object_property_value(ball_1, color, red).
object_property_value(ball_1, size, big).
object_property_value(ball_2, color, blue).
object_property_value(ball_2, size, small).
object_property_value(block_1, color, red).
object_property_value(block_1, size, small).
如果有
physicalObject
的替代方案,那么您可以添加例如:
object_type(ball_1, physical).
object_type(ball_2, physical).
object_type(block_1, physical).
object_type(dream_1, imaginary).
Logtalk(可以在大多数 Prolog 系统上运行)提供直接的表示解决方案。例如:
:- category(physical_object).
:- public(color/1).
color(black).
:- public(size/1).
size(tiny).
:- end_category.
% example objects
:- object(ball_1,
imports(physical_object)).
color(red).
size(big).
:- end_object.
:- object(ball_2,
imports(physical_object)).
color(blue).
size(small).
:- end_object.
:- object(block_1,
imports(physical_object)).
color(red).
size(small).
:- end_object.
请注意,
physical_object
类别为颜色和尺寸属性提供了default值。其他表示也是可能的,包括更紧凑/节省空间的表示。了解有多少个对象以及每个对象有多少个属性将有助于做出明智的选择。
查询对象类似。例如:
% find all properties and values for one object
find_property_value_pairs(Object, Pairs) :-
imports_category(Object, physical_object),
findall(
Property-Value,
( Object::current_predicate(Property/1),
functor(Template, Property, 1),
Object::Template,
arg(1, Template, Value)
),
Pairs
).
% find all objects with properties and values
find_all_object_property_pairs(Pairs) :-
findall(
Object-Properties,
find_property_value_pairs(Object, Properties),
Pairs
).
但是请注意,解的查询和显示是正交的。例如:
?- forall(find_property_value_pairs(Object, Pairs), format('~q - ~q~n', [Object, Pairs])).
ball_1 - [color-red,size-big]
ball_2 - [color-blue,size-small]
block_1 - [color-red,size-small]
true.