Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么prolog无法找到顶点的路径(在图中)?_Prolog - Fatal编程技术网

为什么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]).