我正在使用一个 Prolog 数据库,该数据库包含一组具有属性和值的实体。我想输出每个实体及其每个属性和值。
我对 Prolog 很陌生,我有一些东西可以为我提供所需的信息,但我需要它以特定的方式格式化。
首先,我需要将属性值用引号引起来。
其次,我希望有缩进和换行符以使其更具可读性,但这部分并不是100%必要的。
这是一个玩具版本:
% 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).
(注意:我无法更改实际的数据库,所以我们假设事实必须按原样表示。)这是我的函子,用于获取所有对象及其属性和值:
% 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)])].
这就是我希望的输出:
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")
]
)
].
缩进和换行并不是绝对必要的,但那就更好了。但引用是必须的,我正在努力弄清楚如何使用 format/2
来完成这项工作。这是我尝试过的一件事:
formatSandbox(Formatted) :-
findall((Object), instanceOf(Object, idPhysicalObject), Objects),
forall(Objects, format("Here is an object: ~q", [Object])).
这显然是非常错误的,因为这是我的输出:
?- formatSandbox(X).
ERROR: source_sink `ball_1' does not exist
ERROR: source_sink `ball_2' does not exist
ERROR: source_sink `block_1' does not exist
Here is an object: _50
我以为我正在做的是“对于对象中的所有内容,告诉我它是什么”,但我不知道如何引用“当前对象”,这就是为什么我只是输入 [Object]
,但它不是对吧。任何帮助表示赞赏!
format_property_value((Property, Value), Atom) :-
format(atom(Atom), '(~w, "~w")', [Property, Value]).
format_property_value_list(PropertyValueList, Atom) :-
maplist(format_property_value, PropertyValueList, AtomicList),
atomic_list_concat(AtomicList, ',\n ', Atom0),
format(atom(Atom), ' [\n ~w\n ]', Atom0).
format_object_properties((Object, Properties), Atom) :-
format_property_value_list(Properties, Atom0),
format(atom(Atom), ' (~w,\n~w\n )', [Object, Atom0]).
format_object_properties_list(ObjectPropertiesList, Atom) :-
maplist(format_object_properties, ObjectPropertiesList, AtomicList),
atomic_list_concat(AtomicList, ',\n', Atom0),
format(atom(Atom), '[\n~w\n]', Atom0).
print_all_objects :-
findAllObjects(ObjectPropertiesList),
format_object_properties_list(ObjectPropertiesList, Atom),
writeln(Atom).
例如:
?- format_property_value((color,red), Atom).
Atom = '(color, "red")'.
?- format_property_value_list([(color,red), (size,small)], Atom).
Atom = ' [\n (color, "red"),\n (size, "small")\n ]'.
?- print_all_objects.
[
(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")
]
)
]
true.