Prolog重拨一个电话并且没有明显的原因失败

时间:2016-09-17 18:25:47

标签: prolog logic backtracking unification redo

我对Prolog很新。无论如何,我试图编写一组递归规则,返回给定字符代码列表中每个单词的平均字符数。我的代码如下。

tb1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event ){
                num2= Integer.parseInt(tb1.getText());
                updateSum();
            }
        });

由于我无法分辨的原因,虽然AvgLen获得正确的值,但当我调用medellangd([68,69],AvgLen)时,Prolog会返回false。当我跟踪此呼叫时,虽然最初在AvgLen获得其值之前退出每个呼叫,但Prolog决定重做"(9)更新字(68,1,0,_G2574)"如果我在AvgLen值赋值后输入分号,则失败。为什么会这样?

1 个答案:

答案 0 :(得分:1)

你的谓词工作正常,为了找到一个解决方案prolog尝试一切可能的方式,所以在给出答案AvgLen = 2后,为更多可能的解决方案提供了sercheas。当Prolog试图找到一个解决方案时,它会构建一个证明树,它会保留所有可能的方法来证明目标并逐个尝试,直到找到所有正确的答案,而没有其他方法来证明目标已经离开。这就是调用重做的原因,尝试更多可能的解决方案。如果您希望谓词是确定性的 你可以在下面添加剪切(!):

medellangd(Text,AvgLen) :-
    medellangd(Text,T,1,0,0),
    AvgLen = T,!.

并且当找到第一个正确答案时它们将停止,并且不会进一步搜索。

一个简单的例子是了解prolog的工作原理:

simple_example([]).
simple_example([_]).

如果查询simple_example(L),则上述谓词会成功。其中L为空或有一个元素。 现在,如果您尝试查询simple_example([])。或simple_example([1])。在跟踪中你会看到:

[trace]  ?- simple_example([1]).
   Call: (7) simple_example([1]) ? creep
   Exit: (7) simple_example([1]) ? creep
true.

另一方面,如果您以不同方式编写相同的示例:

  simple_example2(L):- L=[].
  simple_example2(L):- L=[_].

谓词simple_example2显然等同于simple_example但是如果查询simple_example2([])。在跟踪中你会看到,因为我们[]匹配simple_example2中的两个L,它将尝试两者,当然只有第一个是正确的:

[trace]  ?- simple_example2([1]).
   Call: (7) simple_example2([1]) ? Unknown option (h for help)
   Call: (7) simple_example2([1]) ? Unknown option (h for help)
   Call: (7) simple_example2([1]) ? Unknown option (h for help)
   Call: (7) simple_example2([1]) ? creep
   Call: (8) [1]=[] ? creep
   Fail: (8) [1]=[] ? creep
   Redo: (7) simple_example2([1]) ? creep
   Call: (8) [1]=[_G3328] ? creep
   Exit: (8) [1]=[1] ? creep
   Exit: (7) simple_example2([1]) ? creep
true.