gpt4 book ai didi

prolog - Prolog 元解释器中的循环

转载 作者:行者123 更新时间:2023-12-02 09:54:56 24 4
gpt4 key购买 nike

我正在 Prolog 中编写一个简单的元解释器,用于自学。基本上我想保留给定解决方案的“概率”。为此,我只需声明我的条款正确的概率。我希望如果这有效,我会以更好的基础来扩展它,但现在我只对解决眼前的问题感兴趣,即我的元解释器循环:

代码:

fuzzy_prove(true, 1.0) :- !.
fuzzy_prove(probability(P), P) :- !.
fuzzy_prove((A,B), Prob) :-
fuzzy_prove(A, P1),
fuzzy_prove(B, P2),
Prob is P1 * P2.
fuzzy_prove(A, P) :-
clause(A, B), fuzzy_prove(B, P).

father(dave, jean).
father(dave, don) :- probability(0.5).
father(don, claudia).
father(don, jimmy) :- probability(0.5).
father(jean, davey).

grandfather(Grandpop, Babs) :-
father(Grandpop, Dad),
father(Dad, Babs).

我的查询起初似乎有效:

?- fuzzy_prove(grandfather(X, Z), Prob).
X = dave,
Z = davey,
Prob = 1.0 ;
X = dave,
Z = claudia,
Prob = 0.5 ;
X = dave,
Z = jimmy,
Prob = 0.25 ;

当我询问下一个解决方案时,我陷入了疯狂的循环。如果我中断它,它看起来像这样:

continue (trace mode)
Call: (3,973,299) fuzzy_prove(call((father(_G3, _G28), father(_G28, _G4))), _G5) ?
^ Call: (3,973,300) clause(call((father(_G3, _G28), father(_G28, _G4))), _G2044) ?
^ Exit: (3,973,300) clause(call((father(_G3, _G28), father(_G28, _G4))), call((father(_G3, _G28), father(_G28, _G4)))) ?
Call: (3,973,300) fuzzy_prove(call((father(_G3, _G28), father(_G28, _G4))), _G5) ?
^ Call: (3,973,301) clause(call((father(_G3, _G28), father(_G28, _G4))), _G2051) ?
^ Exit: (3,973,301) clause(call((father(_G3, _G28), father(_G28, _G4))), call((father(_G3, _G28), father(_G28, _G4)))) ?
Call: (3,973,301) fuzzy_prove(call((father(_G3, _G28), father(_G28, _G4))), _G5) ?
^ Call: (3,973,302) clause(call((father(_G3, _G28), father(_G28, _G4))), _G2058) ?
^ Exit: (3,973,302) clause(call((father(_G3, _G28), father(_G28, _G4))), call((father(_G3, _G28), father(_G28, _G4)))) ?
Call: (3,973,302) fuzzy_prove(call((father(_G3, _G28), father(_G28, _G4))), _G5) ?
^ Call: (3,973,303) clause(call((father(_G3, _G28), father(_G28, _G4))), _G2065) ?
^ Exit: (3,973,303) clause(call((father(_G3, _G28), father(_G28, _G4))), call((father(_G3, _G28), father(_G28, _G4)))) ?
Call: (3,973,303) fuzzy_prove(call((father(_G3, _G28), father(_G28, _G4))), _G5) ?
^ Call: (3,973,304) clause(call((father(_G3, _G28), father(_G28, _G4))), _G2072) ?
^ Exit: (3,973,304) clause(call((father(_G3, _G28), father(_G28, _G4))), call((father(_G3, _G28), father(_G28, _G4)))) ?

我确信我正在做一些明显愚蠢的事情,但我很难看出它是什么。

最佳答案

带有 (,) 仿函数的子句匹配两次:fuzzy_prove 的第三个和第四个子句,当它匹配第四个子句时,它最终将无限循环,因为子句主体本身就是一个 and 并且不能简化。

此查询将演示正在发生的情况:

clause(grandfather(A,B), C0), clause(C0, C1), clause(C1, C2).

在我的解释器上至少 C1 = C2,并且我们有一个无限循环。

在递归之前,您至少需要检查子句主体的仿函数不是 (,)。我怀疑还会有其他像这样的极端情况,因此实际上最好弄清楚如何正确处理调用仿函数。

关于prolog - Prolog 元解释器中的循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34218029/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com