Prolog 何时使用跟踪/0中的新变量调用重做端口,何时不调用?

Prolog 何时使用跟踪/0中的新变量调用重做端口,何时不调用?,prolog,choice-point,Prolog,Choice Point,在实现的过程中,我想知道在回溯过程中何时使用新变量调用重做端口,何时使用相同的变量调用重做端口 例如,我有以下知识库: location(desk,office). location(apple,kitchen). location(flashlight,desk). location('washing machine',cellar). location(nani,'washing machine'). location(broccoli,kitchen). location(crackers

在实现的过程中,我想知道在回溯过程中何时使用新变量调用重做端口,何时使用相同的变量调用重做端口

例如,我有以下知识库:

location(desk,office).
location(apple,kitchen).
location(flashlight,desk).
location('washing machine',cellar).
location(nani,'washing machine').
location(broccoli,kitchen).
location(crackers,kitchen).
location(computer,office).

door(office,hall).
door(kitchen,office).
door(hall,'dining room').
door(kitchen,cellar).
door('dining room',kitchen).
跟踪查询时
?-(位置(X,Y),门(厨房,Y))。
我得到:

   Call: (9) location(_7998, _8000) ? creep
   Exit: (9) location(desk, office) ? creep
   Call: (9) door(kitchen, office) ? creep
   Exit: (9) door(kitchen, office) ? creep
X = desk,
Y = office ;
   Redo: (9) door(kitchen, office) ? creep      <==== 1
   Fail: (9) door(kitchen, office) ? creep
   Redo: (9) location(_7998, _8000) ? creep
   Exit: (9) location(apple, kitchen) ? creep
   Call: (9) door(kitchen, kitchen) ? creep
   Fail: (9) door(kitchen, kitchen) ? creep
   Redo: (9) location(_7998, _8000) ? creep
   Exit: (9) location(flashlight, desk) ? creep
   Call: (9) door(kitchen, desk) ? creep
   Fail: (9) door(kitchen, desk) ? creep
   Redo: (9) location(_7998, _8000) ? creep
   Exit: (9) location('washing machine', cellar) ? creep
   Call: (9) door(kitchen, cellar) ? creep
   Exit: (9) door(kitchen, cellar) ? creep
X = 'washing machine',
Y = cellar ;
   Redo: (9) location(_7998, _8000) ? creep    <==== 2
   Exit: (9) location(nani, 'washing machine') ? creep
   Call: (9) door(kitchen, 'washing machine') ? creep
   Fail: (9) door(kitchen, 'washing machine') ? creep
   Redo: (9) location(_7998, _8000) ? creep
   Exit: (9) location(broccoli, kitchen) ? creep
呼叫:(9)位置(_7998,_8000)?爬行
出口:(9)位置(办公桌、办公室)?爬行
电话:(9)门(厨房、办公室)?爬行
出口:(9)门(厨房、办公室)?爬行
X=桌子,
Y=办公室;

重做:(9)门(厨房、办公室)?爬行这只是一条作为答案发布的评论,因为它有一张图片

如果使用图形调试器,则可以在创建选择点时看到

?- gtrace.
true.

[trace] ?- (location(X,Y),door(kitchen,Y)).
在调试器的下图中,我用绿色矩形突出显示了选择点

要退出顶层跟踪模式,请输入
nodebug

[trace] ?- nodebug.
true.

?- 
注意:这是导致使用重做端口的选择点。
注意:调试prolog的另一种方法是使用。同时阅读带有失败片段的问题


这只是一条作为答案发布的评论,因为它有一张图片

如果使用图形调试器,则可以在创建选择点时看到

?- gtrace.
true.

[trace] ?- (location(X,Y),door(kitchen,Y)).
在调试器的下图中,我用绿色矩形突出显示了选择点

要退出顶层跟踪模式,请输入
nodebug

[trace] ?- nodebug.
true.

?- 
注意:这是导致使用重做端口的选择点。
注意:调试prolog的另一种方法是使用。同时阅读带有失败片段的问题


此答案使用SWI Prolog

第一次使用trace时,第一件有帮助的事情是创建所有端口。默认情况下,unify端口不可见,但可以使用使其可见

?- visible(+unify).
现在,由于这是一个运行时间很短的查询,因此不必为每个端口按空格键,我们可以使用

?- leash(-call).
?- leash(-exit).
?- leash(-redo).
?- leash(-fail).
现在,如果打开跟踪并运行查询

?- trace.
[trace] ?- (location(X,Y),door(kitchen,Y)).
除答案外,您无需按空格键

这样做会有回报

   Call: (9) location(_9632, _9634)
   Unify: (9) location(desk, office)
   Exit: (9) location(desk, office)
   Call: (9) door(kitchen, office)
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
X = desk,
Y = office ;
   Redo: (9) door(kitchen, office)
   Fail: (9) door(kitchen, office)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(apple, kitchen)
   Exit: (9) location(apple, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(flashlight, desk)
   Exit: (9) location(flashlight, desk)
   Call: (9) door(kitchen, desk)
   Fail: (9) door(kitchen, desk)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location('washing machine', cellar)
   Exit: (9) location('washing machine', cellar)
   Call: (9) door(kitchen, cellar)
   Unify: (9) door(kitchen, cellar)
   Exit: (9) door(kitchen, cellar)
X = 'washing machine',
Y = cellar ;
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(nani, 'washing machine')
   Exit: (9) location(nani, 'washing machine')
   Call: (9) door(kitchen, 'washing machine')
   Fail: (9) door(kitchen, 'washing machine')
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(broccoli, kitchen)
   Exit: (9) location(broccoli, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(crackers, kitchen)
   Exit: (9) location(crackers, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(computer, office)
   Exit: (9) location(computer, office)
   Call: (9) door(kitchen, office)
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
X = computer,
Y = office ;
   Redo: (9) door(kitchen, office)
   Fail: (9) door(kitchen, office)
false.
现在可以看到Unify端口

由于这是一个如此简短的查询,我将对跟踪的重要行进行注释,从而回答您的问题

   % location fact 1: location(desk, office) -------------------------
   % First predicate of query - location(X,Y)

   % The location facts are matched in the order of the source code
   % Since the code is looking for location(X,Y)
   % it matches location fact 1: location(desk, office)
   % Since there are more location facts like location(X, Y),
   % e.g.
   %   location(apple,kitchen).
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   % a choice point is generated
   % choice point: location 1
   Call: (9) location(_9632, _9634)

   % Unifies with first location fact.
   % X binds with desk
   % Y binds with office
   Unify: (9) location(desk, office)

   Exit: (9) location(desk, office)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with office
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,office)
   % it matches door fact 2: door(kitchen,office)
   % Since there are more door facts like door(kitchen,Y),
   % e.g.
   %    door(kitchen,cellar).
   % a choice point is generated
   % choice point: door 1
   Call: (9) door(kitchen, office)

   % Since there is a door(kitchen, office) fact
   % unify with second predicate
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
   % No more predicates in the query so return result.
X = desk,
Y = office ;

   % Remember choice point: door 1
   % Use the second predicate
   % on the remaining door facts like door(kitchen,Y)
   % e.g.
   %    door(kitchen,cellar).
   Redo: (9) door(kitchen, office)

   % There are no more door facts that unify with door(kitchen, office)
   % so fail.
   Fail: (9) door(kitchen, office)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 2: location(apple, kitchen) -----------------------

   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(apple,kitchen).
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The second fact unifies with the first predicate location(X,Y)
   % X binds with apple
   % Y binds with kitchen
   Unify: (9) location(apple, kitchen)
   Exit: (9) location(apple, kitchen)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with kitchen
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,kitchen)
   % it matches none of the door facts
   % and since it checked all of the door facts
   % no choice point was generated.
   Call: (9) door(kitchen, kitchen)

   % There is no door(kitchen, kitchen) fact so fail.
   Fail: (9) door(kitchen, kitchen)

   % location fact 3: location(flashlight, desk) ---------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(flashlight, desk)
   Exit: (9) location(flashlight, desk)
   Call: (9) door(kitchen, desk)
   Fail: (9) door(kitchen, desk)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 4: location('washing machine', cellar)  -----------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The forth fact unifies with the first predicate location(X,Y)
   % X binds with 'washing machine'
   % Y binds with cellar
   Unify: (9) location('washing machine', cellar)

   Exit: (9) location('washing machine', cellar)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with cellar
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,cellar)
   % it matches door fact 4: door(kitchen,cellar)
   % Since there are NO more door facts like door(kitchen,Y),
   % NO choice point is generated
   Call: (9) door(kitchen, cellar)

   % There is a door(kitchen, cellar) fact so unify.
   Unify: (9) door(kitchen, cellar)
   Exit: (9) door(kitchen, cellar)
   % No more predicates in the query so return result.
X = 'washing machine',
Y = cellar ;

   % location fact 5: location(nani, 'washing machine') --------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(nani, 'washing machine')
   Exit: (9) location(nani, 'washing machine')
   Call: (9) door(kitchen, 'washing machine')
   Fail: (9) door(kitchen, 'washing machine')

   % location fact 6: location(broccoli, kitchen) --------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(broccoli, kitchen)
   Exit: (9) location(broccoli, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)

   % location fact 7: location(crackers, kitchen) --------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(crackers, kitchen)
   Exit: (9) location(crackers, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 8: location(computer, office) ---------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The last fact unifies with the first predicate location(X,Y)
   % X binds with computer
   % Y binds with office
   Unify: (9) location(computer, office)
   Exit: (9) location(computer, office)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with office
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,office)
   % it matches door fact 2: door(kitchen,office)
   % Since there are more door facts like door(kitchen,Y),
   % e.g.
   %    door(kitchen,cellar).
   % a choice point is generated
   % choice point: door 2
   Call: (9) door(kitchen, office)

   % Since there is a door(kitchen, office) fact
   % unify with second predicate
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
   % No more predicates in the query so return result.
X = computer,
Y = office ;
   % Remember choice point: door 2
   % Use the second predicate
   % on the remaining door facts like door(kitchen,Y)
   % e.g.
   %    door(kitchen,cellar).
   Redo: (9) door(kitchen, office)

   % There are no more door facts that unify with door(kitchen, office)
   % so fail.
   Fail: (9) door(kitchen, office)

   % There are no more location facts so end the query.
false.
补充 当我创建答案时,它是在一个文本编辑器中,可以为Prolog代码做语法高亮显示,为了帮助我保持正确,我打开了三个窗格进行比较。一个窗格有位置和门规则。一个窗格有注释,第三个窗格有类似的注释。当我向下移动代码时,我不断更新第三个窗格中的注释,以匹配第二个窗格中的类似注释,同时检查第一个窗格中的事实。我注意到这一点,因为这可能是一个更好的方式来理解的意见,而不是阅读他们从这个答案张贴

编辑器已启用,并且已安装用于突出显示序言的编辑器


此答案使用SWI Prolog

第一次使用trace时,第一件有帮助的事情是创建所有端口。默认情况下,unify端口不可见,但可以使用使其可见

?- visible(+unify).
现在,由于这是一个运行时间很短的查询,因此不必为每个端口按空格键,我们可以使用

?- leash(-call).
?- leash(-exit).
?- leash(-redo).
?- leash(-fail).
现在,如果打开跟踪并运行查询

?- trace.
[trace] ?- (location(X,Y),door(kitchen,Y)).
除答案外,您无需按空格键

这样做会有回报

   Call: (9) location(_9632, _9634)
   Unify: (9) location(desk, office)
   Exit: (9) location(desk, office)
   Call: (9) door(kitchen, office)
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
X = desk,
Y = office ;
   Redo: (9) door(kitchen, office)
   Fail: (9) door(kitchen, office)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(apple, kitchen)
   Exit: (9) location(apple, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(flashlight, desk)
   Exit: (9) location(flashlight, desk)
   Call: (9) door(kitchen, desk)
   Fail: (9) door(kitchen, desk)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location('washing machine', cellar)
   Exit: (9) location('washing machine', cellar)
   Call: (9) door(kitchen, cellar)
   Unify: (9) door(kitchen, cellar)
   Exit: (9) door(kitchen, cellar)
X = 'washing machine',
Y = cellar ;
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(nani, 'washing machine')
   Exit: (9) location(nani, 'washing machine')
   Call: (9) door(kitchen, 'washing machine')
   Fail: (9) door(kitchen, 'washing machine')
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(broccoli, kitchen)
   Exit: (9) location(broccoli, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(crackers, kitchen)
   Exit: (9) location(crackers, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(computer, office)
   Exit: (9) location(computer, office)
   Call: (9) door(kitchen, office)
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
X = computer,
Y = office ;
   Redo: (9) door(kitchen, office)
   Fail: (9) door(kitchen, office)
false.
现在可以看到Unify端口

由于这是一个如此简短的查询,我将对跟踪的重要行进行注释,从而回答您的问题

   % location fact 1: location(desk, office) -------------------------
   % First predicate of query - location(X,Y)

   % The location facts are matched in the order of the source code
   % Since the code is looking for location(X,Y)
   % it matches location fact 1: location(desk, office)
   % Since there are more location facts like location(X, Y),
   % e.g.
   %   location(apple,kitchen).
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   % a choice point is generated
   % choice point: location 1
   Call: (9) location(_9632, _9634)

   % Unifies with first location fact.
   % X binds with desk
   % Y binds with office
   Unify: (9) location(desk, office)

   Exit: (9) location(desk, office)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with office
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,office)
   % it matches door fact 2: door(kitchen,office)
   % Since there are more door facts like door(kitchen,Y),
   % e.g.
   %    door(kitchen,cellar).
   % a choice point is generated
   % choice point: door 1
   Call: (9) door(kitchen, office)

   % Since there is a door(kitchen, office) fact
   % unify with second predicate
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
   % No more predicates in the query so return result.
X = desk,
Y = office ;

   % Remember choice point: door 1
   % Use the second predicate
   % on the remaining door facts like door(kitchen,Y)
   % e.g.
   %    door(kitchen,cellar).
   Redo: (9) door(kitchen, office)

   % There are no more door facts that unify with door(kitchen, office)
   % so fail.
   Fail: (9) door(kitchen, office)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 2: location(apple, kitchen) -----------------------

   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(apple,kitchen).
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The second fact unifies with the first predicate location(X,Y)
   % X binds with apple
   % Y binds with kitchen
   Unify: (9) location(apple, kitchen)
   Exit: (9) location(apple, kitchen)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with kitchen
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,kitchen)
   % it matches none of the door facts
   % and since it checked all of the door facts
   % no choice point was generated.
   Call: (9) door(kitchen, kitchen)

   % There is no door(kitchen, kitchen) fact so fail.
   Fail: (9) door(kitchen, kitchen)

   % location fact 3: location(flashlight, desk) ---------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(flashlight,desk).
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(flashlight, desk)
   Exit: (9) location(flashlight, desk)
   Call: (9) door(kitchen, desk)
   Fail: (9) door(kitchen, desk)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 4: location('washing machine', cellar)  -----------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location('washing machine',cellar).
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The forth fact unifies with the first predicate location(X,Y)
   % X binds with 'washing machine'
   % Y binds with cellar
   Unify: (9) location('washing machine', cellar)

   Exit: (9) location('washing machine', cellar)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with cellar
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,cellar)
   % it matches door fact 4: door(kitchen,cellar)
   % Since there are NO more door facts like door(kitchen,Y),
   % NO choice point is generated
   Call: (9) door(kitchen, cellar)

   % There is a door(kitchen, cellar) fact so unify.
   Unify: (9) door(kitchen, cellar)
   Exit: (9) door(kitchen, cellar)
   % No more predicates in the query so return result.
X = 'washing machine',
Y = cellar ;

   % location fact 5: location(nani, 'washing machine') --------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(nani,'washing machine').
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(nani, 'washing machine')
   Exit: (9) location(nani, 'washing machine')
   Call: (9) door(kitchen, 'washing machine')
   Fail: (9) door(kitchen, 'washing machine')

   % location fact 6: location(broccoli, kitchen) --------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(broccoli,kitchen).
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(broccoli, kitchen)
   Exit: (9) location(broccoli, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)

   % location fact 7: location(crackers, kitchen) --------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(crackers,kitchen).
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)
   Unify: (9) location(crackers, kitchen)
   Exit: (9) location(crackers, kitchen)
   Call: (9) door(kitchen, kitchen)
   Fail: (9) door(kitchen, kitchen)

   % Since the second predicate failed,
   % go back to the first predicate location(X,Y)
   % location fact 8: location(computer, office) ---------------------
   % Remember choice point: location 1
   % Use the first predicate
   % on the remaining location facts like location(X,Y)
   % e.g.
   %   location(computer,office).
   Redo: (9) location(_9632, _9634)

   % The last fact unifies with the first predicate location(X,Y)
   % X binds with computer
   % Y binds with office
   Unify: (9) location(computer, office)
   Exit: (9) location(computer, office)

   % Second predicate of query - door(kitchen,Y)).
   % Y is bound with office
   % The door facts are matched in the order of the source code
   % Since the code is only looking for door(kitchen,office)
   % it matches door fact 2: door(kitchen,office)
   % Since there are more door facts like door(kitchen,Y),
   % e.g.
   %    door(kitchen,cellar).
   % a choice point is generated
   % choice point: door 2
   Call: (9) door(kitchen, office)

   % Since there is a door(kitchen, office) fact
   % unify with second predicate
   Unify: (9) door(kitchen, office)
   Exit: (9) door(kitchen, office)
   % No more predicates in the query so return result.
X = computer,
Y = office ;
   % Remember choice point: door 2
   % Use the second predicate
   % on the remaining door facts like door(kitchen,Y)
   % e.g.
   %    door(kitchen,cellar).
   Redo: (9) door(kitchen, office)

   % There are no more door facts that unify with door(kitchen, office)
   % so fail.
   Fail: (9) door(kitchen, office)

   % There are no more location facts so end the query.
false.
补充 当我创建答案时,它是在一个文本编辑器中,可以为Prolog代码做语法高亮显示,为了帮助我保持正确,我打开了三个窗格进行比较。一个窗格有位置和门规则。一个窗格有注释,第三个窗格有类似的注释。当我向下移动代码时,我不断更新第三个窗格中的注释,以匹配第二个窗格中的类似注释,同时检查第一个窗格中的事实。我注意到这一点,因为这可能是一个更好的方式来理解的意见,而不是阅读他们从这个答案张贴

编辑器已启用,并且已安装用于突出显示序言的编辑器


谢谢你的帮助。出于某种原因,我完全忽略了编辑你的问题标题的可能性。在你看来,现在是把这个问题作为对上述问题的评论,还是应该单独提出一个问题?对于初学者来说,要洞察问题之间的密切关系有点困难。作为初学者,如果你不确定,可以问一个新问题。如果有人觉得它是复制品,他们会让你知道,并应将其标记为复制品。IIRC如果有三个人将它作为同一个副本投票,它将被标记为一个,或者如果某人有足够的代表,他们可以自己做。有趣的是:我创建了标签
选择点
,并在那里添加了一些可能有助于解释选择点的参考。感谢您的帮助。出于某种原因,我完全忽略了编辑你的问题标题的可能性。在你看来,现在是把这个问题作为对上述问题的评论,还是应该单独提出一个问题?对于初学者来说,要洞察问题之间的密切关系有点困难。作为初学者,如果你不确定,可以问一个新问题。如果有人觉得它是复制品,他们会让你知道,并应将其标记为复制品。IIRC如果有三个人将它作为同一个副本投票,它将被标记为一个,或者如果某人有足够的代表,他们可以自己做。有趣的是:我创建了标签
选择点
,并在那里添加了一些可能有助于解释选择点的参考。谢谢你的详细回答。我现在还记得