【问题标题】:Implement the member predicate as a one-liner将成员谓词实现为单行
【发布时间】:2009-11-16 19:11:14
【问题描述】:

面试题!

这是您通常在 Prolog 中定义member 关系的方式:

member(X, [X|_]).        % member(X, [Head|Tail]) is true if X = Head 
                         % that is, if X is the head of the list
member(X, [_|Tail]) :-   % or if X is a member of Tail,
  member(X, Tail).       % ie. if member(X, Tail) is true.

只使用一个规则来定义它。

【问题讨论】:

  • 求职面试?什么工作?在哪里?多亏了 Prolog,人们能找到工作吗?

标签: list prolog dcg


【解决方案1】:

由于您没有指定我们允许使用的其他谓词,我将尝试作弊。 :P

member(X, L) :- append(_, [X|_], L).

【讨论】:

    【解决方案2】:
    1. 解决方案:

      member(X, [Y|T]) :- X = Y; member(X, T).
      
    2. 演示:

      ?- member(a, []).
      fail.
      ?- member(a, [a]).
      true ;
      fail.
      ?- member(a, [b]).
      fail.
      ?- member(a, [1, 2, 3, a, 5, 6, a]).
      true ;
      true ;
      fail.
      
    3. 它是如何工作的:

      • 我们正在寻找第一个参数 X 在第二个参数 [Y|T] 中的出现。
      • 假定第二个参数是一个列表。 Y 匹配其头部,T 匹配尾部。
      • 因此,空列表的谓词失败(应该如此)。
      • 如果X = Y(即X可以与Y统一)那么我们在列表中找到了X。否则 (;) 我们测试X 是否在尾部。
    4. 备注:

      • 感谢humble coffee 指出使用=(统一)比使用==(测试相等性)产生更灵活的代码。
      • 此代码还可用于枚举给定列表的元素:

        ?- member(X, [a, b]).
        X = a ;
        X = b ;
        fail.
        
      • 它可以用来“枚举”所有包含给定元素的列表:

        ?- member(a, X).
        X = [a|_G246] ;
        X = [_G245, a|_G249] ;
        X = [_G245, _G248, a|_G252] ;
        ...
        
      • 将上述代码中的= 替换为== 会降低其灵活性:它会立即在member(X, [a]) 上失败并导致member(a, X) 上的堆栈溢出(使用SWI-Prolog 5.6 版测试) .57)。

    【讨论】:

    • 嗯很可爱。关键是;运算符 - 我不知道您可以在规则内执行“或”操作。
    • 如果将“X == Y”替换为“X = Y”,则可以使用 member(X, [a])。甚至为 member(a, X) 得到一个合理的结果。
    • @humble 咖啡:谢谢!过去几年我几乎没有接触过 Prolog,所以我的知识有点生疏:)
    • 它被用来枚举元素/列表等是 prolog 工作方式的一个很棒的副作用 =)。这个例子并不特别——如果你定义了加法,你会自动得到减法。如果你定义了一个 TypeChecker,你也为所有类型良好的程序定义了一个枚举器。
    • X == Y vs X = Y 的要点是,第二个你强制统一(据我所知很糟糕),第二个你做深度相等检查
    【解决方案3】:
    newmember(X, Xs) :-
       phrase(( ..., [X] ),Xs, _).
    

    ... --> [] | [_], ... .
    

    其实下面的定义也保证Xs是一个列表:

    member_oflist(X, Xs) :-
       phrase(( ..., [X], ... ), Xs).
    

    致谢

    上述...的定义第一次出现在p。 205,注释 1 的

    David B. Searls,用定从句语法研究 DNA 的语言学。 NACLP 1989,第 1 卷。

    【讨论】:

      【解决方案4】:

      你也可以试试这个:

      member(X,L) :- append(_,[X|_],L).
      

      【讨论】:

      • 糟糕,我没有注意到这个解决方案已经给出了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 2018-04-02
      • 2014-01-26
      相关资源
      最近更新 更多