我试图编写一组谓词,用递归替换嵌套谓词中的术语;即
假设:
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
答案 0 :(得分:2)
这是一种简化的方法,可能会有一些例外情况供您检查和探索,但它说明了(=..)/2
和maplist/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