在prolog中管理多个匹配

时间:2015-01-19 20:07:54

标签: prolog

假设您输入了图表的描述,例如“A就在B附近”,您想要更新您的知识库。

使用Prolog我决定使用这个解决方案:

:- dynamic edge/2.

store(Desc):- Desc=[A,is,near,B],
          assert(edge(A,B)),
          write(A-B).


store(Desc):- Desc=[A,is,near,B,that,is,near,C],
          write(A-B),nl,
          write(B-C),
          assert(edge(A,B)),
          assert(edge(B,C)).

我想将解析扩展到潜在的无限句,例如: '1接近2,接近3接近4等', 所以我想做的就是(用伪代码符号表达的想法):

  procedure store(Sentence)
  begin
  foreach 'X is near Y' in Sentence  assert edge(X,Y).
  foreach 'X that is near Y' in Sentence assert edge(X,Y).
  end

我如何在Prolog中实现这一目标?

2 个答案:

答案 0 :(得分:1)

首先,您可以在一个步骤中进行模式匹配和统一。其次,您需要使谓词递归。 消费该句子中的第一个单词(即列表的第一个元素)并让递归目标处理其余的:

store([A, is, near, B]):-
    assert_edge(A, B).
store([A, is, near, B, that|Other]):-
    assert_edge(A, B),
    store([B|Other]).

assert_edge(A, B):-
    ...

另一种方法是对setof/3等列表使用append/3和内置谓词:

?- L = [a, that, is, near, b, that, is, near, c, that, is, near, d],
   setof(A-B, L1^L2^append(L1,[A, that, is, near, B|L2], L), Edges).

L = [a, that, is, near, b, that, is, near, c|...],
Edges = [a-b, b-c, c-d].

答案 1 :(得分:1)

DCG方法在这里可以很好地运作:

store --> [A], is_near(B), { assertz(edge(A, B)) }, and_near(B).

and_near(_) --> [].
and_near(A) --> [that], is_near(B), { assertz(edge(A, B)) }, and_near(B).

is_near(A) --> [is, near, A].

store(L) :- phrase(store, L).

然后您使用查询:

| ?- store([a, is, near, b, that, is, near, c, that, is, near, d]).

true ? ;

no
| ?- listing(edge).

% file: user_input

edge(a, b).
edge(b, c).
edge(c, d).

yes
| ?-

您还可以使用DCG提取到列表:

extract([edge(A,B)|Edges]) --> [A], is_near(B), and_near(B, Edges).

and_near(_, []) --> [].
and_near(A, [edge(A,B)|Edges]) --> [that], is_near(B), and_near(B, Edges).

is_near(A) --> [is, near, A].

extract(L, Edges) :-
    phrase(extract(Edges), L).

| ?- extract([a,is,near,b,that,is,near,c,that,is,near,d], Edges).

Edges = [edge(a,b),edge(b,c),edge(c,d)] ? a

no
| ?-