如何封送一个谓词从JSON在Prolog?



在Python中,从JSON封送对象是很常见的。我在Prolog中寻求类似的功能,无论是swi-prolog还是scryer

例如,如果我们有JSON声明

{'predicate': 
{'mortal(X)', ':-', 'human(X)'}
}

我希望找到类似load_predicates(j)的东西,并立即咨询该数据。json.dumps()loads()的版本也将非常有用。

编辑:为了清楚起见,这将允许与从用户收集规则的客户端应用程序的互操作性。这个应用程序可能不是在Prolog中,而是像React.js这样的东西。

我同意评论者的意见,首先将JSON数据转换为正确格式的.pl文件,然后加载它会更容易。

但是,您可以直接从JSON中加载谓词,将它们转换为Prolog可以理解的表示形式,并使用assertz将它们添加到知识库中。

如果数据确实包含谓词所需的所有语法(如问题中的示例数据中的情况),那么转换表示就相当简单,因为您只需要将列表的元素连接到字符串中,然后从字符串中创建一个术语。注意,在Guy Coder的第一条注释中,这个假设跳过了第2步。

请注意Prolog JSON库在接受的格式上是相当严格的:只有双引号可以作为字符串分隔符,单值列表(即不是键值对)需要使用[a,b,c]而不是{a,b,c}符号。因此,首先需要重写示例数据:

{"predicate": 
["mortal(X)", ":-", "human(X)"]
}

然后你可以在SWI-Prolog中加载它。最小工作示例:

:- use_module(library(http/json)).
% example fact for testing
human(aristotle).
load_predicate(J) :-
% open the file
open(J, read, JSONstream, []),
% parse the JSON data
json_read(JSONstream, json(L)),
% check for an occurrence of the predicate key with value L2
member(predicate=L2, L),
% concatenate the list into a string
atomics_to_string(L2, S),
% create a term from the string
term_string(T, S),
% add to knowledge base
assertz(T).

示例运行:

?- consult('mwe.pl').
true.
?- load_predicate('example_predicate.json').
true.
?- mortal(X).
X = aristotle.

详细解释:

谓词json_read以以下形式存储数据:

json([predicate=['mortal(X)', :-, 'human(X)']])

这是json术语中的一个列表,每个键值对有一个元素。元素的语法为key=value。在对json_read的调用中,您已经可以剥离json()项并将列表直接存储在变量L中。

则使用member/2搜索复合词predicate=L2。如果JSON文件中有多个谓词,那么应该将其转换为foreach或递归调用,以处理列表中的所有谓词。

由于列表L2已经包含一个语法格式良好的Prolog谓词,它可以直接连接,使用term_string/2转换为术语并断言。注意,如果谓词还不是所需的格式,您可以使用内置的谓词操作功能从各个部分构造一个谓词,参见https://www.swi-prolog.org/pldoc/doc_for?object=copy_predicate_clauses/2获取一些指针。

最新更新