【问题标题】:compare length of prolog lists比较序言列表的长度
【发布时间】:2017-11-04 23:28:11
【问题描述】:

我有以下序言程序:

len([X],[Y],Count) :-
       length(X,K),
       length(Y,I),
       K < I,
       Count is 0
   ;   I < K,
       Count is 2
   ;   I = K,
       Count is 1.

当我输入时: len( [1,2], [5,2,4], X ).

我得到: Singleton variable in branch: K and I

我在这里查找了这意味着什么:http://www.swi-prolog.org/pldoc/man?section=singleton 我尝试过 _K &amp; _I 但你只能这样做一次。

这个程序应该取两个列表并比较每个列表的长度以确定输出值。

【问题讨论】:

  • 我不明白你的程序应该做什么。 Count 似乎是一个比较器,而不是列表的计数。此外,模式匹配是错误的。
  • length/2 目标之后的所有内容都需要用一对圆括号括起来。然后[X] 应该是X 等等。

标签: prolog


【解决方案1】:

你的代码的第一个问题是子句的头部有错误:

len(<b>[X]</b>,<b>[Y]</b>,Count) :- ...

这意味着第一个和第二个列表只能是单例(具有一个元素的列表)。所以我们需要将其重写为:

len(<b>X</b>,<b>Y</b>,Count) :- ...

第二个问题是the ; has higher priority than ,,因此Prolog解释器会将其解释为:

len(X,Y,Count) :-
    (
        length(X,K),
        length(Y,I),
        K < I,
        Count is 0
    );
    (
        I < K,
        Count is 2
    );
    (
        I = K,
        Count is 1
    ).

这意味着如果第一个条件失败,Prolog 将回溯,现在在该分支中,它看到 I &lt; K,但对于 Prolog,这些是新变量(因为它们位于不同的分支中)。 Prolog 解释器会警告您这很奇怪,尤其是在您编写 I &lt; K 的情况下,因为它需要将 IK 接地,所以这会出错。

您需要将程序重写为:

len(X,Y,Count) :-
    length(X,K),
    length(Y,I),
    (
        (
            K < I,
            Count is 0
        );
        (
            I < K,
            Count is 2
        );
        (
            I = K,
            Count is 1
        )
    ).

或者不那么冗长:

len(X,Y,Count) :-
    length(X,K),
    length(Y,I),
    (
        K < I,
        Count is 0
    ;   I < K,
        Count is 2
    ;   I = K,
        Count is 1
    ).

但这当然很麻烦。更优雅的解决方案是先编写一个compare/3 谓词:

cmp(X,Y,0) :-
    X < Y.
cmp(X,Y,2) :-
    X > Y.
cmp(X,X,1).

然后写:

cmp(X,Y,0) :-
    X < Y.
cmp(X,Y,2) :-
    X > Y.
cmp(X,X,1).

len(X,Y,Cmp) :-
    length(X,K),
    length(Y,I),
    cmp(K,I,Cmp).

【讨论】:

  • 你的重写和原来的程序一样糟糕。请使用listing/0 查看常见缩进的样子
  • @false:同时修改了。
  • 你仍然把;放在最后——并且在周围使用了很多不必要的圆括号
  • :请使用listing/0 看看Prolog 社区发现了什么... 将; 放在一行的末尾是极具误导性的
  • 答案中已经提到了。 ; 表示这是一个“逻辑”或。所以这意味着 Prolog 将回溯。它将这些痕迹视为独立的痕迹。所以在第二个跟踪中,你只提到了一次I,所以 Prolog 警告你这没有多大意义。
猜你喜欢
  • 1970-01-01
  • 2021-03-18
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 2017-12-24
  • 2019-02-17
  • 1970-01-01
相关资源
最近更新 更多