【问题标题】:"not" operator or negation in PrologProlog中的“非”运算符或否定
【发布时间】:2013-03-05 20:37:49
【问题描述】:

背景

我需要编写一个关系 power(P) 来查看一个列表并确定 P 中除一个元素之外的所有元素是否为零。

这是我所拥有的:

%I have a relation called zero(P) which decides if every element is zero.

power([H|T]) :- H is not zero,  %The current element is non zero, the tail is all zero.
                zero(T).         
power([0|T]) :- power(T).       %The current element is zero, 
                                %but the tail has a non zero element in it.

一些资源建议使用剪切运算符 (!),它控制回溯,我认为这不是我想要的。

我还遇到了不可证明运算符 (\+),它似乎交换了结果(不可证明返回是),我认为这也不是我想要的。

我确实找到了Prolog Dictionary,但我不知道“not”是什么意思或如何使用它(您可以想象,Ctrl+F 会找到许多“not”的实例)。

问题

如何在序言中说“H 不为零”?

EDIT列表是整数列表。

【问题讨论】:

    标签: prolog negation


    【解决方案1】:

    假设你的论点是一个数字列表,你可以简单地使用arithmetic operators

    power([H|T]):- H =\= 0, zero(T).
    power([H|T]):- H =:= 0, power(T).
    

    一般来说,你也可以写\+ (H=0)。也就是说H不能和0统一。

    问题是,如果使用不是数字列表的列表调用此谓词,您希望发生什么。上面的代码会导致错误。如果你希望它在这种情况下失败,那么它可以定义为

    power([H|T]):- \+(H=0), zero(T).
    power([H|T]):- H=0, power(T).
    

    【讨论】:

    • 这正是我想要的。超级简单。谢谢。
    【解决方案2】:

    使用“不可证明”运算符的可行解决方案:

      zero([]).
      zero([0|T]) :- zero(T).
    
      power([H|T]) :- \+ zero(H), zero(T).         
      power([0|T]) :- power(T).
    

    【讨论】:

    • 这里有一个错误:zero(H) 是用数字调用的,但需要一个列表。 :)
    • 您是否建议改为power([H|T]):- \+ zero([H]), zero(T).?似乎零关系也接受一个数字来代替列表,而且效果很好。
    • 没关系,zero(T) 总是取一个列表的尾部,它总是一个列表(即使它是空列表)。我的错。
    【解决方案3】:

    zero/1 似乎是一个相当专业的谓词。如果您想了解更多惯用(高级?)Prolog,请考虑基于库的“单行”定义(apply):

    power(L) :- include(=\=(0), L, [_]).
    

    测试:

    ?- power([0,99,0,0]).
    true.
    
    ?- power([0,99,0,1]).
    false.
    

    当然,我无法想象你为什么将这样的谓词命名为“权力”……

    【讨论】:

    • Prolog 对我来说是一个大问题:可用的教学材料(在线)通常使用非惯用的解决方案。人们可以找到使用看似随机的 Prolog 子集非最佳解决的主要琐碎问题。我希望有一个 Prolog 教程,“Python 教程”风格,用于 SWI-Prolog,向我们展示当前的实现应该如何根据其开发人员和高级用户来使用。
    • @Boris:Prolog 受到其 long 传统(几乎是当代 C)和实现差异的阻碍。正在努力帮助初学者,但我认为 StackOverflow 方法现在更好用。我正在考虑将来自 SO 的资源集成到我正在开发的小型 IDE 中,以将良好的 SWI-Prolog 文档与一些用例集成。
    • 我完全理解其中的困难。 SWI-Prolog 文档确实非常好。尽管如此,考虑到 Jan Wielemaker 和其他人在实现中付出的努力,几乎没有一个像样的教程(一般不是关于 Prolog,或者逻辑编程:只是关于 SWI 实现)。您和其他一些人在这里为 SO 上的新人提供了宝贵的帮助,但不幸的是,大部分大学的 Prolog 教学方法都采用了笨拙的方法。
    • 作为一个小例子,您建议的 OP 原始问题的解决方案可能被认为是不可接受的。教授会引用说教的理由,这很愚蠢。
    • @CapelliC 我命名谓词幂是因为该列表是表示多项式的系数列表,例如 1 + x + 4x^2 + 5x^3 表示为 [1,1,4,5 ]。我需要找到 x 的简单幂,即列表中只有一个元素是非零的。我没有解释那部分,因为我的问题比这简单得多。感谢您提供有效的解决方案,我会查看您提供的链接。
    猜你喜欢
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    相关资源
    最近更新 更多