使用递归在嵌套谓词中执行替换

时间:2018-02-13 10:27:35

标签: recursion prolog

我试图编写一组谓词,用递归替换嵌套谓词中的术语;即

假设:

r(a, aa).
r(c, cc).
r(e, ee).
p(a, b, c).
p(a, b, p(d, e, f)).
p(a, p(p(b, c, d), e, f), g).

我想:

p(aa, b, cc)
p(aa, b, p(d, ee, f))
p(aa, p(p(b, cc, d), ee, f), g)

这是一个(可能非常不正确)的尝试:

inf(p(A, B, C), p(AA, BB, CC)):-
    p(A, B, C),
    (   r(A, AA);
        r(B, BB);
        r(C, CC)
    ).
inf(p(A, B, C), p(AA, BB, CC)):-
    p(A, B, C),
    (   r(A, AA);
        r(B, BB);
        r(C, CC)
    ),
    (   inf(A, AA);
        inf(B, BB);
        inf(C, CC)
    ).

通过调用inf(X, Y).,可以获得:

X = p(a, b, c),
Y = p(aa, _1262, _1264)
X = p(a, b, c),
Y = p(_1064, _1066, cc)
X = p(a, b, p(d, e, f)),
Y = p(aa, _1074, _1076)
X = p(a, p(p(b, c, d), e, f), g),
Y = p(aa, _1082, _1084)
false

这不是我想要的。我怀疑我的基础案例如何与代码进行替换相结合有问题。

非常感谢任何帮助!

感谢/ JC

1 个答案:

答案 0 :(得分:2)

这是一种简化的方法,可能会有一些例外情况供您检查和探索,但它说明了(=..)/2maplist/3的方便使用。 (=..)/2提供术语与列表之间的等效性(例如p(a, b, p(d, e, f)) =.. L结果为L = [p, a, b, p(d, e, f)]Term =.. [foo, x, y]结果为Term = foo(x, y)) 。通过获取与术语等效的列表,您可以使用递归列表处理来处理任意复合术语。

maplist(foo, List1, List2)foo(X1, X2)的{​​{1}}和X1的每个对应元素List1执行查询X2,并且如果每个查询成功,则成功为Prolog通常对查询执行的每次成功提供参数实例化。

只要List2对列表的每个元素都成功,您就可以使用maplist(r, TermList, SubList)使用映射r执行简单替换。但是,在这种情况下,如果没有映射,您需要再次使用相同术语成功的映射。为此,您可以将r定义如下。

map_r