格式化嵌套的 Prolog 输出

问题描述 投票:0回答:1

我正在使用一个 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]

,但它不是对吧。

任何帮助表示赞赏!

prolog swi-prolog
1个回答
0
投票
您可以使用以下代码生成所需的输出:

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.
    
© www.soinside.com 2019 - 2024. All rights reserved.