如何在Prolog中封送来自JSON的 predicate ?

bqjvbblv  于 2023-01-06  发布在  其他
关注(0)|答案(1)|浏览(135)

在Python中,它与marshal objects from JSON是相同的,我正在Prolog中寻找类似的功能,无论是swi-prolog还是scryer
例如,如果JSON声明

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

我希望能找到load_predicates(j)这样的东西,并立即查阅这些数据,json.dumps()loads()的版本也会非常有用。
编辑:为了清楚起见,这将允许与客户端应用程序的互操作性,客户端应用程序将从用户那里收集规则。该应用程序可能不在Prolog中,而是类似React. js的东西。

wrrgggsh

wrrgggsh1#

我同意评论者的观点,首先将JSON数据转换为正确格式的.pl文件,然后加载它会更容易。
但是,您可以直接从JSON加载 predicate ,将它们转换为Prolog可以理解的表示形式,然后使用assertz将它们添加到知识库中。
如果数据确实包含 predicate 所需的所有语法(如问题中的示例数据),那么转换表示就相当简单,因为您只需要将列表中的元素连接成字符串,然后从字符串中创建一个术语。注意,这个假设跳过了Guy Coder第一个注解中的第二步。
请注意,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.

详细说明:
predicate json_read以以下形式存储数据:

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

这是json术语中的列表,每个元素对应一个键值对。该元素的语法为key=value。在调用json_read时,您已经可以剥离json()术语并将列表直接存储在变量L中。
然后使用member/2搜索复合词predicate=L2,如果JSON文件中有多个 predicate ,则应将其转换为foreach或递归调用,以处理列表中的所有 predicate 。
由于列表L2已经包含了一个语法良好的Prolog predicate ,所以可以使用term_string/2将其连接起来,转换为一个术语,然后Assert。注意,如果 predicate 还没有达到所需的格式,您可以使用内置的 predicate 操作功能从各个片段中构造一个 predicate ,有关一些指针,请参见https://www.swi-prolog.org/pldoc/doc_for?object=copy_predicate_clauses/2

相关问题