在Prolog中配对2个词典

时间:2013-10-10 12:14:01

标签: prolog

我需要在prolog中实现字典配对。这就是我所做的:

pp((A, B), (B,C), RES) :-
    RES = [(A,C)].

pp((A, AA),[B|BS], RES) :-
    pp((A, AA), B, RES1),
    pp((A, AA), BS, RES2),
    append(RES1, RES2, RES).

pp([A|AS], [B|BS], C) :-
    pp(A, [B|BS], RES1),
    pp(AS, [B|BS], RES2),
    append(RES1, RES2, RES),
    list_to_set(RES, C).
pp(_, _, C) :-
    C = [].

输出:

?- pp([(a,b),(b,c)],[(b,c),(c,z)],C).
C = [ (a, c), (b, z)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (a, c), (b, z)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (a, c)] ;
C = [ (b, z)] ;
C = [] ;
C = [] ;
C = [] ;
C = [] ;
C = [ (b, z)] ;
C = [] ;
C = [] ;
C = [] ;
C = [] ;
C = [ (b, z)] ;
C = [] ;
C = [] ;
C = [] ;
C = [] ;
C = [].

?- 

第一个结果是正确答案。问题是为什么谓词pp允许C成为所有其他值?

1 个答案:

答案 0 :(得分:1)

Prolog将尝试它可以匹配的所有替代品,然后您将这些结果作为算法中意外计算的结果。

你'重载'pp / 3,使用它来匹配两个列表和元素。 这没有多大意义,因为您的数据结构不是递归的。

而不是建议削减(削减提交做出选择,然后可以帮助避免那些令人沮丧的结果),我认为你可以使用一些内置得到相同的结果,比list_to_set / 2更容易应用

pp([],_,[]).
pp([(A,B)|As], X, [(A,C)|R]) :- select((B,C), X, Y), !, pp(As, Y, R).
% BUG ! pp([_|As], X, R) :- select(As, X, R).
pp([_|As], X, R) :- pp(As, X, R).

注意成功选择/ 3后的剪切,避免跟随“跳过规则”。

编辑以从第二个词典中获取更多单词,让我们重试成功的匹配:

pp([(A,B)|As], X, [(A,C)|R]) :- select((B,C), X, Y), !, pp([(A,B)|As], Y, R).