【问题标题】:Prolog - Check number of occurences doesn't work as expectedProlog - 检查出现次数未按预期工作
【发布时间】:2015-11-19 12:49:04
【问题描述】:

在 Prolog 中: 我有以下函数可以计算列表中某个元素的出现次数:

%count(L:list,E:int,N:int) (i,i,o)
count([],_,0).
count([H|T],E,C):-H == E,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).

我测试了它,它运行良好。但是问题来了,我有另一个函数必须检查“1”在列表中出现的次数是否少于 2 次。

check(L):-count(L,1,C),C<2.

例如,每当我尝试检查列表[1,1,1,1] 时,我得到的结果都是“true”,这是错误的,我不知道为什么。我尝试进行一些更改,但该功能不起作用。

【问题讨论】:

标签: list prolog prolog-dif


【解决方案1】:

改善您的测试习惯!

在测试 Prolog 代码时,不要只查看某个查询的第一个答案并得出“它有效”的结论。

非确定性 Prolog 的核心。

很多时候,某些代码似乎乍一看(在查看第一个答案时)可以正常工作,但在回溯时会出现问题(主要是错误的答案和/或未终止)。 p>


回到您最初的问题...如果您想要/需要保留,请考虑使用代码@Ruben presented in his answer 的以下最小变体:

计数([],_,0)。 计数([E|T],E,C):- 计数(T,E,C1), C是C1+1。 计数([H|T],E,C):- dif(H,E), 计数(T,E,C)。

dif/2 以合理的逻辑方式表达句法术语的不等式。有关它的信息,请查看

【讨论】:

    【解决方案2】:

    这是因为count([1,1,1,1],1,1) 也是真的!在你的最后一个count 中,当 H 等于 E 时,它也可以匹配。为了说明这一点,使用; 让 prolog 寻找更多count([1,1,1,1],1,R) 的答案。你会看到会发生什么。

    count([],_,0).
    count([E|T],E,C):-
        count(T,E,C1),
        C is C1+1.
    count([H|T],E,C):-
        H \= E,
        count(T,E,C).
    
    check(L) :- 
        count(L,1,C),
        C < 2.
    


    ?- check([1,1,1,1,1]).
    false
    ?- check([1]).
    true
    

    【讨论】:

    • 注意语义不同,可能无意中,OP的原始测试不能被统一代替
    • 非常感谢,我刚刚发现我忘了在第二个子句中插入“剪切”,但是由于您的回答,我看到了问题所在,并且两个版本都可以正常工作。跨度>
    【解决方案3】:

    第二个和第三个子句头部匹配相同的序列。作为最小的更正,我会提交测试

    count([],_,0).
    count([H|T],E,C):-H == E,!,count(T,E,C1),C is C1+1.
    count([_|T],E,C):-count(T,E,C).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 2018-02-08
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      相关资源
      最近更新 更多