为什么prolog无法找到顶点的路径(在图中)?
我想问你一个问题: 我有一个练习说: 设有向图为什么prolog无法找到顶点的路径(在图中)?,prolog,Prolog,我想问你一个问题: 我有一个练习说: 设有向图弧(a,b),弧(b,c),弧(a,d),弧(d,e),弧(d,f),弧(f,a)和弧(f,g)。测试go/2,go1/3谓词。 我需要知道为什么Prolog对以下查询的回答为false: ?-go1(a、b、X) 我有一个下图和下面粘贴的代码 代码如下: arc(a,b).%these are the edges. arc(b,c). arc(a,d). arc(d,e). arc(d,f). arc(f,a). arc(f,g). go(X,
弧(a,b)
,弧(b,c)
,弧(a,d)
,弧(d,e)
,弧(d,f)
,弧(f,a)
和弧(f,g)
。测试go/2
,go1/3
谓词。
我需要知道为什么Prolog对以下查询的回答为false:
?-go1(a、b、X)
我有一个下图和下面粘贴的代码
代码如下:
arc(a,b).%these are the edges.
arc(b,c).
arc(a,d).
arc(d,e).
arc(d,f).
arc(f,a).
arc(f,g).
go(X,X).
go(X,Y):-arc(X,Z),go(Z,Y).
% without arc(f,a):
% yes ?- go(a,c).
% no ?- go(d,c).
% no ?- go(f,a).
% yes ?- go(a,g).
%
% with arc(f,a):
% yes ?- go(a,c).
% out of local stack ?- go(a,g).
member1(H,[H|_]).
member1(H,[_|T]):-member1(H,T).
go1(X,X,_).
go1(X,Y,T):-arc(X,Z),not(member1(Z,[X|T])),go1(Z,Y,[X|T]).
% with arc(f,a):
% yes ?- go1(a,c,[]).
% yes ?- go1(a,g,[]).
伙计们,请帮我弄清楚为什么会这样?为什么Prolog对以下查询的回答为false:
?-go1(a、b、X)
我尝试跟踪查询,得到的答案如下:
[trace] ?- go1(a,b,X).
Call: (8) go1(a, b, _982) ? creep
Call: (9) arc(a, _1202) ? creep
Exit: (9) arc(a, b) ? creep
^ Call: (9) not(member1(b, [a|_982])) ? creep
Call: (10) member1(b, [a|_982]) ? creep
Call: (11) member1(b, _982) ? creep
Exit: (11) member1(b, [b|_1206]) ? creep
Exit: (10) member1(b, [a, b|_1206]) ? creep
^ Fail: (9) not(user:member1(b, [a|_982])) ? creep
Redo: (9) arc(a, _1202) ? creep
Exit: (9) arc(a, d) ? creep
^ Call: (9) not(member1(d, [a|_982])) ? creep
Call: (10) member1(d, [a|_982]) ? creep
Call: (11) member1(d, _982) ? creep
Exit: (11) member1(d, [d|_1206]) ? creep
Exit: (10) member1(d, [a, d|_1206]) ? creep
^ Fail: (9) not(user:member1(d, [a|_982])) ? creep
Fail: (8) go1(a, b, _982) ? creep
false.
好吧,我不明白的是为什么我们有下面的答案:
Exit: (11) member1(b, [b|_1206]) ? creep
Exit: (10) member1(b, [a, b|_1206]) ? creep
^ Fail: (9) not(user:member1(b, [a|_982])) ? creep
为什么序言没有认识到从a到b有一条边?为什么它说b在列表中,毕竟只有[a]。为什么这个电话在那里失败了?查询失败的原因是什么?向其传递一个自由变量
X
,这意味着:
member(b, [a|X]).
事实上,call将会成功:
?- member(b, [a|X]).
X = [b|_2142] ;
X = [_2140, b|_2148] ;
X = [_2140, _2146, b|_2154]
现在not(member(Z,[X | T])
将成功,因为member(Z,[X | T])
的搜索失败,但在这里它将始终成功,因为自由变量总是可以固定到包含Z
的列表,因此它失败
如果您将其命名为:
go1 (a, b, [])
因此,用
go1(A,B,p)
调用它,以获得路径p
,,这意味着我们可以使用空列表,但不能使用变量来实现这一点。我说的对吗?好的。我明白了。非常感谢你,威廉这个图表说明帮助很大,我发现它总是在问题中可悲地缺失。
go1(A, B, P) :-
go1(A, B, P, []).
go1(A, A, [A], _).
go1(A, C, [A|T], V) :-
arc(A, B),
\+ member(B, [A|V]),
go1(B, C, T, [A|V]).