我们是如何得到这个值的? 你好Prolog天才:让我们考虑给定的数据库: q3(t(V, nul, nul), 0). q3(t(V, Q, nul), 1). q3(t(V, nul, Q), 1). q3(t(V, Q1, Q2), T) :- q3(Q1, T1), q3(Q2, T2), T is 1+T1+T2.
和下面的查询我们是如何得到这个值的? 你好Prolog天才:让我们考虑给定的数据库: q3(t(V, nul, nul), 0). q3(t(V, Q, nul), 1). q3(t(V, nul, Q), 1). q3(t(V, Q1, Q2), T) :- q3(Q1, T1), q3(Q2, T2), T is 1+T1+T2.,prolog,Prolog,和下面的查询 ?- q3(t(4, t(2, nul, t(3, t(1,nul,nul), t(9,nul,nul))), t(7, t(5, nul, t(6, nul, nul)), t(9, t(1,nul,nul), t(9,nul,nul)))),T). 为什么答案是5? 提前感谢谓词不只是给出5作为答案。如果您运行它,它会产生几个答案:5、6、6、6、7、7、6、7和7 q3(t(4,t(2,nul,t(3, t(1,nul,nul), t(9,nul,nul))),t(
?- q3(t(4,
t(2,
nul,
t(3, t(1,nul,nul), t(9,nul,nul))),
t(7, t(5, nul, t(6, nul, nul)),
t(9, t(1,nul,nul), t(9,nul,nul)))),T).
为什么答案是5?
提前感谢谓词不只是给出5作为答案。如果您运行它,它会产生几个答案:5、6、6、6、7、7、6、7和7
q3(t(4,t(2,nul,t(3, t(1,nul,nul), t(9,nul,nul))),t(7, t(5, nul, t(6, nul, nul)), t(9, t(1,nul,nul), t(9,nul,nul)))),T).
V = 4
Q1 = t(2,nul,t(3, t(1,nul,nul), t(9,nul,nul)))
V = 2
Q1 = nul
Q2 != nul
=> T1 = 1
Q2 = t(7, t(5, nul, t(6, nul, nul)), t(9, t(1,nul,nul), t(9,nul,nul)))
V = 7
Q1 = t(5, nul, t(6, nul, nul))
V = 5
Q1 = nul
Q2 != nul
=> T1 = 1
Q2 = t(9, t(1,nul,nul), t(9,nul,nul))
V = 9
Q1 = t(1,nul,nul)
=> T1 = 0
Q2 = t(9,nul,nul)
=> T2 = 0
=> T2 = 1 + 0 + 0 = 1
=> T2 = 1 + 1 + 1 = 3
=> T = 1 + 1 + 3 = 5.
结构tV,L,R表示二叉树。重新格式化查询以使其更可见:
q3( t(4,
t(2,
nul,
t(3,
t(1, nul, nul),
t(9, nul, nul)
)
),
t(7,
t(5,
nul,
t(6, nul, nul)
),
t(9,
t(1, nul, nul),
t(9, nul, nul)
)
)
),
T).
或者,将第一个参数放置得更像一棵树,这样我们就可以将其可视化:
_______4_______
/ \
2 ____7____
/ \ / \
n _3_ 5 _9_
/ \ / \ / \
1 9 n 6 1 9
/ \ / \ / \ / \ / \
n n n n n n n n n n
现在让我们考虑Q3定义的规则:
没有子节点的节点计为0。这不算数 至少有一个nul子节点的节点计为1 一个节点有两个子节点,不管它们是什么,都算作1加上为每个子节点给定的数量之和 我们可以从谓词子句的这些定义中看出,任何具有两个nul子级的节点都将满足子句1、2或3。因此,每一个这样的节点都有可能为回溯提供3种解决方案。然而,谓词2和谓词3将删减只有一个nul子节点的节点下面的解决方案。树中只有一个分支没有唯一的空子级,这就是从节点值9开始的分支。每个分支,因为它们有两个nul节点,贡献了3个解决方案。这就是出现的3x3或9个总体解决方案,这就是我们看到的5、6、6、6、7、7、6、7和7 要确定5从何而来,这是第一个解决方案,您只需要查看每个节点的哪个子句首先成功Node@4: matches rule 4: 1 + Node@2 + Node@7
Node@2: matches rule 3: 1
Node@7: matches rule 4: 1 + Node@5 + Node@9
Node@5: matches rule 3: 1
Node@9: matches rule 4: 1 + Node@1 + Node@9
Node@1: matches rule 1: 0
Node@9: matches rule 1: 0
如果我们把这些加起来,我们得到:Node@4总和为1+1+1+1+1+0+0=5,实际上只是把上面的1加起来。其他规则也将匹配的回溯产生其他8个值
看起来q3正在尝试计数节点,但这样做不正确。要正确执行此操作,让我们从定义规则开始:
如果一个节点是nul,它应该计为零
如果节点不为null,则节点计数应为左分支和右分支的节点计数之和,加上当前节点的1
使用这两个条款,我们得到:
| ?- q3(t(4,
t(2,
nul,
t(3, t(1,nul,nul), t(9,nul,nul))),
t(7, t(5, nul, t(6, nul, nul)),
t(9, t(1,nul,nul), t(9,nul,nul)))),T).
T = 11
yes
| ?-
一个解决方案是11,它是节点数。谓词不只是给出5作为答案。如果您运行它,它会产生几个答案:5、6、6、6、7、7、6、7和7 结构tV,L,R表示二叉树。重新格式化查询以使其更可见:
q3( t(4,
t(2,
nul,
t(3,
t(1, nul, nul),
t(9, nul, nul)
)
),
t(7,
t(5,
nul,
t(6, nul, nul)
),
t(9,
t(1, nul, nul),
t(9, nul, nul)
)
)
),
T).
或者,将第一个参数放置得更像一棵树,这样我们就可以将其可视化:
_______4_______
/ \
2 ____7____
/ \ / \
n _3_ 5 _9_
/ \ / \ / \
1 9 n 6 1 9
/ \ / \ / \ / \ / \
n n n n n n n n n n
现在让我们考虑Q3定义的规则:
没有子节点的节点计为0。这不算数 至少有一个nul子节点的节点计为1 一个节点有两个子节点,不管它们是什么,都算作1加上为每个子节点给定的数量之和 我们可以从谓词子句的这些定义中看出,任何具有两个nul子级的节点都将满足子句1、2或3。因此,每一个这样的节点都有可能为回溯提供3种解决方案。然而,谓词2和谓词3将删减只有一个nul子节点的节点下面的解决方案。树中只有一个分支没有唯一的空子级,这就是从节点值9开始的分支。每个分支,因为它们有两个nul节点,贡献了3个解决方案。这就是出现的3x3或9个总体解决方案,这就是我们看到的5、6、6、6、7、7、6、7和7 要确定5从何而来,这是第一个解决方案,您只需要查看每个节点的哪个子句首先成功Node@4: matches rule 4: 1 + Node@2 + Node@7
Node@2: matches rule 3: 1
Node@7: matches rule 4: 1 + Node@5 + Node@9
Node@5: matches rule 3: 1
Node@9: matches rule 4: 1 + Node@1 + Node@9
Node@1: matches rule 1: 0
Node@9: matches rule 1: 0
如果我们把这些加起来,我们得到:Node@4总和为1+1+1+1+1+0+0=5,实际上只是把上面的1加起来。其他规则也将匹配的回溯产生其他8个值
看起来q3正在尝试计数节点,但这样做不正确。要正确执行此操作,让我们从定义规则开始:
如果一个节点是nul,它应该计为零
如果节点不为null,则节点计数应为左分支和右分支的节点计数之和,加上当前节点的1
使用这两个条款,我们得到:
| ?- q3(t(4,
t(2,
nul,
t(3, t(1,nul,nul), t(9,nul,nul))),
t(7, t(5, nul, t(6, nul, nul)),
t(9, t(1,nul,nul), t(9,nul,nul)))),T).
T = 11
yes
| ?-
一个解决方案是11,即节点数。显而易见的答案是执行以下操作:
?- trace(q3/2), trace(is/2).
% q3/2: [call,redo,exit,fail]
% (is)/2: [call,redo,exit,fail]
true.
[debug] ?- q3(t(4, % <- (6)
t(2, % <- (7)
nul, % (7) -> 1
t(3, % .
t(1,nul,nul), % .
t(9,nul,nul))), % .
t(7, % <- (7)
t(5, % <- (8)
nul, % (8) -> 1
t(6, nul, nul)), % .
t(9, % <- (8)
t(1,nul,nul), % (9) -> 0
t(9,nul,nul) % (9) -> 0
) % 1 + 0 + 0 = 1 (8) -> 1
) % 1 + 1 + 1 = 3 (7) -> 3
), % 1 + 1 + 3 = 5 (6) -> 5
T).
T Call: (6) q3(t(4, t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul)))), _G386)
T Call: (7) q3(t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), _G538)
T Exit: (7) q3(t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), 1)
T Call: (7) q3(t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul))), _G538)
T Call: (8) q3(t(5, nul, t(6, nul, nul)), _G538)
T Exit: (8) q3(t(5, nul, t(6, nul, nul)), 1)
T Call: (8) q3(t(9, t(1, nul, nul), t(9, nul, nul)), _G538)
T Call: (9) q3(t(1, nul, nul), _G538)
T Exit: (9) q3(t(1, nul, nul), 0)
T Call: (9) q3(t(9, nul, nul), _G538)
T Exit: (9) q3(t(9, nul, nul), 0)
T Call: (9) _G543 is 1+0+0
T Exit: (9) 1 is 1+0+0
T Exit: (8) q3(t(9, t(1, nul, nul), t(9, nul, nul)), 1)
T Call: (8) _G549 is 1+1+1
T Exit: (8) 3 is 1+1+1
T Exit: (7) q3(t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul))), 3)
T Call: (7) _G386 is 1+1+3
T Exit: (7) 5 is 1+1+3
T Exit: (6) q3(t(4, t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul)))), 5)
T = 5 .
在设置术语格式时,了解第3/2季度将如何处理它并不太困难。谓词足够短,可以用肉眼进行模式匹配。当然,你也可以查看非常详细的跟踪。您将在树上注意到,在第一次搜索解决方案时,一些子树根本没有被探索。显而易见的答案是执行以下操作:
?- trace(q3/2), trace(is/2).
% q3/2: [call,redo,exit,fail]
% (is)/2: [call,redo,exit,fail]
true.
[debug] ?- q3(t(4, % <- (6)
t(2, % <- (7)
nul, % (7) -> 1
t(3, % .
t(1,nul,nul), % .
t(9,nul,nul))), % .
t(7, % <- (7)
t(5, % <- (8)
nul, % (8) -> 1
t(6, nul, nul)), % .
t(9, % <- (8)
t(1,nul,nul), % (9) -> 0
t(9,nul,nul) % (9) -> 0
) % 1 + 0 + 0 = 1 (8) -> 1
) % 1 + 1 + 1 = 3 (7) -> 3
), % 1 + 1 + 3 = 5 (6) -> 5
T).
T Call: (6) q3(t(4, t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul)))), _G386)
T Call: (7) q3(t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), _G538)
T Exit: (7) q3(t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), 1)
T Call: (7) q3(t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul))), _G538)
T Call: (8) q3(t(5, nul, t(6, nul, nul)), _G538)
T Exit: (8) q3(t(5, nul, t(6, nul, nul)), 1)
T Call: (8) q3(t(9, t(1, nul, nul), t(9, nul, nul)), _G538)
T Call: (9) q3(t(1, nul, nul), _G538)
T Exit: (9) q3(t(1, nul, nul), 0)
T Call: (9) q3(t(9, nul, nul), _G538)
T Exit: (9) q3(t(9, nul, nul), 0)
T Call: (9) _G543 is 1+0+0
T Exit: (9) 1 is 1+0+0
T Exit: (8) q3(t(9, t(1, nul, nul), t(9, nul, nul)), 1)
T Call: (8) _G549 is 1+1+1
T Exit: (8) 3 is 1+1+1
T Exit: (7) q3(t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul))), 3)
T Call: (7) _G386 is 1+1+3
T Exit: (7) 5 is 1+1+3
T Exit: (6) q3(t(4, t(2, nul, t(3, t(1, nul, nul), t(9, nul, nul))), t(7, t(5, nul, t(6, nul, nul)), t(9, t(1, nul, nul), t(9, nul, nul)))), 5)
T = 5 .
在设置术语格式时,了解第3/2季度将如何处理它并不太困难。谓词足够短,可以用肉眼进行模式匹配。当然,你也可以查看非常详细的跟踪。你会注意到树上有一些小树
在第一次寻找解决方案的过程中,他们根本不会去探索这些问题。这个程序应该做什么?这只是一个旧期中考试的问题,他们要求给出给定查询的输出,当然!这个程序应该做什么?这只是一个旧期中考试的问题,他们要求给出给定查询的输出,当然!你知道t_u,u,u代表什么结构,以及q3的结果代表什么吗?troot,leftChild,rightChild二叉树!,希望这是你的问题:第三季度给出的答案不仅仅是5。这个特殊的谓词产生了多个解:5,6,6,6,7,7,6,7。正确的,但在这个特定的问题上,一个答案就足够了,我最感兴趣的是用来解决这个问题的算法,clemos给出了精彩的答案!从那里很明显,我们回过头来寻找其他解决方案!你知道t_u,u,u代表什么结构,以及q3的结果代表什么吗?troot,leftChild,rightChild二叉树!,希望这是你的问题:第三季度给出的答案不仅仅是5。这个特殊的谓词产生了多个解:5,6,6,6,7,7,6,7。正确的,但在这个特定的问题上,一个答案就足够了,我最感兴趣的是用来解决这个问题的算法,clemos给出了精彩的答案!从那里很明显,我们回过头来寻找其他解决方案!谢谢你这么深刻的回答!!非常有用!再喝一杯咖啡3个多小时的开场白:@ApexPredator咖啡确实有帮助谢谢你这么深刻的回答!!非常有用!再喝一杯咖啡3个多小时的开场白:@ApexPredator咖啡确实有帮助