所以我试图绘制2个Prolog问题的树的决定,一个使用累加器而另一个不使用累加器。以下是我的问题和我所做的解决方案:
div.style.cssText = "color:green";
第二个有累加器:
length([H|T],N) :- length(T,N1), N is N1+1.
length([ ],0).
Goal: ?: length([1,2,3],N)
决策树是否正确绘制?或者我犯了错误?什么是绘制这种递归决策树的正确方法?
感谢。
答案 0 :(得分:2)
您所指的树通常称为搜索树又称SLD树,不要与证明树混淆。
您概述的两个问题都是最简单的搜索树案例:
这三个特征意味着SLD树中只有一个分支。
您将获得以下搜索树:
请注意,要使其成为正确的搜索树,每个步骤中最多只能解析一个目标,这会使搜索树变得非常大...因此它会在很常见的是人们制作简化的树木,每个步骤都可以解决多个目标,这可能不是真正的搜索树,而是以更加简洁的方式说明搜索。
树中的边缘标有替换,这些替换作为统一算法的一部分应用于变量。
搜索树与跟踪密切对应,您通常可以从程序的跟踪到搜索树进行直接翻译。
我建议你研究具有多个答案和可能失败的分支的查询的搜索树,从而为更多有趣的树提供多个分支。来自Sterling的Prolog Art of Shapiro的一个例子:
<强>程序:强>
father(abraham, isaac). male(isaac)
father(haran, lot). male(lot).
father(haran, milcah). female(milcah).
father(haran, yiscah). female(yiscah).
son(X,Y):- father(Y,X), male(X).
daughter(X,Y):- father(Y,X), female(X).
查询:
?: son(S, haran)
搜索树强>
答案 1 :(得分:1)
了解事物的一种好方法是自己重新实现它。
当已经有Prolog来实现时,实现Prolog尤其好。 :)
program( patriarchs, P ) :-
P = [ % [son(S, haran)] , % Resolvent
[father(abraham, isaac)] % Clauses...
, [father(haran, lot)] % [Head, Body...]
, [father(haran, milcah)]
, [father(haran, yiscah)]
, [male(isaac)]
, [male(lot)]
, [female(milcah)]
, [female(yiscah)]
, [son(X,Y), father(Y,X), male(X)]
, [daughter(X,Y), father(Y,X), female(X)]
].
solve( Program ):-
Program = [[] | _]. % empty resolvent -- success
solve( [[Goal | Res] | Clauses] ) :-
member( Rule, Clauses),
copy_term( Rule, [Head | Body]), % rename vars
Goal = Head, % unify head
append( Body, Res, Res2 ), % replace goal
solve( [Res2 | Clauses] ).
query( What, Query ):- % Query is a list of Goals to Solve
program( What, Program),
solve( [ Query | Program ] ).
测试
23 ?- query( patriarchs, [son(S, haran)] ).
S = lot ;
false.
现在可以扩展上述solve/1
来记录Goal
成功实例化的记录,从而使统一Goal = Head
成为可能。