在swi-prolog中使用词典

时间:2016-10-26 19:41:12

标签: dictionary prolog swi-prolog

我正在使用Prolog中的简单Web服务,并希望使用格式化为JSON的数据来响应我的用户。一个很好的工具是reply_json_dict/1,它接受​​一个字典,并使用格式正确的JSON主体在HTTP响应中对其进行转换。

我的麻烦在于构建响应字典本身似乎有点麻烦。例如,当我返回一些数据时,我有数据id但可能/可能没有数据属性(可能是未绑定的变量)。目前我做了以下事情:

OutDict0 = _{ id : DataId },
( nonvar(Props) -> OutDict1 = OutDict0.put(_{ attributes : Props }) ; OutDict1 = OutDict0 ),
reply_json_dict(OutDict1)

哪种方法正常,因此输出为{ "id" : "III" }{ "id" : "III", "attributes" : "AAA" },具体取决于Props是否受约束,但是......我正在寻找一种更简单的方法。主要是因为如果我需要添加更多可选的键/值对,我最终会产生多种含义,如:

OutDict0 = _{ id : DataId },
( nonvar(Props) -> OutDict1 = OutDict0.put(_{ attributes : Props }) ; OutDict1 = OutDict0 ),
( nonvar(Time) -> OutDict2 = OutDict1.put(_{ time : Time }) ; OutDict2 = OutDict1 ),
( nonvar(UserName) -> OutDict3 = OutDict2.put(_{ userName : UserName }) ; OutDict3 = OutDict2 ),
reply_json_dict(OutDict3)

这似乎是错的。有更简单的方法吗?

干杯,   亚切克

3 个答案:

答案 0 :(得分:3)

在这种情况下,我的建议是使用不同的谓词来发出JSON ,而不是乱用字典。

例如,考虑json_write/2,它允许您在HTTP库所需的当前输出中发出JSON。

假设您对数据字段的表示是在整个HTTP库中用于选项处理的常用Name(Value)表示法:

Fields0 = [attributes(Props),time(Time),userName(UserName)],

使用 include/3,您的整个示例变为:

main :-
        Fields0 = [id(DataId),attributes(Props),time(Time),userName(UserName)],
        include(ground, Fields0, Fields),
        json_write(current_output, json(Fields)).

您可以自己尝试一下,方法是在上面的代码段中为 singleton variables 中的各个元素插入合适的值。

例如,我们可以(任意)使用:

        Fields0 = [id(i9),attributes(_),time('12:00'),userName(_)],

得到以下特性:

?- main.
{"id":"i9", "time":"12:00"}
true.

您只需要发出合适的内容类型标头,并且具有reply_json_dict/1 给您的相同输出。

答案 1 :(得分:2)

如果您使用列表来表示需要进入字典的所有值,则可以一步完成。

?- Props = [a,b,c], get_time(Time),
   D0 = _{id:001},
   include(ground, [props:Props,time:Time,user:UserName], Fs),
   D = D0.put(Fs).
D0 = _17726{id:1},
Fs = [props:[a, b, c], time:1477557597.205908],
D = _17726{id:1, props:[a, b, c], time:1477557597.205908}.

这在使用include(ground)的答案中借用了这个想法。

答案 2 :(得分:1)

非常感谢mat和Boris的建议!最后我结合了你的想法:

dict_filter_vars(DictIn, DictOut) :-
    findall(Key=Value, (get_dict(Key, DictIn, Value), nonvar(Value)), Pairs),
    dict_create(DictOut, _, Pairs).

然后我可以使用那么简单:

DictWithVars = _{ id : DataId, attributes : Props, time : Time, userName : UserName },
dict_filter_vars(DictWithVars, DictOut),
reply_json_dict(DictOut)