基于模式匹配进行多个断言
make multiple assert basing on pattern matching
给定一个字符串的解析树,我的目标是更新我的知识库。
来自如下可变长度的句子:
"node 1 is near node 2 that is near node 3 that is near node 4 that..."
在我的表示中变成了句子的解析树表示,例如:
s(desc(np(noun(node),id(1)),vp(verb(is),prep(near),np(noun(node),id(2),rel_clause(rel(that)...
我想从中提取并断言以下信息:
edge(1,2),edge(2,3),edge(3,4).
我怎样才能实现这个目标?
我试过用
之类的方法处理一些案例
:- dynamic edge/2.
extract(T):- T= s(desc(np(noun(node),id(A)),vp(verb(is),prep(near),np(noun(node),id(B)))),
assert(edge(A,B)).
extract(T):- T= s(desc(np(noun(node),id(A)),vp(verb(is),prep(near),np(noun(node),id(B),rel_clause(rel(that)...
等
但我想管理潜在的无限句子。
我正在使用 SWI-prolog。
编辑:
我输入的解析树的完整示例:
desc(np(noun(node), id(1)), vp(verb(is), prep(near), np(noun(node), id(2),
rel_clause(rel(that), vp(verb(is), prep(near), np(noun(node), id(3),
rel_clause(rel(that), vp(verb(is), prep(near), np(noun(node), id(4)))))))))
首先要做的是对您的数据提出一个更有用的描述。一种方法是像这样分解它:
description = desc(subject, verb_part)
subject = np(noun(node), id(A))
verb_part = vp(verb(is), prep(near), object_part)
object_part = np(noun(node), id(B))
object_part = np(noun(node), id(B), rel_part)
rel_part = relcl(rel(that), verb_part)
从这里,您可以看到递归发生的位置并编写符合上述定义的谓词:
% description = desc(subject, verb_part)
% subject = np(noun(node), id(A))
%
extract(desc(np(noun(node), id(A)), VerbPart)) :-
select_edge(A, VerbPart).
% verb_part = vp(verb(is), prep(near), object_part)
%
select_edge(A, vp(verb(is), prep(near), ObjectPart)) :-
connect_node(A, ObjectPart).
% object_part = np(noun(node), id(B))
%
connect_node(A, np(noun(node), id(B))) :-
assertz(edge(A, B)).
% object_part = np(noun(node), id(B), rel_part)
% rel_part = relcl(rel(that), verb_part)
%
connect_node(A, np(noun(node), id(B), relcl(rel(that), VerbPart))) :-
assertz(edge(A, B)),
select_edge(B, VerbPart).
要执行:
| ?- extract(desc(np(noun(node), id(1)), vp(verb(is), prep(near), np(noun(node), id(2),
relcl(rel(that), vp(verb(is), prep(near), np(noun(node), id(3),
relcl(rel(that), vp(verb(is), prep(near), np(noun(node), id(4))))))))))).
true ? ;
no
结果是肯定的,如果我们列出 edge/2
个事实就可以看出:
| ?- listing(edge).
% file: user_input
edge(1, 2).
edge(2, 3).
edge(3, 4).
yes
您还可以在列表中收集边而不是断言它们,并使查询结果为 [edge(1,2), edge(2,3), edge(3,4)]
:
extract(desc(np(noun(node), id(A)), VerbPart), Edges) :-
select_edge(A, VerbPart, Edges).
select_edge(A, vp(verb(is), prep(near), ObjectPart), Edges) :-
connect_node(A, ObjectPart, Edges).
connect_node(A, np(noun(node), id(B)), [edge(A,B)]).
connect_node(A, np(noun(node), id(B), relcl(rel(that), VerbPart)), [edge(A,B)|Edges]) :-
select_edge(B, VerbPart, Edges).
然后使用 maplist
:
从结果列表中一次断言它们
extract(Description, Edges), maplist(assertz, Edges).
给定一个字符串的解析树,我的目标是更新我的知识库。
来自如下可变长度的句子:
"node 1 is near node 2 that is near node 3 that is near node 4 that..."
在我的表示中变成了句子的解析树表示,例如:
s(desc(np(noun(node),id(1)),vp(verb(is),prep(near),np(noun(node),id(2),rel_clause(rel(that)...
我想从中提取并断言以下信息:
edge(1,2),edge(2,3),edge(3,4).
我怎样才能实现这个目标?
我试过用
之类的方法处理一些案例 :- dynamic edge/2.
extract(T):- T= s(desc(np(noun(node),id(A)),vp(verb(is),prep(near),np(noun(node),id(B)))),
assert(edge(A,B)).
extract(T):- T= s(desc(np(noun(node),id(A)),vp(verb(is),prep(near),np(noun(node),id(B),rel_clause(rel(that)...
等 但我想管理潜在的无限句子。
我正在使用 SWI-prolog。
编辑: 我输入的解析树的完整示例:
desc(np(noun(node), id(1)), vp(verb(is), prep(near), np(noun(node), id(2),
rel_clause(rel(that), vp(verb(is), prep(near), np(noun(node), id(3),
rel_clause(rel(that), vp(verb(is), prep(near), np(noun(node), id(4)))))))))
首先要做的是对您的数据提出一个更有用的描述。一种方法是像这样分解它:
description = desc(subject, verb_part)
subject = np(noun(node), id(A))
verb_part = vp(verb(is), prep(near), object_part)
object_part = np(noun(node), id(B))
object_part = np(noun(node), id(B), rel_part)
rel_part = relcl(rel(that), verb_part)
从这里,您可以看到递归发生的位置并编写符合上述定义的谓词:
% description = desc(subject, verb_part)
% subject = np(noun(node), id(A))
%
extract(desc(np(noun(node), id(A)), VerbPart)) :-
select_edge(A, VerbPart).
% verb_part = vp(verb(is), prep(near), object_part)
%
select_edge(A, vp(verb(is), prep(near), ObjectPart)) :-
connect_node(A, ObjectPart).
% object_part = np(noun(node), id(B))
%
connect_node(A, np(noun(node), id(B))) :-
assertz(edge(A, B)).
% object_part = np(noun(node), id(B), rel_part)
% rel_part = relcl(rel(that), verb_part)
%
connect_node(A, np(noun(node), id(B), relcl(rel(that), VerbPart))) :-
assertz(edge(A, B)),
select_edge(B, VerbPart).
要执行:
| ?- extract(desc(np(noun(node), id(1)), vp(verb(is), prep(near), np(noun(node), id(2),
relcl(rel(that), vp(verb(is), prep(near), np(noun(node), id(3),
relcl(rel(that), vp(verb(is), prep(near), np(noun(node), id(4))))))))))).
true ? ;
no
结果是肯定的,如果我们列出 edge/2
个事实就可以看出:
| ?- listing(edge).
% file: user_input
edge(1, 2).
edge(2, 3).
edge(3, 4).
yes
您还可以在列表中收集边而不是断言它们,并使查询结果为 [edge(1,2), edge(2,3), edge(3,4)]
:
extract(desc(np(noun(node), id(A)), VerbPart), Edges) :-
select_edge(A, VerbPart, Edges).
select_edge(A, vp(verb(is), prep(near), ObjectPart), Edges) :-
connect_node(A, ObjectPart, Edges).
connect_node(A, np(noun(node), id(B)), [edge(A,B)]).
connect_node(A, np(noun(node), id(B), relcl(rel(that), VerbPart)), [edge(A,B)|Edges]) :-
select_edge(B, VerbPart, Edges).
然后使用 maplist
:
extract(Description, Edges), maplist(assertz, Edges).