我正在使用SWI Prolog学习Prolog以获得一个普遍的exame,我有一些问题需要理解我的老师在这个例子中所做的事情(在我看来是不完整的)来实现谓词:
k(T1,T2,N)
TRUE 如果 T1和T2是树,如果它们具有共同的N个子树(如果子树在两个树T1和T2之间是共同的,则这个子树存在于T1和T2)
他给了我另一个谓词 T(t),其中t是一个特定的树,而T(t)给我t的所有子树(如果你想看到这个东西的图形解释你可以看到此文件的幻灯片18:http://www.informatica.uniroma2.it/upload/2012/LPDA/08_Lezione_ZNZ.pptx)
所以他说:
k(T1,T2,N)
TRUE ,如果为TRUE,则为
在实践中,如果T1和T2的子树(从T(T1)谓词给出)与T2的所有子句的交集为TRUE,则树T1和T2具有N个公共子树是正确的。来自T(T2)谓词)在模块中恰好是N(即作为数字)
好的,继续:他以下列方式定义树:
tree(F, LIST_OF_SUBTREES).
其中R是当前树的根
因此,如果树T1和T2具有N个公共子树,则使用前一个属性,实现谓词 k(T1,T2,N)为TRUE。
此谓词必须在树T1和T2中使用 EXAUSTIVE SEARCH
然后他以这种方式实现 k / 3 谓词:
k(T1,T2,N) :- t(T1, ST1),
t(T2, ST2),
intersect(ST1,ST2,LST),
lenght(LST,N).
这在我看来非常清楚(如果我错了,请纠正我):
所以谓词 k(T1,T2,N)如果计算出的N值与给定的N值一致,则为真。
直到这里我认为一切都很清楚......现在我有一些问题要理解他如何实现取t树的** t(T,STL)谓词并在STL中列出所有子树的列表
他给我以下代码:
t(T,STL) :- bagof(ST, st(T,ST), STL).
st_r(tree(A,_), tree(A,[]).
st_r(tree(A,R), tree(A,R1) :- st_l(R,R1).
st_l([],[]).
st_l([X|R],[X1|R1]) :- st(X,X1),
st_l(R,R1).
st(T,T1) :- st_r(T,T1).
st(tree(A,R),T1) :- member(T,R),
st(T,T1).
关于谓词:
t(T,STL) :- bagof(ST, st(T,ST), STL).
我认为只需执行谓词中构建的 bagof ,其中 ST 是子树对象,如果满足目标 st (T,ST)被放入 STL 列表(子树列表)
但现在我不明白 st / 2 谓词(我的目标)如何运作!!!有人可以尝试向我解释这个谓词以及相关的 st_l / 2 和 st_r / 2 谓词的逻辑吗?
请问,我也有一些疑问,如何具体建立两棵树,我可以用来测试这个程序。你能给我两块简单的树来测试吗?
最后我认为,在这个例子中,缺少 intersect / 3 谓词
TNX
安德烈
答案 0 :(得分:1)
这里命名它有点神秘,我会试着猜测它。
st/2
应该代表子树,其目的是在回溯时枚举所有子树。st_r/2
应该代表subtree_root。它单独返回 root 和 leafs 。st_l/2
那么应该代表subtree_leafs。它列出了'扁平'树,替换了实际的子树。我不同意st / 2枚举仅子树。实际上,它返回 more 树,因为第一个子句st_r执行了修剪。这对我来说似乎是一个不寻常的定义 - 但是,它是的定义。
谓词intersect / 3在SWI-prolog库(列表)中定义为intersection / 3。
经过两次错字修正后,该代码给了我
?- t(tree(x,[tree(u,[]),tree(v,[tree(p,[]),tree(q,[])])]),L).
L = [tree(x, []), tree(x, [tree(u, []), tree(v, [])]), tree(x, [tree(u, []), tree(v, [tree(p, []), tree(..., ...)])]), tree(x, [tree(u, []), tree(v, [tree(..., ...)|...])]), tree(x, [tree(u, []), tree(v, [...|...])]), tree(x, [tree(u, []), tree(..., ...)]), tree(x, [tree(..., ...)|...]), tree(x, [...|...]), tree(..., ...)|...].