运行带有跟踪的查询,统一启用端口并关闭.?- 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找到了基于谓词名称和Arity的子句/事实,它将检查查询和该子句或事实的头部是否可以统一. 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发现了基于谓词名称和Arity的子句/事实,它将检查查询和该子句的标题是否可以统一. plays与plays 统一mike与mike 统一_7040与leadguitar结合在一起. _7040绑定到leadguitar.Exit: (9) plays(mike, leadguitar)这只是完成Prolog 盒子模型的端口.显示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) - cp1Call: (9) leadguitar\=leadguitar这是第四条X \= Y语句,其中X绑定到leadguitar并且Y绑定到leadguitarFail: (9) leadguitar\=leadguitar由于leadguitar与leadguitar相同,因此此查询失败.失败后,Prolog会返回到最后一个选择点(Redo),并尝试寻找其他解决方案.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)的结果.其余的只是复制/粘贴已完成的操作,并更改语句,变量,绑定值等.此答案与之相似,但是有更多详细信息.值得注意的是这个问题此查询未回答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不在演奏Leadguitar,鼓和baseguitar.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.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.Can drew, alice, and mike make a combo? combo(mike,alice,drew).true so the answer is yes they can make a combo.I need help understanding the steps the program takes to answer the above query in prolog. Any help with a list of steps is greatly appreciated so I can gain a deeper understanding of each step Prolog takes.Here is an example of a list of steps Prolog takes for a different example just to give an idea of what I am looking for.In the case of talkswith(bob,allen), the engine took the following steps:Intalkswith(Person1,Person2):- speaks(Person1,L), speaks(Person2,L), Person1 \= Person2.replace every occurrence of Person1 with bob and Person2 with allen to get talkswith(bob,allen) :- speaks(bob,L), speaks(allen,L), bob \= allen.Let’s see if we can find a value for L that makes the right side true. Start with speaks(bob,L). What can L be? Here are our facts:speaks(allen, russian).speaks(bob, english).speaks(mary, russian).speaks(mary, english).In fact 1, the first slot isn’t bob, so that won’t work. In fact 2, the first slot is bob, so let’s try L = englishin speaks(allen,L), bob \= allen. Now we are asking speaks(allen,english), bob\= allen.Back to the knowledge base. Does speaks(allen,english) match a fact? Not fact 1, not fact 2, not fact 3, not fact 4. This fails.Now we back up to step 2. Fact 2 didn’t work out, so let’s try fact 3. No, that isn’t bob. Fact 4 isn’t bob either. We can’t find a value for L that works, so the search failed. 解决方案 Prolog uses 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 and for each stack frame a new set of variables can be created.For these facts plays(alice, leadguitar).plays(noah, drums).plays(mike, leadguitar).plays(mike, drums).plays(katie, baseguitar).plays(drew, leadguitar).plays(drew, baseguitar).and this predicate combo(Person1,Person2,Person3):- plays(Person1,X), plays(Person2,Y), plays(Person3,Z), X \= Y, Y \= Z, X\=Z.and this querycombo(mike,alice,drew).First read SWI-Prolog Debugging and Tracing ProgramsRun the query with trace, unify port enabled and leashing off.?- 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 looks for a predicate that matches the query. When Prolog looks for a predicate it searches by predicate name, in this case combo, and arity, in this case 3 and finds only one predicate with one clause. Prolog also searches for predicates in the order they appear in the source code. There is more to it (indexing) but that level of detail is not needed to explain this simple query.Unify: (8) combo(mike, alice, drew)Once Prolog has found a clause/fact based on predicate name and arity it checks that the query and head of the clause or fact can be unified.mike unifies with Person1. Person1 is now bound to mike.alice unifies with Person2. Person2 is now bound to alice.drew unifies with Person3. Person3 is now bound to drew.Call: (9) plays(mike, _7040)If the previous statement unifies, then the next statement is called. Each statement is a query in itself. So running the query plays(mike,X). as a stand alone query is the same as this statement in the clause. There are many facts for plays/2 and two of them match plays(mike,X). Prolog uses the first one it finds, however since there are more than one, a choice point is made. We will call this specific choice point plays(mike,X) - cp1 and refer back a specific choice point when a corresponding REDO is encountered.Unify: (9) plays(mike, leadguitar)Once Prolog has found a clause/fact based on predicate name and arity it checks that the query and head of the clause can be unified.plays unifies with playsmike unifies with mike_7040 unifies with leadguitar. _7040 is bound to leadguitar.Exit: (9) plays(mike, leadguitar)This is just completing the ports of the Prolog box model. It shows the result of Call: (9) plays(mike, _7040). No unification takes place for this statement.Call: (9) plays(alice, _7040)Unify: (9) plays(alice, leadguitar)Exit: (9) plays(alice, leadguitar)Same pattern for alice. Alice has only one fact so not choice points generated for her.Call: (9) plays(drew, _7040)Unify: (9) plays(drew, leadguitar)Exit: (9) plays(drew, leadguitar)Same pattern for drew. Since drew has two facts for plays(drew,X). a choice point is generated. plays(drew,X) - cp1Call: (9) leadguitar\=leadguitarThis is the fourth statement X \= Y with X is bound to leadguitar and Y is bound to leadguitarFail: (9) leadguitar\=leadguitarSince leadguitar is not different from leadguitar this query fails. Upon failure Prolog goes back to the last choice point (Redo) and tries to find another solution.Redo: (9) plays(drew, _7040)Remember the last choice point created, plays(drew,X) - cp1. Since something failed the query is tried with another possible solution. Since the first choice point for plays(drew,X) failed with X being leadguitar, the second fact is used, plays(drew,baseguitar).Unify: (9) plays(drew, baseguitar)Just shows that the second fact for plays(drew,X) is being used.Exit: (9) plays(drew, baseguitar)It shows the result of Redo: (9) plays(drew, _7040).The remainder is just more copy/paste of what has been done already and changing out the statements, variables, bound values, etc.This answer is similar, but has more detail.Of note is this questionis not answered by this querycombo(Person1,Person2,Person3):- plays(Person1,X), plays(Person2,Y), plays(Person3,Z), X \= Y, Y \= Z, X\=Z.because if these facts are addedplays(alice, flute).plays(noah, cello).plays(mike, trumpet).this query ?- combo(alice,noah,mike).true ;true .says true but alice, noah and mike are not playing the leadguitar, drums, and baseguitar. 这篇关于Prolog-用英语解释跟踪步骤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-05 02:02