Dictionary 在swi-prolog中使用词典

Dictionary 在swi-prolog中使用词典,dictionary,prolog,swi-prolog,meta-predicate,Dictionary,Prolog,Swi Prolog,Meta Predicate,我正在Prolog中开发一个简单的web服务,希望用JSON格式的数据响应我的用户。一个很好的工具是reply\u json\u dict/1,它获取一个字典,并将其转换为具有格式良好的json正文的HTTP响应 我的问题是,构建响应字典本身似乎有点麻烦。例如,当我返回一些数据时,我有数据id,但可能/可能没有数据属性(可能是未绑定的变量)。目前,我做了以下工作: OutDict0 = _{ id : DataId }, ( nonvar(Props) -> OutDict1 = OutD

我正在Prolog中开发一个简单的web服务,希望用JSON格式的数据响应我的用户。一个很好的工具是
reply\u json\u 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”}
,这取决于
道具是否绑定,但是。。。我正在寻找一种更简单的方法。主要是因为如果我需要添加更多可选的键/值对,我最终会得到多个含义,如:

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)
这似乎是错误的。有没有更简单的方法

干杯,
Jacek

在本例中,我的建议是使用一个不同的谓词来表示JSON

例如,考虑,它允许您发出JSON,也可以在当前输出中按HythPiBrRARS要求。 假设您对数据字段的表示是整个HTTP库中用于选项处理的通用

名称(值)
符号:

Fields0 = [attributes(Props),time(Time),userName(UserName)], 您可以自己尝试一下,为上面代码段中的单个元素(单例变量)插入合适的值

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

Fields0=[id(i9)、属性(u3;)、时间('12:00')、用户名(3;)], 屈服:

?- main. {"id":"i9", "time":"12:00"} true. -主要的。 {“id”:“i9”,“time”:“12:00”} 符合事实的
您只需要发出适当的内容类型标题,并具有与
reply\u json\u dict/1
相同的输出。

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

例如,考虑,它允许您发出JSON,也可以在当前输出中按HythPiBrRARS要求。 假设您对数据字段的表示是整个HTTP库中用于选项处理的通用

名称(值)
符号:

Fields0 = [attributes(Props),time(Time),userName(UserName)], 您可以自己尝试一下,为上面代码段中的单个元素(单例变量)插入合适的值

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

Fields0=[id(i9)、属性(u3;)、时间('12:00')、用户名(3;)], 屈服:

?- main. {"id":"i9", "time":"12:00"} true. -主要的。 {“id”:“i9”,“time”:“12:00”} 符合事实的
您只需要发出合适的内容类型标题,并具有与
reply\u json\u dict/1
相同的输出。

如果您使用列表表示需要进入dict的所有值,您可以一步完成

?- 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}.

这借用了mat答案中的想法,使用
包含(地面)

如果您使用列表来表示需要输入目录的所有值,则可以一步完成

?- 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}.

这借用了mat回答中的想法,使用
包含(地面)

非常感谢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)

非常感谢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)

看起来不错,建议不错,谢谢。不过,目前我有点被字典难住了。将尝试判断以您的方式重做我的代码需要多少成本。干杯,Jacek太棒了!请注意,必要的更改是非常局部的:即使您的所有其他代码都使用字典,您也可以按照我概述的方式输出值,只需构建一个列表而不是一个字典。@Jacek您可以使用
dict\u create(D,\u,Fields)创建一个过滤列表的字典
或使用
D=D0.put(Fields)
将列表中的元素添加到现有的dict中。这看起来很整洁,非常好的建议,谢谢。不过,目前我有点被字典难住了。将尝试判断以您的方式重做我的代码需要多少成本。干杯,Jacek太棒了!请注意,必要的更改是非常局部的:即使您的所有其他代码都使用字典,您也可以按照我概述的方式输出值,只需构建一个列表而不是一个字典。@Jacek您可以使用
dict\u create(D,\u,Fields)创建一个过滤列表的字典
或使用
D=D0.put(Fields)
将列表中的元素添加到现有的dict中。很好,您已经用这些输入解决了它!但问题仍然存在:既然你已经有了所需的清单,为什么还要创建一个dict呢?考虑到每次使用dict都会降低应用程序的可移植性,因为dict不是Prolog的标准功能……这一点很好,尽管我现在不太关心可移植性。dict的好处在于它保持了键的唯一性,因此映射到JSON对象更自然。请注意,尽管JSON标准允许非唯一键,但许多库不允许,因此最好保持它们的唯一性。在
findall
@Boris:-)的第一个参数中,您不需要在
Key=Value
周围加括号,这样更好。编辑了答案。很好,你已经用这些输入解决了它!但问题仍然存在:既然你已经有了所需的清单,为什么还要创建一个dict呢?考虑到每次使用dict都会降低应用程序的可移植性,因为dict不是Prolog的标准功能……这一点很好,尽管我现在不太关心可移植性。dict的好处在于它保持了键的唯一性,因此映射到JSON对象更自然。请注意,尽管JSON标准允许非唯一键,但许多库不允许,因此最好保持它们的唯一性<