Prolog - 用英语解释跟踪步骤
Prolog - Explain trace steps in English
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
duetwith(Person1,Person2):-
plays(Person1,L),
plays(Person2,L),
Person1 \= Person2.
我编写了一个名为组合的新规则,用于确定三个人是否可以使用鼓手、基础吉他和主音吉他进行组合。
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
德鲁、爱丽丝和迈克可以组合吗?
combo(mike,alice,drew).
是的,所以答案是肯定的,他们可以组合。
我需要帮助来理解程序在序言中回答上述查询所采取的步骤。非常感谢任何有关步骤列表的帮助,这样我可以更深入地了解 Prolog 采取的每个步骤。
这是 Prolog 针对不同示例所采取的步骤列表的示例,只是为了让您了解我在寻找什么。
在 talkswith(bob,allen)
的情况下,引擎采取了以下步骤:
在
与(人 1,人 2)交谈:-
说话(Person1,L),
说话(Person2,L),
Person1 \= Person2.
将每个出现的 Person1
替换为 bob
并将 Person2
替换为 allen
以获得
talkswith(bob,allen) :-
speaks(bob,L),
speaks(allen,L),
bob \= allen.
让我们看看是否可以找到使右侧为真的 L 值。从 speaks(bob,L).
开始 L 可以是什么?这是我们的事实:
- 会说(艾伦,俄语)。
- 会说(鲍勃,英语)。
- 会说(玛丽,俄语)。
- 会说(玛丽,英语)。
事实上1,第一个slot不是bob,所以不行。事实上 2,第一个槽位是 bob,所以让我们尝试 L = english
in speaks(allen,L), bob \= allen.
Now we are asking speaks(allen,english), bob\= allen.
- 返回知识库。
speaks(allen,english)
是否符合事实?不是事实 1,不是事实 2,不是事实 3,不是事实 4。这失败了。
- 现在我们回到第 2 步。事实 2 没有解决,所以让我们试试事实 3。不,那不是鲍勃。事实 4 也不是鲍勃。我们找不到适用的 L 值,因此搜索失败。
replace every occurrence of Person1 with bob
Prolog 使用 syntactic unification which never does replacement. A free variable can only be bound once to a value. If it looks like a variable is being changed more than once, it is not. There can be many stack frames 并且可以为每个堆栈帧创建一组新变量。
Trace is somewhat helpful but I need to translate that into the form of the example above with the steps written out and explained in plain English.
对于这些事实
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
和这个谓词
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
和这个查询
combo(mike,alice,drew).
首先阅读 SWI-Prolog Debugging and Tracing Programs
运行 带跟踪的查询,启用统一端口并关闭。
?- visible(+unify).
true.
?- leash(-all).
true.
?- trace.
true.
[trace] ?- combo(mike,alice,drew).
Call: (8) combo(mike, alice, drew)
Unify: (8) combo(mike, alice, drew)
Call: (9) plays(mike, _7040)
Unify: (9) plays(mike, leadguitar)
Exit: (9) plays(mike, leadguitar)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(mike, _7040)
Unify: (9) plays(mike, drums)
Exit: (9) plays(mike, drums)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=baseguitar
Exit: (9) leadguitar\=baseguitar
Call: (9) drums\=baseguitar
Exit: (9) drums\=baseguitar
Exit: (8) combo(mike, alice, drew)
true.
Call: (8) combo(mike, alice, drew)
Prolog 查找匹配查询的谓词。当 Prolog 查找谓词时,它按谓词名称搜索,在本例中为 combo
,在本例中为元数,在本例中为 3
,并且只找到一个带有一个子句的谓词。 Prolog 还按照谓词在源代码中出现的顺序搜索谓词。它还有更多内容(索引),但解释这个简单的查询不需要那么详细。
Unify: (8) combo(mike, alice, drew)
一旦 Prolog 根据谓词名称和元数找到 clause/fact,它就会检查子句或事实的查询和头部是否可以统一。
mike
与Person1
统一。 Person1
现在绑定到 mike
。
alice
与 Person2
统一。 Person2
现在绑定到 alice
。
drew
与 Person3
统一。 Person3
现在绑定到 drew
。
Call: (9) plays(mike, _7040)
如果前一条语句统一,则调用下一条语句。每个语句本身就是一个查询。因此 运行 查询 plays(mike,X).
作为独立查询与子句中的此语句相同。 plays/2
有很多事实,其中两个匹配 plays(mike,X).
Prolog 使用它找到的第一个,但是因为有多个事实,所以做出了选择点。我们将调用这个特定的选择点plays(mike,X) - cp1
,并在遇到相应的REDO时返回一个特定的选择点。
Unify: (9) plays(mike, leadguitar)
一旦 Prolog 根据谓词名称和元数找到 clause/fact,它就会检查子句的查询和头部是否可以统一。
plays
与 plays
统一
mike
与 mike
统一
_7040
与 leadguitar
统一。 _7040
绑定到 leadguitar
.
Exit: (9) plays(mike, leadguitar)
这只是完成 Prolog 的端口 box model。它显示了 Call: (9) plays(mike, _7040)
的结果。此声明没有统一。
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
alice
的模式相同。爱丽丝只有一个事实,所以没有为她生成选择点。
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
drew
的模式相同。由于 drew 有两个关于 plays(drew,X).
的事实,因此生成了一个选择点。 plays(drew,X) - cp1
Call: (9) leadguitar\=leadguitar
这是第四条语句 X \= Y
,其中 X
绑定到 leadguitar
,Y
绑定到 leadguitar
Fail: (9) leadguitar\=leadguitar
由于 leadguitar
与 leadguitar
没有区别,此查询失败。失败后 Prolog 返回到最后一个选择点(重做)并尝试找到另一个解决方案。
Redo: (9) plays(drew, _7040)
记住最后创建的选择点,plays(drew,X) - cp1
。由于某些事情失败了,因此尝试使用另一种可能的解决方案进行查询。由于 plays(drew,X)
的第一个选择点因 X
为 leadguitar
而失败,因此使用了第二个事实,plays(drew,baseguitar).
Unify: (9) plays(drew, baseguitar)
只是表明正在使用 plays(drew,X)
的第二个事实。
Exit: (9) plays(drew, baseguitar)
显示Redo: (9) plays(drew, _7040)
的结果。
剩下的只是 copy/paste 已经完成的工作,以及更改语句、变量、绑定值等
这个 类似,但有更多细节。
值得注意的是这个问题
I write a new rule called combo that determines whether or not three people can make a combo with a drummer, a base guitar, and a lead guitar.
此查询未回答
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
因为如果加上这些事实
plays(alice, flute).
plays(noah, cello).
plays(mike, trumpet).
这个查询
?- combo(alice,noah,mike).
true ;
true .
说正确,但 alice
、noah
和 mike
没有演奏主音吉他、鼓和底吉他。
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
duetwith(Person1,Person2):-
plays(Person1,L),
plays(Person2,L),
Person1 \= Person2.
我编写了一个名为组合的新规则,用于确定三个人是否可以使用鼓手、基础吉他和主音吉他进行组合。
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
德鲁、爱丽丝和迈克可以组合吗?
combo(mike,alice,drew).
是的,所以答案是肯定的,他们可以组合。
我需要帮助来理解程序在序言中回答上述查询所采取的步骤。非常感谢任何有关步骤列表的帮助,这样我可以更深入地了解 Prolog 采取的每个步骤。
这是 Prolog 针对不同示例所采取的步骤列表的示例,只是为了让您了解我在寻找什么。
在 talkswith(bob,allen)
的情况下,引擎采取了以下步骤:
在
与(人 1,人 2)交谈:- 说话(Person1,L), 说话(Person2,L), Person1 \= Person2.
将每个出现的 Person1
替换为 bob
并将 Person2
替换为 allen
以获得
talkswith(bob,allen) :-
speaks(bob,L),
speaks(allen,L),
bob \= allen.
让我们看看是否可以找到使右侧为真的 L 值。从
speaks(bob,L).
开始 L 可以是什么?这是我们的事实:- 会说(艾伦,俄语)。
- 会说(鲍勃,英语)。
- 会说(玛丽,俄语)。
- 会说(玛丽,英语)。
事实上1,第一个slot不是bob,所以不行。事实上 2,第一个槽位是 bob,所以让我们尝试
L = english
inspeaks(allen,L), bob \= allen.
Now we are askingspeaks(allen,english), bob\= allen.
- 返回知识库。
speaks(allen,english)
是否符合事实?不是事实 1,不是事实 2,不是事实 3,不是事实 4。这失败了。 - 现在我们回到第 2 步。事实 2 没有解决,所以让我们试试事实 3。不,那不是鲍勃。事实 4 也不是鲍勃。我们找不到适用的 L 值,因此搜索失败。
replace every occurrence of Person1 with bob
Prolog 使用 syntactic unification which never does replacement. A free variable can only be bound once to a value. If it looks like a variable is being changed more than once, it is not. There can be many stack frames 并且可以为每个堆栈帧创建一组新变量。
Trace is somewhat helpful but I need to translate that into the form of the example above with the steps written out and explained in plain English.
对于这些事实
plays(alice, leadguitar).
plays(noah, drums).
plays(mike, leadguitar).
plays(mike, drums).
plays(katie, baseguitar).
plays(drew, leadguitar).
plays(drew, baseguitar).
和这个谓词
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
和这个查询
combo(mike,alice,drew).
首先阅读 SWI-Prolog Debugging and Tracing Programs
运行 带跟踪的查询,启用统一端口并关闭。
?- visible(+unify).
true.
?- leash(-all).
true.
?- trace.
true.
[trace] ?- combo(mike,alice,drew).
Call: (8) combo(mike, alice, drew)
Unify: (8) combo(mike, alice, drew)
Call: (9) plays(mike, _7040)
Unify: (9) plays(mike, leadguitar)
Exit: (9) plays(mike, leadguitar)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(mike, _7040)
Unify: (9) plays(mike, drums)
Exit: (9) plays(mike, drums)
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=leadguitar
Fail: (9) leadguitar\=leadguitar
Redo: (9) plays(drew, _7040)
Unify: (9) plays(drew, baseguitar)
Exit: (9) plays(drew, baseguitar)
Call: (9) drums\=leadguitar
Exit: (9) drums\=leadguitar
Call: (9) leadguitar\=baseguitar
Exit: (9) leadguitar\=baseguitar
Call: (9) drums\=baseguitar
Exit: (9) drums\=baseguitar
Exit: (8) combo(mike, alice, drew)
true.
Call: (8) combo(mike, alice, drew)
Prolog 查找匹配查询的谓词。当 Prolog 查找谓词时,它按谓词名称搜索,在本例中为 combo
,在本例中为元数,在本例中为 3
,并且只找到一个带有一个子句的谓词。 Prolog 还按照谓词在源代码中出现的顺序搜索谓词。它还有更多内容(索引),但解释这个简单的查询不需要那么详细。
Unify: (8) combo(mike, alice, drew)
一旦 Prolog 根据谓词名称和元数找到 clause/fact,它就会检查子句或事实的查询和头部是否可以统一。
mike
与Person1
统一。 Person1
现在绑定到 mike
。
alice
与 Person2
统一。 Person2
现在绑定到 alice
。
drew
与 Person3
统一。 Person3
现在绑定到 drew
。
Call: (9) plays(mike, _7040)
如果前一条语句统一,则调用下一条语句。每个语句本身就是一个查询。因此 运行 查询 plays(mike,X).
作为独立查询与子句中的此语句相同。 plays/2
有很多事实,其中两个匹配 plays(mike,X).
Prolog 使用它找到的第一个,但是因为有多个事实,所以做出了选择点。我们将调用这个特定的选择点plays(mike,X) - cp1
,并在遇到相应的REDO时返回一个特定的选择点。
Unify: (9) plays(mike, leadguitar)
一旦 Prolog 根据谓词名称和元数找到 clause/fact,它就会检查子句的查询和头部是否可以统一。
plays
与 plays
统一
mike
与 mike
统一
_7040
与 leadguitar
统一。 _7040
绑定到 leadguitar
.
Exit: (9) plays(mike, leadguitar)
这只是完成 Prolog 的端口 box model。它显示了 Call: (9) plays(mike, _7040)
的结果。此声明没有统一。
Call: (9) plays(alice, _7040)
Unify: (9) plays(alice, leadguitar)
Exit: (9) plays(alice, leadguitar)
alice
的模式相同。爱丽丝只有一个事实,所以没有为她生成选择点。
Call: (9) plays(drew, _7040)
Unify: (9) plays(drew, leadguitar)
Exit: (9) plays(drew, leadguitar)
drew
的模式相同。由于 drew 有两个关于 plays(drew,X).
的事实,因此生成了一个选择点。 plays(drew,X) - cp1
Call: (9) leadguitar\=leadguitar
这是第四条语句 X \= Y
,其中 X
绑定到 leadguitar
,Y
绑定到 leadguitar
Fail: (9) leadguitar\=leadguitar
由于 leadguitar
与 leadguitar
没有区别,此查询失败。失败后 Prolog 返回到最后一个选择点(重做)并尝试找到另一个解决方案。
Redo: (9) plays(drew, _7040)
记住最后创建的选择点,plays(drew,X) - cp1
。由于某些事情失败了,因此尝试使用另一种可能的解决方案进行查询。由于 plays(drew,X)
的第一个选择点因 X
为 leadguitar
而失败,因此使用了第二个事实,plays(drew,baseguitar).
Unify: (9) plays(drew, baseguitar)
只是表明正在使用 plays(drew,X)
的第二个事实。
Exit: (9) plays(drew, baseguitar)
显示Redo: (9) plays(drew, _7040)
的结果。
剩下的只是 copy/paste 已经完成的工作,以及更改语句、变量、绑定值等
这个
值得注意的是这个问题
I write a new rule called combo that determines whether or not three people can make a combo with a drummer, a base guitar, and a lead guitar.
此查询未回答
combo(Person1,Person2,Person3):-
plays(Person1,X),
plays(Person2,Y),
plays(Person3,Z),
X \= Y,
Y \= Z,
X\=Z.
因为如果加上这些事实
plays(alice, flute).
plays(noah, cello).
plays(mike, trumpet).
这个查询
?- combo(alice,noah,mike).
true ;
true .
说正确,但 alice
、noah
和 mike
没有演奏主音吉他、鼓和底吉他。