【问题标题】:Prolog - Explain trace steps in EnglishProlog - 用英语解释跟踪步骤
【发布时间】:2019-04-27 11:17:51
【问题描述】:
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 的新规则,用于确定三个人是否可以与鼓手、基础吉他和主音吉他进行组合。

combo(Person1,Person2,Person3):- 
    plays(Person1,X), 
    plays(Person2,Y), 
    plays(Person3,Z), 
    X \= Y, 
    Y \= Z, 
    X\=Z.

draw、alice 和 mike 可以组合吗?

combo(mike,alice,drew).

是的,所以答案是肯定的,他们可以组合。

我需要帮助来理解程序在序言中回答上述查询所采取的步骤。非常感谢任何有关步骤列表的帮助,以便我可以更深入地了解 Prolog 所采取的每个步骤。

这是 Prolog 为不同示例所采取的步骤列表示例,只是为了说明我在寻找什么。

对于talkswith(bob,allen),引擎采取了以下步骤:

  1. 与(Person1,Person2) 交谈:- 说话(Person1,L), 说话(Person2,L), 人 1 \= 人 2。

将每次出现的Person1 替换为bob,将Person2 替换为allen 以获得

talkswith(bob,allen) :- 
    speaks(bob,L),
    speaks(allen,L),
    bob \= allen.
  1. 让我们看看我们能否找到一个使右侧为真的 L 值。从speaks(bob,L). 开始 L 可以是什么?以下是我们的事实:

    1. 会说话(艾伦,俄语)。
    2. 会说(鲍勃,英语)。
    3. 会说话(玛丽,俄语)。
    4. 会说(玛丽,英语)。
  2. 事实上 1,第一个插槽不是 bob,所以这行不通。其实2,第一个槽是bob,所以我们试试L = englishinspeaks(allen,L), bob \= allen.现在我们在问speaks(allen,english), bob\= allen.

  3. 返回知识库。 speaks(allen,english) 是否符合事实?不是事实 1,不是事实 2,不是事实 3,不是事实 4。这失败了。
  4. 现在我们回到第 2 步。事实 2 没有成功,所以让我们试试事实 3。不,这不是 bob。事实 4 也不是鲍勃。我们找不到有效的 L 值,因此搜索失败。

【问题讨论】:

  • 您可以使用trace.,然后Prolog将打印它为获得结果所做的所有步骤。
  • 是的,跟踪有点帮助,但我需要将其翻译成上面示例的形式,并用简单的英语写出并解释。
  • 是的,跟踪有点帮助,但我需要将其翻译成上面示例的形式,并用简单的英语写出和解释的步骤。您在理解跟踪方面有困难吗?什么方面?

标签: prolog trace unification


【解决方案1】:

将所有出现的 Person1 替换为 bob

Prolog 使用syntactic unification,它从不替换。 free variable 只能绑定一次到一个值。如果看起来一个变量被多次更改,则不是。可以有很多stack frames,并且可以为每个堆栈帧创建一组新的变量。


Trace 有点帮助,但我需要将其翻译成上面示例的形式,并用简单的英语写出和解释步骤。

对于这些事实

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-PrologDebugging 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)和 arity(在本例中为 3)搜索,并且只找到一个带有一个子句的谓词。 Prolog 还按照它们在源代码中出现的顺序搜索谓词。它还有更多内容(索引),但解释这个简单的查询不需要这种详细程度。


Unify: (8) combo(mike, alice, drew)

一旦 Prolog 根据谓词名称和数量找到了一个子句/事实,它会检查查询和子句或事实的头部是否可以统一。

mikePerson1 统一。 Person1 现在绑定到 mike
alicePerson2 统一。 Person2 现在绑定到 alice
drewPerson3 统一。 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 根据谓词名称和数量找到了一个子句/事实,它会检查查询和子句的头部是否可以统一。

playsplays 合并
mikemike 合并
_7040leadguitar 合并。 _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 的模式相同。由于draw 有两个plays(drew,X). 的事实,因此生成了一个选择点。 plays(drew,X) - cp1


Call: (9) leadguitar\=leadguitar

这是第四条语句X \= YX 绑定到leadguitarY 绑定到leadguitar


Fail: (9) leadguitar\=leadguitar

由于leadguitarleadguitar 没有区别,因此此查询失败。失败时,Prolog 会返回上一个选择点(重做)并尝试寻找另一个解决方案。


Redo: (9) plays(drew, _7040)

记住最后创建的选择点plays(drew,X) - cp1。由于某些事情失败了,因此使用另一种可能的解决方案尝试查询。由于plays(drew,X) 的第一个选择点失败,Xleadguitar,因此使用第二个事实,plays(drew,baseguitar).


Unify: (9) plays(drew, baseguitar)

只是表明plays(drew,X) 的第二个事实正在被使用。


Exit: (9) plays(drew, baseguitar)

它显示了Redo: (9) plays(drew, _7040) 的结果。


剩下的只是对已经完成的内容进行更多的复制/粘贴,并更改语句、变量、绑定值等。


这个answer 类似,但有更多细节。


值得注意的是这个问题

我编写了一个名为 combo 的新规则,用于确定三个人是否可以与鼓手、基础吉他和主音吉他进行组合。

此查询未回答

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 .

说的是真的,但 alicenoahmike 没有演奏主吉他、鼓和贝斯吉他。

【讨论】:

  • 我应该用更清晰的方式措辞。三个人可以组成一个组合,只要他们各自演奏不同的乐器。
  • 请记住,如果您阅读了此答案并学到了一些东西,那么您应该对其进行投票。
  • 我不确定你是不是在针对我自己发表评论,但我赞成所有的 cmets 和答案
  • 不,评论不是针对你的。如果是的话,我会用你的 id @Royale_w_cheese 标记它。许多人阅读了这些问题并从中学习,甚至没有花时间对它们进行投票。如果他们懒得投票,我们为什么还要费心回答问题。
  • 在你用i should have worded it in a clearer manner. 澄清之前,它是不正确的,但从那以后就没有了。可以按照您将其编写为can make a combo with a drummer, a base guitar, and a lead guitar 的方式进行制作。这将是另一个不错的新发布问题。
猜你喜欢
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
相关资源
最近更新 更多